/*
 * Copyright (c) 2011-2016 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.
 */

/**=========================================================================
 *     
 *       \file  wlan_qct_wdi_dts.c
 *          
 *       \brief  Data Transport Service API 
 *                               
 * WLAN Device Abstraction layer External API for Dataservice
 * DESCRIPTION
 *  This file contains the external API implemntation exposed by the 
 *   wlan device abstarction layer module.
 *
 */


#include "wlan_qct_wdi.h"
#include "wlan_qct_dxe.h"
#include "wlan_qct_wdi_ds.h"
#include "wlan_qct_wdi_ds_i.h"
#include "wlan_qct_wdi_dts.h"
#include "wlan_qct_wdi_dp.h"
#include "wlan_qct_wdi_sta.h"
#include "vos_utils.h"
#include "vos_api.h"


static WDTS_TransportDriverTrype gTransportDriver = {
  WLANDXE_Open, 
  WLANDXE_Start, 
  WLANDXE_ClientRegistration, 
  WLANDXE_TxFrame,
  WLANDXE_CompleteTX,
  WLANDXE_SetPowerState,
  WLANDXE_ChannelDebug,
  WLANDXE_KickDxe,
  WLANDXE_Stop,
  WLANDXE_Close,
  WLANDXE_GetFreeTxDataResNumber,
  WLANDXE_SetupLogTransfer,
  WLANDXE_StartLogTransfer
};

static WDTS_SetPowerStateCbInfoType gSetPowerStateCbInfo;

typedef struct 
{
   uint32 phyRate;   //unit in Mega bits per sec X 10
   uint32 tputRate;  //unit in Mega bits per sec X 10
   uint32 tputBpms;  //unit in Bytes per msec = (tputRateX1024x1024)/(8x10X1000) ~= (tputRate*13)
   uint32 tputBpus;  //unit in Bytes per usec: round off to integral value
}WDTS_RateInfo;

#define WDTS_MAX_NUMBER_OF_RX_PKT 5
#define WDTS_MAX_PAGE_SIZE 4096
#define WDTS_MAX_RXDB_DATA_SIZE 128

#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"

struct WDTS_RxPktInfo
{
    uint8 rx_bd[WDTS_MAX_RXDB_DATA_SIZE];
    void *pFrame_head;
    void *pFrame_tail;
    uint32 pFrame_len;
};

static struct WDTS_PktInfoBuff
{
    struct WDTS_RxPktInfo PktInfo[WDTS_MAX_NUMBER_OF_RX_PKT];
    uint32 current_count;
    uint8 current_position;
}WDTS_Pkt_Data_Buff = { .current_position = 0, .current_count = 0 };

#define WDTS_MAX_RATE_NUM               137
#define WDTS_MAX_11B_RATE_NUM           8
#define MB_PER_SEC_TO_BYTES_PER_MSEC    13

WDTS_RateInfo g11bRateInfo[WDTS_MAX_11B_RATE_NUM]  = {
    //11b rates
    {  10,  9,  117, 8}, //index 0
    {  20,  17, 221, 5}, //index 1
    {  55,  41, 533, 2}, //index 2
    { 110,  68, 884, 1}, //index 3

    //11b short preamble
    {  10,  10,  130, 8}, //index 4
    {  20,  18,  234, 5}, //index 5
    {  55,  44,  572, 2}, //index 6
    { 110,  77, 1001, 1}, //index 7
};

WDTS_RateInfo gRateInfo[WDTS_MAX_RATE_NUM]  = {
    //11b rates
    {  10,  9,  117, 0}, //index 0
    {  20,  17, 221, 0}, //index 1
    {  55,  41, 533, 0}, //index 2
    { 110,  68, 884, 0}, //index 3

    //11b short preamble
    {  10,  10,  130, 0}, //index 4
    {  20,  18,  234, 0}, //index 5
    {  55,  44,  572, 0}, //index 6
    { 110,  77, 1001, 0}, //index 7

    //11ag
    {  60,  50,  650, 1}, //index 8
    {  90,  70,  910, 1}, //index 9
    { 120, 100, 1300, 1}, //index 10
    { 180, 150, 1950, 2}, //index 11
    { 240, 190, 2470, 2}, //index 12
    { 360, 280, 3640, 4}, //index 13
    { 480, 350, 4550, 5}, //index 14
    { 540, 380, 4940, 6}, //index 15

    //11n SIMO
    {  65,  54,  702, 1}, //index 16
    { 130, 108, 1404, 1}, //index 17
    { 195, 161, 2093, 2}, //index 18
    { 260, 217, 2821, 3}, //index 19
    { 390, 326, 4238, 4}, //index 20
    { 520, 435, 5655, 6}, //index 21
    { 585, 492, 6396, 6}, //index 22
    { 650, 548, 7124, 7}, //index 23

    //11n SIMO SGI
    {  72,  59,  767, 1}, //index 24
    { 144, 118, 1534, 2}, //index 25
    { 217, 180, 2340, 2}, //index 26
    { 289, 243, 3159, 3}, //index 27
    { 434, 363, 4719, 5}, //index 28
    { 578, 486, 6318, 6}, //index 29
    { 650, 548, 7124, 7}, //index 30
    { 722, 606, 7878, 8}, //index 31

    //11n GF SIMO
    {  65,  54,  702, 1}, //index 32
    { 130, 108, 1404, 1}, //index 33
    { 195, 161, 2093, 2}, //index 34
    { 260, 217, 2821, 3}, //index 35
    { 390, 326, 4238, 4}, //index 36
    { 520, 435, 5655, 6}, //index 37
    { 585, 492, 6396, 6}, //index 38
    { 650, 548, 7124, 7}, //index 39

    //11n SIMO CB MCS 0 - 7 
    { 135,   110,  1430,  1}, //index 40
    { 270,   223,  2899,  3}, //index 41
    { 405,   337,  4381,  4}, //index 42
    { 540,   454,  5902,  6}, //index 43
    { 810,   679,  8827,  9}, //index 44
    { 1080,  909, 11817, 12}, //index 45
    { 1215, 1022, 13286, 13}, //index 46
    { 1350, 1137, 14781, 15}, //index 47

    //11n SIMO CB SGI MCS 0 - 7
    { 150,   121,  1573,  2}, //index 48
    { 300,   249,  3237,  3}, //index 49
    { 450,   378,  4914,  5}, //index 50
    { 600,   503,  6539,  7}, //index 51
    { 900,   758,  9854,  10}, //index 52
    { 1200, 1010, 13130, 13}, //index 53
    { 1350, 1137, 14781, 15}, //index 54
    { 1500, 1262, 16406, 16}, //index 55

    //11n SIMO GF CB MCS 0 - 7 
    { 135,   110,   1430,  1}, //index 56
    { 270,   223,   2899,  3}, //index 57
    { 405,   337,   4381,  4}, //index 58
    { 540,   454,   5902,  6}, //index 59
    { 810,   679,   8827,  9}, //index 60
    { 1080,  909,  11817, 12}, //index 61
    { 1215, 1022,  13286, 13}, //index 62
    { 1350, 1137,  14781, 15}, //index 63

    //11AC  
    { 1350,  675,  8775,  9}, //reserved 64
    { 1350,  675,  8775,  9}, //reserved 65
    {   65,   45,   585,  1}, //index 66
    {  130,   91,  1183,  1}, //index 67
    {  195,  136,  1768,  2}, //index 68
    {  260,  182,  2366,  2}, //index 69
    {  390,  273,  3549,  4}, //index 70
    {  520,  364,  4732,  5}, //index 71
    {  585,  409,  5317,  5}, //index 72
    {  650,  455,  5915,  6}, //index 73
    {  780,  546,  7098,  7}, //index 74
    { 1350,  675,  8775,  9}, //reserved 75
    { 1350,  675,  8775,  9}, //reserved 76
    { 1350,  675,  8775,  9}, //reserved 77
    { 1350,  675,  8775,  9}, //index 78
    { 1350,  675,  8775,  9}, //index 79
    { 1350,  675,  8775,  9}, //index 80
    { 1350,  675,  8775,  9}, //index 81
    { 1350,  675,  8775,  9}, //index 82
    { 1350,  675,  8775,  9}, //index 83
    {  655,  458,  5954,  6}, //index 84
    {  722,  505,  6565,  7}, //index 85
    {  866,  606,  7878,  8}, //index 86
    { 1350,  675,  8775,  9}, //reserved 87
    { 1350,  675,  8775,  9}, //reserved 88
    { 1350,  675,  8775,  9}, //reserved 89
    {  135,   94,  1222,  1}, //index 90
    {  270,  189,  2457,  2}, //index 91
    {  405,  283,  3679,  4}, //index 92
    {  540,  378,  4914,  5}, //index 93
    {  810,  567,  7371,  7}, //index 94
    { 1080,  756,  9828, 10}, //index 95
    { 1215,  850, 11050, 11}, //index 96
    { 1350,  675,  8775,  9}, //index 97
    { 1350,  675,  8775,  9}, //index 98
    { 1620,  810, 10530, 11}, //index 99
    { 1800,  900, 11700, 12}, //index 100
    { 1350,  675,  8775,  9}, //reserved 101
    { 1350,  675,  8775,  9}, //index 102
    { 1350,  675,  8775,  9}, //index 103
    { 1350,  675,  8775,  9}, //index 104
    { 1350,  675,  8775,  9}, //index 105
    { 1350,  675,  8775,  9}, //index 106
    { 1200,  840, 10920, 11}, //index 107
    { 1350,  675,  8775,  9}, //index 108
    { 1500,  750,  9750, 10}, //index 109
    { 1350,  675,  8775,  9}, //index 110
    { 1800,  900, 11700, 12}, //index 111
    { 2000, 1000, 13000, 13}, //index 112
    { 1350,  675,  8775,  9}, //index 113
    {  292,  204,  2652,  3}, //index 114
    {  585,  409,  5317,  5}, //index 115
    {  877,  613,  7969,  8}, //index 116
    { 1170,  819, 10647, 11}, //index 117
    { 1755,  877, 11401, 11}, //index 118
    { 2340, 1170, 15210, 15}, //index 119
    { 2632, 1316, 17108, 17}, //index 120
    { 2925, 1462, 19006, 19}, //index 121
    { 1350,  675,  8775,  9}, //index 122
    { 3510, 1755, 22815, 23}, //index 123
    { 3900, 1950, 25350, 25}, //index 124
    { 1350,  675,  8775,  9}, //reserved 125
    { 1350,  675,  8775,  9}, //index 126
    { 1350,  675,  8775,  9}, //index 127
    { 1350,  675,  8775,  9}, //index 128
    { 1350,  675,  8775,  9}, //index 129
    { 1350,  675,  8775,  9}, //index 130
    { 1350,  675,  8775,  9}, //index 131
    { 2925, 1462, 19006, 19}, //index 132
    { 3250, 1625, 21125, 21}, //index 133
    { 1350,  675,  8775,  9}, //index 134
    { 3900, 1950, 25350, 25}, //index 135
    { 4333, 2166, 28158, 28}  //index 136
 };

