/*
 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/*===========================================================================

                       W L A N _ Q C T _ T L _ B A. C
                                               
  OVERVIEW:
  
  This software unit holds the implementation of the WLAN Transport Layer
  Block Ack session support. Also included are the AMSDU de-aggregation 
  completion and MSDU re-ordering functionality. 
  
  The functions externalized by this module are to be called ONLY by the main
  TL module or the HAL layer.

  DEPENDENCIES: 

  Are listed for each API below. 
===========================================================================*/

/*===========================================================================

                      EDIT HISTORY FOR FILE


  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.


   $Header$$DateTime$$Author$


  when        who     what, where, why
----------    ---    --------------------------------------------------------
2010-10-xx    dli     Change ucCIndex to point to the slot the next frame to be expected to fwd
2008-08-22    sch     Update based on unit test
2008-07-31    lti     Created module

===========================================================================*/

/*----------------------------------------------------------------------------
 * Include Files
 * -------------------------------------------------------------------------*/
#include "wlan_qct_tl.h" 
#include "wlan_qct_wda.h" 
#include "wlan_qct_tli.h" 
#include "wlan_qct_tli_ba.h" 
#include "wlan_qct_hal.h" 
#include "wlan_qct_tl_trace.h"
#include "vos_trace.h"
#include "vos_types.h"
#include "vos_list.h"
#include "vos_lock.h"
#include "tlDebug.h"
/*----------------------------------------------------------------------------
 * Preprocessor Definitions and Constants
 * -------------------------------------------------------------------------*/
//#define WLANTL_REORDER_DEBUG_MSG_ENABLE
#define WLANTL_BA_REORDERING_AGING_TIMER   30   /* 30 millisec */
#define WLANTL_BA_MIN_FREE_RX_VOS_BUFFER   0    /* RX VOS buffer low threshold */
#define CSN_WRAP_AROUND_THRESHOLD          3000 /* CSN wrap around threshold */


const v_U8_t  WLANTL_TID_2_AC[WLAN_MAX_TID] = {   WLANTL_AC_BE,
                                                  WLANTL_AC_BK,
                                                  WLANTL_AC_BK,
                                                  WLANTL_AC_BE,
                                                  WLANTL_AC_VI,
                                                  WLANTL_AC_VI,
                                                  WLANTL_AC_VO,
                                                  WLANTL_AC_VO };

/*==========================================================================

   FUNCTION    tlReorderingAgingTimerExpierCB

   DESCRIPTION 
      After aging timer expiered, all Qed frames have to be routed to upper
      layer. Otherwise, there is possibilitied that ahng some frames
    
   PARAMETERS 
      v_PVOID_t  timerUdata    Timer callback user data
                               Has information about where frames should be
                               routed
   
   RETURN VALUE
      VOS_STATUS_SUCCESS       General success
      VOS_STATUS_E_INVAL       Invalid frame handle
  
============================================================================*/
v_VOID_t WLANTL_ReorderingAgingTimerExpierCB
(
   v_PVOID_t  timerUdata
)
{
   WLANTL_TIMER_EXPIER_UDATA_T *expireHandle;
   WLANTL_BAReorderType        *ReorderInfo;
   WLANTL_CbType               *pTLHandle;
   WLANTL_STAClientType*       pClientSTA = NULL;
   vos_pkt_t                   *vosDataBuff;
   VOS_STATUS                   status = VOS_STATUS_SUCCESS;
   v_U8_t                       ucSTAID;
   v_U8_t                       ucTID;
   v_U8_t                       opCode;
   WLANTL_RxMetaInfoType        wRxMetaInfo;
   v_U32_t                      fwIdx = 0;
   WDI_DS_RxMetaInfoType       *pRxMetadata;
   vos_pkt_t                   *pCurrent;
   vos_pkt_t                   *pNext;
   v_S15_t                      seq = 0;
   v_U32_t                      cIndex;
   /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   if(NULL == timerUdata)
   {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer Callback User data NULL"));
      return;
   }

   expireHandle = (WLANTL_TIMER_EXPIER_UDATA_T *)timerUdata;
   ucSTAID      = (v_U8_t)expireHandle->STAID;
   ucTID        = expireHandle->TID;
   if(WLANTL_STA_ID_INVALID(ucSTAID) || WLANTL_TID_INVALID(ucTID))
   {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"SID %d or TID %d is not valid",
                  ucSTAID, ucTID));
      return;
   }

   pTLHandle    = (WLANTL_CbType *)expireHandle->pTLHandle;
   if(NULL == pTLHandle)
   {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"TL Control block NULL"));
      return;
   }

   pClientSTA = pTLHandle->atlSTAClients[ucSTAID];
   if( NULL == pClientSTA ){
      TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
          "TL:STA Memory not allocated STA ID: %d, %s", ucSTAID, __func__));
      return;
   }

   ReorderInfo = &pClientSTA->atlBAReorderInfo[ucTID];
   if(NULL == ReorderInfo)
   {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Reorder data NULL, this could not happen SID %d, TID %d", 
                  ucSTAID, ucTID));
      return;
   }

   if(0 == pClientSTA->atlBAReorderInfo[ucTID].ucExists)
   {
       TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Reorder session doesn't exist SID %d, TID %d", 
                   ucSTAID, ucTID));
       return;
   }

   if(!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&ReorderInfo->reorderLock)))
   {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Get LOCK Fail"));
      return;
   }

   if( 0 == pClientSTA->atlBAReorderInfo[ucTID].ucExists )
   {
      vos_lock_release(&ReorderInfo->reorderLock);
      return;
   }

   opCode      = WLANTL_OPCODE_FWDALL_DROPCUR;
   vosDataBuff = NULL;

   MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_REORDER_TIMER_EXP_CB,
                      ucSTAID , opCode ));


   TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"BA timeout with %d pending frames, curIdx %d", ReorderInfo->pendingFramesCount, ReorderInfo->ucCIndex));

   if(ReorderInfo->pendingFramesCount == 0)
   {
      if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock)))
      {
         TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail"));
      }
      return;
   }

   if(0 == ReorderInfo->ucCIndex)
   {
      fwIdx = ReorderInfo->winSize;
   }
   else
   {
      fwIdx = ReorderInfo->ucCIndex - 1;
   }

   cIndex = ReorderInfo->ucCIndex;
   status = WLANTL_ChainFrontPkts(fwIdx, opCode, 
                                  &vosDataBuff, ReorderInfo, NULL);
   ReorderInfo->ucCIndex = cIndex;
   if(!VOS_IS_STATUS_SUCCESS(status))
   {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make packet chain fail with Qed frames %d", status));
      if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock)))
      {
         TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail"));
      }
      return;
   }

   if(NULL == pClientSTA->pfnSTARx)
   {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Callback function NULL with STAID %d", ucSTAID));
      if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock)))
      {
         TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail"));
      }
      return;
   }

   if(NULL == vosDataBuff)
   {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"No pending frames, why triggered timer? "));
      if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock)))
      {
         TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail"));
      }
      return;
   }

   /* Do replay check before giving packets to upper layer
      replay check code : check whether replay check is needed or not */
   if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid) {
      WLANTL_ReorderReplayCheck(pClientSTA, &vosDataBuff, ucTID);
   }

   pCurrent = vosDataBuff;

   while (pCurrent != NULL)
   {
       vos_pkt_walk_packet_chain(pCurrent, &pNext, VOS_FALSE);

       if (NULL == pNext)
       {
           /* This is the last packet, retrieve its sequence number */
           pRxMetadata = WDI_DS_ExtractRxMetaData(VOS_TO_WPAL_PKT(pCurrent));
           seq = WDA_GET_RX_REORDER_CUR_PKT_SEQ_NO(pRxMetadata);
       }
       pCurrent = pNext;
   }
   TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
          "%s: Sending out Frame no: %d to HDD", __func__, seq));
   ReorderInfo->LastSN = seq;

   if( WLAN_STA_SOFTAP == pClientSTA->wSTADesc.wSTAType)
   {
      WLANTL_FwdPktToHDD( expireHandle->pAdapter, vosDataBuff, ucSTAID);
   }
   else
   {
      wRxMetaInfo.ucUP = ucTID;
      pClientSTA->pfnSTARx(expireHandle->pAdapter,
                                           vosDataBuff, ucSTAID, &wRxMetaInfo);
   }
   if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock)))
   {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail"));
   }
   return;
}/*WLANTL_ReorderingAgingTimerExpierCB*/

