/*
 * Copyright (c) 2012-2018 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_hdd_tx_rx.c
  
  \brief Linux HDD Tx/RX APIs
  
  ==========================================================================*/
  
/*--------------------------------------------------------------------------- 
  Include files
  -------------------------------------------------------------------------*/ 
#include <wlan_hdd_tx_rx.h>
#include <wlan_hdd_softap_tx_rx.h>
#include <wlan_hdd_dp_utils.h>
#include <wlan_qct_tl.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/ratelimit.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
#include <soc/qcom/subsystem_restart.h>
#else
#include <mach/subsystem_restart.h>
#endif

#include <wlan_hdd_p2p.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include <net/ieee80211_radiotap.h>
#include "sapApi.h"
#include <vos_sched.h>
#ifdef FEATURE_WLAN_TDLS
#include "wlan_hdd_tdls.h"
#endif

#include "vos_diag_core_event.h"
#include "vos_utils.h"
#include  "sapInternal.h"
#include  "wlan_hdd_trace.h"
#include  "wlan_qct_wda.h"
/*--------------------------------------------------------------------------- 
  Preprocessor definitions and constants
  -------------------------------------------------------------------------*/ 

const v_U8_t hddWmmAcToHighestUp[] = {
   SME_QOS_WMM_UP_RESV,
   SME_QOS_WMM_UP_EE,
   SME_QOS_WMM_UP_VI,
   SME_QOS_WMM_UP_NC
};

//Mapping Linux AC interpretation to TL AC.
const v_U8_t hdd_QdiscAcToTlAC[] = {
   WLANTL_AC_VO,
   WLANTL_AC_VI,
   WLANTL_AC_BE,
   WLANTL_AC_BK,
   WLANTL_AC_HIGH_PRIO,
};

#define HDD_TX_TIMEOUT_RATELIMIT_INTERVAL 20*HZ
#define HDD_TX_TIMEOUT_RATELIMIT_BURST    1
#define HDD_TX_STALL_SSR_THRESHOLD        5
#define HDD_TX_STALL_SSR_THRESHOLD_HIGH   13
#define HDD_TX_STALL_RECOVERY_THRESHOLD HDD_TX_STALL_SSR_THRESHOLD - 2
#define HDD_TX_STALL_KICKDXE_THRESHOLD  HDD_TX_STALL_SSR_THRESHOLD - 4
#define HDD_TX_STALL_FATAL_EVENT_THRESHOLD 2
#define EAPOL_MASK 0x8013
#define EAPOL_M1_BIT_MASK 0x8000
#define EAPOL_M2_BIT_MASK 0x0001
#define EAPOL_M3_BIT_MASK 0x8013
#define EAPOL_M4_BIT_MASK 0x0003


int gRatefromIdx[] = {
 10,20,55,100,
 10,20,55,110,
 60,90,120,180,240,360,480,540,
 65,130,195,260,390,520,585,650,
 72,144,217,289,434,578,650,722,
 65,130,195,260,390,520,585,650,
 135,270,405,540,810,1080,1215,1350,
 150,300,450,600,900,1200,1350,1500,
 135,270,405,540,810,1080,1215,1350,
 1350,1350,65,130,195,260,390, 520,
 585,650,780,1350,1350,1350,1350,1350,
 1350,1350,1350,1350,655,722,866,1350,
 1350,1350,135,270,405,540,810,1080,
 1215,1350,1350,1620,1800,1350,1350,1350,
 1350,1350,1350,1200,1350,1500,1350,1800,
 2000,1350, 292,585,877,1170,1755,2340,
 2632,2925,1350,3510,3900,1350,1350,1350,
 1350,1350,1350,1350,2925,3250,1350,3900,
 4333
 };
#ifdef FEATURE_WLAN_DIAG_SUPPORT
#define HDD_EAPOL_PACKET_TYPE_OFFSET  (15)
#define HDD_EAPOL_KEY_INFO_OFFSET     (19)
#define HDD_EAPOL_DEST_MAC_OFFSET     (0)
#define HDD_EAPOL_SRC_MAC_OFFSET      (6)
#endif /* FEATURE_WLAN_DIAG_SUPPORT */


static DEFINE_RATELIMIT_STATE(hdd_tx_timeout_rs,                 \
                              HDD_TX_TIMEOUT_RATELIMIT_INTERVAL, \
                              HDD_TX_TIMEOUT_RATELIMIT_BURST);

static struct sk_buff* hdd_mon_tx_fetch_pkt(hdd_adapter_t* pAdapter);

/*--------------------------------------------------------------------------- 
  Type declarations
  -------------------------------------------------------------------------*/ 
  
/*--------------------------------------------------------------------------- 
  Function definitions and documenation
  -------------------------------------------------------------------------*/ 

#ifdef DATA_PATH_UNIT_TEST
//Utility function to dump an sk_buff
static void dump_sk_buff(struct sk_buff * skb)
{
  VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: head = %pK", __func__, skb->head);
  VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data = %pK", __func__, skb->data);
  VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: tail = %pK", __func__, skb->tail);
  VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: end = %pK", __func__, skb->end);
  VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: len = %d", __func__, skb->len);
  VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data_len = %d", __func__, skb->data_len);
  VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: mac_len = %d", __func__, skb->mac_len);

  VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
     skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], 
     skb->data[5], skb->data[6], skb->data[7]); 
  VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
     skb->data[8], skb->data[9], skb->data[10], skb->data[11], skb->data[12],
     skb->data[13], skb->data[14], skb->data[15]); 
}

//Function for Unit Test only
static void transport_thread(hdd_adapter_t *pAdapter)
{
   v_U8_t staId;
   WLANTL_ACEnumType ac = WLANTL_AC_BE;
   vos_pkt_t *pVosPacket = NULL ;
   vos_pkt_t dummyPacket;
   WLANTL_MetaInfoType pktMetaInfo;
   WLANTL_RxMetaInfoType pktRxMetaInfo;
   VOS_STATUS status = VOS_STATUS_E_FAILURE;

   if (NULL == pAdapter)
   {
       VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
              FL("pAdapter is NULL"));
       VOS_ASSERT(0);
       return;
   }

   status = hdd_tx_fetch_packet_cbk( pAdapter->pvosContext,
                                     &staId,
                                     &ac,
                                     &pVosPacket,
                                     &pktMetaInfo );
  if (status != VOS_STATUS_SUCCESS && status != VOS_STATUS_E_EMPTY)
     VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                "%s: Test FAIL hdd_tx_fetch_packet_cbk", __func__);
  else
     VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                "%s: Test PASS hdd_tx_fetch_packet_cbk", __func__);

  status = hdd_tx_complete_cbk(pAdapter->pvosContext, &dummyPacket, VOS_STATUS_SUCCESS);
  if (status != VOS_STATUS_SUCCESS)
     VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                "%s: Test FAIL hdd_tx_complete_cbk", __func__);
  else
     VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                "%s: Test PASS hdd_tx_complete_cbk", __func__);

  status = hdd_tx_low_resource_cbk(pVosPacket, pAdapter);
  if (status != VOS_STATUS_SUCCESS)
     VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                "%s: Test FAIL hdd_tx_low_resource_cbk", __func__);
  else
     VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                "%s: Test PASS hdd_tx_low_resource_cbk", __func__);
  
  status = hdd_rx_packet_cbk( pAdapter->pvosContext,
                              &dummyPacket,
                              staId,
                              &pktRxMetaInfo);
  if (status != VOS_STATUS_SUCCESS)
     VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                "%s: Test FAIL hdd_rx_packet_cbk", __func__);
  else
     VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                "%s: Test PASS hdd_rx_packet_cbk", __func__);

}
#endif


/**============================================================================
  @brief hdd_flush_tx_queues() - Utility function to flush the TX queues

  @param pAdapter : [in] pointer to adapter context  
  @return         : VOS_STATUS_E_FAILURE if any errors encountered 
                  : VOS_STATUS_SUCCESS otherwise
  ===========================================================================*/
static VOS_STATUS hdd_flush_tx_queues( hdd_adapter_t *pAdapter )
{
   VOS_STATUS status = VOS_STATUS_SUCCESS;
   v_SINT_t i = -1;
   hdd_list_node_t *anchor = NULL;
   skb_list_node_t *pktNode = NULL;
   struct sk_buff *skb = NULL;

   pAdapter->isVosLowResource = VOS_FALSE;

   MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_FLUSH_TX_QUEUES,
                    pAdapter->sessionId, 0));

   while (++i != NUM_TX_QUEUES) 
   {
      //Free up any packets in the Tx queue
      spin_lock_bh(&pAdapter->wmm_tx_queue[i].lock);
      while (true) 
      {
         status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[i], &anchor );
         if(VOS_STATUS_E_EMPTY != status)
         {
            pktNode = list_entry(anchor, skb_list_node_t, anchor);
            skb = pktNode->skb;
            //TODO
            //++pAdapter->stats.tx_dropped; 
            ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
            ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
            kfree_skb(skb);
            continue;
         }
         break;
      }
      spin_unlock_bh(&pAdapter->wmm_tx_queue[i].lock);
      // backpressure is no longer in effect
      pAdapter->isTxSuspended[i] = VOS_FALSE;
   }

   return status;
}

/**============================================================================
  @brief hdd_flush_ibss_tx_queues() - Utility function to flush the TX queues
                                      in IBSS mode

  @param pAdapter : [in] pointer to adapter context
                  : [in] Staion Id
  @return         : VOS_STATUS_E_FAILURE if any errors encountered
                  : VOS_STATUS_SUCCESS otherwise
  ===========================================================================*/
void hdd_flush_ibss_tx_queues( hdd_adapter_t *pAdapter, v_U8_t STAId)
{
   v_U8_t i;
   hdd_list_node_t *anchor = NULL;
   skb_list_node_t *pktNode = NULL;
   struct sk_buff *skb = NULL;
   hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
   hdd_ibss_peer_info_t *pPeerInfo = &pHddStaCtx->ibss_peer_info;

   for (i = 0; i < NUM_TX_QUEUES; i ++)
   {
      spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock);
      while (true)
      {
         if (VOS_STATUS_E_EMPTY !=
              hdd_list_remove_front(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i],
                                    &anchor))
         {
            //If success then we got a valid packet from some AC
            pktNode = list_entry(anchor, skb_list_node_t, anchor);
            skb = pktNode->skb;
            ++pAdapter->stats.tx_dropped;
            ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
            ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
            kfree_skb(skb);
            continue;
         }
         break;
      }
      spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock);
   }
}

static struct sk_buff* hdd_mon_tx_fetch_pkt(hdd_adapter_t* pAdapter)
{
   skb_list_node_t *pktNode = NULL;
   struct sk_buff *skb = NULL;
   v_SIZE_t size = 0;
   WLANTL_ACEnumType ac = 0;
   VOS_STATUS status = VOS_STATUS_E_FAILURE;
   hdd_list_node_t *anchor = NULL;

   if (NULL == pAdapter)
   {
      VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
       FL("pAdapter is NULL"));
      VOS_ASSERT(0);
      return NULL;
   }

   // do we have any packets pending in this AC?
   hdd_list_size( &pAdapter->wmm_tx_queue[ac], &size ); 
   if( size == 0 )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                 "%s: NO Packet Pending", __func__);
      return NULL;
   }

   //Remove the packet from the queue
   spin_lock_bh(&pAdapter->wmm_tx_queue[ac].lock);
   status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[ac], &anchor );
   spin_unlock_bh(&pAdapter->wmm_tx_queue[ac].lock);

   if(VOS_STATUS_SUCCESS == status)
   {
      //If success then we got a valid packet from some AC
      pktNode = list_entry(anchor, skb_list_node_t, anchor);
      skb = pktNode->skb;
   }
   else
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                "%s: Not able to remove Packet from the list",
                  __func__);

      return NULL;
   }

   // if we are in a backpressure situation see if we can turn the hose back on
   if ( (pAdapter->isTxSuspended[ac]) &&
        (size <= HDD_TX_QUEUE_LOW_WATER_MARK) )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
                 "%s: TX queue[%d] re-enabled", __func__, ac);
      pAdapter->isTxSuspended[ac] = VOS_FALSE;      
      /* Enable Queues which we have disabled earlier */
      hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues"));
      netif_tx_start_all_queues( pAdapter->dev ); 
   }

   return skb;
}

