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