Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 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 | |
Kevin McKinney | 2979460 | 2012-05-26 12:05:12 -0400 | [diff] [blame] | 18 | static VOID UpdateTokenCount(register struct bcm_mini_adapter *Adapter) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 19 | { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 20 | ULONG liCurrentTime; |
| 21 | INT i = 0; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 22 | struct timeval tv; |
| 23 | |
Ceri James | 89babcc | 2012-10-23 13:51:56 +0100 | [diff] [blame] | 24 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, |
| 25 | "=====>\n"); |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 26 | if (NULL == Adapter) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 27 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, |
Ceri James | 89babcc | 2012-10-23 13:51:56 +0100 | [diff] [blame] | 28 | DBG_LVL_ALL, "Adapter found NULL!\n"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 29 | return; |
| 30 | } |
| 31 | |
| 32 | do_gettimeofday(&tv); |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 33 | for (i = 0; i < NO_OF_QUEUES; i++) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 34 | if (TRUE == Adapter->PackInfo[i].bValid && |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 35 | (1 == Adapter->PackInfo[i].ucDirection)) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 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); |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 40 | if (0 != liCurrentTime) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 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; |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 47 | if (Adapter->PackInfo[i].uiCurrentTokenCount >= |
| 48 | Adapter->PackInfo[i].uiMaxBucketSize) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 49 | Adapter->PackInfo[i].uiCurrentTokenCount = |
| 50 | Adapter->PackInfo[i].uiMaxBucketSize; |
| 51 | } |
| 52 | } |
| 53 | } |
| 54 | } |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 55 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "<=====\n"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 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 | ***********************************************************************/ |
Kevin McKinney | 2979460 | 2012-05-26 12:05:12 -0400 | [diff] [blame] | 75 | static ULONG GetSFTokenCount(struct bcm_mini_adapter *Adapter, struct bcm_packet_info *psSF) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 76 | { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 77 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow ===>"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 78 | /* Validate the parameters */ |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 79 | if (NULL == Adapter || (psSF < Adapter->PackInfo && |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 80 | (uintptr_t)psSF > (uintptr_t) &Adapter->PackInfo[HiPriority])) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 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)); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 82 | return 0; |
| 83 | } |
| 84 | |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 85 | if (false != psSF->bValid && psSF->ucDirection) { |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 86 | if (0 != psSF->uiCurrentTokenCount) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 87 | return psSF->uiCurrentTokenCount; |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 88 | } else { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 89 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %zd Available %u\n", |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 90 | psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount); |
| 91 | psSF->uiPendedLast = 1; |
| 92 | } |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 93 | } else { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 94 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %zd not valid\n", psSF-Adapter->PackInfo); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 95 | } |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 96 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow <==="); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 97 | return 0; |
| 98 | } |
| 99 | |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 100 | /** |
| 101 | @ingroup tx_functions |
| 102 | This function despatches packet from the specified queue. |
| 103 | @return Zero(success) or Negative value(failure) |
| 104 | */ |
Kevin McKinney | 2979460 | 2012-05-26 12:05:12 -0400 | [diff] [blame] | 105 | static INT SendPacketFromQueue(struct bcm_mini_adapter *Adapter,/**<Logical Adapter*/ |
Kevin McKinney | 0b3edf7 | 2012-05-26 12:05:01 -0400 | [diff] [blame] | 106 | struct bcm_packet_info *psSF, /**<Queue identifier*/ |
Lilis Iskandar | fd18e9f | 2013-07-28 03:34:47 +0800 | [diff] [blame] | 107 | struct sk_buff *Packet) /**<Pointer to the packet to be sent*/ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 108 | { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 109 | INT Status = STATUS_FAILURE; |
| 110 | UINT uiIndex = 0, PktLen = 0; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 111 | |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 112 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "=====>"); |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 113 | if (!Adapter || !Packet || !psSF) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 114 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "Got NULL Adapter or Packet"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 115 | return -EINVAL; |
| 116 | } |
| 117 | |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 118 | if (psSF->liDrainCalculated == 0) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 119 | psSF->liDrainCalculated = jiffies; |
Lilis Iskandar | ea20a1e | 2013-07-28 03:34:45 +0800 | [diff] [blame] | 120 | /* send the packet to the fifo.. */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 121 | PktLen = Packet->len; |
| 122 | Status = SetupNextSend(Adapter, Packet, psSF->usVCID_Value); |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 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))) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 126 | Adapter->aTxPktSizeHist[uiIndex]++; |
| 127 | } |
| 128 | } |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 129 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, SEND_QUEUE, DBG_LVL_ALL, "<====="); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 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 | ****************************************************************************/ |
Kevin McKinney | 2979460 | 2012-05-26 12:05:12 -0400 | [diff] [blame] | 145 | static VOID CheckAndSendPacketFromIndex(struct bcm_mini_adapter *Adapter, struct bcm_packet_info *psSF) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 146 | { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 147 | struct sk_buff *QueuePacket = NULL; |
| 148 | char *pControlPacket = NULL; |
| 149 | INT Status = 0; |
| 150 | int iPacketLen = 0; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 151 | |
| 152 | |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 153 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%zd ====>", (psSF-Adapter->PackInfo)); |
Lilis Iskandar | ea20a1e | 2013-07-28 03:34:45 +0800 | [diff] [blame] | 154 | if ((psSF != &Adapter->PackInfo[HiPriority]) && Adapter->LinkUpStatus && atomic_read(&psSF->uiPerSFTxResourceCount)) { /* Get data packet */ |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 155 | if (!psSF->ucDirection) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 156 | return; |
| 157 | |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 158 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount "); |
| 159 | if (Adapter->IdleMode || Adapter->bPreparingForLowPowerMode) |
Stephen Hemminger | 5cf084f | 2010-11-01 13:57:35 -0400 | [diff] [blame] | 160 | return; /* in idle mode */ |
| 161 | |
Lilis Iskandar | ea20a1e | 2013-07-28 03:34:45 +0800 | [diff] [blame] | 162 | /* Check for Free Descriptors */ |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 163 | if (atomic_read(&Adapter->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 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; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 166 | } |
| 167 | |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 168 | spin_lock_bh(&psSF->SFQueueLock); |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 169 | QueuePacket = psSF->FirstTxQueue; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 170 | |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 171 | if (QueuePacket) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 172 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Dequeuing Data Packet"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 173 | |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 174 | if (psSF->bEthCSSupport) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 175 | iPacketLen = QueuePacket->len; |
| 176 | else |
| 177 | iPacketLen = QueuePacket->len-ETH_HLEN; |
| 178 | |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 179 | iPacketLen <<= 3; |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 180 | if (iPacketLen <= GetSFTokenCount(Adapter, psSF)) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 181 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Allowed bytes %d", |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 182 | (iPacketLen >> 3)); |
| 183 | |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 184 | DEQUEUEPACKET(psSF->FirstTxQueue, psSF->LastTxQueue); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 185 | psSF->uiCurrentBytesOnHost -= (QueuePacket->len); |
| 186 | psSF->uiCurrentPacketsOnHost--; |
| 187 | atomic_dec(&Adapter->TotalPacketCount); |
| 188 | spin_unlock_bh(&psSF->SFQueueLock); |
| 189 | |
Lilis Iskandar | 0a67653 | 2013-07-28 03:34:46 +0800 | [diff] [blame] | 190 | Status = SendPacketFromQueue(Adapter, psSF, QueuePacket); |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 191 | psSF->uiPendedLast = false; |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 192 | } else { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 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", |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 195 | psSF->uiCurrentTokenCount, iPacketLen); |
Lilis Iskandar | ea20a1e | 2013-07-28 03:34:45 +0800 | [diff] [blame] | 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 | */ |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 201 | psSF->uiPendedLast = TRUE; |
| 202 | spin_unlock_bh(&psSF->SFQueueLock); |
| 203 | } |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 204 | } else { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 205 | spin_unlock_bh(&psSF->SFQueueLock); |
| 206 | } |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 207 | } else { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 208 | |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 209 | if ((atomic_read(&Adapter->CurrNumFreeTxDesc) > 0) && |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 210 | (atomic_read(&Adapter->index_rd_txcntrlpkt) != |
| 211 | atomic_read(&Adapter->index_wr_txcntrlpkt))) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 212 | pControlPacket = Adapter->txctlpacket |
| 213 | [(atomic_read(&Adapter->index_rd_txcntrlpkt)%MAX_CNTRL_PKTS)]; |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 214 | if (pControlPacket) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 215 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Sending Control packet"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 216 | Status = SendControlPacket(Adapter, pControlPacket); |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 217 | if (STATUS_SUCCESS == Status) { |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 218 | spin_lock_bh(&psSF->SFQueueLock); |
| 219 | psSF->NumOfPacketsSent++; |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 220 | psSF->uiSentBytes += ((struct bcm_leader *)pControlPacket)->PLength; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 221 | psSF->uiSentPackets++; |
| 222 | atomic_dec(&Adapter->TotalPacketCount); |
Kevin McKinney | ff35204 | 2012-05-26 12:05:11 -0400 | [diff] [blame] | 223 | psSF->uiCurrentBytesOnHost -= ((struct bcm_leader *)pControlPacket)->PLength; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 224 | psSF->uiCurrentPacketsOnHost--; |
| 225 | atomic_inc(&Adapter->index_rd_txcntrlpkt); |
| 226 | spin_unlock_bh(&psSF->SFQueueLock); |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 227 | } else { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 228 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "SendControlPacket Failed\n"); |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 229 | } |
| 230 | } else { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 231 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, " Control Pkt is not available, Indexing is wrong...."); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 232 | } |
Lilis Iskandar | 0a67653 | 2013-07-28 03:34:46 +0800 | [diff] [blame] | 233 | } |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 234 | } |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 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 | ********************************************************************/ |
Kevin McKinney | 2979460 | 2012-05-26 12:05:12 -0400 | [diff] [blame] | 248 | VOID transmit_packets(struct bcm_mini_adapter *Adapter) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 249 | { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 250 | UINT uiPrevTotalCount = 0; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 251 | int iIndex = 0; |
| 252 | |
Lisa Nguyen | 3abd6f1 | 2013-10-28 01:35:59 -0700 | [diff] [blame] | 253 | bool exit_flag = TRUE; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 254 | |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 255 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "=====>"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 256 | |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 257 | if (NULL == Adapter) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 258 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Got NULL Adapter"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 259 | return; |
| 260 | } |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 261 | if (Adapter->device_removed == TRUE) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 262 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Device removed"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 263 | return; |
| 264 | } |
| 265 | |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 266 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nUpdateTokenCount ====>\n"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 267 | |
| 268 | UpdateTokenCount(Adapter); |
| 269 | |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 270 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nPruneQueueAllSF ====>\n"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 271 | |
| 272 | PruneQueueAllSF(Adapter); |
| 273 | |
| 274 | uiPrevTotalCount = atomic_read(&Adapter->TotalPacketCount); |
| 275 | |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 276 | for (iIndex = HiPriority; iIndex >= 0; iIndex--) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 277 | if (!uiPrevTotalCount || (TRUE == Adapter->device_removed)) |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 278 | break; |
| 279 | |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 280 | if (Adapter->PackInfo[iIndex].bValid && |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 281 | Adapter->PackInfo[iIndex].uiPendedLast && |
| 282 | Adapter->PackInfo[iIndex].uiCurrentBytesOnHost) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 283 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex.."); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 284 | CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]); |
| 285 | uiPrevTotalCount--; |
| 286 | } |
| 287 | } |
| 288 | |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 289 | while (uiPrevTotalCount > 0 && !Adapter->device_removed) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 290 | exit_flag = TRUE; |
Lilis Iskandar | ea20a1e | 2013-07-28 03:34:45 +0800 | [diff] [blame] | 291 | /* second iteration to parse non-pending queues */ |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 292 | for (iIndex = HiPriority; iIndex >= 0; iIndex--) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 293 | if (!uiPrevTotalCount || (TRUE == Adapter->device_removed)) |
| 294 | break; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 295 | |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 296 | if (Adapter->PackInfo[iIndex].bValid && |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 297 | Adapter->PackInfo[iIndex].uiCurrentBytesOnHost && |
| 298 | !Adapter->PackInfo[iIndex].uiPendedLast) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 299 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Calling CheckAndSendPacketFromIndex.."); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 300 | CheckAndSendPacketFromIndex(Adapter, &Adapter->PackInfo[iIndex]); |
| 301 | uiPrevTotalCount--; |
Lisa Nguyen | f70c8a9 | 2013-10-28 01:36:19 -0700 | [diff] [blame] | 302 | exit_flag = false; |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 303 | } |
| 304 | } |
| 305 | |
Lilis Iskandar | 68f4f09 | 2013-07-28 03:34:44 +0800 | [diff] [blame] | 306 | if (Adapter->IdleMode || Adapter->bPreparingForLowPowerMode) { |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 307 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "In Idle Mode\n"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 308 | break; |
| 309 | } |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 310 | if (exit_flag == TRUE) |
Lilis Iskandar | 0a67653 | 2013-07-28 03:34:46 +0800 | [diff] [blame] | 311 | break; |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 312 | } /* end of inner while loop */ |
Stephen Hemminger | 5cf084f | 2010-11-01 13:57:35 -0400 | [diff] [blame] | 313 | |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 314 | update_per_cid_rx(Adapter); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 315 | Adapter->txtransmit_running = 0; |
Lilis Iskandar | 37c79c7 | 2013-07-28 03:34:43 +0800 | [diff] [blame] | 316 | BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<======"); |
Stephen Hemminger | f8942e0 | 2010-09-08 14:46:36 -0700 | [diff] [blame] | 317 | } |