IxEthDBWiFi.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /**
  2. * @file IxEthDBAPI.c
  3. *
  4. * @brief Implementation of the public 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. * SPDX-License-Identifier: BSD-3-Clause
  17. * @par
  18. * -- End of Copyright Notice --
  19. */
  20. #include "IxEthDB_p.h"
  21. /* forward prototypes */
  22. IX_ETH_DB_PUBLIC
  23. MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations);
  24. /**
  25. * @brief sets the BBSID value for the WiFi header conversion feature
  26. *
  27. * @param portID ID of the port
  28. * @param bbsid pointer to the 6-byte BBSID value
  29. *
  30. * Note that this function is documented in the main component
  31. * header file, IxEthDB.h.
  32. *
  33. * @return IX_ETH_DB_SUCCESS if the operation completed successfully
  34. * or an appropriate error message otherwise
  35. */
  36. IX_ETH_DB_PUBLIC
  37. IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid)
  38. {
  39. IxNpeMhMessage message;
  40. IX_STATUS result;
  41. IX_ETH_DB_CHECK_PORT(portID);
  42. IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  43. IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
  44. IX_ETH_DB_CHECK_REFERENCE(bbsid);
  45. memcpy(ixEthDBPortInfo[portID].bbsid, bbsid, sizeof (IxEthDBMacAddr));
  46. FILL_SETBBSID_MSG(message, portID, bbsid);
  47. IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
  48. return result;
  49. }
  50. /**
  51. * @brief updates the Frame Control and Duration/ID WiFi header
  52. * conversion parameters in an NPE
  53. *
  54. * @param portID ID of the port
  55. *
  56. * This function will send a message to the NPE updating the
  57. * frame conversion parameters for 802.3 => 802.11 header conversion.
  58. *
  59. * @return IX_ETH_DB_SUCCESS if the operation completed successfully
  60. * or IX_ETH_DB_FAIL otherwise
  61. *
  62. * @internal
  63. */
  64. IX_ETH_DB_PRIVATE
  65. IxEthDBStatus ixEthDBWiFiFrameControlDurationIDUpdate(IxEthDBPortId portID)
  66. {
  67. IxNpeMhMessage message;
  68. IX_STATUS result;
  69. FILL_SETFRAMECONTROLDURATIONID(message, portID, ixEthDBPortInfo[portID].frameControlDurationID);
  70. IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
  71. return result;
  72. }
  73. /**
  74. * @brief sets the Duration/ID WiFi frame header conversion parameter
  75. *
  76. * @param portID ID of the port
  77. * @param durationID 16-bit value containing the new Duration/ID parameter
  78. *
  79. * Note that this function is documented in the main component
  80. * header file, IxEthDB.h.
  81. *
  82. * @return IX_ETH_DB_SUCCESS if the operation completed successfully
  83. * or an appropriate error message otherwise
  84. */
  85. IX_ETH_DB_PUBLIC
  86. IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID)
  87. {
  88. IX_ETH_DB_CHECK_PORT(portID);
  89. IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  90. IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
  91. ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF0000) | durationID;
  92. return ixEthDBWiFiFrameControlDurationIDUpdate(portID);
  93. }
  94. /**
  95. * @brief sets the Frame Control WiFi frame header conversion parameter
  96. *
  97. * @param portID ID of the port
  98. * @param durationID 16-bit value containing the new Frame Control parameter
  99. *
  100. * Note that this function is documented in the main component
  101. * header file, IxEthDB.h.
  102. *
  103. * @return IX_ETH_DB_SUCCESS if the operation completed successfully
  104. * or an appropriate error message otherwise
  105. */
  106. IX_ETH_DB_PUBLIC
  107. IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl)
  108. {
  109. IX_ETH_DB_CHECK_PORT(portID);
  110. IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  111. IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
  112. ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF) | (frameControl << 16);
  113. return ixEthDBWiFiFrameControlDurationIDUpdate(portID);
  114. }
  115. /**
  116. * @brief removes a WiFi header conversion record
  117. *
  118. * @param portID ID of the port
  119. * @param macAddr MAC address of the record to remove
  120. *
  121. * Note that this function is documented in the main
  122. * component header file, IxEthDB.h.
  123. *
  124. * @return IX_ETH_DB_SUCCESS if the operation completed
  125. * successfully or an appropriate error message otherwise
  126. */
  127. IX_ETH_DB_PUBLIC
  128. IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
  129. {
  130. MacDescriptor recordTemplate;
  131. IX_ETH_DB_CHECK_PORT(portID);
  132. IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  133. IX_ETH_DB_CHECK_REFERENCE(macAddr);
  134. IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
  135. memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
  136. recordTemplate.type = IX_ETH_DB_WIFI_RECORD;
  137. recordTemplate.portID = portID;
  138. return ixEthDBRemove(&recordTemplate, NULL);
  139. }
  140. /**
  141. * @brief adds a WiFi header conversion record
  142. *
  143. * @param portID ID of the port
  144. * @param macAddr MAC address of the record to add
  145. * @param gatewayMacAddr address of the gateway (or
  146. * NULL if this is a station record)
  147. *
  148. * This function adds a record of type AP_TO_AP (gateway is not NULL)
  149. * or AP_TO_STA (gateway is NULL) in the main database as a
  150. * WiFi header conversion record.
  151. *
  152. * @return IX_ETH_DB_SUCCESS if the operation completed
  153. * successfully or an appropriate error message otherwise
  154. *
  155. * @internal
  156. */
  157. IX_ETH_DB_PRIVATE
  158. IxEthDBStatus ixEthDBWiFiEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
  159. {
  160. MacDescriptor recordTemplate;
  161. IX_ETH_DB_CHECK_PORT(portID);
  162. IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  163. IX_ETH_DB_CHECK_REFERENCE(macAddr);
  164. IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
  165. memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr));
  166. recordTemplate.type = IX_ETH_DB_WIFI_RECORD;
  167. recordTemplate.portID = portID;
  168. if (gatewayMacAddr != NULL)
  169. {
  170. memcpy(recordTemplate.recordData.wifiData.gwMacAddress, gatewayMacAddr, sizeof (IxEthDBMacAddr));
  171. recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_AP;
  172. }
  173. else
  174. {
  175. memset(recordTemplate.recordData.wifiData.gwMacAddress, 0, sizeof (IxEthDBMacAddr));
  176. recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_STA;
  177. }
  178. return ixEthDBAdd(&recordTemplate, NULL);
  179. }
  180. /**
  181. * @brief adds a WiFi header conversion record
  182. *
  183. * @param portID ID of the port
  184. * @param macAddr MAC address of the record to add
  185. * @param gatewayMacAddr address of the gateway
  186. *
  187. * This function adds a record of type AP_TO_AP
  188. * in the main database as a WiFi header conversion record.
  189. *
  190. * This is simply a wrapper over @ref ixEthDBWiFiEntryAdd().
  191. *
  192. * Note that this function is documented in the main
  193. * component header file, IxEthDB.h.
  194. *
  195. * @return IX_ETH_DB_SUCCESS if the operation completed
  196. * successfully or an appropriate error message otherwise
  197. */
  198. IX_ETH_DB_PUBLIC
  199. IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr)
  200. {
  201. IX_ETH_DB_CHECK_REFERENCE(gatewayMacAddr);
  202. return ixEthDBWiFiEntryAdd(portID, macAddr, gatewayMacAddr);
  203. }
  204. /**
  205. * @brief adds a WiFi header conversion record
  206. *
  207. * @param portID ID of the port
  208. * @param macAddr MAC address of the record to add
  209. *
  210. * This function adds a record of type AP_TO_STA
  211. * in the main database as a WiFi header conversion record.
  212. *
  213. * This is simply a wrapper over @ref ixEthDBWiFiEntryAdd().
  214. *
  215. * Note that this function is documented in the main
  216. * component header file, IxEthDB.h.
  217. *
  218. * @return IX_ETH_DB_SUCCESS if the operation completed
  219. * successfully or an appropriate error message otherwise
  220. */
  221. IX_ETH_DB_PUBLIC
  222. IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
  223. {
  224. return ixEthDBWiFiEntryAdd(portID, macAddr, NULL);
  225. }
  226. /**
  227. * @brief selects a set of gateways from a tree of
  228. * WiFi header conversion records
  229. *
  230. * @param stations binary tree containing pointers to WiFi header
  231. * conversion records
  232. *
  233. * This function browses through the input binary tree, identifies
  234. * records of type AP_TO_AP, clones these records and appends them
  235. * to a vine (a single right-branch binary tree) which is returned
  236. * as result. A maximum of MAX_GW_SIZE entries containing gateways
  237. * will be cloned from the original tree.
  238. *
  239. * @return vine (linear binary tree) containing record
  240. * clones of AP_TO_AP type, which have a gateway field
  241. *
  242. * @internal
  243. */
  244. IX_ETH_DB_PUBLIC
  245. MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations)
  246. {
  247. MacTreeNodeStack *stack;
  248. MacTreeNode *gateways, *insertionPlace;
  249. UINT32 gwIndex = 1; /* skip the empty root */
  250. if (stations == NULL)
  251. {
  252. return NULL;
  253. }
  254. stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack));
  255. if (stack == NULL)
  256. {
  257. ERROR_LOG("DB: (WiFi) failed to allocate the node stack for gateway tree linearization, out of memory?\n");
  258. return NULL;
  259. }
  260. /* initialize root node */
  261. gateways = insertionPlace = NULL;
  262. /* start browsing the station tree */
  263. NODE_STACK_INIT(stack);
  264. /* initialize stack by pushing the tree root at offset 0 */
  265. NODE_STACK_PUSH(stack, stations, 0);
  266. while (NODE_STACK_NONEMPTY(stack))
  267. {
  268. MacTreeNode *node;
  269. UINT32 offset;
  270. NODE_STACK_POP(stack, node, offset);
  271. /* we can store maximum 31 (32 total, 1 empty root) entries in the gateway tree */
  272. if (offset > (MAX_GW_SIZE - 1)) break;
  273. /* check if this record has a gateway address */
  274. if (node->descriptor != NULL && node->descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP)
  275. {
  276. /* found a record, create an insertion place */
  277. if (insertionPlace != NULL)
  278. {
  279. insertionPlace->right = ixEthDBAllocMacTreeNode();
  280. insertionPlace = insertionPlace->right;
  281. }
  282. else
  283. {
  284. gateways = ixEthDBAllocMacTreeNode();
  285. insertionPlace = gateways;
  286. }
  287. if (insertionPlace == NULL)
  288. {
  289. /* no nodes left, bail out with what we have */
  290. ixOsalCacheDmaFree(stack);
  291. return gateways;
  292. }
  293. /* clone the original record for the gateway tree */
  294. insertionPlace->descriptor = ixEthDBCloneMacDescriptor(node->descriptor);
  295. /* insert and update the offset in the original record */
  296. node->descriptor->recordData.wifiData.gwAddressIndex = gwIndex++;
  297. }
  298. /* browse the tree */
  299. if (node->left != NULL)
  300. {
  301. NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset));
  302. }
  303. if (node->right != NULL)
  304. {
  305. NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset));
  306. }
  307. }
  308. ixOsalCacheDmaFree(stack);
  309. return gateways;
  310. }
  311. /**
  312. * @brief downloads the WiFi header conversion table to an NPE
  313. *
  314. * @param portID ID of the port
  315. *
  316. * This function prepares the WiFi header conversion tables and
  317. * downloads them to the specified NPE port.
  318. *
  319. * The header conversion tables consist in the main table of
  320. * addresses and the secondary table of gateways. AP_TO_AP records
  321. * from the first table contain index fields into the second table
  322. * for gateway selection.
  323. *
  324. * Note that this function is documented in the main component
  325. * header file, IxEthDB.h.
  326. *
  327. * @return IX_ETH_DB_SUCCESS if the operation completed successfully
  328. * or an appropriate error message otherwise
  329. */
  330. IX_ETH_DB_PUBLIC
  331. IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID)
  332. {
  333. IxEthDBPortMap query;
  334. MacTreeNode *stations = NULL, *gateways = NULL, *gateway = NULL;
  335. IxNpeMhMessage message;
  336. PortInfo *portInfo;
  337. IX_STATUS result;
  338. IX_ETH_DB_CHECK_PORT(portID);
  339. IX_ETH_DB_CHECK_SINGLE_NPE(portID);
  340. IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION);
  341. portInfo = &ixEthDBPortInfo[portID];
  342. SET_DEPENDENCY_MAP(query, portID);
  343. ixEthDBUpdateLock();
  344. stations = ixEthDBQuery(NULL, query, IX_ETH_DB_WIFI_RECORD, MAX_ELT_SIZE);
  345. gateways = ixEthDBGatewaySelect(stations);
  346. /* clean up gw area */
  347. memset((void *) portInfo->updateMethod.npeGwUpdateZone, FULL_GW_BYTE_SIZE, 0);
  348. /* write all gateways */
  349. gateway = gateways;
  350. while (gateway != NULL)
  351. {
  352. ixEthDBNPEGatewayNodeWrite((void *) (((UINT32) portInfo->updateMethod.npeGwUpdateZone)
  353. + gateway->descriptor->recordData.wifiData.gwAddressIndex * ELT_ENTRY_SIZE),
  354. gateway);
  355. gateway = gateway->right;
  356. }
  357. /* free the gateway tree */
  358. if (gateways != NULL)
  359. {
  360. ixEthDBFreeMacTreeNode(gateways);
  361. }
  362. FILL_SETAPMACTABLE_MSG(message,
  363. IX_OSAL_MMU_VIRT_TO_PHYS(portInfo->updateMethod.npeGwUpdateZone));
  364. IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
  365. if (result == IX_SUCCESS)
  366. {
  367. /* update the main tree (the stations tree) */
  368. portInfo->updateMethod.searchTree = stations;
  369. result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_WIFI_RECORD);
  370. }
  371. ixEthDBUpdateUnlock();
  372. return result;
  373. }