update for HEAD-2003021201
[reactos.git] / drivers / net / npf / tme.c
1 /*
2  * Copyright (c) 2001
3  *      Politecnico di Torino.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that: (1) source code distributions
7  * retain the above copyright notice and this paragraph in its entirety, (2)
8  * distributions including binary code include the above copyright notice and
9  * this paragraph in its entirety in the documentation or other materials
10  * provided with the distribution, and (3) all advertising materials mentioning
11  * features or use of this software display the following acknowledgement:
12  * ``This product includes software developed by the Politecnico
13  * di Torino, and its contributors.'' Neither the name of
14  * the University nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior
16  * written permission.
17  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20  */
21
22 #ifdef WIN32
23 #include "tme.h"
24 #endif
25
26 #ifdef __FreeBSD__
27 #include <net/tme/tme.h>
28 #endif
29
30 /* resizes extended memory */ 
31 uint32 init_extended_memory(uint32 size, MEM_TYPE *mem_ex)
32 {
33         uint8 *tmp;
34         
35         if ((mem_ex==NULL)||(mem_ex->buffer==NULL)||(size==0))
36                 return TME_ERROR;  /* awfully never reached!!!! */
37
38         tmp=mem_ex->buffer;
39         mem_ex->buffer=NULL;
40         FREE_MEMORY(tmp);
41
42         ALLOCATE_MEMORY(tmp,uint8,size);
43         if (tmp==NULL)
44                 return TME_ERROR; /* no memory */
45                         
46         mem_ex->size=size;
47         mem_ex->buffer=tmp;
48         return TME_SUCCESS;
49
50 }
51
52 /* activates a block of the TME */
53 uint32 set_active_tme_block(TME_CORE *tme, uint32 block)  
54 {
55
56         if ((block>=MAX_TME_DATA_BLOCKS)||(!IS_VALIDATED(tme->validated_blocks,block)))
57                 return TME_ERROR;
58         tme->active=block;
59         tme->working=block;
60         return TME_SUCCESS;
61
62 }
63
64 /* simply inserts default values in a TME block      */
65 /* it DOESN'T initialize the block in the core!!     */
66 /* FIXME default values are defined at compile time, */
67 /* it will be useful to store them in the registry   */
68 uint32 init_tme_block(TME_CORE *tme, uint32 block)
69 {
70         
71         TME_DATA *data;
72         if (block>=MAX_TME_DATA_BLOCKS)
73                 return TME_ERROR;
74         data=&(tme->block_data[block]);
75         tme->working=block;
76
77         ZERO_MEMORY(data,sizeof(TME_DATA));
78
79         /* entries in LUT     */
80         data->lut_entries=TME_LUT_ENTRIES_DEFAULT;
81         /* blocks             */
82         data->shared_memory_blocks=TME_SHARED_MEMORY_BLOCKS_DEFAULT;
83         /* block size         */
84         data->block_size=TME_BLOCK_SIZE_DEFAULT;
85         /* lookup function    */
86         data->lookup_code=lut_fcn_mapper(TME_LOOKUP_CODE_DEFAULT);
87         /* rehashing value    */
88         data->rehashing_value=TME_REHASHING_VALUE_DEFAULT;
89         /* out lut function   */
90         data->out_lut_exec=TME_OUT_LUT_EXEC_DEFAULT;
91         /* default function   */
92         data->default_exec=TME_DEFAULT_EXEC_DEFAULT;
93         /* extra segment size */
94         data->extra_segment_size=TME_EXTRA_SEGMENT_SIZE_DEFAULT;
95         
96
97         data->enable_deletion=FALSE;
98         data->last_read.tv_sec=0;
99         data->last_read.tv_usec=0;
100         return TME_SUCCESS;
101
102 }
103 /* it validates a TME block and          */
104 /* (on OK) inserts the block in the core */
105 uint32 validate_tme_block(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 block, uint32 mem_ex_offset)
106 {
107         uint32 required_memory;
108         uint8 *base=mem_ex_offset+mem_ex->buffer;
109         TME_DATA *data;
110         
111         /* FIXME soluzione un po' posticcia... */
112         if (mem_ex_offset==0)
113                 return TME_ERROR;
114
115         if (block>=MAX_TME_DATA_BLOCKS)
116                 return TME_ERROR;
117         data=&tme->block_data[block];
118         
119         if (data->lut_entries==0)
120                 return TME_ERROR;
121
122         if (data->key_len==0)
123                 return TME_ERROR;
124
125         if (data->shared_memory_blocks==0)
126                 return TME_ERROR;
127
128         if (data->block_size==0)
129                 return TME_ERROR;
130
131         /* checks if the lookup function is valid       */
132         if (data->lookup_code==NULL)
133                 return TME_ERROR;
134
135         /* checks if the out lut exec function is valid */
136         if (exec_fcn_mapper(data->out_lut_exec)==NULL)
137                 return TME_ERROR;
138
139         /* checks if the default exec function is valid */
140         if (exec_fcn_mapper(data->default_exec)==NULL)
141                 return TME_ERROR;
142
143         /* let's calculate memory needed                */
144         required_memory=data->lut_entries*sizeof(RECORD); /*LUT*/
145         required_memory+=data->block_size*data->shared_memory_blocks; /*shared segment*/
146         required_memory+=data->extra_segment_size; /*extra segment*/
147
148         if (required_memory>(mem_ex->size-mem_ex_offset))
149                 return TME_ERROR;  /*not enough memory*/
150
151         /* the TME block can be initialized             */
152         ZERO_MEMORY(base,required_memory);
153         
154         data->lut_base_address=base;
155         
156         data->shared_memory_base_address=
157                 data->lut_base_address+
158                 data->lut_entries*sizeof(RECORD);
159
160         data->extra_segment_base_address=
161                 data->shared_memory_base_address+
162                 data->block_size*data->shared_memory_blocks;
163         data->filled_blocks=1;
164         VALIDATE(tme->validated_blocks,block);
165         tme->active=block;
166         tme->working=block;
167         return TME_SUCCESS;
168 }
169                                                                                                                          
170 /* I/F between the bpf machine and the callbacks, just some checks */
171 uint32 lookup_frontend(MEM_TYPE *mem_ex, TME_CORE *tme,uint32 mem_ex_offset, struct time_conv *time_ref)
172 {
173         if (tme->active==TME_NONE_ACTIVE)
174                 return TME_FALSE;
175         
176         return (tme->block_data[tme->active].lookup_code)(mem_ex_offset+mem_ex->buffer,&tme->block_data[tme->active],mem_ex, time_ref);
177 }
178
179 /* I/F between the bpf machine and the callbacks, just some checks */
180 uint32 execute_frontend(MEM_TYPE *mem_ex, TME_CORE *tme, uint32 pkt_size, uint32 offset)
181 {
182         
183         exec_fcn tmp;
184         TME_DATA *data;
185         uint8 *block;
186         uint8 *mem_data;
187
188         if (tme->active==TME_NONE_ACTIVE)
189                 return TME_ERROR;
190
191         data=&tme->block_data[tme->active];
192         
193         if (data->last_found==NULL)
194         {       /*out lut exec */
195                 tmp=exec_fcn_mapper(data->out_lut_exec);
196                 block=data->shared_memory_base_address;
197         }
198         else
199         {   /*checks if last_found is valid */
200                 if ((data->last_found<data->lut_base_address)||(data->last_found>=data->shared_memory_base_address))
201                         return TME_ERROR;
202                 else
203                 {
204                         tmp=exec_fcn_mapper(SW_ULONG_AT(&((RECORD*)data->last_found)->exec_fcn,0));
205                         if (tmp==NULL)
206                                 return TME_ERROR;
207                         block=SW_ULONG_AT(&((RECORD*)data->last_found)->block,0)+mem_ex->buffer;
208                         if ((block<data->shared_memory_base_address)||(block>=data->extra_segment_base_address))
209                                 return TME_ERROR;
210                 }
211         }
212         
213         if (offset>=mem_ex->size)
214                 return TME_ERROR;
215         
216         mem_data=mem_ex->buffer+offset;
217         
218         return tmp(block,pkt_size,data,mem_ex,mem_data);
219 }
220
221 /*resets all the TME core*/
222 uint32 reset_tme(TME_CORE *tme)
223 {
224         if (tme==NULL)
225                 return TME_ERROR;
226         ZERO_MEMORY(tme, sizeof(TME_CORE));     
227         return TME_SUCCESS;
228 }
229         
230 /* returns a register value of the active TME block   */
231 /* FIXME last found in maniera elegante e veloce ?!?! */
232 uint32 get_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 *rval)
233 {
234         switch(rgstr)
235         {
236         case TME_LUT_ENTRIES:
237                 *rval=data->lut_entries;
238                 return TME_SUCCESS;
239         case TME_MAX_FILL_STATE:
240                 *rval=data->max_fill_state;
241                 return TME_SUCCESS;
242         case TME_REHASHING_VALUE:
243                 *rval=data->rehashing_value;
244                 return TME_SUCCESS;
245         case TME_KEY_LEN:
246                 *rval=data->key_len;
247                 return TME_SUCCESS;
248         case TME_SHARED_MEMORY_BLOCKS:
249                 *rval=data->shared_memory_blocks;
250                 return TME_SUCCESS;
251         case TME_FILLED_ENTRIES:
252                 *rval=data->filled_entries;
253                 return TME_SUCCESS;
254         case TME_BLOCK_SIZE:
255                 *rval=data->block_size;
256                 return TME_SUCCESS;
257         case TME_EXTRA_SEGMENT_SIZE:
258                 *rval=data->extra_segment_size;
259                 return TME_SUCCESS;
260         case TME_FILLED_BLOCKS:
261                 *rval=data->filled_blocks;
262                 return TME_SUCCESS;
263         case TME_DEFAULT_EXEC:
264                 *rval=data->default_exec;
265                 return TME_SUCCESS;
266         case TME_OUT_LUT_EXEC:
267                 *rval=data->out_lut_exec;
268                 return TME_SUCCESS;
269         case TME_SHARED_MEMORY_BASE_ADDRESS:
270                 *rval=data->shared_memory_base_address-mem_ex->buffer;
271                 return TME_SUCCESS;
272         case TME_LUT_BASE_ADDRESS:
273                 *rval=data->lut_base_address-mem_ex->buffer;
274                 return TME_SUCCESS;
275         case TME_EXTRA_SEGMENT_BASE_ADDRESS:
276                 *rval=data->extra_segment_base_address-mem_ex->buffer;
277                 return TME_SUCCESS;
278         case TME_LAST_FOUND_BLOCK:
279                 if (data->last_found==NULL)
280                         *rval=0;
281                 else
282                         *rval=data->last_found-mem_ex->buffer;
283                 return TME_SUCCESS;
284
285         default:
286                 return TME_ERROR;
287         }
288 }
289
290 /* sets a register value in the active block          */
291 /* FIXME last found in maniera elegante e veloce ?!?! */
292 uint32 set_tme_block_register(TME_DATA *data,MEM_TYPE *mem_ex,uint32 rgstr,uint32 value, int32 init)
293 {       /* very very very dangerous!!!!!!!!!!! */
294         lut_fcn tmp;
295         switch(rgstr)
296         {
297         case TME_MAX_FILL_STATE:
298                 data->max_fill_state=value;
299                 return TME_SUCCESS;
300         case TME_REHASHING_VALUE:
301                 data->rehashing_value=value;
302                 return TME_SUCCESS;
303         case TME_FILLED_ENTRIES: 
304                 data->filled_entries=value;
305                 return TME_SUCCESS;
306         case TME_FILLED_BLOCKS:  
307                 if (value<=data->shared_memory_blocks)
308                 {
309                         data->filled_blocks=value;
310                         return TME_SUCCESS;
311                 }
312                 else
313                         return TME_ERROR;
314         case TME_DEFAULT_EXEC:  
315                 data->default_exec=value;
316                 return TME_SUCCESS;
317         case TME_OUT_LUT_EXEC:
318                 data->out_lut_exec=value;
319                 return TME_SUCCESS;
320         case TME_LOOKUP_CODE:
321                 tmp=lut_fcn_mapper(value);
322                 if (tmp==NULL)
323                         return TME_ERROR;
324                 else
325                         data->lookup_code=tmp;
326                 return TME_SUCCESS;
327         default:
328                 break;
329         }
330
331         if (init)
332                 switch (rgstr)
333                 {
334
335                 case TME_LUT_ENTRIES: 
336                         data->lut_entries=value;
337                         return TME_SUCCESS;
338                 case TME_KEY_LEN: 
339                         data->key_len=value;
340                         return TME_SUCCESS;
341                 case TME_SHARED_MEMORY_BLOCKS: 
342                         data->shared_memory_blocks=value;
343                         return TME_SUCCESS;
344                 case TME_BLOCK_SIZE:  
345                         data->block_size=value;
346                         return TME_SUCCESS;
347                 case TME_EXTRA_SEGMENT_SIZE: 
348                         data->extra_segment_size=value;
349                         return TME_SUCCESS;
350                 default:
351                         return TME_ERROR;
352                 }
353         else
354                 return TME_ERROR;
355
356 }
357
358 /* chooses the TME block for read */
359 uint32 set_active_read_tme_block(TME_CORE *tme, uint32 block)  
360 {
361
362         if ((block>=MAX_TME_DATA_BLOCKS)||(!IS_VALIDATED(tme->validated_blocks,block)))
363                 return TME_ERROR;
364         tme->active_read=block;
365         return TME_SUCCESS;
366
367 }
368
369 /* chooses if the autodeletion must be used */
370 uint32 set_autodeletion(TME_DATA *data, uint32 value)
371 {
372         if (value==0)  /* no autodeletion */
373                 data->enable_deletion=FALSE;
374         else
375                 data->enable_deletion=TRUE;
376
377         return TME_SUCCESS;
378 }