]>
Commit | Line | Data |
---|---|---|
ba94a1bb WD |
1 | /** |
2 | * @file IxEthDB_p.h | |
3 | * | |
4 | * @brief Private MAC learning API | |
5 | * | |
6 | * @par | |
7 | * IXP400 SW Release version 2.0 | |
8 | * | |
9 | * -- Copyright Notice -- | |
10 | * | |
11 | * @par | |
12 | * Copyright 2001-2005, Intel Corporation. | |
13 | * All rights reserved. | |
14 | * | |
15 | * @par | |
16 | * Redistribution and use in source and binary forms, with or without | |
17 | * modification, are permitted provided that the following conditions | |
18 | * are met: | |
19 | * 1. Redistributions of source code must retain the above copyright | |
20 | * notice, this list of conditions and the following disclaimer. | |
21 | * 2. Redistributions in binary form must reproduce the above copyright | |
22 | * notice, this list of conditions and the following disclaimer in the | |
23 | * documentation and/or other materials provided with the distribution. | |
24 | * 3. Neither the name of the Intel Corporation nor the names of its contributors | |
25 | * may be used to endorse or promote products derived from this software | |
26 | * without specific prior written permission. | |
27 | * | |
28 | * @par | |
29 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' | |
30 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
31 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
32 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE | |
33 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
34 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
35 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
36 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
37 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
38 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
39 | * SUCH DAMAGE. | |
40 | * | |
41 | * @par | |
42 | * -- End of Copyright Notice -- | |
43 | */ | |
44 | ||
45 | #ifndef IxEthDB_p_H | |
46 | #define IxEthDB_p_H | |
47 | ||
48 | #include <IxTypes.h> | |
49 | #include <IxOsal.h> | |
50 | #include <IxEthDB.h> | |
51 | #include <IxNpeMh.h> | |
52 | #include <IxEthDBPortDefs.h> | |
53 | ||
54 | #include "IxEthDBMessages_p.h" | |
55 | #include "IxEthDBLog_p.h" | |
56 | ||
57 | #if (CPU==SIMSPARCSOLARIS) | |
58 | ||
59 | /* when running unit tests intLock() won't protect the event queue so we lock it manually */ | |
60 | #define TEST_FIXTURE_LOCK_EVENT_QUEUE { ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER); } | |
61 | #define TEST_FIXTURE_UNLOCK_EVENT_QUEUE { ixOsalMutexUnlock(&eventQueueLock); } | |
62 | ||
63 | #else | |
64 | ||
65 | #define TEST_FIXTURE_LOCK_EVENT_QUEUE /* nothing */ | |
66 | #define TEST_FIXTURE_UNLOCK_EVENT_QUEUE /* nothing */ | |
67 | ||
68 | #endif /* #if(CPU==SIMSPARCSOLARIS) */ | |
69 | ||
70 | #ifndef IX_UNIT_TEST | |
71 | ||
72 | #define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER /* nothing */ | |
73 | #define TEST_FIXTURE_MARK_OVERFLOW_EVENT /* nothing */ | |
74 | ||
75 | #else | |
76 | ||
77 | extern int dbAccessCounter; | |
78 | extern int overflowEvent; | |
79 | ||
80 | #define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER { dbAccessCounter++; } | |
81 | #define TEST_FIXTURE_MARK_OVERFLOW_EVENT { overflowEvent = 1; } | |
82 | ||
83 | #endif | |
84 | ||
85 | /* code readability markers */ | |
86 | #define __mempool__ /* memory pool marker */ | |
87 | #define __lock__ /* hash write locking marker */ | |
88 | #define __smartpointer__ /* smart pointer marker - warning: use only clone() when duplicating! */ | |
89 | #define __alignment__ /* marker for data used only as alignment zones */ | |
90 | ||
91 | /* constants */ | |
92 | #define IX_ETH_DB_NPE_TIMEOUT (100) /* NPE response timeout, in ms */ | |
93 | ||
94 | /** | |
95 | * number of hash table buckets | |
96 | * it should be at least 8x the predicted number of entries for performance | |
97 | * each bucket needs 8 bytes | |
98 | */ | |
99 | #define NUM_BUCKETS (8192) | |
100 | ||
101 | /** | |
102 | * number of hash table buckets to preload when incrementing bucket iterator | |
103 | * = two cache lines | |
104 | */ | |
105 | #define IX_ETHDB_CACHE_LINE_AHEAD (2) | |
106 | ||
107 | #define IX_ETHDB_BUCKETPTR_AHEAD ((IX_ETHDB_CACHE_LINE_AHEAD * IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *)) | |
108 | ||
109 | #define IX_ETHDB_BUCKET_INDEX_MASK (((IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *)) - 1) | |
110 | ||
111 | /* locks */ | |
112 | #define MAX_LOCKS (20) /**< maximum number of locks used simultaneously, do not tamper with */ | |
113 | ||
114 | /* learning tree constants */ | |
115 | #define INITIAL_ELT_SIZE (8) /**< initial byte size of tree (empty unused root size) */ | |
116 | #define MAX_ELT_SIZE (512) /**< maximum number of entries (includes unused root) */ | |
117 | #define MAX_GW_SIZE (32) /**< maximum number of gateway entries (including unused root) */ | |
118 | #define MAX_FW_SIZE (32) /**< maximum number of firewall entries (including unused root) */ | |
119 | #define ELT_ENTRY_SIZE (8) /**< entry size, in bytes */ | |
120 | #define ELT_ROOT_OFFSET (ELT_ENTRY_SIZE) /**< tree root offset, in bytes - node preceeding root is unused */ | |
121 | #define FULL_ELT_BYTE_SIZE (MAX_ELT_SIZE * ELT_ENTRY_SIZE) /**< full size of tree, in bytes, including unused root */ | |
122 | #define FULL_GW_BYTE_SIZE (MAX_GW_SIZE * ELT_ENTRY_SIZE) /**< full size of gateway list, in bytes, including unused root */ | |
123 | #define FULL_FW_BYTE_SIZE (MAX_FW_SIZE * ELT_ENTRY_SIZE) /**< full size of firewall table, in bytes, including unused root */ | |
124 | ||
125 | /* maximum size of the VLAN table: | |
126 | * 4096 bits (one per VLAN) | |
127 | * 8 bits in one byte | |
128 | * interleaved VLAN membership and VLAN TTI (*2) */ | |
129 | #define FULL_VLAN_BYTE_SIZE (4096 / 8 * 2) | |
130 | ||
131 | /* upper 9 bits used as set index, lower 3 bits as byte index */ | |
132 | #define VLAN_SET_OFFSET(vlanID) ((vlanID) >> 3) | |
133 | #define VLAN_SET_MASK(vlanID) (0x7 - ((vlanID) & 0x7)) | |
134 | ||
135 | /* Update zone definitions */ | |
136 | #define NPE_TREE_MEM_SIZE (4096) /* ((511 entries + 1 unused root) * 8 bytes/entry) */ | |
137 | ||
138 | /* check the above value, we rely on 4k */ | |
139 | #if NPE_TREE_MEM_SIZE != 4096 | |
140 | #error NPE_TREE_MEM_SIZE is not defined to 4096 bytes! | |
141 | #endif | |
142 | ||
143 | /* Size Filtering limits (Jumbo frame filtering) */ | |
144 | #define IX_ETHDB_MAX_FRAME_SIZE 65535 /* other ports than NPE ports */ | |
145 | #define IX_ETHDB_MIN_FRAME_SIZE 1 /* other ports than NPE ports */ | |
146 | #define IX_ETHDB_MAX_NPE_FRAME_SIZE 16320 /* NPE ports firmware limit */ | |
147 | #define IX_ETHDB_MIN_NPE_FRAME_SIZE 1 /* NPE ports firmware limit */ | |
148 | #define IX_ETHDB_DEFAULT_FRAME_SIZE 1522 | |
149 | ||
150 | /* memory management pool sizes */ | |
151 | ||
152 | /* | |
153 | * Note: | |
154 | * | |
155 | * NODE_POOL_SIZE controls the maximum number of elements in the database at any one time. | |
156 | * It should be large enough to cover all the search trees of all the ports simultaneously. | |
157 | * | |
158 | * MAC_POOL_SIZE should be higher than NODE_POOL_SIZE by at least the total number of MAC addresses | |
159 | * possible to be held at any time in all the ports. | |
160 | * | |
161 | * TREE_POOL_SIZE should follow the same guideline as for MAC_POOL_SIZE. | |
162 | * | |
163 | * The database structure described here (2000/4000/4000) is enough for two NPEs holding at most 511 | |
164 | * entries each plus one PCI NIC holding at most 900 entries. | |
165 | */ | |
166 | ||
167 | #define NODE_POOL_SIZE (2000) /**< number of HashNode objects - also master number of elements in the database; each entry has 16 bytes */ | |
168 | #define MAC_POOL_SIZE (4000) /**< number of MacDescriptor objects; each entry has 28 bytes */ | |
169 | #define TREE_POOL_SIZE (4000) /**< number of MacTreeNode objects; each entry has 16 bytes */ | |
170 | ||
171 | /* retry policies */ | |
472d5460 YS |
172 | #define BUSY_RETRY_ENABLED (true) /**< if set to true the API will retry automatically calls returning BUSY */ |
173 | #define FOREVER_RETRY (true) /**< if set to true the API will retry forever BUSY calls */ | |
174 | #define MAX_RETRIES (400) /**< upper retry limit - used only when FOREVER_RETRY is false */ | |
ba94a1bb WD |
175 | #define BUSY_RETRY_YIELD (5) /**< ticks to yield for every failed retry */ |
176 | ||
177 | /* event management */ | |
178 | #define EVENT_QUEUE_SIZE (500) /**< size of the sink collecting events from the Message Handler FIFO */ | |
179 | #define EVENT_PROCESSING_LIMIT (100) /**< batch processing control size (how many events are extracted from the queue at once) */ | |
180 | ||
181 | /* MAC descriptors */ | |
472d5460 YS |
182 | #define STATIC_ENTRY (true) |
183 | #define DYNAMIC_ENTRY (false) | |
ba94a1bb WD |
184 | |
185 | /* age reset on next maintenance - incrementing by 1 will reset to 0 */ | |
186 | #define AGE_RESET (0xFFFFFFFF) | |
187 | ||
188 | /* dependency maps */ | |
189 | #define EMPTY_DEPENDENCY_MAP (0) | |
190 | ||
191 | /* trees */ | |
192 | #define RIGHT (1) | |
193 | #define LEFT (-1) | |
194 | ||
195 | /* macros */ | |
ba94a1bb WD |
196 | #define IX_ETH_DB_CHECK_PORT_EXISTS(portID) \ |
197 | { \ | |
198 | if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \ | |
199 | { \ | |
200 | return IX_ETH_DB_INVALID_PORT; \ | |
201 | } \ | |
202 | } | |
203 | ||
204 | #define IX_ETH_DB_CHECK_PORT_INITIALIZED(portID) \ | |
205 | { \ | |
206 | if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \ | |
207 | { \ | |
208 | return IX_ETH_DB_INVALID_PORT; \ | |
209 | } \ | |
210 | else \ | |
211 | { \ | |
212 | if (!ixEthDBPortInfo[portID].initialized) \ | |
213 | { \ | |
214 | return IX_ETH_DB_PORT_UNINITIALIZED; \ | |
215 | } \ | |
216 | } \ | |
217 | } | |
218 | ||
219 | /* single NPE check */ | |
220 | #define IX_ETH_DB_CHECK_SINGLE_NPE(portID) \ | |
221 | if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS) \ | |
222 | { \ | |
223 | WARNING_LOG("EthDB: port ID %d is unavailable\n",(UINT32) portID); \ | |
224 | \ | |
225 | return IX_ETH_DB_INVALID_PORT; \ | |
226 | } | |
227 | ||
228 | /* feature check */ | |
229 | #define IX_ETH_DB_CHECK_FEATURE(portID, feature) \ | |
230 | if ((ixEthDBPortInfo[portID].featureStatus & feature) == 0) \ | |
231 | { \ | |
232 | return IX_ETH_DB_FEATURE_UNAVAILABLE; \ | |
233 | } | |
234 | ||
235 | /* busy retrying */ | |
236 | #define BUSY_RETRY(functionCall) \ | |
237 | { \ | |
238 | UINT32 retries = 0; \ | |
239 | IxEthDBStatus br_result; \ | |
240 | \ | |
241 | while ((br_result = functionCall) == IX_ETH_DB_BUSY \ | |
242 | && BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \ | |
243 | \ | |
244 | if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (br_result == IX_ETH_DB_FAIL)) \ | |
245 | {\ | |
246 | ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY failed at %s:%d\n", __FILE__, __LINE__); \ | |
247 | }\ | |
248 | } | |
249 | ||
250 | #define BUSY_RETRY_WITH_RESULT(functionCall, brwr_result) \ | |
251 | { \ | |
252 | UINT32 retries = 0; \ | |
253 | \ | |
254 | while ((brwr_result = functionCall) == IX_ETH_DB_BUSY \ | |
255 | && BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \ | |
256 | \ | |
257 | if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (brwr_result == IX_ETH_DB_FAIL)) \ | |
258 | {\ | |
259 | ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY_WITH_RESULT failed at %s:%d\n", __FILE__, __LINE__); \ | |
260 | }\ | |
261 | } | |
262 | ||
263 | /* iterators */ | |
264 | #define IS_ITERATOR_VALID(iteratorPtr) ((iteratorPtr)->node != NULL) | |
265 | ||
266 | /* dependency port maps */ | |
267 | ||
268 | /* Warning: if port indexing starts from 1 replace (portID) with (portID - 1) in DEPENDENCY_MAP (and make sure IX_ETH_DB_NUMBER_OF_PORTS is big enough) */ | |
269 | ||
270 | /* gives an empty dependency map */ | |
271 | #define SET_EMPTY_DEPENDENCY_MAP(map) { int i = 0; for (; i < 32 ; i++) map[i] = 0; } | |
272 | ||
472d5460 | 273 | #define IS_EMPTY_DEPENDENCY_MAP(result, map) { int i = 0 ; result = true; for (; i < 32 ; i++) if (map[i] != 0) { result = false; break; }} |
ba94a1bb WD |
274 | |
275 | /** | |
276 | * gives a map consisting only of 'portID' | |
277 | */ | |
278 | #define SET_DEPENDENCY_MAP(map, portID) {SET_EMPTY_DEPENDENCY_MAP(map); map[portID >> 3] = 1 << (portID & 0x7);} | |
279 | ||
280 | /** | |
281 | * gives a map resulting from joining map1 and map2 | |
282 | */ | |
283 | #define JOIN_MAPS(map, map1, map2) { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] | map2[i]; } | |
284 | ||
285 | /** | |
286 | * gives the map resulting from joining portID and map | |
287 | */ | |
288 | #define JOIN_PORT_TO_MAP(map, portID) { map[portID >> 3] |= 1 << (portID & 0x7); } | |
289 | ||
290 | /** | |
291 | * gives the map resulting from excluding portID from map | |
292 | */ | |
293 | #define EXCLUDE_PORT_FROM_MAP(map, portID) { map[portID >> 3] &= ~(1 << (portID & 0x7); } | |
294 | ||
295 | /** | |
472d5460 | 296 | * returns true if map1 is a subset of map2 and false otherwise |
ba94a1bb | 297 | */ |
472d5460 | 298 | #define IS_MAP_SUBSET(result, map1, map2) { int i = 0; result = true; for (; i < 32 ; i++) if ((map1[i] | map2[i]) != map2[i]) result = false; } |
ba94a1bb WD |
299 | |
300 | /** | |
472d5460 | 301 | * returns true is portID is part of map and false otherwise |
ba94a1bb WD |
302 | */ |
303 | #define IS_PORT_INCLUDED(portID, map) ((map[portID >> 3] & (1 << (portID & 0x7))) != 0) | |
304 | ||
305 | /** | |
306 | * returns the difference between map1 and map2 (ports included in map1 and not included in map2) | |
307 | */ | |
308 | #define DIFF_MAPS(map, map1, map2) { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] ^ (map1[i] & map2[i]); } | |
309 | ||
310 | /** | |
472d5460 | 311 | * returns true if the maps collide (have at least one port in common) and false otherwise |
ba94a1bb | 312 | */ |
472d5460 | 313 | #define MAPS_COLLIDE(result, map1, map2) { int i = 0; result = false; for (; i < 32 ; i++) if ((map1[i] & map2[i]) != 0) result = true; } |
ba94a1bb WD |
314 | |
315 | /* size (number of ports) of a dependency map */ | |
316 | #define GET_MAP_SIZE(map, size) { int i = 0, b = 0; size = 0; for (; i < 32 ; i++) { char y = map[i]; for (; b < 8 && (y >>= 1); b++) size += (y & 1); }} | |
317 | ||
318 | /* copy map2 into map1 */ | |
319 | #define COPY_DEPENDENCY_MAP(map1, map2) { memcpy (map1, map2, sizeof (map1)); } | |
320 | ||
321 | /* definition of a port map size/port number which cannot be reached (we support at most 32 ports) */ | |
322 | #define MAX_PORT_SIZE (0xFF) | |
323 | #define MAX_PORT_NUMBER (0xFF) | |
324 | ||
325 | #define IX_ETH_DB_CHECK_REFERENCE(ptr) { if ((ptr) == NULL) { return IX_ETH_DB_INVALID_ARG; } } | |
326 | #define IX_ETH_DB_CHECK_MAP(portID, map) { if (!IS_PORT_INCLUDED(portID, map)) { return IX_ETH_DB_INVALID_ARG; } } | |
327 | ||
328 | /* event queue macros */ | |
329 | #define EVENT_QUEUE_WRAP(offset) ((offset) >= EVENT_QUEUE_SIZE ? (offset) - EVENT_QUEUE_SIZE : (offset)) | |
330 | ||
331 | #define CAN_ENQUEUE(eventQueuePtr) ((eventQueuePtr)->length < EVENT_QUEUE_SIZE) | |
332 | ||
333 | #define QUEUE_HEAD(eventQueuePtr) (&(eventQueuePtr)->queue[EVENT_QUEUE_WRAP((eventQueuePtr)->base + (eventQueuePtr)->length)]) | |
334 | ||
335 | #define QUEUE_TAIL(eventQueuePtr) (&(eventQueuePtr)->queue[(eventQueuePtr)->base]) | |
336 | ||
337 | #define PUSH_UPDATE_QUEUE(eventQueuePtr) { (eventQueuePtr)->length++; } | |
338 | ||
339 | #define SHIFT_UPDATE_QUEUE(eventQueuePtr) \ | |
340 | { \ | |
341 | (eventQueuePtr)->base = EVENT_QUEUE_WRAP((eventQueuePtr)->base + 1); \ | |
342 | (eventQueuePtr)->length--; \ | |
343 | } | |
344 | ||
345 | #define RESET_QUEUE(eventQueuePtr) \ | |
346 | { \ | |
347 | (eventQueuePtr)->base = 0; \ | |
348 | (eventQueuePtr)->length = 0; \ | |
349 | } | |
350 | ||
351 | /* node stack macros - used to browse a tree without using a recursive function */ | |
352 | #define NODE_STACK_INIT(stack) { (stack)->nodeCount = 0; } | |
353 | #define NODE_STACK_PUSH(stack, node, offset) { (stack)->nodes[(stack)->nodeCount] = (node); (stack)->offsets[(stack)->nodeCount++] = (offset); } | |
354 | #define NODE_STACK_POP(stack, node, offset) { (node) = (stack)->nodes[--(stack)->nodeCount]; offset = (stack)->offsets[(stack)->nodeCount]; } | |
355 | #define NODE_STACK_NONEMPTY(stack) ((stack)->nodeCount != 0) | |
356 | ||
357 | #ifndef IX_NDEBUG | |
358 | #define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100) | |
359 | #define LOG_NPE_MSG(msg) \ | |
360 | do { \ | |
361 | UINT32 npeMsgHistoryIndex = (npeMsgHistoryLen++) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH; \ | |
362 | npeMsgHistory[npeMsgHistoryIndex][0] = msg.data[0]; \ | |
363 | npeMsgHistory[npeMsgHistoryIndex][1] = msg.data[1]; \ | |
364 | } while (0); | |
365 | #else | |
366 | #define LOG_NPE_MSG() /* nothing */ | |
367 | #endif | |
368 | ||
369 | /* ----------- Data -------------- */ | |
370 | ||
371 | /* typedefs */ | |
372 | ||
373 | typedef UINT32 (*HashFunction)(void *entity); | |
374 | typedef BOOL (*MatchFunction)(void *reference, void *entry); | |
375 | typedef void (*FreeFunction)(void *entry); | |
376 | ||
377 | /** | |
378 | * basic component of a hash table | |
379 | */ | |
380 | typedef struct HashNode_t | |
381 | { | |
382 | void *data; /**< specific data */ | |
383 | struct HashNode_t *next; /**< used for bucket chaining */ | |
384 | ||
385 | __mempool__ struct HashNode_t *nextFree; /**< memory pool management */ | |
386 | ||
387 | __lock__ IxOsalFastMutex lock; /**< node lock */ | |
388 | } HashNode; | |
389 | ||
390 | /** | |
391 | * @brief hash table iterator definition | |
392 | * | |
393 | * an iterator is an object which can be used | |
394 | * to browse a hash table | |
395 | */ | |
396 | typedef struct | |
397 | { | |
398 | UINT32 bucketIndex; /**< index of the currently iterated bucket */ | |
399 | HashNode *previousNode; /**< reference to the previously iterated node within the current bucket */ | |
400 | HashNode *node; /**< reference to the currently iterated node */ | |
401 | } HashIterator; | |
402 | ||
403 | /** | |
404 | * definition of a MAC descriptor (a database record) | |
405 | */ | |
406 | ||
407 | typedef enum | |
408 | { | |
409 | IX_ETH_DB_WIFI_AP_TO_STA = 0x0, | |
410 | IX_ETH_DB_WIFI_AP_TO_AP = 0x1 | |
411 | } IxEthDBWiFiRecordType; | |
412 | ||
413 | typedef union | |
414 | { | |
415 | struct | |
416 | { | |
417 | UINT32 age; | |
472d5460 | 418 | BOOL staticEntry; /**< true if this address is static (doesn't age) */ |
ba94a1bb WD |
419 | } filteringData; |
420 | ||
421 | struct | |
422 | { | |
423 | UINT32 age; | |
424 | BOOL staticEntry; | |
425 | UINT32 ieee802_1qTag; | |
426 | } filteringVlanData; | |
427 | ||
428 | struct | |
429 | { | |
430 | IxEthDBWiFiRecordType type; /**< AP_TO_AP (0x1) or AP_TO_STA (0x0) */ | |
431 | UINT32 gwAddressIndex; /**< used only when linearizing the entries for NPE usage */ | |
432 | UINT8 gwMacAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; | |
433 | ||
434 | __alignment__ UINT8 reserved2[2]; | |
435 | } wifiData; | |
436 | } IxEthDBRecordData; | |
437 | ||
438 | typedef struct MacDescriptor_t | |
439 | { | |
440 | UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; | |
441 | ||
442 | __alignment__ UINT8 reserved1[2]; | |
443 | ||
444 | UINT32 portID; | |
445 | IxEthDBRecordType type; | |
446 | IxEthDBRecordData recordData; | |
447 | ||
448 | /* used for internal operations, such as NPE linearization */ | |
449 | void *internal; | |
450 | ||
451 | /* custom user data */ | |
452 | void *user; | |
453 | ||
454 | __mempool__ struct MacDescriptor_t *nextFree; /**< memory pool management */ | |
455 | __smartpointer__ UINT32 refCount; /**< smart pointer reference counter */ | |
456 | } MacDescriptor; | |
457 | ||
458 | /** | |
459 | * hash table definition | |
460 | */ | |
461 | typedef struct | |
462 | { | |
463 | HashNode *hashBuckets[NUM_BUCKETS]; | |
464 | UINT32 numBuckets; | |
465 | ||
466 | __lock__ IxOsalFastMutex bucketLocks[NUM_BUCKETS]; | |
467 | ||
468 | HashFunction entryHashFunction; | |
469 | MatchFunction *matchFunctions; | |
470 | FreeFunction freeFunction; | |
471 | } HashTable; | |
472 | ||
473 | typedef enum | |
474 | { | |
475 | IX_ETH_DB_MAC_KEY = 1, | |
476 | IX_ETH_DB_MAC_PORT_KEY = 2, | |
477 | IX_ETH_DB_MAC_VLAN_KEY = 3, | |
478 | IX_ETH_DB_MAX_KEY_INDEX = 3 | |
479 | } IxEthDBSearchKeyType; | |
480 | ||
481 | typedef struct MacTreeNode_t | |
482 | { | |
483 | __smartpointer__ MacDescriptor *descriptor; | |
484 | struct MacTreeNode_t *left, *right; | |
485 | ||
486 | __mempool__ struct MacTreeNode_t *nextFree; | |
487 | } MacTreeNode; | |
488 | ||
489 | typedef IxEthDBStatus (*IxEthDBPortUpdateHandler)(IxEthDBPortId portID, IxEthDBRecordType type); | |
490 | ||
491 | typedef void (*IxEthDBNoteWriteFn)(void *address, MacTreeNode *node); | |
492 | ||
493 | typedef struct | |
494 | { | |
472d5460 YS |
495 | BOOL updateEnabled; /**< true if updates are enabled for port */ |
496 | BOOL userControlled; /**< true if the user has manually used ixEthDBPortUpdateEnableSet */ | |
497 | BOOL treeInitialized; /**< true if the NPE has received an initial tree */ | |
ba94a1bb WD |
498 | IxEthDBPortUpdateHandler updateHandler; /**< port update handler routine */ |
499 | void *npeUpdateZone; /**< port update memory zone */ | |
500 | void *npeGwUpdateZone; /**< port update memory zone for gateways */ | |
501 | void *vlanUpdateZone; /**< port update memory zone for VLAN tables */ | |
502 | MacTreeNode *searchTree; /**< internal search tree, in MacTreeNode representation */ | |
472d5460 | 503 | BOOL searchTreePendingWrite; /**< true if searchTree holds a tree pending write to the port */ |
ba94a1bb WD |
504 | } PortUpdateMethod; |
505 | ||
506 | typedef struct | |
507 | { | |
508 | IxEthDBPortId portID; /**< port ID */ | |
472d5460 YS |
509 | BOOL enabled; /**< true if the port is enabled */ |
510 | BOOL agingEnabled; /**< true if aging on this port is enabled */ | |
ba94a1bb WD |
511 | BOOL initialized; |
512 | IxEthDBPortMap dependencyPortMap; /**< dependency port map for this port */ | |
513 | PortUpdateMethod updateMethod; /**< update method structure */ | |
472d5460 | 514 | BOOL macAddressUploaded; /**< true if the MAC address was uploaded into the port */ |
ba94a1bb WD |
515 | UINT32 maxRxFrameSize; /**< maximum Rx frame size for this port */ |
516 | UINT32 maxTxFrameSize; /**< maximum Rx frame size for this port */ | |
517 | ||
518 | UINT8 bbsid[6]; | |
519 | __alignment__ UINT8 reserved[2]; | |
520 | UINT32 frameControlDurationID; /**< Frame Control - Duration/ID WiFi control */ | |
521 | ||
522 | IxEthDBVlanTag vlanTag; /**< default VLAN tag for port */ | |
523 | IxEthDBPriorityTable priorityTable; /**< QoS <=> internal priority mapping */ | |
524 | IxEthDBVlanSet vlanMembership; | |
525 | IxEthDBVlanSet transmitTaggingInfo; | |
526 | IxEthDBFrameFilter frameFilter; | |
527 | IxEthDBTaggingAction taggingAction; | |
528 | ||
529 | UINT32 npeFrameFilter; | |
530 | UINT32 npeTaggingAction; | |
531 | ||
532 | IxEthDBFirewallMode firewallMode; | |
533 | BOOL srcAddressFilterEnabled; | |
534 | ||
535 | BOOL stpBlocked; | |
536 | ||
537 | IxEthDBFeature featureCapability; | |
538 | IxEthDBFeature featureStatus; | |
539 | ||
540 | UINT32 ixEthDBTrafficClassAQMAssignments[IX_IEEE802_1Q_QOS_PRIORITY_COUNT]; | |
541 | ||
542 | UINT32 ixEthDBTrafficClassCount; | |
543 | ||
544 | UINT32 ixEthDBTrafficClassAvailable; | |
545 | ||
546 | ||
547 | ||
548 | __lock__ IxOsalMutex npeAckLock; | |
549 | } PortInfo; | |
550 | ||
551 | /* list of port information structures indexed on port Ids */ | |
552 | extern IX_ETH_DB_PUBLIC PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS]; | |
553 | ||
554 | typedef enum | |
555 | { | |
556 | IX_ETH_DB_ADD_FILTERING_RECORD = 0xFF0001, | |
557 | IX_ETH_DB_REMOVE_FILTERING_RECORD = 0xFF0002 | |
558 | } PortEventType; | |
559 | ||
560 | typedef struct | |
561 | { | |
562 | UINT32 eventType; | |
563 | IxEthDBPortId portID; | |
564 | IxEthDBMacAddr macAddr; | |
565 | BOOL staticEntry; | |
566 | } PortEvent; | |
567 | ||
568 | typedef struct | |
569 | { | |
570 | PortEvent queue[EVENT_QUEUE_SIZE]; | |
571 | UINT32 base; | |
572 | UINT32 length; | |
573 | } PortEventQueue; | |
574 | ||
575 | typedef struct | |
576 | { | |
577 | IxEthDBPortId portID; /**< originating port */ | |
578 | MacDescriptor *macDescriptors[MAX_ELT_SIZE]; /**< addresses to be synced into db */ | |
579 | UINT32 addressCount; /**< number of addresses */ | |
580 | } TreeSyncInfo; | |
581 | ||
582 | typedef struct | |
583 | { | |
584 | MacTreeNode *nodes[MAX_ELT_SIZE]; | |
585 | UINT32 offsets[MAX_ELT_SIZE]; | |
586 | UINT32 nodeCount; | |
587 | } MacTreeNodeStack; | |
588 | ||
589 | /* Prototypes */ | |
590 | ||
591 | /* ----------- Memory management -------------- */ | |
592 | ||
593 | IX_ETH_DB_PUBLIC void ixEthDBInitMemoryPools(void); | |
594 | ||
595 | IX_ETH_DB_PUBLIC HashNode* ixEthDBAllocHashNode(void); | |
596 | IX_ETH_DB_PUBLIC void ixEthDBFreeHashNode(HashNode *); | |
597 | ||
598 | IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBAllocMacDescriptor(void); | |
599 | IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor); | |
600 | IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacDescriptor(MacDescriptor *); | |
601 | ||
602 | IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBAllocMacTreeNode(void); | |
603 | IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *); | |
604 | IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacTreeNode(MacTreeNode *); | |
605 | ||
606 | IX_ETH_DB_PUBLIC void ixEthDBPoolFreeMacTreeNode(MacTreeNode *); | |
607 | IX_ETH_DB_PUBLIC UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree); | |
608 | IX_ETH_DB_PUBLIC int ixEthDBShowMemoryStatus(void); | |
609 | ||
610 | /* Hash Table */ | |
611 | IX_ETH_DB_PUBLIC void ixEthDBInitHash(HashTable *hashTable, UINT32 numBuckets, HashFunction entryHashFunction, MatchFunction *matchFunctions, FreeFunction freeFunction); | |
612 | ||
613 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry); | |
614 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference); | |
615 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult); | |
616 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference); | |
617 | IX_ETH_DB_PUBLIC void ixEthDBReleaseHashNode(HashNode *node); | |
618 | ||
619 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator); | |
620 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator); | |
621 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator); | |
622 | IX_ETH_DB_PUBLIC void ixEthDBReleaseHashIterator(HashIterator *iterator); | |
623 | ||
624 | /* API Support */ | |
625 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); | |
626 | IX_ETH_DB_PUBLIC void ixEthDBMaximumFrameSizeAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); | |
627 | ||
628 | /* DB Core functions */ | |
629 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInit(void); | |
630 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger); | |
631 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger); | |
632 | IX_ETH_DB_PUBLIC HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter); | |
633 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter); | |
634 | ||
635 | /* Learning support */ | |
636 | IX_ETH_DB_PUBLIC UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2); | |
637 | IX_ETH_DB_PUBLIC BOOL ixEthDBAddressMatch(void *reference, void *entry); | |
638 | IX_ETH_DB_PUBLIC UINT32 ixEthDBEntryXORHash(void *macDescriptor); | |
639 | IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyXORHash(void *macAddress); | |
640 | ||
641 | /* Port updates */ | |
642 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type); | |
643 | IX_ETH_DB_PUBLIC void ixEthDBUpdatePortLearningTrees(IxEthDBPortMap triggerPorts); | |
644 | IX_ETH_DB_PUBLIC void ixEthDBNPEAccessRequest(IxEthDBPortId portID); | |
645 | IX_ETH_DB_PUBLIC void ixEthDBUpdateLock(void); | |
646 | IX_ETH_DB_PUBLIC void ixEthDBUpdateUnlock(void); | |
647 | IX_ETH_DB_PUBLIC MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maximumEntries); | |
648 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta); | |
649 | ||
650 | /* Init/unload */ | |
651 | IX_ETH_DB_PUBLIC void ixEthDBPortSetAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); | |
652 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBEventProcessorInit(void); | |
653 | IX_ETH_DB_PUBLIC void ixEthDBPortInit(IxEthDBPortId portID); | |
654 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID); | |
655 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID); | |
656 | IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasInit(void); | |
657 | IX_ETH_DB_PUBLIC UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions); | |
658 | IX_ETH_DB_PUBLIC UINT32 ixEthDBRecordSerializeMethodsRegister(void); | |
659 | IX_ETH_DB_PUBLIC UINT32 ixEthDBUpdateTypeRegister(BOOL *typeArray); | |
660 | IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasUnload(void); | |
661 | IX_ETH_DB_PUBLIC void ixEthDBFeatureCapabilityScan(void); | |
662 | IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType); | |
663 | ||
664 | /* Event processing */ | |
665 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDefaultEventCallbackEnable(IxEthDBPortId portID, BOOL enable); | |
666 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry); | |
667 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID); | |
668 | IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); | |
669 | ||
670 | /* NPE adaptor */ | |
671 | IX_ETH_DB_PUBLIC void ixEthDBGetMacDatabaseCbk(IxNpeMhNpeId npeID, IxNpeMhMessage msg); | |
672 | IX_ETH_DB_PUBLIC void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg); | |
673 | IX_ETH_DB_PUBLIC void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize); | |
674 | IX_ETH_DB_PUBLIC void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *blocks, UINT32 *startIndex); | |
675 | IX_ETH_DB_PUBLIC void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node); | |
676 | ||
677 | /* Other public API functions */ | |
678 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void); | |
679 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void); | |
680 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate); | |
681 | ||
682 | /* Maximum Tx/Rx public functions */ | |
683 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize); | |
684 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize); | |
685 | ||
686 | /* VLAN-related */ | |
687 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet); | |
688 | ||
689 | /* Record search */ | |
690 | IX_ETH_DB_PUBLIC BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry); | |
691 | IX_ETH_DB_PUBLIC BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry); | |
692 | IX_ETH_DB_PUBLIC BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry); | |
693 | IX_ETH_DB_PUBLIC BOOL ixEthDBNullMatch(void *reference, void *entry); | |
694 | IX_ETH_DB_PUBLIC HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter); | |
695 | IX_ETH_DB_PUBLIC HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter); | |
696 | ||
697 | /* Utilities */ | |
698 | IX_ETH_DB_PUBLIC const char* mac2string(const unsigned char *mac); | |
699 | IX_ETH_DB_PUBLIC void showHashInfo(void); | |
700 | IX_ETH_DB_PUBLIC int ixEthDBAnalyzeHash(void); | |
701 | IX_ETH_DB_PUBLIC const char* errorString(IxEthDBStatus error); | |
702 | IX_ETH_DB_PUBLIC int numHashElements(void); | |
703 | IX_ETH_DB_PUBLIC void zapHashtable(void); | |
704 | IX_ETH_DB_PUBLIC BOOL ixEthDBCheckSingleBitValue(UINT32 value); | |
705 | ||
706 | /* Single Eth NPE Check */ | |
707 | IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portId); | |
708 | ||
709 | #endif /* IxEthDB_p_H */ | |
710 |