1f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger/********************************************************************** 2f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* LEAKYBUCKET.C 3f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* This file contains the routines related to Leaky Bucket Algorithm. 4f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger***********************************************************************/ 5f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger#include "headers.h" 6f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 7f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger/********************************************************************* 8f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Function - UpdateTokenCount() 9f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* 10f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Description - This function calculates the token count for each 11f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* channel and updates the same in Adapter strucuture. 12f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* 13f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Parameters - Adapter: Pointer to the Adapter structure. 14f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* 15f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Returns - None 16f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger**********************************************************************/ 17f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 1844a17eff844d92421c8b568c84df29735e1e45f9Arnd Bergmannstatic VOID UpdateTokenCount(register PMINI_ADAPTER Adapter) 19f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger{ 20f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger ULONG liCurrentTime; 21f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger INT i = 0; 22f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger struct timeval tv; 23f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 24f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "=====>\n"); 25f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(NULL == Adapter) 26f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 27f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Adapter found NULL!\n"); 28f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger return; 29f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 30f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 31f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger do_gettimeofday(&tv); 32f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger for(i = 0; i < NO_OF_QUEUES; i++) 33f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 34f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(TRUE == Adapter->PackInfo[i].bValid && 35f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger (1 == Adapter->PackInfo[i].ucDirection)) 36f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 37f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger liCurrentTime = ((tv.tv_sec- 38f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger Adapter->PackInfo[i].stLastUpdateTokenAt.tv_sec)*1000 + 39f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger (tv.tv_usec-Adapter->PackInfo[i].stLastUpdateTokenAt.tv_usec)/ 40f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 1000); 41f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(0!=liCurrentTime) 42f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 43f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger Adapter->PackInfo[i].uiCurrentTokenCount += (ULONG) 44f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger ((Adapter->PackInfo[i].uiMaxAllowedRate) * 45f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger ((ULONG)((liCurrentTime)))/1000); 46f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger memcpy(&Adapter->PackInfo[i].stLastUpdateTokenAt, 47f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger &tv, sizeof(struct timeval)); 48f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger Adapter->PackInfo[i].liLastUpdateTokenAt = liCurrentTime; 49f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if((Adapter->PackInfo[i].uiCurrentTokenCount) >= 50f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger Adapter->PackInfo[i].uiMaxBucketSize) 51f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 52f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger Adapter->PackInfo[i].uiCurrentTokenCount = 53f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger Adapter->PackInfo[i].uiMaxBucketSize; 54f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 55f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 56f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 57f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 58f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "<=====\n"); 59f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger return; 60f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 61f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger} 62f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 63f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 64f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger/********************************************************************* 65f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Function - IsPacketAllowedForFlow() 66f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* 67f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Description - This function checks whether the given packet from the 68f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* specified queue can be allowed for transmission by 69f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* checking the token count. 70f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* 71f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Parameters - Adapter : Pointer to the Adpater structure. 72f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* - iQIndex : The queue Identifier. 73f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* - ulPacketLength: Number of bytes to be transmitted. 74f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* 75f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Returns - The number of bytes allowed for transmission. 76f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* 77f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger***********************************************************************/ 7820f48653fcf51f6d1246b5f3f86b40ed779385b2Stephen Hemmingerstatic ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF) 79f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger{ 80f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow ===>"); 81f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger /* Validate the parameters */ 82f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(NULL == Adapter || (psSF < Adapter->PackInfo && 839f1c75ac2dba752ad3734bd3ffab805a6a3fbedaArnd Bergmann (uintptr_t)psSF > (uintptr_t) &Adapter->PackInfo[HiPriority])) 84f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 85c5ebe2278ba600ff48663ec84c6e7f34d291503fStephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %zd\n", Adapter, (psSF-Adapter->PackInfo)); 86f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger return 0; 87f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 88f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 89f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(FALSE != psSF->bValid && psSF->ucDirection) 90f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 91f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(0 != psSF->uiCurrentTokenCount) 92f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 93f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger return psSF->uiCurrentTokenCount; 94f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 95f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger else 96f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 97c5ebe2278ba600ff48663ec84c6e7f34d291503fStephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %zd Available %u\n", 98f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount); 99f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger psSF->uiPendedLast = 1; 100f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 101f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 102f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger else 103f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 104c5ebe2278ba600ff48663ec84c6e7f34d291503fStephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %zd not valid\n", psSF-Adapter->PackInfo); 105f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 106f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow <==="); 107f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger return 0; 108f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger} 109f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 110f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger/** 111f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger@ingroup tx_functions 112f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen HemmingerThis function despatches packet from the specified queue. 113f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger@return Zero(success) or Negative value(failure) 114f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger*/ 11520f48653fcf51f6d1246b5f3f86b40ed779385b2Stephen Hemmingerstatic INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**<Logical Adapter*/ 11620f48653fcf51f6d1246b5f3f86b40ed779385b2Stephen Hemminger PacketInfo *psSF, /**<Queue identifier*/ 11720f48653fcf51f6d1246b5f3f86b40ed779385b2Stephen Hemminger struct sk_buff* Packet) /**<Pointer to the packet to be sent*/ 118f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger{ 119f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger INT Status=STATUS_FAILURE; 120f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger UINT uiIndex =0,PktLen = 0; 121f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 122f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "=====>"); 123f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(!Adapter || !Packet || !psSF) 124f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 125f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "Got NULL Adapter or Packet"); 126f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger return -EINVAL; 127f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 128f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 129f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(psSF->liDrainCalculated==0) 130f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 131f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger psSF->liDrainCalculated = jiffies; 132f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 133f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger ///send the packet to the fifo.. 134f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger PktLen = Packet->len; 135f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger Status = SetupNextSend(Adapter, Packet, psSF->usVCID_Value); 136f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(Status == 0) 137f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 138f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++) 139f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { if((PktLen <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) && (PktLen > MIBS_PKTSIZEHIST_RANGE*(uiIndex))) 140f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger Adapter->aTxPktSizeHist[uiIndex]++; 141f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 142f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 143f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "<====="); 144f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger return Status; 145f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger} 146f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 147f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger/************************************************************************ 148f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Function - CheckAndSendPacketFromIndex() 149f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* 150f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Description - This function dequeues the data/control packet from the 151f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* specified queue for transmission. 152f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* 153f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Parameters - Adapter : Pointer to the driver control structure. 154f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* - iQIndex : The queue Identifier. 155f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* 156f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Returns - None. 157f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* 158f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger****************************************************************************/ 15920f48653fcf51f6d1246b5f3f86b40ed779385b2Stephen Hemmingerstatic VOID CheckAndSendPacketFromIndex(PMINI_ADAPTER Adapter, PacketInfo *psSF) 160f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger{ 161f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger struct sk_buff *QueuePacket=NULL; 162f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger char *pControlPacket = NULL; 163f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger INT Status=0; 164f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger int iPacketLen=0; 165f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 166f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 167c5ebe2278ba600ff48663ec84c6e7f34d291503fStephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%zd ====>", (psSF-Adapter->PackInfo)); 1689f1c75ac2dba752ad3734bd3ffab805a6a3fbedaArnd Bergmann if((psSF != &Adapter->PackInfo[HiPriority]) && Adapter->LinkUpStatus && atomic_read(&psSF->uiPerSFTxResourceCount))//Get data packet 169f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 170f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(!psSF->ucDirection ) 171f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger return; 172f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 173f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount "); 174f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode) 1755cf084f44ac24189ef3373010da49e26d651aa06Stephen Hemminger return; /* in idle mode */ 1765cf084f44ac24189ef3373010da49e26d651aa06Stephen Hemminger 177f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger // Check for Free Descriptors 178f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(atomic_read(&Adapter->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS) 179f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 180f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, " No Free Tx Descriptor(%d) is available for Data pkt..",atomic_read(&Adapter->CurrNumFreeTxDesc)); 181f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger return ; 182f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 183f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 184f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger spin_lock_bh(&psSF->SFQueueLock); 185f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger QueuePacket=psSF->FirstTxQueue; 186f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 187f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(QueuePacket) 188f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 189f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Dequeuing Data Packet"); 190f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 191f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(psSF->bEthCSSupport) 192f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger iPacketLen = QueuePacket->len; 193f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger else 194f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger iPacketLen = QueuePacket->len-ETH_HLEN; 195f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 196f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger iPacketLen<<=3; 197f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(iPacketLen <= GetSFTokenCount(Adapter, psSF)) 198f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 199f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Allowed bytes %d", 200f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger (iPacketLen >> 3)); 201f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 202f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger DEQUEUEPACKET(psSF->FirstTxQueue,psSF->LastTxQueue); 203f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger psSF->uiCurrentBytesOnHost -= (QueuePacket->len); 204f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger psSF->uiCurrentPacketsOnHost--; 205f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger atomic_dec(&Adapter->TotalPacketCount); 206f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger spin_unlock_bh(&psSF->SFQueueLock); 207f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 208f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger Status = SendPacketFromQueue(Adapter, psSF, QueuePacket); 209f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger psSF->uiPendedLast = FALSE; 210f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 211f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger else 212f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 213c5ebe2278ba600ff48663ec84c6e7f34d291503fStephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %zd\n", psSF-Adapter->PackInfo); 214f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n", 215f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger psSF->uiCurrentTokenCount, iPacketLen); 21625985edcedea6396277003854657b5f3cb31a628Lucas De Marchi //this part indicates that because of non-availability of the tokens 217f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger //pkt has not been send out hence setting the pending flag indicating the host to send it out 218f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger //first next iteration . 219f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger psSF->uiPendedLast = TRUE; 220f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger spin_unlock_bh(&psSF->SFQueueLock); 221f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 222f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 223f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger else 224f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 225f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger spin_unlock_bh(&psSF->SFQueueLock); 226f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 227f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 228f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger else 229f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 230f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 231f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if((atomic_read(&Adapter->CurrNumFreeTxDesc) > 0 ) && 232f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger (atomic_read(&Adapter->index_rd_txcntrlpkt) != 233f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger atomic_read(&Adapter->index_wr_txcntrlpkt)) 234f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger ) 235f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 236f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger pControlPacket = Adapter->txctlpacket 237f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger [(atomic_read(&Adapter->index_rd_txcntrlpkt)%MAX_CNTRL_PKTS)]; 238f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(pControlPacket) 239f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 240f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Sending Control packet"); 241f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger Status = SendControlPacket(Adapter, pControlPacket); 242f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(STATUS_SUCCESS==Status) 243f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 244f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger spin_lock_bh(&psSF->SFQueueLock); 245f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger psSF->NumOfPacketsSent++; 246f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger psSF->uiSentBytes+=((PLEADER)pControlPacket)->PLength; 247f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger psSF->uiSentPackets++; 248f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger atomic_dec(&Adapter->TotalPacketCount); 249f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger psSF->uiCurrentBytesOnHost -= ((PLEADER)pControlPacket)->PLength; 250f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger psSF->uiCurrentPacketsOnHost--; 251f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger atomic_inc(&Adapter->index_rd_txcntrlpkt); 252f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger spin_unlock_bh(&psSF->SFQueueLock); 253f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 254f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger else 255f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "SendControlPacket Failed\n"); 256f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 257f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger else 258f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 259f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, " Control Pkt is not available, Indexing is wrong...."); 260f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 261f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 262f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 263f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger} 264f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 265f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 266f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger/******************************************************************* 267f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Function - transmit_packets() 268f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* 269f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Description - This function transmits the packets from different 270f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* queues, if free descriptors are available on target. 271f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* 272f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Parameters - Adapter: Pointer to the Adapter structure. 273f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* 274f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger* Returns - None. 275f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger********************************************************************/ 276f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen HemmingerVOID transmit_packets(PMINI_ADAPTER Adapter) 277f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger{ 278f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger UINT uiPrevTotalCount = 0; 279f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger int iIndex = 0; 280f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 281f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BOOLEAN exit_flag = TRUE ; 282f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 283f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "=====>"); 284f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 285f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(NULL == Adapter) 286f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 287f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX,TX_PACKETS, DBG_LVL_ALL, "Got NULL Adapter"); 288f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger return; 289f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 290f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(Adapter->device_removed == TRUE) 291f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 292f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device removed"); 293f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger return; 294f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 295f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 296f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nUpdateTokenCount ====>\n"); 297f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 298f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger UpdateTokenCount(Adapter); 299f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 300f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nPruneQueueAllSF ====>\n"); 301f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 302f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger PruneQueueAllSF(Adapter); 303f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 304f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger uiPrevTotalCount = atomic_read(&Adapter->TotalPacketCount); 305f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 306f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger for(iIndex=HiPriority;iIndex>=0;iIndex--) 307f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 308f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if( !uiPrevTotalCount || (TRUE == Adapter->device_removed)) 309f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger break; 310f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 311f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(Adapter->PackInfo[iIndex].bValid && 312f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger Adapter->PackInfo[iIndex].uiPendedLast && 313f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger Adapter->PackInfo[iIndex].uiCurrentBytesOnHost) 314f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 315f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex.."); 316f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]); 317f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger uiPrevTotalCount--; 318f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 319f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 320f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 321f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger while(uiPrevTotalCount > 0 && !Adapter->device_removed) 322f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 323f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger exit_flag = TRUE ; 324f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger //second iteration to parse non-pending queues 325f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger for(iIndex=HiPriority;iIndex>=0;iIndex--) 326f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 327f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if( !uiPrevTotalCount || (TRUE == Adapter->device_removed)) 328f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger break; 329f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 330f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(Adapter->PackInfo[iIndex].bValid && 331f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger Adapter->PackInfo[iIndex].uiCurrentBytesOnHost && 332f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger !Adapter->PackInfo[iIndex].uiPendedLast ) 333f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 334f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex.."); 335f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]); 336f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger uiPrevTotalCount--; 337f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger exit_flag = FALSE; 338f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 339f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 340f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger 341f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode) 342f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger { 343f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "In Idle Mode\n"); 344f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger break; 345f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger } 346f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger if(exit_flag == TRUE ) 347f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger break ; 348f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger }/* end of inner while loop */ 3495cf084f44ac24189ef3373010da49e26d651aa06Stephen Hemminger 350f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger update_per_cid_rx (Adapter); 351f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger Adapter->txtransmit_running = 0; 352f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<======"); 353f8942e07a3db9d82e8fb11d3d494876b8bae9ff9Stephen Hemminger} 354