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
;