void hdd_mon_tx_mgmt_pkt(hdd_adapter_t* pAdapter)
{
   hdd_cfg80211_state_t *cfgState;
   struct sk_buff* skb;
   hdd_adapter_t* pMonAdapter = NULL;
   struct ieee80211_hdr *hdr;
   hdd_context_t *pHddCtx;
   int ret = 0;

   ENTER();
   if (pAdapter == NULL)
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
       FL("pAdapter is NULL"));
      VOS_ASSERT(0);
      return;
   }
   pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   ret = wlan_hdd_validate_context(pHddCtx);
   if (0 != ret)
   {
       return;
   }
   pMonAdapter = hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_MONITOR );
   if (pMonAdapter == NULL)
   {
       hddLog(VOS_TRACE_LEVEL_ERROR,
              "%s: pMonAdapter is NULL", __func__);
       return;
   }
   cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter );

   if( NULL != cfgState->buf )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
          "%s: Already one MGMT packet Tx going on", __func__);
      return;
   }

   skb = hdd_mon_tx_fetch_pkt(pMonAdapter);

   if (NULL == skb)
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
       "%s: No Packet Pending", __func__);
      return;
   }

   cfgState->buf = vos_mem_malloc( skb->len ); //buf;
   if( cfgState->buf == NULL )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
          "%s: Failed to Allocate memory", __func__);
      goto fail;
   }

   cfgState->len = skb->len;

   vos_mem_copy( cfgState->buf, skb->data, skb->len);

   cfgState->skb = skb; //buf;
   cfgState->action_cookie = (uintptr_t)cfgState->buf;

   hdr = (struct ieee80211_hdr *)skb->data;
   if( (hdr->frame_control & HDD_FRAME_TYPE_MASK)
                                       == HDD_FRAME_TYPE_MGMT )
   {
       if( (hdr->frame_control & HDD_FRAME_SUBTYPE_MASK)
                                       == HDD_FRAME_SUBTYPE_DEAUTH )
       {
          struct tagCsrDelStaParams delStaParams;

          WLANSAP_PopulateDelStaParams(hdr->addr1,
                                  eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
                                 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);

          hdd_softap_sta_deauth(pAdapter, &delStaParams);
          goto mgmt_handled;
       }
       else if( (hdr->frame_control & HDD_FRAME_SUBTYPE_MASK) 
                                      == HDD_FRAME_SUBTYPE_DISASSOC )
       {
          hdd_softap_sta_disassoc( pAdapter, hdr->addr1 ); 
          goto mgmt_handled;
       }
   }
   VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
      "%s: Sending action frame to SAP to TX, Len %d", __func__, skb->len);

   if (VOS_STATUS_SUCCESS != 
      WLANSAP_SendAction( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                           skb->data, skb->len, 0) )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
          "%s: WLANSAP_SendAction returned fail", __func__);
      hdd_sendActionCnf( pAdapter, FALSE );
   }
   EXIT();
   return;

mgmt_handled:
   EXIT();
   hdd_sendActionCnf( pAdapter, TRUE );
   return;
fail:
   kfree_skb(pAdapter->skb_to_tx);
   pAdapter->skb_to_tx = NULL;
   return;
}

void __hdd_mon_tx_work_queue(struct work_struct *work)
{
   hdd_adapter_t* pAdapter = container_of(work, hdd_adapter_t, monTxWorkQueue);
   hdd_mon_tx_mgmt_pkt(pAdapter);
}

void hdd_mon_tx_work_queue(struct work_struct *work)
{
   vos_ssr_protect(__func__);
   __hdd_mon_tx_work_queue(work);
   vos_ssr_unprotect(__func__);
}

int hdd_mon_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
   VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
           "%s: Packet Rcvd at Monitor interface,"
             " Dropping the packet",__func__);
   kfree_skb(skb);
   return NETDEV_TX_OK;
}

/**============================================================================
  @brief hdd_dhcp_pkt_info() -
               Function to log DHCP pkt info

  @param skb      : [in]  pointer to OS packet (sk_buff)
  @return         : None
  ===========================================================================*/

void hdd_dhcp_pkt_info(struct sk_buff *skb)
{
    /* port no 67 (0x43) or 68 (0x44) */

    if (*((u8*)skb->data + BOOTP_MSG_OFFSET) == BOOTP_REQUEST_MSG)
        hddLog(VOS_TRACE_LEVEL_INFO, FL("Request"));
    else if (*((u8*)skb->data + BOOTP_MSG_OFFSET) == BOOTP_RESPONSE_MSG)
        hddLog(VOS_TRACE_LEVEL_INFO, FL("Response"));
    else
        hddLog(VOS_TRACE_LEVEL_INFO, FL("DHCP invalid"));

    hddLog(VOS_TRACE_LEVEL_INFO,
            FL("DHCP Dest Addr: %pM Src Addr %pM "
                " source port : %d, dest port : %d"),
            skb->data, (skb->data + 6),
            ntohs(*((u16*)((u8*)skb->data + UDP_SRC_PORT_OFFSET))),
            ntohs(*((u16*)((u8*)skb->data + UDP_DEST_PORT_OFFSET))));

    if ((skb->data[DHCP_OPTION53_OFFSET] == DHCP_OPTION53) &&
        (skb->data[DHCP_OPTION53_LENGTH_OFFSET] == DHCP_OPTION53_LENGTH)) {

        switch (skb->data[DHCP_OPTION53_STATUS_OFFSET]) {
        case DHCPDISCOVER:
            hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP DISCOVER"));
            break;
        case DHCPREQUEST:
            hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP REQUEST"));
            break;
        case DHCPOFFER:
            hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP OFFER"));
            break;
        case DHCPACK:
            hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP ACK"));
            break;
        case DHCPNAK:
            hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP NACK"));
            break;
        case DHCPRELEASE:
            hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP RELEASE"));
            break;
        case DHCPINFORM:
            hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP INFORM"));
            break;

        default:
            hddLog(VOS_TRACE_LEVEL_INFO,
                    "%s: DHCP Not Defined OPTION53 : %d", __func__,
                    skb->data[DHCP_OPTION53_STATUS_OFFSET]);
        }
    }
}

/**============================================================================
  @brief hdd_dump_dhcp_pkt() -
               Function to dump DHCP packets in TX and RX path.

  @param skb      : [in]  pointer to OS packet (sk_buff)
  @param path     : [in]  bool indicating TX/RX path
  @return         : None
  ===========================================================================*/
void hdd_dump_dhcp_pkt(struct sk_buff *skb, int path)
{

    if ((ntohs(*((u16*)((u8*)skb->data + ETH_TYPE_OFFSET)))
                == ETH_TYPE_IP_PKT) ||
            (ntohs(*((u8*)skb->data + PROTOCOL_OFFSET)) == UDP_PROTOCOL)) {

        /* IP protocol 12 bytes of mac addresses in 802.3 header */
        if ( ntohs(*((u16*)((u8*)skb->data + UDP_DEST_PORT_OFFSET))) ==
                BOOTP_SERVER_PORT  ||
                ntohs(*((u16*)((u8*)skb->data + UDP_DEST_PORT_OFFSET))) ==
                BOOTP_CLIENT_PORT  ||
                ntohs(*((u16*)((u8*)skb->data + UDP_SRC_PORT_OFFSET))) ==
                BOOTP_SERVER_PORT  ||
                ntohs(*((u16*)((u8*)skb->data + UDP_SRC_PORT_OFFSET))) ==
                BOOTP_CLIENT_PORT ) {

            if (path == TX_PATH) {
                hddLog(VOS_TRACE_LEVEL_INFO, FL("DHCP TX PATH"));
            } else {
                hddLog(VOS_TRACE_LEVEL_INFO, FL("DHCP RX PATH"));
            }

            hdd_dhcp_pkt_info(skb);
        }
    }
}

/**============================================================================
   @brief hdd_ibss_hard_start_xmit() - Function registered with the Linux OS for
   transmitting packets in case of IBSS. There are 2 versions of this function.
   One that uses locked queue and other that uses lockless queues. Both have been
   retained to do some performance testing

   @param skb      : [in]  pointer to OS packet (sk_buff)
   @param dev      : [in] pointer to network device

   @return         : NET_XMIT_DROP if packets are dropped
                   : NET_XMIT_SUCCESS if packet is enqueued succesfully
   ===========================================================================*/
 int hdd_ibss_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
    VOS_STATUS status;
    WLANTL_ACEnumType ac;
    sme_QosWmmUpType up;
    skb_list_node_t *pktNode = NULL;
    hdd_list_node_t *anchor = NULL;
    v_SIZE_t pktListSize = 0;
    hdd_adapter_t *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);
    hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    hdd_ibss_peer_info_t * pPeerInfo;
    v_U8_t STAId = WLAN_MAX_STA_COUNT;
    v_BOOL_t txSuspended = VOS_FALSE;
    struct sk_buff *skb1;
    v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;

    if (NULL == pHddCtx || NULL == pHddStaCtx) {
        VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                   "%s HDD context is NULL", __func__);
        return NETDEV_TX_BUSY;
    }
    pPeerInfo = &pHddStaCtx->ibss_peer_info;
    ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;

    //Get TL AC corresponding to Qdisc queue index/AC.
    ac = hdd_QdiscAcToTlAC[skb->queue_mapping];

    if (eConnectionState_IbssDisconnected == pHddStaCtx->conn_info.connState)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                  "%s: Tx frame in disconnected state in IBSS mode", __func__);
        ++pAdapter->stats.tx_dropped;
        ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
        ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
        kfree_skb(skb);
        return NETDEV_TX_OK;
    }

     STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
     if ((STAId == HDD_WLAN_INVALID_STA_ID) &&
           (vos_is_macaddr_broadcast( pDestMacAddress ) ||
            vos_is_macaddr_group(pDestMacAddress)))
     {
          STAId = IBSS_BROADCAST_STAID;
          VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_LOW,
                     "%s: BC/MC packet", __func__);
     }
     else if (STAId >= HDD_MAX_NUM_IBSS_STA)
     {
          VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                     "%s: Received Unicast frame with invalid staID", __func__);
          ++pAdapter->stats.tx_dropped;
          ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
          ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
          kfree_skb(skb);
          return NETDEV_TX_OK;
     }

    //user priority from IP header, which is already extracted and set from
    //select_queue call back function
    up = skb->priority;
    ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];

    VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO,
               "%s: Classified as ac %d up %d", __func__, ac, up);

    if ( pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP )
    {
       hdd_dump_dhcp_pkt(skb, TX_PATH);
    }

     spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
     hdd_list_size(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &pktListSize);
     if(pktListSize >= pAdapter->aTxQueueLimit[ac])
     {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
             "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize);
        pPeerInfo->ibssStaInfo[STAId].txSuspended[ac] = VOS_TRUE;
        netif_stop_subqueue(dev, skb_get_queue_mapping(skb));
        txSuspended = VOS_TRUE;
        spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                   "%s: TX queue full for AC=%d Disable OS TX queue",
                   __func__, ac );
         return NETDEV_TX_BUSY;
     }

     /* If 3/4th of the max queue size is used then enable the flag.
      * This flag indicates to place the DHCP packets in VOICE AC queue.*/
    if (WLANTL_AC_BE == ac)
    {
       if (pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
       {
           VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                      "%s: TX queue for Best Effort AC is 3/4th full", __func__);
           pAdapter->isVosLowResource = VOS_TRUE;
       }
       else
       {
           pAdapter->isVosLowResource = VOS_FALSE;
       }
    }

    spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);

    //Use the skb->cb field to hold the list node information
    pktNode = (skb_list_node_t *)&skb->cb;

    //Stick the OS packet inside this node.
    pktNode->skb = skb;

    //Stick the User Priority inside this node
    pktNode->userPriority = up;

    INIT_LIST_HEAD(&pktNode->anchor);

    spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
    status = hdd_list_insert_back_size( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac],
                                       &pktNode->anchor, &pktListSize );
    spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
    if ( !VOS_IS_STATUS_SUCCESS( status ) )
    {
       VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                  "%s:Insert Tx queue failed. Pkt dropped", __func__);
       ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
       ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
       ++pAdapter->stats.tx_dropped;
       kfree_skb(skb);
       return NETDEV_TX_OK;
    }

    ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
    ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac];
    ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;

    if (1 == pktListSize)
    {
       //Let TL know we have a packet to send for this AC
       status = WLANTL_STAPktPending( pHddCtx->pvosContext, STAId, ac );

       if ( !VOS_IS_STATUS_SUCCESS( status ) )
       {
          VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                   "%s: Failed to signal TL for AC=%d STAId =%d",
                       __func__, ac, STAId );

          /* Remove the packet from queue. It must be at the back of the queue, as TX thread
           * cannot preempt us in the middle as we are in a soft irq context.
           *  Also it must be the same packet that we just allocated.
           */
          spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
          status = hdd_list_remove_back( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &anchor);
          spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
          /* Free the skb only if we are able to remove it from the list.
           * If we are not able to retrieve it from the list it means that
           * the skb was pulled by TX Thread and is use so we should not free
           * it here
           */
          if (VOS_IS_STATUS_SUCCESS(status))
          {
             pktNode = list_entry(anchor, skb_list_node_t, anchor);
             skb1 = pktNode->skb;
             kfree_skb(skb1);
          }
          ++pAdapter->stats.tx_dropped;
          ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
          ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac];
          return NETDEV_TX_OK;
       }
    }

    netif_trans_update(dev);

    return NETDEV_TX_OK;
 }

/**============================================================================
  @brief __hdd_hard_start_xmit() - Function registered with the Linux OS for
  transmitting packets. There are 2 versions of this function. One that uses
  locked queue and other that uses lockless queues. Both have been retained to
  do some performance testing

  @param skb      : [in]  pointer to OS packet (sk_buff)
  @param dev      : [in] pointer to Libra network device

  @return         : NET_XMIT_DROP if packets are dropped
                  : NET_XMIT_SUCCESS if packet is enqueued succesfully
  ===========================================================================*/
