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