staging/bcm: add sparse annotations
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / bcm / LeakyBucket.c
blobcae382313ce91d78b22e54d18382b97a5ad25a47
1 /**********************************************************************
2 * LEAKYBUCKET.C
3 * This file contains the routines related to Leaky Bucket Algorithm.
4 ***********************************************************************/
5 #include "headers.h"
7 /*********************************************************************
8 * Function - UpdateTokenCount()
10 * Description - This function calculates the token count for each
11 * channel and updates the same in Adapter strucuture.
13 * Parameters - Adapter: Pointer to the Adapter structure.
15 * Returns - None
16 **********************************************************************/
18 static VOID UpdateTokenCount(register PMINI_ADAPTER Adapter)
20 ULONG liCurrentTime;
21 INT i = 0;
22 struct timeval tv;
24 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "=====>\n");
25 if(NULL == Adapter)
27 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Adapter found NULL!\n");
28 return;
31 do_gettimeofday(&tv);
32 for(i = 0; i < NO_OF_QUEUES; i++)
34 if(TRUE == Adapter->PackInfo[i].bValid &&
35 (1 == Adapter->PackInfo[i].ucDirection))
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)
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)
52 Adapter->PackInfo[i].uiCurrentTokenCount =
53 Adapter->PackInfo[i].uiMaxBucketSize;
58 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "<=====\n");
59 return;
64 /*********************************************************************
65 * Function - IsPacketAllowedForFlow()
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.
71 * Parameters - Adapter : Pointer to the Adpater structure.
72 * - iQIndex : The queue Identifier.
73 * - ulPacketLength: Number of bytes to be transmitted.
75 * Returns - The number of bytes allowed for transmission.
77 ***********************************************************************/
78 static __inline ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF)
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]))
85 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %ld\n", Adapter, (psSF-Adapter->PackInfo));
86 return 0;
89 if(FALSE != psSF->bValid && psSF->ucDirection)
91 if(0 != psSF->uiCurrentTokenCount)
93 return psSF->uiCurrentTokenCount;
95 else
97 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %ld Available %u\n",
98 psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount);
99 psSF->uiPendedLast = 1;
102 else
104 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %ld not valid\n", psSF-Adapter->PackInfo);
106 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow <===");
107 return 0;
110 static __inline void RemovePacketFromQueue(PacketInfo *pPackInfo , struct sk_buff *Packet)
112 struct sk_buff *psQueueCurrent=NULL, *psLastQueueNode=NULL;
113 psQueueCurrent = pPackInfo->FirstTxQueue;
114 while(psQueueCurrent)
116 if(Packet == psQueueCurrent)
118 if(psQueueCurrent == pPackInfo->FirstTxQueue)
120 pPackInfo->FirstTxQueue=psQueueCurrent->next;
121 if(psQueueCurrent==pPackInfo->LastTxQueue)
122 pPackInfo->LastTxQueue=NULL;
124 else
126 psLastQueueNode->next=psQueueCurrent->next;
128 break;
130 psLastQueueNode = psQueueCurrent;
131 psQueueCurrent=psQueueCurrent->next;
135 @ingroup tx_functions
136 This function despatches packet from the specified queue.
137 @return Zero(success) or Negative value(failure)
139 static __inline INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**<Logical Adapter*/
140 PacketInfo *psSF, /**<Queue identifier*/
141 struct sk_buff* Packet) /**<Pointer to the packet to be sent*/
143 INT Status=STATUS_FAILURE;
144 UINT uiIndex =0,PktLen = 0;
146 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "=====>");
147 if(!Adapter || !Packet || !psSF)
149 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "Got NULL Adapter or Packet");
150 return -EINVAL;
153 if(psSF->liDrainCalculated==0)
155 psSF->liDrainCalculated = jiffies;
157 ///send the packet to the fifo..
158 PktLen = Packet->len;
159 Status = SetupNextSend(Adapter, Packet, psSF->usVCID_Value);
160 if(Status == 0)
162 for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++)
163 { if((PktLen <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) && (PktLen > MIBS_PKTSIZEHIST_RANGE*(uiIndex)))
164 Adapter->aTxPktSizeHist[uiIndex]++;
167 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "<=====");
168 return Status;
171 /************************************************************************
172 * Function - CheckAndSendPacketFromIndex()
174 * Description - This function dequeues the data/control packet from the
175 * specified queue for transmission.
177 * Parameters - Adapter : Pointer to the driver control structure.
178 * - iQIndex : The queue Identifier.
180 * Returns - None.
182 ****************************************************************************/
183 static __inline VOID CheckAndSendPacketFromIndex
184 (PMINI_ADAPTER Adapter, PacketInfo *psSF)
186 struct sk_buff *QueuePacket=NULL;
187 char *pControlPacket = NULL;
188 INT Status=0;
189 int iPacketLen=0;
192 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%ld ====>", (psSF-Adapter->PackInfo));
193 if((psSF != &Adapter->PackInfo[HiPriority]) && Adapter->LinkUpStatus && atomic_read(&psSF->uiPerSFTxResourceCount))//Get data packet
195 if(!psSF->ucDirection )
196 return;
198 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount ");
199 if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode)
201 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle Mode..Hence blocking Data Packets..\n");
202 return;
204 // Check for Free Descriptors
205 if(atomic_read(&Adapter->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS)
207 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));
208 return ;
211 #if 0
212 PruneQueue(Adapter,(psSF-Adapter->PackInfo));
213 #endif
214 spin_lock_bh(&psSF->SFQueueLock);
215 QueuePacket=psSF->FirstTxQueue;
217 if(QueuePacket)
219 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Dequeuing Data Packet");
221 if(psSF->bEthCSSupport)
222 iPacketLen = QueuePacket->len;
223 else
224 iPacketLen = QueuePacket->len-ETH_HLEN;
226 iPacketLen<<=3;
227 if(iPacketLen <= GetSFTokenCount(Adapter, psSF))
229 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Allowed bytes %d",
230 (iPacketLen >> 3));
232 DEQUEUEPACKET(psSF->FirstTxQueue,psSF->LastTxQueue);
233 psSF->uiCurrentBytesOnHost -= (QueuePacket->len);
234 psSF->uiCurrentPacketsOnHost--;
235 atomic_dec(&Adapter->TotalPacketCount);
236 spin_unlock_bh(&psSF->SFQueueLock);
238 Status = SendPacketFromQueue(Adapter, psSF, QueuePacket);
239 psSF->uiPendedLast = FALSE;
241 else
243 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %ld\n", psSF-Adapter->PackInfo);
244 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n",
245 psSF->uiCurrentTokenCount, iPacketLen);
246 //this part indicates that becuase of non-availability of the tokens
247 //pkt has not been send out hence setting the pending flag indicating the host to send it out
248 //first next iteration .
249 psSF->uiPendedLast = TRUE;
250 spin_unlock_bh(&psSF->SFQueueLock);
253 else
255 spin_unlock_bh(&psSF->SFQueueLock);
258 else
261 if((atomic_read(&Adapter->CurrNumFreeTxDesc) > 0 ) &&
262 (atomic_read(&Adapter->index_rd_txcntrlpkt) !=
263 atomic_read(&Adapter->index_wr_txcntrlpkt))
266 pControlPacket = Adapter->txctlpacket
267 [(atomic_read(&Adapter->index_rd_txcntrlpkt)%MAX_CNTRL_PKTS)];
268 if(pControlPacket)
270 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Sending Control packet");
271 Status = SendControlPacket(Adapter, pControlPacket);
272 if(STATUS_SUCCESS==Status)
274 spin_lock_bh(&psSF->SFQueueLock);
275 psSF->NumOfPacketsSent++;
276 psSF->uiSentBytes+=((PLEADER)pControlPacket)->PLength;
277 psSF->uiSentPackets++;
278 atomic_dec(&Adapter->TotalPacketCount);
279 psSF->uiCurrentBytesOnHost -= ((PLEADER)pControlPacket)->PLength;
280 psSF->uiCurrentPacketsOnHost--;
281 atomic_inc(&Adapter->index_rd_txcntrlpkt);
282 spin_unlock_bh(&psSF->SFQueueLock);
284 else
285 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "SendControlPacket Failed\n");
287 else
289 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, " Control Pkt is not available, Indexing is wrong....");
294 if(Status != STATUS_SUCCESS) //Tx of data packet to device Failed
296 if(Adapter->bcm_jiffies == 0)
297 Adapter->bcm_jiffies = jiffies;
299 else
301 Adapter->bcm_jiffies = 0;
303 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<=====");
307 /*******************************************************************
308 * Function - transmit_packets()
310 * Description - This function transmits the packets from different
311 * queues, if free descriptors are available on target.
313 * Parameters - Adapter: Pointer to the Adapter structure.
315 * Returns - None.
316 ********************************************************************/
317 VOID transmit_packets(PMINI_ADAPTER Adapter)
319 UINT uiPrevTotalCount = 0;
320 int iIndex = 0;
322 BOOLEAN exit_flag = TRUE ;
324 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "=====>");
326 if(NULL == Adapter)
328 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX,TX_PACKETS, DBG_LVL_ALL, "Got NULL Adapter");
329 return;
331 if(Adapter->device_removed == TRUE)
333 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device removed");
334 return;
337 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nUpdateTokenCount ====>\n");
339 UpdateTokenCount(Adapter);
341 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nPruneQueueAllSF ====>\n");
343 PruneQueueAllSF(Adapter);
345 uiPrevTotalCount = atomic_read(&Adapter->TotalPacketCount);
347 for(iIndex=HiPriority;iIndex>=0;iIndex--)
349 if( !uiPrevTotalCount || (TRUE == Adapter->device_removed))
350 break;
352 if(Adapter->PackInfo[iIndex].bValid &&
353 Adapter->PackInfo[iIndex].uiPendedLast &&
354 Adapter->PackInfo[iIndex].uiCurrentBytesOnHost)
356 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex..");
357 CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]);
358 uiPrevTotalCount--;
362 while(uiPrevTotalCount > 0 && !Adapter->device_removed)
364 exit_flag = TRUE ;
365 //second iteration to parse non-pending queues
366 for(iIndex=HiPriority;iIndex>=0;iIndex--)
368 if( !uiPrevTotalCount || (TRUE == Adapter->device_removed))
369 break;
371 if(Adapter->PackInfo[iIndex].bValid &&
372 Adapter->PackInfo[iIndex].uiCurrentBytesOnHost &&
373 !Adapter->PackInfo[iIndex].uiPendedLast )
375 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex..");
376 CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]);
377 uiPrevTotalCount--;
378 exit_flag = FALSE;
382 if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode)
384 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "In Idle Mode\n");
385 break;
387 if(exit_flag == TRUE )
388 break ;
389 }/* end of inner while loop */
390 if(Adapter->bcm_jiffies == 0 &&
391 atomic_read(&Adapter->TotalPacketCount) != 0 &&
392 uiPrevTotalCount == atomic_read(&Adapter->TotalPacketCount))
394 Adapter->bcm_jiffies = jiffies;
396 update_per_cid_rx (Adapter);
397 Adapter->txtransmit_running = 0;
398 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<======");