/*----------------------------------------------------------------------------
    INTERACTION WITH TL Main
 ---------------------------------------------------------------------------*/
/*==========================================================================

   FUNCTION    WLANTL_InitBAReorderBuffer

   DESCRIPTION 
      Init Reorder buffer array
    
   PARAMETERS 
      v_PVOID_t   pvosGCtx Global context

   RETURN VALUE
      NONE
  
============================================================================*/

void WLANTL_InitBAReorderBuffer
(
   v_PVOID_t   pvosGCtx
)
{
   WLANTL_CbType        *pTLCb;
   v_U32_t              idx;
   v_U32_t              pIdx;

   pTLCb = VOS_GET_TL_CB(pvosGCtx);
   if (NULL == pTLCb)
   {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
                       "%s: Invalid TL Control Block", __func__));
      return;
   }

   for(idx = 0; idx < WLANTL_MAX_BA_SESSION; idx++)
   {
      pTLCb->reorderBufferPool[idx].isAvailable = VOS_TRUE;
      for(pIdx = 0; pIdx < WLANTL_MAX_WINSIZE; pIdx++)
      {
         pTLCb->reorderBufferPool[idx].arrayBuffer[pIdx] = NULL;
         pTLCb->reorderBufferPool[idx].ullReplayCounter[pIdx] = 0; 
      }
   }

   TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"BA reorder buffer init"));
   return;
}

/*==========================================================================

  FUNCTION    WLANTL_BaSessionAdd

  DESCRIPTION 
    HAL notifies TL when a new Block Ack session is being added. 
    
  DEPENDENCIES 
    A BA session on Rx needs to be added in TL before the response is 
    being sent out 
    
  PARAMETERS 

    IN
    pvosGCtx:       pointer to the global vos context; a handle to TL's 
                    control block can be extracted from its context 
    ucSTAId:        identifier of the station for which requested the BA 
                    session
    ucTid:          Tspec ID for the new BA session
    uSize:          size of the reordering window

   
  RETURN VALUE
    The result code associated with performing the operation  

    VOS_STATUS_E_INVAL:      Input parameters are invalid 
    VOS_STATUS_E_FAULT:      Station ID is outside array boundaries or pointer 
                             to TL cb is NULL ; access would cause a page fault  
    VOS_STATUS_E_EXISTS:     Station was not registered or BA session already
                             exists
    VOS_STATUS_E_NOSUPPORT:  Not yet supported
    
  SIDE EFFECTS 
  
============================================================================*/
VOS_STATUS
WLANTL_BaSessionAdd 
( 
  v_PVOID_t   pvosGCtx, 
  v_U16_t     sessionID,
  v_U32_t     ucSTAId,
  v_U8_t      ucTid, 
  v_U32_t     uBufferSize,
  v_U32_t     winSize,
  v_U32_t     SSN
)
{
  WLANTL_CbType        *pTLCb = NULL;
  WLANTL_STAClientType *pClientSTA = NULL;
  WLANTL_BAReorderType *reorderInfo;
  v_U32_t               idx;
  VOS_STATUS            status = VOS_STATUS_SUCCESS;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /*------------------------------------------------------------------------
    Sanity check
   ------------------------------------------------------------------------*/
  if ( WLANTL_TID_INVALID(ucTid))
  {
    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
              "WLAN TL:Invalid parameter sent on WLANTL_BaSessionAdd");
    return VOS_STATUS_E_INVAL;
  }

  if ( WLANTL_STA_ID_INVALID( ucSTAId ) )
  {
    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
              "WLAN TL:Invalid station id requested on WLANTL_BaSessionAdd");
    return VOS_STATUS_E_FAULT;
  }

  /*------------------------------------------------------------------------
    Extract TL control block and check existance
   ------------------------------------------------------------------------*/
  pTLCb = VOS_GET_TL_CB(pvosGCtx);
  if ( NULL == pTLCb ) 
  {
    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
          "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_BaSessionAdd");
    return VOS_STATUS_E_FAULT;
  }

  pClientSTA  = pTLCb->atlSTAClients[ucSTAId];
  if ( NULL == pClientSTA )
  {
      TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
          "WLAN TL:Client Memory was not allocated on %s", __func__));
      return VOS_STATUS_E_FAILURE;
  }

  if ( 0 == pClientSTA->ucExists )
  {
    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
          "WLAN TL:Station was not yet registered on WLANTL_BaSessionAdd");
    return VOS_STATUS_E_EXISTS;
  }

  reorderInfo = &pClientSTA->atlBAReorderInfo[ucTid];
  if (!VOS_IS_STATUS_SUCCESS(
     vos_lock_acquire(&reorderInfo->reorderLock)))
  {
    TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
           "%s: Release LOCK Fail", __func__));
    return VOS_STATUS_E_FAULT;
  }
  /*------------------------------------------------------------------------
    Verify that BA session was not already added
   ------------------------------------------------------------------------*/
  if ( 0 != reorderInfo->ucExists )
  {
    reorderInfo->ucExists++;
    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
              "WLAN TL:BA session already exists on WLANTL_BaSessionAdd");
    vos_lock_release(&reorderInfo->reorderLock);
    return VOS_STATUS_E_EXISTS;
  }

  /*------------------------------------------------------------------------
    Initialize new BA session 
   ------------------------------------------------------------------------*/
  for(idx = 0; idx < WLANTL_MAX_BA_SESSION; idx++)
  {
    if(VOS_TRUE == pTLCb->reorderBufferPool[idx].isAvailable)
    {
      pClientSTA->atlBAReorderInfo[ucTid].reorderBuffer =
                                            &(pTLCb->reorderBufferPool[idx]);
      pTLCb->reorderBufferPool[idx].isAvailable = VOS_FALSE;
      TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"%dth buffer available, buffer PTR 0x%pK",
                  idx,
                  pClientSTA->atlBAReorderInfo[ucTid].reorderBuffer
                  ));
      break;
    }
  }

  
  if (WLAN_STA_SOFTAP == pClientSTA->wSTADesc.wSTAType)
  {
      if (WLANTL_MAX_BA_SESSION == idx)
      {
          VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
              "Number of Add BA request received more than allowed");
          vos_lock_release(&reorderInfo->reorderLock);
          return VOS_STATUS_E_NOSUPPORT;
      }
  }
  reorderInfo->timerUdata.pAdapter     = pvosGCtx;
  reorderInfo->timerUdata.pTLHandle    = (v_PVOID_t)pTLCb;
  reorderInfo->timerUdata.STAID        = ucSTAId;
  reorderInfo->timerUdata.TID          = ucTid;

  /* BA aging timer */
  status = vos_timer_init(&reorderInfo->agingTimer,
                          VOS_TIMER_TYPE_SW,
                          WLANTL_ReorderingAgingTimerExpierCB,
                          (v_PVOID_t)(&reorderInfo->timerUdata));
  if(!VOS_IS_STATUS_SUCCESS(status))
  {
     TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
            "%s: Timer Init Fail", __func__));
     vos_lock_release(&reorderInfo->reorderLock);
     return status;
  }

  pClientSTA->atlBAReorderInfo[ucTid].ucExists++;
  pClientSTA->atlBAReorderInfo[ucTid].usCount   = 0;
  pClientSTA->atlBAReorderInfo[ucTid].ucCIndex  = 0;
  if(0 == winSize)
  {
    pClientSTA->atlBAReorderInfo[ucTid].winSize = WLANTL_MAX_WINSIZE;
  }
  else
  {
    pClientSTA->atlBAReorderInfo[ucTid].winSize   = winSize;
  }
  pClientSTA->atlBAReorderInfo[ucTid].SSN       = SSN;
  pClientSTA->atlBAReorderInfo[ucTid].sessionID = sessionID;
  pClientSTA->atlBAReorderInfo[ucTid].pendingFramesCount = 0;
  pClientSTA->atlBAReorderInfo[ucTid].LastSN = SSN;
  TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
             "WLAN TL:New BA session added for STA: %d TID: %d",
             ucSTAId, ucTid));

  if(!VOS_IS_STATUS_SUCCESS(
     vos_lock_release(&reorderInfo->reorderLock)))
  {
    TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
           "%s: Release LOCK Fail", __func__));
    return VOS_STATUS_E_FAULT;
  }
  return VOS_STATUS_SUCCESS;
}/* WLANTL_BaSessionAdd */

