Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.2.
  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}