IxEthDBWiFi.c 15 KB

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