Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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