blob: a15597e7744ed15e129661882afbe1d78d75940d [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*===========================================================================
23
24 W L A N _ Q C T _ T L _ B A. C
25
26 OVERVIEW:
27
28 This software unit holds the implementation of the WLAN Transport Layer
29 Block Ack session support. Also included are the AMSDU de-aggregation
30 completion and MSDU re-ordering functionality.
31
32 The functions externalized by this module are to be called ONLY by the main
33 TL module or the HAL layer.
34
35 DEPENDENCIES:
36
37 Are listed for each API below.
38
39
40 Copyright (c) 2008 QUALCOMM Incorporated.
41 All Rights Reserved.
42 Qualcomm Confidential and Proprietary
43===========================================================================*/
44
45/*===========================================================================
46
47 EDIT HISTORY FOR FILE
48
49
50 This section contains comments describing changes made to the module.
51 Notice that changes are listed in reverse chronological order.
52
53
54 $Header$$DateTime$$Author$
55
56
57 when who what, where, why
58---------- --- --------------------------------------------------------
592010-10-xx dli Change ucCIndex to point to the slot the next frame to be expected to fwd
602008-08-22 sch Update based on unit test
612008-07-31 lti Created module
62
63===========================================================================*/
64
65/*----------------------------------------------------------------------------
66 * Include Files
67 * -------------------------------------------------------------------------*/
68#include "wlan_qct_tl.h"
69#include "wlan_qct_wda.h"
70#include "wlan_qct_tli.h"
71#include "wlan_qct_tli_ba.h"
72#include "wlan_qct_hal.h"
73#include "vos_list.h"
74#include "vos_lock.h"
75#include "tlDebug.h"
76/*----------------------------------------------------------------------------
77 * Preprocessor Definitions and Constants
78 * -------------------------------------------------------------------------*/
79//#define WLANTL_REORDER_DEBUG_MSG_ENABLE
80#define WLANTL_BA_REORDERING_AGING_TIMER 30 /* 30 millisec */
81#define WLANTL_BA_MIN_FREE_RX_VOS_BUFFER 0 /* RX VOS buffer low threshold */
82
83
84/*==========================================================================
85
86 FUNCTION tlReorderingAgingTimerExpierCB
87
88 DESCRIPTION
89 After aging timer expiered, all Qed frames have to be routed to upper
90 layer. Otherwise, there is possibilitied that ahng some frames
91
92 PARAMETERS
93 v_PVOID_t timerUdata Timer callback user data
94 Has information about where frames should be
95 routed
96
97 RETURN VALUE
98 VOS_STATUS_SUCCESS General success
99 VOS_STATUS_E_INVAL Invalid frame handle
100
101============================================================================*/
102v_VOID_t WLANTL_ReorderingAgingTimerExpierCB
103(
104 v_PVOID_t timerUdata
105)
106{
107 WLANTL_TIMER_EXPIER_UDATA_T *expireHandle;
108 WLANTL_BAReorderType *ReorderInfo;
109 WLANTL_CbType *pTLHandle;
110 vos_pkt_t *vosDataBuff;
111 VOS_STATUS status = VOS_STATUS_SUCCESS;
112 v_U8_t ucSTAID;
113 v_U8_t ucTID;
114 v_U8_t opCode;
115 WLANTL_RxMetaInfoType wRxMetaInfo;
116 v_U32_t fwIdx = 0;
117 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
118
119 if(NULL == timerUdata)
120 {
121 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer Callback User data NULL"));
122 return;
123 }
124
125 expireHandle = (WLANTL_TIMER_EXPIER_UDATA_T *)timerUdata;
126 ucSTAID = (v_U8_t)expireHandle->STAID;
127 ucTID = expireHandle->TID;
128 if(WLANTL_STA_ID_INVALID(ucSTAID) || WLANTL_TID_INVALID(ucTID))
129 {
130 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"SID %d or TID %d is not valid",
131 ucSTAID, ucTID));
132 return;
133 }
134
135 pTLHandle = (WLANTL_CbType *)expireHandle->pTLHandle;
136 if(NULL == pTLHandle)
137 {
138 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"TL Control block NULL"));
139 return;
140 }
141
142 ReorderInfo = &pTLHandle->atlSTAClients[ucSTAID].atlBAReorderInfo[ucTID];
143 if(NULL == ReorderInfo)
144 {
145 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Reorder data NULL, this could not happen SID %d, TID %d",
146 ucSTAID, ucTID));
147 return;
148 }
149
150 if(0 == pTLHandle->atlSTAClients[ucSTAID].atlBAReorderInfo[ucTID].ucExists)
151 {
152 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Reorder session doesn't exist SID %d, TID %d",
153 ucSTAID, ucTID));
154 return;
155 }
156
157 if(!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&ReorderInfo->reorderLock)))
158 {
159 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Get LOCK Fail"));
160 return;
161 }
162
163 if( pTLHandle->atlSTAClients[ucSTAID].atlBAReorderInfo[ucTID].ucExists == 0 )
164 {
165 vos_lock_release(&ReorderInfo->reorderLock);
166 return;
167 }
168
169 opCode = WLANTL_OPCODE_FWDALL_DROPCUR;
170 vosDataBuff = NULL;
171
172
Mohit Khanna23863762012-09-11 17:40:09 -0700173 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"BA timeout with %d pending frames, curIdx %d", ReorderInfo->pendingFramesCount, ReorderInfo->ucCIndex));
Jeff Johnson295189b2012-06-20 16:38:30 -0700174
175 if(ReorderInfo->pendingFramesCount == 0)
176 {
177 if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock)))
178 {
179 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail"));
180 }
181 return;
182 }
183
184 if(0 == ReorderInfo->ucCIndex)
185 {
186 fwIdx = ReorderInfo->winSize;
187 }
188 else
189 {
190 fwIdx = ReorderInfo->ucCIndex - 1;
191 }
192
193#ifdef ANI_CHIPSET_VOLANS
194 /* Do replay check before giving packets to upper layer
195 replay check code : check whether replay check is needed or not */
196 if(VOS_TRUE == pTLHandle->atlSTAClients[ucSTAID].ucIsReplayCheckValid)
197 {
198 v_U64_t ullpreviousReplayCounter = 0;
199 v_U64_t ullcurrentReplayCounter = 0;
200 v_U8_t ucloopCounter = 0;
201 v_BOOL_t status = 0;
202
203 /*Do replay check for all packets which are in Reorder buffer */
204 for(ucloopCounter = 0; ucloopCounter < WLANTL_MAX_WINSIZE; ucloopCounter++)
205 {
206 /*Get previous reply counter*/
207 ullpreviousReplayCounter = pTLHandle->atlSTAClients[ucSTAID].ullReplayCounter[ucTID];
208
209 /*Get current replay counter of packet in reorder buffer*/
210 ullcurrentReplayCounter = ReorderInfo->reorderBuffer->ullReplayCounter[ucloopCounter];
211
212 /*Check for holes, if a hole is found in Reorder buffer then
213 no need to do replay check on it, skip the current
214 hole and do replay check on other packets*/
215 if(NULL != (ReorderInfo->reorderBuffer->arrayBuffer[ucloopCounter]))
216 {
217 status = WLANTL_IsReplayPacket(ullcurrentReplayCounter, ullpreviousReplayCounter);
218 if(VOS_TRUE == status)
219 {
220 /*Increment the debug counter*/
221 pTLHandle->atlSTAClients[ucSTAID].ulTotalReplayPacketsDetected++;
222
223 /*A replay packet found*/
224 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
225 "WLANTL_ReorderingAgingTimerExpierCB: total dropped replay packets on STA ID %X is [0x%lX]\n",
226 ucSTAID, pTLHandle->atlSTAClients[ucSTAID].ulTotalReplayPacketsDetected);
227
228 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
229 "WLANTL_ReorderingAgingTimerExpierCB: replay packet found with PN : [0x%llX]\n",
230 ullcurrentReplayCounter);
231
232 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
233 "WLANTL_ReorderingAgingTimerExpierCB: Drop the replay packet with PN : [0x%llX]\n",
234 ullcurrentReplayCounter);
235
236 ReorderInfo->reorderBuffer->arrayBuffer[ucloopCounter] = NULL;
237 ReorderInfo->reorderBuffer->ullReplayCounter[ucloopCounter] = 0;
238 }
239 else
240 {
241 /*Not a replay packet update previous replay counter*/
242 pTLHandle->atlSTAClients[ucSTAID].ullReplayCounter[ucTID] = ullcurrentReplayCounter;
243 }
244 }
245 else
246 {
247 /* A hole detected in Reorder buffer*/
248 //BAMSGERROR("WLANTL_ReorderingAgingTimerExpierCB,hole detected\n",0,0,0);
249
250 }
251 }
252 }
253#endif
254
255 status = WLANTL_ChainFrontPkts(fwIdx, opCode,
256 &vosDataBuff, ReorderInfo, NULL);
257 if(!VOS_IS_STATUS_SUCCESS(status))
258 {
259 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make packet chain fail with Qed frames %d", status));
260 if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock)))
261 {
262 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail"));
263 }
264 return;
265 }
266
267 if(NULL == pTLHandle->atlSTAClients[ucSTAID].pfnSTARx)
268 {
269 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Callback function NULL with STAID %d", ucSTAID));
270 if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock)))
271 {
272 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail"));
273 }
274 return;
275 }
276
277 if(NULL == vosDataBuff)
278 {
279 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"No pending frames, why triggered timer? "));
280 if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock)))
281 {
282 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail"));
283 }
284 return;
285 }
286
287#ifdef WLAN_SOFTAP_FEATURE
288 if( WLAN_STA_SOFTAP == pTLHandle->atlSTAClients[ucSTAID].wSTADesc.wSTAType)
289 {
290 WLANTL_FwdPktToHDD( expireHandle->pAdapter, vosDataBuff, ucSTAID);
291 }
292 else
293#endif
294 {
295 wRxMetaInfo.ucUP = ucTID;
296 pTLHandle->atlSTAClients[ucSTAID].pfnSTARx(expireHandle->pAdapter,
297 vosDataBuff, ucSTAID, &wRxMetaInfo);
298 }
299 if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock)))
300 {
301 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail"));
302 }
303 return;
304}/*WLANTL_ReorderingAgingTimerExpierCB*/
305
306/*----------------------------------------------------------------------------
307 INTERACTION WITH TL Main
308 ---------------------------------------------------------------------------*/
309/*==========================================================================
310
311 FUNCTION WLANTL_InitBAReorderBuffer
312
313 DESCRIPTION
314 Init Reorder buffer array
315
316 PARAMETERS
317 v_PVOID_t pvosGCtx Global context
318
319 RETURN VALUE
320 NONE
321
322============================================================================*/
323
324void WLANTL_InitBAReorderBuffer
325(
326 v_PVOID_t pvosGCtx
327)
328{
329 WLANTL_CbType *pTLCb;
330 v_U32_t idx;
331 v_U32_t pIdx;
332
333 pTLCb = VOS_GET_TL_CB(pvosGCtx);
334 if (NULL == pTLCb)
335 {
336 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
337 "%s: Invalid TL Control Block", __FUNCTION__));
338 return;
339 }
340
341 for(idx = 0; idx < WLANTL_MAX_BA_SESSION; idx++)
342 {
343 pTLCb->reorderBufferPool[idx].isAvailable = VOS_TRUE;
344 for(pIdx = 0; pIdx < WLANTL_MAX_WINSIZE; pIdx++)
345 {
346 pTLCb->reorderBufferPool[idx].arrayBuffer[pIdx] = NULL;
347#ifdef ANI_CHIPSET_VOLANS
348 pTLCb->reorderBufferPool[idx].ullReplayCounter[pIdx] = 0;
349#endif
350 }
351 }
352
353 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"BA reorder buffer init"));
354 return;
355}
356
357/*==========================================================================
358
359 FUNCTION WLANTL_BaSessionAdd
360
361 DESCRIPTION
362 HAL notifies TL when a new Block Ack session is being added.
363
364 DEPENDENCIES
365 A BA session on Rx needs to be added in TL before the response is
366 being sent out
367
368 PARAMETERS
369
370 IN
371 pvosGCtx: pointer to the global vos context; a handle to TL's
372 control block can be extracted from its context
373 ucSTAId: identifier of the station for which requested the BA
374 session
375 ucTid: Tspec ID for the new BA session
376 uSize: size of the reordering window
377
378
379 RETURN VALUE
380 The result code associated with performing the operation
381
382 VOS_STATUS_E_INVAL: Input parameters are invalid
383 VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer
384 to TL cb is NULL ; access would cause a page fault
385 VOS_STATUS_E_EXISTS: Station was not registered or BA session already
386 exists
387 VOS_STATUS_E_NOSUPPORT: Not yet supported
388
389 SIDE EFFECTS
390
391============================================================================*/
392VOS_STATUS
393WLANTL_BaSessionAdd
394(
395 v_PVOID_t pvosGCtx,
396 v_U16_t sessionID,
397 v_U32_t ucSTAId,
398 v_U8_t ucTid,
399 v_U32_t uBufferSize,
400 v_U32_t winSize,
401 v_U32_t SSN
402)
403{
404 WLANTL_CbType *pTLCb = NULL;
405 WLANTL_BAReorderType *reorderInfo;
406 v_U32_t idx;
407 VOS_STATUS status = VOS_STATUS_SUCCESS;
408 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
409
410 /*------------------------------------------------------------------------
411 Sanity check
412 ------------------------------------------------------------------------*/
413 if ( WLANTL_TID_INVALID(ucTid))
414 {
415 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
416 "WLAN TL:Invalid parameter sent on WLANTL_BaSessionAdd");
417 return VOS_STATUS_E_INVAL;
418 }
419
420 if ( WLANTL_STA_ID_INVALID( ucSTAId ) )
421 {
422 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
423 "WLAN TL:Invalid station id requested on WLANTL_BaSessionAdd");
424 return VOS_STATUS_E_FAULT;
425 }
426
427 /*------------------------------------------------------------------------
428 Extract TL control block and check existance
429 ------------------------------------------------------------------------*/
430 pTLCb = VOS_GET_TL_CB(pvosGCtx);
431 if ( NULL == pTLCb )
432 {
433 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
434 "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_BaSessionAdd");
435 return VOS_STATUS_E_FAULT;
436 }
437
438 if ( 0 == pTLCb->atlSTAClients[ucSTAId].ucExists )
439 {
440 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
441 "WLAN TL:Station was not yet registered on WLANTL_BaSessionAdd");
442 return VOS_STATUS_E_EXISTS;
443 }
444
445 /*------------------------------------------------------------------------
446 Verify that BA session was not already added
447 ------------------------------------------------------------------------*/
448 if ( 0 != pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].ucExists )
449 {
450 pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].ucExists++;
451 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
452 "WLAN TL:BA session already exists on WLANTL_BaSessionAdd");
453 return VOS_STATUS_E_EXISTS;
454 }
455
456 /*------------------------------------------------------------------------
457 Initialize new BA session
458 ------------------------------------------------------------------------*/
459 reorderInfo = &pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid];
460
461 for(idx = 0; idx < WLANTL_MAX_BA_SESSION; idx++)
462 {
463 if(VOS_TRUE == pTLCb->reorderBufferPool[idx].isAvailable)
464 {
465 pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].reorderBuffer =
466 &(pTLCb->reorderBufferPool[idx]);
467 pTLCb->reorderBufferPool[idx].isAvailable = VOS_FALSE;
468 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"%dth buffer available, buffer PTR 0x%p",
469 idx,
470 pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].reorderBuffer
471 ));
472 break;
473 }
474 }
475
476#ifdef WLAN_SOFTAP_FEATURE
477
478 if( WLAN_STA_SOFTAP == pTLCb->atlSTAClients[ucSTAId].wSTADesc.wSTAType)
479 {
480 if( WLANTL_MAX_BA_SESSION == idx)
481 {
482 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
483 "Number of Add BA request received more than allowed \n");
484 return VOS_STATUS_E_NOSUPPORT;
485 }
486 }
487#endif
488 reorderInfo->timerUdata.pAdapter = pvosGCtx;
489 reorderInfo->timerUdata.pTLHandle = (v_PVOID_t)pTLCb;
490 reorderInfo->timerUdata.STAID = ucSTAId;
491 reorderInfo->timerUdata.TID = ucTid;
492
493 /* BA aging timer */
494 status = vos_timer_init(&reorderInfo->agingTimer,
495 VOS_TIMER_TYPE_SW,
496 WLANTL_ReorderingAgingTimerExpierCB,
497 (v_PVOID_t)(&reorderInfo->timerUdata));
498 if(!VOS_IS_STATUS_SUCCESS(status))
499 {
500 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer Init Fail"));
501 return status;
502 }
503
504 /* Reorder LOCK
505 * During handle normal RX frame, if timer sxpier, abnormal race condition happen
506 * Frames should be protected from double handle */
507 status = vos_lock_init(&reorderInfo->reorderLock);
508 if(!VOS_IS_STATUS_SUCCESS(status))
509 {
510 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Lock Init Fail"));
511 return status;
512 }
513
514 pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].ucExists++;
515 pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].usCount = 0;
516 pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].ucCIndex = 0;
517 if(0 == winSize)
518 {
519 pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].winSize =
520 WLANTL_MAX_WINSIZE;
521 }
522 else
523 {
524 pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].winSize = winSize;
525 }
526 pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].SSN = SSN;
527 pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].sessionID = sessionID;
528 pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].pendingFramesCount = 0;
529 TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
530 "WLAN TL:New BA session added for STA: %d TID: %d",
531 ucSTAId, ucTid));
532
533 return VOS_STATUS_SUCCESS;
534}/* WLANTL_BaSessionAdd */
535
536/*==========================================================================
537
538 FUNCTION WLANTL_BaSessionDel
539
540 DESCRIPTION
541 HAL notifies TL when a new Block Ack session is being deleted.
542
543 DEPENDENCIES
544
545 PARAMETERS
546
547 IN
548 pvosGCtx: pointer to the global vos context; a handle to TL's
549 control block can be extracted from its context
550 ucSTAId: identifier of the station for which requested the BA
551 session
552 ucTid: Tspec ID for the new BA session
553
554 RETURN VALUE
555 The result code associated with performing the operation
556
557 VOS_STATUS_E_INVAL: Input parameters are invalid
558 VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer
559 to TL cb is NULL ; access would cause a page fault
560 VOS_STATUS_E_EXISTS: Station was not registered or BA session already
561 exists
562 VOS_STATUS_E_NOSUPPORT: Not yet supported
563
564 SIDE EFFECTS
565
566============================================================================*/
567VOS_STATUS
568WLANTL_BaSessionDel
569(
570 v_PVOID_t pvosGCtx,
571 v_U16_t ucSTAId,
572 v_U8_t ucTid
573)
574{
575 WLANTL_CbType* pTLCb = NULL;
576 vos_pkt_t* vosDataBuff = NULL;
577 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
578 VOS_STATUS lockStatus = VOS_STATUS_E_FAILURE;
579 WLANTL_BAReorderType* reOrderInfo = NULL;
580 WLANTL_RxMetaInfoType wRxMetaInfo;
581 v_U32_t fwIdx = 0;
582 tANI_U8 lockRetryCnt = 0;
583 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
584
585 /*------------------------------------------------------------------------
586 Sanity check
587 ------------------------------------------------------------------------*/
588 if ( WLANTL_TID_INVALID(ucTid))
589 {
590 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
591 "WLAN TL:Invalid parameter sent on WLANTL_BaSessionDel");
592 return VOS_STATUS_E_INVAL;
593 }
594
595 if ( WLANTL_STA_ID_INVALID( ucSTAId ) )
596 {
597 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
598 "WLAN TL:Invalid station id requested on WLANTL_BaSessionDel");
599 return VOS_STATUS_E_FAULT;
600 }
601
602 /*------------------------------------------------------------------------
603 Extract TL control block and check existance
604 ------------------------------------------------------------------------*/
605 pTLCb = VOS_GET_TL_CB(pvosGCtx);
606 if ( NULL == pTLCb )
607 {
608 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
609 "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_BaSessionDel");
610 return VOS_STATUS_E_FAULT;
611 }
612
613 if (( 0 == pTLCb->atlSTAClients[ucSTAId].ucExists ) &&
614 ( 0 == pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].ucExists ))
615 {
616 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
617 "WLAN TL:Station was not yet registered on WLANTL_BaSessionDel");
618 return VOS_STATUS_E_EXISTS;
619 }
620 else if(( 0 == pTLCb->atlSTAClients[ucSTAId].ucExists ) &&
621 ( 0 != pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].ucExists ))
622 {
623 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,
624 "STA was deleted but BA info is still there, just remove BA info");
625
626 reOrderInfo = &pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid];
627 reOrderInfo->reorderBuffer->isAvailable = VOS_TRUE;
628 memset(&reOrderInfo->reorderBuffer->arrayBuffer[0],
629 0,
630 WLANTL_MAX_WINSIZE * sizeof(v_PVOID_t));
631 vos_timer_destroy(&reOrderInfo->agingTimer);
632 memset(reOrderInfo, 0, sizeof(WLANTL_BAReorderType));
633
634 return VOS_STATUS_SUCCESS;
635 }
636
637 /*------------------------------------------------------------------------
638 Verify that BA session was added
639 ------------------------------------------------------------------------*/
640 if ( 0 == pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].ucExists )
641 {
642 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
643 "WLAN TL:BA session does not exists on WLANTL_BaSessionDel");
644 return VOS_STATUS_E_EXISTS;
645 }
646
647
648 /*------------------------------------------------------------------------
649 Send all pending packets to HDD
650 ------------------------------------------------------------------------*/
651 reOrderInfo = &pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid];
652
653 /*------------------------------------------------------------------------
654 Invalidate reorder info here. This ensures that no packets are
655 bufferd after reorder buffer is cleaned.
656 */
657 lockStatus = vos_lock_acquire(&reOrderInfo->reorderLock);
658 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
659 {
660 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
661 "Unable to acquire reorder vos lock in %s\n", __FUNCTION__));
662 return lockStatus;
663 }
664 pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].ucExists = 0;
665
666 TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
667 "WLAN TL: Fwd all packets to HDD on WLANTL_BaSessionDel"));
668
669 if(0 == reOrderInfo->ucCIndex)
670 {
671 fwIdx = reOrderInfo->winSize;
672 }
673 else
674 {
675 fwIdx = reOrderInfo->ucCIndex - 1;
676 }
677
678 if(0 != reOrderInfo->pendingFramesCount)
679 {
680 vosStatus = WLANTL_ChainFrontPkts(fwIdx,
681 WLANTL_OPCODE_FWDALL_DROPCUR,
682 &vosDataBuff, reOrderInfo, pTLCb);
683 }
684
685 if ((VOS_STATUS_SUCCESS == vosStatus) && (NULL != vosDataBuff))
686 {
687 TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
688 "WLAN TL: Chaining was successful sending all pkts to HDD : %x",
689 vosDataBuff ));
690
691#ifdef WLAN_SOFTAP_FEATURE
692 if ( WLAN_STA_SOFTAP == pTLCb->atlSTAClients[ucSTAId].wSTADesc.wSTAType )
693 {
694 WLANTL_FwdPktToHDD( pvosGCtx, vosDataBuff, ucSTAId);
695 }
696 else
697#endif
698 {
699 wRxMetaInfo.ucUP = ucTid;
700 pTLCb->atlSTAClients[ucSTAId].pfnSTARx( pvosGCtx, vosDataBuff, ucSTAId,
701 &wRxMetaInfo );
702 }
703 }
704
705 vos_lock_release(&reOrderInfo->reorderLock);
706
707 /*------------------------------------------------------------------------
708 Delete reordering timer
709 ------------------------------------------------------------------------*/
710 if(VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(&reOrderInfo->agingTimer))
711 {
712 vosStatus = vos_timer_stop(&reOrderInfo->agingTimer);
713 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
714 {
715 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer stop fail", vosStatus));
716 return vosStatus;
717 }
718 }
719
720 if(VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&reOrderInfo->agingTimer))
721 {
722 vosStatus = vos_timer_destroy(&reOrderInfo->agingTimer);
723 }
724 else
725 {
726 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer is not stopped state current state is %d",
727 vos_timer_getCurrentState(&reOrderInfo->agingTimer)));
728 }
729 if ( VOS_STATUS_SUCCESS != vosStatus )
730 {
731 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,
732 "WLAN TL:Failed to destroy reorder timer on WLANTL_BaSessionAdd");
733 }
734
735 /*------------------------------------------------------------------------
736 Delete session
737 ------------------------------------------------------------------------*/
738 pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].usCount = 0;
739 pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].ucCIndex = 0;
740 reOrderInfo->winSize = 0;
741 reOrderInfo->SSN = 0;
742 reOrderInfo->sessionID = 0;
743
744 while (vos_lock_destroy(&reOrderInfo->reorderLock) == VOS_STATUS_E_BUSY)
745 {
746 if( lockRetryCnt > 2)
747 {
748 TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
749 "Unable to destroy reorderLock\n"));
750 break;
751 }
752 vos_sleep(1);
753 lockRetryCnt++;
754 }
755
756 TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
757 "WLAN TL: BA session deleted for STA: %d TID: %d",
758 ucSTAId, ucTid));
759
760 memset((v_U8_t *)(&reOrderInfo->reorderBuffer->arrayBuffer[0]),
761 0,
762 WLANTL_MAX_WINSIZE * sizeof(v_PVOID_t));
763 reOrderInfo->reorderBuffer->isAvailable = VOS_TRUE;
764
765 return VOS_STATUS_SUCCESS;
766}/* WLANTL_BaSessionDel */
767
768
769/*----------------------------------------------------------------------------
770 INTERACTION WITH TL main module
771 ---------------------------------------------------------------------------*/
772
773/*==========================================================================
774 AMSDU sub-frame processing module
775 ==========================================================================*/
776/*==========================================================================
777 FUNCTION WLANTL_AMSDUProcess
778
779 DESCRIPTION
780 Process A-MSDU sub-frame. Start of chain if marked as first frame.
781 Linked at the end of the existing AMSDU chain.
782
783 DEPENDENCIES
784
785 PARAMETERS
786
787 IN/OUT:
788 vosDataBuff: vos packet for the received data
789 outgoing contains the root of the chain for the rx
790 aggregated MSDU if the frame is marked as last; otherwise
791 NULL
792
793 IN
794 pvosGCtx: pointer to the global vos context; a handle to TL's
795 control block can be extracted from its context
796 pvBDHeader: pointer to the BD header
797 ucSTAId: Station ID
798 ucMPDUHLen: length of the MPDU header
799 usMPDULen: length of the MPDU
800
801 RETURN VALUE
802 The result code associated with performing the operation
803
804 VOS_STATUS_E_INVAL: invalid input parameters
805 VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a
806 page fault
807 VOS_STATUS_SUCCESS: Everything is good :)
808
809 Other values can be returned as a result of a function call, please check
810 corresponding API for more info.
811
812 SIDE EFFECTS
813
814============================================================================*/
815VOS_STATUS
816WLANTL_AMSDUProcess
817(
818 v_PVOID_t pvosGCtx,
819 vos_pkt_t** ppVosDataBuff,
820 v_PVOID_t pvBDHeader,
821 v_U8_t ucSTAId,
822 v_U8_t ucMPDUHLen,
823 v_U16_t usMPDULen
824)
825{
826 v_U8_t ucFsf; /* First AMSDU sub frame */
827 v_U8_t ucAef; /* Error in AMSDU sub frame */
828 WLANTL_CbType* pTLCb = NULL;
829 v_U8_t MPDUHeaderAMSDUHeader[WLANTL_MPDU_HEADER_LEN + TL_AMSDU_SUBFRM_HEADER_LEN];
830 v_U16_t subFrameLength;
831 v_U16_t paddingSize;
832 VOS_STATUS vStatus = VOS_STATUS_SUCCESS;
833 v_U16_t MPDUDataOffset;
834 v_U16_t packetLength;
835 static v_U32_t numAMSDUFrames = 0;
836 vos_pkt_t* vosDataBuff;
837 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
838 /*------------------------------------------------------------------------
839 Sanity check
840 ------------------------------------------------------------------------*/
841 if (( NULL == ppVosDataBuff ) || (NULL == *ppVosDataBuff) || ( NULL == pvBDHeader ) ||
842 ( WLANTL_STA_ID_INVALID(ucSTAId)) )
843 {
844 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
845 "WLAN TL:Invalid parameter sent on WLANTL_AMSDUProcess");
846 return VOS_STATUS_E_INVAL;
847 }
848
849 vosDataBuff = *ppVosDataBuff;
850 /*------------------------------------------------------------------------
851 Extract TL control block
852 ------------------------------------------------------------------------*/
853 pTLCb = VOS_GET_TL_CB(pvosGCtx);
854 if ( NULL == pTLCb )
855 {
856 VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
857 "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_AMSDUProcess");
858 return VOS_STATUS_E_FAULT;
859 }
860
861 /*------------------------------------------------------------------------
862 Check frame
863 ------------------------------------------------------------------------*/
864 ucAef = (v_U8_t)WDA_GET_RX_AEF( pvBDHeader );
865 ucFsf = (v_U8_t)WDA_GET_RX_ESF( pvBDHeader );
866#ifndef FEATURE_WLAN_INTEGRATED_SOC
867 MPDUDataOffset = (v_U16_t)WDA_GET_RX_MPDU_DATA_OFFSET(pvBDHeader) - WLANHAL_RX_BD_HEADER_SIZE;
868#else
869 /* On Prima, MPDU data offset not includes BD header size */
870 MPDUDataOffset = (v_U16_t)WDA_GET_RX_MPDU_DATA_OFFSET(pvBDHeader);
871#endif /* FEATURE_WLAN_INTEGRATED_SOC */
872
873 if ( WLANHAL_RX_BD_AEF_SET == ucAef )
874 {
875 TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
876 "WLAN TL:Error in AMSDU - dropping entire chain"));
877
878 vos_pkt_return_packet(vosDataBuff);
879 *ppVosDataBuff = NULL;
880 return VOS_STATUS_SUCCESS; /*Not a transport error*/
881 }
882
883 if((0 != ucMPDUHLen) && ucFsf)
884 {
885 /*
886 * This is first AMSDU sub frame
887 * AMSDU Header should be removed
888 * MPDU header should be stored into context to recover next frames
889 */
890 vStatus = vos_pkt_pop_head(vosDataBuff, MPDUHeaderAMSDUHeader, ucMPDUHLen + TL_AMSDU_SUBFRM_HEADER_LEN);
891 if(!VOS_IS_STATUS_SUCCESS(vStatus))
892 {
893 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Pop MPDU AMSDU Header fail"));
894 vos_pkt_return_packet(vosDataBuff);
895 *ppVosDataBuff = NULL;
896 return VOS_STATUS_SUCCESS; /*Not a transport error*/
897 }
898 pTLCb->atlSTAClients[ucSTAId].ucMPDUHeaderLen = ucMPDUHLen;
899 memcpy(pTLCb->atlSTAClients[ucSTAId].aucMPDUHeader, MPDUHeaderAMSDUHeader, ucMPDUHLen);
900 /* AMSDU header stored to handle gabage data within next frame */
901 }
902 else
903 {
904 /* Trim gabage, size is frameLoop */
905 if(MPDUDataOffset > 0)
906 {
907 vStatus = vos_pkt_trim_head(vosDataBuff, MPDUDataOffset);
908 }
909 if(!VOS_IS_STATUS_SUCCESS(vStatus))
910 {
911 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Trim Garbage Data fail"));
912 vos_pkt_return_packet(vosDataBuff);
913 *ppVosDataBuff = NULL;
914 return VOS_STATUS_SUCCESS; /*Not a transport error*/
915 }
916
917 /* Remove MPDU header and AMSDU header from the packet */
918 vStatus = vos_pkt_pop_head(vosDataBuff, MPDUHeaderAMSDUHeader, ucMPDUHLen + TL_AMSDU_SUBFRM_HEADER_LEN);
919 if(!VOS_IS_STATUS_SUCCESS(vStatus))
920 {
921 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"AMSDU Header Pop fail"));
922 vos_pkt_return_packet(vosDataBuff);
923 *ppVosDataBuff = NULL;
924 return VOS_STATUS_SUCCESS; /*Not a transport error*/
925 }
926 } /* End of henalding not first sub frame specific */
927
928 /* Put in MPDU header into all the frame */
929 vStatus = vos_pkt_push_head(vosDataBuff, pTLCb->atlSTAClients[ucSTAId].aucMPDUHeader, pTLCb->atlSTAClients[ucSTAId].ucMPDUHeaderLen);
930 if(!VOS_IS_STATUS_SUCCESS(vStatus))
931 {
932 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"MPDU Header Push back fail"));
933 vos_pkt_return_packet(vosDataBuff);
934 *ppVosDataBuff = NULL;
935 return VOS_STATUS_SUCCESS; /*Not a transport error*/
936 }
937
938 /* Find Padding and remove */
939 memcpy(&subFrameLength, MPDUHeaderAMSDUHeader + ucMPDUHLen + WLANTL_AMSDU_SUBFRAME_LEN_OFFSET, sizeof(v_U16_t));
940 subFrameLength = vos_be16_to_cpu(subFrameLength);
941 paddingSize = usMPDULen - ucMPDUHLen - subFrameLength - TL_AMSDU_SUBFRM_HEADER_LEN;
942
943 vos_pkt_get_packet_length(vosDataBuff, &packetLength);
944 if((paddingSize > 0) && (paddingSize < packetLength))
945 {
946 /* There is padding bits, remove it */
947 vos_pkt_trim_tail(vosDataBuff, paddingSize);
948 }
949 else if(0 == paddingSize)
950 {
951 /* No Padding bits */
952 /* Do Nothing */
953 }
954 else
955 {
956 /* Padding size is larger than Frame size, Actually negative */
957 /* Not a valid case, not a valid frame, drop it */
958 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Padding Size is negative, no possible %d", paddingSize));
959 vos_pkt_return_packet(vosDataBuff);
960 *ppVosDataBuff = NULL;
961 return VOS_STATUS_SUCCESS; /*Not a transport error*/
962 }
963
964 numAMSDUFrames++;
965 if(0 == (numAMSDUFrames % 5000))
966 {
967 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"%lu AMSDU frames arrived", numAMSDUFrames));
968 }
969 return VOS_STATUS_SUCCESS;
970}/* WLANTL_AMSDUProcess */
971
972/*==========================================================================
973 Re-ordering module
974 ==========================================================================*/
975
976/*==========================================================================
977 FUNCTION WLANTL_MSDUReorder
978
979 DESCRIPTION
980 MSDU reordering
981
982 DEPENDENCIES
983
984 PARAMETERS
985
986 IN
987
988 vosDataBuff: vos packet for the received data
989 pvBDHeader: pointer to the BD header
990 ucSTAId: Station ID
991
992 RETURN VALUE
993 The result code associated with performing the operation
994
995 VOS_STATUS_SUCCESS: Everything is good :)
996
997 SIDE EFFECTS
998
999============================================================================*/
1000VOS_STATUS WLANTL_MSDUReorder
1001(
1002 WLANTL_CbType *pTLCb,
1003 vos_pkt_t **vosDataBuff,
1004 v_PVOID_t pvBDHeader,
1005 v_U8_t ucSTAId,
1006 v_U8_t ucTid
1007)
1008{
1009 WLANTL_BAReorderType *currentReorderInfo;
1010 vos_pkt_t *vosPktIdx;
1011 v_U8_t ucOpCode;
1012 v_U8_t ucSlotIdx;
1013 v_U8_t ucFwdIdx;
1014 v_U16_t CSN;
1015 v_U32_t ucCIndexOrig;
1016 VOS_STATUS status = VOS_STATUS_SUCCESS;
1017 VOS_STATUS lockStatus = VOS_STATUS_SUCCESS;
1018 VOS_STATUS timerStatus = VOS_STATUS_SUCCESS;
1019 VOS_TIMER_STATE timerState;
1020 v_SIZE_t rxFree;
1021#ifdef ANI_CHIPSET_VOLANS
1022 v_U64_t ullreplayCounter = 0; /* 48-bit replay counter */
1023#endif
1024 if((NULL == pTLCb) || (*vosDataBuff == NULL))
1025 {
1026 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid ARG pTLCb 0x%p, vosDataBuff 0x%p",
1027 pTLCb, *vosDataBuff));
1028 return VOS_STATUS_E_INVAL;
1029 }
1030
1031 currentReorderInfo = &pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid];
1032
1033 lockStatus = vos_lock_acquire(&currentReorderInfo->reorderLock);
1034 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1035 {
1036 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1037 return lockStatus;
1038 }
1039
1040 if( pTLCb->atlSTAClients[ucSTAId].atlBAReorderInfo[ucTid].ucExists == 0 )
1041 {
1042 vos_lock_release(&currentReorderInfo->reorderLock);
1043 return VOS_STATUS_E_INVAL;
1044 }
1045 ucOpCode = (v_U8_t)WDA_GET_RX_REORDER_OPCODE(pvBDHeader);
1046 ucSlotIdx = (v_U8_t)WDA_GET_RX_REORDER_SLOT_IDX(pvBDHeader);
1047 ucFwdIdx = (v_U8_t)WDA_GET_RX_REORDER_FWD_IDX(pvBDHeader);
1048 CSN = (v_U16_t)WDA_GET_RX_REORDER_CUR_PKT_SEQ_NO(pvBDHeader);
1049
1050
1051
1052#ifdef WLANTL_HAL_VOLANS
1053 /* Replay check code : check whether replay check is needed or not */
1054 if(VOS_TRUE == pTLCb->atlSTAClients[ucSTAId].ucIsReplayCheckValid)
1055 {
1056 /* Getting 48-bit replay counter from the RX BD */
1057 ullreplayCounter = WDA_DS_GetReplayCounter(aucBDHeader);
1058 }
1059#endif
1060
1061#ifdef WLANTL_REORDER_DEBUG_MSG_ENABLE
1062 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"opCode %d SI %d, FI %d, CI %d seqNo %d", ucOpCode, ucSlotIdx, ucFwdIdx, currentReorderInfo->ucCIndex, CSN));
1063#else
1064 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"opCode %d SI %d, FI %d, CI %d seqNo %d", ucOpCode, ucSlotIdx, ucFwdIdx, currentReorderInfo->ucCIndex, CSN));
1065#endif
1066
1067 // remember our current CI so that later we can tell if it advanced
1068 ucCIndexOrig = currentReorderInfo->ucCIndex;
1069
1070 switch(ucOpCode)
1071 {
1072 case WLANTL_OPCODE_INVALID:
1073 /* Do nothing just pass through current frame */
1074 break;
1075
1076 case WLANTL_OPCODE_QCUR_FWDBUF:
1077 if(0 == currentReorderInfo->pendingFramesCount)
1078 {
1079 //This frame will be fwd'ed to the OS. The next slot is the one we expect next
1080 currentReorderInfo->ucCIndex = (ucSlotIdx + 1) % currentReorderInfo->winSize;
1081 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1082 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1083 {
1084 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1085 return lockStatus;
1086 }
1087 return status;
1088 }
1089 status = WLANTL_QueueCurrent(currentReorderInfo,
1090 vosDataBuff,
1091 ucSlotIdx);
1092#ifdef ANI_CHIPSET_VOLANS
1093 if(VOS_TRUE == pTLCb->atlSTAClients[ucSTAId].ucIsReplayCheckValid)
1094 {
1095 WLANTL_FillReplayCounter(currentReorderInfo,
1096 ullreplayCounter, ucSlotIdx);
1097 }
1098#endif
1099 if(VOS_STATUS_E_RESOURCES == status)
1100 {
1101 /* This is the case slot index is already cycle one route, route all the frames Qed */
1102 vosPktIdx = NULL;
1103 status = WLANTL_ChainFrontPkts(ucFwdIdx,
1104 WLANTL_OPCODE_FWDALL_QCUR,
1105 &vosPktIdx,
1106 currentReorderInfo,
1107 pTLCb);
1108 if(!VOS_IS_STATUS_SUCCESS(status))
1109 {
1110 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status));
1111 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1112 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1113 {
1114 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1115 return lockStatus;
1116 }
1117 return status;
1118 }
1119 status = vos_pkt_chain_packet(vosPktIdx, *vosDataBuff, 1);
1120 *vosDataBuff = vosPktIdx;
1121 currentReorderInfo->pendingFramesCount = 0;
1122 }
1123 else
1124 {
1125 vosPktIdx = NULL;
1126 status = WLANTL_ChainFrontPkts(ucFwdIdx,
1127 WLANTL_OPCODE_QCUR_FWDBUF,
1128 &vosPktIdx,
1129 currentReorderInfo,
1130 pTLCb);
1131 if(!VOS_IS_STATUS_SUCCESS(status))
1132 {
1133 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status));
1134 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1135 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1136 {
1137 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1138 return lockStatus;
1139 }
1140 return status;
1141 }
1142 *vosDataBuff = vosPktIdx;
1143 }
1144 break;
1145
1146 case WLANTL_OPCODE_FWDBUF_FWDCUR:
1147 vosPktIdx = NULL;
1148 status = WLANTL_ChainFrontPkts(ucFwdIdx,
1149 WLANTL_OPCODE_FWDBUF_FWDCUR,
1150 &vosPktIdx,
1151 currentReorderInfo,
1152 pTLCb);
1153 if(!VOS_IS_STATUS_SUCCESS(status))
1154 {
1155 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status));
1156 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1157 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1158 {
1159 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1160 return lockStatus;
1161 }
1162 return status;
1163 }
1164
1165 if(NULL == vosPktIdx)
1166 {
1167 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Nothing to chain, just send current frame\n"));
1168 }
1169 else
1170 {
1171 status = vos_pkt_chain_packet(vosPktIdx, *vosDataBuff, 1);
1172 if(!VOS_IS_STATUS_SUCCESS(status))
1173 {
1174 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain with CUR frame fail %d",
1175 status));
1176 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1177 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1178 {
1179 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1180 return lockStatus;
1181 }
1182 return status;
1183 }
1184 *vosDataBuff = vosPktIdx;
1185 }
1186 //ucFwdIdx is the slot this packet supposes to take but there is a hole there
1187 //It looks that the chip will put the next packet into the slot ucFwdIdx.
1188 currentReorderInfo->ucCIndex = ucFwdIdx;
1189 break;
1190
1191 case WLANTL_OPCODE_QCUR:
1192 status = WLANTL_QueueCurrent(currentReorderInfo,
1193 vosDataBuff,
1194 ucSlotIdx);
1195#ifdef ANI_CHIPSET_VOLANS
1196 if(VOS_TRUE == pTLCb->atlSTAClients[ucSTAId].ucIsReplayCheckValid)
1197 {
1198 WLANTL_FillReplayCounter(currentReorderInfo,
1199 ullreplayCounter, ucSlotIdx);
1200 }
1201#endif
1202 if(VOS_STATUS_E_RESOURCES == status)
1203 {
1204 /* This is the case slot index is already cycle one route, route all the frames Qed */
1205 vosPktIdx = NULL;
1206 status = WLANTL_ChainFrontPkts(ucFwdIdx,
1207 WLANTL_OPCODE_FWDALL_QCUR,
1208 &vosPktIdx,
1209 currentReorderInfo,
1210 pTLCb);
1211 if(!VOS_IS_STATUS_SUCCESS(status))
1212 {
1213 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status));
1214 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1215 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1216 {
1217 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1218 return lockStatus;
1219 }
1220 return status;
1221 }
1222 status = vos_pkt_chain_packet(vosPktIdx, *vosDataBuff, 1);
1223 *vosDataBuff = vosPktIdx;
1224 currentReorderInfo->pendingFramesCount = 0;
1225 }
1226 else
1227 {
1228 /* Since current Frame is Qed, no frame will be routed */
1229 *vosDataBuff = NULL;
1230 }
1231 break;
1232
1233 case WLANTL_OPCODE_FWDBUF_QUEUECUR:
1234 vosPktIdx = NULL;
1235 status = WLANTL_ChainFrontPkts(ucFwdIdx,
1236 WLANTL_OPCODE_FWDBUF_QUEUECUR,
1237 &vosPktIdx,
1238 currentReorderInfo,
1239 pTLCb);
1240 if(!VOS_IS_STATUS_SUCCESS(status))
1241 {
1242 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make chain with buffered frame fail %d",
1243 status));
1244 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1245 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1246 {
1247 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1248 return lockStatus;
1249 }
1250 return status;
1251 }
1252 //This opCode means the window shift. Enforce the current Index
1253 currentReorderInfo->ucCIndex = ucFwdIdx;
1254
1255 status = WLANTL_QueueCurrent(currentReorderInfo,
1256 vosDataBuff,
1257 ucSlotIdx);
1258#ifdef ANI_CHIPSET_VOLANS
1259 if(VOS_TRUE == pTLCb->atlSTAClients[ucSTAId].ucIsReplayCheckValid)
1260 {
1261 WLANTL_FillReplayCounter(currentReorderInfo,
1262 ullreplayCounter, ucSlotIdx);
1263 }
1264#endif
1265 if(VOS_STATUS_E_RESOURCES == status)
1266 {
1267 vos_pkt_return_packet(vosPktIdx);
1268 /* This is the case slot index is already cycle one route, route all the frames Qed */
1269 vosPktIdx = NULL;
1270 status = WLANTL_ChainFrontPkts(ucFwdIdx,
1271 WLANTL_OPCODE_FWDALL_QCUR,
1272 &vosPktIdx,
1273 currentReorderInfo,
1274 pTLCb);
1275 if(!VOS_IS_STATUS_SUCCESS(status))
1276 {
1277 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status));
1278 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1279 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1280 {
1281 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1282 return lockStatus;
1283 }
1284 return status;
1285 }
1286 status = vos_pkt_chain_packet(vosPktIdx, *vosDataBuff, 1);
1287 *vosDataBuff = vosPktIdx;
1288 currentReorderInfo->pendingFramesCount = 0;
1289 }
1290 *vosDataBuff = vosPktIdx;
1291 break;
1292
1293 case WLANTL_OPCODE_FWDBUF_DROPCUR:
1294 vosPktIdx = NULL;
1295 status = WLANTL_ChainFrontPkts(ucFwdIdx,
1296 WLANTL_OPCODE_FWDBUF_DROPCUR,
1297 &vosPktIdx,
1298 currentReorderInfo,
1299 pTLCb);
1300 if(!VOS_IS_STATUS_SUCCESS(status))
1301 {
1302 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make chain with buffered frame fail %d",
1303 status));
1304 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1305 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1306 {
1307 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1308 return lockStatus;
1309 }
1310 return status;
1311 }
1312
1313 //Since BAR frame received, set the index to the right location
1314 currentReorderInfo->ucCIndex = ucFwdIdx;
1315
1316 /* Current frame has to be dropped, BAR frame */
1317 status = vos_pkt_return_packet(*vosDataBuff);
1318 if(!VOS_IS_STATUS_SUCCESS(status))
1319 {
1320 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Drop BAR frame fail %d",
1321 status));
1322 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1323 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1324 {
1325 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1326 return lockStatus;
1327 }
1328 return status;
1329 }
1330 *vosDataBuff = vosPktIdx;
1331 break;
1332
1333 case WLANTL_OPCODE_FWDALL_DROPCUR:
1334 vosPktIdx = NULL;
1335 status = WLANTL_ChainFrontPkts(ucFwdIdx,
1336 WLANTL_OPCODE_FWDALL_DROPCUR,
1337 &vosPktIdx,
1338 currentReorderInfo,
1339 pTLCb);
1340 if(!VOS_IS_STATUS_SUCCESS(status))
1341 {
1342 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make chain with buffered frame fail %d",
1343 status));
1344 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1345 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1346 {
1347 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1348 return lockStatus;
1349 }
1350 return status;
1351 }
1352
1353 //Since BAR frame received and beyond cur window, set the index to the right location
1354 currentReorderInfo->ucCIndex = 0;
1355
1356 status = vos_pkt_return_packet(*vosDataBuff);
1357 if(!VOS_IS_STATUS_SUCCESS(status))
1358 {
1359 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Drop BAR frame fail %d",
1360 status));
1361 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1362 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1363 {
1364 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1365 return lockStatus;
1366 }
1367 return status;
1368 }
1369
1370 *vosDataBuff = vosPktIdx;
1371 break;
1372
1373 case WLANTL_OPCODE_FWDALL_QCUR:
1374 vosPktIdx = NULL;
1375 status = WLANTL_ChainFrontPkts(currentReorderInfo->winSize,
1376 WLANTL_OPCODE_FWDALL_DROPCUR,
1377 &vosPktIdx,
1378 currentReorderInfo,
1379 pTLCb);
1380 if(!VOS_IS_STATUS_SUCCESS(status))
1381 {
1382 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make chain with buffered frame fail %d",
1383 status));
1384 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1385 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1386 {
1387 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1388 return lockStatus;
1389 }
1390 return status;
1391 }
1392 status = WLANTL_QueueCurrent(currentReorderInfo,
1393 vosDataBuff,
1394 ucSlotIdx);
1395#ifdef ANI_CHIPSET_VOLANS
1396 if(VOS_TRUE == pTLCb->atlSTAClients[ucSTAId].ucIsReplayCheckValid)
1397 {
1398 WLANTL_FillReplayCounter(currentReorderInfo,
1399 ullreplayCounter, ucSlotIdx);
1400 }
1401#endif
1402 if(!VOS_IS_STATUS_SUCCESS(status))
1403 {
1404 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Q Current frame fail %d",
1405 status));
1406 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1407 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1408 {
1409 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1410 return lockStatus;
1411 }
1412 return status;
1413 }
1414 currentReorderInfo->ucCIndex = ucSlotIdx;
1415 *vosDataBuff = vosPktIdx;
1416 break;
1417
1418 case WLANTL_OPCODE_TEARDOWN:
1419 // do we have a procedure in place to teardown BA?
1420
1421 // fall through to drop the current packet
1422 case WLANTL_OPCODE_DROPCUR:
1423 vos_pkt_return_packet(*vosDataBuff);
1424 *vosDataBuff = NULL;
1425 break;
1426
1427 default:
1428 break;
1429 }
1430
1431 /* Check the available VOS RX buffer size
1432 * If remaining VOS RX buffer is too few, have to make space
1433 * Route all the Qed frames upper layer
1434 * Otherwise, RX thread could be stall */
1435 vos_pkt_get_available_buffer_pool(VOS_PKT_TYPE_RX_RAW, &rxFree);
1436 if(WLANTL_BA_MIN_FREE_RX_VOS_BUFFER > rxFree)
1437 {
1438 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"RX Free", rxFree));
1439 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"RX free buffer count is too low, Pending frame count is %d",
1440 currentReorderInfo->pendingFramesCount));
1441 vosPktIdx = NULL;
1442 status = WLANTL_ChainFrontPkts(ucFwdIdx,
1443 WLANTL_OPCODE_FWDALL_DROPCUR,
1444 &vosPktIdx,
1445 currentReorderInfo,
1446 pTLCb);
1447 if(!VOS_IS_STATUS_SUCCESS(status))
1448 {
1449 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status));
1450 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1451 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1452 {
1453 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1454 return lockStatus;
1455 }
1456 return status;
1457 }
1458 if(NULL != *vosDataBuff)
1459 {
1460 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Already something, Chain it"));
1461 vos_pkt_chain_packet(*vosDataBuff, vosPktIdx, 1);
1462 }
1463 else
1464 {
1465 *vosDataBuff = vosPktIdx;
1466 }
1467 currentReorderInfo->pendingFramesCount = 0;
1468 }
1469
1470 /*
1471 * Current aging timer logic:
1472 * 1) if we forwarded any packets and the timer is running:
1473 * stop the timer
1474 * 2) if there are packets queued and the timer is not running:
1475 * start the timer
1476 */
1477 timerState = vos_timer_getCurrentState(&currentReorderInfo->agingTimer);
1478 if ((VOS_TIMER_STATE_RUNNING == timerState) &&
1479 (ucCIndexOrig != currentReorderInfo->ucCIndex))
1480 {
1481 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"HOLE filled, Pending Frames Count %d",
1482 currentReorderInfo->pendingFramesCount));
1483
1484 // we forwarded some packets so stop aging the current hole
1485 timerStatus = vos_timer_stop(&currentReorderInfo->agingTimer);
1486 timerState = VOS_TIMER_STATE_STOPPED;
1487
1488 // ignore the returned status since there is a race condition
1489 // whereby between the time we called getCurrentState() and the
1490 // time we call stop() the timer could have fired. In that case
1491 // stop() will return an error, but we don't care since the
1492 // timer has stopped
1493 }
1494
1495 if (currentReorderInfo->pendingFramesCount > 0)
1496 {
1497 if (VOS_TIMER_STATE_STOPPED == timerState)
1498 {
1499 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"There is a new HOLE, Pending Frames Count %d",
1500 currentReorderInfo->pendingFramesCount));
1501 timerStatus = vos_timer_start(&currentReorderInfo->agingTimer,
1502 WLANTL_BA_REORDERING_AGING_TIMER);
1503 if(!VOS_IS_STATUS_SUCCESS(timerStatus))
1504 {
1505 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer start fail", timerStatus));
1506 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1507 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1508 {
1509 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1510 return lockStatus;
1511 }
1512 return timerStatus;
1513 }
1514 }
1515 else
1516 {
1517 // we didn't forward any packets and the timer was already
1518 // running so we're still aging the same hole
1519 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Still HOLE, Pending Frames Count %d",
1520 currentReorderInfo->pendingFramesCount));
1521 }
1522 }
1523
1524 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
1525 if(!VOS_IS_STATUS_SUCCESS(lockStatus))
1526 {
1527 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
1528 return lockStatus;
1529 }
1530 return VOS_STATUS_SUCCESS;
1531}/* WLANTL_MSDUReorder */
1532
1533
1534/*==========================================================================
1535 Utility functions
1536 ==========================================================================*/
1537
1538/*==========================================================================
1539
1540 FUNCTION WLANTL_QueueCurrent
1541
1542 DESCRIPTION
1543 It will queue a packet at a given slot index in the MSDU reordering list.
1544
1545 DEPENDENCIES
1546
1547 PARAMETERS
1548
1549 IN
1550 pwBaReorder: pointer to the BA reordering session info
1551 vosDataBuff: data buffer to be queued
1552 ucSlotIndex: slot index
1553
1554 RETURN VALUE
1555 The result code associated with performing the operation
1556
1557 VOS_STATUS_SUCCESS: Everything is OK
1558
1559
1560 SIDE EFFECTS
1561
1562============================================================================*/
1563VOS_STATUS WLANTL_QueueCurrent
1564(
1565 WLANTL_BAReorderType* pwBaReorder,
1566 vos_pkt_t** vosDataBuff,
1567 v_U8_t ucSlotIndex
1568)
1569{
1570 VOS_STATUS status = VOS_STATUS_SUCCESS;
1571
1572 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"vos Packet has to be Qed 0x%p",
1573 *vosDataBuff));
1574 if(NULL != pwBaReorder->reorderBuffer->arrayBuffer[ucSlotIndex])
1575 {
1576 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"One Cycle rounded, lost many frames already, not in Q %d\n",
1577 pwBaReorder->pendingFramesCount));
1578 return VOS_STATUS_E_RESOURCES;
1579 }
1580
1581 pwBaReorder->reorderBuffer->arrayBuffer[ucSlotIndex] =
1582 (v_PVOID_t)(*vosDataBuff);
1583 pwBaReorder->pendingFramesCount++;
1584 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Assigned, Pending Frames %d at slot %d, dataPtr 0x%x",
1585 pwBaReorder->pendingFramesCount,
1586 ucSlotIndex,
1587 pwBaReorder->reorderBuffer->arrayBuffer[ucSlotIndex]));
1588
1589 return status;
1590}/*WLANTL_QueueCurrent*/
1591
1592/*==========================================================================
1593
1594 FUNCTION WLANTL_ChainFrontPkts
1595
1596 DESCRIPTION
1597 It will remove all the packets from the front of a vos list and chain
1598 them to a vos pkt .
1599
1600 DEPENDENCIES
1601
1602 PARAMETERS
1603
1604 IN
1605 ucCount: number of packets to extract
1606 pwBaReorder: pointer to the BA reordering session info
1607
1608 OUT
1609 vosDataBuff: data buffer containing the extracted chain of packets
1610
1611 RETURN VALUE
1612 The result code associated with performing the operation
1613
1614 VOS_STATUS_SUCCESS: Everything is OK
1615
1616
1617 SIDE EFFECTS
1618
1619============================================================================*/
1620VOS_STATUS WLANTL_ChainFrontPkts
1621(
1622 v_U32_t fwdIndex,
1623 v_U8_t opCode,
1624 vos_pkt_t **vosDataBuff,
1625 WLANTL_BAReorderType *pwBaReorder,
1626 WLANTL_CbType *pTLCb
1627)
1628{
1629 VOS_STATUS status = VOS_STATUS_SUCCESS;
1630 v_U32_t idx;
1631 v_PVOID_t currentDataPtr = NULL;
1632 int negDetect;
1633#ifdef WLANTL_REORDER_DEBUG_MSG_ENABLE
1634#define WLANTL_OUT_OF_WINDOW_IDX 65
1635 v_U32_t frameIdx[2] = {0, 0}, ffidx = fwdIndex, idx2 = WLANTL_OUT_OF_WINDOW_IDX;
1636 int pending = pwBaReorder->pendingFramesCount, start = WLANTL_OUT_OF_WINDOW_IDX, end;
1637#endif
1638
1639 if(pwBaReorder->ucCIndex >= fwdIndex)
1640 {
1641 fwdIndex += pwBaReorder->winSize;
1642 }
1643
1644 if((WLANTL_OPCODE_FWDALL_DROPCUR == opCode) ||
1645 (WLANTL_OPCODE_FWDALL_QCUR == opCode))
1646 {
1647 fwdIndex = pwBaReorder->ucCIndex + pwBaReorder->winSize;
1648 }
1649
1650 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Current Index %d, FWD Index %d, reorderBuffer 0x%p",
1651 pwBaReorder->ucCIndex % pwBaReorder->winSize,
1652 fwdIndex % pwBaReorder->winSize,
1653 pwBaReorder->reorderBuffer));
1654
1655 negDetect = pwBaReorder->pendingFramesCount;
1656 for(idx = pwBaReorder->ucCIndex; idx <= fwdIndex; idx++)
1657 {
1658 currentDataPtr =
1659 pwBaReorder->reorderBuffer->arrayBuffer[idx % pwBaReorder->winSize];
1660 if(NULL != currentDataPtr)
1661 {
1662#ifdef WLANTL_REORDER_DEBUG_MSG_ENABLE
1663 idx2 = (idx >= pwBaReorder->winSize) ? (idx - pwBaReorder->winSize) : idx;
1664 frameIdx[idx2 / 32] |= 1 << (idx2 % 32);
1665 if(start == WLANTL_OUT_OF_WINDOW_IDX) start = idx2;
1666#endif
1667 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"There is buffered frame %d",
1668 idx % pwBaReorder->winSize));
1669 if(NULL == *vosDataBuff)
1670 {
1671 *vosDataBuff = (vos_pkt_t *)currentDataPtr;
1672 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"This is new head %d",
1673 idx % pwBaReorder->winSize));
1674 }
1675 else
1676 {
1677 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"There is bufered Just add %d",
1678 idx % pwBaReorder->winSize));
1679 vos_pkt_chain_packet(*vosDataBuff,
1680 (vos_pkt_t *)currentDataPtr,
1681 VOS_TRUE);
1682 }
1683 pwBaReorder->reorderBuffer->arrayBuffer[idx % pwBaReorder->winSize]
1684 = NULL;
1685 pwBaReorder->pendingFramesCount--;
1686 negDetect--;
1687 if(negDetect < 0)
1688 {
1689 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"This is not possible, some balance has problem\n"));
1690 VOS_ASSERT(0);
1691 return VOS_STATUS_E_FAULT;
1692 }
1693 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Slot Index %d, set as NULL, Pending Frames %d",
1694 idx % pwBaReorder->winSize,
1695 pwBaReorder->pendingFramesCount
1696 ));
1697 pwBaReorder->ucCIndex = (idx + 1) % pwBaReorder->winSize;
1698 }
1699 else
1700 {
1701 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Empty Array %d",
1702 idx % pwBaReorder->winSize));
1703 }
1704 TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Current Index %d, winSize %d",
1705 pwBaReorder->ucCIndex,
1706 pwBaReorder->winSize
1707 ));
1708 }
1709
1710#ifdef WLANTL_REORDER_DEBUG_MSG_ENABLE
1711 end = idx2;
1712
1713 TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Fwd 0x%08X-%08X opCode %d fwdIdx %d windowSize %d pending frame %d fw no. %d from idx %d to %d",
1714 frameIdx[1], frameIdx[0], opCode, ffidx, pwBaReorder->winSize, pending, pending - negDetect, start, end));
1715#endif
1716
1717 return status;
1718}/*WLANTL_ChainFrontPkts*/
1719#ifdef ANI_CHIPSET_VOLANS
1720/*==========================================================================
1721
1722 FUNCTION WLANTL_FillReplayCounter
1723
1724 DESCRIPTION
1725 It will fill repaly counter at a given slot index in the MSDU reordering list.
1726
1727 DEPENDENCIES
1728
1729 PARAMETERS
1730
1731 IN
1732 pwBaReorder : pointer to the BA reordering session info
1733 replayCounter: replay counter to be filled
1734 ucSlotIndex : slot index
1735
1736 RETURN VALUE
1737 NONE
1738
1739
1740 SIDE EFFECTS
1741 NONE
1742
1743 ============================================================================*/
1744void WLANTL_FillReplayCounter
1745(
1746 WLANTL_BAReorderType* pwBaReorder,
1747 v_U64_t ullreplayCounter,
1748 v_U8_t ucSlotIndex
1749)
1750{
1751
1752 //BAMSGDEBUG("replay counter to be filled in Qed frames %llu",
1753 //replayCounter, 0, 0);
1754
1755 pwBaReorder->reorderBuffer->ullReplayCounter[ucSlotIndex] = ullreplayCounter;
1756 //BAMSGDEBUG("Assigned, replay counter Pending Frames %d at slot %d, replay counter[0x%llX]\n",
1757 //pwBaReorder->pendingFramesCount,
1758 //ucSlotIndex,
1759 //pwBaReorder->reorderBuffer->ullReplayCounter);
1760 return;
1761}/*WLANTL_FillReplayCounter*/
1762#endif /*End of #ifdef WLANTL_HAL_VOLANS*/
1763