int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
   VOS_STATUS status;
   WLANTL_ACEnumType qid, ac;
   sme_QosWmmUpType up;
   skb_list_node_t *pktNode = NULL;
   hdd_list_node_t *anchor = NULL;
   v_SIZE_t pktListSize = 0;
   hdd_adapter_t *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);
   v_BOOL_t granted;
   v_U8_t STAId = WLAN_MAX_STA_COUNT;
   hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   v_BOOL_t txSuspended = VOS_FALSE;
   struct sk_buff *skb1;
   v_BOOL_t arp_pkt;

   if (NULL == pHddCtx) {
       VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                  "%s HDD context is NULL", __func__);
       return NETDEV_TX_BUSY;
   }

   ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled;

   if (unlikely(netif_subqueue_stopped(dev, skb))) {
       VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                  "%s is called when netif TX %d is disabled",
                  __func__, skb->queue_mapping);
       return NETDEV_TX_BUSY;
   }

   arp_pkt = vos_is_arp_pkt(skb, false);

   if (arp_pkt)
   {
       ++pAdapter->hdd_stats.hddArpStats.txCount;
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                 "%s :ARP packet received form net_dev", __func__);
   }

   //Get TL Q index corresponding to Qdisc queue index/AC.
   qid = hdd_QdiscAcToTlAC[skb->queue_mapping];
   ac  = qid;

   if (qid == WLANTL_AC_HIGH_PRIO)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                "%s It must be a Eapol/Wapi/DHCP packet device_mode:%d",
                __func__, pAdapter->device_mode);
      ac = hddWmmUpToAcMap[skb->priority];
   }

      if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
      {
         VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                FL("Tx frame in not associated state in %d context"),
                    pAdapter->device_mode);

         if (arp_pkt)
         {
            ++pAdapter->hdd_stats.hddArpStats.txDropped;
            pAdapter->hdd_stats.hddArpStats.reason = HDD_TX_FRAME_IN_NOT_ASSOCIATED_STATE;
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
            "%s :Tx frame in not associated state, ARP packet Dropped ",
            __func__);
         }
         ++pAdapter->stats.tx_dropped;
         ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
         ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
         kfree_skb(skb);
         return NETDEV_TX_OK;
      }
      STAId = pHddStaCtx->conn_info.staId[0];

   //user priority from IP header, which is already extracted and set from
   //select_queue call back function
   up = skb->priority;

   ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[qid];

#ifdef HDD_WMM_DEBUG
   VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
              "%s: Classified as ac %d up %d", __func__, ac, up);
#endif // HDD_WMM_DEBUG

   if (pHddCtx->cfg_ini->gEnableRoamDelayStats)
   {
       vos_record_roam_event(e_HDD_FIRST_XMIT_TIME, (void *)skb, 0);
   }

   spin_lock(&pAdapter->wmm_tx_queue[qid].lock);
   /*CR 463598,384996*/
   /*For every increment of 10 pkts in the queue, we inform TL about pending pkts.
    *We check for +1 in the logic,to take care of Zero count which
    *occurs very frequently in low traffic cases */
   if((pAdapter->wmm_tx_queue[qid].count + 1) % 10 == 0)
   {
      /* Use the following debug statement during Engineering Debugging.There are chance that this will lead to a Watchdog Bark
            * if it is in the mainline code and if the log level is enabled by someone for debugging
           VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,"%s:Queue is Filling up.Inform TL again about pending packets", __func__);*/

      status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                    STAId, qid
                                    );
      if ( !VOS_IS_STATUS_SUCCESS( status ) )
      {
         VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                    "%s: WLANTL_STAPktPending() returned error code %d",
                    __func__, status);

         if (arp_pkt)
         {
            ++pAdapter->hdd_stats.hddArpStats.txDropped;
            pAdapter->hdd_stats.hddArpStats.reason = HDD_WLANTL_STAPKTPENDING_RETURNED_ERROR_CODE;
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
            "%s:ARP Packet Dropped WLANTL_STAPktPending returned error %d",
            __func__, status);
         }
         ++pAdapter->stats.tx_dropped;
         ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
         ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
         kfree_skb(skb);
         spin_unlock(&pAdapter->wmm_tx_queue[qid].lock);
         return NETDEV_TX_OK;
      }
   }

   if (pHddCtx->bad_sta[STAId]) {
      hdd_list_node_t *anchor = NULL;
      skb_list_node_t *pktNode = NULL;
      struct sk_buff *fskb = NULL;

      if (pAdapter->wmm_tx_queue[qid].count >=
          pAdapter->wmm_tx_queue[qid].max_size / 2) {
         hdd_list_remove_front(&pAdapter->wmm_tx_queue[qid],
                               &anchor);
         pktNode = list_entry(anchor, skb_list_node_t, anchor);
         fskb = pktNode->skb;
         kfree_skb(fskb);
         ++pAdapter->stats.tx_dropped;
         ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
      }
   }

   //If we have already reached the max queue size, disable the TX queue
   if ( pAdapter->wmm_tx_queue[qid].count == pAdapter->wmm_tx_queue[qid].max_size)
   {
         ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressured;
         ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressuredAC[qid];
         hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queue for QId %d"), qid);
         netif_tx_stop_queue(netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)));
         pAdapter->isTxSuspended[qid] = VOS_TRUE;
         txSuspended = VOS_TRUE;
         MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_NETDEV,
                          pAdapter->sessionId, qid));
   }

   /* If 3/4th of the max queue size is used then enable the flag.
    * This flag indicates to place the DHCP packets in VOICE AC queue.*/
   if (WLANTL_AC_BE == qid)
   {
      if (pAdapter->wmm_tx_queue[qid].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
      {
          pAdapter->isVosLowResource = VOS_TRUE;
      }
      else
      {
          pAdapter->isVosLowResource = VOS_FALSE;
      }
   }

   spin_unlock(&pAdapter->wmm_tx_queue[qid].lock);

   if (( NULL != pHddCtx ) &&
      (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
   {
       hdd_dump_dhcp_pkt(skb, TX_PATH);
   }

   if (VOS_TRUE == txSuspended)
   {
       VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                  "%s: TX queue full for QId=%d Disable OS TX queue",
                  __func__, qid );
      return NETDEV_TX_BUSY;
   }

   //Use the skb->cb field to hold the list node information
   pktNode = (skb_list_node_t *)&skb->cb;

   //Stick the OS packet inside this node.
   pktNode->skb = skb;

   //Stick the User Priority inside this node
   pktNode->userPriority = up;


   INIT_LIST_HEAD(&pktNode->anchor);

   //Insert the OS packet into the appropriate AC queue
   spin_lock(&pAdapter->wmm_tx_queue[qid].lock);
   status = hdd_list_insert_back_size( &pAdapter->wmm_tx_queue[qid], &pktNode->anchor, &pktListSize );
   spin_unlock(&pAdapter->wmm_tx_queue[qid].lock);

   if ( !VOS_IS_STATUS_SUCCESS( status ) )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s:Insert Tx queue failed. Pkt dropped", __func__);

      if (arp_pkt)
      {
          ++pAdapter->hdd_stats.hddArpStats.txDropped;
          pAdapter->hdd_stats.hddArpStats.reason = HDD_INSERT_TX_QUEUE_FAILED;
          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                    "%s:Insert Tx queue failed. ARP packet dropped", __func__);
      }
      ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
      ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
      ++pAdapter->stats.tx_dropped;
      kfree_skb(skb);
      return NETDEV_TX_OK;
   }

   ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued;
   ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[qid];
   ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count;

   if (HDD_PSB_CHANGED == pAdapter->psbChanged)
   {
      /* Function which will determine acquire admittance for a
       * WMM AC is required or not based on psb configuration done
       * in the framework
       */
       hdd_wmm_acquire_access_required(pAdapter, ac);
   }

   //Make sure we have access to this access category
   if (((pAdapter->psbChanged & (1 << ac)) && likely(pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed)) ||
           (pHddStaCtx->conn_info.uIsAuthenticated == VOS_FALSE))
   {
      granted = VOS_TRUE;
   }
   else
   {
      status = hdd_wmm_acquire_access( pAdapter, ac, &granted );
      pAdapter->psbChanged |= (1 << ac);
   }

   if ( (granted && ( pktListSize == 1 )) ||
        (qid == WLANTL_AC_HIGH_PRIO))
   {
      //Let TL know we have a packet to send for this AC
      //VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__);
      status = WLANTL_STAPktPending(
                                  (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                   STAId, qid );
      if ( !VOS_IS_STATUS_SUCCESS( status ) )
      {
         VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
                   "%s: Failed to signal TL for QId=%d", __func__, qid );

         //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle
         //as we are in a soft irq context. Also it must be the same packet that we just allocated.
         spin_lock(&pAdapter->wmm_tx_queue[qid].lock);
         status = hdd_list_remove_back( &pAdapter->wmm_tx_queue[qid], &anchor );
         spin_unlock(&pAdapter->wmm_tx_queue[qid].lock);
         /* Free the skb only if we are able to remove it from the list.
          * If we are not able to retrieve it from the list it means that
          * the skb was pulled by TX Thread and is use so we should not free
          * it here
          */
         if (VOS_IS_STATUS_SUCCESS(status))
         {
            pktNode = list_entry(anchor, skb_list_node_t, anchor);
            skb1 = pktNode->skb;
            kfree_skb(skb1);
         }

         if (arp_pkt)
         {
           ++pAdapter->hdd_stats.hddArpStats.txDropped;
           pAdapter->hdd_stats.hddArpStats.reason = HDD_FAILED_TO_SIGNAL_TL;
           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
           "%s: ARP packet Dropped : Failed to signal TL for QId=%d",
           __func__, qid );
         }
         ++pAdapter->stats.tx_dropped;
         ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
         ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
         return NETDEV_TX_OK;
      }
   }

   netif_trans_update(dev);

   return NETDEV_TX_OK;
}

int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	int ret;
	vos_ssr_protect(__func__);
	ret = __hdd_hard_start_xmit(skb, dev);
	vos_ssr_unprotect(__func__);
	return ret;
}

/**============================================================================
  @brief hdd_Ibss_GetStaId() - Get the StationID using the Peer Mac address

  @param pHddStaCtx : [in] pointer to HDD Station Context
  pMacAddress [in]  pointer to Peer Mac address
  staID [out]  pointer to Station Index
  @return    : VOS_STATUS_SUCCESS/VOS_STATUS_E_FAILURE
  ===========================================================================*/

VOS_STATUS hdd_Ibss_GetStaId(hdd_station_ctx_t *pHddStaCtx, v_MACADDR_t *pMacAddress, v_U8_t *staId)
{
    v_U8_t idx;

    for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++)
    {
        if (vos_mem_compare(&pHddStaCtx->conn_info.peerMacAddress[ idx ],
                pMacAddress, sizeof(v_MACADDR_t)))
        {
            *staId = pHddStaCtx->conn_info.staId[idx];
            return VOS_STATUS_SUCCESS;
        }
    }

    return VOS_STATUS_E_FAILURE;
}

/**============================================================================
  @brief __hdd_tx_timeout() - Function handles timeout during transmission.

  @param dev : [in] pointer to network device
  @return    : None
  ===========================================================================*/
void __hdd_tx_timeout(struct net_device *dev)
{
   hdd_adapter_t *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_context_t *pHddCtx;
   struct netdev_queue *txq;
   hdd_remain_on_chan_ctx_t *pRemainChanCtx;
   int i = 0;
   int status = 0;
   v_ULONG_t diff_in_jiffies = 0;
   hdd_station_ctx_t *pHddStaCtx = NULL;

   TX_TIMEOUT_TRACE(dev, VOS_MODULE_ID_HDD_DATA);

   if ( NULL == pAdapter )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
              FL("pAdapter is NULL"));
      VOS_ASSERT(0);
      return;
   }

   pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   status = wlan_hdd_validate_context(pHddCtx);
   if (status !=0 )
   {
       return;
   }

   pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
   if ( NULL == pHddStaCtx )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
              FL("pHddStaCtx is NULL"));
      return;
   }

   ++pAdapter->hdd_stats.hddTxRxStats.txTimeoutCount;

   //Getting here implies we disabled the TX queues for too long. Queues are 
   //disabled either because of disassociation or low resource scenarios. In
   //case of disassociation it is ok to ignore this. But if associated, we have
   //do possible recovery here

   VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
              "num_bytes AC0: %d AC1: %d AC2: %d AC3: %d",
              pAdapter->wmm_tx_queue[0].count,
              pAdapter->wmm_tx_queue[1].count,
              pAdapter->wmm_tx_queue[2].count,
              pAdapter->wmm_tx_queue[3].count);

   VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
              "tx_suspend AC0: %d AC1: %d AC2: %d AC3: %d",
              pAdapter->isTxSuspended[0],
              pAdapter->isTxSuspended[1],
              pAdapter->isTxSuspended[2],
              pAdapter->isTxSuspended[3]);

   for (i = 0; i < dev->num_tx_queues; i++)
   {
      txq = netdev_get_tx_queue(dev, i);
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                "Queue%d status: %d txq->trans_start %lu",
                 i, netif_tx_queue_stopped(txq),txq->trans_start);
   }

   VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
              "carrier state: %d", netif_carrier_ok(dev));

   /* continuousTxTimeoutCount will be reset whenever TL fetches packet
    * from HDD
    */
   ++pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount;

   diff_in_jiffies = jiffies - pAdapter->hdd_stats.hddTxRxStats.jiffiesLastTxTimeOut;
   if((pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount > 1)&&
     ((diff_in_jiffies) > (HDD_TX_TIMEOUT * 2 ))
     )
   {
        /*
         * In Open security case when there is no traffic is running, it may possible
         * tx time-out may once happen and later we recovered then we need to
         * reset the continuousTxTimeoutCount because it is only getting modified
         * when traffic is running. So if over a period of time if this count reaches
         * to HDD_TX_STALL_SSR_THRESHOLD  then host is triggering false subsystem restart.
         * so in genuine Tx Time out case kernel will call the tx time-out back to back at
         * interval of HDD_TX_TIMEOUT.So now we are checking if previous TX TIME out was
         * occurred more then twice of HDD_TX_TIMEOUT back then we may recovered here.
        */
        pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
        VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                  FL("This is false alarm so resetting the continuousTxTimeoutCount"));
   }

   //update last jiffies after the check
   pAdapter->hdd_stats.hddTxRxStats.jiffiesLastTxTimeOut = jiffies;

   if (!pHddStaCtx->conn_info.uIsAuthenticated) {
      VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                FL("TL is not in authenticated state so skipping SSR"));
      pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
      goto print_log;
   }
   if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
          HDD_TX_STALL_KICKDXE_THRESHOLD)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
                "%s: Request Kick DXE for recovery",__func__);
      WLANTL_TLDebugMessage(WLANTL_DEBUG_KICKDXE);
   }
   if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount ==
          HDD_TX_STALL_RECOVERY_THRESHOLD)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,
                "%s: Request firmware for recovery",__func__);
      WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP);
   }

   /*
    * This function is getting called in softirq context, So don't hold
    * any mutex.
    * There is no harm here in not holding the mutex as long as we are
    * not accessing the pRemainChanCtx contents.
    */
   pRemainChanCtx = hdd_get_remain_on_channel_ctx(pHddCtx);
   if (!pRemainChanCtx)
   {
      if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
          HDD_TX_STALL_SSR_THRESHOLD)
      {
          // Driver could not recover, issue SSR
          VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                    "%s: Cannot recover from Data stall Issue SSR",
                      __func__);
          WLANTL_FatalError();
          // reset count after issuing the SSR
          pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;
          return;
      }
   }
   else
   {
      VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                "Remain on channel in progress");
      /* The supplicant can retry "P2P Invitation Request" for 120 times
       * and so there is a possbility that we can remain off channel for
       * the entire duration of these retries(which can be max 60sec).
       * If we encounter such a case, let us not trigger SSR after 30sec
       * but wait for 60sec to let the device go on home channel and start
       * tx. If tx does not start within 70sec we will issue SSR.
       */
      if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount >
          HDD_TX_STALL_SSR_THRESHOLD_HIGH)
      {
          // Driver could not recover, issue SSR
          VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                    "%s: Cannot recover from Data stall Issue SSR",
                      __func__);
          WLANTL_FatalError();
          return;
      }
   }

