Merge branch 'mpc86xx'
[platform/kernel/u-boot.git] / cpu / ixp / npe / IxEthDBFeatures.c
1 /**
2  * @file IxEthDBFeatures.c
3  *
4  * @brief Implementation of the EthDB feature control 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 "IxNpeDl.h"
46 #include "IxEthDBQoS.h"
47 #include "IxEthDB_p.h"
48
49 /**
50  * @brief scans the capabilities of the loaded NPE images
51  *
52  * This function MUST be called by the ixEthDBInit() function.
53  * No EthDB features (including learning and filtering) are enabled
54  * before this function is called.
55  *
56  * @return none
57  *
58  * @internal
59  */
60 IX_ETH_DB_PUBLIC
61 void ixEthDBFeatureCapabilityScan(void)
62 {
63     IxNpeDlImageId imageId, npeAImageId;
64     IxEthDBPortId portIndex;
65     PortInfo *portInfo;
66     IxEthDBPriorityTable defaultPriorityTable;
67     IX_STATUS result;
68     UINT32 queueIndex;
69     UINT32 queueStructureIndex;
70     UINT32 trafficClassDefinitionIndex;
71
72     /* read version of NPE A - required to set the AQM queues for B and C */
73     npeAImageId.functionalityId = 0;
74     ixNpeDlLoadedImageGet(IX_NPEDL_NPEID_NPEA, &npeAImageId);
75
76     for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++)
77     {
78         IxNpeMhMessage msg;
79
80         portInfo = &ixEthDBPortInfo[portIndex];
81
82         /* check and bypass if NPE B or C is fused out */
83         if (ixEthDBSingleEthNpeCheck(portIndex) != IX_ETH_DB_SUCCESS) continue;
84
85         /* all ports are capable of LEARNING by default */
86         portInfo->featureCapability |= IX_ETH_DB_LEARNING;
87         portInfo->featureStatus     |= IX_ETH_DB_LEARNING;
88
89         if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE)
90         {
91
92             if (ixNpeDlLoadedImageGet(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), &imageId) != IX_SUCCESS)
93             {
94                 WARNING_LOG("DB: (FeatureScan) NpeDl did not provide the image ID for NPE port %d\n", portIndex);
95             }
96             else
97             {
98                 /* initialize and empty NPE response mutex */
99                 ixOsalMutexInit(&portInfo->npeAckLock);
100                 ixOsalMutexLock(&portInfo->npeAckLock, IX_OSAL_WAIT_FOREVER);
101
102                 /* check NPE response to GetStatus */
103                 msg.data[0] = IX_ETHNPE_NPE_GETSTATUS << 24;
104                 msg.data[1] = 0;
105                 IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), msg, result);
106                 if (result != IX_SUCCESS)
107                 {
108                     WARNING_LOG("DB: (FeatureScan) warning, could not send message to the NPE\n");
109                     continue;
110                 }
111
112
113                 if (imageId.functionalityId == 0x00
114                     || imageId.functionalityId == 0x03
115                     || imageId.functionalityId == 0x04
116                     || imageId.functionalityId == 0x80)
117                 {
118                     portInfo->featureCapability |= IX_ETH_DB_FILTERING;
119                     portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
120                     portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
121                 }
122                 else if (imageId.functionalityId == 0x01
123                          || imageId.functionalityId == 0x81)
124                 {
125                     portInfo->featureCapability |= IX_ETH_DB_FILTERING;
126                     portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
127                     portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
128                     portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS;
129                 }
130                 else if (imageId.functionalityId == 0x02
131                          || imageId.functionalityId == 0x82)
132                 {
133                     portInfo->featureCapability |= IX_ETH_DB_WIFI_HEADER_CONVERSION;
134                     portInfo->featureCapability |= IX_ETH_DB_FIREWALL;
135                     portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL;
136                     portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS;
137                 }
138
139                 /* reset AQM queues */
140                 memset(portInfo->ixEthDBTrafficClassAQMAssignments, 0, sizeof (portInfo->ixEthDBTrafficClassAQMAssignments));
141
142                 /* ensure there's at least one traffic class record in the definition table, otherwise we have no default case, hence no queues */
143                 IX_ENSURE(sizeof (ixEthDBTrafficClassDefinitions) != 0, "DB: no traffic class definitions found, check IxEthDBQoS.h");
144
145                 /* find the traffic class definition index compatible with the current NPE A functionality ID */
146                 for (trafficClassDefinitionIndex = 0 ;
147                     trafficClassDefinitionIndex < sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0]);
148                     trafficClassDefinitionIndex++)
149                 {
150                     if (ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX] == npeAImageId.functionalityId)
151                     {
152                         /* found it */
153                         break;
154                     }
155                 }
156
157                 /* select the default case if we went over the array boundary */
158                 if (trafficClassDefinitionIndex == sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0]))
159                 {
160                     trafficClassDefinitionIndex = 0; /* the first record is the default case */
161                 }
162
163                 /* select queue assignment structure based on the traffic class configuration index */
164                 queueStructureIndex = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX];
165
166                 /* only traffic class 0 is active at initialization time */
167                 portInfo->ixEthDBTrafficClassCount = 1;
168
169                 /* enable port, VLAN and Firewall feature bits to initialize QoS/VLAN/Firewall configuration */
170                 portInfo->featureStatus |= IX_ETH_DB_VLAN_QOS;
171                 portInfo->featureStatus |= IX_ETH_DB_FIREWALL;
172                 portInfo->enabled        = TRUE;
173
174 #define CONFIG_WITH_VLAN  /* test-only: VLAN support not included to save space!!! */
175 #ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
176                 /* set VLAN initial configuration (permissive) */
177                 if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) /* QoS-enabled image */
178                 {
179                     /* QoS capable */
180                     portInfo->ixEthDBTrafficClassAvailable = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX];
181
182                     /* set AQM queues */
183                     for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++)
184                     {
185                         portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] = ixEthDBQueueAssignments[queueStructureIndex][queueIndex];
186                     }
187
188                     /* set default PVID (0) and default traffic class 0 */
189                     ixEthDBPortVlanTagSet(portIndex, 0);
190
191                     /* enable reception of all frames */
192                     ixEthDBAcceptableFrameTypeSet(portIndex, IX_ETH_DB_ACCEPT_ALL_FRAMES);
193
194                     /* clear full VLAN membership */
195                     ixEthDBPortVlanMembershipRangeRemove(portIndex, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID);
196
197                     /* clear TTI table - no VLAN tagged frames will be transmitted */
198                     ixEthDBEgressVlanRangeTaggingEnabledSet(portIndex, 0, 4094, FALSE);
199
200                     /* set membership on 0, otherwise no Tx or Rx is working */
201                     ixEthDBPortVlanMembershipAdd(portIndex, 0);
202                 }
203                 else /* QoS not available in this image */
204 #endif /* test-only */
205                 {
206                     /* initialize traffic class availability (only class 0 is available) */
207                     portInfo->ixEthDBTrafficClassAvailable = 1;
208
209                     /* point all AQM queues to traffic class 0 */
210                     for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++)
211                     {
212                         portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] =
213                             ixEthDBQueueAssignments[queueStructureIndex][0];
214                     }
215                 }
216
217 #ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
218                 /* download priority mapping table and Rx queue configuration */
219                 memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable));
220                 ixEthDBPriorityMappingTableSet(portIndex, defaultPriorityTable);
221 #endif
222
223                 /* by default we turn off invalid source MAC address filtering */
224                 ixEthDBFirewallInvalidAddressFilterEnable(portIndex, FALSE);
225
226                 /* disable port, VLAN, Firewall feature bits */
227                 portInfo->featureStatus &= ~IX_ETH_DB_VLAN_QOS;
228                 portInfo->featureStatus &= ~IX_ETH_DB_FIREWALL;
229                 portInfo->enabled        = FALSE;
230
231                 /* enable filtering by default if present */
232                 if ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0)
233                 {
234                     portInfo->featureStatus |= IX_ETH_DB_FILTERING;
235                 }
236             }
237         }
238     }
239 }
240
241 /**
242  * @brief returns the capability of a port
243  *
244  * @param portID ID of the port
245  * @param featureSet location to store the port capability in
246  *
247  * This function will save the capability set of the given port
248  * into the given location. Capabilities are bit-ORed, each representing
249  * a bit of the feature set.
250  *
251  * Note that this function is documented in the main component
252  * public header file, IxEthDB.h.
253  *
254  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
255  * or IX_ETH_DB_INVALID_PORT if the given port is invalid
256  */
257 IX_ETH_DB_PUBLIC
258 IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet)
259 {
260     IX_ETH_DB_CHECK_PORT_INITIALIZED(portID);
261
262     IX_ETH_DB_CHECK_REFERENCE(featureSet);
263
264     *featureSet = ixEthDBPortInfo[portID].featureCapability;
265
266     return IX_ETH_DB_SUCCESS;
267 }
268
269 /**
270  * @brief enables or disables a port capability
271  *
272  * @param portID ID of the port
273  * @param feature feature to enable or disable
274  * @param enabled TRUE to enable the selected feature or FALSE to disable it
275  *
276  * Note that this function is documented in the main component
277  * header file, IxEthDB.h.
278  *
279  * @return IX_ETH_DB_SUCCESS if the operation completed
280  * successfully or an appropriate error message otherwise
281  */
282 IX_ETH_DB_PUBLIC
283 IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enable)
284 {
285     PortInfo *portInfo;
286     IxEthDBPriorityTable defaultPriorityTable;
287     IxEthDBVlanSet vlanSet;
288     IxEthDBStatus status = IX_ETH_DB_SUCCESS;
289     BOOL portEnabled;
290
291     IX_ETH_DB_CHECK_PORT_INITIALIZED(portID);
292
293     portInfo    = &ixEthDBPortInfo[portID];
294     portEnabled = portInfo->enabled;
295
296     /* check that only one feature is selected */
297     if (!ixEthDBCheckSingleBitValue(feature))
298     {
299         return IX_ETH_DB_FEATURE_UNAVAILABLE;
300     }
301
302     /* port capable of this feature? */
303     if ((portInfo->featureCapability & feature) == 0)
304     {
305         return IX_ETH_DB_FEATURE_UNAVAILABLE;
306     }
307
308     /* mutual exclusion between learning and WiFi header conversion */
309     if (enable && ((feature | portInfo->featureStatus) & (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION))
310             == (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION))
311     {
312         return IX_ETH_DB_NO_PERMISSION;
313     }
314
315     /* learning must be enabled before filtering */
316     if (enable && (feature == IX_ETH_DB_FILTERING) && ((portInfo->featureStatus & IX_ETH_DB_LEARNING) == 0))
317     {
318         return IX_ETH_DB_NO_PERMISSION;
319     }
320
321     /* filtering must be disabled before learning */
322     if (!enable && (feature == IX_ETH_DB_LEARNING) && ((portInfo->featureStatus & IX_ETH_DB_FILTERING) != 0))
323     {
324         return IX_ETH_DB_NO_PERMISSION;
325     }
326
327     /* redundant enabling or disabling */
328     if ((!enable && ((portInfo->featureStatus & feature) == 0))
329         || (enable && ((portInfo->featureStatus & feature) != 0)))
330     {
331         /* do nothing */
332         return IX_ETH_DB_SUCCESS;
333     }
334
335     /* force port enabled */
336     portInfo->enabled = TRUE;
337
338     if (enable)
339     {
340         /* turn on enable bit */
341         portInfo->featureStatus |= feature;
342
343 #ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
344         /* if this is VLAN/QoS set the default priority table */
345         if (feature == IX_ETH_DB_VLAN_QOS)
346         {
347             /* turn on VLAN/QoS (most permissive mode):
348                 - set default 802.1Q priority mapping table, in accordance to the
349                   availability of traffic classes
350                 - set the acceptable frame filter to accept all
351                 - set the Ingress tagging mode to pass-through
352                 - set full VLAN membership list
353                 - set full TTI table
354                 - set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0)
355                 - enable TPID port extraction
356             */
357
358             portInfo->ixEthDBTrafficClassCount = portInfo->ixEthDBTrafficClassAvailable;
359
360             /* set default 802.1Q priority mapping table - note that C indexing starts from 0, so we substract 1 here */
361             memcpy (defaultPriorityTable,
362                 (const void *) ixEthIEEE802_1QUserPriorityToTrafficClassMapping[portInfo->ixEthDBTrafficClassCount - 1],
363                 sizeof (defaultPriorityTable));
364
365             /* update priority mapping and AQM queue assignments */
366             status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable);
367
368             if (status == IX_ETH_DB_SUCCESS)
369             {
370                 status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
371             }
372
373             if (status == IX_ETH_DB_SUCCESS)
374             {
375                 status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH);
376             }
377
378             /* set membership and TTI tables */
379             memset (vlanSet, 0xFF, sizeof (vlanSet));
380
381             if (status == IX_ETH_DB_SUCCESS)
382             {
383                 /* use the internal function to bypass PVID check */
384                 status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet);
385             }
386
387             if (status == IX_ETH_DB_SUCCESS)
388             {
389                 /* use the internal function to bypass PVID check */
390                 status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet);
391             }
392
393             /* reset the PVID */
394             if (status == IX_ETH_DB_SUCCESS)
395             {
396                 status = ixEthDBPortVlanTagSet(portID, 0);
397             }
398
399             /* enable TPID port extraction */
400             if (status == IX_ETH_DB_SUCCESS)
401             {
402                 status = ixEthDBVlanPortExtractionEnable(portID, TRUE);
403             }
404         }
405         else if (feature == IX_ETH_DB_FIREWALL)
406 #endif
407         {
408             /* firewall starts in black-list mode unless otherwise configured before *
409              * note that invalid source MAC address filtering is disabled by default */
410             if (portInfo->firewallMode != IX_ETH_DB_FIREWALL_BLACK_LIST
411                 && portInfo->firewallMode != IX_ETH_DB_FIREWALL_WHITE_LIST)
412             {
413                 status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
414
415                 if (status == IX_ETH_DB_SUCCESS)
416                 {
417                     status = ixEthDBFirewallInvalidAddressFilterEnable(portID, FALSE);
418                 }
419             }
420         }
421
422         if (status != IX_ETH_DB_SUCCESS)
423         {
424             /* checks failed, disable */
425             portInfo->featureStatus &= ~feature;
426         }
427     }
428     else
429     {
430         /* turn off features */
431         if (feature == IX_ETH_DB_FIREWALL)
432         {
433             /* turning off the firewall is equivalent to:
434                 - set to black-list mode
435                 - clear all the entries and download the new table
436                 - turn off the invalid source address checking
437             */
438
439             status = ixEthDBDatabaseClear(portID, IX_ETH_DB_FIREWALL_RECORD);
440
441             if (status == IX_ETH_DB_SUCCESS)
442             {
443                 status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
444             }
445
446             if (status == IX_ETH_DB_SUCCESS)
447             {
448                 status = ixEthDBFirewallInvalidAddressFilterEnable(portID, FALSE);
449             }
450
451             if (status == IX_ETH_DB_SUCCESS)
452             {
453                 status = ixEthDBFirewallTableDownload(portID);
454             }
455         }
456         else if (feature == IX_ETH_DB_WIFI_HEADER_CONVERSION)
457         {
458             /* turn off header conversion */
459             status = ixEthDBDatabaseClear(portID, IX_ETH_DB_WIFI_RECORD);
460
461             if (status == IX_ETH_DB_SUCCESS)
462             {
463                 status = ixEthDBWiFiConversionTableDownload(portID);
464             }
465         }
466 #ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */
467         else if (feature == IX_ETH_DB_VLAN_QOS)
468         {
469             /* turn off VLAN/QoS:
470                 - set a priority mapping table with one traffic class
471                 - set the acceptable frame filter to accept all
472                 - set the Ingress tagging mode to pass-through
473                 - clear the VLAN membership list
474                 - clear the TTI table
475                 - set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0)
476                 - disable TPID port extraction
477             */
478
479             /* initialize all => traffic class 0 priority mapping table */
480             memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable));
481             portInfo->ixEthDBTrafficClassCount = 1;
482             status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable);
483
484             if (status == IX_ETH_DB_SUCCESS)
485             {
486                 status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
487             }
488
489             if (status == IX_ETH_DB_SUCCESS)
490             {
491                 status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH);
492             }
493
494             /* clear membership and TTI tables */
495             memset (vlanSet, 0, sizeof (vlanSet));
496
497             if (status == IX_ETH_DB_SUCCESS)
498             {
499                 /* use the internal function to bypass PVID check */
500                 status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet);
501             }
502
503             if (status == IX_ETH_DB_SUCCESS)
504             {
505                 /* use the internal function to bypass PVID check */
506                 status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet);
507             }
508
509             /* reset the PVID */
510             if (status == IX_ETH_DB_SUCCESS)
511             {
512                 status = ixEthDBPortVlanTagSet(portID, 0);
513             }
514
515             /* disable TPID port extraction */
516             if (status == IX_ETH_DB_SUCCESS)
517             {
518                 status = ixEthDBVlanPortExtractionEnable(portID, FALSE);
519             }
520         }
521 #endif
522
523         if (status == IX_ETH_DB_SUCCESS)
524         {
525             /* checks passed, disable */
526             portInfo->featureStatus &= ~feature;
527         }
528     }
529
530     /* restore port enabled state */
531     portInfo->enabled = portEnabled;
532
533     return status;
534 }
535
536 /**
537  * @brief returns the status of a feature
538  *
539  * @param portID port ID
540  * @param present location to store a boolean value indicating
541  * if the feature is present (TRUE) or not (FALSE)
542  * @param enabled location to store a booleam value indicating
543  * if the feature is present (TRUE) or not (FALSE)
544  *
545  * Note that this function is documented in the main component
546  * header file, IxEthDB.h.
547  *
548  * @return IX_ETH_DB_SUCCESS if the operation completed
549  * successfully or an appropriate error message otherwise
550  */
551 IX_ETH_DB_PUBLIC
552 IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled)
553 {
554     PortInfo *portInfo;
555
556     IX_ETH_DB_CHECK_PORT(portID);
557
558     IX_ETH_DB_CHECK_REFERENCE(present);
559
560     IX_ETH_DB_CHECK_REFERENCE(enabled);
561
562     portInfo = &ixEthDBPortInfo[portID];
563
564     *present = (portInfo->featureCapability & feature) != 0;
565     *enabled = (portInfo->featureStatus & feature) != 0;
566
567     return IX_ETH_DB_SUCCESS;
568 }
569
570 /**
571  * @brief returns the value of an EthDB property
572  *
573  * @param portID ID of the port
574  * @param feature feature owning the property
575  * @param property ID of the property
576  * @param type location to store the property type into
577  * @param value location to store the property value into
578  *
579  * Note that this function is documented in the main component
580  * header file, IxEthDB.h.
581  *
582  * @return IX_ETH_DB_SUCCESS if the operation completed
583  * successfully or an appropriate error message otherwise
584  */
585 IX_ETH_DB_PUBLIC
586 IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value)
587 {
588     IX_ETH_DB_CHECK_PORT_EXISTS(portID);
589
590     IX_ETH_DB_CHECK_REFERENCE(type);
591
592     IX_ETH_DB_CHECK_REFERENCE(value);
593
594     if (feature == IX_ETH_DB_VLAN_QOS)
595     {
596         if (property == IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY)
597         {
598             * (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount;
599             *type              = IX_ETH_DB_INTEGER_PROPERTY;
600
601             return IX_ETH_DB_SUCCESS;
602         }
603         else if (property >= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY
604             && property <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY)
605         {
606             UINT32 classDelta = property - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
607
608             if (classDelta >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount)
609             {
610                 return IX_ETH_DB_FAIL;
611             }
612
613             * (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[classDelta];
614             *type              = IX_ETH_DB_INTEGER_PROPERTY;
615
616             return IX_ETH_DB_SUCCESS;
617         }
618     }
619
620     return IX_ETH_DB_INVALID_ARG;
621 }
622
623 /**
624  * @brief sets the value of an EthDB property
625  *
626  * @param portID ID of the port
627  * @param feature feature owning the property
628  * @param property ID of the property
629  * @param value location containing the property value
630  *
631  * This function implements a private property intended
632  * only for EthAcc usage. Upon setting the IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE
633  * property (the value is ignored), the availability of traffic classes is
634  * frozen to whatever traffic class structure is currently in use.
635  * This means that if VLAN_QOS has been enabled before EthAcc
636  * initialization then all the defined traffic classes will be available;
637  * otherwise only one traffic class (0) will be available.
638  *
639  * Note that this function is documented in the main component
640  * header file, IxEthDB.h as not accepting any parameters. The
641  * current implementation is only intended for the private use of EthAcc.
642  *
643  * Also note that once this function is called the effect is irreversible,
644  * unless EthDB is complete unloaded and re-initialized.
645  *
646  * @return IX_ETH_DB_INVALID_ARG (no read-write properties are
647  * supported in this release)
648  */
649 IX_ETH_DB_PUBLIC
650 IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value)
651 {
652     IX_ETH_DB_CHECK_PORT_EXISTS(portID);
653
654     if ((feature == IX_ETH_DB_VLAN_QOS) && (property == IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE))
655     {
656         ixEthDBPortInfo[portID].ixEthDBTrafficClassAvailable = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount;
657
658         return IX_ETH_DB_SUCCESS;
659     }
660
661     return IX_ETH_DB_INVALID_ARG;
662 }