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