print_log:
   /* If Tx stalled for a long time then *hdd_tx_timeout* is called
    * every 5sec. The TL debug spits out a lot of information on the
    * serial console, if it is called every time *hdd_tx_timeout* is
    * called then we may get a watchdog bite on the Application
    * processor, so ratelimit the TL debug logs.
    */
   if (__ratelimit(&hdd_tx_timeout_rs))
   {
      hdd_wmm_tx_snapshot(pAdapter);
      WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT);
   }
   /* Call fatal event if data stall is for
    * HDD_TX_STALL_FATAL_EVENT_THRESHOLD times
    */
   if (HDD_TX_STALL_FATAL_EVENT_THRESHOLD ==
       pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount)
      vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
                   WLAN_LOG_INDICATOR_HOST_DRIVER,
                   WLAN_LOG_REASON_DATA_STALL,
                   FALSE, TRUE);
}

/**============================================================================
  @brief hdd_tx_timeout() - Function called by OS if there is any
  timeout during transmission. Since HDD simply enqueues packet
  and returns control to OS right away, this would never be invoked

  @param dev : [in] pointer to network device
  @return    : None
  ===========================================================================*/
void hdd_tx_timeout(struct net_device *dev)
{
    vos_ssr_protect(__func__);
    __hdd_tx_timeout(dev);
    vos_ssr_unprotect(__func__);
}

/**============================================================================
  @brief __hdd_stats() - Function registered with the Linux OS for
  device TX/RX statistic

  @param dev      : [in] pointer to Libra network device
  
  @return         : pointer to net_device_stats structure
  ===========================================================================*/
struct net_device_stats* __hdd_stats(struct net_device *dev)
{
   hdd_adapter_t *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);

   if ( NULL == pAdapter )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
              FL("pAdapter is NULL"));
      VOS_ASSERT(0);
      return NULL;
   }
   
   return &pAdapter->stats;
}

struct net_device_stats* hdd_stats(struct net_device *dev)
{
    struct net_device_stats* dev_stats;

    vos_ssr_protect(__func__);
    dev_stats = __hdd_stats(dev);
    vos_ssr_unprotect(__func__);

    return dev_stats;
}

/**============================================================================
  @brief hdd_ibss_init_tx_rx() - Init function to initialize Tx/RX
  modules in HDD

  @param pAdapter : [in] pointer to adapter context
  @return         : VOS_STATUS_E_FAILURE if any errors encountered
                  : VOS_STATUS_SUCCESS otherwise
  ===========================================================================*/
void hdd_ibss_init_tx_rx( hdd_adapter_t *pAdapter )
{
   v_U8_t i;
   v_U8_t STAId = 0;
   hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
   hdd_ibss_peer_info_t *pPeerInfo = &pHddStaCtx->ibss_peer_info;
   v_U8_t pACWeights[] = {
                           HDD_SOFTAP_BK_WEIGHT_DEFAULT,
                           HDD_SOFTAP_BE_WEIGHT_DEFAULT,
                           HDD_SOFTAP_VI_WEIGHT_DEFAULT,
                           HDD_SOFTAP_VO_WEIGHT_DEFAULT
                         };

   pAdapter->isVosOutOfResource = VOS_FALSE;
   pAdapter->isVosLowResource = VOS_FALSE;

   // Since SAP model is used for IBSS also. Using same queue length as in SAP.
   pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN;
   pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN;
   pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN;
   pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN;

   for (STAId = 0; STAId < HDD_MAX_NUM_IBSS_STA; STAId++)
   {
      vos_mem_zero(&pPeerInfo->ibssStaInfo[STAId], sizeof(hdd_ibss_station_info_t));
      for (i = 0; i < NUM_TX_QUEUES; i ++)
      {
         hdd_list_init(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
      }
   }

   /* Update the AC weights suitable for SoftAP mode of operation */
   WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights);
}

/**============================================================================
  @brief hdd_ibss_deinit_tx_rx() - Deinit function to clean up Tx/RX
  modules in HDD

  @param pAdapter : [in] pointer to adapter context..
  @return         : VOS_STATUS_E_FAILURE if any errors encountered.
                  : VOS_STATUS_SUCCESS otherwise
  ===========================================================================*/
VOS_STATUS hdd_ibss_deinit_tx_rx( hdd_adapter_t *pAdapter )
{
   VOS_STATUS status = VOS_STATUS_SUCCESS;
   v_U8_t STAId = 0;
   hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
   hdd_ibss_peer_info_t * pPeerInfo = &pHddStaCtx->ibss_peer_info;
   hdd_list_node_t *anchor = NULL;
   skb_list_node_t *pktNode = NULL;
   struct sk_buff *skb = NULL;
   v_SINT_t i = -1;

   for (STAId = 0; STAId < HDD_MAX_NUM_IBSS_STA; STAId++)
   {
      if (VOS_FALSE == pPeerInfo->ibssStaInfo[STAId].isUsed)
      {
         continue;
      }
      for (i = 0; i < NUM_TX_QUEUES; i ++)
      {
         spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock);
         while (true)
         {
            status = hdd_list_remove_front ( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i], &anchor);

            if (VOS_STATUS_E_EMPTY != status)
            {
               //If success then we got a valid packet from some AC
               pktNode = list_entry(anchor, skb_list_node_t, anchor);
               skb = pktNode->skb;
               ++pAdapter->stats.tx_dropped;
               ++pAdapter->hdd_stats.hddTxRxStats.txFlushed;
               ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i];
               kfree_skb(skb);
               continue;
            }

            //current list is empty
            break;
         }
         pPeerInfo->ibssStaInfo[STAId].txSuspended[i] = VOS_FALSE;
         spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock);
      }
   }
   pAdapter->isVosLowResource = VOS_FALSE;

   return status;
}

/**============================================================================
  @brief hdd_init_tx_rx() - Init function to initialize Tx/RX
  modules in HDD

  @param pAdapter : [in] pointer to adapter context  
  @return         : VOS_STATUS_E_FAILURE if any errors encountered 
                  : VOS_STATUS_SUCCESS otherwise
  ===========================================================================*/
VOS_STATUS hdd_init_tx_rx( hdd_adapter_t *pAdapter )
{
   VOS_STATUS status = VOS_STATUS_SUCCESS;
   v_SINT_t i = -1;

   if ( NULL == pAdapter )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
              FL("pAdapter is NULL"));
      VOS_ASSERT(0);
      return VOS_STATUS_E_FAILURE;
   }

   pAdapter->isVosOutOfResource = VOS_FALSE;
   pAdapter->isVosLowResource = VOS_FALSE;

   //vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
   //Will be zeroed out during alloc

   while (++i != NUM_TX_QUEUES)
   { 
      pAdapter->isTxSuspended[i] = VOS_FALSE; 
      hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN);
   }

   return status;
}


/**============================================================================
  @brief hdd_deinit_tx_rx() - Deinit function to clean up Tx/RX
  modules in HDD

  @param pAdapter : [in] pointer to adapter context  
  @return         : VOS_STATUS_E_FAILURE if any errors encountered 
                  : VOS_STATUS_SUCCESS otherwise
  ===========================================================================*/
VOS_STATUS hdd_deinit_tx_rx( hdd_adapter_t *pAdapter )
{
   VOS_STATUS status = VOS_STATUS_SUCCESS;
   v_SINT_t i = -1;

   if ( NULL == pAdapter )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
              FL("pAdapter is NULL"));
      VOS_ASSERT(0);
      return VOS_STATUS_E_FAILURE;
   }

   status = hdd_flush_tx_queues(pAdapter);
   if (VOS_STATUS_SUCCESS != status)
       VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
          FL("failed to flush tx queues"));

   while (++i != NUM_TX_QUEUES) 
   {
      //Free up actual list elements in the Tx queue
      hdd_list_destroy( &pAdapter->wmm_tx_queue[i] );
   }

   return status;
}


/**============================================================================
  @brief hdd_disconnect_tx_rx() - Disconnect function to clean up Tx/RX
  modules in HDD

  @param pAdapter : [in] pointer to adapter context  
  @return         : VOS_STATUS_E_FAILURE if any errors encountered 
                  : VOS_STATUS_SUCCESS otherwise
  ===========================================================================*/
VOS_STATUS hdd_disconnect_tx_rx( hdd_adapter_t *pAdapter )
{
   return hdd_flush_tx_queues(pAdapter);
}


/**============================================================================
  @brief hdd_IsEAPOLPacket() - Checks the packet is EAPOL or not.

  @param pVosPacket : [in] pointer to vos packet  
  @return         : VOS_TRUE if the packet is EAPOL 
                  : VOS_FALSE otherwise
  ===========================================================================*/