/* TX stats */
typedef struct
{
  wpt_uint32 txBytesPushed;
  wpt_uint32 txPacketsPushed; //Can be removed to optimize memory
}WDI_DTS_TX_TrafficStatsType;

/* RX stats */
typedef struct
{
  wpt_uint32 rxBytesRcvd;
  wpt_uint32 rxPacketsRcvd;  //Can be removed to optimize memory
}WDI_DTS_RX_TrafficStatsType;

typedef struct {
   wpt_uint8 running;
   WDI_DTS_RX_TrafficStatsType rxStats[HAL_NUM_STA][WDTS_MAX_RATE_NUM];
   WDI_DTS_TX_TrafficStatsType txStats[HAL_NUM_STA];
   WDI_TrafficStatsType        netTxRxStats[HAL_NUM_STA];
}WDI_DTS_TrafficStatsType;

static WDI_DTS_TrafficStatsType gDsTrafficStats;

#define DTS_RATE_TPUT(x) gRateInfo[x].tputBpus
#define DTS_11BRATE_TPUT_MULTIPLIER(x) g11bRateInfo[x].tputBpus

/* RX thread frame size threshold to delay frame drain */
#define DTS_RX_DELAY_FRAMESIZE_THRESHOLD  500

/* API to fill Rate Info based on the mac efficiency passed to it
 * macEff si used to caclulate mac throughput based on each rate index/PHY rate.
 * This is eventually used by MAS to calculate RX stats periodically sent to FW
 * The start and end Rate Index are the other arguments to this API - the new mac
 * efficiency passed to this API (Arg1)  is only applied between startRateIndex (arg2) and endRateIndex (arg3).
 */
void WDTS_FillRateInfo(wpt_uint8 macEff, wpt_int16 startRateIndex, wpt_int16 endRateIndex)
{
    int i;

    DTI_TRACE( DTI_TRACE_LEVEL_ERROR, "Change only 11ac rates");

    for (i=startRateIndex; i<=endRateIndex; i++)
    {
        // tputRate --> unit in Mega bits per sec X 10
        gRateInfo[i].tputRate = ((gRateInfo[i].phyRate * macEff)/100);
        // tputBmps --> unit in Bytes per msec = (tputRateX1024x1024)/(8x10X1000) ~= (tputRate*13)
        gRateInfo[i].tputBpms = gRateInfo[i].tputRate * MB_PER_SEC_TO_BYTES_PER_MSEC;
        // tputBpus --> unit in Bytes per usec: (+ 500) to round off to integral value
        gRateInfo[i].tputBpus = ((gRateInfo[i].tputBpms + 500) / 1000);
        if (gRateInfo[i].tputBpus == 0)
            gRateInfo[i].tputBpus = 1;

        DTI_TRACE( DTI_TRACE_LEVEL_ERROR, "%4u, %4u, %5u, %2u",
                            gRateInfo[i].phyRate,
                            gRateInfo[i].tputRate,
                            gRateInfo[i].tputBpms,
                            gRateInfo[i].tputBpus );
    }
}

/* Tx/Rx stats function
 * This function should be invoked to fetch the current stats
  * Parameters:
 *  pStats:Pointer to the collected stats
 *  len: length of buffer pointed to by pStats
 *  Return Status: None
 */
void WDTS_GetTrafficStats(WDI_TrafficStatsType** pStats, wpt_uint32 *len)
{
   if(gDsTrafficStats.running)
   {
      uint8 staIdx, rate;
      WDI_TrafficStatsType *pNetTxRxStats = gDsTrafficStats.netTxRxStats;
      wpalMemoryZero(pNetTxRxStats, sizeof(gDsTrafficStats.netTxRxStats));

      for(staIdx = 0; staIdx < HAL_NUM_STA; staIdx++, pNetTxRxStats++)
      {
          pNetTxRxStats->txBytesPushed += gDsTrafficStats.txStats[staIdx].txBytesPushed;
          pNetTxRxStats->txPacketsPushed+= gDsTrafficStats.txStats[staIdx].txPacketsPushed;
          for(rate = 0; rate < WDTS_MAX_11B_RATE_NUM; rate++)
          {
             pNetTxRxStats->rxBytesRcvd +=
               gDsTrafficStats.rxStats[staIdx][rate].rxBytesRcvd;
             pNetTxRxStats->rxPacketsRcvd +=
               gDsTrafficStats.rxStats[staIdx][rate].rxPacketsRcvd;
             pNetTxRxStats->rxTimeTotal +=
               gDsTrafficStats.rxStats[staIdx][rate].rxBytesRcvd*DTS_11BRATE_TPUT_MULTIPLIER(rate);
          }
          for(rate = WDTS_MAX_11B_RATE_NUM; rate < WDTS_MAX_RATE_NUM; rate++)
          {
             pNetTxRxStats->rxBytesRcvd += 
               gDsTrafficStats.rxStats[staIdx][rate].rxBytesRcvd;
             pNetTxRxStats->rxPacketsRcvd += 
               gDsTrafficStats.rxStats[staIdx][rate].rxPacketsRcvd;
             pNetTxRxStats->rxTimeTotal += 
               gDsTrafficStats.rxStats[staIdx][rate].rxBytesRcvd/DTS_RATE_TPUT(rate);
          }

          pNetTxRxStats->rxTimeTotal = pNetTxRxStats->rxTimeTotal/1000;

      }
      *pStats = gDsTrafficStats.netTxRxStats;
      *len = sizeof(gDsTrafficStats.netTxRxStats);
   }
   else
   {
      *pStats = NULL;
      *len = 0;
   }
}

