/** * \fn runScheduler * \brief The scheduler processing (static function) * * Loops over the mgmt-queues (high priority first) and if queue enabled and * has packets, dequeue a packet and send it to the TxCtrl. * Exit if the port level is disabled or if couldn't send anything from both queues. * * \note Protect the queues access against preemption from external context (EAPOL). * \param pTxMgmtQ - The module's object * \return void * \sa */ static void runScheduler (TTxMgmtQ *pTxMgmtQ) { TI_STATUS eStatus; TTxCtrlBlk *pPktCtrlBlk; TI_UINT32 uQueId = 0; /* start from highest priority queue */ while(1) { /* If the Mgmt port is closed exit. */ if ( !pTxMgmtQ->bMgmtPortEnable ) { return; } /* Check that the current queue is not busy and is enabled by the state-machine. */ if ( !pTxMgmtQ->aQueueBusy[uQueId] && pTxMgmtQ->aQueueEnabledBySM[uQueId]) { /* Dequeue a packet in a critical section */ context_EnterCriticalSection (pTxMgmtQ->hContext); pPktCtrlBlk = (TTxCtrlBlk *) que_Dequeue (pTxMgmtQ->aQueues[uQueId]); context_LeaveCriticalSection (pTxMgmtQ->hContext); if (pPktCtrlBlk) { pTxMgmtQ->tDbgCounters.aDequeuePackets[uQueId]++; /* Send the packet */ eStatus = txCtrl_XmitMgmt (pTxMgmtQ->hTxCtrl, pPktCtrlBlk); /* In case the return status is busy it means that the packet wasn't handled so we need to requeue the packet for future try. */ if(eStatus == STATUS_XMIT_BUSY) { /* Requeue the packet in a critical section */ context_EnterCriticalSection (pTxMgmtQ->hContext); que_Requeue (pTxMgmtQ->aQueues[uQueId], (TI_HANDLE)pPktCtrlBlk); context_LeaveCriticalSection (pTxMgmtQ->hContext); pTxMgmtQ->tDbgCounters.aRequeuePackets[uQueId]++; } /* The packet was handled by the lower Tx layers. */ else { pTxMgmtQ->tDbgCounters.aXmittedPackets[uQueId]++; /* Successful delivery so start next tx from the high priority queue (mgmt), * giving it strict priority over the lower queue. */ uQueId = 0; continue; } } } /* If we got here we couldn't deliver a packet from current queue, so progress to lower * priority queue and if already in lowest queue exit. */ uQueId++; if (uQueId < NUM_OF_MGMT_QUEUES) { continue; /* Try sending from next queue (i.e. the EAPOL queue). */ } else { /* We couldn't send from both queues so indicate end of packets burst and exit. */ TWD_txXfer_EndOfBurst (pTxMgmtQ->hTWD); return; } } /* End of while */ /* Unreachable code */ }
/** * \fn runScheduler * \brief The scheduler processing (static function) * * Loops over the mgmt-queues (high priority first) and if queue enabled and * has packets, dequeue a packet and send it to the TxCtrl. * Exit if the port level is disabled or if couldn't send anything from both queues. * * \note Protect the queues access against preemption from external context (EAPOL). * \param pTxMgmtQ - The module's object * \return void * \sa */ static void runScheduler (TTxMgmtQ *pTxMgmtQ) { TI_STATUS eStatus; TTxCtrlBlk *pPktCtrlBlk; TI_UINT32 uQueId = 0; /* start from highest priority queue */ TMgmtLinkQ *pLinkQ; TI_UINT32 uHlid = 0; TI_BOOL bQueueActive; TI_BOOL bLinkActive; while(1) { /* If the Mgmt port is closed or AC for mgmt is busy, exit. */ if ( (!pTxMgmtQ->bMgmtPortEnable) || (pTxMgmtQ->aMgmtAcBusy) ) { return; } pLinkQ = &pTxMgmtQ->aMgmtLinkQ[uHlid]; /* Link queues */ bLinkActive = ( (!pLinkQ->bBusy) && pLinkQ->bEnabled ); bQueueActive = pLinkQ->aQenabled[uQueId]; /* Check that the current link and current queue are not busy and are enabled */ if ( bLinkActive && bQueueActive) { /* Dequeue a packet in a critical section */ context_EnterCriticalSection (pTxMgmtQ->hContext); pPktCtrlBlk = (TTxCtrlBlk *) que_Dequeue (pLinkQ->aQueues[uQueId]); context_LeaveCriticalSection (pTxMgmtQ->hContext); if (pPktCtrlBlk) { pLinkQ->tDbgCounters.aDequeuePackets[uQueId]++; /* Send the packet */ eStatus = txCtrl_XmitMgmt (pTxMgmtQ->hTxCtrl, pPktCtrlBlk); /* In case the return status is busy it means that the packet wasn't handled so we need to requeue the packet for future try. */ if(eStatus == STATUS_XMIT_BUSY) { /* Requeue the packet in a critical section */ context_EnterCriticalSection (pTxMgmtQ->hContext); que_Requeue (pLinkQ->aQueues[uQueId], (TI_HANDLE)pPktCtrlBlk); context_LeaveCriticalSection (pTxMgmtQ->hContext); pLinkQ->tDbgCounters.aRequeuePackets[uQueId]++; } /* The packet was handled by the lower Tx layers. */ else { pLinkQ->tDbgCounters.aXmittedPackets[uQueId]++; /* Successful delivery so start next tx from the high priority queue (mgmt), * giving it strict priority over the lower queue. */ uQueId = 0; continue; } } } /* If we got here we couldn't deliver a packet from current queue, so progress to lower * priority queue and if already in lowest queue exit. */ if (bLinkActive) /* Continue to next queue only if the link is active */ { uQueId++; if (uQueId < NUM_OF_MGMT_QUEUES) { continue; /* Try sending from next queue (i.e. the EAPOL queue). */ } } /* * continue to next link */ uHlid++; if (uHlid < WLANLINKS_MAX_LINKS) { uQueId = 0; continue; } else { /* We couldn't send from both queues so indicate end of packets burst and exit. */ TWD_txXfer_EndOfBurst (pTxMgmtQ->hTWD); return; } } /* End of while */ /* Unreachable code */ }