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