1 /**********************************************************************
3 * This file contains the routines related to Leaky Bucket Algorithm.
4 ***********************************************************************/
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.
16 **********************************************************************/
18 static VOID
UpdateTokenCount(register PMINI_ADAPTER Adapter
)
24 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, TOKEN_COUNTS
, DBG_LVL_ALL
, "=====>\n");
27 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, TOKEN_COUNTS
, DBG_LVL_ALL
, "Adapter found NULL!\n");
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
)/
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");
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
));
89 if(FALSE
!= psSF
->bValid
&& psSF
->ucDirection
)
91 if(0 != psSF
->uiCurrentTokenCount
)
93 return psSF
->uiCurrentTokenCount
;
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;
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 <===");
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
;
126 psLastQueueNode
->next
=psQueueCurrent
->next
;
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");
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
);
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
, "<=====");
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.
182 ****************************************************************************/
183 static __inline VOID CheckAndSendPacketFromIndex
184 (PMINI_ADAPTER Adapter
, PacketInfo
*psSF
)
186 struct sk_buff
*QueuePacket
=NULL
;
187 char *pControlPacket
= NULL
;
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
)
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");
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
));
212 PruneQueue(Adapter
,(psSF
-Adapter
->PackInfo
));
214 spin_lock_bh(&psSF
->SFQueueLock
);
215 QueuePacket
=psSF
->FirstTxQueue
;
219 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, TX_PACKETS
, DBG_LVL_ALL
, "Dequeuing Data Packet");
221 if(psSF
->bEthCSSupport
)
222 iPacketLen
= QueuePacket
->len
;
224 iPacketLen
= QueuePacket
->len
-ETH_HLEN
;
227 if(iPacketLen
<= GetSFTokenCount(Adapter
, psSF
))
229 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, TX_PACKETS
, DBG_LVL_ALL
, "Allowed bytes %d",
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
;
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
);
255 spin_unlock_bh(&psSF
->SFQueueLock
);
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
)];
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
);
285 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, TX_PACKETS
, DBG_LVL_ALL
, "SendControlPacket Failed\n");
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
;
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.
316 ********************************************************************/
317 VOID
transmit_packets(PMINI_ADAPTER Adapter
)
319 UINT uiPrevTotalCount
= 0;
322 BOOLEAN exit_flag
= TRUE
;
324 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, TX_PACKETS
, DBG_LVL_ALL
, "=====>");
328 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
,TX_PACKETS
, DBG_LVL_ALL
, "Got NULL Adapter");
331 if(Adapter
->device_removed
== TRUE
)
333 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, TX_PACKETS
, DBG_LVL_ALL
, "Device removed");
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
))
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
]);
362 while(uiPrevTotalCount
> 0 && !Adapter
->device_removed
)
365 //second iteration to parse non-pending queues
366 for(iIndex
=HiPriority
;iIndex
>=0;iIndex
--)
368 if( !uiPrevTotalCount
|| (TRUE
== Adapter
->device_removed
))
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
]);
382 if(Adapter
->IdleMode
|| Adapter
->bPreparingForLowPowerMode
)
384 BCM_DEBUG_PRINT(Adapter
,DBG_TYPE_TX
, TX_PACKETS
, DBG_LVL_ALL
, "In Idle Mode\n");
387 if(exit_flag
== TRUE
)
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
, "<======");