]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/npe/IxEthDBAPI.c
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / drivers / net / npe / IxEthDBAPI.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  * 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 #include "IxFeatureCtrl.h"
47
48 extern HashTable dbHashtable;
49 extern IxEthDBPortMap overflowUpdatePortList;
50 extern BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
51
52 IX_ETH_DB_PUBLIC
53 IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
54 {
55     IX_ETH_DB_CHECK_PORT(portID);
56     
57     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
58     
59     IX_ETH_DB_CHECK_REFERENCE(macAddr);
60     
61     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
62
63     return ixEthDBTriggerAddPortUpdate(macAddr, portID, true);
64 }
65     
66 IX_ETH_DB_PUBLIC
67 IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
68 {
69     IX_ETH_DB_CHECK_PORT(portID);
70     
71     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
72         
73     IX_ETH_DB_CHECK_REFERENCE(macAddr);
74
75     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
76
77     return ixEthDBTriggerAddPortUpdate(macAddr, portID, false);
78 }
79
80 IX_ETH_DB_PUBLIC
81 IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr)
82 {
83     HashNode *searchResult;
84
85     IX_ETH_DB_CHECK_REFERENCE(macAddr);
86
87     searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
88
89     if (searchResult == NULL)
90     {
91         return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
92     }
93     
94     ixEthDBReleaseHashNode(searchResult);
95     
96     /* build a remove event and place it on the event queue */
97     return ixEthDBTriggerRemovePortUpdate(macAddr, ((MacDescriptor *) searchResult->data)->portID);
98 }
99        
100 IX_ETH_DB_PUBLIC
101 void ixEthDBDatabaseMaintenance()
102 {
103     HashIterator iterator;
104     UINT32 portIndex;
105     BOOL agingRequired = false;
106
107     /* ports who will have deleted records and therefore will need updating */
108     IxEthDBPortMap triggerPorts;
109
110     if (IX_FEATURE_CTRL_SWCONFIG_ENABLED !=
111         ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
112     {
113         return;
114     }
115
116     SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
117
118     /* check if there's at least a port that needs aging */
119     for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
120     {
121         if (ixEthDBPortInfo[portIndex].agingEnabled && ixEthDBPortInfo[portIndex].enabled)
122         {
123             agingRequired = true;
124         }
125     }
126
127     if (agingRequired)
128     {
129         /* ask each NPE port to write back the database for aging inspection */
130         for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
131         {
132             if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE
133                 && ixEthDBPortInfo[portIndex].agingEnabled
134                 && ixEthDBPortInfo[portIndex].enabled)
135             {
136                 IxNpeMhMessage message;
137                 IX_STATUS result;
138                 
139                 /* send EDB_GetMACAddressDatabase message */
140                 FILL_GETMACADDRESSDATABASE(message, 
141                     0 /* unused */, 
142                     IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone));
143
144                 IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), message, result);
145
146                 if (result == IX_SUCCESS)
147                 {
148                     /* analyze NPE copy */
149                     ixEthDBNPESyncScan(portIndex, ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone, FULL_ELT_BYTE_SIZE);
150
151                     IX_ETH_DB_SUPPORT_TRACE("DB: (API) Finished scanning NPE tree on port %d\n", portIndex);
152                 }
153                 else
154                 {
155                     ixEthDBPortInfo[portIndex].agingEnabled                = false;
156                     ixEthDBPortInfo[portIndex].updateMethod.updateEnabled  = false;
157                     ixEthDBPortInfo[portIndex].updateMethod.userControlled = true;
158
159                     ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
160                         IX_OSAL_LOG_DEV_STDOUT, 
161                         "EthDB: (Maintenance) warning, disabling aging and updates for port %d (assumed dead)\n",
162                         portIndex, 0, 0, 0, 0, 0);
163
164                     ixEthDBDatabaseClear(portIndex, IX_ETH_DB_ALL_RECORD_TYPES);
165                 }
166             }
167         }
168
169         /* browse database and age entries */
170         BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
171
172         while (IS_ITERATOR_VALID(&iterator))
173         {
174             MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
175             UINT32 *age               = NULL;
176             BOOL staticEntry          = true;
177
178             if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
179             {
180                 age         = &descriptor->recordData.filteringData.age;
181                 staticEntry = descriptor->recordData.filteringData.staticEntry;
182             }
183             else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
184             {
185                 age         = &descriptor->recordData.filteringVlanData.age;
186                 staticEntry = descriptor->recordData.filteringVlanData.staticEntry;
187             }
188             else
189             {
190                 staticEntry = true;
191             }
192
193             if (ixEthDBPortInfo[descriptor->portID].agingEnabled && (staticEntry == false))
194             {
195                 /* manually increment the age if the port has no such capability */
196                 if ((ixEthDBPortDefinitions[descriptor->portID].capabilities & IX_ETH_ENTRY_AGING) == 0)
197                 {
198                     *age += (IX_ETH_DB_MAINTENANCE_TIME / 60);
199                 }
200
201                 /* age entry if it exceeded the maximum time to live */
202                 if (*age >= (IX_ETH_DB_LEARNING_ENTRY_AGE_TIME / 60))
203                 {
204                     /* add port to the set of update trigger ports */
205                     JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
206
207                     /* delete entry */
208                     BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
209                 }
210                 else
211                 {
212                     /* move to the next record */
213                     BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
214                 }
215             }
216             else
217             {
218                 /* move to the next record */
219                 BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
220             }
221         }
222
223         /* update ports which lost records */
224         ixEthDBUpdatePortLearningTrees(triggerPorts);
225     }
226 }
227
228 IX_ETH_DB_PUBLIC
229 IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType)
230 {
231     IxEthDBPortMap triggerPorts;
232     HashIterator iterator;
233
234     if (portID >= IX_ETH_DB_NUMBER_OF_PORTS && portID != IX_ETH_DB_ALL_PORTS)
235     {
236         return IX_ETH_DB_INVALID_PORT;
237     }
238
239     /* check if the user passes some extra bits */
240     if ((recordType | IX_ETH_DB_ALL_RECORD_TYPES) != IX_ETH_DB_ALL_RECORD_TYPES)
241     {
242         return IX_ETH_DB_INVALID_ARG;
243     }
244
245     SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
246     
247     /* browse database and age entries */
248     BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
249
250     while (IS_ITERATOR_VALID(&iterator))
251     {
252         MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
253
254         if (((descriptor->portID == portID) || (portID == IX_ETH_DB_ALL_PORTS))
255             && ((descriptor->type & recordType) != 0))
256         {
257             /* add to trigger if automatic updates are required */
258             if (ixEthDBPortUpdateRequired[descriptor->type])
259             {
260                 /* add port to the set of update trigger ports */
261                 JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
262             }
263
264             /* delete entry */
265             BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
266         }
267         else
268         {
269             /* move to the next record */
270             BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
271         }
272     }
273
274     /* update ports which lost records */
275     ixEthDBUpdatePortLearningTrees(triggerPorts);
276     
277     return IX_ETH_DB_SUCCESS;
278 }
279
280 IX_ETH_DB_PUBLIC
281 IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
282 {
283     HashNode *searchResult;
284     IxEthDBStatus result = IX_ETH_DB_NO_SUCH_ADDR;
285
286     IX_ETH_DB_CHECK_PORT(portID);
287     
288     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
289     
290     IX_ETH_DB_CHECK_REFERENCE(macAddr);
291
292     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
293
294     searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
295
296     if (searchResult == NULL)
297     {
298         return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
299     }
300
301     if (((MacDescriptor *) (searchResult->data))->portID == portID)
302     {
303         result = IX_ETH_DB_SUCCESS; /* address and port match */
304     }
305
306     ixEthDBReleaseHashNode(searchResult);
307
308     return result;
309 }
310
311 IX_ETH_DB_PUBLIC
312 IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
313 {
314     HashNode *searchResult;
315
316     IX_ETH_DB_CHECK_REFERENCE(portID);
317     
318     IX_ETH_DB_CHECK_REFERENCE(macAddr);
319
320     searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
321
322     if (searchResult == NULL)
323     {
324         return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
325     }
326
327     /* return the port ID */
328     *portID = ((MacDescriptor *) searchResult->data)->portID;
329
330     ixEthDBReleaseHashNode(searchResult);
331
332     return IX_ETH_DB_SUCCESS;
333 }
334
335 IX_ETH_DB_PUBLIC
336 IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID)
337 {
338     IX_ETH_DB_CHECK_PORT(portID);
339
340     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
341
342     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
343
344     ixEthDBPortInfo[portID].agingEnabled = false;
345
346     return IX_ETH_DB_SUCCESS;
347 }
348
349 IX_ETH_DB_PUBLIC
350 IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID)
351 {
352     IX_ETH_DB_CHECK_PORT(portID);
353
354     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
355
356     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
357
358     ixEthDBPortInfo[portID].agingEnabled = true;
359
360     return IX_ETH_DB_SUCCESS;
361 }
362
363 IX_ETH_DB_PUBLIC
364 IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
365 {
366     HashNode *searchResult;
367     MacDescriptor *descriptor;
368
369     IX_ETH_DB_CHECK_REFERENCE(portID);
370     
371     IX_ETH_DB_CHECK_REFERENCE(macAddr);
372
373     searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
374
375     if (searchResult == NULL)
376     {
377         return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
378     }
379     
380     descriptor = (MacDescriptor *) searchResult->data;
381
382     /* return the port ID */
383     *portID = descriptor->portID;
384
385     /* reset entry age */
386     if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
387     {
388         descriptor->recordData.filteringData.age = 0;
389     }
390     else
391     {
392         descriptor->recordData.filteringVlanData.age = 0;
393     }
394
395     ixEthDBReleaseHashNode(searchResult);
396
397     return IX_ETH_DB_SUCCESS;
398 }
399
400 IX_ETH_DB_PUBLIC
401 IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
402 {
403     IX_ETH_DB_CHECK_PORT(portID);
404     
405     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
406     
407     IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
408     
409     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
410
411     /* force bit at offset 255 to 0 (reserved) */
412     dependencyPortMap[31] &= 0xFE;
413
414     COPY_DEPENDENCY_MAP(ixEthDBPortInfo[portID].dependencyPortMap, dependencyPortMap);
415
416     return IX_ETH_DB_SUCCESS;
417 }
418
419 IX_ETH_DB_PUBLIC
420 IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
421 {
422     IX_ETH_DB_CHECK_PORT(portID);
423     
424     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
425     
426     IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
427     
428     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
429
430     COPY_DEPENDENCY_MAP(dependencyPortMap, ixEthDBPortInfo[portID].dependencyPortMap);
431
432     return IX_ETH_DB_SUCCESS;
433 }
434
435 IX_ETH_DB_PUBLIC
436 IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate)
437 {
438     IX_ETH_DB_CHECK_PORT(portID);
439
440     IX_ETH_DB_CHECK_SINGLE_NPE(portID);    
441
442     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
443
444     ixEthDBPortInfo[portID].updateMethod.updateEnabled  = enableUpdate;
445     ixEthDBPortInfo[portID].updateMethod.userControlled = true;
446
447     return IX_ETH_DB_SUCCESS;
448 }