2010-09-08 15:46:36 -06:00
|
|
|
/**********************************************************************
|
2014-08-29 14:50:16 -06:00
|
|
|
* LEAKYBUCKET.C
|
2010-09-08 15:46:36 -06:00
|
|
|
* This file contains the routines related to Leaky Bucket Algorithm.
|
|
|
|
***********************************************************************/
|
|
|
|
#include "headers.h"
|
|
|
|
|
2014-08-29 14:50:16 -06:00
|
|
|
/**
|
|
|
|
* UpdateTokenCount() - Calculates the token count for each channel
|
|
|
|
* and updates the same in Adapter structure
|
|
|
|
* @Adapter: Pointer to the Adapter structure.
|
|
|
|
*
|
|
|
|
* Return: None
|
|
|
|
*/
|
2012-05-26 10:05:12 -06:00
|
|
|
static VOID UpdateTokenCount(register struct bcm_mini_adapter *Adapter)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-07-27 13:34:43 -06:00
|
|
|
ULONG liCurrentTime;
|
|
|
|
INT i = 0;
|
2010-09-08 15:46:36 -06:00
|
|
|
struct timeval tv;
|
2014-06-30 02:25:17 -06:00
|
|
|
struct bcm_packet_info *curr_pi;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
Staging: bcm: LeakyBucket.c: Checkpatch fixes
This fixes the following checkpatch issues:
WARNING: line over 80 characters
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "=====>\n");
ERROR: space required after that ',' (ctx:VxV)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "=====>\n");
^
WARNING: line over 80 characters
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Adapter found NULL!\n");
ERROR: space required after that ',' (ctx:VxV)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Adapter found NULL!\n");
^
Signed-off-by: Ceri James <jamesceri@googlemail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-10-23 06:51:56 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
|
|
|
|
"=====>\n");
|
2013-07-27 13:34:44 -06:00
|
|
|
if (NULL == Adapter) {
|
2013-07-27 13:34:43 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS,
|
Staging: bcm: LeakyBucket.c: Checkpatch fixes
This fixes the following checkpatch issues:
WARNING: line over 80 characters
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "=====>\n");
ERROR: space required after that ',' (ctx:VxV)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "=====>\n");
^
WARNING: line over 80 characters
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Adapter found NULL!\n");
ERROR: space required after that ',' (ctx:VxV)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Adapter found NULL!\n");
^
Signed-off-by: Ceri James <jamesceri@googlemail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-10-23 06:51:56 -06:00
|
|
|
DBG_LVL_ALL, "Adapter found NULL!\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
do_gettimeofday(&tv);
|
2013-07-27 13:34:44 -06:00
|
|
|
for (i = 0; i < NO_OF_QUEUES; i++) {
|
2014-06-30 02:25:17 -06:00
|
|
|
curr_pi = &Adapter->PackInfo[i];
|
|
|
|
|
2014-06-30 02:25:18 -06:00
|
|
|
if (TRUE == curr_pi->bValid && (1 == curr_pi->ucDirection)) {
|
|
|
|
liCurrentTime = ((tv.tv_sec -
|
2014-06-30 02:25:17 -06:00
|
|
|
curr_pi->stLastUpdateTokenAt.tv_sec)*1000 +
|
2014-06-30 02:25:18 -06:00
|
|
|
(tv.tv_usec - curr_pi->stLastUpdateTokenAt.tv_usec) /
|
2010-09-08 15:46:36 -06:00
|
|
|
1000);
|
2013-07-27 13:34:44 -06:00
|
|
|
if (0 != liCurrentTime) {
|
2014-06-30 02:25:17 -06:00
|
|
|
curr_pi->uiCurrentTokenCount += (ULONG)
|
|
|
|
((curr_pi->uiMaxAllowedRate) *
|
2010-09-08 15:46:36 -06:00
|
|
|
((ULONG)((liCurrentTime)))/1000);
|
2014-06-30 02:25:18 -06:00
|
|
|
memcpy(&curr_pi->stLastUpdateTokenAt, &tv,
|
|
|
|
sizeof(struct timeval));
|
2014-06-30 02:25:17 -06:00
|
|
|
curr_pi->liLastUpdateTokenAt = liCurrentTime;
|
|
|
|
if (curr_pi->uiCurrentTokenCount >=
|
|
|
|
curr_pi->uiMaxBucketSize) {
|
|
|
|
curr_pi->uiCurrentTokenCount =
|
|
|
|
curr_pi->uiMaxBucketSize;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
|
|
|
|
"<=====\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-29 14:50:16 -06:00
|
|
|
/**
|
|
|
|
* IsPacketAllowedForFlow() - This function checks whether the given
|
|
|
|
* packet from the specified queue can be allowed for transmission by
|
|
|
|
* checking the token count.
|
|
|
|
* @Adapter: Pointer to the Adpater structure.
|
|
|
|
* @iQIndex: The queue Identifier.
|
|
|
|
* @ulPacketLength: Number of bytes to be transmitted.
|
|
|
|
*
|
|
|
|
* Returns: The number of bytes allowed for transmission.
|
|
|
|
*/
|
2012-05-26 10:05:12 -06:00
|
|
|
static ULONG GetSFTokenCount(struct bcm_mini_adapter *Adapter, struct bcm_packet_info *psSF)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
|
|
|
|
"IsPacketAllowedForFlow ===>");
|
|
|
|
|
2010-09-08 15:46:36 -06:00
|
|
|
/* Validate the parameters */
|
2013-07-27 13:34:43 -06:00
|
|
|
if (NULL == Adapter || (psSF < Adapter->PackInfo &&
|
2013-07-27 13:34:44 -06:00
|
|
|
(uintptr_t)psSF > (uintptr_t) &Adapter->PackInfo[HiPriority])) {
|
2014-06-30 02:25:18 -06:00
|
|
|
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));
|
2010-09-08 15:46:36 -06:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-10-28 02:36:19 -06:00
|
|
|
if (false != psSF->bValid && psSF->ucDirection) {
|
2013-07-27 13:34:44 -06:00
|
|
|
if (0 != psSF->uiCurrentTokenCount) {
|
2014-06-30 02:25:18 -06:00
|
|
|
return psSF->uiCurrentTokenCount;
|
2013-07-27 13:34:44 -06:00
|
|
|
} else {
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
"Not enough tokens in queue %zd Available %u\n",
|
|
|
|
psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount);
|
2010-09-08 15:46:36 -06:00
|
|
|
psSF->uiPendedLast = 1;
|
|
|
|
}
|
2013-07-27 13:34:44 -06:00
|
|
|
} else {
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
|
|
|
|
"IPAFF: Queue %zd not valid\n",
|
|
|
|
psSF-Adapter->PackInfo);
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL,
|
|
|
|
"IsPacketAllowedForFlow <===");
|
2010-09-08 15:46:36 -06:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ingroup tx_functions
|
|
|
|
This function despatches packet from the specified queue.
|
|
|
|
@return Zero(success) or Negative value(failure)
|
|
|
|
*/
|
2012-05-26 10:05:12 -06:00
|
|
|
static INT SendPacketFromQueue(struct bcm_mini_adapter *Adapter,/**<Logical Adapter*/
|
2014-06-30 02:25:18 -06:00
|
|
|
struct bcm_packet_info *psSF, /**<Queue identifier*/
|
2013-07-27 13:34:47 -06:00
|
|
|
struct sk_buff *Packet) /**<Pointer to the packet to be sent*/
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-07-27 13:34:43 -06:00
|
|
|
INT Status = STATUS_FAILURE;
|
|
|
|
UINT uiIndex = 0, PktLen = 0;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL,
|
|
|
|
"=====>");
|
2013-07-27 13:34:44 -06:00
|
|
|
if (!Adapter || !Packet || !psSF) {
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL,
|
|
|
|
"Got NULL Adapter or Packet");
|
2010-09-08 15:46:36 -06:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2013-07-27 13:34:43 -06:00
|
|
|
if (psSF->liDrainCalculated == 0)
|
2010-09-08 15:46:36 -06:00
|
|
|
psSF->liDrainCalculated = jiffies;
|
2013-07-27 13:34:45 -06:00
|
|
|
/* send the packet to the fifo.. */
|
2010-09-08 15:46:36 -06:00
|
|
|
PktLen = Packet->len;
|
|
|
|
Status = SetupNextSend(Adapter, Packet, psSF->usVCID_Value);
|
2013-07-27 13:34:44 -06:00
|
|
|
if (Status == 0) {
|
|
|
|
for (uiIndex = 0; uiIndex < MIBS_MAX_HIST_ENTRIES; uiIndex++) {
|
2014-06-30 02:25:18 -06:00
|
|
|
if ((PktLen <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) &&
|
|
|
|
(PktLen > MIBS_PKTSIZEHIST_RANGE*(uiIndex)))
|
2010-09-08 15:46:36 -06:00
|
|
|
Adapter->aTxPktSizeHist[uiIndex]++;
|
|
|
|
}
|
|
|
|
}
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL,
|
|
|
|
"<=====");
|
2010-09-08 15:46:36 -06:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2014-06-30 02:25:19 -06:00
|
|
|
static void get_data_packet(struct bcm_mini_adapter *ad,
|
|
|
|
struct bcm_packet_info *ps_sf)
|
|
|
|
{
|
|
|
|
int packet_len;
|
|
|
|
struct sk_buff *qpacket;
|
|
|
|
|
|
|
|
if (!ps_sf->ucDirection)
|
|
|
|
return;
|
|
|
|
|
|
|
|
BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
|
|
|
|
"UpdateTokenCount ");
|
|
|
|
if (ad->IdleMode || ad->bPreparingForLowPowerMode)
|
|
|
|
return; /* in idle mode */
|
|
|
|
|
|
|
|
/* Check for Free Descriptors */
|
|
|
|
if (atomic_read(&ad->CurrNumFreeTxDesc) <=
|
|
|
|
MINIMUM_PENDING_DESCRIPTORS) {
|
|
|
|
BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
|
|
|
|
" No Free Tx Descriptor(%d) is available for Data pkt..",
|
|
|
|
atomic_read(&ad->CurrNumFreeTxDesc));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
spin_lock_bh(&ps_sf->SFQueueLock);
|
|
|
|
qpacket = ps_sf->FirstTxQueue;
|
|
|
|
|
|
|
|
if (qpacket) {
|
|
|
|
BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
|
|
|
|
"Dequeuing Data Packet");
|
|
|
|
|
|
|
|
if (ps_sf->bEthCSSupport)
|
|
|
|
packet_len = qpacket->len;
|
|
|
|
else
|
|
|
|
packet_len = qpacket->len - ETH_HLEN;
|
|
|
|
|
|
|
|
packet_len <<= 3;
|
|
|
|
if (packet_len <= GetSFTokenCount(ad, ps_sf)) {
|
|
|
|
BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
|
|
|
|
DBG_LVL_ALL, "Allowed bytes %d",
|
|
|
|
(packet_len >> 3));
|
|
|
|
|
|
|
|
DEQUEUEPACKET(ps_sf->FirstTxQueue, ps_sf->LastTxQueue);
|
|
|
|
ps_sf->uiCurrentBytesOnHost -= (qpacket->len);
|
|
|
|
ps_sf->uiCurrentPacketsOnHost--;
|
|
|
|
atomic_dec(&ad->TotalPacketCount);
|
|
|
|
spin_unlock_bh(&ps_sf->SFQueueLock);
|
|
|
|
|
|
|
|
SendPacketFromQueue(ad, ps_sf, qpacket);
|
|
|
|
ps_sf->uiPendedLast = false;
|
|
|
|
} else {
|
|
|
|
BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
|
|
|
|
DBG_LVL_ALL, "For Queue: %zd\n",
|
|
|
|
ps_sf - ad->PackInfo);
|
|
|
|
BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
"\nAvailable Tokens = %d required = %d\n",
|
|
|
|
ps_sf->uiCurrentTokenCount,
|
|
|
|
packet_len);
|
|
|
|
/*
|
|
|
|
this part indicates that because of
|
|
|
|
non-availability of the tokens
|
|
|
|
pkt has not been send out hence setting the
|
|
|
|
pending flag indicating the host to send it out
|
|
|
|
first next iteration.
|
|
|
|
*/
|
|
|
|
ps_sf->uiPendedLast = TRUE;
|
|
|
|
spin_unlock_bh(&ps_sf->SFQueueLock);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
spin_unlock_bh(&ps_sf->SFQueueLock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-30 02:25:20 -06:00
|
|
|
static void send_control_packet(struct bcm_mini_adapter *ad,
|
|
|
|
struct bcm_packet_info *ps_sf)
|
|
|
|
{
|
|
|
|
char *ctrl_packet = NULL;
|
|
|
|
INT status = 0;
|
|
|
|
|
|
|
|
if ((atomic_read(&ad->CurrNumFreeTxDesc) > 0) &&
|
|
|
|
(atomic_read(&ad->index_rd_txcntrlpkt) !=
|
|
|
|
atomic_read(&ad->index_wr_txcntrlpkt))) {
|
|
|
|
ctrl_packet = ad->txctlpacket
|
|
|
|
[(atomic_read(&ad->index_rd_txcntrlpkt)%MAX_CNTRL_PKTS)];
|
|
|
|
if (ctrl_packet) {
|
|
|
|
BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
"Sending Control packet");
|
|
|
|
status = SendControlPacket(ad, ctrl_packet);
|
|
|
|
if (STATUS_SUCCESS == status) {
|
|
|
|
spin_lock_bh(&ps_sf->SFQueueLock);
|
|
|
|
ps_sf->NumOfPacketsSent++;
|
|
|
|
ps_sf->uiSentBytes += ((struct bcm_leader *)ctrl_packet)->PLength;
|
|
|
|
ps_sf->uiSentPackets++;
|
|
|
|
atomic_dec(&ad->TotalPacketCount);
|
|
|
|
ps_sf->uiCurrentBytesOnHost -= ((struct bcm_leader *)ctrl_packet)->PLength;
|
|
|
|
ps_sf->uiCurrentPacketsOnHost--;
|
|
|
|
atomic_inc(&ad->index_rd_txcntrlpkt);
|
|
|
|
spin_unlock_bh(&ps_sf->SFQueueLock);
|
|
|
|
} else {
|
|
|
|
BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
"SendControlPacket Failed\n");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
BCM_DEBUG_PRINT(ad, DBG_TYPE_TX, TX_PACKETS,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
" Control Pkt is not available, Indexing is wrong....");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-29 14:50:16 -06:00
|
|
|
/**
|
|
|
|
* CheckAndSendPacketFromIndex() - This function dequeues the
|
|
|
|
* data/control packet from the specified queue for transmission.
|
|
|
|
* @Adapter: Pointer to the driver control structure.
|
|
|
|
* @iQIndex: The queue Identifier.
|
|
|
|
*
|
|
|
|
* Returns: None.
|
|
|
|
*/
|
2014-06-30 02:25:18 -06:00
|
|
|
static VOID CheckAndSendPacketFromIndex(struct bcm_mini_adapter *Adapter,
|
|
|
|
struct bcm_packet_info *psSF)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
|
|
|
|
"%zd ====>", (psSF-Adapter->PackInfo));
|
|
|
|
if ((psSF != &Adapter->PackInfo[HiPriority]) &&
|
|
|
|
Adapter->LinkUpStatus &&
|
|
|
|
atomic_read(&psSF->uiPerSFTxResourceCount)) { /* Get data packet */
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-06-30 02:25:19 -06:00
|
|
|
get_data_packet(Adapter, psSF);
|
2013-07-27 13:34:44 -06:00
|
|
|
} else {
|
2014-06-30 02:25:20 -06:00
|
|
|
send_control_packet(Adapter, psSF);
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-29 14:50:16 -06:00
|
|
|
/**
|
|
|
|
* transmit_packets() - This function transmits the packets from
|
|
|
|
* different queues, if free descriptors are available on target.
|
|
|
|
* @Adapter: Pointer to the Adapter structure.
|
|
|
|
*
|
|
|
|
* Returns: None.
|
|
|
|
*/
|
2012-05-26 10:05:12 -06:00
|
|
|
VOID transmit_packets(struct bcm_mini_adapter *Adapter)
|
2010-09-08 15:46:36 -06:00
|
|
|
{
|
2013-07-27 13:34:43 -06:00
|
|
|
UINT uiPrevTotalCount = 0;
|
2010-09-08 15:46:36 -06:00
|
|
|
int iIndex = 0;
|
|
|
|
|
2013-10-28 02:35:59 -06:00
|
|
|
bool exit_flag = TRUE;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
|
|
|
|
"=====>");
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-07-27 13:34:44 -06:00
|
|
|
if (NULL == Adapter) {
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
|
|
|
|
"Got NULL Adapter");
|
2010-09-08 15:46:36 -06:00
|
|
|
return;
|
|
|
|
}
|
2013-07-27 13:34:44 -06:00
|
|
|
if (Adapter->device_removed == TRUE) {
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
|
|
|
|
"Device removed");
|
2010-09-08 15:46:36 -06:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
|
|
|
|
"\nUpdateTokenCount ====>\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
|
|
|
|
UpdateTokenCount(Adapter);
|
|
|
|
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
|
|
|
|
"\nPruneQueueAllSF ====>\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
|
|
|
|
PruneQueueAllSF(Adapter);
|
|
|
|
|
|
|
|
uiPrevTotalCount = atomic_read(&Adapter->TotalPacketCount);
|
|
|
|
|
2013-07-27 13:34:44 -06:00
|
|
|
for (iIndex = HiPriority; iIndex >= 0; iIndex--) {
|
2013-07-27 13:34:43 -06:00
|
|
|
if (!uiPrevTotalCount || (TRUE == Adapter->device_removed))
|
2010-09-08 15:46:36 -06:00
|
|
|
break;
|
|
|
|
|
2013-07-27 13:34:43 -06:00
|
|
|
if (Adapter->PackInfo[iIndex].bValid &&
|
2013-07-27 13:34:44 -06:00
|
|
|
Adapter->PackInfo[iIndex].uiPendedLast &&
|
|
|
|
Adapter->PackInfo[iIndex].uiCurrentBytesOnHost) {
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS,
|
|
|
|
DBG_LVL_ALL,
|
|
|
|
"Calling CheckAndSendPacketFromIndex..");
|
|
|
|
CheckAndSendPacketFromIndex(Adapter,
|
|
|
|
&Adapter->PackInfo[iIndex]);
|
2010-09-08 15:46:36 -06:00
|
|
|
uiPrevTotalCount--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-27 13:34:44 -06:00
|
|
|
while (uiPrevTotalCount > 0 && !Adapter->device_removed) {
|
2013-07-27 13:34:43 -06:00
|
|
|
exit_flag = TRUE;
|
2013-07-27 13:34:45 -06:00
|
|
|
/* second iteration to parse non-pending queues */
|
2013-07-27 13:34:44 -06:00
|
|
|
for (iIndex = HiPriority; iIndex >= 0; iIndex--) {
|
2014-06-30 02:25:18 -06:00
|
|
|
if (!uiPrevTotalCount ||
|
|
|
|
(TRUE == Adapter->device_removed))
|
2013-07-27 13:34:43 -06:00
|
|
|
break;
|
2010-09-08 15:46:36 -06:00
|
|
|
|
2013-07-27 13:34:43 -06:00
|
|
|
if (Adapter->PackInfo[iIndex].bValid &&
|
2013-07-27 13:34:44 -06:00
|
|
|
Adapter->PackInfo[iIndex].uiCurrentBytesOnHost &&
|
|
|
|
!Adapter->PackInfo[iIndex].uiPendedLast) {
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX,
|
|
|
|
TX_PACKETS, DBG_LVL_ALL,
|
|
|
|
"Calling CheckAndSendPacketFromIndex..");
|
2010-09-08 15:46:36 -06:00
|
|
|
CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]);
|
|
|
|
uiPrevTotalCount--;
|
2013-10-28 02:36:19 -06:00
|
|
|
exit_flag = false;
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-27 13:34:44 -06:00
|
|
|
if (Adapter->IdleMode || Adapter->bPreparingForLowPowerMode) {
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS,
|
|
|
|
DBG_LVL_ALL, "In Idle Mode\n");
|
2010-09-08 15:46:36 -06:00
|
|
|
break;
|
|
|
|
}
|
2013-07-27 13:34:43 -06:00
|
|
|
if (exit_flag == TRUE)
|
2013-07-27 13:34:46 -06:00
|
|
|
break;
|
2013-07-27 13:34:43 -06:00
|
|
|
} /* end of inner while loop */
|
2010-11-01 11:57:35 -06:00
|
|
|
|
2013-07-27 13:34:43 -06:00
|
|
|
update_per_cid_rx(Adapter);
|
2010-09-08 15:46:36 -06:00
|
|
|
Adapter->txtransmit_running = 0;
|
2014-06-30 02:25:18 -06:00
|
|
|
BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL,
|
|
|
|
"<======");
|
2010-09-08 15:46:36 -06:00
|
|
|
}
|