~ubuntu-branches/ubuntu/maverick/u-boot-omap3/maverick

« back to all changes in this revision

Viewing changes to cpu/ixp/npe/IxEthDBAPI.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2010-03-22 15:06:23 UTC
  • Revision ID: james.westby@ubuntu.com-20100322150623-i21g8rgiyl5dohag
Tags: upstream-2010.3git20100315
ImportĀ upstreamĀ versionĀ 2010.3git20100315

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}