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