/*==========================================================================

  FUNCTION    WLANTL_BaSessionDel

  DESCRIPTION 
    HAL notifies TL when a new Block Ack session is being deleted. 
    
  DEPENDENCIES 
    
  PARAMETERS 

    IN
    pvosGCtx:       pointer to the global vos context; a handle to TL's 
                    control block can be extracted from its context 
    ucSTAId:        identifier of the station for which requested the BA 
                    session
    ucTid:          Tspec ID for the new BA session
   
  RETURN VALUE
    The result code associated with performing the operation  

    VOS_STATUS_E_INVAL:      Input parameters are invalid 
    VOS_STATUS_E_FAULT:      Station ID is outside array boundaries or pointer 
                             to TL cb is NULL ; access would cause a page fault  
    VOS_STATUS_E_EXISTS:     Station was not registered or BA session already
                             exists
    VOS_STATUS_E_NOSUPPORT:  Not yet supported
    
  SIDE EFFECTS 
  
============================================================================*/
VOS_STATUS
WLANTL_BaSessionDel 
( 
  v_PVOID_t      pvosGCtx, 
  v_U16_t        ucSTAId,
  v_U8_t         ucTid
)
{
  WLANTL_CbType*          pTLCb       = NULL;
  WLANTL_STAClientType    *pClientSTA   = NULL;
  vos_pkt_t*              vosDataBuff = NULL;
  VOS_STATUS              vosStatus   = VOS_STATUS_E_FAILURE;
  VOS_STATUS              lockStatus = VOS_STATUS_E_FAILURE;  
  WLANTL_BAReorderType*   reOrderInfo = NULL;
  WLANTL_RxMetaInfoType   wRxMetaInfo;
  v_U32_t                 fwIdx = 0;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

   /*------------------------------------------------------------------------
    Sanity check
   ------------------------------------------------------------------------*/
  if ( WLANTL_TID_INVALID(ucTid))
  {
    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
              "WLAN TL:Invalid parameter sent on WLANTL_BaSessionDel");
    return VOS_STATUS_E_INVAL;
  }

   if ( WLANTL_STA_ID_INVALID( ucSTAId ) )
  {
    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
              "WLAN TL:Invalid station id requested on WLANTL_BaSessionDel");
    return VOS_STATUS_E_FAULT;
  }

  /*------------------------------------------------------------------------
    Extract TL control block and check existance
   ------------------------------------------------------------------------*/
  pTLCb = VOS_GET_TL_CB(pvosGCtx);
  if ( NULL == pTLCb ) 
  {
    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
          "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_BaSessionDel");
    return VOS_STATUS_E_FAULT;
  }

  pClientSTA = pTLCb->atlSTAClients[ucSTAId];

  if ( NULL == pClientSTA )
  {
    TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
        "WLAN TL:Client Memory was not allocated on %s", __func__));
    return VOS_STATUS_E_FAILURE;
  }

  if (( 0 == pClientSTA->ucExists ) &&
      ( 0 == pClientSTA->atlBAReorderInfo[ucTid].ucExists ))
  {
    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,
          "WLAN TL:Station was not yet registered on WLANTL_BaSessionDel");
    return VOS_STATUS_E_EXISTS;
  }
  else if(( 0 == pClientSTA->ucExists ) &&
          ( 0 != pClientSTA->atlBAReorderInfo[ucTid].ucExists ))
  {
    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,
          "STA was deleted but BA info is still there, just remove BA info");

    reOrderInfo = &pClientSTA->atlBAReorderInfo[ucTid];
    reOrderInfo->reorderBuffer->isAvailable = VOS_TRUE;
    memset(&reOrderInfo->reorderBuffer->arrayBuffer[0],
           0,
           WLANTL_MAX_WINSIZE * sizeof(v_PVOID_t));
    vos_timer_destroy(&reOrderInfo->agingTimer);
    memset(reOrderInfo, 0, sizeof(WLANTL_BAReorderType));

    return VOS_STATUS_SUCCESS;
  }

  /*------------------------------------------------------------------------
    Verify that BA session was added
   ------------------------------------------------------------------------*/
  if ( 0 == pClientSTA->atlBAReorderInfo[ucTid].ucExists )
  {
    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
               "WLAN TL:BA session does not exists on WLANTL_BaSessionDel");
    return VOS_STATUS_E_EXISTS;
  }

  
  /*------------------------------------------------------------------------
     Send all pending packets to HDD 
   ------------------------------------------------------------------------*/
  reOrderInfo = &pClientSTA->atlBAReorderInfo[ucTid];

  /*------------------------------------------------------------------------
     Invalidate reorder info here. This ensures that no packets are 
     bufferd after  reorder buffer is cleaned.
   */
  lockStatus = vos_lock_acquire(&reOrderInfo->reorderLock);
  if(!VOS_IS_STATUS_SUCCESS(lockStatus))
  {
    TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
          "Unable to acquire reorder vos lock in %s", __func__));
    return lockStatus;
  }
  pClientSTA->atlBAReorderInfo[ucTid].ucExists = 0;

  TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
               "WLAN TL: Fwd all packets to HDD on WLANTL_BaSessionDel"));

  if(0 == reOrderInfo->ucCIndex)
  {
     fwIdx = reOrderInfo->winSize;
  }
  else
  {
     fwIdx = reOrderInfo->ucCIndex - 1;
  }

  if(0 != reOrderInfo->pendingFramesCount)
  {
    vosStatus = WLANTL_ChainFrontPkts(fwIdx,
                                      WLANTL_OPCODE_FWDALL_DROPCUR,
                                      &vosDataBuff, reOrderInfo, pTLCb);
  }

  if ((VOS_STATUS_SUCCESS == vosStatus) && (NULL != vosDataBuff))
  {
    TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
             "WLAN TL: Chaining was successful sending all pkts to HDD : %x",
              vosDataBuff ));

    /* Do replay check before giving packets to upper layer
       replay check code : check whether replay check is needed or not */
    if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid) {
      WLANTL_ReorderReplayCheck(pClientSTA, &vosDataBuff, ucTid);
    }

    if ( WLAN_STA_SOFTAP == pClientSTA->wSTADesc.wSTAType )
    {
      WLANTL_FwdPktToHDD( pvosGCtx, vosDataBuff, ucSTAId);
    }
    else
    {
      wRxMetaInfo.ucUP = ucTid;
      pClientSTA->pfnSTARx( pvosGCtx, vosDataBuff, ucSTAId,
                                            &wRxMetaInfo );
    }
  }

  /*------------------------------------------------------------------------
     Delete reordering timer
   ------------------------------------------------------------------------*/
  if(VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(&reOrderInfo->agingTimer))
  {
    vosStatus = vos_timer_stop(&reOrderInfo->agingTimer);
    if(!VOS_IS_STATUS_SUCCESS(vosStatus))
    { 
       TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer stop fail: %d", vosStatus));
       vos_lock_release(&reOrderInfo->reorderLock);
       return vosStatus;
    }
  }

  if(VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&reOrderInfo->agingTimer))
  {
     vosStatus = vos_timer_destroy(&reOrderInfo->agingTimer);
  }
  else
  {
    TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer is not stopped state current state is %d",
                vos_timer_getCurrentState(&reOrderInfo->agingTimer)));
  }
  if ( VOS_STATUS_SUCCESS != vosStatus ) 
  {
    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,
              "WLAN TL:Failed to destroy reorder timer on WLANTL_BaSessionAdd");
  }

  /*------------------------------------------------------------------------
    Delete session 
   ------------------------------------------------------------------------*/
  pClientSTA->atlBAReorderInfo[ucTid].usCount  = 0;
  pClientSTA->atlBAReorderInfo[ucTid].ucCIndex = 0;
  reOrderInfo->winSize   = 0;
  reOrderInfo->SSN       = 0;
  reOrderInfo->sessionID = 0;
  reOrderInfo->LastSN = 0;

  MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_BA_SESSION_DEL,
                      ucSTAId, ucTid ));

  TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH,
             "WLAN TL: BA session deleted for STA: %d TID: %d",
             ucSTAId, ucTid));

  memset((v_U8_t *)(&reOrderInfo->reorderBuffer->arrayBuffer[0]),
                    0,
                    WLANTL_MAX_WINSIZE * sizeof(v_PVOID_t));
  reOrderInfo->reorderBuffer->isAvailable = VOS_TRUE;

  vos_lock_release(&reOrderInfo->reorderLock);
  return VOS_STATUS_SUCCESS;
}/* WLANTL_BaSessionDel */


/*----------------------------------------------------------------------------
    INTERACTION WITH TL main module
 ---------------------------------------------------------------------------*/

/*==========================================================================
      AMSDU sub-frame processing module
  ==========================================================================*/
/*==========================================================================
  FUNCTION    WLANTL_AMSDUProcess

  DESCRIPTION 
    Process A-MSDU sub-frame. Start of chain if marked as first frame. 
    Linked at the end of the existing AMSDU chain. 

  DEPENDENCIES 
         
  PARAMETERS 

   IN/OUT:
   vosDataBuff: vos packet for the received data
                 outgoing contains the root of the chain for the rx 
                 aggregated MSDU if the frame is marked as last; otherwise 
                 NULL
   
   IN
   pvosGCtx:     pointer to the global vos context; a handle to TL's 
                 control block can be extracted from its context 
   pvBDHeader:   pointer to the BD header
   ucSTAId:      Station ID 
   ucMPDUHLen:   length of the MPDU header
   usMPDULen:    length of the MPDU 
      
  RETURN VALUE
    The result code associated with performing the operation  

    VOS_STATUS_E_INVAL:   invalid input parameters
    VOS_STATUS_E_FAULT:   pointer to TL cb is NULL ; access would cause a 
                          page fault  
    VOS_STATUS_SUCCESS:   Everything is good :)

  Other values can be returned as a result of a function call, please check 
  corresponding API for more info. 
  
  SIDE EFFECTS 
  
============================================================================*/
VOS_STATUS
WLANTL_AMSDUProcess
( 
  v_PVOID_t   pvosGCtx,
  vos_pkt_t** ppVosDataBuff, 
  v_PVOID_t   pvBDHeader,
  v_U8_t      ucSTAId,
  v_U8_t      ucMPDUHLen,
  v_U16_t     usMPDULen
)
{
  v_U8_t          ucFsf; /* First AMSDU sub frame */
  v_U8_t          ucAef; /* Error in AMSDU sub frame */
  WLANTL_CbType*  pTLCb = NULL; 
  WLANTL_STAClientType *pClientSTA = NULL;
  v_U8_t          MPDUHeaderAMSDUHeader[WLANTL_MPDU_HEADER_LEN + TL_AMSDU_SUBFRM_HEADER_LEN];
  v_U16_t         subFrameLength;
  v_U16_t         paddingSize;
  VOS_STATUS      vStatus = VOS_STATUS_SUCCESS;
  v_U16_t         MPDUDataOffset;
  v_U16_t         packetLength; 
  static v_U32_t  numAMSDUFrames;
  vos_pkt_t*      vosDataBuff;
  uint8_t llc_hdr[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};

  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  /*------------------------------------------------------------------------
    Sanity check
   ------------------------------------------------------------------------*/
  if (( NULL == ppVosDataBuff ) || (NULL == *ppVosDataBuff) || ( NULL == pvBDHeader ) || 
      ( WLANTL_STA_ID_INVALID(ucSTAId)) )
  {
    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
               "WLAN TL:Invalid parameter sent on WLANTL_AMSDUProcess");
    return VOS_STATUS_E_INVAL;
  }

  vosDataBuff = *ppVosDataBuff;
  /*------------------------------------------------------------------------
    Extract TL control block 
   ------------------------------------------------------------------------*/
  pTLCb = VOS_GET_TL_CB(pvosGCtx);
  if ( NULL == pTLCb ) 
  {
    VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
         "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_AMSDUProcess");
    return VOS_STATUS_E_FAULT;
  }

  pClientSTA = pTLCb->atlSTAClients[ucSTAId];

  if ( NULL == pClientSTA )
  {
      TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
          "WLAN TL:Client Memory was not allocated on %s", __func__));
      return VOS_STATUS_E_FAILURE;
  }

  /*------------------------------------------------------------------------
    Check frame
   ------------------------------------------------------------------------*/
  ucAef =  (v_U8_t)WDA_GET_RX_AEF( pvBDHeader );
  ucFsf =  (v_U8_t)WDA_GET_RX_ESF( pvBDHeader );
  /* On Prima, MPDU data offset not includes BD header size */
  MPDUDataOffset = (v_U16_t)WDA_GET_RX_MPDU_DATA_OFFSET(pvBDHeader);

  if ( WLANHAL_RX_BD_AEF_SET == ucAef ) 
  {
    TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
               "WLAN TL:Error in AMSDU - dropping entire chain"));

    vos_pkt_return_packet(vosDataBuff);
    *ppVosDataBuff = NULL;
    return VOS_STATUS_SUCCESS; /*Not a transport error*/ 
  }

  if((0 != ucMPDUHLen) && ucFsf)
  {
    /*
     * This is first AMSDU sub frame
     * AMSDU Header should be removed
     * MPDU header should be stored into context to recover next frames
     */
    /* Assumed here Address4 is never part of AMSDU received at TL */
    if (ucMPDUHLen > WLANTL_MPDU_HEADER_LEN)
    {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"MPDU Header length (%d) is greater",ucMPDUHLen));
      vos_pkt_return_packet(vosDataBuff);
      *ppVosDataBuff = NULL;
      return VOS_STATUS_SUCCESS; /*Not a transport error*/
    }

    vStatus = vos_pkt_pop_head(vosDataBuff, MPDUHeaderAMSDUHeader, ucMPDUHLen + TL_AMSDU_SUBFRM_HEADER_LEN);
    if(!VOS_IS_STATUS_SUCCESS(vStatus))
    {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Pop MPDU AMSDU Header fail"));
      vos_pkt_return_packet(vosDataBuff);
      *ppVosDataBuff = NULL;
      return VOS_STATUS_SUCCESS; /*Not a transport error*/ 
    }
    pClientSTA->ucMPDUHeaderLen = ucMPDUHLen;
    vos_mem_copy(pClientSTA->aucMPDUHeader, MPDUHeaderAMSDUHeader, ucMPDUHLen);
    /* AMSDU header stored to handle garbage data within next frame */
    pClientSTA->drop_amsdu = false;
  }
  else
  {
    /* Trim garbage, size is frameLoop */
    if(MPDUDataOffset > 0)
    {
      vStatus = vos_pkt_trim_head(vosDataBuff, MPDUDataOffset);
    }
    if(!VOS_IS_STATUS_SUCCESS(vStatus))
    {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Trim Garbage Data fail"));
      vos_pkt_return_packet(vosDataBuff);
      *ppVosDataBuff = NULL;
      return VOS_STATUS_SUCCESS; /*Not a transport error*/ 
    }

    /* Remove MPDU header and AMSDU header from the packet */
    vStatus = vos_pkt_pop_head(vosDataBuff, MPDUHeaderAMSDUHeader, ucMPDUHLen + TL_AMSDU_SUBFRM_HEADER_LEN);
    if(!VOS_IS_STATUS_SUCCESS(vStatus))
    {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"AMSDU Header Pop fail"));
      vos_pkt_return_packet(vosDataBuff);
      *ppVosDataBuff = NULL;
      return VOS_STATUS_SUCCESS; /*Not a transport error*/ 
    }
  } /* End of henalding not first sub frame specific */

  /* Put in MPDU header into all the frame */
  vStatus = vos_pkt_push_head(vosDataBuff, pClientSTA->aucMPDUHeader, pClientSTA->ucMPDUHeaderLen);
  if(!VOS_IS_STATUS_SUCCESS(vStatus))
  {
    TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"MPDU Header Push back fail"));
    vos_pkt_return_packet(vosDataBuff);
    *ppVosDataBuff = NULL;
    return VOS_STATUS_SUCCESS; /*Not a transport error*/ 
  }

  if (pClientSTA->drop_amsdu) {
         vos_pkt_return_packet(vosDataBuff);
         *ppVosDataBuff = NULL;
         return VOS_STATUS_SUCCESS;
  }

  /**
   * Set drop_amsdu flag and drop AMSDU subframe if AMSDU subframe DA
   * is equal to LLC header
   */
   if (vos_mem_compare2(MPDUHeaderAMSDUHeader + ucMPDUHLen, llc_hdr, 6) == 0) {
      pClientSTA->drop_amsdu = true;
      vos_pkt_return_packet(vosDataBuff);
      *ppVosDataBuff = NULL;
      VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
                "WLAN TL:Invalid AMSDU frame - dropping");
      return VOS_STATUS_SUCCESS;
   }

  /* Find Padding and remove */
  vos_mem_copy(&subFrameLength, MPDUHeaderAMSDUHeader + ucMPDUHLen + WLANTL_AMSDU_SUBFRAME_LEN_OFFSET, sizeof(v_U16_t));
  subFrameLength = vos_be16_to_cpu(subFrameLength);
  paddingSize = usMPDULen - ucMPDUHLen - subFrameLength - TL_AMSDU_SUBFRM_HEADER_LEN;

  vos_pkt_get_packet_length(vosDataBuff, &packetLength);
  if((paddingSize > 0) && (paddingSize < packetLength))
  {
    /* There is padding bits, remove it */
    vos_pkt_trim_tail(vosDataBuff, paddingSize);
  }
  else if(0 == paddingSize)
  {
    /* No Padding bits */
    /* Do Nothing */
  }
  else
  {
    /* Padding size is larger than Frame size, Actually negative */
    /* Not a valid case, not a valid frame, drop it */
    TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Padding Size is negative, no possible %d", paddingSize));
    vos_pkt_return_packet(vosDataBuff);
    *ppVosDataBuff = NULL;
    return VOS_STATUS_SUCCESS; /*Not a transport error*/ 
  }

  numAMSDUFrames++;
  if(0 == (numAMSDUFrames % 5000))
  {
    TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"%u AMSDU frames arrived", numAMSDUFrames));
  }
  return VOS_STATUS_SUCCESS;
}/* WLANTL_AMSDUProcess */

/*==========================================================================
      Re-ordering module
  ==========================================================================*/

/*==========================================================================
  FUNCTION    WLANTL_MSDUReorder

  DESCRIPTION 
    MSDU reordering 

  DEPENDENCIES 
         
  PARAMETERS 

   IN
   
   vosDataBuff: vos packet for the received data
   pvBDHeader: pointer to the BD header
   ucSTAId:    Station ID 
      
  RETURN VALUE
    The result code associated with performing the operation  

    VOS_STATUS_SUCCESS:   Everything is good :)

  SIDE EFFECTS 
  
============================================================================*/
VOS_STATUS WLANTL_MSDUReorder
( 
   WLANTL_CbType    *pTLCb,
   vos_pkt_t        **vosDataBuff, 
   v_PVOID_t        pvBDHeader,
   v_U8_t           ucSTAId,
   v_U8_t           ucTid
)
{
   WLANTL_BAReorderType *currentReorderInfo;
   WLANTL_STAClientType *pClientSTA = NULL;
   vos_pkt_t            *vosPktIdx;
   v_U8_t               ucOpCode; 
   v_U8_t               ucSlotIdx;
   v_U8_t               ucFwdIdx;
   v_U16_t              CSN;
   v_U32_t              ucCIndexOrig;
   VOS_STATUS           status      = VOS_STATUS_SUCCESS;
   VOS_STATUS           lockStatus  = VOS_STATUS_SUCCESS; 
   VOS_STATUS           timerStatus = VOS_STATUS_SUCCESS; 
   VOS_TIMER_STATE      timerState;
   v_SIZE_t             rxFree;
   v_U64_t              ullreplayCounter = 0; /* 48-bit replay counter */
   v_U8_t               ac;
   v_U16_t              reorderTime;
   if((NULL == pTLCb) || (*vosDataBuff == NULL))
   {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid ARG pTLCb 0x%pK, vosDataBuff 0x%pK",
                  pTLCb, *vosDataBuff));
      return VOS_STATUS_E_INVAL;
   }

   pClientSTA = pTLCb->atlSTAClients[ucSTAId];

   if ( NULL == pClientSTA )
   {
       TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
           "WLAN TL:Client Memory was not allocated on %s", __func__));
       return VOS_STATUS_E_FAILURE;
   }

   currentReorderInfo = &pClientSTA->atlBAReorderInfo[ucTid];

   lockStatus = vos_lock_acquire(&currentReorderInfo->reorderLock);
   if(!VOS_IS_STATUS_SUCCESS(lockStatus))
   {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
      return lockStatus;
   }

   if( pClientSTA->atlBAReorderInfo[ucTid].ucExists == 0 )
   {
     vos_lock_release(&currentReorderInfo->reorderLock);
     return VOS_STATUS_E_INVAL;
   }
   ucOpCode  = (v_U8_t)WDA_GET_RX_REORDER_OPCODE(pvBDHeader);
   ucSlotIdx = (v_U8_t)WDA_GET_RX_REORDER_SLOT_IDX(pvBDHeader);
   ucFwdIdx  = (v_U8_t)WDA_GET_RX_REORDER_FWD_IDX(pvBDHeader);
   CSN       = (v_U16_t)WDA_GET_RX_REORDER_CUR_PKT_SEQ_NO(pvBDHeader);

   /* Replay check code : check whether replay check is needed or not */
   if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid)
   {
           /* Getting 48-bit replay counter from the RX BD */
           ullreplayCounter = WDA_DS_GetReplayCounter(pvBDHeader);
   }

#ifdef WLANTL_REORDER_DEBUG_MSG_ENABLE
   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));
#else
   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));
#endif

   // remember our current CI so that later we can tell if it advanced
   ucCIndexOrig = currentReorderInfo->ucCIndex;

   switch(ucOpCode)
   {
      case WLANTL_OPCODE_INVALID:
         /* Do nothing just pass through current frame */
         break;

      case WLANTL_OPCODE_QCUR_FWDBUF:
         if ((currentReorderInfo->LastSN > CSN) &&
              !(currentReorderInfo->set_data_filter))
         {
             if ((currentReorderInfo->LastSN - CSN) < CSN_WRAP_AROUND_THRESHOLD)
             {
                 //this frame is received after BA timer is expired, discard it
                 TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
                          "(QCUR_FWDBUF) dropping old frame, SN=%d LastSN=%d",
                          CSN, currentReorderInfo->LastSN));
                 if (vos_is_arp_pkt((*vosDataBuff)->pSkb, true))
                    vos_update_arp_rx_drop_reorder();

                 status = vos_pkt_return_packet(*vosDataBuff);
                 if (!VOS_IS_STATUS_SUCCESS(status))
                 {
                      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
                             "(QCUR_FWDBUF) drop old frame fail %d", status));
                 }
                 *vosDataBuff = NULL;
                 lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
                 if (!VOS_IS_STATUS_SUCCESS(lockStatus))
                 {
                     TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
                            "WLANTL_MSDUReorder, Release LOCK Fail"));
                     return lockStatus;
                 }
                 return status;
             }
         }
         currentReorderInfo->LastSN = CSN;
         if(0 == currentReorderInfo->pendingFramesCount)
         {
            //This frame will be fwd'ed to the OS. The next slot is the one we expect next
            currentReorderInfo->ucCIndex = (ucSlotIdx + 1) % currentReorderInfo->winSize;
            lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
            if(!VOS_IS_STATUS_SUCCESS(lockStatus))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
               return lockStatus;
            }
            return status;
         }
         status = WLANTL_QueueCurrent(currentReorderInfo,
                                      vosDataBuff,
                                      ucSlotIdx);
         if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid)
         {
             WLANTL_FillReplayCounter(currentReorderInfo,
                               ullreplayCounter, ucSlotIdx);
         }
         if(VOS_STATUS_E_RESOURCES == status)
         {
            MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_QUEUE_CURRENT,
                    currentReorderInfo->sessionID , ucOpCode ));

            /* This is the case slot index is already cycle one route, route all the frames Qed */
            vosPktIdx = NULL;
            status = WLANTL_ChainFrontPkts(ucFwdIdx,
                                           WLANTL_OPCODE_FWDALL_QCUR, 
                                           &vosPktIdx,
                                           currentReorderInfo,
                                           pTLCb);
            if(!VOS_IS_STATUS_SUCCESS(status))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status));
               lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
               if(!VOS_IS_STATUS_SUCCESS(lockStatus))
               {
                  TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
                  return lockStatus;
               }
               return status;
            }
            status = vos_pkt_chain_packet(vosPktIdx, *vosDataBuff, 1);
            *vosDataBuff = vosPktIdx;
            currentReorderInfo->pendingFramesCount = 0;
         }
         else
         {
            vosPktIdx = NULL;
            status = WLANTL_ChainFrontPkts(ucFwdIdx,
                                           WLANTL_OPCODE_QCUR_FWDBUF, 
                                           &vosPktIdx,
                                           currentReorderInfo,
                                           pTLCb);
            if(!VOS_IS_STATUS_SUCCESS(status))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status));
               lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
               if(!VOS_IS_STATUS_SUCCESS(lockStatus))
               {
                  TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
                  return lockStatus;
               }
               return status;
            }
            currentReorderInfo->ucCIndex = ucFwdIdx;
            *vosDataBuff = vosPktIdx;
         }
         break;

      case WLANTL_OPCODE_FWDBUF_FWDCUR:
         vosPktIdx = NULL;
         status = WLANTL_ChainFrontPkts(ucFwdIdx,
                                        WLANTL_OPCODE_FWDBUF_FWDCUR, 
                                        &vosPktIdx,
                                        currentReorderInfo,
                                        pTLCb);
         if(!VOS_IS_STATUS_SUCCESS(status))
         {
            TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status));
            lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
            if(!VOS_IS_STATUS_SUCCESS(lockStatus))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
               return lockStatus;
            }
            return status;
         }

         if(NULL == vosPktIdx)
         {
            TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Nothing to chain, just send current frame"));
         }
         else
         {
            status = vos_pkt_chain_packet(vosPktIdx, *vosDataBuff, 1);
            if(!VOS_IS_STATUS_SUCCESS(status))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain with CUR frame fail %d",
                           status));
               lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
               if(!VOS_IS_STATUS_SUCCESS(lockStatus))
               {
                  TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
                  return lockStatus;
               }
               return status;
            }
            *vosDataBuff = vosPktIdx;
         }
         //ucFwdIdx is the slot this packet supposes to take but there is a hole there
         //It looks that the chip will put the next packet into the slot ucFwdIdx.
         currentReorderInfo->ucCIndex = ucFwdIdx;
         break;

      case WLANTL_OPCODE_QCUR:
        if ((currentReorderInfo->LastSN > CSN) &&
            !(currentReorderInfo->set_data_filter))
        {
            if ((currentReorderInfo->LastSN - CSN) < CSN_WRAP_AROUND_THRESHOLD)
            {
                // this frame is received after BA timer is expired, so disard it
                TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,
                                "(QCUR) dropping old frame, SN=%d LastSN=%d",
                                CSN, currentReorderInfo->LastSN));
                status = vos_pkt_return_packet(*vosDataBuff);
                if (!VOS_IS_STATUS_SUCCESS(status))
                {
                    TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
                               "*** (QCUR) drop old frame fail %d", status));
                }
                *vosDataBuff = NULL;
                lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
                if (!VOS_IS_STATUS_SUCCESS(lockStatus))
                {
                    TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
                                   "WLANTL_MSDUReorder, Release LOCK Fail"));
                    return lockStatus;
                }
                return status;
            }
        }

         status = WLANTL_QueueCurrent(currentReorderInfo,
                                      vosDataBuff,
                                      ucSlotIdx);
           if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid)
           {
               WLANTL_FillReplayCounter(currentReorderInfo,
                                 ullreplayCounter, ucSlotIdx);
           }
         if(VOS_STATUS_E_RESOURCES == status)
         {
            MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_QUEUE_CURRENT,
                                  currentReorderInfo->sessionID , ucOpCode ));

            /* This is the case slot index is already cycle one route, route all the frames Qed */
            vosPktIdx = NULL;
            status = WLANTL_ChainFrontPkts(ucFwdIdx,
                                           WLANTL_OPCODE_FWDALL_QCUR, 
                                           &vosPktIdx,
                                           currentReorderInfo,
                                           pTLCb);
            if(!VOS_IS_STATUS_SUCCESS(status))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status));
               lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
               if(!VOS_IS_STATUS_SUCCESS(lockStatus))
               {
                  TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
                  return lockStatus;
               }
               return status;
            }
            status = vos_pkt_chain_packet(vosPktIdx, *vosDataBuff, 1);
            *vosDataBuff = vosPktIdx;
            currentReorderInfo->pendingFramesCount = 0;
         }
         else
         {
            /* Since current Frame is Qed, no frame will be routed */
            *vosDataBuff = NULL; 
         }
         break;

      case WLANTL_OPCODE_FWDBUF_QUEUECUR:
         vosPktIdx = NULL;
         status = WLANTL_ChainFrontPkts(ucFwdIdx,
                                        WLANTL_OPCODE_FWDBUF_QUEUECUR, 
                                        &vosPktIdx,
                                        currentReorderInfo,
                                        pTLCb);
         if(!VOS_IS_STATUS_SUCCESS(status))
         {
            TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make chain with buffered frame fail %d",
                        status));
            lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
            if(!VOS_IS_STATUS_SUCCESS(lockStatus))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
               return lockStatus;
            }
            return status;
         }
         //This opCode means the window shift. Enforce the current Index
         currentReorderInfo->ucCIndex = ucFwdIdx;

         status = WLANTL_QueueCurrent(currentReorderInfo,
                                      vosDataBuff,
                                      ucSlotIdx);
           if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid)
           {
               WLANTL_FillReplayCounter(currentReorderInfo,
                                 ullreplayCounter, ucSlotIdx);
           }
         if(VOS_STATUS_E_RESOURCES == status)
         {
            MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_QUEUE_CURRENT,
                                   currentReorderInfo->sessionID , ucOpCode ));

            vos_pkt_return_packet(vosPktIdx); 
            /* This is the case slot index is already cycle one route, route all the frames Qed */
            vosPktIdx = NULL;
            status = WLANTL_ChainFrontPkts(ucFwdIdx,
                                           WLANTL_OPCODE_FWDALL_QCUR, 
                                           &vosPktIdx,
                                           currentReorderInfo,
                                           pTLCb);
            if(!VOS_IS_STATUS_SUCCESS(status))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status));
               lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
               if(!VOS_IS_STATUS_SUCCESS(lockStatus))
               {
                  TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
                  return lockStatus;
               }
               return status;
            }
            status = vos_pkt_chain_packet(vosPktIdx, *vosDataBuff, 1);
            *vosDataBuff = vosPktIdx;
            currentReorderInfo->pendingFramesCount = 0;
         }
         *vosDataBuff = vosPktIdx;
         break;

      case WLANTL_OPCODE_FWDBUF_DROPCUR:
         vosPktIdx = NULL;
         status = WLANTL_ChainFrontPkts(ucFwdIdx,
                                        WLANTL_OPCODE_FWDBUF_DROPCUR, 
                                        &vosPktIdx,
                                        currentReorderInfo,
                                        pTLCb);
         if(!VOS_IS_STATUS_SUCCESS(status))
         {
            TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make chain with buffered frame fail %d",
                        status));
            lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
            if(!VOS_IS_STATUS_SUCCESS(lockStatus))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
               return lockStatus;
            }
            return status;
         }

         //Since BAR frame received, set the index to the right location
         currentReorderInfo->ucCIndex = ucFwdIdx;

         /* Current frame has to be dropped, BAR frame */
         status = vos_pkt_return_packet(*vosDataBuff);
         if(!VOS_IS_STATUS_SUCCESS(status))
         {
            TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Drop BAR frame fail %d",
                        status));
            lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
            if(!VOS_IS_STATUS_SUCCESS(lockStatus))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
               return lockStatus;
            }
            return status;
         }
         *vosDataBuff = vosPktIdx;
         break;
 
      case WLANTL_OPCODE_FWDALL_DROPCUR:
         vosPktIdx = NULL;
         status = WLANTL_ChainFrontPkts(ucFwdIdx,
                                        WLANTL_OPCODE_FWDALL_DROPCUR, 
                                        &vosPktIdx,
                                        currentReorderInfo,
                                        pTLCb);
         if(!VOS_IS_STATUS_SUCCESS(status))
         {
            TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make chain with buffered frame fail %d",
                        status));
            lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
            if(!VOS_IS_STATUS_SUCCESS(lockStatus))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
               return lockStatus;
            }
            return status;
         }

         //Since BAR frame received and beyond cur window, set the index to the right location
         currentReorderInfo->ucCIndex = 0;

         status = vos_pkt_return_packet(*vosDataBuff);
         if(!VOS_IS_STATUS_SUCCESS(status))
         {
            TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Drop BAR frame fail %d",
                        status));
            lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
            if(!VOS_IS_STATUS_SUCCESS(lockStatus))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
               return lockStatus;
            }
            return status;
         }

         *vosDataBuff = vosPktIdx;
         break;

      case WLANTL_OPCODE_FWDALL_QCUR:
         vosPktIdx = NULL;
         status = WLANTL_ChainFrontPkts(currentReorderInfo->winSize,
                                        WLANTL_OPCODE_FWDALL_DROPCUR, 
                                        &vosPktIdx,
                                        currentReorderInfo,
                                        pTLCb);
         if(!VOS_IS_STATUS_SUCCESS(status))
         {
            TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make chain with buffered frame fail %d",
                        status));
            lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
            if(!VOS_IS_STATUS_SUCCESS(lockStatus))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
               return lockStatus;
            }
            return status;
         }
         status = WLANTL_QueueCurrent(currentReorderInfo,
                                      vosDataBuff,
                                      ucSlotIdx);
           if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid)
           {
               WLANTL_FillReplayCounter(currentReorderInfo,
                                 ullreplayCounter, ucSlotIdx);
           }

         if(VOS_STATUS_E_RESOURCES == status)
         {
             MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_QUEUE_CURRENT,
                                   currentReorderInfo->sessionID , ucOpCode ));
         }

         if(!VOS_IS_STATUS_SUCCESS(status))
         {
            TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Q Current frame fail %d",
                        status));
            lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
            if(!VOS_IS_STATUS_SUCCESS(lockStatus))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
               return lockStatus;
            }
            return status;
         }
         currentReorderInfo->ucCIndex = ucSlotIdx;
         *vosDataBuff = vosPktIdx;
         break;

      case WLANTL_OPCODE_TEARDOWN:
         // do we have a procedure in place to teardown BA?

         // fall through to drop the current packet
      case WLANTL_OPCODE_DROPCUR:
         vos_pkt_return_packet(*vosDataBuff);
         *vosDataBuff = NULL;
         break;

      default:
         break;
   }

   /* Check the available VOS RX buffer size
    * If remaining VOS RX buffer is too few, have to make space
    * Route all the Qed frames upper layer
    * Otherwise, RX thread could be stall */
   vos_pkt_get_available_buffer_pool(VOS_PKT_TYPE_RX_RAW, &rxFree);
   if(WLANTL_BA_MIN_FREE_RX_VOS_BUFFER >= rxFree)
   {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "RX Free: %d", rxFree));
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "RX free buffer count is too low, Pending frame count is %d",
                  currentReorderInfo->pendingFramesCount));
      vosPktIdx = NULL;
      status = WLANTL_ChainFrontPkts(ucFwdIdx,
                                     WLANTL_OPCODE_FWDALL_DROPCUR, 
                                     &vosPktIdx,
                                     currentReorderInfo,
                                     pTLCb);
      if(!VOS_IS_STATUS_SUCCESS(status))
      {
         TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status));
         lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
         if(!VOS_IS_STATUS_SUCCESS(lockStatus))
         {
            TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
            return lockStatus;
         }
         return status;
      }
      if(NULL != *vosDataBuff)
      {
         TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Already something, Chain it"));
         vos_pkt_chain_packet(*vosDataBuff, vosPktIdx, 1);
      }
      else
      {
         *vosDataBuff = vosPktIdx;
      }
      currentReorderInfo->pendingFramesCount = 0;
   }

   /*
    * Current aging timer logic:
    * 1) if we forwarded any packets and the timer is running:
    *    stop the timer
    * 2) if there are packets queued and the timer is not running:
    *    start the timer
    * 3) if timer is running and no pending frame:
    *    stop the timer
    */
   timerState = vos_timer_getCurrentState(&currentReorderInfo->agingTimer);
   if ((VOS_TIMER_STATE_RUNNING == timerState) &&
       ((ucCIndexOrig != currentReorderInfo->ucCIndex) ||
        (0 == currentReorderInfo->pendingFramesCount)))
   {
      TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"HOLE filled, Pending Frames Count %d",
                 currentReorderInfo->pendingFramesCount));

      // we forwarded some packets so stop aging the current hole
      timerStatus = vos_timer_stop(&currentReorderInfo->agingTimer);
      timerState = VOS_TIMER_STATE_STOPPED;

      // ignore the returned status since there is a race condition
      // whereby between the time we called getCurrentState() and the
      // time we call stop() the timer could have fired.  In that case
      // stop() will return an error, but we don't care since the
      // timer has stopped
   }

   if (currentReorderInfo->pendingFramesCount > 0)
   {
      if (VOS_TIMER_STATE_STOPPED == timerState)
      {
         TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"There is a new HOLE, Pending Frames Count %d",
                    currentReorderInfo->pendingFramesCount));
         ac = WLANTL_TID_2_AC[ucTid];
         if (WLANTL_AC_INVALID(ac))
         {
             reorderTime = WLANTL_BA_REORDERING_AGING_TIMER;
             TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid AC %d using default reorder time %d",
                              ac, reorderTime));
         }
         else
         {
             reorderTime = pTLCb->tlConfigInfo.ucReorderAgingTime[ac];
         }
         timerStatus = vos_timer_start(&currentReorderInfo->agingTimer,
                                       reorderTime);
         if(!VOS_IS_STATUS_SUCCESS(timerStatus))
         {
            TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer start fail: %d", timerStatus));
            lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
            if(!VOS_IS_STATUS_SUCCESS(lockStatus))
            {
               TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
               return lockStatus;
            }
            return timerStatus;
         }
      }
      else
      {
         // we didn't forward any packets and the timer was already
         // running so we're still aging the same hole
         TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Still HOLE, Pending Frames Count %d",
                    currentReorderInfo->pendingFramesCount));
      }
   }

   lockStatus = vos_lock_release(&currentReorderInfo->reorderLock);
   if(!VOS_IS_STATUS_SUCCESS(lockStatus))
   {
      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail"));
      return lockStatus;
   }
   return VOS_STATUS_SUCCESS;
}/* WLANTL_MSDUReorder */