v_BOOL_t hdd_IsEAPOLPacket( vos_pkt_t *pVosPacket )
{
    VOS_STATUS vosStatus  = VOS_STATUS_SUCCESS;
    v_BOOL_t   fEAPOL     = VOS_FALSE; 
    void       *pBuffer   = NULL;

    
    vosStatus = vos_pkt_peek_data( pVosPacket, (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET,
                          &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE );
    if ( VOS_IS_STATUS_SUCCESS( vosStatus ) )
    {
       if ( pBuffer && *(unsigned short*)pBuffer ==
                             vos_cpu_to_be16(HDD_ETHERTYPE_802_1_X) )
       {
          fEAPOL = VOS_TRUE;
       }
    }  
    
   return fEAPOL;
}

/**============================================================================
  @brief hdd_IsARP() - Checks the packet is ARP or not.

  @param pVosPacket : [in] pointer to vos packet
  @return         : VOS_TRUE if the packet is ARP
                  : VOS_FALSE otherwise
  ===========================================================================*/

v_BOOL_t hdd_IsARP( vos_pkt_t *pVosPacket )
{
    VOS_STATUS vosStatus  = VOS_STATUS_SUCCESS;
    v_BOOL_t   fIsARP     = VOS_FALSE;
    void       *pBuffer   = NULL;


    vosStatus = vos_pkt_peek_data( pVosPacket,
                           (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET,
                          &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE );
    if ( VOS_IS_STATUS_SUCCESS( vosStatus ) )
    {
       if ( pBuffer && *(unsigned short*)pBuffer ==
                                 vos_cpu_to_be16(HDD_ETHERTYPE_ARP) )
       {
          fIsARP = VOS_TRUE;
       }
    }

   return fIsARP;
}

#ifdef FEATURE_WLAN_WAPI // Need to update this function
/**============================================================================
  @brief hdd_IsWAIPacket() - Checks the packet is WAI or not.

  @param pVosPacket : [in] pointer to vos packet
  @return         : VOS_TRUE if the packet is WAI
                  : VOS_FALSE otherwise
  ===========================================================================*/

v_BOOL_t hdd_IsWAIPacket( vos_pkt_t *pVosPacket )
{
    VOS_STATUS vosStatus  = VOS_STATUS_SUCCESS;
    v_BOOL_t   fIsWAI     = VOS_FALSE;
    void       *pBuffer   = NULL;

    // Need to update this function
    vosStatus = vos_pkt_peek_data( pVosPacket, (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET,
                          &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE );

    if (VOS_IS_STATUS_SUCCESS( vosStatus ) )
    {
       if ( pBuffer && *(unsigned short*)pBuffer ==
                               vos_cpu_to_be16(HDD_ETHERTYPE_WAI) )
       {
          fIsWAI = VOS_TRUE;
       }
    }

   return fIsWAI;
}
#endif /* FEATURE_WLAN_WAPI */

/**============================================================================
  @brief hdd_tx_complete_cbk() - Callback function invoked by TL
  to indicate that a packet has been transmitted across the SDIO bus
  succesfully. OS packet resources can be released after this cbk.

  @param vosContext   : [in] pointer to VOS context   
  @param pVosPacket   : [in] pointer to VOS packet (containing skb) 
  @param vosStatusIn  : [in] status of the transmission 

  @return             : VOS_STATUS_E_FAILURE if any errors encountered 
                      : VOS_STATUS_SUCCESS otherwise
  ===========================================================================*/
VOS_STATUS hdd_tx_complete_cbk( v_VOID_t *vosContext, 
                                vos_pkt_t *pVosPacket, 
                                VOS_STATUS vosStatusIn )
{
   VOS_STATUS status = VOS_STATUS_SUCCESS;
   hdd_adapter_t *pAdapter = NULL;   
   hdd_context_t *pHddCtx = NULL;
   void* pOsPkt = NULL;
   
   if( ( NULL == vosContext ) || ( NULL == pVosPacket )  )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                       "%s: Null params being passed", __func__);
      return VOS_STATUS_E_FAILURE; 
   }

   //Return the skb to the OS
   status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE );
   if (!VOS_IS_STATUS_SUCCESS( status ))
   {
      //This is bad but still try to free the VOSS resources if we can
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                       "%s: Failure extracting skb from vos pkt", __func__);
      vos_pkt_return_packet( pVosPacket );
      return VOS_STATUS_E_FAILURE;
   }
   
   //Get the HDD context.
   pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
   //Get the Adapter context.
   pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_INFRA_STATION);
   if (pAdapter == NULL || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                    "%s: Invalid adapter %pK", __func__, pAdapter);
   }
   else
   {
      ++pAdapter->hdd_stats.hddTxRxStats.txCompleted;
   }

   kfree_skb((struct sk_buff *)pOsPkt); 

   //Return the VOS packet resources.
   status = vos_pkt_return_packet( pVosPacket );
   if (!VOS_IS_STATUS_SUCCESS( status ))
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                    "%s: Could not return VOS packet to the pool", __func__);
   }

   return status;
}

/**============================================================================
  @brief hdd_ibss_tx_fetch_packet_cbk() - Callback function invoked by TL to
  fetch a packet for transmission.

  @param vosContext   : [in] pointer to VOS context
  @param staId        : [in] Station for which TL is requesting a pkt
  @param ac           : [in] access category requested by TL
  @param pVosPacket   : [out] pointer to VOS packet packet pointer
  @param pPktMetaInfo : [out] pointer to meta info for the pkt

  @return             : VOS_STATUS_E_EMPTY if no packets to transmit
                      : VOS_STATUS_E_FAILURE if any errors encountered
                      : VOS_STATUS_SUCCESS otherwise
 ===========================================================================*/
VOS_STATUS hdd_ibss_tx_fetch_packet_cbk( v_VOID_t *vosContext,
                                    v_U8_t *pStaId,
                                    WLANTL_ACEnumType  ac,
                                    vos_pkt_t **ppVosPacket,
                                    WLANTL_MetaInfoType *pPktMetaInfo )
{
   VOS_STATUS status = VOS_STATUS_E_FAILURE;
   hdd_adapter_t *pAdapter = NULL;
   hdd_list_node_t *anchor = NULL;
   skb_list_node_t *pktNode = NULL;
   struct sk_buff *skb = NULL;
   vos_pkt_t *pVosPacket = NULL;
   v_MACADDR_t* pDestMacAddress = NULL;
   v_TIME_t timestamp;
   v_SIZE_t size = 0;
   v_U8_t STAId = WLAN_MAX_STA_COUNT;
   hdd_context_t *pHddCtx = NULL;
   hdd_station_ctx_t *pHddStaCtx = NULL;
   hdd_ibss_peer_info_t *pPeerInfo = NULL;
   v_U8_t proto_type = 0;
   v_U16_t packet_size;

   //Sanity check on inputs
   if ( ( NULL == vosContext ) ||
        ( NULL == pStaId ) ||
        ( NULL == ppVosPacket ) ||
        ( NULL == pPktMetaInfo ) )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                 "%s: Null Params being passed", __func__);
      return VOS_STATUS_E_FAILURE;
   }

   //Get the HDD context.
   pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
   if ( NULL == pHddCtx )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                 "%s: HDD adapter context is Null", __func__);
      return VOS_STATUS_E_FAILURE;
   }

   STAId = *pStaId;
   pAdapter = pHddCtx->sta_to_adapter[STAId];
   if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
   {
      VOS_ASSERT(0);
      return VOS_STATUS_E_FAILURE;
   }

  pHddStaCtx = &pAdapter->sessionCtx.station;
  pPeerInfo = &pHddStaCtx->ibss_peer_info;

  if (FALSE == pPeerInfo->ibssStaInfo[STAId].isUsed )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                 "%s: Unregistered STAId %d passed by TL", __func__, STAId);
      return VOS_STATUS_E_FAILURE;
   }

   ++pAdapter->hdd_stats.hddTxRxStats.txFetched;

   *ppVosPacket = NULL;

   //Make sure the AC being asked for is sane
   if( ac > WLANTL_MAX_AC || ac < 0)
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                 "%s: Invalid AC %d passed by TL", __func__, ac);
      return VOS_STATUS_E_FAILURE;
   }

   ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];

   //Get the vos packet before so that we are prepare for VOS low reseurce condition
   //This simplifies the locking and unlocking of Tx queue
   status = vos_pkt_wrap_data_packet( &pVosPacket,
                                      VOS_PKT_TYPE_TX_802_3_DATA,
                                      NULL, //OS Pkt is not being passed
                                      hdd_tx_low_resource_cbk,
                                      pAdapter );

   if ((status == VOS_STATUS_E_ALREADY) || (status == VOS_STATUS_E_RESOURCES))
   {
      //Remember VOS is in a low resource situation
      pAdapter->isVosOutOfResource = VOS_TRUE;
      ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
                 "%s: VOSS in Low Resource scenario", __func__);
      //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty.
      return VOS_STATUS_E_FAILURE;
   }

   /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there.
      Do not get next AC as the other branch does.
   */
   spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
   hdd_list_size(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &size);

   if (0 == size)
   {
      spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);
      vos_pkt_return_packet(pVosPacket);
      return VOS_STATUS_E_EMPTY;
   }

   status = hdd_list_remove_front( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &anchor );
   spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock);

   VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                       "%s: AC %d has packets pending", __func__, ac);

   if(VOS_STATUS_SUCCESS == status)
   {
      //If success then we got a valid packet from some AC
      pktNode = list_entry(anchor, skb_list_node_t, anchor);
      skb = pktNode->skb;
   }
   else
   {
      ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                 "%s: Error in de-queuing skb from Tx queue status = %d",
                 __func__, status );
      vos_pkt_return_packet(pVosPacket);
      return VOS_STATUS_E_FAILURE;
   }

   //Attach skb to VOS packet.
   status = vos_pkt_set_os_packet( pVosPacket, skb );
   if (status != VOS_STATUS_SUCCESS)
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                 "%s: Error attaching skb", __func__);
      vos_pkt_return_packet(pVosPacket);
      ++pAdapter->stats.tx_dropped;
      ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
      kfree_skb(skb);
      return VOS_STATUS_E_FAILURE;
   }

   //Return VOS packet to TL;
   *ppVosPacket = pVosPacket;

   //Fill out the meta information needed by TL
   vos_pkt_get_timestamp( pVosPacket, &timestamp );
   pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
   if ( 1 < size )
   {
       pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
   }
   else
   {
       pPktMetaInfo->bMorePackets = 0;
   }

   if(pAdapter->sessionCtx.station.conn_info.uIsAuthenticated == VOS_TRUE)
      pPktMetaInfo->ucIsEapol = 0;
   else
      pPktMetaInfo->ucIsEapol = hdd_IsEAPOLPacket( pVosPacket ) ? 1 : 0;

   if ((NULL != pHddCtx) &&
       (pHddCtx->cfg_ini->gEnableDebugLog))
   {
      proto_type = vos_pkt_get_proto_type(skb,
                                          pHddCtx->cfg_ini->gEnableDebugLog);
      if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "IBSS STA TX EAPOL");
      }
      else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "IBSS STA TX DHCP");
      }
      else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "IBSS STA TX ARP");
      }
   }

   vos_pkt_get_packet_length( pVosPacket,&packet_size );
   if ( HDD_ETHERTYPE_ARP_SIZE == packet_size )
       pPktMetaInfo->ucIsArp = hdd_IsARP( pVosPacket ) ? 1 : 0;

   pPktMetaInfo->ucUP = pktNode->userPriority;
   pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
   pPktMetaInfo->ucType = 0;

   //Extract the destination address from ethernet frame
   pDestMacAddress = (v_MACADDR_t*)skb->data;

   // we need 802.3 to 802.11 frame translation
   // (note that Bcast/Mcast will be translated in SW, unicast in HW)
   pPktMetaInfo->ucDisableFrmXtl = 0;
   pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
   pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;

   if ( (pPeerInfo->ibssStaInfo[STAId].txSuspended[ac]) &&
        (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) ))
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                 "%s: TX queue re-enabled", __func__);
      pPeerInfo->ibssStaInfo[STAId].txSuspended[ac] = VOS_FALSE;
      netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb));
   }

   // We're giving the packet to TL so consider it transmitted from
   // a statistics perspective.  We account for it here instead of
   // when the packet is returned for two reasons.  First, TL will
   // manipulate the skb to the point where the len field is not
   // accurate, leading to inaccurate byte counts if we account for
   // it later.  Second, TL does not provide any feedback as to
   // whether or not the packet was successfully sent over the air,
   // so the packet counts will be the same regardless of where we
   // account for them
   pAdapter->stats.tx_bytes += skb->len;
   ++pAdapter->stats.tx_packets;
   ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
   ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
   pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;

   VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
              "%s: Valid VOS PKT returned to TL", __func__);

   return status;
}

/**============================================================================
  @brief hdd_tx_fetch_packet_cbk() - Callback function invoked by TL to 
  fetch a packet for transmission.

  @param vosContext   : [in] pointer to VOS context  
  @param staId        : [in] Station for which TL is requesting a pkt
  @param ac           : [in] access category requested by TL
  @param pVosPacket   : [out] pointer to VOS packet packet pointer
  @param pPktMetaInfo : [out] pointer to meta info for the pkt 
  
  @return             : VOS_STATUS_E_EMPTY if no packets to transmit
                      : VOS_STATUS_E_FAILURE if any errors encountered 
                      : VOS_STATUS_SUCCESS otherwise
  ===========================================================================*/
VOS_STATUS hdd_tx_fetch_packet_cbk( v_VOID_t *vosContext,
                                    v_U8_t *pStaId,
                                    WLANTL_ACEnumType  ac,
                                    vos_pkt_t **ppVosPacket,
                                    WLANTL_MetaInfoType *pPktMetaInfo )
{
   VOS_STATUS status = VOS_STATUS_E_FAILURE;
   hdd_adapter_t *pAdapter = NULL;
   hdd_context_t *pHddCtx = NULL;
   hdd_list_node_t *anchor = NULL;
   skb_list_node_t *pktNode = NULL;
   struct sk_buff *skb = NULL;
   vos_pkt_t *pVosPacket = NULL;
   v_MACADDR_t* pDestMacAddress = NULL;
   v_TIME_t timestamp;
   WLANTL_ACEnumType newAc;
   v_SIZE_t size = 0;
   v_U16_t packet_size;
   tANI_U8   acAdmitted, i;
   v_U8_t proto_type = 0;
   WLANTL_ACEnumType actualAC;
   v_BOOL_t arp_pkt;

   //Sanity check on inputs
   if ( ( NULL == vosContext ) || 
        ( NULL == pStaId ) || 
        ( NULL == ppVosPacket ) ||
        ( NULL == pPktMetaInfo ) )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                          "%s: Null Params being passed", __func__);
      return VOS_STATUS_E_FAILURE;
   }

   //Get the HDD context.
   pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
   if(pHddCtx == NULL)
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                        "%s: HDD adapter context is Null", __func__);
      return VOS_STATUS_E_FAILURE;
   }
   pAdapter = pHddCtx->sta_to_adapter[*pStaId];
   if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
              FL("invalid adapter:%pK for staId:%u"), pAdapter, *pStaId);
      VOS_ASSERT(0);
      return VOS_STATUS_E_FAILURE;
   }

   ++pAdapter->hdd_stats.hddTxRxStats.txFetched;

   *ppVosPacket = NULL;

   //Make sure the AC being asked for is sane
   if (ac > WLANTL_AC_HIGH_PRIO || ac < 0)
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                            "%s: Invalid QId %d passed by TL", __func__, ac);
      return VOS_STATUS_E_FAILURE;
   }

   ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac];