/* WDTS_DeactivateTrafficStats
 * This function should be invoked to deactivate traffic stats collection
  * Parameters: None
 *  Return Status: None
 */
void WDTS_DeactivateTrafficStats(void)
{
   gDsTrafficStats.running = eWLAN_PAL_FALSE;
}

/* WDTS_ActivateTrafficStats
 * This function should be invoked to activate traffic stats collection
  * Parameters: None
 *  Return Status: None
 */
void WDTS_ActivateTrafficStats(void)
{
   gDsTrafficStats.running = eWLAN_PAL_TRUE;
}

/* WDTS_ClearTrafficStats
 * This function should be invoked to clear traffic stats 
  * Parameters: None
 *  Return Status: None
 */
void WDTS_ClearTrafficStats(void)
{
   wpalMemoryZero(gDsTrafficStats.rxStats, sizeof(gDsTrafficStats.rxStats));
   wpalMemoryZero(gDsTrafficStats.txStats, sizeof(gDsTrafficStats.txStats));
}

/* DTS Tx packet complete function. 
 * This function should be invoked by the transport device to indicate 
 * transmit complete for a frame.
 * Parameters:
 * pContext:Cookie that should be passed back to the caller 
 * pFrame:Refernce to PAL frame.
 * Return Value: SUCCESS  Completed successfully.
 *     FAILURE_XXX  Request was rejected due XXX Reason.
 *
 */
wpt_status WDTS_TxPacketComplete(void *pContext, wpt_packet *pFrame, wpt_status status)
{
  WDI_DS_ClientDataType *pClientData = (WDI_DS_ClientDataType*)(pContext);
  WDI_DS_TxMetaInfoType     *pTxMetadata;
  void *pvBDHeader, *physBDHeader;
  wpt_uint8 staIndex;

  // Do Sanity checks
  if(NULL == pContext || NULL == pFrame){
    VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_WARN,
                 "%s: Tx complete cannot proceed(%p:%p)",
                 __func__, pContext, pFrame);
    return eWLAN_PAL_STATUS_E_FAILURE;
  }


  // extract metadata from PAL packet
  pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame);
  pTxMetadata->txCompleteStatus = status;

  // Free BD header from pool
  WDI_GetBDPointers(pFrame, &pvBDHeader,  &physBDHeader);
  switch(pTxMetadata->frmType) 
  {
    case WDI_MAC_DATA_FRAME:
    /* note that EAPOL frame hasn't incremented ReserveCount. see
       WDI_DS_TxPacket() in wlan_qct_wdi_ds.c
    */
#ifdef FEATURE_WLAN_TDLS
    /* I utilizes TDLS mgmt frame always sent at BD_RATE2. (See limProcessTdls.c)
       Assumption here is data frame sent by WDA_TxPacket() <- HalTxFrame/HalTxFrameWithComplete()
       should take managment path. As of today, only TDLS feature has special data frame
       which needs to be treated as mgmt.
    */
    if((!pTxMetadata->isEapol) &&
       ((pTxMetadata->txFlags & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME) != WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME))
#else
    if(!pTxMetadata->isEapol)
#endif
    {
      /* SWAP BD header to get STA index for completed frame */
      WDI_SwapTxBd(pvBDHeader);
      staIndex = (wpt_uint8)WDI_TX_BD_GET_STA_ID(pvBDHeader);
      WDI_DS_MemPoolFree(&(pClientData->dataMemPool), pvBDHeader, physBDHeader);
      WDI_DS_MemPoolDecreaseReserveCount(&(pClientData->dataMemPool), staIndex);
      break;
    }
    // intentional fall-through to handle eapol packet as mgmt
    case WDI_MAC_MGMT_FRAME:
      WDI_DS_MemPoolFree(&(pClientData->mgmtMemPool), pvBDHeader, physBDHeader);
      VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
                   "%s: Management frame Tx complete status: %d", __func__, status);
      break;
  }
  WDI_SetBDPointers(pFrame, 0, 0);

  // Invoke Tx complete callback
  pClientData->txCompleteCB(pClientData->pCallbackContext, pFrame);  
  return eWLAN_PAL_STATUS_SUCCESS;

}


/*===============================================================================
  FUNCTION      WLANTL_GetReplayCounterFromRxBD
     
  DESCRIPTION   This function extracts 48-bit replay packet number from RX BD 
 
  DEPENDENCIES  Validity of replay check must be done before the function 
                is called
                          
  PARAMETERS    pucRxHeader pointer to RX BD header
                                       
  RETRUN        v_U64_t    Packet number extarcted from RX BD

  SIDE EFFECTS   none
 ===============================================================================*/
v_U64_t
WDTS_GetReplayCounterFromRxBD
(
   v_U8_t *pucRxBDHeader
)
{
  v_U64_t ullcurrentReplayCounter = 0;
  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* 48-bit replay counter is created as follows
   from RX BD 6 byte PMI command:
   Addr : AES/TKIP
   0x38 : pn3/tsc3
   0x39 : pn2/tsc2
   0x3a : pn1/tsc1
   0x3b : pn0/tsc0

   0x3c : pn5/tsc5
   0x3d : pn4/tsc4 */
  
#ifdef ANI_BIG_BYTE_ENDIAN
    /* Getting 48-bit replay counter from the RX BD */
    ullcurrentReplayCounter = WDI_RX_BD_GET_PMICMD_20TO23(pucRxBDHeader); 
    ullcurrentReplayCounter <<= 16;
    ullcurrentReplayCounter |= (( WDI_RX_BD_GET_PMICMD_24TO25(pucRxBDHeader) & 0xFFFF0000) >> 16);
    return ullcurrentReplayCounter;
#else
    /* Getting 48-bit replay counter from the RX BD */
    ullcurrentReplayCounter = (WDI_RX_BD_GET_PMICMD_24TO25(pucRxBDHeader) & 0x0000FFFF); 
    ullcurrentReplayCounter <<= 32; 
    ullcurrentReplayCounter |= WDI_RX_BD_GET_PMICMD_20TO23(pucRxBDHeader); 
    return ullcurrentReplayCounter;
#endif
}

/* Store RXBD, skb lenght, skb head, and skb end offset to global buffer.
 * This function should  be invoked when MPDU lenght + MPDU herader Offset
 * if higher then 3872 bytes.
 * Parameters:
 * pFrame:Refernce to PAL frame.
 * pBDHeader: BD header for PAL Frame.
 * Return Value: v_VOID_t
 *
 */
v_VOID_t
WDTS_StoreMetaInfo(wpt_packet *pFrame, wpt_uint8 *pBDHeader)
{
    wpt_uint8  usMPDUHLen;
    wpt_boolean usAsf, usAef, usLsf, usESF;
    wpt_uint16 usMPDULen;
    wpt_uint32 usPmiCmd24to25;
    struct WDTS_RxPktInfo *current_data =
           &WDTS_Pkt_Data_Buff.PktInfo[WDTS_Pkt_Data_Buff.current_position];

    vos_mem_copy(current_data->rx_bd, (void*)wpalPacketGetRawBuf(pFrame),
                                                       WDTS_MAX_RXDB_DATA_SIZE);

    usMPDULen = (wpt_uint16)WDI_RX_BD_GET_MPDU_LEN(pBDHeader);
    usMPDUHLen = (wpt_uint8)WDI_RX_BD_GET_MPDU_H_LEN(pBDHeader);
    usAsf = (wpt_boolean)WDI_RX_BD_GET_ASF(pBDHeader);
    usAef = (wpt_boolean)WDI_RX_BD_GET_AEF(pBDHeader);
    usLsf = (wpt_boolean)WDI_RX_BD_GET_LSF(pBDHeader);
    usESF = (wpt_boolean)WDI_RX_BD_GET_ESF(pBDHeader);
    usPmiCmd24to25 = (wpt_uint32)WDI_RX_BD_GET_PMICMD_24TO25(pBDHeader);

    current_data->pFrame_head = wpalGetOSPktHead(pFrame);
    current_data->pFrame_tail = wpalGetOSPktend(pFrame);
    current_data->pFrame_len = wpalPacketGetLength(pFrame);

    WDTS_Pkt_Data_Buff.current_count++;

    /* Dump packet info */
    VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                  "count: %d usMPDULen: 0x%x, usMPDUHLen: 0x%x, usAsf: %x,"
                  "usAef: %x, usLsf: 0x%x, usESF: 0x%x, usPmiCmd24to25: 0x%x,"
                  "skb_len: 0x%x",WDTS_Pkt_Data_Buff.current_count, usMPDULen,
                  usMPDUHLen, usAsf, usAef, usLsf, usESF, usPmiCmd24to25,
                  current_data->pFrame_len);

    WDTS_Pkt_Data_Buff.current_position++;
    if(WDTS_Pkt_Data_Buff.current_position >= WDTS_MAX_NUMBER_OF_RX_PKT)
       WDTS_Pkt_Data_Buff.current_position = 0;

    return;
}

/**
 *WDTS_RxPacketDump - Dump Rx packet details
 *@pFrame: pointer to first Rx buffer received
 *@pRxMetadata: pointer to RX packet Meta Info
 *
 *DTS utility to dump RX packet details.
 *
 *Return: None.
 */
static void WDTS_RxPacketDump(vos_pkt_t *pFrame,
                              WDI_DS_RxMetaInfoType *pRxMetadata)
{
    tpSirMacMgmtHdr pHdr;

    if (NULL == pRxMetadata) {
        VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                  "%s: RX Meta data info is NULL", __func__);
        return;
    }

    pHdr = (tpSirMacMgmtHdr)pRxMetadata->mpduHeaderPtr;

    /* RX packet type*/
    if (pRxMetadata->bcast)
         VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                   "%s RX Data frame is BC", __func__);
    else if (pHdr->da[0] & 0x01)
         VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                   "%s RX Data frame is MC", __func__);
    else
         VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                   "%s RX Data frame is UC", __func__);

    /* 802.11 packet type, subtype */
    if (WDI_MAC_MGMT_FRAME == pRxMetadata->type) {
       VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                 "%s: Management subtype:%d SA:"MAC_ADDRESS_STR" DA:"
                 MAC_ADDRESS_STR, __func__, pRxMetadata->subtype,
                 MAC_ADDR_ARRAY(pHdr->sa), MAC_ADDR_ARRAY(pHdr->da));
        vos_set_rx_wow_dump(false);
    } else if (WDI_MAC_CTRL_FRAME == pRxMetadata->type) {
        VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                  "%s: Control subtype:%d SA:"MAC_ADDRESS_STR" DA:"
                  MAC_ADDRESS_STR, __func__, pRxMetadata->subtype,
                  MAC_ADDR_ARRAY(pHdr->sa), MAC_ADDR_ARRAY(pHdr->da));
        vos_set_rx_wow_dump(false);
    } else if (WDI_MAC_DATA_FRAME == pRxMetadata->type) {
        VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                  "%s: Data subtype:%d SA:"MAC_ADDRESS_STR" DA:"
                  MAC_ADDRESS_STR, __func__, pRxMetadata->subtype,
                  MAC_ADDR_ARRAY(pHdr->sa), MAC_ADDR_ARRAY(pHdr->da));
    } else
        VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR,
                  "%s: Unknown frame SA:"MAC_ADDRESS_STR,
                   __func__, MAC_ADDR_ARRAY(pHdr->sa));
}

/* DTS Rx packet function. 
 * This function should be invoked by the transport device to indicate 
 * reception of a frame.
 * Parameters:
 * pContext:Cookie that should be passed back to the caller 
 * pFrame:Refernce to PAL frame.
 * Return Value: SUCCESS  Completed successfully.
 *     FAILURE_XXX  Request was rejected due XXX Reason.
 *
 */
wpt_status WDTS_RxPacket (void *pContext, wpt_packet *pFrame, WDTS_ChannelType channel)
{
  WDI_DS_ClientDataType *pClientData = 
    (WDI_DS_ClientDataType*)(pContext);
  wpt_boolean       bASF, bFSF, bLSF, bAEF;
  wpt_uint8                   ucMPDUHOffset, ucMPDUHLen, ucTid;
  wpt_uint8                   *pBDHeader;
  wpt_uint16                  usMPDUDOffset, usMPDULen;
  WDI_DS_RxMetaInfoType     *pRxMetadata;
  wpt_uint8                  isFcBd = 0;
  WDI_DS_LoggingSessionType *pLoggingSession;
  tPerPacketStats             rxStats = {0};
  wpt_uint8 indType = 0;

  tpSirMacFrameCtl  pMacFrameCtl;
  // Do Sanity checks
  if(NULL == pContext || NULL == pFrame){
    return eWLAN_PAL_STATUS_E_FAILURE;
  }

  // Normal DMA transfer does not contain RxBD
  if (WDTS_CHANNEL_RX_FW_LOG == channel)
  {
      pLoggingSession = (WDI_DS_LoggingSessionType *)
                         WDI_DS_GetLoggingSession(pContext);
      wpalFwLogPktSerialize(pFrame, pLoggingSession->logType);

      return eWLAN_PAL_STATUS_SUCCESS;
  }

  /*------------------------------------------------------------------------
    Extract BD header and check if valid
    ------------------------------------------------------------------------*/
  pBDHeader = (wpt_uint8*)wpalPacketGetRawBuf(pFrame);
  if(NULL == pBDHeader)
  {
    DTI_TRACE( DTI_TRACE_LEVEL_ERROR,
       "WLAN TL:BD header received NULL - dropping packet");
    wpalPacketFree(pFrame);
    return eWLAN_PAL_STATUS_E_FAILURE;
  }
  WDI_SwapRxBd(pBDHeader);

  ucMPDUHOffset = (wpt_uint8)WDI_RX_BD_GET_MPDU_H_OFFSET(pBDHeader);
  usMPDUDOffset = (wpt_uint16)WDI_RX_BD_GET_MPDU_D_OFFSET(pBDHeader);
  usMPDULen     = (wpt_uint16)WDI_RX_BD_GET_MPDU_LEN(pBDHeader);
  ucMPDUHLen    = (wpt_uint8)WDI_RX_BD_GET_MPDU_H_LEN(pBDHeader);
  ucTid         = (wpt_uint8)WDI_RX_BD_GET_TID(pBDHeader);

  /* If RX thread drain small size of frame from HW too fast
   * Sometimes HW cannot handle interrupt fast enough
   * And system crash might happen
   * To avoid system crash, input 1usec delay each frame draining
   * within host side, if frame size is smaller that threshold.
   * This is SW work around, to fix HW problem
   * Throughput and SnS test done successfully */
  if (usMPDULen < DTS_RX_DELAY_FRAMESIZE_THRESHOLD)
  {
    wpalBusyWait(1);
  }

  /*------------------------------------------------------------------------
    Gather AMSDU information 
    ------------------------------------------------------------------------*/
  bASF = WDI_RX_BD_GET_ASF(pBDHeader);
  bAEF = WDI_RX_BD_GET_AEF(pBDHeader);
  bFSF = WDI_RX_BD_GET_ESF(pBDHeader);
  bLSF = WDI_RX_BD_GET_LSF(pBDHeader);
  isFcBd = WDI_RX_FC_BD_GET_FC(pBDHeader);
  indType = WDI_RX_BD_GET_PER_SAPOFFLOAD(pBDHeader);

  DTI_TRACE( DTI_TRACE_LEVEL_INFO,
      "WLAN TL:BD header processing data: HO %d DO %d Len %d HLen %d"
      " Tid %d BD %d",
      ucMPDUHOffset, usMPDUDOffset, usMPDULen, ucMPDUHLen, ucTid,
      WDI_RX_BD_HEADER_SIZE);

  pRxMetadata = WDI_DS_ExtractRxMetaData(pFrame);

  if (WDTS_CHANNEL_RX_LOG == channel)
  {
      if (VPKT_SIZE_BUFFER_ALIGNED < (usMPDULen+ucMPDUHOffset))
      {
          /* Size of the packet tranferred by the DMA engine is
           * greater than the the memory allocated for the skb
           * Recover the SKB  case of length is in same memory page
           */
          WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
                   "Invalid Frame size, might memory corrupted(%d+%d/%d)",
                   usMPDULen, ucMPDUHOffset, VPKT_SIZE_BUFFER_ALIGNED);

          // Store RXBD,  skb head, tail and skb lenght in circular buffer
          WDTS_StoreMetaInfo(pFrame, pBDHeader);

          if ((usMPDULen+ucMPDUHOffset) <= WDTS_MAX_PAGE_SIZE)
          {
              wpalRecoverTail(pFrame);
              wpalPacketFree(pFrame);
          } else {
              //Recovery may cause adjoining buffer corruption
              WPAL_BUG(0);
          }

          return eWLAN_PAL_STATUS_SUCCESS;
      }

      /* Firmware should send the Header offset as length
       * of RxBd and data length should be populated to
       * the length of total data being sent
       */
      wpalPacketSetRxLength(pFrame, usMPDULen+ucMPDUHOffset);
      wpalPacketRawTrimHead(pFrame, ucMPDUHOffset);

      if(indType) {
          DTI_TRACE(DTI_TRACE_LEVEL_INFO, "indtype is %d size of pacekt is %lu",
                  indType, sizeof(WDI_RxBdType));
         if (WDI_RXBD_SAP_TX_STATS == indType) {
            pRxMetadata->fc = 1;
            pClientData->receiveFrameCB(pClientData->pCallbackContext, pFrame);
            return eWLAN_PAL_STATUS_SUCCESS;
         }
      }
      else {
          // Invoke Rx complete callback
          wpalLogPktSerialize(pFrame);
          return eWLAN_PAL_STATUS_SUCCESS;
      }
  }
  else
  {
      pRxMetadata->loggingData = 0;
  }

  if(!isFcBd)
  {
      /* When channel is WDTS_CHANNEL_RX_LOG firmware doesn't send MPDU header*/
      if ((usMPDUDOffset <= ucMPDUHOffset || usMPDULen < ucMPDUHLen) &&
              (WDTS_CHANNEL_RX_LOG != channel)) {
        DTI_TRACE( DTI_TRACE_LEVEL_ERROR,
            "WLAN TL:BD header corrupted - dropping packet");
        /* Drop packet ???? */ 
        wpalPacketFree(pFrame);
        return eWLAN_PAL_STATUS_SUCCESS;
      }

      if((ucMPDUHOffset < WDI_RX_BD_HEADER_SIZE) &&  (!(bASF && !bFSF))){
        /* AMSDU case, ucMPDUHOffset = 0  it should be hancdled seperatly */
        /* Drop packet ???? */ 
        wpalPacketFree(pFrame);
        return eWLAN_PAL_STATUS_SUCCESS;
      }

      /* AMSDU frame, but not first sub-frame
       * No MPDU header, MPDU header offset is 0
       * Total frame size is actual frame size + MPDU data offset */
      if((ucMPDUHOffset < WDI_RX_BD_HEADER_SIZE) && (bASF && !bFSF)){
        ucMPDUHOffset = usMPDUDOffset;
      }

      if (VPKT_SIZE_BUFFER_ALIGNED < (usMPDULen+ucMPDUHOffset))
      {
          /* Size of the packet tranferred by the DMA engine is
           * greater than the the memory allocated for the skb
           * Recover the SKB  case of length is in same memory page
           */
          WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL,
                   "Invalid Frame size, might memory corrupted(%d+%d/%d)",
                   usMPDULen, ucMPDUHOffset, VPKT_SIZE_BUFFER_ALIGNED);

          // Store RXBD,  skb head, tail and skb lenght in circular buffer
          WDTS_StoreMetaInfo(pFrame, pBDHeader);

          if ((usMPDULen+ucMPDUHOffset) <= WDTS_MAX_PAGE_SIZE)
          {
              wpalRecoverTail(pFrame);
              wpalPacketFree(pFrame);
          } else {
              //Recovery may cause adjoining buffer corruption
              WPAL_BUG(0);
          }

          return eWLAN_PAL_STATUS_SUCCESS;
      }

      if(eWLAN_PAL_STATUS_SUCCESS != wpalPacketSetRxLength(pFrame, usMPDULen+ucMPDUHOffset))
      {
          DTI_TRACE( DTI_TRACE_LEVEL_ERROR, "Invalid Frame Length, Frame dropped..");
          wpalPacketFree(pFrame);
          return eWLAN_PAL_STATUS_SUCCESS;
      }
      if(eWLAN_PAL_STATUS_SUCCESS != wpalPacketRawTrimHead(pFrame, ucMPDUHOffset))
      {
          DTI_TRACE( DTI_TRACE_LEVEL_ERROR, "Failed to trim Raw Packet Head, Frame dropped..");
          wpalPacketFree(pFrame);
          return eWLAN_PAL_STATUS_SUCCESS;
      }

      pRxMetadata->fc = isFcBd;
      pRxMetadata->staId = WDI_RX_BD_GET_STA_ID(pBDHeader);
      pRxMetadata->addr3Idx = WDI_RX_BD_GET_ADDR3_IDX(pBDHeader);
      pRxMetadata->rxChannel = WDI_RX_BD_GET_RX_CHANNEL(pBDHeader);
      pRxMetadata->rfBand = WDI_RX_BD_GET_RFBAND(pBDHeader);
      pRxMetadata->rtsf = WDI_RX_BD_GET_RTSF(pBDHeader);
      pRxMetadata->bsf = WDI_RX_BD_GET_BSF(pBDHeader);
      pRxMetadata->scan = WDI_RX_BD_GET_SCAN(pBDHeader);
      pRxMetadata->dpuSig = WDI_RX_BD_GET_DPU_SIG(pBDHeader);
      pRxMetadata->ft = WDI_RX_BD_GET_FT(pBDHeader);
      pRxMetadata->ne = WDI_RX_BD_GET_NE(pBDHeader);
      pRxMetadata->llcr = WDI_RX_BD_GET_LLCR(pBDHeader);
      pRxMetadata->bcast = WDI_RX_BD_GET_UB(pBDHeader);
      pRxMetadata->tid = ucTid;
      pRxMetadata->dpuFeedback = WDI_RX_BD_GET_DPU_FEEDBACK(pBDHeader);
      pRxMetadata->rateIndex = WDI_RX_BD_GET_RATEINDEX(pBDHeader);
      pRxMetadata->rxpFlags = WDI_RX_BD_GET_RXPFLAGS(pBDHeader);
      pRxMetadata->mclkRxTimestamp = WDI_RX_BD_GET_TIMESTAMP(pBDHeader);
#ifdef WLAN_FEATURE_11W
      pRxMetadata->rmf = WDI_RX_BD_GET_RMF(pBDHeader);
#endif
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
      pRxMetadata->offloadScanLearn = WDI_RX_BD_GET_OFFLOADSCANLEARN(pBDHeader);
      pRxMetadata->roamCandidateInd = WDI_RX_BD_GET_ROAMCANDIDATEIND(pBDHeader);
      pRxMetadata->perRoamCndInd = WDI_RX_BD_GET_PER_ROAMCANDIDATEIND(pBDHeader);
#endif
#ifdef SAP_AUTH_OFFLOAD
      /* Currently firmware use WDTS_CHANNEL_RX_LOG channel for two purpose.
       * 1) For firmare logging information: driver will do special handling
       * for those message.
       * 2) When SAP offload is enabled: In this case, indication type is stored
       * in pRxMetadata which will be used by LIM later.
       */
      if (WDTS_CHANNEL_RX_LOG == channel)
      {
          pRxMetadata->indType =
              (wpt_uint32)WDI_RX_BD_GET_PER_SAPOFFLOAD(pBDHeader);
          if (pRxMetadata->indType == WDI_RXBD_MLME_STA_STATUS)
          {
              DTI_TRACE( DTI_TRACE_LEVEL_INFO, "%s: Indtype is %d\n",
                      __func__, pRxMetadata->indType);
              pRxMetadata->type    = WDI_MAC_MGMT_FRAME;
          }
      }
      else
      {
          pRxMetadata->indType = 0;
      }
#endif

#ifdef WLAN_FEATURE_EXTSCAN
      pRxMetadata->extscanBuffer = WDI_RX_BD_GET_EXTSCANFULLSCANRESIND(pBDHeader);
