⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ixqmgrdispatcher.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
📖 第 1 页 / 共 3 页
字号:
    {        ixQMgrDispatcherReBuildPriorityTable ();    }}voidixQMgrDispatcherLoopRunB0LLP (IxQMgrDispatchGroup group){    UINT32 intRegVal =0;                /* Interrupt reg val */    UINT32 intRegCheckMask;          /* Mask for checking interrupt bits */    IxQMgrQInfo *currDispatchQInfo;    int priorityTableIndex; /* Priority table index */    int qIndex;             /* Current queue being processed */    UINT32 intRegValCopy = 0;    UINT32 intEnableRegVal = 0;    UINT8 i = 0;#ifndef NDEBUG    IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) ||              (group == IX_QMGR_QUELOW_GROUP));#endif    /* Read the interrupt register */    ixQMgrAqmIfQInterruptRegRead (group, &intRegVal);    /*      * mask any interrupts that are not enabled      */    ixQMgrAqmIfQInterruptEnableRegRead (group, &intEnableRegVal);    intRegVal &= intEnableRegVal;    /* No queue has interrupt register set */    if (intRegVal != 0)    {        if (IX_QMGR_QUELOW_GROUP == group)        {            /*             * As the sticky bit is set, the interrupt register will              * not clear if write back at this point because the condition             * has not been cleared. Take a copy and write back later after             * the condition has been cleared             */            intRegValCopy = intRegVal;        }        else        {            /* no sticky for upper Q's, so write back now */            ixQMgrAqmIfQInterruptRegWrite (group, intRegVal);        }        /* get the first queue Id from the interrupt register value */        qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal);        if (IX_QMGR_QUEUPP_GROUP == group)        {            /* Set the queue range based on the queue group to proccess */            qIndex += IX_QMGR_MIN_QUEUPP_QID;        }        /* check if the interrupt register contains        * only 1 bit set        * For example:        *                                        intRegVal = 0x0010        *               currDispatchQInfo->intRegCheckMask = 0x0010        *    intRegVal == currDispatchQInfo->intRegCheckMask is TRUE.        */        currDispatchQInfo = &dispatchQInfo[qIndex];        if (intRegVal == currDispatchQInfo->intRegCheckMask)        {            /*              * check if Q type periodic -  only lower queues can             * have there type set to periodic              */            if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex])            {                /*                  * Disable the notifications on any sporadics                  */                for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)                {                    if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i])                    {                        ixQMgrNotificationDisable(i);#ifndef NDEBUG                        /* Update statistics */                        dispatcherStats.queueStats[i].disableCount++;#endif                    }                }            }            currDispatchQInfo->callback (qIndex,                                         currDispatchQInfo->callbackId);#ifndef NDEBUG            /* Update statistics */            dispatcherStats.queueStats[qIndex].callbackCnt++;#endif        }        else        {            /* the event is triggered by more than 1 queue,            * the queue search will be starting from the beginning            * or the middle of the priority table            *            * the serach will end when all the bits of the interrupt            * register are cleared. There is no need to maintain            * a seperate value and test it at each iteration.            */            if (IX_QMGR_QUELOW_GROUP == group)            {                /* check if any bit related to queues in the first                 * half of the priority table is set                 */                if (intRegVal & lowPriorityTableFirstHalfMask)                {                    priorityTableIndex =                                       IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;                }                else                {                    priorityTableIndex =                                       IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX;                }            }            else            {                /* check if any bit related to queues in the first                 * half of the priority table is set                 */                if (intRegVal & uppPriorityTableFirstHalfMask)                {                    priorityTableIndex =                                       IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;                }                else                {                    priorityTableIndex =                                       IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX;                }            }            /* iterate following the priority table until all the bits             * of the interrupt register are cleared.             */            do            {                qIndex = priorityTable[priorityTableIndex++];                currDispatchQInfo = &dispatchQInfo[qIndex];                intRegCheckMask = currDispatchQInfo->intRegCheckMask;                /* If this queue caused this interrupt to be raised */                if (intRegVal & intRegCheckMask)                {                    /*                      * check if Q type periodic - only lower queues can                     * have there type set to periodic. There can only be one                     * periodic queue, so the sporadics are only disabled once.                     */                    if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex])                    {                        /*                          * Disable the notifications on any sporadics                          */                        for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)                        {                            if (IX_QMGR_TYPE_REALTIME_SPORADIC ==                                     ixQMgrQTypes[i])                            {                                ixQMgrNotificationDisable(i);                                /*                                  * remove from intRegVal as we don't want                                  * to service any sporadics now                                 */                                intRegVal &= ~dispatchQInfo[i].intRegCheckMask;#ifndef NDEBUG                                /* Update statistics */                                dispatcherStats.queueStats[i].disableCount++;#endif                            }                        }                    }                    currDispatchQInfo->callback (qIndex,                                                 currDispatchQInfo->callbackId);#ifndef NDEBUG                    /* Update statistics */                    dispatcherStats.queueStats[qIndex].callbackCnt++;#endif                    /* Clear the interrupt register bit */                    intRegVal &= ~intRegCheckMask;                }            }            while(intRegVal);        } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */    } /* End of intRegVal != 0 */#ifndef NDEBUG    /* Update statistics */    dispatcherStats.loopRunCnt++;#endif    if ((intRegValCopy != 0) && (IX_QMGR_QUELOW_GROUP == group))    {        /*          * lower groups (therefore sticky) AND at least one enabled interrupt         * Write back to clear the interrupt          */        ixQMgrAqmIfQInterruptRegWrite (IX_QMGR_QUELOW_GROUP, intRegValCopy);    }    /* Rebuild the priority table if needed */    if (rebuildTable)    {        ixQMgrDispatcherReBuildPriorityTable ();    }}PRIVATE voidixQMgrDispatcherReBuildPriorityTable (void){    UINT32 qIndex;    UINT32 priority;    int lowQuePriorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX;    int uppQuePriorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX;    /* Reset the rebuild flag */    rebuildTable = FALSE;    /* initialize the mak used to identify the queues in the first half     * of the priority table     */    lowPriorityTableFirstHalfMask = 0;    uppPriorityTableFirstHalfMask = 0;        /* For each priority level */    for(priority=0; priority<IX_QMGR_NUM_PRIORITY_LEVELS; priority++)    {	/* Foreach low queue in this priority */	for(qIndex=0; qIndex<IX_QMGR_MIN_QUEUPP_QID; qIndex++)	{	    if (dispatchQInfo[qIndex].priority == priority)	    { 		/* build the priority table bitmask which match the		 * queues of the first half of the priority table 		 */		if (lowQuePriorityTableIndex < IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX) 		{		    lowPriorityTableFirstHalfMask |= dispatchQInfo[qIndex].intRegCheckMask;		}		/* build the priority table */		priorityTable[lowQuePriorityTableIndex++] = qIndex;	    }	}	/* Foreach upp queue */	for(qIndex=IX_QMGR_MIN_QUEUPP_QID; qIndex<=IX_QMGR_MAX_QID; qIndex++)	{	    if (dispatchQInfo[qIndex].priority == priority)	    {		/* build the priority table bitmask which match the		 * queues of the first half of the priority table 		 */		if (uppQuePriorityTableIndex < IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX) 		{		    uppPriorityTableFirstHalfMask |= dispatchQInfo[qIndex].intRegCheckMask;		}		/* build the priority table */		priorityTable[uppQuePriorityTableIndex++] = qIndex;	    }	}    }}IxQMgrDispatcherStats*ixQMgrDispatcherStatsGet (void){    return &dispatcherStats;}PRIVATE voiddummyCallback (IxQMgrQId qId,	       IxQMgrCallbackId cbId){    /* Throttle the trace message */    if ((dispatchQInfo[qId].dummyCallbackCount % LOG_THROTTLE_COUNT) == 0)    {	IX_QMGR_LOG_WARNING2("--> dummyCallback: qId (%d), callbackId (%d)\n",qId,cbId);    }    dispatchQInfo[qId].dummyCallbackCount++;#ifndef NDEBUG    /* Update statistcs */    dispatcherStats.queueStats[qId].intNoCallbackCnt++;#endif}voidixQMgrLLPShow (int resetStats){#ifndef NDEBUG    UINT8 i = 0;    IxQMgrQInfo *q;    UINT32 intEnableRegVal = 0;    printf ("Livelock statistics are printed on the fly.\n");    printf ("qId Type     EnableCnt DisableCnt IntEnableState Callbacks\n");    printf ("=== ======== ========= ========== ============== =========\n");    for (i=0; i<= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)    {        q = &dispatchQInfo[i];        if (ixQMgrQTypes[i] != IX_QMGR_TYPE_REALTIME_OTHER)        {            printf (" %2d ", i);            if (ixQMgrQTypes[i] == IX_QMGR_TYPE_REALTIME_SPORADIC)            {                printf ("Sporadic");            }            else            {                printf ("Periodic");            }                       ixQMgrAqmIfQInterruptEnableRegRead (IX_QMGR_QUELOW_GROUP,                                                     &intEnableRegVal);            		    intEnableRegVal &= dispatchQInfo[i].intRegCheckMask;            intEnableRegVal = intEnableRegVal >> i;            printf (" %10d %10d %10d %10d\n",                    dispatcherStats.queueStats[i].enableCount,                    dispatcherStats.queueStats[i].disableCount,                    intEnableRegVal,                    dispatcherStats.queueStats[i].callbackCnt);            if (resetStats)            {                dispatcherStats.queueStats[i].enableCount =                dispatcherStats.queueStats[i].disableCount =                 dispatcherStats.queueStats[i].callbackCnt = 0;            }        }    }#else    IX_QMGR_LOG0("Livelock Prevention statistics are only collected in debug mode\n");#endif}voidixQMgrPeriodicDone (void){    UINT32 i = 0;    UINT32 ixQMgrLockKey = 0;    /*      * for the lower queues     */    for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++)    {        /*         * check for sporadics          */        if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i])        {             /*               * enable any sporadics               */             ixQMgrLockKey = ixOsalIrqLock();             ixQMgrAqmIfQInterruptEnable(i);             ixOsalIrqUnlock(ixQMgrLockKey);#ifndef NDEBUG             /*               * Update statistics               */             dispatcherStats.queueStats[i].enableCount++;             dispatcherStats.queueStats[i].notificationEnabled = TRUE;#endif        }    }}IX_STATUSixQMgrCallbackTypeSet (IxQMgrQId qId,                        IxQMgrType type){    UINT32 ixQMgrLockKey = 0;    IxQMgrType ixQMgrOldType =0;#ifndef NDEBUG    if (!ixQMgrQIsConfigured(qId))    {        return IX_QMGR_Q_NOT_CONFIGURED;    }    if (qId >= IX_QMGR_MIN_QUEUPP_QID)    {        return IX_QMGR_PARAMETER_ERROR;    }    if(!IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type))    {        return IX_QMGR_PARAMETER_ERROR;    }#endif    ixQMgrOldType = ixQMgrQTypes[qId];    ixQMgrQTypes[qId] = type;    /*     * check if Q has been changed from type SPORADIC     */    if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrOldType)    {       /*         * previously Q was a SPORADIC, this means that LLP        * might have had it disabled. enable it now.        */       ixQMgrLockKey = ixOsalIrqLock();       ixQMgrAqmIfQInterruptEnable(qId);       ixOsalIrqUnlock(ixQMgrLockKey);#ifndef NDEBUG       /*         * Update statistics         */       dispatcherStats.queueStats[qId].enableCount++;#endif    }    return IX_SUCCESS;}IX_STATUSixQMgrCallbackTypeGet (IxQMgrQId qId,                        IxQMgrType *type){#ifndef NDEBUG    if (!ixQMgrQIsConfigured(qId))    {        return IX_QMGR_Q_NOT_CONFIGURED;    }    if (qId >= IX_QMGR_MIN_QUEUPP_QID)    {        return IX_QMGR_PARAMETER_ERROR;    }    if(type == NULL)    {         return IX_QMGR_PARAMETER_ERROR;    }#endif    *type = ixQMgrQTypes[qId];    return IX_SUCCESS;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -