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