#endif
      /* typeSubtype in BD doesn't look like correct. Fill from frame ctrl
         TL does it for Volans but TL does not know BD for Prima. WDI should do it */
      if ( 0 == WDI_RX_BD_GET_FT(pBDHeader) ) {
        if ( bASF ) {
          pRxMetadata->subtype = WDI_MAC_DATA_QOS_DATA;
          pRxMetadata->type    = WDI_MAC_DATA_FRAME;
        } else {
          pMacFrameCtl = (tpSirMacFrameCtl)(((wpt_uint8*)pBDHeader) + ucMPDUHOffset);
          pRxMetadata->subtype = pMacFrameCtl->subType;
          pRxMetadata->type    = pMacFrameCtl->type;
        }
      } else {
        pMacFrameCtl = (tpSirMacFrameCtl)(((wpt_uint8*)pBDHeader) + WDI_RX_BD_HEADER_SIZE);
        pRxMetadata->subtype = pMacFrameCtl->subType;
        pRxMetadata->type    = pMacFrameCtl->type;
      }

      pRxMetadata->mpduHeaderPtr = pBDHeader + ucMPDUHOffset;
      pRxMetadata->mpduDataPtr = pBDHeader + usMPDUDOffset;
      pRxMetadata->mpduLength = usMPDULen;
      pRxMetadata->mpduHeaderLength = ucMPDUHLen;

      /*------------------------------------------------------------------------
        Gather AMPDU information 
        ------------------------------------------------------------------------*/
      pRxMetadata->ampdu_reorderOpcode  = (wpt_uint8)WDI_RX_BD_GET_BA_OPCODE(pBDHeader);
      pRxMetadata->ampdu_reorderSlotIdx = (wpt_uint8)WDI_RX_BD_GET_BA_SI(pBDHeader);
      pRxMetadata->ampdu_reorderFwdIdx  = (wpt_uint8)WDI_RX_BD_GET_BA_FI(pBDHeader);
      pRxMetadata->currentPktSeqNo       = (wpt_uint16)WDI_RX_BD_GET_BA_CSN(pBDHeader);


      /*------------------------------------------------------------------------
        Gather AMSDU information 
        ------------------------------------------------------------------------*/
      pRxMetadata->amsdu_asf  =  bASF;
      pRxMetadata->amsdu_aef  =  bAEF;
      pRxMetadata->amsdu_esf  =  bFSF;
      pRxMetadata->amsdu_lsf  =  bLSF;
      pRxMetadata->amsdu_size =  WDI_RX_BD_GET_AMSDU_SIZE(pBDHeader);

      pRxMetadata->rssi0 = WDI_RX_BD_GET_RSSI0(pBDHeader);
      pRxMetadata->rssi1 = WDI_RX_BD_GET_RSSI1(pBDHeader);


        /* Missing: 
      wpt_uint32 fcSTATxQStatus:8;
      wpt_uint32 fcSTAThreshIndMask:8;
      wpt_uint32 fcSTAPwrSaveStateMask:8;
      wpt_uint32 fcSTAValidMask:8;

      wpt_uint8 fcSTATxQLen[8]; // one byte per STA. 
      wpt_uint8 fcSTACurTxRate[8]; // current Tx rate for each sta.   
      unknownUcastPkt 
      */

      pRxMetadata->replayCount = WDTS_GetReplayCounterFromRxBD(pBDHeader);
      pRxMetadata->snr = WDI_RX_BD_GET_SNR(pBDHeader); 

      /* 
       * PAL BD pointer information needs to be populated 
       */ 
      WPAL_PACKET_SET_BD_POINTER(pFrame, pBDHeader);
      WPAL_PACKET_SET_BD_LENGTH(pFrame, sizeof(WDI_RxBdType));

      if (((WDI_ControlBlockType *)pClientData->pcontext)->roamDelayStatsEnabled)
      {
          vos_record_roam_event(e_DXE_RX_PKT_TIME, (void *)pFrame, pRxMetadata->type);
      }
      if ((WLAN_LOG_LEVEL_ACTIVE ==
            vos_get_ring_log_level(RING_ID_PER_PACKET_STATS)) &&
          !(WDI_MAC_CTRL_FRAME == pRxMetadata->type))
      {
          vos_mem_zero(&rxStats,sizeof(tPerPacketStats));
          /* Peer tx packet and it is an Rx packet for us */
          rxStats.is_rx= VOS_TRUE;
          rxStats.tid = ucTid;
          rxStats.rssi = (pRxMetadata->rssi0 > pRxMetadata->rssi1)?
                                pRxMetadata->rssi0 : pRxMetadata->rssi1;
          rxStats.rate_idx = pRxMetadata->rateIndex;
          rxStats.seq_num = pRxMetadata->currentPktSeqNo;
          rxStats.dxe_timestamp = vos_timer_get_system_ticks();
          rxStats.data_len =
               vos_copy_80211_data(pFrame, rxStats.data, pRxMetadata->type);
          wpalPerPktSerialize(&rxStats);
      }

      /* Dump first Rx packet after host wakeup */
      if (vos_get_rx_wow_dump())
          WDTS_RxPacketDump((vos_pkt_t*)pFrame, pRxMetadata);

      /* Invoke Rx complete callback */
      pClientData->receiveFrameCB(pClientData->pCallbackContext, pFrame);
  }
  else
  {
      wpalPacketSetRxLength(pFrame, usMPDULen+ucMPDUHOffset);
      wpalPacketRawTrimHead(pFrame, ucMPDUHOffset);

      /* flow control related */
      pRxMetadata->fc = isFcBd;
      pRxMetadata->mclkRxTimestamp = WDI_RX_BD_GET_TIMESTAMP(pBDHeader);
      pRxMetadata->fcStaTxDisabledBitmap = WDI_RX_FC_BD_GET_STA_TX_DISABLED_BITMAP(pBDHeader);
      pRxMetadata->fcSTAValidMask = WDI_RX_FC_BD_GET_STA_VALID_MASK(pBDHeader);
      /* Invoke Rx complete callback */
      pClientData->receiveFrameCB(pClientData->pCallbackContext, pFrame);  
  }

  /* Log the RX Stats */
  if(gDsTrafficStats.running && pRxMetadata->staId < HAL_NUM_STA)
  {
     if(pRxMetadata->rateIndex < WDTS_MAX_RATE_NUM)
     {
        if(pRxMetadata->type == WDI_MAC_DATA_FRAME)
        {
           gDsTrafficStats.rxStats[pRxMetadata->staId][pRxMetadata->rateIndex].rxBytesRcvd +=
              pRxMetadata->mpduLength;
           gDsTrafficStats.rxStats[pRxMetadata->staId][pRxMetadata->rateIndex].rxPacketsRcvd++;
        }
     }
  }
  return eWLAN_PAL_STATUS_SUCCESS;
}



/* DTS Out of Resource packet function. 
 * This function should be invoked by the transport device to indicate 
 * the device is out of resources.
 * Parameters:
 * pContext:Cookie that should be passed back to the caller 
 * priority: indicates which channel is out of resource.
 * Return Value: SUCCESS  Completed successfully.
 *     FAILURE_XXX  Request was rejected due XXX Reason.
 */
wpt_status WDTS_OOResourceNotification(void *pContext, WDTS_ChannelType channel, wpt_boolean on)
{
  WDI_DS_ClientDataType *pClientData =
    (WDI_DS_ClientDataType *) pContext;
  static wpt_uint8 ac_mask = 0x1f;

  // Do Sanity checks
  if(NULL == pContext){
    return eWLAN_PAL_STATUS_E_FAILURE;
  }
  
  if(on){
    ac_mask |=  channel == WDTS_CHANNEL_TX_LOW_PRI?  0x0f : 0x10;
  } else {
    ac_mask &=  channel == WDTS_CHANNEL_TX_LOW_PRI?  0x10 : 0x0f;
  }


  // Invoke OOR callback
  pClientData->txResourceCB(pClientData->pCallbackContext, ac_mask); 
  return eWLAN_PAL_STATUS_SUCCESS;

}