#ifdef HDD_WMM_DEBUG
   VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
                              "%s: AC %d passed by TL", __func__, ac);
#endif // HDD_WMM_DEBUG

   // do we have any packets pending in this AC?
   hdd_list_size( &pAdapter->wmm_tx_queue[ac], &size ); 
   if( size >  0 )
   {
       // yes, so process it
#ifdef HDD_WMM_DEBUG
       VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
                       "%s: AC %d has packets pending", __func__, ac);
#endif // HDD_WMM_DEBUG
   }
   else
   {
      ++pAdapter->hdd_stats.hddTxRxStats.txFetchEmpty;
#ifdef HDD_WMM_DEBUG
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
                   "%s: no packets pending", __func__);
#endif // HDD_WMM_DEBUG
      return VOS_STATUS_E_FAILURE;
   }

   // Note here that we are not checking "wmmAcAccessAllowed" for packets
   // in new queue since there is no one AC associated to the new queue.
   // Since there will be either eapol or dhcp pkts in new queue overlooking
   // this should be okay from implicit QoS perspective.
   if (ac != WLANTL_AC_HIGH_PRIO)
   {
      // We find an AC with packets
      // or we determine we have no more packets to send
      // HDD is not allowed to change AC.

      // has this AC been admitted? or
      // To allow EAPOL packets when not authenticated
      if (unlikely((0==pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed) &&
                   (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.uIsAuthenticated))
      {
         ++pAdapter->hdd_stats.hddTxRxStats.txFetchEmpty;
#ifdef HDD_WMM_DEBUG
         VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
                    "%s: no packets pending", __func__);
#endif // HDD_WMM_DEBUG
         return VOS_STATUS_E_FAILURE;
      }
   }

   //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources 
   //This simplifies the locking and unlocking of Tx queue
   status = vos_pkt_wrap_data_packet( &pVosPacket, 
                                      VOS_PKT_TYPE_TX_802_3_DATA, 
                                      NULL, //OS Pkt is not being passed
                                      hdd_tx_low_resource_cbk, 
                                      pAdapter );

   if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES)
   {
      //Remember VOS is in a low resource situation
      pAdapter->isVosOutOfResource = VOS_TRUE;
      ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources;
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: VOSS in Low Resource scenario", __func__);
      //TL will now think we have no more packets in this AC
      return VOS_STATUS_E_FAILURE;
   }

   //Remove the packet from the queue
   spin_lock_bh(&pAdapter->wmm_tx_queue[ac].lock);
   status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[ac], &anchor );
   spin_unlock_bh(&pAdapter->wmm_tx_queue[ac].lock);

   if(VOS_STATUS_SUCCESS == status)
   {
      //If success then we got a valid packet from some AC
      pktNode = list_entry(anchor, skb_list_node_t, anchor);
      skb = pktNode->skb;
      actualAC = hddWmmUpToAcMap[pktNode->userPriority];
      if (actualAC >= WLANTL_MAX_AC)
      {
         /* To fix klocwork */
         VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
         "%s: Invalid AC for packet:%d", __func__, actualAC);
         actualAC = WLANTL_AC_BE;
      }
   }
   else
   {
      ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, "%s: Error in de-queuing "
         "skb from Tx queue status = %d", __func__, status );
      vos_pkt_return_packet(pVosPacket);
      return VOS_STATUS_E_FAILURE;
   }
   arp_pkt = vos_is_arp_pkt(skb, false);
   //Attach skb to VOS packet.
   status = vos_pkt_set_os_packet( pVosPacket, skb );
   if (status != VOS_STATUS_SUCCESS)
   {

      if (arp_pkt)
      {
          ++pAdapter->hdd_stats.hddArpStats.txDropped;
          pAdapter->hdd_stats.hddArpStats.reason = HDD_ERROR_ATTACHING_SKB;
          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 "%s :Error attaching skb,ARP packet droped", __func__);
      }

      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: Error attaching skb", __func__);
      vos_pkt_return_packet(pVosPacket);
      ++pAdapter->stats.tx_dropped;
      ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
      kfree_skb(skb);
      return VOS_STATUS_E_FAILURE;
   }

   //Just being paranoid. To be removed later
   if(pVosPacket == NULL)
   {

      if (arp_pkt)
      {
          ++pAdapter->hdd_stats.hddArpStats.txDropped;
          pAdapter->hdd_stats.hddArpStats.reason = HDD_VOS_PACKET_RETURNED_BY_VOSS_IS_NULL;
          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
          "%s :VOS packet returned by VOSS is NULL,ARP packet droped",
          __func__);
      }

      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: VOS packet returned by VOSS is NULL", __func__);
      ++pAdapter->stats.tx_dropped;
      ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
      kfree_skb(skb);
      return VOS_STATUS_E_FAILURE;
   }

#ifdef WLAN_FEATURE_LINK_LAYER_STATS
   if (vos_is_macaddr_multicast((v_MACADDR_t*)skb->data))
   {
        pAdapter->hdd_stats.hddTxRxStats.txMcast[actualAC]++;
   }

#endif

   wlan_hdd_tdls_notify_packet(pAdapter, skb);

   //Return VOS packet to TL;
   *ppVosPacket = pVosPacket;

   //Fill out the meta information needed by TL
   //FIXME This timestamp is really the time stamp of wrap_data_packet
   vos_pkt_get_timestamp( pVosPacket, &timestamp );
   pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp;
   
   if(pAdapter->sessionCtx.station.conn_info.uIsAuthenticated == VOS_TRUE)
      pPktMetaInfo->ucIsEapol = 0;       
   else
      pPktMetaInfo->ucIsEapol = hdd_IsEAPOLPacket( pVosPacket ) ? 1 : 0;

   if (pPktMetaInfo->ucIsEapol)
       wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED);
   if ((NULL != pHddCtx) &&
       (pHddCtx->cfg_ini->gEnableDebugLog))
   {
      proto_type = vos_pkt_get_proto_type(skb,
                                          pHddCtx->cfg_ini->gEnableDebugLog);
      if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "STA TX EAPOL");
      }
      else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "STA TX DHCP");
      }
      else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "STA TX ARP");
      }
   }

   vos_pkt_get_packet_length( pVosPacket,&packet_size );
   if( HDD_ETHERTYPE_ARP_SIZE == packet_size )
      pPktMetaInfo->ucIsArp = hdd_IsARP( pVosPacket ) ? 1 : 0;

   if(pPktMetaInfo->ucIsArp)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                 "%s :STA TX ARP Received in TL ",__func__);
   }

#ifdef FEATURE_WLAN_WAPI
   // Override usIsEapol value when its zero for WAPI case
   pPktMetaInfo->ucIsWai = hdd_IsWAIPacket( pVosPacket ) ? 1 : 0;
#endif /* FEATURE_WLAN_WAPI */

   /* 1. Check if ACM is set for this AC
    * 2. If set, check if this AC had already admitted
    * 3. If not already admitted, downgrade the UP to next best UP
    * 4. Allow only when medium time is non zero when Addts accepted
    *    else downgrade traffic. we opted downgrading over Delts when
    *    medium time is zero because while doing downgradig driver is not
    *    clearing the wmm context so consider in subsequent roaming
    *    if AP (new or same AP) accept the Addts with valid medium time
    *    no application support is required where if we have opted
    *    delts Applications have to again do Addts or STA will never
    *    go for Addts.
    */
   pPktMetaInfo->ac = actualAC;
   if(!pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcAccessRequired ||
      (pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcTspecValid &&
       pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcTspecInfo.medium_time))
   {
      pPktMetaInfo->ucUP = pktNode->userPriority;
      pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
   }
   else
   {
     //Downgrade the UP
      acAdmitted = pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcTspecValid;
      newAc = WLANTL_AC_BK;
      for (i=actualAC-1; i>0; i--)
      {
         if (pAdapter->hddWmmStatus.wmmAcStatus[i].wmmAcAccessRequired == 0)
         {
             newAc = i;
             break;
         }
      }
      pPktMetaInfo->ucUP = hddWmmAcToHighestUp[newAc];
      pPktMetaInfo->ucTID = pPktMetaInfo->ucUP;
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_LOW,
               "Downgrading UP %d to UP %d ",
                pktNode->userPriority, pPktMetaInfo->ucUP);
   }

   if (pHddCtx->cfg_ini->gEnableRoamDelayStats)
   {
       vos_record_roam_event(e_TL_FIRST_XMIT_TIME, NULL, 0);
   }

   pPktMetaInfo->ucType = 0;          //FIXME Don't know what this is
   pPktMetaInfo->ucDisableFrmXtl = 0; //802.3 frame so we need to xlate
   if ( 1 < size )
   {
       pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send
   }
   else
   {
       pPktMetaInfo->bMorePackets = 0;
   }

   //Extract the destination address from ethernet frame
   pDestMacAddress = (v_MACADDR_t*)skb->data;
   pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0;
   pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0;

   

   // if we are in a backpressure situation see if we can turn the hose back on
   if ( (pAdapter->isTxSuspended[ac]) &&
        (size <= HDD_TX_QUEUE_LOW_WATER_MARK) )
   {
      ++pAdapter->hdd_stats.hddTxRxStats.txFetchDePressured;
      ++pAdapter->hdd_stats.hddTxRxStats.txFetchDePressuredAC[ac];
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                 "%s: TX queue[%d] re-enabled", __func__, ac);
      pAdapter->isTxSuspended[ac] = VOS_FALSE;      
      netif_tx_wake_queue(netdev_get_tx_queue(pAdapter->dev, 
                                        skb_get_queue_mapping(skb) ));
      MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_WAKE_NETDEV,
                       pAdapter->sessionId, ac));
   }


   // We're giving the packet to TL so consider it transmitted from
   // a statistics perspective.  We account for it here instead of
   // when the packet is returned for two reasons.  First, TL will
   // manipulate the skb to the point where the len field is not
   // accurate, leading to inaccurate byte counts if we account for
   // it later.  Second, TL does not provide any feedback as to
   // whether or not the packet was successfully sent over the air,
   // so the packet counts will be the same regardless of where we
   // account for them
   pAdapter->stats.tx_bytes += skb->len;
   ++pAdapter->stats.tx_packets;
   ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued;
   ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac];
   pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0;

   if((pHddCtx->cfg_ini->thermalMitigationEnable) &&
      (WLAN_HDD_INFRA_STATION == pAdapter->device_mode))
   {
      if(mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
      {
         VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                    "%s: Tm Lock fail", __func__);
         return VOS_STATUS_E_FAILURE;
      }
      if(WLAN_HDD_TM_LEVEL_1 < pHddCtx->tmInfo.currentTmLevel)
      {
         if(0 == pHddCtx->tmInfo.txFrameCount)
         {
            /* Just recovered from sleep timeout */
            pHddCtx->tmInfo.lastOpenTs = timestamp;
         }

         if((VOS_FALSE == pHddCtx->tmInfo.qBlocked) &&
            ((timestamp - pHddCtx->tmInfo.lastOpenTs) > (pHddCtx->tmInfo.tmAction.txOperationDuration / 10)) &&
            (pHddCtx->tmInfo.txFrameCount >= pHddCtx->tmInfo.tmAction.txBlockFrameCountThreshold))
         {
            /* During TX open duration, TX frame count is larger than threshold
             * Block TX during Sleep time */
            hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
            netif_tx_stop_all_queues(pAdapter->dev);
            pHddCtx->tmInfo.qBlocked = VOS_TRUE;
            pHddCtx->tmInfo.lastblockTs = timestamp;
            if(VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&pHddCtx->tmInfo.txSleepTimer))
            {
               vos_timer_start(&pHddCtx->tmInfo.txSleepTimer, pHddCtx->tmInfo.tmAction.txSleepDuration);
            }
         }
         else if(((timestamp - pHddCtx->tmInfo.lastOpenTs) > (pHddCtx->tmInfo.tmAction.txOperationDuration / 10)) &&
                 (pHddCtx->tmInfo.txFrameCount < pHddCtx->tmInfo.tmAction.txBlockFrameCountThreshold))
         {
            /* During TX open duration, TX frame count is less than threshold
             * Reset count and timestamp to prepare next cycle */
            pHddCtx->tmInfo.lastOpenTs = timestamp;
            pHddCtx->tmInfo.txFrameCount = 0;
         }
         else
         {
            /* Do Nothing */
         }
         pHddCtx->tmInfo.txFrameCount++;
      }
      mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
   }


#ifdef HDD_WMM_DEBUG
   VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,"%s: Valid VOS PKT returned to TL", __func__);
#endif // HDD_WMM_DEBUG

   return status;
}


/**============================================================================
  @brief hdd_tx_low_resource_cbk() - Callback function invoked in the 
  case where VOS packets are not available at the time of the call to get 
  packets. This callback function is invoked by VOS when packets are 
  available.

  @param pVosPacket : [in]  pointer to VOS packet 
  @param userData   : [in]  opaque user data that was passed initially 
  
  @return           : VOS_STATUS_E_FAILURE if any errors encountered, 
                    : VOS_STATUS_SUCCESS otherwise
  =============================================================================*/
