GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / usb / Beceem_driver / src / Common / LeakyBucket.c
blob38563bd37326821f56d6e726629029d8603bc50b
1 /*
2 * LeakyBucket.c
4 *Copyright (C) 2010 Beceem Communications, Inc.
6 *This program is free software: you can redistribute it and/or modify
7 *it under the terms of the GNU General Public License version 2 as
8 *published by the Free Software Foundation.
10 *This program is distributed in the hope that it will be useful,but
11 *WITHOUT ANY WARRANTY; without even the implied warranty of
12 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 *See the GNU General Public License for more details.
15 *You should have received a copy of the GNU General Public License
16 *along with this program. If not, write to the Free Software Foundation, Inc.,
17 *51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 /**********************************************************************
23 * This file contains the routines related to Leaky Bucket Algorithm.
24 ***********************************************************************/
25 #include<headers.h>
27 /*********************************************************************
28 * Function - UpdateTokenCount()
30 * Description - This function calculates the token count for each
31 * channel and updates the same in Adapter strucuture.
33 * Parameters - Adapter: Pointer to the Adapter structure.
35 * Returns - None
36 **********************************************************************/
38 VOID UpdateTokenCount(register PMINI_ADAPTER Adapter)
40 ULONG liElapsedTime;
41 INT i = 0;
42 ULONG currjiffies = jiffies;
45 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "=====>\n");
46 if(NULL == Adapter)
48 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Adapter found NULL!\n");
49 return;
52 for(i = 0; i < NO_OF_QUEUES; i++)
54 if(TRUE == Adapter->PackInfo[i].bValid &&
55 (1 == Adapter->PackInfo[i].ucDirection))
57 liElapsedTime = currjiffies - Adapter->localjiffies;
58 if(0!=liElapsedTime)
60 Adapter->PackInfo[i].uiCurrentTokenCount += (ULONG)
61 (((Adapter->PackInfo[i].uiMaxAllowedRate) * liElapsedTime)/HZ);
63 if((Adapter->PackInfo[i].uiCurrentTokenCount) >= Adapter->PackInfo[i].uiMaxBucketSize)
65 Adapter->PackInfo[i].uiCurrentTokenCount = Adapter->PackInfo[i].uiMaxBucketSize;
70 Adapter->localjiffies = currjiffies;
71 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "<=====\n");
72 return;
77 /*********************************************************************
78 * Function - IsPacketAllowedForFlow()
80 * Description - This function checks whether the given packet from the
81 * specified queue can be allowed for transmission by
82 * checking the token count.
84 * Parameters - Adapter : Pointer to the Adpater structure.
85 * - iQIndex : The queue Identifier.
86 * - ulPacketLength: Number of bytes to be transmitted.
88 * Returns - The number of bytes allowed for transmission.
90 ***********************************************************************/
91 static __inline ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF)
93 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow ===>");
94 /* Validate the parameters */
95 if(NULL == Adapter || (psSF < Adapter->PackInfo &&
96 (UINT)psSF > (UINT) &Adapter->PackInfo[HiPriority]))
98 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %d\n", Adapter, (psSF-Adapter->PackInfo));
99 return 0;
102 if(FALSE != psSF->bValid && psSF->ucDirection)
104 if(0 != psSF->uiCurrentTokenCount)
106 return psSF->uiCurrentTokenCount;
108 else
110 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %d Available %u\n",
111 psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount);
112 psSF->uiPendedLast = 1;
115 else
117 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %d not valid\n", psSF-Adapter->PackInfo);
119 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow <===");
120 return 0;
123 static __inline void RemovePacketFromQueue(PacketInfo *pPackInfo , struct sk_buff *Packet)
125 struct sk_buff *psQueueCurrent=NULL, *psLastQueueNode=NULL;
126 psQueueCurrent = pPackInfo->FirstTxQueue;
127 while(psQueueCurrent)
129 if((UINT)Packet == (UINT)psQueueCurrent)
131 if((UINT)psQueueCurrent == (UINT)pPackInfo->FirstTxQueue)
133 pPackInfo->FirstTxQueue=psQueueCurrent->next;
134 if((UINT)psQueueCurrent==(UINT)pPackInfo->LastTxQueue)
135 pPackInfo->LastTxQueue=NULL;
137 else
139 psLastQueueNode->next=psQueueCurrent->next;
141 break;
143 psLastQueueNode = psQueueCurrent;
144 psQueueCurrent=psQueueCurrent->next;
148 @ingroup tx_functions
149 This function despatches packet from the specified queue.
150 @return Zero(success) or Negative value(failure)
152 static __inline INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
153 PacketInfo *psSF, /**<Queue identifier*/
154 struct sk_buff* Packet) /**<Pointer to the packet to be sent*/
156 INT Status=STATUS_FAILURE;
157 UINT uiIndex =0,PktLen = 0;
159 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "=====>");
160 if(!Adapter || !Packet || !psSF)
162 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "Got NULL Adapter or Packet");
163 return -EINVAL;
166 if(psSF->liDrainCalculated==0)
168 psSF->liDrainCalculated = jiffies;
170 ///send the packet to the fifo..
171 PktLen = Packet->len;
172 Status = SetupNextSend(Adapter, Packet, psSF->usVCID_Value);
173 if(Status == 0)
175 for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++)
176 { if((PktLen <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) && (PktLen > MIBS_PKTSIZEHIST_RANGE*(uiIndex)))
177 Adapter->aTxPktSizeHist[uiIndex]++;
180 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "<=====");
181 return Status;
184 /************************************************************************
185 * Function - CheckAndSendPacketFromIndex()
187 * Description - This function dequeues the data/control packet from the
188 * specified queue for transmission.
190 * Parameters - Adapter : Pointer to the driver control structure.
191 * - iQIndex : The queue Identifier.
193 * Returns - None.
195 ****************************************************************************/
196 static __inline VOID CheckAndSendPacketFromIndex
197 (PMINI_ADAPTER Adapter, PacketInfo *psSF)
199 struct sk_buff *QueuePacket=NULL;
200 char *pControlPacket = NULL;
201 INT Status=0;
202 int iPacketLen=0;
205 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%d ====>", (psSF-Adapter->PackInfo));
206 if(((UINT)psSF != (UINT)&Adapter->PackInfo[HiPriority]) && Adapter->LinkUpStatus )//Get data packet
208 if(!psSF->ucDirection )
209 return;
211 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount ");
212 if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode)
214 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle Mode..Hence blocking Data Packets..\n");
215 return;
217 // Check for Free Descriptors
218 if(atomic_read(&Adapter->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS)
220 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));
221 return ;
224 #if 0
225 PruneQueue(Adapter,(psSF-Adapter->PackInfo));
226 #endif
227 spin_lock_bh(&psSF->SFQueueLock);
228 QueuePacket=psSF->FirstTxQueue;
230 if(QueuePacket)
232 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Dequeuing Data Packet");
234 if(psSF->bEthCSSupport)
235 iPacketLen = QueuePacket->len;
236 else
237 iPacketLen = QueuePacket->len-ETH_HLEN;
239 iPacketLen<<=3;
240 if(iPacketLen <= GetSFTokenCount(Adapter, psSF))
242 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Allowed bytes %d",
243 (iPacketLen >> 3));
245 DEQUEUEPACKET(psSF->FirstTxQueue,psSF->LastTxQueue);
246 psSF->uiCurrentBytesOnHost -= (QueuePacket->len);
247 psSF->uiCurrentPacketsOnHost--;
248 atomic_dec(&Adapter->TotalPacketCount);
249 spin_unlock_bh(&psSF->SFQueueLock);
251 Status = SendPacketFromQueue(Adapter, psSF, QueuePacket);
252 psSF->uiPendedLast = FALSE;
254 else
256 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %d\n", psSF-Adapter->PackInfo);
257 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n",
258 psSF->uiCurrentTokenCount, iPacketLen);
259 //this part indicates that becuase of non-availability of the tokens
260 //pkt has not been send out hence setting the pending flag indicating the host to send it out
261 //first next iteration .
262 psSF->uiPendedLast = TRUE;
263 spin_unlock_bh(&psSF->SFQueueLock);
266 else
268 spin_unlock_bh(&psSF->SFQueueLock);
271 else if((UINT)psSF == (UINT)&Adapter->PackInfo[HiPriority])
273 spin_lock_bh(&psSF->SFQueueLock);
274 if((atomic_read(&Adapter->CurrNumFreeTxDesc) > 0 ) &&
275 (atomic_read(&Adapter->index_rd_txcntrlpkt) !=
276 atomic_read(&Adapter->index_wr_txcntrlpkt))
279 pControlPacket = Adapter->txctlpacket
280 [(atomic_read(&Adapter->index_rd_txcntrlpkt)%MAX_CNTRL_PKTS)];
281 if(pControlPacket)
283 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Sending Control packet");
284 Status = SendControlPacket(Adapter, pControlPacket);
285 if(STATUS_SUCCESS==Status)
288 psSF->NumOfPacketsSent++;
289 psSF->uiSentBytes+=((PLEADER)pControlPacket)->PLength;
290 psSF->uiSentPackets++;
291 atomic_dec(&Adapter->TotalPacketCount);
292 psSF->uiCurrentBytesOnHost -= ((PLEADER)pControlPacket)->PLength;
293 psSF->uiCurrentPacketsOnHost--;
294 atomic_inc(&Adapter->index_rd_txcntrlpkt);
297 else
298 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "SendControlPacket Failed\n");
300 else
302 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, " Control Pkt is not available, Indexing is wrong....");
306 spin_unlock_bh(&psSF->SFQueueLock);
309 if(Status != STATUS_SUCCESS) //Tx of data packet to device Failed
311 if(Adapter->bcm_jiffies == 0)
312 Adapter->bcm_jiffies = jiffies;
314 else
316 Adapter->bcm_jiffies = 0;
318 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<=====");
322 /*******************************************************************
323 * Function - transmit_packets()
325 * Description - This function transmits the packets from different
326 * queues, if free descriptors are available on target.
328 * Parameters - Adapter: Pointer to the Adapter structure.
330 * Returns - None.
331 ********************************************************************/
332 VOID transmit_packets(PMINI_ADAPTER Adapter)
334 UINT uiPrevTotalCount = 0;
335 int iIndex = 0;
337 BOOLEAN exit_flag = TRUE ;
339 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "=====>");
341 if(NULL == Adapter)
343 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX,TX_PACKETS, DBG_LVL_ALL, "Got NULL Adapter");
344 return;
346 if(Adapter->device_removed == TRUE)
348 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device removed");
349 return;
352 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nUpdateTokenCount ====>\n");
354 UpdateTokenCount(Adapter);
356 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nPruneQueueAllSF ====>\n");
358 PruneQueueAllSF(Adapter);
360 uiPrevTotalCount = atomic_read(&Adapter->TotalPacketCount);
362 for(iIndex=HiPriority;iIndex>=0;iIndex--)
364 if( !uiPrevTotalCount || (TRUE == Adapter->device_removed))
365 break;
367 if(Adapter->PackInfo[iIndex].bValid &&
368 Adapter->PackInfo[iIndex].uiPendedLast &&
369 Adapter->PackInfo[iIndex].uiCurrentBytesOnHost &&
370 ((iIndex==HiPriority) || (atomic_read(&Adapter->PackInfo[iIndex].uiPerSFTxResourceCount)>0))
373 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex..");
374 CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]);
375 uiPrevTotalCount--;
379 while(uiPrevTotalCount > 0 && !Adapter->device_removed)
381 exit_flag = TRUE ;
382 //second iteration to parse non-pending queues
383 for(iIndex=HiPriority;iIndex>=0;iIndex--)
385 if( !uiPrevTotalCount || (TRUE == Adapter->device_removed))
386 break;
388 if(Adapter->PackInfo[iIndex].bValid &&
389 Adapter->PackInfo[iIndex].uiCurrentBytesOnHost &&
390 !Adapter->PackInfo[iIndex].uiPendedLast &&
391 ((iIndex==HiPriority) || (atomic_read(&Adapter->PackInfo[iIndex].uiPerSFTxResourceCount)>0))
394 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex..");
395 CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]);
396 uiPrevTotalCount--;
397 exit_flag = FALSE;
401 if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode)
403 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "In Idle Mode\n");
404 break;
406 if(exit_flag == TRUE )
407 break ;
408 }/* end of inner while loop */
409 if(Adapter->bcm_jiffies == 0 &&
410 atomic_read(&Adapter->TotalPacketCount) != 0 &&
411 uiPrevTotalCount == atomic_read(&Adapter->TotalPacketCount))
413 Adapter->bcm_jiffies = jiffies;
415 update_per_cid_rx (Adapter);
416 Adapter->txtransmit_running = 0;
417 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<======");