4
* @brief Implementation of the public API
7
* IXP400 SW Release version 2.0
9
* -- Copyright Notice --
12
* Copyright 2001-2005, Intel Corporation.
13
* All rights reserved.
16
* Redistribution and use in source and binary forms, with or without
17
* modification, are permitted provided that the following conditions
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.
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
42
* -- End of Copyright Notice --
45
#include "IxEthDB_p.h"
46
#include "IxFeatureCtrl.h"
48
extern HashTable dbHashtable;
49
extern IxEthDBPortMap overflowUpdatePortList;
50
extern BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];
53
IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
55
IX_ETH_DB_CHECK_PORT(portID);
57
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
59
IX_ETH_DB_CHECK_REFERENCE(macAddr);
61
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
63
return ixEthDBTriggerAddPortUpdate(macAddr, portID, TRUE);
67
IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
69
IX_ETH_DB_CHECK_PORT(portID);
71
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
73
IX_ETH_DB_CHECK_REFERENCE(macAddr);
75
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
77
return ixEthDBTriggerAddPortUpdate(macAddr, portID, FALSE);
81
IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr)
83
HashNode *searchResult;
85
IX_ETH_DB_CHECK_REFERENCE(macAddr);
87
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
89
if (searchResult == NULL)
91
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
94
ixEthDBReleaseHashNode(searchResult);
96
/* build a remove event and place it on the event queue */
97
return ixEthDBTriggerRemovePortUpdate(macAddr, ((MacDescriptor *) searchResult->data)->portID);
101
void ixEthDBDatabaseMaintenance()
103
HashIterator iterator;
105
BOOL agingRequired = FALSE;
107
/* ports who will have deleted records and therefore will need updating */
108
IxEthDBPortMap triggerPorts;
110
if (IX_FEATURE_CTRL_SWCONFIG_ENABLED !=
111
ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING))
116
SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
118
/* check if there's at least a port that needs aging */
119
for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
121
if (ixEthDBPortInfo[portIndex].agingEnabled && ixEthDBPortInfo[portIndex].enabled)
123
agingRequired = TRUE;
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++)
132
if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE
133
&& ixEthDBPortInfo[portIndex].agingEnabled
134
&& ixEthDBPortInfo[portIndex].enabled)
136
IxNpeMhMessage message;
139
/* send EDB_GetMACAddressDatabase message */
140
FILL_GETMACADDRESSDATABASE(message,
142
IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone));
144
IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), message, result);
146
if (result == IX_SUCCESS)
148
/* analyze NPE copy */
149
ixEthDBNPESyncScan(portIndex, ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone, FULL_ELT_BYTE_SIZE);
151
IX_ETH_DB_SUPPORT_TRACE("DB: (API) Finished scanning NPE tree on port %d\n", portIndex);
155
ixEthDBPortInfo[portIndex].agingEnabled = FALSE;
156
ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = FALSE;
157
ixEthDBPortInfo[portIndex].updateMethod.userControlled = TRUE;
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);
164
ixEthDBDatabaseClear(portIndex, IX_ETH_DB_ALL_RECORD_TYPES);
169
/* browse database and age entries */
170
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
172
while (IS_ITERATOR_VALID(&iterator))
174
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
176
BOOL staticEntry = TRUE;
178
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
180
age = &descriptor->recordData.filteringData.age;
181
staticEntry = descriptor->recordData.filteringData.staticEntry;
183
else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
185
age = &descriptor->recordData.filteringVlanData.age;
186
staticEntry = descriptor->recordData.filteringVlanData.staticEntry;
193
if (ixEthDBPortInfo[descriptor->portID].agingEnabled && (staticEntry == FALSE))
195
/* manually increment the age if the port has no such capability */
196
if ((ixEthDBPortDefinitions[descriptor->portID].capabilities & IX_ETH_ENTRY_AGING) == 0)
198
*age += (IX_ETH_DB_MAINTENANCE_TIME / 60);
201
/* age entry if it exceeded the maximum time to live */
202
if (*age >= (IX_ETH_DB_LEARNING_ENTRY_AGE_TIME / 60))
204
/* add port to the set of update trigger ports */
205
JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
208
BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
212
/* move to the next record */
213
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
218
/* move to the next record */
219
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
223
/* update ports which lost records */
224
ixEthDBUpdatePortLearningTrees(triggerPorts);
229
IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType)
231
IxEthDBPortMap triggerPorts;
232
HashIterator iterator;
234
if (portID >= IX_ETH_DB_NUMBER_OF_PORTS && portID != IX_ETH_DB_ALL_PORTS)
236
return IX_ETH_DB_INVALID_PORT;
239
/* check if the user passes some extra bits */
240
if ((recordType | IX_ETH_DB_ALL_RECORD_TYPES) != IX_ETH_DB_ALL_RECORD_TYPES)
242
return IX_ETH_DB_INVALID_ARG;
245
SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
247
/* browse database and age entries */
248
BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
250
while (IS_ITERATOR_VALID(&iterator))
252
MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data;
254
if (((descriptor->portID == portID) || (portID == IX_ETH_DB_ALL_PORTS))
255
&& ((descriptor->type & recordType) != 0))
257
/* add to trigger if automatic updates are required */
258
if (ixEthDBPortUpdateRequired[descriptor->type])
260
/* add port to the set of update trigger ports */
261
JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID);
265
BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
269
/* move to the next record */
270
BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
274
/* update ports which lost records */
275
ixEthDBUpdatePortLearningTrees(triggerPorts);
277
return IX_ETH_DB_SUCCESS;
281
IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
283
HashNode *searchResult;
284
IxEthDBStatus result = IX_ETH_DB_NO_SUCH_ADDR;
286
IX_ETH_DB_CHECK_PORT(portID);
288
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
290
IX_ETH_DB_CHECK_REFERENCE(macAddr);
292
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
294
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
296
if (searchResult == NULL)
298
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
301
if (((MacDescriptor *) (searchResult->data))->portID == portID)
303
result = IX_ETH_DB_SUCCESS; /* address and port match */
306
ixEthDBReleaseHashNode(searchResult);
312
IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
314
HashNode *searchResult;
316
IX_ETH_DB_CHECK_REFERENCE(portID);
318
IX_ETH_DB_CHECK_REFERENCE(macAddr);
320
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
322
if (searchResult == NULL)
324
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
327
/* return the port ID */
328
*portID = ((MacDescriptor *) searchResult->data)->portID;
330
ixEthDBReleaseHashNode(searchResult);
332
return IX_ETH_DB_SUCCESS;
336
IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID)
338
IX_ETH_DB_CHECK_PORT(portID);
340
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
342
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
344
ixEthDBPortInfo[portID].agingEnabled = FALSE;
346
return IX_ETH_DB_SUCCESS;
350
IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID)
352
IX_ETH_DB_CHECK_PORT(portID);
354
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
356
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING);
358
ixEthDBPortInfo[portID].agingEnabled = TRUE;
360
return IX_ETH_DB_SUCCESS;
364
IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr)
366
HashNode *searchResult;
367
MacDescriptor *descriptor;
369
IX_ETH_DB_CHECK_REFERENCE(portID);
371
IX_ETH_DB_CHECK_REFERENCE(macAddr);
373
searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
375
if (searchResult == NULL)
377
return IX_ETH_DB_NO_SUCH_ADDR; /* not found */
380
descriptor = (MacDescriptor *) searchResult->data;
382
/* return the port ID */
383
*portID = descriptor->portID;
385
/* reset entry age */
386
if (descriptor->type == IX_ETH_DB_FILTERING_RECORD)
388
descriptor->recordData.filteringData.age = 0;
392
descriptor->recordData.filteringVlanData.age = 0;
395
ixEthDBReleaseHashNode(searchResult);
397
return IX_ETH_DB_SUCCESS;
401
IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
403
IX_ETH_DB_CHECK_PORT(portID);
405
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
407
IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
409
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
411
/* force bit at offset 255 to 0 (reserved) */
412
dependencyPortMap[31] &= 0xFE;
414
COPY_DEPENDENCY_MAP(ixEthDBPortInfo[portID].dependencyPortMap, dependencyPortMap);
416
return IX_ETH_DB_SUCCESS;
420
IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap)
422
IX_ETH_DB_CHECK_PORT(portID);
424
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
426
IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap);
428
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
430
COPY_DEPENDENCY_MAP(dependencyPortMap, ixEthDBPortInfo[portID].dependencyPortMap);
432
return IX_ETH_DB_SUCCESS;
436
IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate)
438
IX_ETH_DB_CHECK_PORT(portID);
440
IX_ETH_DB_CHECK_SINGLE_NPE(portID);
442
IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING);
444
ixEthDBPortInfo[portID].updateMethod.updateEnabled = enableUpdate;
445
ixEthDBPortInfo[portID].updateMethod.userControlled = TRUE;
447
return IX_ETH_DB_SUCCESS;