VOS_STATUS hdd_tx_low_resource_cbk( vos_pkt_t *pVosPacket, 
                                    v_VOID_t *userData )
{
   VOS_STATUS status;
   v_SINT_t i = 0;
   v_SIZE_t size = 0;
   hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData;
   
   if (NULL == pAdapter || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                 FL("Invalid adapter %pK"), pAdapter);
      return VOS_STATUS_E_FAILURE;
   }

   //Return the packet to VOS. We just needed to know that VOS is out of low resource
   //situation. Here we will only signal TL that there is a pending data for a STA. 
   //VOS packet will be requested (if needed) when TL comes back to fetch data.
   vos_pkt_return_packet( pVosPacket );

   pAdapter->isVosOutOfResource = VOS_FALSE;

   //Indicate to TL that there is pending data if a queue is non empty
   for( i=NUM_TX_QUEUES-1; i>=0; --i )
   {
      size = 0;
      hdd_list_size( &pAdapter->wmm_tx_queue[i], &size );
      if ( size > 0 )
      {
         status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, 
                                        (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId [0], 
                                        (WLANTL_ACEnumType)i );
         if( !VOS_IS_STATUS_SUCCESS( status ) )
         {
            VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                           "%s: Failure in indicating pkt to TL for ac=%d", __func__, i);
         }
      }
   }

   return VOS_STATUS_SUCCESS;
}

static void hdd_mon_add_rx_radiotap_hdr (struct sk_buff *skb,
             int rtap_len,  v_PVOID_t  pRxPacket, hdd_mon_ctx_t *pMonCtx)
{
    u8 rtap_temp[28] = {0};
    struct ieee80211_radiotap_header *rthdr;
    unsigned char *pos;
    u32 mac_time;
    u16 rx_flags = 0;
    u16 rateIdx;
    u16 channel_flags = 0;
    u8 rfBand;
    s8 currentRSSI, currentRSSI0, currentRSSI1;
    s8 noise;

    mac_time = WDA_GET_RX_TIMESTAMP(pRxPacket);
    rateIdx = WDA_GET_RX_MAC_RATE_IDX(pRxPacket);
    if( rateIdx >= 210 && rateIdx <= 217)
       rateIdx-=202;
    if( rateIdx >= 218 && rateIdx <= 225 )
       rateIdx-=210;

    if(rateIdx >= (sizeof(gRatefromIdx)/ sizeof(int))) {
       VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                  "%s: invalid rateIdx %d make it 0", __func__, rateIdx);
       rateIdx = 0;
    }
    rfBand = WDA_GET_RX_RFBAND(pRxPacket);
    if (IS_5G_BAND(rfBand))
        channel_flags |= IEEE80211_CHAN_5GHZ;
    else
        channel_flags |= IEEE80211_CHAN_2GHZ;
    currentRSSI0 = WDA_GETRSSI0(pRxPacket) - 100;
    currentRSSI1 = WDA_GETRSSI1(pRxPacket) - 100;
    currentRSSI  = (currentRSSI0 > currentRSSI1) ? currentRSSI0 : currentRSSI1;
    noise = WDA_GET_RX_SNR(pRxPacket);

    rthdr = (struct ieee80211_radiotap_header *)(&rtap_temp[0]);

    /* radiotap header, set always present flags */
    rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) |
                                    (1 << IEEE80211_RADIOTAP_FLAGS) |
                                    (1 << IEEE80211_RADIOTAP_CHANNEL) |
                                    (1 << IEEE80211_RADIOTAP_RATE) |
                                    (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
                                    (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
                                    (1 << IEEE80211_RADIOTAP_RX_FLAGS));
    rthdr->it_len = cpu_to_le16(rtap_len);

    pos = (unsigned char *) (rthdr + 1);

    /* IEEE80211_RADIOTAP_TSFT */
    put_unaligned_le64(mac_time, pos);
    pos += 8;

    /* IEEE80211_RADIOTAP_FLAGS */
    *pos = 0;
    pos++;

    /* IEEE80211_RADIOTAP_RATE */
    *pos = gRatefromIdx[rateIdx]/5;
    pos++;

    /* IEEE80211_RADIOTAP_CHANNEL */
    put_unaligned_le16(pMonCtx->ChannelNo, pos);
    pos += 2;
    put_unaligned_le16(channel_flags, pos);
    pos += 2;

    /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
    *pos = currentRSSI;
    pos++;

    /* IEEE80211_RADIOTAP_DBM_ANTNOISE */
    *pos = noise;
    pos++;

    if ((pos - (u8 *)rthdr) & 1)
        pos++;
    put_unaligned_le16(rx_flags, pos);
    pos += 2;

    memcpy(skb_push(skb, rtap_len), &rtap_temp[0], rtap_len);
}


VOS_STATUS  hdd_rx_packet_monitor_cbk(v_VOID_t *vosContext,vos_pkt_t *pVosPacket, int conversion)
{
  struct sk_buff *skb = NULL;
  VOS_STATUS status = VOS_STATUS_E_FAILURE;
  hdd_adapter_t *pAdapter = NULL;
  hdd_context_t *pHddCtx = NULL;
  hdd_mon_ctx_t *pMonCtx = NULL;
  v_PVOID_t pvBDHeader = NULL;
  int rxstat;
  int needed_headroom = 0;


  //Sanity check on inputs
   if ( ( NULL == vosContext ) ||
        ( NULL == pVosPacket ) )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                         "%s: Null params being passed", __func__);
      return VOS_STATUS_E_FAILURE;
   }

   pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );

   if (NULL == pHddCtx)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                 FL("Failed to get pHddCtx from vosContext"));
      vos_pkt_return_packet( pVosPacket );
      return VOS_STATUS_E_FAILURE;
   }

   pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR);
   if ((NULL == pAdapter)  || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) )
   {
      VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                 FL("Invalid adapter %pK for MONITOR MODE"), pAdapter);
      vos_pkt_return_packet( pVosPacket );
      return VOS_STATUS_E_FAILURE;
   }

    status =  WDA_DS_PeekRxPacketInfo( pVosPacket, (v_PVOID_t)&pvBDHeader, 1/*Swap BD*/ );
    if ( NULL == pvBDHeader )
    {
      VOS_TRACE( VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
                 "Cannot extract BD header");
      /* Drop packet */
      vos_pkt_return_packet(pVosPacket);
      return VOS_STATUS_E_FAILURE;
    }

   ++pAdapter->hdd_stats.hddTxRxStats.rxChains;
   status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_TRUE );
   if(!VOS_IS_STATUS_SUCCESS( status ))
    {
        ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
        VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                               "%s: Failure extracting skb from vos pkt", __func__);
        vos_pkt_return_packet( pVosPacket );
        return VOS_STATUS_E_FAILURE;
    }

    if(!conversion)
    {
         pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter);
         needed_headroom = sizeof(struct ieee80211_radiotap_header) + 18;
         hdd_mon_add_rx_radiotap_hdr( skb, needed_headroom, pvBDHeader, pMonCtx );
    }

    skb_reset_mac_header( skb );
    skb->dev = pAdapter->dev;
    skb->pkt_type = PACKET_OTHERHOST;
    skb->protocol = htons(ETH_P_802_2);
    skb->ip_summed = CHECKSUM_NONE;
    ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
    ++pAdapter->stats.rx_packets;
    pAdapter->stats.rx_bytes += skb->len;

    rxstat = netif_rx_ni(skb);
    if (NET_RX_SUCCESS == rxstat)
    {
       ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
       ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
    }
    else
    {
       ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
    }

   status = vos_pkt_return_packet( pVosPacket );
   if(!VOS_IS_STATUS_SUCCESS( status ))
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: Failure returning vos pkt", __func__);
   }
   pAdapter->dev->last_rx = jiffies;

return status;
}

bool hdd_is_duplicate_ip_arp(struct sk_buff *skb)
{
   struct in_ifaddr **ifap = NULL;
   struct in_ifaddr *ifa = NULL;
   struct in_device *in_dev;
   uint32_t arp_ip,if_ip;

   if (NULL == skb)
      return false;

   arp_ip = hdd_get_arp_src_ip(skb);

   if(!skb->dev) return false;

   in_dev = __in_dev_get_rtnl(skb->dev);

   if (in_dev) {
      for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
           ifap = &ifa->ifa_next) {
         if (!strcmp(skb->dev->name, ifa->ifa_label))
            break;
      }
   }
   if (ifa && ifa->ifa_local) {

        if_ip = ntohl(ifa->ifa_local);
        if (if_ip == arp_ip) {
         return true;
        }
   }

   return false;
}

/**============================================================================
  @brief hdd_rx_packet_cbk() - Receive callback registered with TL.
  TL will call this to notify the HDD when one or more packets were
  received for a registered STA.

  @param vosContext      : [in] pointer to VOS context  
  @param pVosPacketChain : [in] pointer to VOS packet chain
  @param staId           : [in] Station Id
  @param pRxMetaInfo     : [in] pointer to meta info for the received pkt(s) 

  @return                : VOS_STATUS_E_FAILURE if any errors encountered, 
                         : VOS_STATUS_SUCCESS otherwise
  ===========================================================================*/
VOS_STATUS hdd_rx_packet_cbk( v_VOID_t *vosContext, 
                              vos_pkt_t *pVosPacketChain,
                              v_U8_t staId,
                              WLANTL_RxMetaInfoType* pRxMetaInfo )
{
   hdd_adapter_t *pAdapter = NULL;
   hdd_context_t *pHddCtx = NULL;
   VOS_STATUS status = VOS_STATUS_E_FAILURE;
   int rxstat;
   struct sk_buff *skb = NULL;
   vos_pkt_t* pVosPacket;
   vos_pkt_t* pNextVosPacket;
   v_U8_t proto_type = 0;
   v_BOOL_t arp_pkt;

   //Sanity check on inputs
   if ( ( NULL == vosContext ) || 
        ( NULL == pVosPacketChain ) ||
        ( NULL == pRxMetaInfo ) )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                         "%s: Null params being passed", __func__);
      return VOS_STATUS_E_FAILURE;
   }

   pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext );
   if ( NULL == pHddCtx )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                           "%s: HDD adapter context is Null", __func__);
      return VOS_STATUS_E_FAILURE;
   }

   pAdapter = pHddCtx->sta_to_adapter[staId];
   if ((NULL == pAdapter)  || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) )
   {
      VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                 FL("Invalid adapter %pK for staId %u"), pAdapter, staId);
      return VOS_STATUS_E_FAILURE;
   }

   ++pAdapter->hdd_stats.hddTxRxStats.rxChains;

   // walk the chain until all are processed
   pVosPacket = pVosPacketChain;
   do
   {
      // get the pointer to the next packet in the chain
      // (but don't unlink the packet since we free the entire chain later)
      status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE);

      // both "success" and "empty" are acceptable results
      if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
      {

        if(hdd_IsARP(pVosPacket))
        {
            ++pAdapter->hdd_stats.hddArpStats.rxDropped;
            pAdapter->hdd_stats.hddArpStats.reason = HDD_FAILURE_WALKING_PACKET_CHAIN;
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
            "%s: ARP packet Drop: Failure walking packet chain", __func__);
        }
         ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
         VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                         "%s: Failure walking packet chain", __func__);
         return VOS_STATUS_E_FAILURE;
      }

      // Extract the OS packet (skb).
      status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_FALSE );
      if(!VOS_IS_STATUS_SUCCESS( status ))
      {

        if(hdd_IsARP(pVosPacket))
        {
            ++pAdapter->hdd_stats.hddArpStats.rxDropped;
            pAdapter->hdd_stats.hddArpStats.reason = HDD_FAILURE_EXTRACTING_SKB_FROM_VOS_PKT;
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
             "%s: ARP packet Dropped: Failure extracting skb from vos pkt",
             __func__);
        }
         ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
         VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                                "%s: Failure extracting skb from vos pkt", __func__);
         return VOS_STATUS_E_FAILURE;
      }

      if (TRUE == hdd_IsEAPOLPacket( pVosPacket ))
          wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);

      pVosPacket->pSkb = NULL;

      if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
      {
         VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
           "Magic cookie(%x) for adapter sanity verification is invalid", pAdapter->magic);
         return eHAL_STATUS_FAILURE;
      }

#ifdef FEATURE_WLAN_TDLS
    if ((eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) &&
         0 != pHddCtx->connected_peer_count)
    {
        hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
        u8 mac[6];

        memcpy(mac, skb->data+6, 6);

        if (vos_is_macaddr_group((v_MACADDR_t *)mac)) {
            VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED,
                      "rx broadcast packet, not adding to peer list");
        } else if ((memcmp(pHddStaCtx->conn_info.bssId,
                            mac, 6) != 0) && (pRxMetaInfo->isStaTdls)) {
            wlan_hdd_tdls_update_rx_pkt_cnt_n_rssi(pAdapter, mac,
                    pRxMetaInfo->rssiAvg);
        } else {
            VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED,
                       "rx packet sa is bssid, not adding to peer list");
        }
    }
