2 * @file IxEthAccCommon.c
4 * @author Intel Corporation
7 * @brief This file contains the implementation common support routines for the component
12 * IXP400 SW Release version 2.0
14 * -- Copyright Notice --
17 * Copyright 2001-2005, Intel Corporation.
18 * All rights reserved.
21 * SPDX-License-Identifier: BSD-3-Clause
23 * -- End of Copyright Notice --
27 * Component header files
34 #include "IxEthDBPortDefs.h"
35 #include "IxFeatureCtrl.h"
36 #include "IxEthAcc_p.h"
37 #include "IxEthAccQueueAssign_p.h"
39 #include "IxEthAccDataPlane_p.h"
40 #include "IxEthAccMii_p.h"
43 * @addtogroup IxEthAccPri
47 extern IxEthAccInfo ixEthAccDataInfo
;
51 * @brief Maximum number of RX queues set to be the maximum number
55 #define IX_ETHACC_MAX_RX_QUEUES \
56 (IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY \
57 - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY \
62 * @brief Maximum number of 128 entry RX queues
65 #define IX_ETHACC_MAX_LARGE_RX_QUEUES 4
69 * @brief Data structure template for Default RX Queues
73 IxEthAccQregInfo ixEthAccQmgrRxDefaultTemplate
=
75 IX_ETH_ACC_RX_FRAME_ETH_Q
, /**< Queue ID */
77 ixEthRxFrameQMCallback
, /**< Functional callback */
78 (IxQMgrCallbackId
) 0, /**< Callback tag */
79 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
80 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
81 true, /**< Enable Q notification at startup */
82 IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE
,/**< Q Condition to drive callback */
83 IX_QMGR_Q_WM_LEVEL0
, /**< Q Low water mark */
84 IX_QMGR_Q_WM_LEVEL1
, /**< Q High water mark - needed by NPE */
89 * @brief Data structure template for Small RX Queues
93 IxEthAccQregInfo ixEthAccQmgrRxSmallTemplate
=
95 IX_ETH_ACC_RX_FRAME_ETH_Q
, /**< Queue ID */
97 ixEthRxFrameQMCallback
, /**< Functional callback */
98 (IxQMgrCallbackId
) 0, /**< Callback tag */
99 IX_QMGR_Q_SIZE64
, /**< Allocate Smaller Q */
100 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
101 true, /**< Enable Q notification at startup */
102 IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE
,/**< Q Condition to drive callback */
103 IX_QMGR_Q_WM_LEVEL0
, /**< Q Low water mark */
104 IX_QMGR_Q_WM_LEVEL1
, /**< Q High water mark - needed by NPE */
110 * @brief Data structure used to register & initialize the Queues
114 IxEthAccQregInfo ixEthAccQmgrStaticInfo
[]=
117 IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q
,
119 ixEthRxFreeQMCallback
,
120 (IxQMgrCallbackId
) IX_ETH_PORT_1
,
121 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
122 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
123 false, /**< Disable Q notification at startup */
124 IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE
, /**< Q Condition to drive callback */
125 IX_QMGR_Q_WM_LEVEL0
, /***< Q Low water mark */
126 IX_QMGR_Q_WM_LEVEL64
, /**< Q High water mark */
130 IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q
,
132 ixEthRxFreeQMCallback
,
133 (IxQMgrCallbackId
) IX_ETH_PORT_2
,
134 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
135 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
136 false, /**< Disable Q notification at startup */
137 IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE
, /**< Q Condition to drive callback */
138 IX_QMGR_Q_WM_LEVEL0
, /**< Q Low water mark */
139 IX_QMGR_Q_WM_LEVEL64
, /**< Q High water mark */
143 IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q
,
145 ixEthRxFreeQMCallback
,
146 (IxQMgrCallbackId
) IX_ETH_PORT_3
,
147 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
148 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
149 false, /**< Disable Q notification at startup */
150 IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE
, /**< Q Condition to drive callback */
151 IX_QMGR_Q_WM_LEVEL0
, /**< Q Low water mark */
152 IX_QMGR_Q_WM_LEVEL64
, /**< Q High water mark */
156 IX_ETH_ACC_TX_FRAME_ENET0_Q
,
158 ixEthTxFrameQMCallback
,
159 (IxQMgrCallbackId
) IX_ETH_PORT_1
,
160 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
161 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
162 false, /**< Disable Q notification at startup */
163 IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE
, /**< Q Condition to drive callback */
164 IX_QMGR_Q_WM_LEVEL0
, /**< Q Low water mark */
165 IX_QMGR_Q_WM_LEVEL64
, /**< Q High water mark */
169 IX_ETH_ACC_TX_FRAME_ENET1_Q
,
171 ixEthTxFrameQMCallback
,
172 (IxQMgrCallbackId
) IX_ETH_PORT_2
,
173 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
174 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
175 false, /**< Disable Q notification at startup */
176 IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE
, /**< Q Condition to drive callback */
177 IX_QMGR_Q_WM_LEVEL0
, /**< Q Low water mark */
178 IX_QMGR_Q_WM_LEVEL64
, /**< Q High water mark */
182 IX_ETH_ACC_TX_FRAME_ENET2_Q
,
184 ixEthTxFrameQMCallback
,
185 (IxQMgrCallbackId
) IX_ETH_PORT_3
,
186 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
187 IX_QMGR_Q_ENTRY_SIZE1
, /** Queue Entry Sizes - all Q entries are single ord entries */
188 false, /** Disable Q notification at startup */
189 IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE
, /** Q Condition to drive callback */
190 IX_QMGR_Q_WM_LEVEL0
, /* No queues use almost empty */
191 IX_QMGR_Q_WM_LEVEL64
, /** Q High water mark - needed used */
195 IX_ETH_ACC_TX_FRAME_DONE_ETH_Q
,
197 ixEthTxFrameDoneQMCallback
,
198 (IxQMgrCallbackId
) 0,
199 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
200 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
201 true, /**< Enable Q notification at startup */
202 IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE
, /**< Q Condition to drive callback */
203 IX_QMGR_Q_WM_LEVEL0
, /**< Q Low water mark */
204 IX_QMGR_Q_WM_LEVEL2
, /**< Q High water mark - needed by NPE */
207 { /* Null Termination entry
211 (IxQMgrCallback
) NULL
,
212 (IxQMgrCallbackId
) 0,
225 * @brief Data structure used to register & initialize the Queues
227 * The structure will be filled at run time depending on the NPE
228 * image already loaded and the QoS configured in ethDB.
232 IxEthAccQregInfo ixEthAccQmgrRxQueuesInfo
[IX_ETHACC_MAX_RX_QUEUES
+1]=
234 { /* PlaceHolder for rx queues
235 * depending on the QoS configured
239 (IxQMgrCallback
) NULL
,
240 (IxQMgrCallbackId
) 0,
249 { /* PlaceHolder for rx queues
250 * depending on the QoS configured
254 (IxQMgrCallback
) NULL
,
255 (IxQMgrCallbackId
) 0,
264 { /* PlaceHolder for rx queues
265 * depending on the QoS configured
269 (IxQMgrCallback
) NULL
,
270 (IxQMgrCallbackId
) 0,
279 { /* PlaceHolder for rx queues
280 * depending on the QoS configured
284 (IxQMgrCallback
) NULL
,
285 (IxQMgrCallbackId
) 0,
294 { /* PlaceHolder for rx queues
295 * depending on the QoS configured
299 (IxQMgrCallback
) NULL
,
300 (IxQMgrCallbackId
) 0,
309 { /* PlaceHolder for rx queues
310 * depending on the QoS configured
314 (IxQMgrCallback
) NULL
,
315 (IxQMgrCallbackId
) 0,
324 { /* PlaceHolder for rx queues
325 * depending on the QoS configured
329 (IxQMgrCallback
) NULL
,
330 (IxQMgrCallbackId
) 0,
339 { /* PlaceHolder for rx queues
340 * depending on the QoS configured
344 (IxQMgrCallback
) NULL
,
345 (IxQMgrCallbackId
) 0,
354 { /* Null Termination entry
358 (IxQMgrCallback
) NULL
,
359 (IxQMgrCallbackId
) 0,
370 /* forward declarations */
371 IX_ETH_ACC_PRIVATE IxEthAccStatus
372 ixEthAccQMgrQueueSetup(IxEthAccQregInfo
*qInfoDes
);
375 * @fn ixEthAccQMgrQueueSetup(void)
377 * @brief Setup one queue and its event, and register the callback required
378 * by this component to the QMgr
382 IX_ETH_ACC_PRIVATE IxEthAccStatus
383 ixEthAccQMgrQueueSetup(IxEthAccQregInfo
*qInfoDes
)
388 if ( ixQMgrQConfig( qInfoDes
->qName
,
391 qInfoDes
->qWords
) != IX_SUCCESS
)
393 return IX_ETH_ACC_FAIL
;
396 if ( ixQMgrWatermarkSet( qInfoDes
->qId
,
397 qInfoDes
->AlmostEmptyThreshold
,
398 qInfoDes
->AlmostFullThreshold
401 return IX_ETH_ACC_FAIL
;
405 * Set dispatcher priority.
407 if ( ixQMgrDispatcherPrioritySet( qInfoDes
->qId
,
408 IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY
)
411 return IX_ETH_ACC_FAIL
;
415 * Register callbacks for each Q.
417 if ( ixQMgrNotificationCallbackSet(qInfoDes
->qId
,
419 qInfoDes
->callbackTag
)
422 return IX_ETH_ACC_FAIL
;
426 * Set notification condition for Q
428 if (qInfoDes
->qNotificationEnableAtStartup
== true)
430 if ( ixQMgrNotificationEnable(qInfoDes
->qId
,
431 qInfoDes
->qConditionSource
)
434 return IX_ETH_ACC_FAIL
;
438 return(IX_ETH_ACC_SUCCESS
);
442 * @fn ixEthAccQMgrQueuesConfig(void)
444 * @brief Setup all the queues and register all callbacks required
445 * by this component to the QMgr
447 * The RxFree queues, tx queues, rx queues are configured statically
449 * Rx queues configuration is driven by QoS setup.
450 * Many Rx queues may be required when QoS is enabled (this depends
451 * on IxEthDB setup and the images being downloaded). The configuration
452 * of the rxQueues is done in many steps as follows:
454 * @li select all Rx queues as configured by ethDB for all ports
455 * @li sort the queues by traffic class
456 * @li build the priority dependency for all queues
457 * @li fill the configuration for all rx queues
458 * @li configure all statically configured queues
459 * @li configure all dynamically configured queues
463 * @return IxEthAccStatus
468 IxEthAccStatus
ixEthAccQMgrQueuesConfig(void)
475 IxEthDBProperty trafficClass
;
476 } rxQueues
[IX_ETHACC_MAX_RX_QUEUES
];
479 UINT32 rxQueueCount
= 0;
480 IxQMgrQId ixQId
=IX_QMGR_MAX_NUM_QUEUES
;
481 IxEthDBStatus ixEthDBStatus
= IX_ETH_DB_SUCCESS
;
482 IxEthDBPortId ixEthDbPortId
= 0;
483 IxEthAccPortId ixEthAccPortId
= 0;
485 UINT32 ixHighestNpeId
= 0;
486 UINT32 sortIterations
= 0;
487 IxEthAccStatus ret
= IX_ETH_ACC_SUCCESS
;
488 IxEthAccQregInfo
*qInfoDes
= NULL
;
489 IxEthDBProperty ixEthDBTrafficClass
= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY
;
490 IxEthDBPropertyType ixEthDBPropertyType
= IX_ETH_DB_INTEGER_PROPERTY
;
491 UINT32 ixEthDBParameter
= 0;
492 BOOL completelySorted
= false;
494 /* Fill the corspondance between ports and queues
495 * This defines the mapping from port to queue Ids.
498 ixEthAccPortData
[IX_ETH_PORT_1
].ixEthAccRxData
.rxFreeQueue
499 = IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q
;
500 ixEthAccPortData
[IX_ETH_PORT_2
].ixEthAccRxData
.rxFreeQueue
501 = IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q
;
503 ixEthAccPortData
[IX_ETH_PORT_3
].ixEthAccRxData
.rxFreeQueue
504 = IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q
;
506 ixEthAccPortData
[IX_ETH_PORT_1
].ixEthAccTxData
.txQueue
507 = IX_ETH_ACC_TX_FRAME_ENET0_Q
;
508 ixEthAccPortData
[IX_ETH_PORT_2
].ixEthAccTxData
.txQueue
509 = IX_ETH_ACC_TX_FRAME_ENET1_Q
;
511 ixEthAccPortData
[IX_ETH_PORT_3
].ixEthAccTxData
.txQueue
512 = IX_ETH_ACC_TX_FRAME_ENET2_Q
;
514 /* Fill the corspondance between ports and NPEs
515 * This defines the mapping from port to npeIds.
518 ixEthAccPortData
[IX_ETH_PORT_1
].npeId
= IX_NPEMH_NPEID_NPEB
;
519 ixEthAccPortData
[IX_ETH_PORT_2
].npeId
= IX_NPEMH_NPEID_NPEC
;
521 ixEthAccPortData
[IX_ETH_PORT_3
].npeId
= IX_NPEMH_NPEID_NPEA
;
523 /* set the default rx scheduling discipline */
524 ixEthAccDataInfo
.schDiscipline
= FIFO_NO_PRIORITY
;
527 * Queue Selection step:
529 * The following code selects all the queues and build
530 * a temporary array which contains for each queue
532 * - the highest traffic class (in case of many
533 * priorities configured for the same queue on different
535 * - the number of different Npes which are
536 * configured to write to this queue.
538 * The output of this loop is a temporary array of RX queues
542 #ifdef CONFIG_IXP425_COMPONENT_ETHDB
543 for (ixEthAccPortId
= 0;
544 (ixEthAccPortId
< IX_ETH_ACC_NUMBER_OF_PORTS
)
545 && (ret
== IX_ETH_ACC_SUCCESS
);
548 /* map between ethDb and ethAcc port Ids */
549 ixEthDbPortId
= (IxEthDBPortId
)ixEthAccPortId
;
551 /* map between npeId and ethAcc port Ids */
552 ixNpeId
= IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId
);
554 /* Iterate thru the different priorities */
555 for (ixEthDBTrafficClass
= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY
;
556 ixEthDBTrafficClass
<= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY
;
557 ixEthDBTrafficClass
++)
559 ixEthDBStatus
= ixEthDBFeaturePropertyGet(
563 &ixEthDBPropertyType
,
564 (void *)&ixEthDBParameter
);
566 if (ixEthDBStatus
== IX_ETH_DB_SUCCESS
)
568 /* This port and QoS class are mapped to
571 if (ixEthDBPropertyType
== IX_ETH_DB_INTEGER_PROPERTY
)
573 /* remember the highest npe Id supporting ethernet */
574 if (ixNpeId
> ixHighestNpeId
)
576 ixHighestNpeId
= ixNpeId
;
579 /* search the queue in the list of queues
580 * already used by an other port or QoS
583 rxQueue
< rxQueueCount
;
586 if (rxQueues
[rxQueue
].qId
== (IxQMgrQId
)ixEthDBParameter
)
588 /* found an existing setup, update the number of ports
589 * for this queue if the port maps to
592 if (rxQueues
[rxQueue
].npeId
!= ixNpeId
)
594 rxQueues
[rxQueue
].npeCount
++;
595 rxQueues
[rxQueue
].npeId
= ixNpeId
;
597 /* get the highest traffic class for this queue */
598 if (rxQueues
[rxQueue
].trafficClass
> ixEthDBTrafficClass
)
600 rxQueues
[rxQueue
].trafficClass
= ixEthDBTrafficClass
;
605 if (rxQueue
== rxQueueCount
)
607 /* new queue not found in the current list,
610 IX_OSAL_ASSERT(rxQueueCount
< IX_ETHACC_MAX_RX_QUEUES
);
611 rxQueues
[rxQueueCount
].qId
= ixEthDBParameter
;
612 rxQueues
[rxQueueCount
].npeCount
= 1;
613 rxQueues
[rxQueueCount
].npeId
= ixNpeId
;
614 rxQueues
[rxQueueCount
].trafficClass
= ixEthDBTrafficClass
;
620 /* unexpected property type (not Integer) */
621 ret
= IX_ETH_ACC_FAIL
;
623 IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: unexpected property type returned by EthDB\n", 0, 0, 0, 0, 0, 0);
625 /* no point to continue to iterate */
631 /* No Rx queue configured for this port
632 * and this traffic class. Do nothing.
637 /* notify EthDB that queue initialization is complete and traffic class allocation is frozen */
638 ixEthDBFeaturePropertySet(ixEthDbPortId
,
640 IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE
,
646 ixNpeId
= IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId
);
648 rxQueues
[0].npeCount
= 1;
649 rxQueues
[0].npeId
= ixNpeId
;
650 rxQueues
[0].trafficClass
= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY
;
655 /* check there is at least 1 rx queue : there is no point
656 * to continue if there is no rx queue configured
658 if ((rxQueueCount
== 0) || (ret
== IX_ETH_ACC_FAIL
))
660 IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: no queues configured, bailing out\n", 0, 0, 0, 0, 0, 0);
661 return (IX_ETH_ACC_FAIL
);
666 * Re-order the array of queues by decreasing traffic class
667 * using a bubble sort. (trafficClass 0 is the lowest
668 * priority traffic, trafficClass 7 is the highest priority traffic)
670 * Primary sort order is traffic class
671 * Secondary sort order is npeId
673 * Note that a bubble sort algorithm is not very efficient when
674 * the number of queues grows . However, this is not a very bad choice
675 * considering the very small number of entries to sort. Also, bubble
676 * sort is extremely fast when the list is already sorted.
678 * The output of this loop is a sorted array of queues.
685 completelySorted
= true;
687 rxQueue
< rxQueueCount
- sortIterations
;
690 /* compare adjacent elements */
691 if ((rxQueues
[rxQueue
].trafficClass
<
692 rxQueues
[rxQueue
+1].trafficClass
)
693 || ((rxQueues
[rxQueue
].trafficClass
==
694 rxQueues
[rxQueue
+1].trafficClass
)
695 &&(rxQueues
[rxQueue
].npeId
<
696 rxQueues
[rxQueue
+1].npeId
)))
698 /* swap adjacent elements */
699 int npeCount
= rxQueues
[rxQueue
].npeCount
;
700 UINT32 npeId
= rxQueues
[rxQueue
].npeId
;
701 IxQMgrQId qId
= rxQueues
[rxQueue
].qId
;
702 IxEthDBProperty trafficClass
= rxQueues
[rxQueue
].trafficClass
;
703 rxQueues
[rxQueue
].npeCount
= rxQueues
[rxQueue
+1].npeCount
;
704 rxQueues
[rxQueue
].npeId
= rxQueues
[rxQueue
+1].npeId
;
705 rxQueues
[rxQueue
].qId
= rxQueues
[rxQueue
+1].qId
;
706 rxQueues
[rxQueue
].trafficClass
= rxQueues
[rxQueue
+1].trafficClass
;
707 rxQueues
[rxQueue
+1].npeCount
= npeCount
;
708 rxQueues
[rxQueue
+1].npeId
= npeId
;
709 rxQueues
[rxQueue
+1].qId
= qId
;
710 rxQueues
[rxQueue
+1].trafficClass
= trafficClass
;
711 completelySorted
= false;
715 while (!completelySorted
);
717 /* Queue traffic class list:
719 * Fill an array of rx queues linked by ascending traffic classes.
721 * If the queues are configured as follows
722 * qId 6 -> traffic class 0 (lowest)
723 * qId 7 -> traffic class 0
724 * qId 8 -> traffic class 6
725 * qId 12 -> traffic class 7 (highest)
727 * Then the output of this loop will be
729 * higherPriorityQueue[6] = 8
730 * higherPriorityQueue[7] = 8
731 * higherPriorityQueue[8] = 12
732 * higherPriorityQueue[12] = Invalid queueId
733 * higherPriorityQueue[...] = Invalid queueId
735 * Note that this queue ordering does not handle all possibilities
736 * that could result from different rules associated with different
737 * ports, and inconsistencies in the rules. In all cases, the
738 * output of this algorithm is a simple linked list of queues,
739 * without closed circuit.
741 * This list is implemented as an array with invalid values initialized
742 * with an "invalid" queue id which is the maximum number of queues.
747 * Initialise the rx queue list.
749 for (rxQueue
= 0; rxQueue
< IX_QMGR_MAX_NUM_QUEUES
; rxQueue
++)
751 ixEthAccDataInfo
.higherPriorityQueue
[rxQueue
] = IX_QMGR_MAX_NUM_QUEUES
;
754 /* build the linked list for this NPE.
757 ixNpeId
<= ixHighestNpeId
;
760 /* iterate thru the sorted list of queues
762 ixQId
= IX_QMGR_MAX_NUM_QUEUES
;
764 rxQueue
< rxQueueCount
;
767 if (rxQueues
[rxQueue
].npeId
== ixNpeId
)
769 ixEthAccDataInfo
.higherPriorityQueue
[rxQueues
[rxQueue
].qId
] = ixQId
;
770 /* iterate thru queues with the same traffic class
771 * than the current queue. (queues are ordered by descending
772 * traffic classes and npeIds).
774 while ((rxQueue
< rxQueueCount
- 1)
775 && (rxQueues
[rxQueue
].trafficClass
776 == rxQueues
[rxQueue
+1].trafficClass
)
777 && (ixNpeId
== rxQueues
[rxQueue
].npeId
))
780 ixEthAccDataInfo
.higherPriorityQueue
[rxQueues
[rxQueue
].qId
] = ixQId
;
782 ixQId
= rxQueues
[rxQueue
].qId
;
787 /* point on the first dynamic queue description */
788 qInfoDes
= ixEthAccQmgrRxQueuesInfo
;
790 /* update the list of queues with the rx queues */
792 (rxQueue
< rxQueueCount
) && (ret
== IX_ETH_ACC_SUCCESS
);
795 /* Don't utilize more than IX_ETHACC_MAX_LARGE_RX_QUEUES queues
796 * with the full 128 entries. For the lower priority queues, use
797 * a smaller number of entries. This ensures queue resources
798 * remain available for other components.
800 if( (rxQueueCount
> IX_ETHACC_MAX_LARGE_RX_QUEUES
) &&
801 (rxQueue
< rxQueueCount
- IX_ETHACC_MAX_LARGE_RX_QUEUES
) )
803 /* add the small RX Queue setup template to the list of queues */
804 memcpy(qInfoDes
, &ixEthAccQmgrRxSmallTemplate
, sizeof(*qInfoDes
));
806 /* add the default RX Queue setup template to the list of queues */
807 memcpy(qInfoDes
, &ixEthAccQmgrRxDefaultTemplate
, sizeof(*qInfoDes
));
810 /* setup the RxQueue ID */
811 qInfoDes
->qId
= rxQueues
[rxQueue
].qId
;
813 /* setup the RxQueue watermark level
815 * Each queue can be filled by many NPEs. To avoid the
816 * NPEs to write to a full queue, need to set the
817 * high watermark level for nearly full condition.
818 * (the high watermark level are a power of 2
819 * starting from the top of the queue)
821 * Number of watermark
829 * n approx. 2**ceil(log2(n))
831 if (rxQueues
[rxQueue
].npeCount
== 1)
833 qInfoDes
->AlmostFullThreshold
= IX_QMGR_Q_WM_LEVEL0
;
835 else if (rxQueues
[rxQueue
].npeCount
== 2)
837 qInfoDes
->AlmostFullThreshold
= IX_QMGR_Q_WM_LEVEL1
;
839 else if (rxQueues
[rxQueue
].npeCount
== 3)
841 qInfoDes
->AlmostFullThreshold
= IX_QMGR_Q_WM_LEVEL2
;
845 /* reach the maximum number for CSR 2.0 */
846 IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: maximum number of NPEs per queue reached, bailing out\n", 0, 0, 0, 0, 0, 0);
847 ret
= IX_ETH_ACC_FAIL
;
851 /* move to next queue entry */
855 /* configure the static list (RxFree, Tx and TxDone queues) */
856 for (qInfoDes
= ixEthAccQmgrStaticInfo
;
857 (qInfoDes
->qCallback
!= (IxQMgrCallback
) NULL
)
858 && (ret
== IX_ETH_ACC_SUCCESS
);
861 ret
= ixEthAccQMgrQueueSetup(qInfoDes
);
864 /* configure the dynamic list (Rx queues) */
865 for (qInfoDes
= ixEthAccQmgrRxQueuesInfo
;
866 (qInfoDes
->qCallback
!= (IxQMgrCallback
) NULL
)
867 && (ret
== IX_ETH_ACC_SUCCESS
);
870 ret
= ixEthAccQMgrQueueSetup(qInfoDes
);
877 * @fn ixEthAccQMgrRxQEntryGet(UINT32 *rxQueueEntries)
879 * @brief Add and return the total number of entries in all Rx queues
881 * @param UINT32 rxQueueEntries[in] number of entries in all queues
885 * @note Rx queues configuration is driven by Qos Setup. There is a
886 * variable number of rx queues which are set at initialisation.
891 void ixEthAccQMgrRxQEntryGet(UINT32
*numRxQueueEntries
)
894 IxEthAccQregInfo
*qInfoDes
;;
896 *numRxQueueEntries
= 0;
898 /* iterate thru rx queues */
899 for (qInfoDes
= ixEthAccQmgrRxQueuesInfo
;
900 qInfoDes
->qCallback
!= (IxQMgrCallback
)NULL
;
903 /* retrieve the rx queue level */
905 ixQMgrQNumEntriesGet(qInfoDes
->qId
, &rxQueueLevel
);
906 (*numRxQueueEntries
) += rxQueueLevel
;
911 * @fn ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback)
913 * @brief Change the callback registered to all rx queues.
915 * @param IxQMgrCallback ixQMgrCallback[in] QMgr callback to register
917 * @return IxEthAccStatus
919 * @note The user may decide to use different Rx mechanisms
920 * (e.g. receive many frames at the same time , or receive
921 * one frame at a time, depending on the overall application
922 * performances). A different QMgr callback is registered. This
923 * way, there is no excessive pointer checks in the datapath.
928 IxEthAccStatus
ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback
)
930 IxEthAccQregInfo
*qInfoDes
;
931 IxEthAccStatus ret
= IX_ETH_ACC_SUCCESS
;
933 /* parameter check */
934 if (NULL
== ixQMgrCallback
)
936 ret
= IX_ETH_ACC_FAIL
;
939 /* iterate thru rx queues */
940 for (qInfoDes
= ixEthAccQmgrRxQueuesInfo
;
941 (qInfoDes
->qCallback
!= (IxQMgrCallback
) NULL
)
942 && (ret
== IX_ETH_ACC_SUCCESS
);
945 /* register the rx callback for all queues */
946 if (ixQMgrNotificationCallbackSet(qInfoDes
->qId
,
948 qInfoDes
->callbackTag
951 ret
= IX_ETH_ACC_FAIL
;
958 * @fn ixEthAccSingleEthNpeCheck(IxEthAccPortId portId)
960 * @brief Check the npe exists for this port
962 * @param IxEthAccPortId portId[in] port
964 * @return IxEthAccStatus
969 IxEthAccStatus
ixEthAccSingleEthNpeCheck(IxEthAccPortId portId
)
972 /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */
973 if ((IX_FEATURE_CTRL_SILICON_TYPE_A0
!=
974 (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK
))
975 || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X
!= ixFeatureCtrlDeviceRead ()))
977 if ((IX_ETH_PORT_1
== portId
) &&
978 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0
) ==
979 IX_FEATURE_CTRL_COMPONENT_ENABLED
))
981 return IX_ETH_ACC_SUCCESS
;
984 if ((IX_ETH_PORT_2
== portId
) &&
985 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1
) ==
986 IX_FEATURE_CTRL_COMPONENT_ENABLED
))
988 return IX_ETH_ACC_SUCCESS
;
991 if ((IX_ETH_PORT_3
== portId
) &&
992 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH
) ==
993 IX_FEATURE_CTRL_COMPONENT_ENABLED
))
995 return IX_ETH_ACC_SUCCESS
;
998 return IX_ETH_ACC_FAIL
;
1001 return IX_ETH_ACC_SUCCESS
;
1005 * @fn ixEthAccStatsShow(void)
1007 * @brief Displays all EthAcc stats
1012 void ixEthAccStatsShow(IxEthAccPortId portId
)
1016 printf("\nPort %u\nUnicast MAC : ", portId
);
1017 ixEthAccPortUnicastAddressShow(portId
);
1018 ixEthAccPortMulticastAddressShow(portId
);
1021 ixEthAccDataPlaneShow();