X-Git-Url: http://git.jankratochvil.net/?p=reactos.git;a=blobdiff_plain;f=drivers%2Fnet%2Fnpf%2Ftme.c;fp=drivers%2Fnet%2Fnpf%2Ftme.c;h=87ed7dcad5ad9ba67199ee7950fe03f5ea936439;hp=0000000000000000000000000000000000000000;hb=e3ed2d773259cc445c7ff8181ebd934931365328;hpb=d378c68f5a9bb25c9e671dacd482d2e25d211df3 diff --git a/drivers/net/npf/tme.c b/drivers/net/npf/tme.c new file mode 100644 index 0000000..87ed7dc --- /dev/null +++ b/drivers/net/npf/tme.c @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef WIN32 +#include "tme.h" +#endif + +#ifdef __FreeBSD__ +#include +#endif + +/* resizes extended memory */ +uint32 init_extended_memory(uint32 size, MEM_TYPE *mem_ex) +{ + uint8 *tmp; + + if ((mem_ex==NULL)||(mem_ex->buffer==NULL)||(size==0)) + return TME_ERROR; /* awfully never reached!!!! */ + + tmp=mem_ex->buffer; + mem_ex->buffer=NULL; + FREE_MEMORY(tmp); + + ALLOCATE_MEMORY(tmp,uint8,size); + if (tmp==NULL) + return TME_ERROR; /* no memory */ + + mem_ex->size=size; + mem_ex->buffer=tmp; + return TME_SUCCESS; + +} + +/* activates a block of the TME */ +uint32 set_active_tme_block(TME_CORE *tme, uint32 block) +{ + + if ((block>=MAX_TME_DATA_BLOCKS)||(!IS_VALIDATED(tme->validated_blocks,block))) + return TME_ERROR; + tme->active=block; + tme->working=block; + return TME_SUCCESS; + +} + +/* simply inserts default values in a TME block */ +/* it DOESN'T initialize the block in the core!! */ +/* FIXME default values are defined at compile time, */ +/* it will be useful to store them in the registry */ +uint32 init_tme_block(TME_CORE *tme, uint32 block) +{ + + TME_DATA *data; + if (block>=MAX_TME_DATA_BLOCKS) + return TME_ERROR; + data=&(tme->block_data[block]); + tme->working=block; + + ZERO_MEMORY(data,sizeof(TME_DATA)); + + /* entries in LUT */ + data->lut_entries=TME_LUT_ENTRIES_DEFAULT; + /* blocks */ + data->shared_memory_blocks=TME_SHARED_MEMORY_BLOCKS_DEFAULT; + /* block size */ + data->block_size=TME_BLOCK_SIZE_DEFAULT; + /* lookup function */ + data->lookup_code=lut_fcn_mapper(TME_LOOKUP_CODE_DEFAULT); + /* rehashing value */ + data->rehashing_value=TME_REHASHING_VALUE_DEFAULT; + /* out lut function */ + data->out_lut_exec=TME_OUT_LUT_EXEC_DEFAULT; + /* default function */ + data->default_exec=TME_DEFAULT_EXEC_DEFAULT; + /* extra segment size */ + data->extra_segment_size=TME_EXTRA_SEGMENT_SIZE_DEFAULT; + + + data->enable_deletion=FALSE; + data->last_read.tv_sec=0; + data->last_read.tv_usec=0; + return TME_SUCCESS; + +} +/* it validates a TME block and */ +/* (on OK) inserts the block in the core */ +uint32 validate_tme_block(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 block, uint32 mem_ex_offset) +{ + uint32 required_memory; + uint8 *base=mem_ex_offset+mem_ex->buffer; + TME_DATA *data; + + /* FIXME soluzione un po' posticcia... */ + if (mem_ex_offset==0) + return TME_ERROR; + + if (block>=MAX_TME_DATA_BLOCKS) + return TME_ERROR; + data=&tme->block_data[block]; + + if (data->lut_entries==0) + return TME_ERROR; + + if (data->key_len==0) + return TME_ERROR; + + if (data->shared_memory_blocks==0) + return TME_ERROR; + + if (data->block_size==0) + return TME_ERROR; + + /* checks if the lookup function is valid */ + if (data->lookup_code==NULL) + return TME_ERROR; + + /* checks if the out lut exec function is valid */ + if (exec_fcn_mapper(data->out_lut_exec)==NULL) + return TME_ERROR; + + /* checks if the default exec function is valid */ + if (exec_fcn_mapper(data->default_exec)==NULL) + return TME_ERROR; + + /* let's calculate memory needed */ + required_memory=data->lut_entries*sizeof(RECORD); /*LUT*/ + required_memory+=data->block_size*data->shared_memory_blocks; /*shared segment*/ + required_memory+=data->extra_segment_size; /*extra segment*/ + + if (required_memory>(mem_ex->size-mem_ex_offset)) + return TME_ERROR; /*not enough memory*/ + + /* the TME block can be initialized */ + ZERO_MEMORY(base,required_memory); + + data->lut_base_address=base; + + data->shared_memory_base_address= + data->lut_base_address+ + data->lut_entries*sizeof(RECORD); + + data->extra_segment_base_address= + data->shared_memory_base_address+ + data->block_size*data->shared_memory_blocks; + data->filled_blocks=1; + VALIDATE(tme->validated_blocks,block); + tme->active=block; + tme->working=block; + return TME_SUCCESS; +} + +/* I/F between the bpf machine and the callbacks, just some checks */ +uint32 lookup_frontend(MEM_TYPE *mem_ex, TME_CORE *tme,uint32 mem_ex_offset, struct time_conv *time_ref) +{ + if (tme->active==TME_NONE_ACTIVE) + return TME_FALSE; + + return (tme->block_data[tme->active].lookup_code)(mem_ex_offset+mem_ex->buffer,&tme->block_data[tme->active],mem_ex, time_ref); +} + +/* I/F between the bpf machine and the callbacks, just some checks */ +uint32 execute_frontend(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 pkt_size, uint32 offset) +{ + + exec_fcn tmp; + TME_DATA *data; + uint8 *block; + uint8 *mem_data; + + if (tme->active==TME_NONE_ACTIVE) + return TME_ERROR; + + data=&tme->block_data[tme->active]; + + if (data->last_found==NULL) + { /*out lut exec */ + tmp=exec_fcn_mapper(data->out_lut_exec); + block=data->shared_memory_base_address; + } + else + { /*checks if last_found is valid */ + if ((data->last_foundlut_base_address)||(data->last_found>=data->shared_memory_base_address)) + return TME_ERROR; + else + { + tmp=exec_fcn_mapper(SW_ULONG_AT(&((RECORD*)data->last_found)->exec_fcn,0)); + if (tmp==NULL) + return TME_ERROR; + block=SW_ULONG_AT(&((RECORD*)data->last_found)->block,0)+mem_ex->buffer; + if ((blockshared_memory_base_address)||(block>=data->extra_segment_base_address)) + return TME_ERROR; + } + } + + if (offset>=mem_ex->size) + return TME_ERROR; + + mem_data=mem_ex->buffer+offset; + + return tmp(block,pkt_size,data,mem_ex,mem_data); +} + +/*resets all the TME core*/ +uint32 reset_tme(TME_CORE *tme) +{ + if (tme==NULL) + return TME_ERROR; + ZERO_MEMORY(tme, sizeof(TME_CORE)); + return TME_SUCCESS; +} + +/* returns a register value of the active TME block */ +/* FIXME last found in maniera elegante e veloce ?!?! */ +uint32 get_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 *rval) +{ + switch(rgstr) + { + case TME_LUT_ENTRIES: + *rval=data->lut_entries; + return TME_SUCCESS; + case TME_MAX_FILL_STATE: + *rval=data->max_fill_state; + return TME_SUCCESS; + case TME_REHASHING_VALUE: + *rval=data->rehashing_value; + return TME_SUCCESS; + case TME_KEY_LEN: + *rval=data->key_len; + return TME_SUCCESS; + case TME_SHARED_MEMORY_BLOCKS: + *rval=data->shared_memory_blocks; + return TME_SUCCESS; + case TME_FILLED_ENTRIES: + *rval=data->filled_entries; + return TME_SUCCESS; + case TME_BLOCK_SIZE: + *rval=data->block_size; + return TME_SUCCESS; + case TME_EXTRA_SEGMENT_SIZE: + *rval=data->extra_segment_size; + return TME_SUCCESS; + case TME_FILLED_BLOCKS: + *rval=data->filled_blocks; + return TME_SUCCESS; + case TME_DEFAULT_EXEC: + *rval=data->default_exec; + return TME_SUCCESS; + case TME_OUT_LUT_EXEC: + *rval=data->out_lut_exec; + return TME_SUCCESS; + case TME_SHARED_MEMORY_BASE_ADDRESS: + *rval=data->shared_memory_base_address-mem_ex->buffer; + return TME_SUCCESS; + case TME_LUT_BASE_ADDRESS: + *rval=data->lut_base_address-mem_ex->buffer; + return TME_SUCCESS; + case TME_EXTRA_SEGMENT_BASE_ADDRESS: + *rval=data->extra_segment_base_address-mem_ex->buffer; + return TME_SUCCESS; + case TME_LAST_FOUND_BLOCK: + if (data->last_found==NULL) + *rval=0; + else + *rval=data->last_found-mem_ex->buffer; + return TME_SUCCESS; + + default: + return TME_ERROR; + } +} + +/* sets a register value in the active block */ +/* FIXME last found in maniera elegante e veloce ?!?! */ +uint32 set_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 value, int32 init) +{ /* very very very dangerous!!!!!!!!!!! */ + lut_fcn tmp; + switch(rgstr) + { + case TME_MAX_FILL_STATE: + data->max_fill_state=value; + return TME_SUCCESS; + case TME_REHASHING_VALUE: + data->rehashing_value=value; + return TME_SUCCESS; + case TME_FILLED_ENTRIES: + data->filled_entries=value; + return TME_SUCCESS; + case TME_FILLED_BLOCKS: + if (value<=data->shared_memory_blocks) + { + data->filled_blocks=value; + return TME_SUCCESS; + } + else + return TME_ERROR; + case TME_DEFAULT_EXEC: + data->default_exec=value; + return TME_SUCCESS; + case TME_OUT_LUT_EXEC: + data->out_lut_exec=value; + return TME_SUCCESS; + case TME_LOOKUP_CODE: + tmp=lut_fcn_mapper(value); + if (tmp==NULL) + return TME_ERROR; + else + data->lookup_code=tmp; + return TME_SUCCESS; + default: + break; + } + + if (init) + switch (rgstr) + { + + case TME_LUT_ENTRIES: + data->lut_entries=value; + return TME_SUCCESS; + case TME_KEY_LEN: + data->key_len=value; + return TME_SUCCESS; + case TME_SHARED_MEMORY_BLOCKS: + data->shared_memory_blocks=value; + return TME_SUCCESS; + case TME_BLOCK_SIZE: + data->block_size=value; + return TME_SUCCESS; + case TME_EXTRA_SEGMENT_SIZE: + data->extra_segment_size=value; + return TME_SUCCESS; + default: + return TME_ERROR; + } + else + return TME_ERROR; + +} + +/* chooses the TME block for read */ +uint32 set_active_read_tme_block(TME_CORE *tme, uint32 block) +{ + + if ((block>=MAX_TME_DATA_BLOCKS)||(!IS_VALIDATED(tme->validated_blocks,block))) + return TME_ERROR; + tme->active_read=block; + return TME_SUCCESS; + +} + +/* chooses if the autodeletion must be used */ +uint32 set_autodeletion(TME_DATA *data, uint32 value) +{ + if (value==0) /* no autodeletion */ + data->enable_deletion=FALSE; + else + data->enable_deletion=TRUE; + + return TME_SUCCESS; +} \ No newline at end of file