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