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