source: SVN/rincon/u-boot/cpu/ixp/npe/IxEthDBAPI.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 13.6 KB
Line 
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
48extern HashTable dbHashtable;
49extern IxEthDBPortMap overflowUpdatePortList;
50extern BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
51
52IX_ETH_DB_PUBLIC
53IxEthDBStatus 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   
66IX_ETH_DB_PUBLIC
67IxEthDBStatus 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
80IX_ETH_DB_PUBLIC
81IxEthDBStatus 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       
100IX_ETH_DB_PUBLIC
101void 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
228IX_ETH_DB_PUBLIC
229IxEthDBStatus 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
280IX_ETH_DB_PUBLIC
281IxEthDBStatus 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
311IX_ETH_DB_PUBLIC
312IxEthDBStatus 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
335IX_ETH_DB_PUBLIC
336IxEthDBStatus 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
349IX_ETH_DB_PUBLIC
350IxEthDBStatus 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
363IX_ETH_DB_PUBLIC
364IxEthDBStatus 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
400IX_ETH_DB_PUBLIC
401IxEthDBStatus 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
419IX_ETH_DB_PUBLIC
420IxEthDBStatus 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
435IX_ETH_DB_PUBLIC
436IxEthDBStatus 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}
Note: See TracBrowser for help on using the repository browser.