#endif
      if (pHddCtx->cfg_ini->gEnableDebugLog)
      {
         proto_type = vos_pkt_get_proto_type(skb,
                                             pHddCtx->cfg_ini->gEnableDebugLog);
         if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
         {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "STA RX EAPOL");
         }
         else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type)
         {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "STA RX DHCP");
         }
         else if (VOS_PKT_PROTO_TYPE_ARP & proto_type)
         {
            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      "STA RX ARP");
         }
      }

      arp_pkt = vos_is_arp_pkt(skb, false);

      if (arp_pkt)
      {
         ++pAdapter->hdd_stats.hddArpStats.rxCount;
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                   "%s :STA RX ARP received",__func__);
      }

      if (pHddCtx->rx_wow_dump) {
          if (!(VOS_PKT_PROTO_TYPE_ARP & proto_type) &&
              !(VOS_PKT_PROTO_TYPE_EAPOL & proto_type))
             hdd_log_ip_addr(skb);
          pHddCtx->rx_wow_dump = false;
      }

      if (pHddCtx->cfg_ini->gEnableRoamDelayStats)
      {
          vos_record_roam_event(e_HDD_RX_PKT_CBK_TIME, (void *)skb, 0);
      }
      if (( NULL != pHddCtx ) &&
         (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP))
      {
          hdd_dump_dhcp_pkt(skb, RX_PATH);
      }

      skb->dev = pAdapter->dev;
      skb->protocol = eth_type_trans(skb, skb->dev);
      skb->ip_summed = CHECKSUM_NONE;
      ++pAdapter->hdd_stats.hddTxRxStats.rxPackets;
      ++pAdapter->stats.rx_packets;
      pAdapter->stats.rx_bytes += skb->len;

      if (arp_pkt)
      {
         pAdapter->dad = hdd_is_duplicate_ip_arp(skb);
         if(pAdapter->dad)
         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "%s :Duplicate IP detected",__func__);
      }
#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK
       vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock,
                          HDD_WAKE_LOCK_DURATION,
                          WIFI_POWER_EVENT_WAKELOCK_HOLD_RX);
#endif
      if (pNextVosPacket)
      {
          rxstat = netif_rx(skb);
      }
      else
      {
          rxstat = netif_rx_ni(skb);
      }

      if (NET_RX_SUCCESS == rxstat)
      {

        if (arp_pkt)
        {
           ++pAdapter->hdd_stats.hddArpStats.rxDelivered;
           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                     "STA RX ARP packet Delivered to net stack");
        }

         ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
         ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
      }
      else
      {

        if (arp_pkt)
        {
           ++pAdapter->hdd_stats.hddArpStats.rxRefused;
           pAdapter->hdd_stats.hddArpStats.reason = HDD_STA_RX_ARP_PACKET_REFUSED_IN_NET_STACK;
           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                     "%s :STA RX ARP packet Refused in net stack", __func__);
        }

         ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
      }
      // now process the next packet in the chain
      pVosPacket = pNextVosPacket;

   } while (pVosPacket);

   //Return the entire VOS packet chain to the resource pool
   status = vos_pkt_return_packet( pVosPacketChain );
   if(!VOS_IS_STATUS_SUCCESS( status ))
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: Failure returning vos pkt", __func__);
   }
   
   pAdapter->dev->last_rx = jiffies;

   return status;   
}
/**============================================================================
  @brief hdd_tx_rx_pkt_cnt_stat_timer_handler() -
               Enable/Disable split scan based on TX and RX traffic.
  @param HddContext      : [in] pointer to Hdd context
  @return                : None
  ===========================================================================*/
void hdd_tx_rx_pkt_cnt_stat_timer_handler( void *phddctx)
{
    hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
    hdd_adapter_t *pAdapter = NULL;
    hdd_station_ctx_t *pHddStaCtx = NULL;
    hdd_context_t *pHddCtx = (hdd_context_t *)phddctx;
    hdd_config_t  *cfg_param = pHddCtx->cfg_ini;
    VOS_STATUS status;
    v_U8_t staId = 0;
    v_U8_t fconnected = 0;

    ENTER();
    if (0 != (wlan_hdd_validate_context(pHddCtx)))
    {
        return;
    }
    if (!cfg_param->dynSplitscan)
    {
        VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                "%s: Error : Dynamic split scan is not Enabled : %d",
                __func__, pHddCtx->cfg_ini->dynSplitscan);
        return;
    }

    status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
    while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
    {
        pAdapter = pAdapterNode->pAdapter;

        if ((NULL != pAdapter) && (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic))
        {
            VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                    "%s: Adapter with device mode %d exists",
                    __func__, pAdapter->device_mode);

            if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
                    (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
            {
                pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
                if ((eConnectionState_Associated ==
                                 pHddStaCtx->conn_info.connState) &&
                    (VOS_TRUE == pHddStaCtx->conn_info.uIsAuthenticated))
                {
                    fconnected = TRUE;
                }
            }
            else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
                     (WLAN_HDD_P2P_GO == pAdapter->device_mode))
            {
                v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
                ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext);
                if(pSapCtx == NULL){
                    VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                             FL("psapCtx is NULL"));
                    return;
                }
                for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
                {
                    if ((pSapCtx->aStaInfo[staId].isUsed) &&
                        (WLANTL_STA_AUTHENTICATED ==
                                          pSapCtx->aStaInfo[staId].tlSTAState))
                    {
                        fconnected = TRUE;
                    }
                }
            }
            if ( fconnected )
            {
                VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                        "%s: One of the interface is connected check for scan",
                        __func__);
                VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                       "%s: pkt_tx_count: %d, pkt_rx_count: %d "
                       "miracast = %d", __func__,
                        pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count,
                        pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count,
                        pHddCtx->drvr_miracast);

                vos_timer_start(&pHddCtx->tx_rx_trafficTmr,
                                 cfg_param->trafficMntrTmrForSplitScan);
                //Check for the previous statistics count
                if ((pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count >
                                       cfg_param->txRxThresholdForSplitScan) ||
                    (pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count >
                                       cfg_param->txRxThresholdForSplitScan) ||
                        pHddCtx->drvr_miracast || pHddCtx->is_vowifi_enabled ||
                    (WLAN_HDD_P2P_GO == pAdapter->device_mode))
                {
                    pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count = 0;
                    pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count = 0;

                    if (!pHddCtx->issplitscan_enabled)
                    {
                        pHddCtx->issplitscan_enabled = TRUE;
                        sme_enable_disable_split_scan(
                                            WLAN_HDD_GET_HAL_CTX(pAdapter),
                                            cfg_param->nNumStaChanCombinedConc,
                                            cfg_param->nNumP2PChanCombinedConc);
                    }
                    return;
                }
                else
                {
                    pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count = 0;
                    pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count = 0;
                }
                fconnected = FALSE;
            }
        }
        status = hdd_get_next_adapter( pHddCtx, pAdapterNode, &pNext);
        pAdapterNode = pNext;
    }

    /* If TDLSScanCoexistence is enabled, then the TDLS module shall take care
     * of disabling the split scan and thus do not disable the same when the
     * low TXRX condition is met.
     */
    if ((pHddCtx->isTdlsScanCoexistence == FALSE) && (pHddCtx->issplitscan_enabled))
    {
       VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                        "%s: Disable split scan", __func__);
       pHddCtx->issplitscan_enabled = FALSE;
       sme_enable_disable_split_scan(
                                  pHddCtx->hHal,
                                  SME_DISABLE_SPLIT_SCAN,
                                  SME_DISABLE_SPLIT_SCAN);
    }
    EXIT();
    return;
}

/**
 * hdd_rx_fwd_eapol() - forward cached eapol frames
 * @vosContext : pointer to vos global context
 * @pVosPacket: pointer to vos packet
 *
 * Return: None
 *
 */
void hdd_rx_fwd_eapol(v_VOID_t *vosContext, vos_pkt_t *pVosPacket)
{
   hdd_context_t *pHddCtx = NULL;
   hdd_adapter_t * pAdapter = NULL;
   hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
   struct sk_buff *skb = NULL;
   uint8_t proto_type;
   uint8_t status;

   if ((NULL == vosContext) || (NULL == pVosPacket))
   {
      VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                        "%s: Null global context", __func__);
      return;
   }

   pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vosContext);
   if (NULL == pHddCtx)
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                           "%s: HDD adapter context is Null", __func__);
      return;
   }

   status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );

   while ( NULL != pAdapterNode && 0 == status )
   {
      pAdapter = pAdapterNode->pAdapter;

      if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
         break;

      status = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext);
      pAdapterNode = pNext;
   }

   if (NULL == pAdapter)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                        "%s: No adapter", __func__);
      return;
   }

   vos_pkt_get_os_packet(pVosPacket, (v_VOID_t **)&skb, VOS_FALSE);
   proto_type = vos_pkt_get_proto_type(skb,
                                       pHddCtx->cfg_ini->gEnableDebugLog);
   if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                   "STA RX EAPOL");
   }

   skb->dev = pAdapter->dev;
   skb->protocol = eth_type_trans(skb, skb->dev);
   skb->ip_summed = CHECKSUM_NONE;

   netif_rx_ni(skb);
}

#ifdef FEATURE_WLAN_DIAG_SUPPORT
/*
 * wlan_hdd_get_eapol_params() - Function to extract EAPOL params
 * @skb:                skb data
 * @eapol_params:       Pointer to hold the parsed EAPOL params
 * @event_type:         Event type to indicate Tx/Rx
 *
 * This function parses the input skb data to get the EAPOL params,if the
 * packet is EAPOL and store it in the pointer passed as input
 *
 */
void  wlan_hdd_get_eapol_params(struct sk_buff *skb,
                                    struct vos_event_wlan_eapol *eapol_params,
                                    uint8_t event_type)
{
     uint8_t packet_type=0;

     packet_type = (uint8_t)(*(uint8_t *)
                   (skb->data + HDD_EAPOL_PACKET_TYPE_OFFSET));

    /* EAPOL msg type  i.e. whether EAPOL-Start or
     * EAPOL-Key etc. messages Present at 15 offset.
     */
     eapol_params->eapol_packet_type = packet_type;

    /* This tells if its a M1/M2/M3/M4 packet.
     * Present at 19th offset in EAPOL frame.
     */
     eapol_params->eapol_key_info = (uint16_t)(*(uint16_t *)
                                    (skb->data + HDD_EAPOL_KEY_INFO_OFFSET));
    /* This tells if EAPOL packet is in RX or TX
     * direction.
     */
     eapol_params->event_sub_type = event_type;

    /* This tells the rate at which EAPOL packet
     * is send or received.
     */
     //TODO fill data rate for rx packet.
     eapol_params->eapol_rate = 0;/* As of now, zero */

     vos_mem_copy(eapol_params->dest_addr,
                 (skb->data + HDD_EAPOL_DEST_MAC_OFFSET),
                  sizeof(eapol_params->dest_addr));
     vos_mem_copy(eapol_params->src_addr,
                 (skb->data + HDD_EAPOL_SRC_MAC_OFFSET),
                  sizeof(eapol_params->src_addr));
     return;
}
/*
 * wlan_hdd_event_eapol_log() - Function to log EAPOL events
 * @eapol_params:    Structure containing EAPOL params
 *
 * This function logs the parsed EAPOL params
 *
 * Return: None
 *
 */

static void wlan_hdd_event_eapol_log(struct vos_event_wlan_eapol eapol_params)
{
    WLAN_VOS_DIAG_EVENT_DEF(wlan_diag_event, struct vos_event_wlan_eapol);

    wlan_diag_event.event_sub_type = eapol_params.event_sub_type;
    wlan_diag_event.eapol_packet_type = eapol_params.eapol_packet_type;
    wlan_diag_event.eapol_key_info = eapol_params.eapol_key_info;
    wlan_diag_event.eapol_rate = eapol_params.eapol_rate;
    vos_mem_copy(wlan_diag_event.dest_addr,
                  eapol_params.dest_addr,
                  sizeof (wlan_diag_event.dest_addr));
    vos_mem_copy(wlan_diag_event.src_addr,
                 eapol_params.src_addr,
                 sizeof (wlan_diag_event.src_addr));
    WLAN_VOS_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_EAPOL);
}

/*
 * wlan_hdd_log_eapol() - Function to check and extract EAPOL params
 * @skb:               skb data
 * @event_type:        One of enum wifi_connectivity_events to indicate Tx/Rx
 *
 * This function parses the input skb data to get the EAPOL params,if the
 * packet is EAPOL and store it in the pointer passed as input
 *
 * Return: None
 *
 */
void wlan_hdd_log_eapol(struct sk_buff *skb,
                               uint8_t event_type)
{
    struct vos_event_wlan_eapol eapol_params;

    wlan_hdd_get_eapol_params(skb, &eapol_params, event_type);
    wlan_hdd_event_eapol_log(eapol_params);

    if ((eapol_params.eapol_key_info & EAPOL_MASK )== EAPOL_M1_BIT_MASK)
    {
        hddLog(LOG1, FL("%s: M1 packet"),eapol_params.event_sub_type ==
               WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? "RX" : "TX");
    }
    else if ((eapol_params.eapol_key_info & EAPOL_MASK )== EAPOL_M2_BIT_MASK)
    {
        hddLog(LOG1, FL("%s: M2 packet"),eapol_params.event_sub_type ==
               WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? "RX" : "TX");

    }

    else if ((eapol_params.eapol_key_info & EAPOL_MASK )== EAPOL_M3_BIT_MASK)
    {
        hddLog(LOG1, FL("%s: M3 packet"),eapol_params.event_sub_type ==
               WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? "RX" : "TX");
    }

    else if ((eapol_params.eapol_key_info & EAPOL_MASK )== EAPOL_M4_BIT_MASK)
    {
        hddLog(LOG1, FL("%s: M4 packet"),eapol_params.event_sub_type ==
               WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? "RX" : "TX");

    }

}
#endif /* FEATURE_WLAN_DIAG_SUPPORT */
