Commit | Line | Data |
---|---|---|
f8942e07 SH |
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 | ||
44a17eff | 18 | static VOID UpdateTokenCount(register PMINI_ADAPTER Adapter) |
f8942e07 SH |
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 | ***********************************************************************/ | |
20f48653 | 78 | static ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF) |
f8942e07 SH |
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 && | |
9f1c75ac | 83 | (uintptr_t)psSF > (uintptr_t) &Adapter->PackInfo[HiPriority])) |
f8942e07 | 84 | { |
c5ebe227 | 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)); |
f8942e07 SH |
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 | { | |
c5ebe227 | 97 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %zd Available %u\n", |
f8942e07 SH |
98 | psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount); |
99 | psSF->uiPendedLast = 1; | |
100 | } | |
101 | } | |
102 | else | |
103 | { | |
c5ebe227 | 104 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %zd not valid\n", psSF-Adapter->PackInfo); |
f8942e07 SH |
105 | } |
106 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow <==="); | |
107 | return 0; | |
108 | } | |
109 | ||
f8942e07 SH |
110 | /** |
111 | @ingroup tx_functions | |
112 | This function despatches packet from the specified queue. | |
113 | @return Zero(success) or Negative value(failure) | |
114 | */ | |
20f48653 SH |
115 | static INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**<Logical Adapter*/ |
116 | PacketInfo *psSF, /**<Queue identifier*/ | |
117 | struct sk_buff* Packet) /**<Pointer to the packet to be sent*/ | |
f8942e07 SH |
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 | ****************************************************************************/ | |
20f48653 | 159 | static VOID CheckAndSendPacketFromIndex(PMINI_ADAPTER Adapter, PacketInfo *psSF) |
f8942e07 SH |
160 | { |
161 | struct sk_buff *QueuePacket=NULL; | |
162 | char *pControlPacket = NULL; | |
163 | INT Status=0; | |
164 | int iPacketLen=0; | |
165 | ||
166 | ||
c5ebe227 | 167 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%zd ====>", (psSF-Adapter->PackInfo)); |
9f1c75ac | 168 | if((psSF != &Adapter->PackInfo[HiPriority]) && Adapter->LinkUpStatus && atomic_read(&psSF->uiPerSFTxResourceCount))//Get data packet |
f8942e07 SH |
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) | |
5cf084f4 SH |
175 | return; /* in idle mode */ |
176 | ||
f8942e07 SH |
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 | ||
f8942e07 SH |
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 | { | |
c5ebe227 | 213 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %zd\n", psSF-Adapter->PackInfo); |
f8942e07 SH |
214 | BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n", |
215 | psSF->uiCurrentTokenCount, iPacketLen); | |
25985edc | 216 | //this part indicates that because of non-availability of the tokens |
f8942e07 SH |
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 | } | |
f8942e07 SH |
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 | ********************************************************************/ | |
276 | VOID 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 */ | |
5cf084f4 | 349 | |
f8942e07 SH |
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 | } |