/*
 * 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_uint32 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);

  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)
  {
      indType       = (wpt_uint32)WDI_RX_BD_GET_PER_SAPOFFLOAD(pBDHeader);
      if(indType) {
          DTI_TRACE(DTI_TRACE_LEVEL_INFO, "indtype is %d size of pacekt is %lu",
                  indType, sizeof(WDI_RxBdType));
      }
      else
      {
          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);

          // 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));
}
