Linux Audio

Check our new training course

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