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 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
24 * 1. Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * 3. Neither the name of the Intel Corporation nor the names of its contributors
30 * may be used to endorse or promote products derived from this software
31 * without specific prior written permission.
34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
35 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * -- End of Copyright Notice --
51 * Component header files
58 #include "IxEthDBPortDefs.h"
59 #include "IxFeatureCtrl.h"
60 #include "IxEthAcc_p.h"
61 #include "IxEthAccQueueAssign_p.h"
63 #include "IxEthAccDataPlane_p.h"
64 #include "IxEthAccMii_p.h"
67 * @addtogroup IxEthAccPri
71 extern IxEthAccInfo ixEthAccDataInfo
;
75 * @brief Maximum number of RX queues set to be the maximum number
79 #define IX_ETHACC_MAX_RX_QUEUES \
80 (IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY \
81 - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY \
86 * @brief Maximum number of 128 entry RX queues
89 #define IX_ETHACC_MAX_LARGE_RX_QUEUES 4
93 * @brief Data structure template for Default RX Queues
97 IxEthAccQregInfo ixEthAccQmgrRxDefaultTemplate
=
99 IX_ETH_ACC_RX_FRAME_ETH_Q
, /**< Queue ID */
101 ixEthRxFrameQMCallback
, /**< Functional callback */
102 (IxQMgrCallbackId
) 0, /**< Callback tag */
103 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
104 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
105 TRUE
, /**< Enable Q notification at startup */
106 IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE
,/**< Q Condition to drive callback */
107 IX_QMGR_Q_WM_LEVEL0
, /**< Q Low water mark */
108 IX_QMGR_Q_WM_LEVEL1
, /**< Q High water mark - needed by NPE */
113 * @brief Data structure template for Small RX Queues
117 IxEthAccQregInfo ixEthAccQmgrRxSmallTemplate
=
119 IX_ETH_ACC_RX_FRAME_ETH_Q
, /**< Queue ID */
121 ixEthRxFrameQMCallback
, /**< Functional callback */
122 (IxQMgrCallbackId
) 0, /**< Callback tag */
123 IX_QMGR_Q_SIZE64
, /**< Allocate Smaller Q */
124 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
125 TRUE
, /**< Enable Q notification at startup */
126 IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE
,/**< Q Condition to drive callback */
127 IX_QMGR_Q_WM_LEVEL0
, /**< Q Low water mark */
128 IX_QMGR_Q_WM_LEVEL1
, /**< Q High water mark - needed by NPE */
134 * @brief Data structure used to register & initialize the Queues
138 IxEthAccQregInfo ixEthAccQmgrStaticInfo
[]=
141 IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q
,
143 ixEthRxFreeQMCallback
,
144 (IxQMgrCallbackId
) IX_ETH_PORT_1
,
145 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
146 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
147 FALSE
, /**< Disable Q notification at startup */
148 IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE
, /**< Q Condition to drive callback */
149 IX_QMGR_Q_WM_LEVEL0
, /***< Q Low water mark */
150 IX_QMGR_Q_WM_LEVEL64
, /**< Q High water mark */
154 IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q
,
156 ixEthRxFreeQMCallback
,
157 (IxQMgrCallbackId
) IX_ETH_PORT_2
,
158 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
159 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
160 FALSE
, /**< Disable Q notification at startup */
161 IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE
, /**< Q Condition to drive callback */
162 IX_QMGR_Q_WM_LEVEL0
, /**< Q Low water mark */
163 IX_QMGR_Q_WM_LEVEL64
, /**< Q High water mark */
167 IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q
,
169 ixEthRxFreeQMCallback
,
170 (IxQMgrCallbackId
) IX_ETH_PORT_3
,
171 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
172 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
173 FALSE
, /**< Disable Q notification at startup */
174 IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE
, /**< Q Condition to drive callback */
175 IX_QMGR_Q_WM_LEVEL0
, /**< Q Low water mark */
176 IX_QMGR_Q_WM_LEVEL64
, /**< Q High water mark */
180 IX_ETH_ACC_TX_FRAME_ENET0_Q
,
182 ixEthTxFrameQMCallback
,
183 (IxQMgrCallbackId
) IX_ETH_PORT_1
,
184 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
185 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
186 FALSE
, /**< Disable Q notification at startup */
187 IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE
, /**< Q Condition to drive callback */
188 IX_QMGR_Q_WM_LEVEL0
, /**< Q Low water mark */
189 IX_QMGR_Q_WM_LEVEL64
, /**< Q High water mark */
193 IX_ETH_ACC_TX_FRAME_ENET1_Q
,
195 ixEthTxFrameQMCallback
,
196 (IxQMgrCallbackId
) IX_ETH_PORT_2
,
197 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
198 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
199 FALSE
, /**< Disable Q notification at startup */
200 IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE
, /**< Q Condition to drive callback */
201 IX_QMGR_Q_WM_LEVEL0
, /**< Q Low water mark */
202 IX_QMGR_Q_WM_LEVEL64
, /**< Q High water mark */
206 IX_ETH_ACC_TX_FRAME_ENET2_Q
,
208 ixEthTxFrameQMCallback
,
209 (IxQMgrCallbackId
) IX_ETH_PORT_3
,
210 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
211 IX_QMGR_Q_ENTRY_SIZE1
, /** Queue Entry Sizes - all Q entries are single ord entries */
212 FALSE
, /** Disable Q notification at startup */
213 IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE
, /** Q Condition to drive callback */
214 IX_QMGR_Q_WM_LEVEL0
, /* No queues use almost empty */
215 IX_QMGR_Q_WM_LEVEL64
, /** Q High water mark - needed used */
219 IX_ETH_ACC_TX_FRAME_DONE_ETH_Q
,
221 ixEthTxFrameDoneQMCallback
,
222 (IxQMgrCallbackId
) 0,
223 IX_QMGR_Q_SIZE128
, /**< Allocate Max Size Q */
224 IX_QMGR_Q_ENTRY_SIZE1
, /**< Queue Entry Sizes - all Q entries are single word entries */
225 TRUE
, /**< Enable Q notification at startup */
226 IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE
, /**< Q Condition to drive callback */
227 IX_QMGR_Q_WM_LEVEL0
, /**< Q Low water mark */
228 IX_QMGR_Q_WM_LEVEL2
, /**< Q High water mark - needed by NPE */
231 { /* Null Termination entry
235 (IxQMgrCallback
) NULL
,
236 (IxQMgrCallbackId
) 0,
249 * @brief Data structure used to register & initialize the Queues
251 * The structure will be filled at run time depending on the NPE
252 * image already loaded and the QoS configured in ethDB.
256 IxEthAccQregInfo ixEthAccQmgrRxQueuesInfo
[IX_ETHACC_MAX_RX_QUEUES
+1]=
258 { /* PlaceHolder for rx queues
259 * depending on the QoS configured
263 (IxQMgrCallback
) NULL
,
264 (IxQMgrCallbackId
) 0,
273 { /* PlaceHolder for rx queues
274 * depending on the QoS configured
278 (IxQMgrCallback
) NULL
,
279 (IxQMgrCallbackId
) 0,
288 { /* PlaceHolder for rx queues
289 * depending on the QoS configured
293 (IxQMgrCallback
) NULL
,
294 (IxQMgrCallbackId
) 0,
303 { /* PlaceHolder for rx queues
304 * depending on the QoS configured
308 (IxQMgrCallback
) NULL
,
309 (IxQMgrCallbackId
) 0,
318 { /* PlaceHolder for rx queues
319 * depending on the QoS configured
323 (IxQMgrCallback
) NULL
,
324 (IxQMgrCallbackId
) 0,
333 { /* PlaceHolder for rx queues
334 * depending on the QoS configured
338 (IxQMgrCallback
) NULL
,
339 (IxQMgrCallbackId
) 0,
348 { /* PlaceHolder for rx queues
349 * depending on the QoS configured
353 (IxQMgrCallback
) NULL
,
354 (IxQMgrCallbackId
) 0,
363 { /* PlaceHolder for rx queues
364 * depending on the QoS configured
368 (IxQMgrCallback
) NULL
,
369 (IxQMgrCallbackId
) 0,
378 { /* Null Termination entry
382 (IxQMgrCallback
) NULL
,
383 (IxQMgrCallbackId
) 0,
394 /* forward declarations */
395 IX_ETH_ACC_PRIVATE IxEthAccStatus
396 ixEthAccQMgrQueueSetup(IxEthAccQregInfo
*qInfoDes
);
399 * @fn ixEthAccQMgrQueueSetup(void)
401 * @brief Setup one queue and its event, and register the callback required
402 * by this component to the QMgr
406 IX_ETH_ACC_PRIVATE IxEthAccStatus
407 ixEthAccQMgrQueueSetup(IxEthAccQregInfo
*qInfoDes
)
412 if ( ixQMgrQConfig( qInfoDes
->qName
,
415 qInfoDes
->qWords
) != IX_SUCCESS
)
417 return IX_ETH_ACC_FAIL
;
420 if ( ixQMgrWatermarkSet( qInfoDes
->qId
,
421 qInfoDes
->AlmostEmptyThreshold
,
422 qInfoDes
->AlmostFullThreshold
425 return IX_ETH_ACC_FAIL
;
429 * Set dispatcher priority.
431 if ( ixQMgrDispatcherPrioritySet( qInfoDes
->qId
,
432 IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY
)
435 return IX_ETH_ACC_FAIL
;
439 * Register callbacks for each Q.
441 if ( ixQMgrNotificationCallbackSet(qInfoDes
->qId
,
443 qInfoDes
->callbackTag
)
446 return IX_ETH_ACC_FAIL
;
450 * Set notification condition for Q
452 if ( qInfoDes
->qNotificationEnableAtStartup
== TRUE
)
454 if ( ixQMgrNotificationEnable(qInfoDes
->qId
,
455 qInfoDes
->qConditionSource
)
458 return IX_ETH_ACC_FAIL
;
462 return(IX_ETH_ACC_SUCCESS
);
466 * @fn ixEthAccQMgrQueuesConfig(void)
468 * @brief Setup all the queues and register all callbacks required
469 * by this component to the QMgr
471 * The RxFree queues, tx queues, rx queues are configured statically
473 * Rx queues configuration is driven by QoS setup.
474 * Many Rx queues may be required when QoS is enabled (this depends
475 * on IxEthDB setup and the images being downloaded). The configuration
476 * of the rxQueues is done in many steps as follows:
478 * @li select all Rx queues as configured by ethDB for all ports
479 * @li sort the queues by traffic class
480 * @li build the priority dependency for all queues
481 * @li fill the configuration for all rx queues
482 * @li configure all statically configured queues
483 * @li configure all dynamically configured queues
487 * @return IxEthAccStatus
492 IxEthAccStatus
ixEthAccQMgrQueuesConfig(void)
499 IxEthDBProperty trafficClass
;
500 } rxQueues
[IX_ETHACC_MAX_RX_QUEUES
];
503 UINT32 rxQueueCount
= 0;
504 IxQMgrQId ixQId
=IX_QMGR_MAX_NUM_QUEUES
;
505 IxEthDBStatus ixEthDBStatus
= IX_ETH_DB_SUCCESS
;
506 IxEthDBPortId ixEthDbPortId
= 0;
507 IxEthAccPortId ixEthAccPortId
= 0;
509 UINT32 ixHighestNpeId
= 0;
510 UINT32 sortIterations
= 0;
511 IxEthAccStatus ret
= IX_ETH_ACC_SUCCESS
;
512 IxEthAccQregInfo
*qInfoDes
= NULL
;
513 IxEthDBProperty ixEthDBTrafficClass
= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY
;
514 IxEthDBPropertyType ixEthDBPropertyType
= IX_ETH_DB_INTEGER_PROPERTY
;
515 UINT32 ixEthDBParameter
= 0;
516 BOOL completelySorted
= FALSE
;
518 /* Fill the corspondance between ports and queues
519 * This defines the mapping from port to queue Ids.
522 ixEthAccPortData
[IX_ETH_PORT_1
].ixEthAccRxData
.rxFreeQueue
523 = IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q
;
524 ixEthAccPortData
[IX_ETH_PORT_2
].ixEthAccRxData
.rxFreeQueue
525 = IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q
;
527 ixEthAccPortData
[IX_ETH_PORT_3
].ixEthAccRxData
.rxFreeQueue
528 = IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q
;
530 ixEthAccPortData
[IX_ETH_PORT_1
].ixEthAccTxData
.txQueue
531 = IX_ETH_ACC_TX_FRAME_ENET0_Q
;
532 ixEthAccPortData
[IX_ETH_PORT_2
].ixEthAccTxData
.txQueue
533 = IX_ETH_ACC_TX_FRAME_ENET1_Q
;
535 ixEthAccPortData
[IX_ETH_PORT_3
].ixEthAccTxData
.txQueue
536 = IX_ETH_ACC_TX_FRAME_ENET2_Q
;
538 /* Fill the corspondance between ports and NPEs
539 * This defines the mapping from port to npeIds.
542 ixEthAccPortData
[IX_ETH_PORT_1
].npeId
= IX_NPEMH_NPEID_NPEB
;
543 ixEthAccPortData
[IX_ETH_PORT_2
].npeId
= IX_NPEMH_NPEID_NPEC
;
545 ixEthAccPortData
[IX_ETH_PORT_3
].npeId
= IX_NPEMH_NPEID_NPEA
;
547 /* set the default rx scheduling discipline */
548 ixEthAccDataInfo
.schDiscipline
= FIFO_NO_PRIORITY
;
551 * Queue Selection step:
553 * The following code selects all the queues and build
554 * a temporary array which contains for each queue
556 * - the highest traffic class (in case of many
557 * priorities configured for the same queue on different
559 * - the number of different Npes which are
560 * configured to write to this queue.
562 * The output of this loop is a temporary array of RX queues
566 #ifdef CONFIG_IXP425_COMPONENT_ETHDB
567 for (ixEthAccPortId
= 0;
568 (ixEthAccPortId
< IX_ETH_ACC_NUMBER_OF_PORTS
)
569 && (ret
== IX_ETH_ACC_SUCCESS
);
572 /* map between ethDb and ethAcc port Ids */
573 ixEthDbPortId
= (IxEthDBPortId
)ixEthAccPortId
;
575 /* map between npeId and ethAcc port Ids */
576 ixNpeId
= IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId
);
578 /* Iterate thru the different priorities */
579 for (ixEthDBTrafficClass
= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY
;
580 ixEthDBTrafficClass
<= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY
;
581 ixEthDBTrafficClass
++)
583 ixEthDBStatus
= ixEthDBFeaturePropertyGet(
587 &ixEthDBPropertyType
,
588 (void *)&ixEthDBParameter
);
590 if (ixEthDBStatus
== IX_ETH_DB_SUCCESS
)
592 /* This port and QoS class are mapped to
595 if (ixEthDBPropertyType
== IX_ETH_DB_INTEGER_PROPERTY
)
597 /* remember the highest npe Id supporting ethernet */
598 if (ixNpeId
> ixHighestNpeId
)
600 ixHighestNpeId
= ixNpeId
;
603 /* search the queue in the list of queues
604 * already used by an other port or QoS
607 rxQueue
< rxQueueCount
;
610 if (rxQueues
[rxQueue
].qId
== (IxQMgrQId
)ixEthDBParameter
)
612 /* found an existing setup, update the number of ports
613 * for this queue if the port maps to
616 if (rxQueues
[rxQueue
].npeId
!= ixNpeId
)
618 rxQueues
[rxQueue
].npeCount
++;
619 rxQueues
[rxQueue
].npeId
= ixNpeId
;
621 /* get the highest traffic class for this queue */
622 if (rxQueues
[rxQueue
].trafficClass
> ixEthDBTrafficClass
)
624 rxQueues
[rxQueue
].trafficClass
= ixEthDBTrafficClass
;
629 if (rxQueue
== rxQueueCount
)
631 /* new queue not found in the current list,
634 IX_OSAL_ASSERT(rxQueueCount
< IX_ETHACC_MAX_RX_QUEUES
);
635 rxQueues
[rxQueueCount
].qId
= ixEthDBParameter
;
636 rxQueues
[rxQueueCount
].npeCount
= 1;
637 rxQueues
[rxQueueCount
].npeId
= ixNpeId
;
638 rxQueues
[rxQueueCount
].trafficClass
= ixEthDBTrafficClass
;
644 /* unexpected property type (not Integer) */
645 ret
= IX_ETH_ACC_FAIL
;
647 IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: unexpected property type returned by EthDB\n", 0, 0, 0, 0, 0, 0);
649 /* no point to continue to iterate */
655 /* No Rx queue configured for this port
656 * and this traffic class. Do nothing.
661 /* notify EthDB that queue initialization is complete and traffic class allocation is frozen */
662 ixEthDBFeaturePropertySet(ixEthDbPortId
,
664 IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE
,
670 ixNpeId
= IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId
);
672 rxQueues
[0].npeCount
= 1;
673 rxQueues
[0].npeId
= ixNpeId
;
674 rxQueues
[0].trafficClass
= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY
;
679 /* check there is at least 1 rx queue : there is no point
680 * to continue if there is no rx queue configured
682 if ((rxQueueCount
== 0) || (ret
== IX_ETH_ACC_FAIL
))
684 IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: no queues configured, bailing out\n", 0, 0, 0, 0, 0, 0);
685 return (IX_ETH_ACC_FAIL
);
690 * Re-order the array of queues by decreasing traffic class
691 * using a bubble sort. (trafficClass 0 is the lowest
692 * priority traffic, trafficClass 7 is the highest priority traffic)
694 * Primary sort order is traffic class
695 * Secondary sort order is npeId
697 * Note that a bubble sort algorithm is not very efficient when
698 * the number of queues grows . However, this is not a very bad choice
699 * considering the very small number of entries to sort. Also, bubble
700 * sort is extremely fast when the list is already sorted.
702 * The output of this loop is a sorted array of queues.
709 completelySorted
= TRUE
;
711 rxQueue
< rxQueueCount
- sortIterations
;
714 /* compare adjacent elements */
715 if ((rxQueues
[rxQueue
].trafficClass
<
716 rxQueues
[rxQueue
+1].trafficClass
)
717 || ((rxQueues
[rxQueue
].trafficClass
==
718 rxQueues
[rxQueue
+1].trafficClass
)
719 &&(rxQueues
[rxQueue
].npeId
<
720 rxQueues
[rxQueue
+1].npeId
)))
722 /* swap adjacent elements */
723 int npeCount
= rxQueues
[rxQueue
].npeCount
;
724 UINT32 npeId
= rxQueues
[rxQueue
].npeId
;
725 IxQMgrQId qId
= rxQueues
[rxQueue
].qId
;
726 IxEthDBProperty trafficClass
= rxQueues
[rxQueue
].trafficClass
;
727 rxQueues
[rxQueue
].npeCount
= rxQueues
[rxQueue
+1].npeCount
;
728 rxQueues
[rxQueue
].npeId
= rxQueues
[rxQueue
+1].npeId
;
729 rxQueues
[rxQueue
].qId
= rxQueues
[rxQueue
+1].qId
;
730 rxQueues
[rxQueue
].trafficClass
= rxQueues
[rxQueue
+1].trafficClass
;
731 rxQueues
[rxQueue
+1].npeCount
= npeCount
;
732 rxQueues
[rxQueue
+1].npeId
= npeId
;
733 rxQueues
[rxQueue
+1].qId
= qId
;
734 rxQueues
[rxQueue
+1].trafficClass
= trafficClass
;
735 completelySorted
= FALSE
;
739 while (!completelySorted
);
741 /* Queue traffic class list:
743 * Fill an array of rx queues linked by ascending traffic classes.
745 * If the queues are configured as follows
746 * qId 6 -> traffic class 0 (lowest)
747 * qId 7 -> traffic class 0
748 * qId 8 -> traffic class 6
749 * qId 12 -> traffic class 7 (highest)
751 * Then the output of this loop will be
753 * higherPriorityQueue[6] = 8
754 * higherPriorityQueue[7] = 8
755 * higherPriorityQueue[8] = 12
756 * higherPriorityQueue[12] = Invalid queueId
757 * higherPriorityQueue[...] = Invalid queueId
759 * Note that this queue ordering does not handle all possibilities
760 * that could result from different rules associated with different
761 * ports, and inconsistencies in the rules. In all cases, the
762 * output of this algorithm is a simple linked list of queues,
763 * without closed circuit.
765 * This list is implemented as an array with invalid values initialized
766 * with an "invalid" queue id which is the maximum number of queues.
771 * Initialise the rx queue list.
773 for (rxQueue
= 0; rxQueue
< IX_QMGR_MAX_NUM_QUEUES
; rxQueue
++)
775 ixEthAccDataInfo
.higherPriorityQueue
[rxQueue
] = IX_QMGR_MAX_NUM_QUEUES
;
778 /* build the linked list for this NPE.
781 ixNpeId
<= ixHighestNpeId
;
784 /* iterate thru the sorted list of queues
786 ixQId
= IX_QMGR_MAX_NUM_QUEUES
;
788 rxQueue
< rxQueueCount
;
791 if (rxQueues
[rxQueue
].npeId
== ixNpeId
)
793 ixEthAccDataInfo
.higherPriorityQueue
[rxQueues
[rxQueue
].qId
] = ixQId
;
794 /* iterate thru queues with the same traffic class
795 * than the current queue. (queues are ordered by descending
796 * traffic classes and npeIds).
798 while ((rxQueue
< rxQueueCount
- 1)
799 && (rxQueues
[rxQueue
].trafficClass
800 == rxQueues
[rxQueue
+1].trafficClass
)
801 && (ixNpeId
== rxQueues
[rxQueue
].npeId
))
804 ixEthAccDataInfo
.higherPriorityQueue
[rxQueues
[rxQueue
].qId
] = ixQId
;
806 ixQId
= rxQueues
[rxQueue
].qId
;
811 /* point on the first dynamic queue description */
812 qInfoDes
= ixEthAccQmgrRxQueuesInfo
;
814 /* update the list of queues with the rx queues */
816 (rxQueue
< rxQueueCount
) && (ret
== IX_ETH_ACC_SUCCESS
);
819 /* Don't utilize more than IX_ETHACC_MAX_LARGE_RX_QUEUES queues
820 * with the full 128 entries. For the lower priority queues, use
821 * a smaller number of entries. This ensures queue resources
822 * remain available for other components.
824 if( (rxQueueCount
> IX_ETHACC_MAX_LARGE_RX_QUEUES
) &&
825 (rxQueue
< rxQueueCount
- IX_ETHACC_MAX_LARGE_RX_QUEUES
) )
827 /* add the small RX Queue setup template to the list of queues */
828 memcpy(qInfoDes
, &ixEthAccQmgrRxSmallTemplate
, sizeof(*qInfoDes
));
830 /* add the default RX Queue setup template to the list of queues */
831 memcpy(qInfoDes
, &ixEthAccQmgrRxDefaultTemplate
, sizeof(*qInfoDes
));
834 /* setup the RxQueue ID */
835 qInfoDes
->qId
= rxQueues
[rxQueue
].qId
;
837 /* setup the RxQueue watermark level
839 * Each queue can be filled by many NPEs. To avoid the
840 * NPEs to write to a full queue, need to set the
841 * high watermark level for nearly full condition.
842 * (the high watermark level are a power of 2
843 * starting from the top of the queue)
845 * Number of watermark
853 * n approx. 2**ceil(log2(n))
855 if (rxQueues
[rxQueue
].npeCount
== 1)
857 qInfoDes
->AlmostFullThreshold
= IX_QMGR_Q_WM_LEVEL0
;
859 else if (rxQueues
[rxQueue
].npeCount
== 2)
861 qInfoDes
->AlmostFullThreshold
= IX_QMGR_Q_WM_LEVEL1
;
863 else if (rxQueues
[rxQueue
].npeCount
== 3)
865 qInfoDes
->AlmostFullThreshold
= IX_QMGR_Q_WM_LEVEL2
;
869 /* reach the maximum number for CSR 2.0 */
870 IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: maximum number of NPEs per queue reached, bailing out\n", 0, 0, 0, 0, 0, 0);
871 ret
= IX_ETH_ACC_FAIL
;
875 /* move to next queue entry */
879 /* configure the static list (RxFree, Tx and TxDone queues) */
880 for (qInfoDes
= ixEthAccQmgrStaticInfo
;
881 (qInfoDes
->qCallback
!= (IxQMgrCallback
) NULL
)
882 && (ret
== IX_ETH_ACC_SUCCESS
);
885 ret
= ixEthAccQMgrQueueSetup(qInfoDes
);
888 /* configure the dynamic list (Rx queues) */
889 for (qInfoDes
= ixEthAccQmgrRxQueuesInfo
;
890 (qInfoDes
->qCallback
!= (IxQMgrCallback
) NULL
)
891 && (ret
== IX_ETH_ACC_SUCCESS
);
894 ret
= ixEthAccQMgrQueueSetup(qInfoDes
);
901 * @fn ixEthAccQMgrRxQEntryGet(UINT32 *rxQueueEntries)
903 * @brief Add and return the total number of entries in all Rx queues
905 * @param UINT32 rxQueueEntries[in] number of entries in all queues
909 * @note Rx queues configuration is driven by Qos Setup. There is a
910 * variable number of rx queues which are set at initialisation.
915 void ixEthAccQMgrRxQEntryGet(UINT32
*numRxQueueEntries
)
918 IxEthAccQregInfo
*qInfoDes
;;
920 *numRxQueueEntries
= 0;
922 /* iterate thru rx queues */
923 for (qInfoDes
= ixEthAccQmgrRxQueuesInfo
;
924 qInfoDes
->qCallback
!= (IxQMgrCallback
)NULL
;
927 /* retrieve the rx queue level */
929 ixQMgrQNumEntriesGet(qInfoDes
->qId
, &rxQueueLevel
);
930 (*numRxQueueEntries
) += rxQueueLevel
;
935 * @fn ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback)
937 * @brief Change the callback registered to all rx queues.
939 * @param IxQMgrCallback ixQMgrCallback[in] QMgr callback to register
941 * @return IxEthAccStatus
943 * @note The user may decide to use different Rx mechanisms
944 * (e.g. receive many frames at the same time , or receive
945 * one frame at a time, depending on the overall application
946 * performances). A different QMgr callback is registered. This
947 * way, there is no excessive pointer checks in the datapath.
952 IxEthAccStatus
ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback
)
954 IxEthAccQregInfo
*qInfoDes
;
955 IxEthAccStatus ret
= IX_ETH_ACC_SUCCESS
;
957 /* parameter check */
958 if (NULL
== ixQMgrCallback
)
960 ret
= IX_ETH_ACC_FAIL
;
963 /* iterate thru rx queues */
964 for (qInfoDes
= ixEthAccQmgrRxQueuesInfo
;
965 (qInfoDes
->qCallback
!= (IxQMgrCallback
) NULL
)
966 && (ret
== IX_ETH_ACC_SUCCESS
);
969 /* register the rx callback for all queues */
970 if (ixQMgrNotificationCallbackSet(qInfoDes
->qId
,
972 qInfoDes
->callbackTag
975 ret
= IX_ETH_ACC_FAIL
;
982 * @fn ixEthAccSingleEthNpeCheck(IxEthAccPortId portId)
984 * @brief Check the npe exists for this port
986 * @param IxEthAccPortId portId[in] port
988 * @return IxEthAccStatus
993 IxEthAccStatus
ixEthAccSingleEthNpeCheck(IxEthAccPortId portId
)
996 /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */
997 if ((IX_FEATURE_CTRL_SILICON_TYPE_A0
!=
998 (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK
))
999 || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X
!= ixFeatureCtrlDeviceRead ()))
1001 if ((IX_ETH_PORT_1
== portId
) &&
1002 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0
) ==
1003 IX_FEATURE_CTRL_COMPONENT_ENABLED
))
1005 return IX_ETH_ACC_SUCCESS
;
1008 if ((IX_ETH_PORT_2
== portId
) &&
1009 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1
) ==
1010 IX_FEATURE_CTRL_COMPONENT_ENABLED
))
1012 return IX_ETH_ACC_SUCCESS
;
1015 if ((IX_ETH_PORT_3
== portId
) &&
1016 (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH
) ==
1017 IX_FEATURE_CTRL_COMPONENT_ENABLED
))
1019 return IX_ETH_ACC_SUCCESS
;
1022 return IX_ETH_ACC_FAIL
;
1025 return IX_ETH_ACC_SUCCESS
;
1029 * @fn ixEthAccStatsShow(void)
1031 * @brief Displays all EthAcc stats
1036 void ixEthAccStatsShow(IxEthAccPortId portId
)
1040 printf("\nPort %u\nUnicast MAC : ", portId
);
1041 ixEthAccPortUnicastAddressShow(portId
);
1042 ixEthAccPortMulticastAddressShow(portId
);
1045 ixEthAccDataPlaneShow();