/*==========================================================================
     Utility functions 
  ==========================================================================*/

/*==========================================================================

  FUNCTION    WLANTL_QueueCurrent

  DESCRIPTION 
    It will queue a packet at a given slot index in the MSDU reordering list. 
    
  DEPENDENCIES 
    
  PARAMETERS 

    IN
    pwBaReorder:   pointer to the BA reordering session info 
    vosDataBuff:   data buffer to be queued
    ucSlotIndex:   slot index 
   
  RETURN VALUE
    The result code associated with performing the operation  

    VOS_STATUS_SUCCESS:     Everything is OK

    
  SIDE EFFECTS 
  
============================================================================*/
VOS_STATUS WLANTL_QueueCurrent
(
   WLANTL_BAReorderType*  pwBaReorder,
   vos_pkt_t**            vosDataBuff,
   v_U8_t                 ucSlotIndex
)
{
   VOS_STATUS  status = VOS_STATUS_SUCCESS;

   TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"vos Packet has to be Qed 0x%pK",
               *vosDataBuff));
   if(NULL != pwBaReorder->reorderBuffer->arrayBuffer[ucSlotIndex])
   {
      MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_QUEUE_CURRENT,
                      pwBaReorder->sessionID , pwBaReorder->pendingFramesCount ));

      MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_QUEUE_CURRENT,
                                        pwBaReorder->sessionID , ucSlotIndex ));

      TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"One Cycle rounded, lost many frames already, not in Q %d",
                  pwBaReorder->pendingFramesCount));
      return VOS_STATUS_E_RESOURCES;
   }

   pwBaReorder->reorderBuffer->arrayBuffer[ucSlotIndex] =
                                           (v_PVOID_t)(*vosDataBuff);
   pwBaReorder->pendingFramesCount++;
   TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Assigned, Pending Frames %d at slot %d, dataPtr 0x%x",
               pwBaReorder->pendingFramesCount,
               ucSlotIndex,
               pwBaReorder->reorderBuffer->arrayBuffer[ucSlotIndex]));

   return status;
}/*WLANTL_QueueCurrent*/