void WDTS_LogRxDone(void *pContext)
{
  WDI_DS_LoggingSessionType *pLoggingSession;

  pLoggingSession = (WDI_DS_LoggingSessionType *)
                       WDI_DS_GetLoggingSession(pContext);

  if (NULL == pContext || pLoggingSession == NULL)
  {
    return;
  }
  /* check for done and Log type Mgmt frame = 0, QXDM = 1, FW Mem dump = 2 */
  if (pLoggingSession->done && pLoggingSession->logType <= VALID_FW_LOG_TYPES)
     vos_process_done_indication(pLoggingSession->logType,
                                 pLoggingSession->reasonCode);


  if (pLoggingSession->logType == QXDM_LOGGING &&
     pLoggingSession->reasonCode)
      pLoggingSession->logType = FATAL_EVENT;
  ((WDI_DS_ClientDataType *)(pContext))->rxLogCB(pLoggingSession->logType);

  pLoggingSession->done = 0;
  pLoggingSession->logType = 0;
  pLoggingSession->reasonCode = 0;

  return;
}

void WDTS_MbReceiveMsg(void *pContext)
{
  tpLoggingMailBox pLoggingMb;
  WDI_DS_LoggingSessionType *pLoggingSession;
  wpt_int8 i, noMem = 0;
  wpt_uint32 totalLen = 0;

  pLoggingMb = (tpLoggingMailBox)WDI_DS_GetLoggingMbAddr(pContext);
  pLoggingSession = (WDI_DS_LoggingSessionType *)
                       WDI_DS_GetLoggingSession(pContext);

  for(i = 0; i < MAX_NUM_OF_BUFFER; i++)
  {
      totalLen += pLoggingMb->logBuffLength[i];
      // Send done indication when the logbuffer size exceeds 128KB.
      if (totalLen > MAX_LOG_BUFFER_LENGTH || pLoggingMb->logBuffLength[i] > MAX_LOG_BUFFER_LENGTH)
      {
         DTI_TRACE( DTI_TRACE_LEVEL_ERROR, " %d received invalid log buffer length",
                                              totalLen);
         // Done using Mailbox, zero out the memory.
         wpalMemoryZero(pLoggingMb, sizeof(tLoggingMailBox));
         wpalMemoryZero(pLoggingSession, sizeof(WDI_DS_LoggingSessionType));
         //Set Status as Failure
         pLoggingSession->status = WDTS_LOGGING_STATUS_ERROR;
         WDTS_LogRxDone(pContext);

         return;
      }
  }

  totalLen = 0;
  for(i = 0; i < MAX_NUM_OF_BUFFER; i++)
  {
     pLoggingSession->logBuffAddress[i] = pLoggingMb->logBuffAddress[i];
     if (!noMem)
     {
        pLoggingSession->logBuffLength[i] = gTransportDriver.setupLogTransfer(
                                               pLoggingMb->logBuffAddress[i],
                                               pLoggingMb->logBuffLength[i]);
     }
     else
     {
        pLoggingSession->logBuffLength[i] = 0;
        continue;
     }

     totalLen += pLoggingSession->logBuffLength[i];

     if (pLoggingSession->logBuffLength[i] < pLoggingMb->logBuffLength[i])
     {
        noMem = 1;
     }
  }

  pLoggingSession->done = pLoggingMb->done;
  pLoggingSession->logType = pLoggingMb->logType;
  pLoggingSession->reasonCode = pLoggingMb->reasonCode;
  pLoggingSession->status = WDTS_LOGGING_STATUS_SUCCESS;
  // Done using Mailbox, zero out the memory.
  wpalMemoryZero(pLoggingMb, sizeof(tLoggingMailBox));

  if (totalLen)
  {
     if (gTransportDriver.startLogTransfer() == eWLAN_PAL_STATUS_SUCCESS)
        return;
  }

  // Send Done event to upper layers, since we wont be getting any from DXE
}

/* DTS open  function. 
 * On open the transport device should initialize itself.
 * Parameters:
 *  pContext:Cookie that should be passed back to the caller along 
 *  with the callback.
 *
 * Return Value: SUCCESS  Completed successfully.
 *     FAILURE_XXX  Request was rejected due XXX Reason.
 *
 */
wpt_status WDTS_openTransport( void *pContext)
{
  void *pDTDriverContext; 
  WDI_DS_ClientDataType *pClientData;
  WDI_Status sWdiStatus = WDI_STATUS_SUCCESS;
  WDTS_ClientCallbacks WDTSCb;

  pClientData = (WDI_DS_ClientDataType*) wpalMemoryAllocate(sizeof(WDI_DS_ClientDataType));
  if (!pClientData){
    return eWLAN_PAL_STATUS_E_NOMEM;
  }

  pClientData->suspend = 0;
  WDI_DS_AssignDatapathContext(pContext, (void*)pClientData);

  pDTDriverContext = gTransportDriver.open(); 
  if( NULL == pDTDriverContext )
  {
     DTI_TRACE( DTI_TRACE_LEVEL_ERROR, " %s fail from transport open", __func__);
     return eWLAN_PAL_STATUS_E_FAILURE;
  }
  WDT_AssignTransportDriverContext(pContext, pDTDriverContext);

  WDTSCb.rxFrameReadyCB = WDTS_RxPacket;
  WDTSCb.txCompleteCB = WDTS_TxPacketComplete;
  WDTSCb.lowResourceCB = WDTS_OOResourceNotification;
  WDTSCb.receiveMbMsgCB = WDTS_MbReceiveMsg;
  WDTSCb.receiveLogCompleteCB = WDTS_LogRxDone;
  gTransportDriver.register_client(pDTDriverContext, WDTSCb, (void*)pClientData);

  /* Create a memory pool for Mgmt BDheaders.*/
  sWdiStatus = WDI_DS_MemPoolCreate(&pClientData->mgmtMemPool, WDI_DS_MAX_CHUNK_SIZE, 
                                                     WDI_DS_HI_PRI_RES_NUM);
  if (WDI_STATUS_SUCCESS != sWdiStatus){
    return eWLAN_PAL_STATUS_E_NOMEM;
  }

  /* Create a memory pool for Data BDheaders.*/
  sWdiStatus = WDI_DS_MemPoolCreate(&pClientData->dataMemPool, WDI_DS_MAX_CHUNK_SIZE, 
                                                      WDI_DS_LO_PRI_RES_NUM);
  if (WDI_STATUS_SUCCESS != sWdiStatus){
    return eWLAN_PAL_STATUS_E_NOMEM;
  }

  wpalMemoryZero(&gDsTrafficStats, sizeof(gDsTrafficStats));

  sWdiStatus = WDI_DS_LoggingMbCreate(&pClientData->loggingMbContext, sizeof(tLoggingMailBox));
  if (WDI_STATUS_SUCCESS != sWdiStatus)
    return eWLAN_PAL_STATUS_E_NOMEM;

  return eWLAN_PAL_STATUS_SUCCESS;

}



/* DTS start  function. 
 * On start the transport device should start running.
 * Parameters:
 * pContext:Cookie that should be passed back to the caller along 
 * with the callback.
 *
 * Return Value: SUCCESS  Completed successfully.
 *     FAILURE_XXX  Request was rejected due XXX Reason.
 *
 */
wpt_status WDTS_startTransport( void *pContext)
{
  void *pDTDriverContext = WDT_GetTransportDriverContext(pContext);
  gTransportDriver.start(pDTDriverContext); 
  return eWLAN_PAL_STATUS_SUCCESS;

}


/* DTS Tx packet function. 
 * This function should be invoked by the DAL Dataservice to schedule transmit frame through DXE/SDIO.
 * Parameters:
 * pContext:Cookie that should be passed back to the caller along with the callback.
 * pFrame:Refernce to PAL frame.
 * Return Value: SUCCESS  Completed successfully.
 *     FAILURE_XXX  Request was rejected due XXX Reason.
 *
 */
