source: SVN/cambria/redboot/packages/devs/eth/intel/npe/ethAcc/current/src/IxEthAccCommon.c @ 1

Last change on this file since 1 was 1, checked in by Tim Harvey, 2 years ago

restored latest version of files from server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 32.4 KB
Line 
1/**
2 * @file IxEthAccCommon.c
3 *
4 * @author Intel Corporation
5 * @date 12-Feb-2002
6 *
7 * @brief This file contains the implementation common support routines for the component
8 *
9 * Design Notes:
10 *
11 * @par
12 * IXP400 SW Release version 2.3
13 *
14 * -- Copyright Notice --
15 *
16 * @par
17 * Copyright (c) 2001-2005, Intel Corporation.
18 * All rights reserved.
19 *
20 * @par
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
23 * are met:
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.
32 *
33 *
34 * @par
35 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
36 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 * SUCH DAMAGE.
46 *
47 *
48 * @par
49 * -- End of Copyright Notice --
50 */
51
52/*
53 * Component header files
54 */
55
56#include "IxOsal.h"
57#include "IxEthAcc.h"
58#include "IxEthDB.h"
59#include "IxNpeMh.h"
60#include "IxEthDBPortDefs.h"
61#include "IxFeatureCtrl.h"
62#include "IxEthAcc_p.h"
63#include "IxEthAccQueueAssign_p.h"
64
65#include "IxEthAccDataPlane_p.h"
66#include "IxEthAccMii_p.h"
67#include "IxNpeDl.h"   
68#include "IxAccCommon.h"
69
70/**
71 * @addtogroup IxEthAccPri
72 *@{
73 */
74
75extern IxEthAccInfo   ixEthAccDataInfo;
76
77
78
79/**
80 * @brief Stores Rx Queue info for all rx queues
81 */
82IX_ETH_ACC_PRIVATE
83IxEthAccRxQueue ixEthAccRxQueues[IX_ETHACC_MAX_RX_QUEUES+1];
84
85/* storage for the qmgr register base addresses */
86UINT32 ixEthAccQMIntEnableBaseAddress;
87UINT32 ixEthAccQMIntStatusBaseAddress;
88
89/**
90 *
91 * @brief Data structure template for RX Queues
92 *
93 */
94IX_ETH_ACC_PRIVATE
95IxEthAccQregInfo ixEthAccQmgrRxTemplate =
96{ 
97    IX_QMGR_QUEUE_INVALID,           /**< Queue ID */
98    "Eth Rx Q", 
99    ixEthRxFrameQMCallback,          /**< Functional callback */
100    (IxQMgrCallbackId) 0,            /**< Callback tag        */ 
101    IX_QMGR_Q_SIZE128,               /**< Allocate Max Size Q */
102    IX_QMGR_Q_ENTRY_SIZE1,           /**< Queue Entry Sizes - all Q entries are single word entries   */
103    TRUE,                            /**< Enable Q notification at startup */
104    IX_QMGR_Q_SOURCE_ID_NOT_E,       /**< Q Condition to drive callback   */
105    IX_QMGR_Q_WM_LEVEL0,             /**< Q Low water mark */
106    IX_QMGR_Q_WM_LEVEL1,             /**< Q High water mark - needed by NPE */
107};
108
109/**
110 *
111 * @brief Data structure template for RX Free Queues
112 *
113 */
114IX_ETH_ACC_PRIVATE
115IxEthAccQregInfo ixEthAccQmgrRxFreeTemplate =
116{
117    IX_QMGR_QUEUE_INVALID,
118    "Eth Rx Free Q",
119    ixEthRxFreeQMCallback,
120    (IxQMgrCallbackId) 0,
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_QMGR_Q_SOURCE_ID_E,           /**< 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 */
127};
128
129/**
130 *
131 * @brief Data structure template for TX Queues
132 *
133 */
134IX_ETH_ACC_PRIVATE
135IxEthAccQregInfo ixEthAccQmgrTxTemplate =
136{
137     IX_QMGR_QUEUE_INVALID,
138    "Eth Tx Q",
139     ixEthTxFrameQMCallback,
140     (IxQMgrCallbackId) 0,
141    IX_QMGR_Q_SIZE128,               /**< Allocate Max Size Q */
142    IX_QMGR_Q_ENTRY_SIZE1,           /**< Queue Entry Sizes - all Q entries are single word entries   */
143    FALSE,                           /**< Disable Q notification at startup */
144    IX_QMGR_Q_SOURCE_ID_E,           /**< Q Condition to drive callback  */
145    IX_QMGR_Q_WM_LEVEL0,             /**< Q Low water mark */
146    IX_QMGR_Q_WM_LEVEL64,            /**< Q High water mark */
147};
148
149/**
150 *
151 * @brief Data structure template for TxDone Queue
152 *
153 */
154IX_ETH_ACC_PRIVATE
155IxEthAccQregInfo ixEthAccQmgrTxDoneTemplate =
156{
157     IX_ETH_ACC_TX_DONE_Q,
158    "Eth Tx Done Q",
159     ixEthTxFrameDoneQMCallback,
160     (IxQMgrCallbackId) 0,
161    IX_QMGR_Q_SIZE128,               /**< Allocate Max Size Q */
162    IX_QMGR_Q_ENTRY_SIZE1,           /**< Queue Entry Sizes - all Q entries are single word entries   */
163    TRUE,                            /**< Enable Q notification at startup */
164    IX_QMGR_Q_SOURCE_ID_NOT_E,       /**< Q Condition to drive callback  */
165    IX_QMGR_Q_WM_LEVEL0,             /**< Q Low water mark */
166    IX_QMGR_Q_WM_LEVEL2,             /**< Q High water mark - needed by NPE */
167};
168
169/**
170 * @brief RX Queue size table indexed by relative queue priority
171 */
172IX_ETH_ACC_PRIVATE const
173IxQMgrQSizeInWords ixEthAccRxQueueSizeTable[IX_ETHACC_MAX_RX_QUEUES] =
174{
175    IX_QMGR_Q_SIZE128, /* highest priority */
176    IX_QMGR_Q_SIZE64,  /* second highest */
177    IX_QMGR_Q_SIZE32,  /* third highest */
178    IX_QMGR_Q_SIZE16,  /* fourth highest */
179    IX_QMGR_Q_SIZE16,  /* fifth highest */
180    IX_QMGR_Q_SIZE16,  /* sixth highest */
181    IX_QMGR_Q_SIZE16,  /* seventh highest */
182    IX_QMGR_Q_SIZE16   /* lowest */
183};
184
185/**
186 * @brief Queue nearly full watermark table indexed by NPE count
187 */
188IX_ETH_ACC_PRIVATE const
189IxQMgrWMLevel ixEthAccQueueNFWatermarkTable[] =
190{
191    IX_QMGR_Q_WM_LEVEL0,  /* NPE count == 0 (invalid) */ 
192    IX_QMGR_Q_WM_LEVEL0,  /* NPE count == 1 */
193    IX_QMGR_Q_WM_LEVEL1,  /* NPE count == 2 */
194    IX_QMGR_Q_WM_LEVEL2,  /* NPE count == 3 */
195    IX_QMGR_Q_WM_LEVEL4,  /* NPE count == 4 */
196    IX_QMGR_Q_WM_LEVEL4,  /* NPE count == 5 */
197    IX_QMGR_Q_WM_LEVEL8,  /* NPE count == 6 */
198    IX_QMGR_Q_WM_LEVEL8   /* NPE count == 7 */
199};
200
201/**
202 * @brief Static Queue assignment array per NPEs indexed by NPE ID
203 */
204IX_ETH_ACC_PRIVATE const
205UINT8 ixEthAccNpeStaticQueueConfigs[][2] =
206{
207    /* { TX Queue              , RX Free Queue } */
208    { IX_ETH_ACC_TX_NPEA_Q, IX_ETH_ACC_RX_FREE_NPEA_Q},
209    { IX_ETH_ACC_TX_NPEB_Q, IX_ETH_ACC_RX_FREE_NPEB_Q},
210    { IX_ETH_ACC_TX_NPEC_Q, IX_ETH_ACC_RX_FREE_NPEC_Q}
211};
212
213/*
214 * Forward declaration of private functions
215 */
216IX_ETH_ACC_PRIVATE
217IxEthAccStatus ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes);
218PRIVATE IxEthAccStatus
219ixEthAccQMgrQueueUnsetup (IxEthAccQregInfo *qInfoDes);
220IX_ETH_ACC_PRIVATE
221IxEthAccStatus ixEthAccGetRxQueueList(IxEthAccPortId portId,
222                                      IxEthAccRxQueue *rxQueues);
223
224
225/**
226 * @fn ixEthAccQMgrQueueSetup(IxEthAccQregInfo*)
227 *
228 * @brief Setup one queue and its event, and register the callback required
229 * by this component to the QMgr
230 *
231 * @internal
232 */
233IX_ETH_ACC_PRIVATE IxEthAccStatus
234ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes)
235{
236    int ret;
237
238    ret = ixQMgrQConfig( qInfoDes->qName,
239                        qInfoDes->qId,
240                        qInfoDes->qSize,
241                        qInfoDes->qWords);
242
243    /* If queue is already configured, continue anyway */
244    if(ret != IX_SUCCESS && ret != IX_QMGR_Q_ALREADY_CONFIGURED)
245    {
246        return IX_ETH_ACC_FAIL;
247    }
248       
249    if ( ixQMgrWatermarkSet( qInfoDes->qId,
250                             qInfoDes->AlmostEmptyThreshold,
251                             qInfoDes->AlmostFullThreshold
252                             ) != IX_SUCCESS)
253    {
254        return IX_ETH_ACC_FAIL;
255    }
256
257    /*
258     * Set dispatcher priority.
259     */
260    if ( ixQMgrDispatcherPrioritySet( qInfoDes->qId, 
261                                      IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY) 
262         != IX_SUCCESS)
263    {
264        return IX_ETH_ACC_FAIL;
265    }
266       
267    /*
268     * Register callbacks for each Q.
269     */ 
270    if ( ixQMgrNotificationCallbackSet(qInfoDes->qId,
271                                       qInfoDes->qCallback,
272                                       qInfoDes->callbackTag) 
273         != IX_SUCCESS )
274    {
275        return IX_ETH_ACC_FAIL;
276    }
277
278    /*
279     * Set notification condition for Q
280     */ 
281    if ( qInfoDes->qNotificationEnableAtStartup == TRUE ) 
282    {
283        if (   ixQMgrNotificationEnable(qInfoDes->qId,
284                                        qInfoDes->qConditionSource)
285               != IX_SUCCESS )
286        {
287            return IX_ETH_ACC_FAIL;
288        }
289    }
290
291    return(IX_ETH_ACC_SUCCESS);
292}
293
294/*
295 * ixEthAccQMgrQueueUnsetup ()
296 * added to the same file
297 */
298
299PRIVATE IxEthAccStatus
300ixEthAccQMgrQueueUnsetup (IxEthAccQregInfo *qInfoDes)
301{
302    if (IX_ETH_ACC_SUCCESS != ixQMgrNotificationDisable(qInfoDes->qId))
303    {
304        IX_ETH_ACC_WARNING_LOG ("Failed to disable the notification for QId=%u\n", 
305                                (UINT32) qInfoDes->qId, 0, 0, 0, 0, 0);
306        return IX_ETH_ACC_FAIL;
307    }
308    return IX_ETH_ACC_SUCCESS;
309}
310
311/**
312 * @fn ixEthAccGetRxQueueList(IxEthAccPortId, IxEthAccRxQueue *)
313 *
314 * @brief Fill in and sort the rx queue array
315 *
316 * @li select all Rx queues as configured by ethDB for all ports
317 * @li sort the queues by traffic class
318 *
319 * @param none
320 *
321 * @return UINT32 (num Rx queues)
322 *
323 * @internal
324 */
325IX_ETH_ACC_PRIVATE
326IxEthAccStatus ixEthAccGetRxQueueList(IxEthAccPortId portId, IxEthAccRxQueue *rxQueues)
327{
328    IxEthDBStatus ixEthDBStatus = IX_ETH_DB_SUCCESS;
329    IxEthDBProperty ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY;
330    IxEthDBPropertyType ixEthDBPropertyType = IX_ETH_DB_INTEGER_PROPERTY;
331    UINT32 ixEthDBParameter = 0;
332    BOOL completelySorted = FALSE;
333    UINT32 rxQueue = 0;
334    UINT32 sortIterations = 0;
335    IxEthNpeNodeId ixNpeId = IX_ETHNPE_PHYSICAL_ID_TO_NODE(portId);
336
337    /*
338     * Queue Selection step:
339     *
340     * The following code selects all the queues and fills
341     * the RxQueue array
342     *
343     */
344
345    /* Iterate thru the different priorities */
346    for (ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; 
347         ixEthDBTrafficClass <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY; 
348         ixEthDBTrafficClass++)
349    {
350        ixEthDBStatus = ixEthDBFeaturePropertyGet(
351                                portId,
352                                IX_ETH_DB_VLAN_QOS,
353                                ixEthDBTrafficClass,
354                                &ixEthDBPropertyType,
355                                (void *)&ixEthDBParameter);
356
357        if (ixEthDBStatus == IX_ETH_DB_SUCCESS)
358        {
359            /* This port and QoS class are mapped to
360             * a RX queue.
361             */
362            if (ixEthDBPropertyType == IX_ETH_DB_INTEGER_PROPERTY)
363            {
364                /* search the queue in the list of queues
365                 * already used by an other port or QoS
366                 */
367                for (   rxQueue = 0;
368                        ((rxQueues[rxQueue].npeCount != 0)
369                        && (rxQueue < IX_ETHACC_MAX_RX_QUEUES));
370                        rxQueue++)
371                {
372                    if (rxQueues[rxQueue].qId == (IxQMgrQId)ixEthDBParameter)
373                    {
374                        /* found an existing setup, update the number of ports
375                         * for this queue if the port maps to
376                         * a different NPE.
377                         */
378                        if (rxQueues[rxQueue].npeId != ixNpeId)
379                        {
380                            rxQueues[rxQueue].npeCount++;
381                            rxQueues[rxQueue].npeId = ixNpeId;
382                        }
383                        /* get the highest traffic class for this queue */
384                        if (rxQueues[rxQueue].trafficClass > ixEthDBTrafficClass)
385                        {
386                            rxQueues[rxQueue].trafficClass = ixEthDBTrafficClass;
387                        }
388                        break;
389                    }
390                }
391                if (rxQueues[rxQueue].npeCount == 0)
392                {
393                    /* new queue not found in the current list,
394                     * add a new entry.
395                     */
396                    IX_OSAL_ASSERT(rxQueue < IX_ETHACC_MAX_RX_QUEUES);
397                    rxQueues[rxQueue].qId = ixEthDBParameter;
398                    rxQueues[rxQueue].npeCount = 1;
399                    rxQueues[rxQueue].npeId = ixNpeId;
400                    rxQueues[rxQueue].trafficClass = ixEthDBTrafficClass;
401                }
402            }
403            else
404            {
405                /* unexpected property type (not Integer) */
406                IX_ETH_ACC_WARNING_LOG("ixEthAccGetRxQueueList: In Port=%u, unexpected property type returned by EthDB\n", (UINT32) portId, 0, 0, 0, 0, 0);
407                /* no point to continue to iterate */
408                return (IX_ETH_ACC_FAIL);
409            }
410        }
411        else
412        {
413            /* No Rx queue configured for this port
414             * and this traffic class. Do nothing.
415             */
416        }
417    }
418
419    /* check there is at least 1 rx queue : there is no point
420     * to continue if there is no rx queue configured
421     */
422    if (rxQueues[0].npeCount == 0)
423    {
424        IX_ETH_ACC_WARNING_LOG("ixEthAccGetRxQueueList: In Port=%u, no queues configured, bailing out\n", 
425                               (UINT32) portId, 0, 0, 0, 0, 0);
426        /* queue configuration error so return queue count 0 */
427        return (IX_ETH_ACC_FAIL);
428    }
429
430    /* Queue sort step:
431     *
432     * Re-order the array of queues by decreasing traffic class
433     * using a bubble sort. (trafficClass 0 is the lowest
434     * priority traffic, trafficClass 7 is the highest priority traffic)
435     *
436     * Primary sort order is traffic class
437     * Secondary sort order is npeId
438     *
439     * Note that a bubble sort algorithm is not very efficient when
440     * the number of queues grows . However, this is not a very bad choice
441     * considering the very small number of entries to sort. Also, bubble
442     * sort is extremely fast when the list is already sorted.
443     *
444     * The output of this loop is a sorted array of queues.
445     *
446     */
447    sortIterations = 0;
448    do
449    {
450        sortIterations++;
451        completelySorted = TRUE;
452        for (rxQueue = 0;   (rxQueues[rxQueue+1].npeCount != 0)
453             && (rxQueue < IX_ETHACC_MAX_RX_QUEUES - sortIterations); 
454             rxQueue++)
455        {
456            /* compare adjacent elements */
457            if ((rxQueues[rxQueue].trafficClass <
458                rxQueues[rxQueue+1].trafficClass)
459                || ((rxQueues[rxQueue].trafficClass ==
460                     rxQueues[rxQueue+1].trafficClass)
461                    &&(rxQueues[rxQueue].npeId <
462                       rxQueues[rxQueue+1].npeId)))
463            {
464                /* swap adjacent elements */
465                int npeCount = rxQueues[rxQueue].npeCount;
466                UINT32 npeId = rxQueues[rxQueue].npeId;
467                IxQMgrQId qId = rxQueues[rxQueue].qId;
468                IxEthDBProperty trafficClass = rxQueues[rxQueue].trafficClass;
469                rxQueues[rxQueue].npeCount = rxQueues[rxQueue+1].npeCount;
470                rxQueues[rxQueue].npeId = rxQueues[rxQueue+1].npeId;
471                rxQueues[rxQueue].qId = rxQueues[rxQueue+1].qId;
472                rxQueues[rxQueue].trafficClass = rxQueues[rxQueue+1].trafficClass;
473                rxQueues[rxQueue+1].npeCount = npeCount;
474                rxQueues[rxQueue+1].npeId = npeId;
475                rxQueues[rxQueue+1].qId = qId;
476                rxQueues[rxQueue+1].trafficClass = trafficClass;
477                completelySorted = FALSE;
478            }
479        }
480    }
481    while (!completelySorted);
482
483    return (IX_ETH_ACC_SUCCESS);
484}
485
486/**
487 * @fn ixEthAccQMgrQueuesConfig(void)
488 *
489 * @brief Setup all the queues and register all callbacks required
490 * by this component to the QMgr
491 *
492 * Rx queues configuration is driven by QoS setup.
493 * Many Rx queues may be required when QoS is enabled (this depends
494 * on IxEthDB setup and the images being downloaded). The configuration
495 * of the rxQueues is done in many steps as follows:
496 *
497 * @li select all Rx queues as configured by ethDB for all ports
498 * @li sort the queues by traffic class
499 * @li build the priority dependency for all queues
500 * @li fill the configuration for all rx queues
501 * @li configure all statically configured queues
502 * @li configure all dynamically configured queues
503 *
504 * @param none
505 *
506 * @return IxEthAccStatus
507 *
508 * @internal
509 */
510IX_ETH_ACC_PUBLIC
511IxEthAccStatus ixEthAccQMgrQueuesConfig(IxEthAccPortId portId)
512{
513    IxEthAccQregInfo qInfoDes;
514    IxEthAccQregInfo rxFreeQInfoDes;
515    IxEthAccQregInfo txQInfoDes;
516    UINT32 rxQueue = 0;
517    /* Rx queue list stored globally */
518    IxEthAccRxQueue *rxQueues = ixEthAccRxQueues;
519    IxEthAccStatus ret = IX_ETH_ACC_SUCCESS;
520    IxEthNpeNodeId ixNpeId = IX_ETHNPE_PHYSICAL_ID_TO_NODE(portId);
521
522
523    /* Configure the TxDone Queue
524     * Note that the TxDone queue is shared by all ports
525     * ixEthAccQMgrQueueSetup makes sure it is not configured again
526     */ 
527    memcpy(&qInfoDes, &ixEthAccQmgrTxDoneTemplate, sizeof(qInfoDes));
528    /* setup the TxDone Queue watermark level from the static table */
529    qInfoDes.AlmostFullThreshold = ixEthAccQueueNFWatermarkTable[ixEthAccDataInfo.npeCount];
530    ret = ixEthAccQMgrQueueSetup(&qInfoDes);
531 
532        if(ret) return (ret);
533
534    /* Configure the TX and RxFree Queues for this port
535     */ 
536    memcpy(&rxFreeQInfoDes, &ixEthAccQmgrRxFreeTemplate, sizeof(rxFreeQInfoDes));
537    ixEthAccPortData[portId].ixEthAccRxData.rxFreeQueueSource \
538        = rxFreeQInfoDes.qConditionSource;
539    rxFreeQInfoDes.callbackTag = portId;
540
541    memcpy(&txQInfoDes, &ixEthAccQmgrTxTemplate, sizeof(txQInfoDes));
542    ixEthAccPortData[portId].ixEthAccTxData.txQueueSource \
543        = txQInfoDes.qConditionSource;
544    txQInfoDes.callbackTag = portId;
545
546    ixEthAccPortData[portId].ixEthAccRxData.rxFreeQueue \
547        = rxFreeQInfoDes.qId \
548        = ixEthAccNpeStaticQueueConfigs[ixNpeId][IX_ETHACC_RXFREE_QUEUE_ASSIGNMENT_INDEX];
549    ixEthAccPortData[portId].ixEthAccTxData.txQueue \
550        = txQInfoDes.qId \
551        = ixEthAccNpeStaticQueueConfigs[ixNpeId][IX_ETHACC_TX_QUEUE_ASSIGNMENT_INDEX];
552
553    ret = ixEthAccQMgrQueueSetup(&rxFreeQInfoDes);
554
555    if(ret) return (ret);
556   
557        ret = ixEthAccQMgrQueueSetup(&txQInfoDes);
558
559    if(ret) return (ret);
560           
561
562    /* Get RX queue list */
563    ret = ixEthAccGetRxQueueList(portId, rxQueues);   
564
565    if(ret) return (ret);
566
567    /* get RX queue template for the queues */
568    memcpy(&qInfoDes, &ixEthAccQmgrRxTemplate, sizeof(qInfoDes));
569
570    /* go through all the queues configuring with proper parameters:
571     * - queue ID (from rxQueues list)
572     * - queue size (larger size for higher priority queues)
573     * - Almost full watermark (based on npe count for queue)
574     */
575    for (rxQueue = 0;
576         (rxQueues[rxQueue].npeCount != 0) && (ret == IX_ETH_ACC_SUCCESS);
577         rxQueue++)
578    {
579        /* copy the local priority qId into dataplane struct and add to bitmask */
580        ixEthAccDataInfo.rxQueues[rxQueue] = rxQueues[rxQueue].qId;
581        ixEthAccDataInfo.rxQueuesIntMask |= (1 << (rxQueues[rxQueue].qId));
582
583        /* setup the Rx Queue ID */
584        qInfoDes.qId = rxQueues[rxQueue].qId;
585       
586        /* setup the Rx Queue size from static table */
587        qInfoDes.qSize = ixEthAccRxQueueSizeTable[rxQueue];
588       
589        /* setup the Rx Queue watermark level from the static table */
590        qInfoDes.AlmostFullThreshold = ixEthAccQueueNFWatermarkTable[rxQueues[rxQueue].npeCount];
591
592        /* Set the callback tag in Rx queue storage
593         * Used for callback registration */
594        rxQueues[rxQueue].callbackTag = qInfoDes.callbackTag;
595
596        /* configure this queue */
597      ret = ixEthAccQMgrQueueSetup(&qInfoDes);
598       
599
600    }
601    /* set invalid last entry in dataplane struct */
602    ixEthAccDataInfo.rxQueues[rxQueue] = IX_QMGR_MAX_NUM_QUEUES;
603
604    /* notify EthDB that queue initialization is complete and traffic class allocation is frozen */
605    ixEthDBFeaturePropertySet(portId,
606        IX_ETH_DB_VLAN_QOS,
607        IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE,
608        NULL /* ignored */);
609
610    return (ret);                               
611}
612
613/* @ixEthUnconfigQueues
614 *
615 * @params none
616 *
617 * @fn - unconfigures the queues configured in ixEthAccInit
618 *
619 * @return IxEthAccStatus
620 */
621
622IX_ETH_ACC_PUBLIC
623IxEthAccStatus ixEthAccQueuesUnconfig (void)
624{
625    IxEthAccStatus ret = IX_ETH_ACC_SUCCESS;
626    IxEthAccQregInfo qInfoDes;
627    IxEthAccPortId portId;
628    UINT32 rxQueue = 0;
629    /* Rx queue list stored globally */
630    IxEthAccRxQueue *rxQueues = ixEthAccRxQueues;
631
632    /* Get RX queue list */
633    ret = ixEthAccGetRxQueueList(0, rxQueues);   
634    if(ret) return (ret);
635
636    /* un configure the Rx queues */
637    for (rxQueue = 0;
638         (rxQueues[rxQueue].npeCount != 0) && (ret == IX_ETH_ACC_SUCCESS);
639         rxQueue++)
640    {
641        memset(&qInfoDes, 0, sizeof(IxEthAccQregInfo));
642        qInfoDes.qId = rxQueues[rxQueue].qId;
643        ret = ixEthAccQMgrQueueUnsetup (&qInfoDes);
644    }
645
646    /* clear the rxQueues data structure */
647    memset(rxQueues, 0, sizeof(ixEthAccRxQueues));
648
649    /* un configure the TxDone queue */
650    ret = ixEthAccQMgrQueueUnsetup(&ixEthAccQmgrTxDoneTemplate);
651
652    /* un configure the RxFree and Tx queues */
653    for (portId = 0;
654         portId < IX_ETH_ACC_NUM_PORTS;
655        ++portId)
656    {
657        ixQMgrNotificationDisable(ixEthAccPortData[portId].ixEthAccTxData.txQueue);
658        ixQMgrNotificationDisable(ixEthAccPortData[portId].ixEthAccRxData.rxFreeQueue);
659    }
660
661    return ret;
662}
663
664
665
666/**
667 * @fn ixEthAccQMgrRxQEntryGet(UINT32 *rxQueueEntries)
668 *
669 * @brief Add and return the total number of entries in all Rx queues
670 *
671 * @param UINT32 rxQueueEntries[in] number of entries in all queues
672 *
673 * @return void
674 *
675 * @note Rx queues configuration is driven by Qos Setup. There is a
676 * variable number of rx queues which are set at initialisation.
677 *
678 * @internal
679 */
680IX_ETH_ACC_PUBLIC
681void ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries)
682{
683    UINT32 rxQueueLevel;
684    IxEthAccRxQueue *rxQueuePtr;
685
686    *numRxQueueEntries = 0;
687
688    /* iterate thru rx queues */
689    for (rxQueuePtr = ixEthAccRxQueues;
690         rxQueuePtr->npeCount != 0;
691         ++rxQueuePtr)
692    {
693        /* retrieve the rx queue level */
694        rxQueueLevel = 0;
695        ixQMgrQNumEntriesGet(rxQueuePtr->qId, &rxQueueLevel);
696        (*numRxQueueEntries) += rxQueueLevel;
697    }
698}
699
700/**
701 * @fn ixEthAccQMgrRxNotificationEnable(void)
702 *
703 * @brief Enable AQM notification for all rx queues.
704 *
705 * @return IxEthAccStatus
706 *
707 */
708IX_ETH_ACC_PUBLIC
709void ixEthAccQMgrRxNotificationEnable()
710{
711    UINT32 intEnableReg;
712
713    intEnableReg = IX_OSAL_READ_LONG(ixEthAccQMIntEnableBaseAddress);
714    IX_OSAL_WRITE_LONG(ixEthAccQMIntEnableBaseAddress,
715        (intEnableReg | ixEthAccDataInfo.rxQueuesIntMask)); 
716}
717
718/**
719 * @fn ixEthAccQMgrRxNotificationDisable(void)
720 *
721 * @brief Disable AQM notification for all rx queues.
722 *
723 * @return IxEthAccStatus
724 *
725 */
726IX_ETH_ACC_PUBLIC
727void ixEthAccQMgrRxNotificationDisable()
728{
729    UINT32 intEnableReg;
730
731    intEnableReg = IX_OSAL_READ_LONG(ixEthAccQMIntEnableBaseAddress);
732    IX_OSAL_WRITE_LONG(ixEthAccQMIntEnableBaseAddress,
733        (intEnableReg & ~(ixEthAccDataInfo.rxQueuesIntMask)));
734    IX_OSAL_WRITE_LONG(ixEthAccQMIntStatusBaseAddress,
735        ixEthAccDataInfo.rxQueuesIntMask); 
736}
737
738/**
739 * @fn ixEthAccQMgrRxCallbacksRegister
740 *
741 * @brief Change the callback registered to all rx queues.
742 *
743 * @param IxQMgrCallback ixQMgrCallback[in] QMgr callback to register
744 * @param IxQMgrCallbackId ixQMgrCallbackTag[in] callback tag to register
745 *
746 * @return IxEthAccStatus
747 *
748 * @note The user may decide to use different Rx mechanisms
749 * (e.g. receive many frames at the same time , or receive
750 *  one frame at a time, depending on the overall application
751 *  performances). A different QMgr callback is registered. This
752 *  way, there is no excessive pointer checks in the datapath.
753 *
754 * @internal
755 */
756IX_ETH_ACC_PUBLIC
757IxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback,
758                                               IxQMgrCallbackId ixQMgrCallbackTag)
759{
760    IxEthAccRxQueue *rxQueuePtr;
761    IxEthAccStatus ret = IX_ETH_ACC_SUCCESS;
762    IxQMgrCallbackId callbackTag = ixQMgrCallbackTag;
763   
764    /* parameter check */
765    if (NULL == ixQMgrCallback)
766    {
767        ret = IX_ETH_ACC_FAIL;
768    }
769   
770    /* iterate thru rx queues */
771    for (rxQueuePtr = ixEthAccRxQueues;
772         (rxQueuePtr->npeCount != 0)
773             && (ret == IX_ETH_ACC_SUCCESS);
774         ++rxQueuePtr)
775    {
776        /* if no tag given, use stored tag */
777        if(ixQMgrCallbackTag == 0)
778            callbackTag = rxQueuePtr->callbackTag;
779        /* register the rx callback for all queues */
780        ret = ixQMgrNotificationCallbackSet(rxQueuePtr->qId,
781                                             ixQMgrCallback,
782                                             callbackTag);
783    }
784    return(ret);
785}
786
787/**
788 * @fn ixEthAccSingleEthNpeCheck(IxEthAccPortId portId)
789 *
790 * @brief Check the hardware and microcode exists for this port
791 *
792 * @param IxEthAccPortId portId[in] port
793 *
794 * @return IxEthAccStatus
795 *
796 * @note The following conditions must all be true to pass:
797 *  - The port's associated NPE exists
798 *  - An ethernet NPE image is loaded
799 *  - For ports 1-3 on NPEB, the correct 4port image is loaded
800 *    and the (1-3 ports) are enabled in hardware
801 *  - The Ethernet coprocessor exists for the port
802 *
803 * @internal
804 */
805IX_ETH_ACC_PUBLIC
806IxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId physicalId)
807{
808    UINT8 functionalityId;
809
810    IxEthNpeNodeId npeId = IX_ETHNPE_PHYSICAL_ID_TO_NODE(physicalId);
811    IxEthNpePortId portId = IX_ETHNPE_PHYSICAL_ID_TO_PORT(physicalId);
812   
813    if (IX_SUCCESS != ixNpeDlLoadedImageFunctionalityGet(npeId, &functionalityId))
814    {
815        return IX_ETH_ACC_FAIL;
816    }
817    else
818    {
819        /* If not IXP42X A0 stepping, proceed to check for existence of NPEs and ethernet coprocessors */ 
820        if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != 
821            (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK))
822            || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ()))
823        {
824            switch(npeId)
825            {
826              case IX_NPEDL_NPEID_NPEA: 
827                if ((ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) ==
828                     IX_FEATURE_CTRL_COMPONENT_DISABLED) ||
829                     ((ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) ==
830#ifndef __ixp43X
831                     IX_FEATURE_CTRL_COMPONENT_DISABLED) || 
832                     (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
833#endif
834                     IX_FEATURE_CTRL_COMPONENT_DISABLED)))
835                {
836                    return IX_ETH_ACC_FAIL;
837                }
838                break;
839
840              case IX_NPEDL_NPEID_NPEB: 
841                if ( (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) ==
842                     IX_FEATURE_CTRL_COMPONENT_DISABLED) )
843                {
844                    return IX_ETH_ACC_FAIL;
845                }
846                if (portId == 0)
847                {
848                    if( ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
849                        IX_FEATURE_CTRL_COMPONENT_DISABLED)
850                    {
851                        return IX_ETH_ACC_FAIL;     
852                    }
853                }
854                else /* ports 1-3 */
855                {
856                    if( ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB_ETH) ==
857                        IX_FEATURE_CTRL_COMPONENT_DISABLED)
858                    {
859                        return IX_ETH_ACC_FAIL;     
860                    }
861
862                }
863                break;
864
865              case IX_NPEDL_NPEID_NPEC: 
866                if ((ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) ==
867                     IX_FEATURE_CTRL_COMPONENT_DISABLED) ||
868                     ((ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
869#ifndef __ixp43X
870                     IX_FEATURE_CTRL_COMPONENT_DISABLED) ||
871                     (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
872#endif
873                     IX_FEATURE_CTRL_COMPONENT_DISABLED)))
874                {
875                    return IX_ETH_ACC_FAIL;
876                }
877                break;
878
879              default: /* invalid NPE */
880                return IX_ETH_ACC_FAIL;
881            }
882        }
883        return IX_ETH_ACC_SUCCESS;
884    }
885}
886
887/**
888 * @fn ixEthAccStatsShow(void)
889 *
890 * @brief Displays all EthAcc stats
891 *
892 * @return void
893 *
894 */
895void ixEthAccStatsShow(IxEthAccPortId portId)
896{
897    ixEthAccMdioShow();
898
899    printf("\nPort %u\nUnicast MAC : ", portId);
900    ixEthAccPortUnicastAddressShow(portId);
901    ixEthAccPortMulticastAddressShow(portId);
902    printf("\n");
903
904    ixEthAccDataPlaneShow();
905}
906
907/**
908 * This function is responsible to activate Flag Bus status from AQM to
909 * NPE. Only Rx Queue, RxFree and TxDone Queue are involved.
910 * Note: user is required to disable IRQ before calling this function.
911 */
912IX_ETH_ACC_PUBLIC IxEthAccStatus
913ixEthAccQMStatusUpdate(IxEthAccPortId portId)
914{ 
915   UINT32 rxFreeId = 0; 
916   UINT32 qEntry = 0;
917   UINT32 rxQueue = 0;
918   IxEthAccRxQueue *rxQueues = ixEthAccRxQueues;
919   IxEthAccStatus ret = IX_ETH_ACC_SUCCESS;
920
921   if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
922   {
923       return (IX_ETH_ACC_FAIL);
924   }
925
926    IX_ETH_ACC_VALIDATE_PORT_ID(portId);
927
928    if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
929    {
930        IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot reupdate QM Status.\n",(INT32) portId,0,0,0,0,0);
931        return IX_ETH_ACC_FAIL ;
932    } 
933
934    if (!IX_ETH_IS_PORT_INITIALIZED(portId))
935    {
936        return (IX_ETH_ACC_PORT_UNINITIALIZED);
937    }
938 
939   /*
940    * (1) Read an entry from TxDone Queue.
941    * (2) If there is any entry, write the entry back to TxDone Queue.
942    */
943    if (ixQMgrQRead(IX_ETH_ACC_TX_DONE_Q, &qEntry) == IX_SUCCESS)
944    { 
945      /* Avoid qEntry=0 (NULL) to be written to HwQ. */
946      if(qEntry > 0)
947      {
948       if (ixQMgrQWrite(IX_ETH_ACC_TX_DONE_Q, &qEntry) != IX_SUCCESS)
949       {
950         return (IX_ETH_ACC_FAIL);       
951       } 
952      }
953    }
954
955    /*
956    * (1) Read an entry from RxFree Queue, then
957    * (2) If thre is any entry, write the entry back to RxFree Queue.
958    */ 
959    rxFreeId = IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId);
960   
961    if (ixQMgrQRead(rxFreeId, &qEntry) == IX_SUCCESS)
962    {
963       /* Avoid qEntry=0 (NULL) to be written to HwQ. */
964       if(qEntry > 0)
965       {
966        if (ixQMgrQWrite(rxFreeId, &qEntry) != IX_SUCCESS)
967        {
968          return (IX_ETH_ACC_FAIL);       
969        } 
970       }
971    }
972   
973   /*
974    * (1) Read an entry from Rx Queue.
975    * (2) If there is any entry, write the entry back to Rx Queue.
976    *  Note: For QoS enabled image, there are more than 1 RxQ.
977    */
978    /* Get RX queue list */
979    ret = ixEthAccGetRxQueueList(portId, rxQueues);   
980
981    if(ret) return (ret);
982
983    for (rxQueue = 0;
984         (rxQueues[rxQueue].npeCount != 0);
985         rxQueue++)
986    {
987      if (ixQMgrQRead(rxQueues[rxQueue].qId, &qEntry) == IX_SUCCESS)
988      {
989        /* Avoid qEntry=0 (NULL) to be written to HwQ. */
990        if(qEntry > 0)
991        {
992         if (ixQMgrQWrite(rxQueues[rxQueue].qId, &qEntry) != IX_SUCCESS)
993         {
994           return (IX_ETH_ACC_FAIL);       
995         }
996        }
997      }       
998    }
999
1000   return (IX_ETH_ACC_SUCCESS);
1001}
1002
1003/**
1004 * @fn ixEthHssAccCoExistInit(void)
1005 *
1006 * @brief Check ethernet&hss co-existence services initialized and init mutex
1007 *
1008 * @return IxEthAccStatus
1009 *
1010 * @internal
1011 */
1012IX_ETH_ACC_PUBLIC IxEthAccStatus
1013ixEthHssAccCoExistInit(void)
1014{
1015    UINT8 functionalityId;
1016    IX_STATUS retStatus;
1017
1018    retStatus = ixNpeDlLoadedImageFunctionalityGet(IX_NPEDL_NPEID_NPEA, &functionalityId);
1019
1020    /* Check for parameter error */
1021    if (IX_NPEDL_PARAM_ERR ==  retStatus)
1022    {
1023        return IX_ETH_ACC_FAIL;
1024    }   
1025
1026    /* Check if NPE image is downloaded to NPE A. If NPE image is not downloaded
1027     * in NPE A, ixNpeDlLoadedImageFunctionalityGet returns IX_FAIL.If this is the case,
1028     * we can return IX_ETH_ACC_SUCCESS to not interrupt the following
1029     * steps in ixEthAccInit() 
1030     */
1031    if (IX_FAIL == retStatus)
1032    {
1033        return IX_ETH_ACC_SUCCESS;
1034    }
1035
1036    /*
1037     * To enable Ethernet & HSS co-existence feature in NPE A, check the functionality
1038     * of downloaded NPE image when the functionality id is either 0x00900000
1039     * (HSS channelized + learning/filtering support) or 0x00910000
1040     * (HSS channelized + header conversion support)
1041     */
1042#if defined(IX_NPEDL_NPEIMAGE_NPEA_ETH_MACFILTERLEARN_HSSCHAN_COEXIST) \
1043        && defined(IX_NPEDL_NPEIMAGE_NPEA_ETH_HDRCONV_HSSCHAN_COEXIST)
1044    if ((functionalityId == IX_FUNCTIONID_FROM_NPEIMAGEID_GET(
1045         IX_NPEDL_NPEIMAGE_NPEA_ETH_MACFILTERLEARN_HSSCHAN_COEXIST) ||
1046         functionalityId == IX_FUNCTIONID_FROM_NPEIMAGEID_GET(
1047         IX_NPEDL_NPEIMAGE_NPEA_ETH_HDRCONV_HSSCHAN_COEXIST)) &&
1048         ixEthHssAccCoexistEnable != TRUE)
1049    {
1050        /* If service is initialized and the common mutex is not initialized, initialize it */
1051        if (TRUE != ixEthHssComMutexInitDone)
1052        {
1053           if (ixOsalMutexInit(&ixEthHssCoexistLock) != IX_SUCCESS)
1054           {
1055              IX_ETH_ACC_WARNING_LOG("ixEthHssAccCoExistInit: Common co-exist mutex init failed\n", 0, 0, 0, 0, 0, 0);
1056              return IX_ETH_ACC_FAIL;
1057           }
1058
1059           ixEthHssComMutexInitDone = TRUE;
1060        }
1061
1062        ixEthHssAccCoexistEnable = TRUE;
1063    }
1064#endif
1065
1066    return IX_ETH_ACC_SUCCESS;
1067}
1068
1069/**
1070 * @fn ixEthHssAccCoExistUninit(void)
1071 *
1072 * @brief Check ethernet&hss co-existence services uninitialized
1073 *
1074 * @return IxEthAccStatus
1075 *
1076 * @internal
1077 */
1078IX_ETH_ACC_PUBLIC IxEthAccStatus
1079ixEthHssAccCoExistUninit(void)
1080{
1081    /*
1082     * Destroy common mutex initialized for Eth+HSS co-existence services.
1083     * Check whether already destroyed in the HSS component
1084     */
1085
1086#if defined(IX_NPEDL_NPEIMAGE_NPEA_ETH_MACFILTERLEARN_HSSCHAN_COEXIST) \
1087        && defined(IX_NPEDL_NPEIMAGE_NPEA_ETH_HDRCONV_HSSCHAN_COEXIST)
1088
1089    if (FALSE != ixEthHssAccCoexistEnable)
1090    {
1091       if (FALSE != ixEthHssComMutexInitDone)
1092       {
1093          if (ixOsalMutexDestroy (&ixEthHssCoexistLock) != IX_SUCCESS)
1094          {
1095              IX_ETH_ACC_WARNING_LOG("ixEthHssAccCoExistUninit: Common co-exist mutex destroy failed\n", 0, 0, 0, 0, 0, 0);
1096
1097              return IX_ETH_ACC_FAIL;
1098          }
1099
1100          ixEthHssComMutexInitDone = FALSE;
1101       }
1102
1103       ixEthHssAccCoexistEnable = FALSE;
1104    }
1105#endif
1106
1107    return IX_ETH_ACC_SUCCESS;
1108}
1109
Note: See TracBrowser for help on using the repository browser.