/*==========================================================================

  FUNCTION    WLANTL_ChainFrontPkts

  DESCRIPTION 
    It will remove all the packets from the front of a vos list and chain 
    them to a vos pkt . 
    
  DEPENDENCIES 
    
  PARAMETERS 

    IN
    ucCount:       number of packets to extract
    pwBaReorder:   pointer to the BA reordering session info 

    OUT
    vosDataBuff:   data buffer containing the extracted chain of packets
   
  RETURN VALUE
    The result code associated with performing the operation  

    VOS_STATUS_SUCCESS:     Everything is OK

    
  SIDE EFFECTS 
  
============================================================================*/
VOS_STATUS WLANTL_ChainFrontPkts
( 
   v_U32_t                fwdIndex,
   v_U8_t                 opCode,
   vos_pkt_t              **vosDataBuff,
   WLANTL_BAReorderType   *pwBaReorder,
   WLANTL_CbType          *pTLCb
)
{
   VOS_STATUS          status = VOS_STATUS_SUCCESS;
   v_U32_t             idx; 
   v_PVOID_t           currentDataPtr = NULL;
   int                 negDetect;
#ifdef WLANTL_REORDER_DEBUG_MSG_ENABLE
#define WLANTL_OUT_OF_WINDOW_IDX    65
   v_U32_t frameIdx[2] = {0, 0}, ffidx = fwdIndex, idx2 = WLANTL_OUT_OF_WINDOW_IDX;
   int pending = pwBaReorder->pendingFramesCount, start = WLANTL_OUT_OF_WINDOW_IDX, end;
#endif

   if(pwBaReorder->ucCIndex >= fwdIndex)
   {
      fwdIndex += pwBaReorder->winSize;
   }

   if((WLANTL_OPCODE_FWDALL_DROPCUR == opCode) ||
      (WLANTL_OPCODE_FWDALL_QCUR == opCode))
   {
      fwdIndex = pwBaReorder->ucCIndex + pwBaReorder->winSize;
   }

   TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Current Index %d, FWD Index %d, reorderBuffer 0x%pK",
               pwBaReorder->ucCIndex % pwBaReorder->winSize,
               fwdIndex % pwBaReorder->winSize,
               pwBaReorder->reorderBuffer));

   negDetect = pwBaReorder->pendingFramesCount;
   for(idx = pwBaReorder->ucCIndex; idx <= fwdIndex; idx++)
   {
      currentDataPtr = 
      pwBaReorder->reorderBuffer->arrayBuffer[idx % pwBaReorder->winSize];
      if(NULL != currentDataPtr)
      {
#ifdef WLANTL_REORDER_DEBUG_MSG_ENABLE
         idx2 = (idx >=  pwBaReorder->winSize) ? (idx -  pwBaReorder->winSize) : idx;
         frameIdx[idx2 / 32] |= 1 << (idx2 % 32);
         if(start == WLANTL_OUT_OF_WINDOW_IDX) start = idx2;
#endif
         TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"There is buffered frame %d",
                     idx % pwBaReorder->winSize));
         if(NULL == *vosDataBuff)
         {
            *vosDataBuff = (vos_pkt_t *)currentDataPtr;
            TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"This is new head %d",
                        idx % pwBaReorder->winSize));
         }
         else
         {
            TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"There is bufered Just add %d",
                        idx % pwBaReorder->winSize));
            vos_pkt_chain_packet(*vosDataBuff,
                                 (vos_pkt_t *)currentDataPtr,
                                 VOS_TRUE);
         }
         pwBaReorder->reorderBuffer->arrayBuffer[idx  % pwBaReorder->winSize]
                                                                       = NULL;
         pwBaReorder->pendingFramesCount--;
         negDetect--;
         if(negDetect < 0)
         {
            TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"This is not possible, some balance has problem"));
            VOS_ASSERT(0);
            return VOS_STATUS_E_FAULT;
         }
         TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Slot Index %d, set as NULL, Pending Frames %d",
                     idx  % pwBaReorder->winSize,
                     pwBaReorder->pendingFramesCount
                     ));
         pwBaReorder->ucCIndex = (idx + 1) % pwBaReorder->winSize;
      }
      else
      {
         TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Empty Array %d",
                     idx % pwBaReorder->winSize));
      }
      TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Current Index %d, winSize %d",
                  pwBaReorder->ucCIndex,
                  pwBaReorder->winSize
                  ));
   }

#ifdef WLANTL_REORDER_DEBUG_MSG_ENABLE
   end = idx2;

   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",
                     frameIdx[1], frameIdx[0], opCode, ffidx, pwBaReorder->winSize, pending, pending - negDetect, start, end));
#endif

   return status; 
}/*WLANTL_ChainFrontPkts*/
/*==========================================================================
 
  FUNCTION    WLANTL_FillReplayCounter
 
  DESCRIPTION 
    It will fill repaly counter at a given slot index in the MSDU reordering list. 
            
  DEPENDENCIES 
                    
  PARAMETERS 

  IN
      pwBaReorder  :   pointer to the BA reordering session info 
      replayCounter:   replay counter to be filled
      ucSlotIndex  :   slot index 
                                      
  RETURN VALUE
     NONE 

                                                 
  SIDE EFFECTS 
     NONE
        
 ============================================================================*/
void WLANTL_FillReplayCounter
(
   WLANTL_BAReorderType*  pwBaReorder,
   v_U64_t                ullreplayCounter,
   v_U8_t                 ucSlotIndex
)
{

   //BAMSGDEBUG("replay counter to be filled in Qed frames %llu",
               //replayCounter, 0, 0);

   pwBaReorder->reorderBuffer->ullReplayCounter[ucSlotIndex] = ullreplayCounter;
   //BAMSGDEBUG("Assigned, replay counter Pending Frames %d at slot %d, replay counter[0x%llX]\n",
               //pwBaReorder->pendingFramesCount,
               //ucSlotIndex,
               //pwBaReorder->reorderBuffer->ullReplayCounter);
   return;
}/*WLANTL_FillReplayCounter*/

void WLANTL_ReorderReplayCheck(WLANTL_STAClientType *pClientSTA,
                               vos_pkt_t **vosDataBuff, v_U8_t ucTid)
{
   vos_pkt_t *pVosCurPkt;
   vos_pkt_t *pNextVosPkt;
   vos_pkt_t *pVosHeadPkt = NULL;
   vos_pkt_t *pfreeVosPkt = NULL;
   v_U64_t   prevReplayCounter = 0;
   v_BOOL_t status;

   pVosCurPkt = *vosDataBuff;

   do {
      vos_pkt_walk_packet_chain(pVosCurPkt, &pNextVosPkt, VOS_FALSE);
      prevReplayCounter = pClientSTA->ullReplayCounter[ucTid];
      status =  WLANTL_IsReplayPacket(pVosCurPkt->pn_num,
                                      prevReplayCounter);
      if(VOS_FALSE == status) {
         pClientSTA->ullReplayCounter[ucTid] = pVosCurPkt->pn_num;
         pVosHeadPkt = pVosCurPkt;
      } else {
         VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,
                   "%s: Non-AMSDU Drop the replay packet PN: [0x%llX]",
                   __func__, pVosCurPkt->pn_num);
         pClientSTA->ulTotalReplayPacketsDetected++;

         pfreeVosPkt = pVosCurPkt;
         pfreeVosPkt->pNext = NULL;
         vos_pkt_return_packet(pfreeVosPkt);

         if (pVosHeadPkt != NULL) {
            pVosHeadPkt->pNext = pNextVosPkt;
         }
         else {
            *vosDataBuff = pNextVosPkt;
         }
      }

      pVosCurPkt = pNextVosPkt;
   } while (pVosCurPkt);
}