wpt_status WDTS_TxPacket(void *pContext, wpt_packet *pFrame)
{
  void *pDTDriverContext = WDT_GetTransportDriverContext(pContext);
  WDI_DS_TxMetaInfoType     *pTxMetadata;
  WDTS_ChannelType channel = WDTS_CHANNEL_TX_LOW_PRI;
  wpt_status status = eWLAN_PAL_STATUS_SUCCESS;
  tPerPacketStats               txPktStat = {0};

  // extract metadata from PAL packet
  pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame);

  //Log the TX Stats
  if(gDsTrafficStats.running && pTxMetadata->staIdx < HAL_NUM_STA)
  {
     if(pTxMetadata->frmType & WDI_MAC_DATA_FRAME)
     {
        gDsTrafficStats.txStats[pTxMetadata->staIdx].txBytesPushed +=
           pTxMetadata->fPktlen;
        gDsTrafficStats.txStats[pTxMetadata->staIdx].txPacketsPushed += 1;
      }
  }

  // assign MDPU to correct channel??
  channel =  (pTxMetadata->frmType & WDI_MAC_DATA_FRAME)? 
    /* EAPOL frame uses TX_HIGH_PRIORITY DXE channel
       To make sure EAPOL (for second session) is pushed even if TX_LO channel
       already reached to low resource condition
       This can happen especially in MCC, high data traffic TX in first session
     */
#ifdef FEATURE_WLAN_TDLS
     /* I utilizes TDLS mgmt frame always sent at BD_RATE2. (See limProcessTdls.c)
        Assumption here is data frame sent by WDA_TxPacket() <- HalTxFrame/HalTxFrameWithComplete()
        should take managment path. As of today, only TDLS feature has special data frame
        which needs to be treated as mgmt.
      */
      (((pTxMetadata->isEapol) || (pTxMetadata->txFlags & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME))? WDTS_CHANNEL_TX_HIGH_PRI : WDTS_CHANNEL_TX_LOW_PRI) : WDTS_CHANNEL_TX_HIGH_PRI;
#else
      ((pTxMetadata->isEapol) ? WDTS_CHANNEL_TX_HIGH_PRI : WDTS_CHANNEL_TX_LOW_PRI) : WDTS_CHANNEL_TX_HIGH_PRI;
#endif
  // Send packet to  Transport Driver. 
  status =  gTransportDriver.xmit(pDTDriverContext, pFrame, channel);
  if ((WLAN_LOG_LEVEL_ACTIVE ==
           vos_get_ring_log_level(RING_ID_PER_PACKET_STATS)) &&
       !(pTxMetadata->frmType & WDI_MAC_CTRL_FRAME)){

      vos_mem_zero(&txPktStat,sizeof(tPerPacketStats));
      txPktStat.tid = pTxMetadata->fUP;
      txPktStat.dxe_timestamp = vos_timer_get_system_ticks();
      /*HW limitation cant get the seq number*/
      txPktStat.seq_num = 0;
      txPktStat.data_len =
      vos_copy_80211_data((void *)pFrame, txPktStat.data,
                   pTxMetadata->frmType);
      wpalPerPktSerialize(&txPktStat);
  }
  if (((WDI_ControlBlockType *)pContext)->roamDelayStatsEnabled)
  {
      vos_record_roam_event(e_DXE_FIRST_XMIT_TIME, (void *)pFrame, pTxMetadata->frmType);
  }
  return status;
}

/* DTS Tx Complete function. 
 * This function should be invoked by the DAL Dataservice to notify tx completion to DXE/SDIO.
 * Parameters:
 * pContext:Cookie that should be passed back to the caller along with the callback.
 * ucTxResReq:TX resource number required by TL
 * Return Value: SUCCESS  Completed successfully.
 *     FAILURE_XXX  Request was rejected due XXX Reason.
 *
 */
wpt_status WDTS_CompleteTx(void *pContext, wpt_uint32 ucTxResReq)
{
  void *pDTDriverContext = WDT_GetTransportDriverContext(pContext);
  
  // Notify completion to  Transport Driver. 
  return gTransportDriver.txComplete(pDTDriverContext, ucTxResReq);
}

/* DXE Set power state ACK callback. 
 * This callback function should be invoked by the DXE to notify WDI that set
 * power state request is complete.
 * Parameters:
 * status: status of the set operation
 * Return Value: None.
 *
 */
void  WDTS_SetPowerStateCb(wpt_status   status, unsigned int dxePhyAddr)
{
   //print a msg
   if(NULL != gSetPowerStateCbInfo.cback) 
   {
      gSetPowerStateCbInfo.cback(status, dxePhyAddr, gSetPowerStateCbInfo.pUserData);
   }
}


/* DTS Set power state function. 
 * This function should be invoked by the DAL to notify the WLAN device power state.
 * Parameters:
 * pContext:Cookie that should be passed back to the caller along with the callback.
 * powerState:Power state of the WLAN device.
 * Return Value: SUCCESS  Set successfully in DXE control blk.
 *     FAILURE_XXX  Request was rejected due XXX Reason.
 *
 */
wpt_status WDTS_SetPowerState(void *pContext, WDTS_PowerStateType  powerState,
                              WDTS_SetPowerStateCbType cback)
{
   void *pDTDriverContext = WDT_GetTransportDriverContext(pContext);
   wpt_status status = eWLAN_PAL_STATUS_SUCCESS;

   if( cback )
   {
      //save the cback & cookie
      gSetPowerStateCbInfo.pUserData = pContext;
      gSetPowerStateCbInfo.cback = cback;
      status = gTransportDriver.setPowerState(pDTDriverContext, powerState,
                                            WDTS_SetPowerStateCb);
   }
   else
   {
      status = gTransportDriver.setPowerState(pDTDriverContext, powerState,
                                               NULL);
   }

   return status;
}

/* DTS Transport Channel Debug
 * Display DXE Channel debugging information
 * User may request to display DXE channel snapshot
 * Or if host driver detects any abnormal stcuk may display
 * Parameters:
 *  displaySnapshot : Display DXE snapshot option
 *  enableStallDetect : Enable stall detect feature
                        This feature will take effect to data performance
                        Not integrate till fully verification
 * Return Value: NONE
 *
 */
void WDTS_ChannelDebug(wpt_boolean displaySnapshot, wpt_uint8 debugFlags)
{
   gTransportDriver.channelDebug(displaySnapshot, debugFlags);
   return;
}

/* DTS Transport Channel Kick Dxe
 * Request Kick DXE when HDD TX time out happen
 *
 * Parameters  : NONE
 * Return Value: NONE
 *
 */
void WDTS_ChannelKickDxe()
{
   gTransportDriver.kickDxe();
   return;
}

/* DTS Stop function. 
 * Stop Transport driver, ie DXE, SDIO
 * Parameters:
 * pContext:Cookie that should be passed back to the caller along with the callback.
 * Return Value: SUCCESS  Completed successfully.
 *     FAILURE_XXX  Request was rejected due XXX Reason.
 *
 */
wpt_status WDTS_Stop(void *pContext)
{
  void *pDTDriverContext = WDT_GetTransportDriverContext(pContext);
  wpt_status status = eWLAN_PAL_STATUS_SUCCESS;

  status =  gTransportDriver.stop(pDTDriverContext);

  wpalMemoryZero(&gDsTrafficStats, sizeof(gDsTrafficStats));

  return status;
}

/* DTS Stop function. 
 * Stop Transport driver, ie DXE, SDIO
 * Parameters:
 * pContext:Cookie that should be passed back to the caller along with the callback.
 * Return Value: SUCCESS  Completed successfully.
 *     FAILURE_XXX  Request was rejected due XXX Reason.
 *
 */
wpt_status WDTS_Close(void *pContext)
{
  void *pDTDriverContext = WDT_GetTransportDriverContext(pContext);
  WDI_DS_ClientDataType *pClientData = WDI_DS_GetDatapathContext(pContext);
  wpt_status status = eWLAN_PAL_STATUS_SUCCESS;

  /*Destroy the mem pool for mgmt BD headers*/
  WDI_DS_MemPoolDestroy(&pClientData->mgmtMemPool);
  
  /*Destroy the mem pool for mgmt BD headers*/
  WDI_DS_MemPoolDestroy(&pClientData->dataMemPool);

  WDI_DS_LoggingMbDestroy(&pClientData->loggingMbContext);

  status =  gTransportDriver.close(pDTDriverContext);

  wpalMemoryFree(pClientData);

  return status;
}

/* Get free TX data descriptor number from DXE
 * Parameters:
 * pContext: Cookie that should be passed back to the caller along with the callback.
 * Return Value: number of free descriptors for TX data channel
 *
 */
wpt_uint32 WDTS_GetFreeTxDataResNumber(void *pContext)
{
  return 
     gTransportDriver.getFreeTxDataResNumber(WDT_GetTransportDriverContext(pContext));
}
