IxEthDBNPEAdaptor.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. /**
  2. * @file IxEthDBDBNPEAdaptor.c
  3. *
  4. * @brief Routines that read and write learning/search trees in NPE-specific format
  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. * SPDX-License-Identifier: BSD-3-Clause
  17. * @par
  18. * -- End of Copyright Notice --
  19. */
  20. #include "IxEthDB_p.h"
  21. #include "IxEthDBLog_p.h"
  22. /* forward prototype declarations */
  23. IX_ETH_DB_PUBLIC void ixEthDBELTShow(IxEthDBPortId portID);
  24. IX_ETH_DB_PUBLIC void ixEthDBShowNpeMsgHistory(void);
  25. /* data */
  26. UINT8* ixEthDBNPEUpdateArea[IX_ETH_DB_NUMBER_OF_PORTS];
  27. UINT32 dumpEltSize;
  28. /* private data */
  29. IX_ETH_DB_PRIVATE IxEthDBNoteWriteFn ixEthDBNPENodeWrite[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
  30. #define IX_ETH_DB_MAX_DELTA_ZONES (6) /* at most 6 EP Delta zones, according to NPE FS */
  31. IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDeltaOffset[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES];
  32. IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDelta[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES];
  33. /**
  34. * @brief allocates non-cached or contiguous NPE tree update areas for all the ports
  35. *
  36. * This function is called only once at initialization time from
  37. * @ref ixEthDBInit().
  38. *
  39. * @warning do not call manually
  40. *
  41. * @see ixEthDBInit()
  42. *
  43. * @internal
  44. */
  45. IX_ETH_DB_PUBLIC
  46. void ixEthDBNPEUpdateAreasInit(void)
  47. {
  48. UINT32 portIndex;
  49. PortUpdateMethod *update;
  50. for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
  51. {
  52. update = &ixEthDBPortInfo[portIndex].updateMethod;
  53. if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
  54. {
  55. update->npeUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_ELT_BYTE_SIZE);
  56. update->npeGwUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_GW_BYTE_SIZE);
  57. update->vlanUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_VLAN_BYTE_SIZE);
  58. if (update->npeUpdateZone == NULL
  59. || update->npeGwUpdateZone == NULL
  60. || update->vlanUpdateZone == NULL)
  61. {
  62. ERROR_LOG("Fatal error: IX_ACC_DRV_DMA_MALLOC() returned NULL, no NPE update zones available\n");
  63. }
  64. else
  65. {
  66. memset(update->npeUpdateZone, 0, FULL_ELT_BYTE_SIZE);
  67. memset(update->npeGwUpdateZone, 0, FULL_GW_BYTE_SIZE);
  68. memset(update->vlanUpdateZone, 0, FULL_VLAN_BYTE_SIZE);
  69. }
  70. }
  71. else
  72. {
  73. /* unused */
  74. update->npeUpdateZone = NULL;
  75. update->npeGwUpdateZone = NULL;
  76. update->vlanUpdateZone = NULL;
  77. }
  78. }
  79. }
  80. /**
  81. * @brief deallocates the NPE update areas for all the ports
  82. *
  83. * This function is called at component de-initialization time
  84. * by @ref ixEthDBUnload().
  85. *
  86. * @warning do not call manually
  87. *
  88. * @internal
  89. */
  90. IX_ETH_DB_PUBLIC
  91. void ixEthDBNPEUpdateAreasUnload(void)
  92. {
  93. UINT32 portIndex;
  94. for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
  95. {
  96. if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
  97. {
  98. IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone);
  99. IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.npeGwUpdateZone);
  100. IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.vlanUpdateZone);
  101. }
  102. }
  103. }
  104. /**
  105. * @brief general-purpose NPE callback function
  106. *
  107. * @param npeID NPE ID
  108. * @param msg NPE message
  109. *
  110. * This function will unblock the caller by unlocking
  111. * the npeAckLock mutex defined for each NPE port
  112. *
  113. * @internal
  114. */
  115. IX_ETH_DB_PUBLIC
  116. void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg)
  117. {
  118. IxEthDBPortId portID = IX_ETH_DB_NPE_TO_PORT_ID(npeID);
  119. PortInfo *portInfo;
  120. if (portID >= IX_ETH_DB_NUMBER_OF_PORTS)
  121. {
  122. /* invalid port */
  123. return;
  124. }
  125. if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE)
  126. {
  127. /* not an NPE */
  128. return;
  129. }
  130. portInfo = &ixEthDBPortInfo[portID];
  131. ixOsalMutexUnlock(&portInfo->npeAckLock);
  132. }
  133. /**
  134. * @brief synchronizes the database with tree
  135. *
  136. * @param portID port ID of the NPE whose tree is to be scanned
  137. * @param eltBaseAddress memory base address of the NPE serialized tree
  138. * @param eltSize size in bytes of the NPE serialized tree
  139. *
  140. * Scans the NPE learning tree and resets the age of active database records.
  141. *
  142. * @internal
  143. */
  144. IX_ETH_DB_PUBLIC
  145. void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize)
  146. {
  147. UINT32 eltEntryOffset;
  148. UINT32 entryPortID;
  149. /* invalidate cache */
  150. IX_OSAL_CACHE_INVALIDATE(eltBaseAddress, eltSize);
  151. for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE)
  152. {
  153. /* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node
  154. *
  155. * the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit]
  156. * therefore we can just use the pointer for database searches as only the first 6 bytes are checked
  157. */
  158. void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset);
  159. /* debug */
  160. IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) checking node at offset %d...\n", eltEntryOffset / ELT_ENTRY_SIZE);
  161. if (IX_EDB_NPE_NODE_VALID(eltNodeAddress) != true)
  162. {
  163. IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is empty\n");
  164. }
  165. else if (eltEntryOffset == ELT_ROOT_OFFSET)
  166. {
  167. IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is root\n");
  168. }
  169. if (IX_EDB_NPE_NODE_VALID(eltNodeAddress))
  170. {
  171. entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress));
  172. /* check only active entries belonging to this port */
  173. if (ixEthDBPortInfo[portID].agingEnabled && IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) && (portID == entryPortID)
  174. && ((ixEthDBPortDefinitions[portID].capabilities & IX_ETH_ENTRY_AGING) == 0))
  175. {
  176. /* search record */
  177. HashNode *node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_FILTERING_RECORDS);
  178. /* safety check, maybe user deleted record right before sync? */
  179. if (node != NULL)
  180. {
  181. /* found record */
  182. MacDescriptor *descriptor = (MacDescriptor *) node->data;
  183. IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) synced entry [%s] already in the database, updating fields\n", mac2string(eltNodeAddress));
  184. /* reset age - set to -1 so that maintenance will restore it to 0 (or more) when incrementing */
  185. if (!descriptor->recordData.filteringData.staticEntry)
  186. {
  187. if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
  188. {
  189. descriptor->recordData.filteringData.age = AGE_RESET;
  190. }
  191. else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
  192. {
  193. descriptor->recordData.filteringVlanData.age = AGE_RESET;
  194. }
  195. }
  196. /* end transaction */
  197. ixEthDBReleaseHashNode(node);
  198. }
  199. }
  200. else
  201. {
  202. IX_ETH_DB_NPE_VERBOSE_TRACE("\t... found portID %d, we check only port %d\n", entryPortID, portID);
  203. }
  204. }
  205. }
  206. }
  207. /**
  208. * @brief writes a search tree in NPE format
  209. *
  210. * @param type type of records to be written into the NPE update zone
  211. * @param totalSize maximum size of the linearized tree
  212. * @param baseAddress memory base address where to write the NPE tree into
  213. * @param tree search tree to write in NPE format
  214. * @param blocks number of written 64-byte blocks
  215. * @param startIndex optimal binary search start index
  216. *
  217. * Serializes the given tree in NPE linear format
  218. *
  219. * @return none
  220. *
  221. * @internal
  222. */
  223. IX_ETH_DB_PUBLIC
  224. void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *epDelta, UINT32 *blocks)
  225. {
  226. MacTreeNodeStack *stack;
  227. UINT32 maxOffset = 0;
  228. UINT32 emptyOffset;
  229. stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack));
  230. if (stack == NULL)
  231. {
  232. ERROR_LOG("DB: (NPEAdaptor) failed to allocate the node stack for learning tree linearization, out of memory?\n");
  233. return;
  234. }
  235. /* zero out empty root */
  236. memset(baseAddress, 0, ELT_ENTRY_SIZE);
  237. NODE_STACK_INIT(stack);
  238. if (tree != NULL)
  239. {
  240. /* push tree root at offset 1 */
  241. NODE_STACK_PUSH(stack, tree, 1);
  242. maxOffset = 1;
  243. }
  244. while (NODE_STACK_NONEMPTY(stack))
  245. {
  246. MacTreeNode *node;
  247. UINT32 offset;
  248. NODE_STACK_POP(stack, node, offset);
  249. /* update maximum offset */
  250. if (offset > maxOffset)
  251. {
  252. maxOffset = offset;
  253. }
  254. IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) writing MAC [%s] at offset %d\n", mac2string(node->descriptor->macAddress), offset);
  255. /* add node to NPE ELT at position indicated by offset */
  256. if (offset < MAX_ELT_SIZE)
  257. {
  258. ixEthDBNPENodeWrite[type]((void *) (((UINT32) baseAddress) + offset * ELT_ENTRY_SIZE), node);
  259. }
  260. if (node->left != NULL)
  261. {
  262. NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset));
  263. }
  264. else
  265. {
  266. /* ensure this entry is zeroed */
  267. memset((void *) ((UINT32) baseAddress + LEFT_CHILD_OFFSET(offset) * ELT_ENTRY_SIZE), 0, ELT_ENTRY_SIZE);
  268. }
  269. if (node->right != NULL)
  270. {
  271. NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset));
  272. }
  273. else
  274. {
  275. /* ensure this entry is zeroed */
  276. memset((void *) ((UINT32) baseAddress + RIGHT_CHILD_OFFSET(offset) * ELT_ENTRY_SIZE), 0, ELT_ENTRY_SIZE);
  277. }
  278. }
  279. emptyOffset = maxOffset + 1;
  280. /* zero out rest of the tree */
  281. IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Emptying tree from offset %d, address 0x%08X, %d bytes\n",
  282. emptyOffset, ((UINT32) baseAddress) + emptyOffset * ELT_ENTRY_SIZE, totalSize - (emptyOffset * ELT_ENTRY_SIZE));
  283. if (emptyOffset < MAX_ELT_SIZE - 1)
  284. {
  285. memset((void *) (((UINT32) baseAddress) + (emptyOffset * ELT_ENTRY_SIZE)), 0, totalSize - (emptyOffset * ELT_ENTRY_SIZE));
  286. }
  287. /* flush cache */
  288. IX_OSAL_CACHE_FLUSH(baseAddress, totalSize);
  289. /* debug */
  290. IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Ethernet learning/filtering tree XScale wrote at address 0x%08X (max %d bytes):\n\n",
  291. (UINT32) baseAddress, FULL_ELT_BYTE_SIZE);
  292. IX_ETH_DB_NPE_DUMP_ELT(baseAddress, FULL_ELT_BYTE_SIZE);
  293. /* compute number of 64-byte blocks */
  294. if (blocks != NULL)
  295. {
  296. *blocks = maxOffset != 0 ? 1 + maxOffset / 8 : 0;
  297. IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Wrote %d 64-byte blocks\n", *blocks);
  298. }
  299. /* compute epDelta - start index for binary search */
  300. if (epDelta != NULL)
  301. {
  302. UINT32 deltaIndex = 0;
  303. *epDelta = 0;
  304. for (; deltaIndex < IX_ETH_DB_MAX_DELTA_ZONES ; deltaIndex ++)
  305. {
  306. if (ixEthDBEPDeltaOffset[type][deltaIndex] >= maxOffset)
  307. {
  308. *epDelta = ixEthDBEPDelta[type][deltaIndex];
  309. break;
  310. }
  311. }
  312. IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Computed epDelta %d (based on maxOffset %d)\n", *epDelta, maxOffset);
  313. }
  314. ixOsalCacheDmaFree(stack);
  315. }
  316. /**
  317. * @brief implements a dummy node serialization function
  318. *
  319. * @param address address of where the node is to be serialized (unused)
  320. * @param node tree node to be serialized (unused)
  321. *
  322. * This function is registered for safety reasons and should
  323. * never be called. It will display an error message if this
  324. * function is called.
  325. *
  326. * @return none
  327. *
  328. * @internal
  329. */
  330. IX_ETH_DB_PRIVATE
  331. void ixEthDBNullSerialize(void *address, MacTreeNode *node)
  332. {
  333. IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Warning, the NullSerialize function was called, wrong record type?\n");
  334. }
  335. /**
  336. * @brief writes a filtering entry in NPE linear format
  337. *
  338. * @param address memory address to write node to
  339. * @param node node to be written
  340. *
  341. * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
  342. * in NPE-readable format.
  343. *
  344. * @internal
  345. */
  346. IX_ETH_DB_PRIVATE
  347. void ixEthDBNPELearningNodeWrite(void *address, MacTreeNode *node)
  348. {
  349. /* copy mac address */
  350. memcpy(address, node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
  351. /* copy port ID */
  352. NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET) = IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(node->descriptor->portID);
  353. /* copy flags (valid and not active, as the NPE sets it to active) and clear reserved section (bits 2-7) */
  354. NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) = (UINT8) IX_EDB_FLAGS_INACTIVE_VALID;
  355. IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) writing ELT node 0x%08x:0x%08x\n", * (UINT32 *) address, * (((UINT32 *) (address)) + 1));
  356. }
  357. /**
  358. * @brief writes a WiFi header conversion record in
  359. * NPE linear format
  360. *
  361. * @param address memory address to write node to
  362. * @param node node to be written
  363. *
  364. * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
  365. * in NPE-readable format.
  366. *
  367. * @internal
  368. */
  369. IX_ETH_DB_PRIVATE
  370. void ixEthDBNPEWiFiNodeWrite(void *address, MacTreeNode *node)
  371. {
  372. /* copy mac address */
  373. memcpy(address, node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
  374. /* copy index */
  375. NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_WIFI_INDEX_OFFSET) = node->descriptor->recordData.wifiData.gwAddressIndex;
  376. /* copy flags (type and valid) */
  377. NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_WIFI_FLAGS_OFFSET) = node->descriptor->recordData.wifiData.type << 1 | IX_EDB_FLAGS_VALID;
  378. }
  379. /**
  380. * @brief writes a WiFi gateway header conversion record in
  381. * NPE linear format
  382. *
  383. * @param address memory address to write node to
  384. * @param node node to be written
  385. *
  386. * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
  387. * in NPE-readable format.
  388. *
  389. * @internal
  390. */
  391. IX_ETH_DB_PUBLIC
  392. void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node)
  393. {
  394. /* copy mac address */
  395. memcpy(address, node->descriptor->recordData.wifiData.gwMacAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
  396. /* set reserved field, two bytes */
  397. NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET) = 0;
  398. NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET + 1) = 0;
  399. }
  400. /**
  401. * @brief writes a firewall record in
  402. * NPE linear format
  403. *
  404. * @param address memory address to write node to
  405. * @param node node to be written
  406. *
  407. * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree
  408. * in NPE-readable format.
  409. *
  410. * @internal
  411. */
  412. IX_ETH_DB_PRIVATE
  413. void ixEthDBNPEFirewallNodeWrite(void *address, MacTreeNode *node)
  414. {
  415. /* set reserved field */
  416. NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET) = 0;
  417. /* set flags */
  418. NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_FLAGS_OFFSET) = IX_EDB_FLAGS_VALID;
  419. /* copy mac address */
  420. memcpy((void *) ((UINT32) address + IX_EDB_NPE_NODE_FW_ADDR_OFFSET), node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE);
  421. }
  422. /**
  423. * @brief registers the NPE serialization methods
  424. *
  425. * This functions registers NPE serialization methods
  426. * for writing the following types of records in NPE
  427. * readable linear format:
  428. * - filtering records
  429. * - WiFi header conversion records
  430. * - WiFi gateway header conversion records
  431. * - firewall records
  432. *
  433. * Note that this function should be called by the
  434. * component initialization function.
  435. *
  436. * @return number of registered record types
  437. *
  438. * @internal
  439. */
  440. IX_ETH_DB_PUBLIC
  441. UINT32 ixEthDBRecordSerializeMethodsRegister()
  442. {
  443. int i;
  444. /* safety - register a blank method for everybody first */
  445. for ( i = 0 ; i < IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1 ; i++)
  446. {
  447. ixEthDBNPENodeWrite[i] = ixEthDBNullSerialize;
  448. }
  449. /* register real methods */
  450. ixEthDBNPENodeWrite[IX_ETH_DB_FILTERING_RECORD] = ixEthDBNPELearningNodeWrite;
  451. ixEthDBNPENodeWrite[IX_ETH_DB_FILTERING_VLAN_RECORD] = ixEthDBNPELearningNodeWrite;
  452. ixEthDBNPENodeWrite[IX_ETH_DB_WIFI_RECORD] = ixEthDBNPEWiFiNodeWrite;
  453. ixEthDBNPENodeWrite[IX_ETH_DB_FIREWALL_RECORD] = ixEthDBNPEFirewallNodeWrite;
  454. ixEthDBNPENodeWrite[IX_ETH_DB_GATEWAY_RECORD] = ixEthDBNPEGatewayNodeWrite;
  455. /* EP Delta arrays */
  456. memset(ixEthDBEPDeltaOffset, 0, sizeof (ixEthDBEPDeltaOffset));
  457. memset(ixEthDBEPDelta, 0, sizeof (ixEthDBEPDelta));
  458. /* filtering records */
  459. ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][0] = 1;
  460. ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][0] = 0;
  461. ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][1] = 3;
  462. ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][1] = 7;
  463. ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][2] = 511;
  464. ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][2] = 14;
  465. /* wifi records */
  466. ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][0] = 1;
  467. ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][0] = 0;
  468. ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][1] = 3;
  469. ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][1] = 7;
  470. ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][2] = 511;
  471. ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][2] = 14;
  472. /* firewall records */
  473. ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][0] = 0;
  474. ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][0] = 0;
  475. ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][1] = 1;
  476. ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][1] = 5;
  477. ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][2] = 3;
  478. ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][2] = 13;
  479. ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][3] = 7;
  480. ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][3] = 21;
  481. ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][4] = 15;
  482. ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][4] = 29;
  483. ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][5] = 31;
  484. ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][5] = 37;
  485. return 5; /* 5 methods registered */
  486. }
  487. #ifndef IX_NDEBUG
  488. IX_ETH_DB_PUBLIC UINT32 npeMsgHistory[IX_ETH_DB_NPE_MSG_HISTORY_DEPTH][2];
  489. IX_ETH_DB_PUBLIC UINT32 npeMsgHistoryLen = 0;
  490. /**
  491. * When compiled in DEBUG mode, this function can be used to display
  492. * the history of messages sent to the NPEs (up to 100).
  493. */
  494. IX_ETH_DB_PUBLIC
  495. void ixEthDBShowNpeMsgHistory()
  496. {
  497. UINT32 i = 0;
  498. UINT32 base, len;
  499. if (npeMsgHistoryLen <= IX_ETH_DB_NPE_MSG_HISTORY_DEPTH)
  500. {
  501. base = 0;
  502. len = npeMsgHistoryLen;
  503. }
  504. else
  505. {
  506. base = npeMsgHistoryLen % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
  507. len = IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
  508. }
  509. printf("NPE message history [last %d messages, from least to most recent]:\n", len);
  510. for (; i < len ; i++)
  511. {
  512. UINT32 pos = (base + i) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH;
  513. printf("msg[%d]: 0x%08x:0x%08x\n", i, npeMsgHistory[pos][0], npeMsgHistory[pos][1]);
  514. }
  515. }
  516. IX_ETH_DB_PUBLIC
  517. void ixEthDBELTShow(IxEthDBPortId portID)
  518. {
  519. IxNpeMhMessage message;
  520. IX_STATUS result;
  521. /* send EDB_GetMACAddressDatabase message */
  522. FILL_GETMACADDRESSDATABASE(message,
  523. 0 /* reserved */,
  524. IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portID].updateMethod.npeUpdateZone));
  525. IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
  526. if (result == IX_SUCCESS)
  527. {
  528. /* analyze NPE copy */
  529. UINT32 eltEntryOffset;
  530. UINT32 entryPortID;
  531. UINT32 eltBaseAddress = (UINT32) ixEthDBPortInfo[portID].updateMethod.npeUpdateZone;
  532. UINT32 eltSize = FULL_ELT_BYTE_SIZE;
  533. /* invalidate cache */
  534. IX_OSAL_CACHE_INVALIDATE((void *) eltBaseAddress, eltSize);
  535. printf("Listing records in main learning tree for port %d\n", portID);
  536. for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE)
  537. {
  538. /* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node
  539. *
  540. * the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit]
  541. * therefore we can just use the pointer for database searches as only the first 6 bytes are checked
  542. */
  543. void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset);
  544. if (IX_EDB_NPE_NODE_VALID(eltNodeAddress))
  545. {
  546. HashNode *node;
  547. entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress));
  548. /* search record */
  549. node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_RECORD_TYPES);
  550. printf("%s - port %d - %s ", mac2string((unsigned char *) eltNodeAddress), entryPortID,
  551. IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) ? "active" : "inactive");
  552. /* safety check, maybe user deleted record right before sync? */
  553. if (node != NULL)
  554. {
  555. /* found record */
  556. MacDescriptor *descriptor = (MacDescriptor *) node->data;
  557. printf("- %s ",
  558. descriptor->type == IX_ETH_DB_FILTERING_RECORD ? "filtering" :
  559. descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD ? "vlan" :
  560. descriptor->type == IX_ETH_DB_WIFI_RECORD ? "wifi" : "other (check main DB)");
  561. if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) printf("- age %d - %s ",
  562. descriptor->recordData.filteringData.age,
  563. descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic");
  564. if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) printf("- age %d - %s - tci %d ",
  565. descriptor->recordData.filteringVlanData.age,
  566. descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic",
  567. descriptor->recordData.filteringVlanData.ieee802_1qTag);
  568. /* end transaction */
  569. ixEthDBReleaseHashNode(node);
  570. }
  571. else
  572. {
  573. printf("- not synced");
  574. }
  575. printf("\n");
  576. }
  577. }
  578. }
  579. else
  580. {
  581. ixOsalLog(IX_OSAL_LOG_LVL_FATAL, IX_OSAL_LOG_DEV_STDOUT,
  582. "EthDB: (ShowELT) Could not complete action (communication failure)\n",
  583. portID, 0, 0, 0, 0, 0);
  584. }
  585. }
  586. #endif