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

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

/*============================================================================
  @file wlan_hdd_wmm.c

  This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation)
  houses all the logic for WMM in HDD.

  On the control path, it has the logic to setup QoS, modify QoS and delete
  QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an
  explicit application invoked and an internal HDD invoked.  The implicit QoS
  is for applications that do NOT call the custom QCT WLAN OIDs for QoS but
  which DO mark their traffic for priortization. It also has logic to start,
  update and stop the U-APSD trigger frame generation. It also has logic to
  read WMM related config parameters from the registry.

  On the data path, it has the logic to figure out the WMM AC of an egress
  packet and when to signal TL to serve a particular AC queue. It also has the
  logic to retrieve a packet based on WMM priority in response to a fetch from
  TL.

  The remaining functions are utility functions for information hiding.


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

/*---------------------------------------------------------------------------
  Include files
  -------------------------------------------------------------------------*/
#include <wlan_hdd_tx_rx.h>
#include <wlan_hdd_dp_utils.h>
#include <wlan_hdd_wmm.h>
#include <wlan_hdd_ether.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
#include <linux/ip.h>
#include <linux/semaphore.h>
#include <wlan_hdd_hostapd.h>
#include <wlan_hdd_softap_tx_rx.h>
#include <vos_sched.h>
#include "sme_Api.h"
#include "sapInternal.h"
// change logging behavior based upon debug flag
#ifdef HDD_WMM_DEBUG
#define WMM_TRACE_LEVEL_FATAL      VOS_TRACE_LEVEL_FATAL
#define WMM_TRACE_LEVEL_ERROR      VOS_TRACE_LEVEL_FATAL
#define WMM_TRACE_LEVEL_WARN       VOS_TRACE_LEVEL_FATAL
#define WMM_TRACE_LEVEL_INFO       VOS_TRACE_LEVEL_FATAL
#define WMM_TRACE_LEVEL_INFO_HIGH  VOS_TRACE_LEVEL_FATAL
#define WMM_TRACE_LEVEL_INFO_LOW   VOS_TRACE_LEVEL_FATAL
#else
#define WMM_TRACE_LEVEL_FATAL      VOS_TRACE_LEVEL_FATAL
#define WMM_TRACE_LEVEL_ERROR      VOS_TRACE_LEVEL_ERROR
#define WMM_TRACE_LEVEL_WARN       VOS_TRACE_LEVEL_WARN
#define WMM_TRACE_LEVEL_INFO       VOS_TRACE_LEVEL_INFO
#define WMM_TRACE_LEVEL_INFO_HIGH  VOS_TRACE_LEVEL_INFO_HIGH
#define WMM_TRACE_LEVEL_INFO_LOW   VOS_TRACE_LEVEL_INFO_LOW
#endif

// DHCP Port number
#define DHCP_SOURCE_PORT 0x4400
#define DHCP_DESTINATION_PORT 0x4300

#define HDD_WMM_UP_TO_AC_MAP_SIZE 8

#define IPv6_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5],\
        (a)[6], (a)[7], (a)[8], (a)[9], (a)[10], (a)[11], (a)[12], (a)[13],\
        (a)[14], (a)[15]
#define IPv6_ADDR_STR "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:"\
                       "%02x%02x:%02x%02x"

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

//Linux based UP -> AC Mapping
const v_U8_t hddLinuxUpToAcMap[8] = {
   HDD_LINUX_AC_BE,
   HDD_LINUX_AC_BK,
   HDD_LINUX_AC_BK,
   HDD_LINUX_AC_BE,
   HDD_LINUX_AC_VI,
   HDD_LINUX_AC_VI,
   HDD_LINUX_AC_VO,
   HDD_LINUX_AC_VO
};

#ifndef WLAN_MDM_CODE_REDUCTION_OPT
/**
  @brief hdd_wmm_enable_tl_uapsd() - function which decides whether and
  how to update UAPSD parameters in TL

  @param pQosContext : [in] the pointer the QoS instance control block

  @return
  None
*/
static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
{
   hdd_adapter_t* pAdapter = pQosContext->pAdapter;
   WLANTL_ACEnumType acType = pQosContext->acType;
   hdd_wmm_ac_status_t *pAc = NULL;
   VOS_STATUS status;
   v_U32_t service_interval;
   v_U32_t suspension_interval;
   sme_QosWmmDirType direction;
   v_BOOL_t psb;

   if (acType >= WLANTL_MAX_AC)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Invalid AC: %d", __func__, acType);
      return;
   }

   pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];

   // The TSPEC must be valid
   if (pAc->wmmAcTspecValid == VOS_FALSE)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Invoked with invalid TSPEC",
                __func__);
      return;
   }

   // determine the service interval
   if (pAc->wmmAcTspecInfo.min_service_interval)
   {
      service_interval = pAc->wmmAcTspecInfo.min_service_interval;
   }
   else if (pAc->wmmAcTspecInfo.max_service_interval)
   {
      service_interval = pAc->wmmAcTspecInfo.max_service_interval;
   }
   else
   {
      // no service interval is present in the TSPEC
      // this is OK, there just won't be U-APSD
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                "%s: No service interval supplied",
                __func__);
      service_interval = 0;
   }

   // determine the suspension interval & direction
   suspension_interval = pAc->wmmAcTspecInfo.suspension_interval;
   direction = pAc->wmmAcTspecInfo.ts_info.direction;
   psb = pAc->wmmAcTspecInfo.ts_info.psb;

   // if we have previously enabled U-APSD, have any params changed?
   if ((pAc->wmmAcUapsdInfoValid) &&
       (pAc->wmmAcUapsdServiceInterval == service_interval) &&
       (pAc->wmmAcUapsdSuspensionInterval == suspension_interval) &&
       (pAc->wmmAcUapsdDirection == direction) &&
       (pAc->wmmAcIsUapsdEnabled == psb))
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                "%s: No change in U-APSD parameters",
                __func__);
      return;
   }

   // are we in the appropriate power save modes?
   if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_BEACON_MODE_POWER_SAVE))
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                "%s: BMPS is not enabled",
                __func__);
      return;
   }

   if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_UAPSD_MODE_POWER_SAVE))
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                "%s: U-APSD is not enabled",
                __func__);
      return;
   }

   // everything is in place to notify TL
   status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                    (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                                    acType,
                                    pAc->wmmAcTspecInfo.ts_info.tid,
                                    pAc->wmmAcTspecInfo.ts_info.up,
                                    service_interval,
                                    suspension_interval,
                                    direction);

   if ( !VOS_IS_STATUS_SUCCESS( status ) )
   {
      VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                 "%s: Failed to enable U-APSD for AC=%d",
                 __func__, acType );
      return;
   }

   // stash away the parameters that were used
   pAc->wmmAcUapsdInfoValid = VOS_TRUE;
   pAc->wmmAcUapsdServiceInterval = service_interval;
   pAc->wmmAcUapsdSuspensionInterval = suspension_interval;
   pAc->wmmAcUapsdDirection = direction;
   pAc->wmmAcIsUapsdEnabled = psb;

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
             "%s: Enabled UAPSD in TL srv_int=%d "
             "susp_int=%d dir=%d AC=%d",
             __func__,
             service_interval,
             suspension_interval,
             direction,
             acType);

}

/**
  @brief hdd_wmm_disable_tl_uapsd() - function which decides whether
  to disable UAPSD parameters in TL

  @param pQosContext : [in] the pointer the QoS instance control block

  @return
  None
*/
static void hdd_wmm_disable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext)
{
   hdd_adapter_t* pAdapter = pQosContext->pAdapter;
   WLANTL_ACEnumType acType = pQosContext->acType;
   hdd_wmm_ac_status_t *pAc = NULL;
   VOS_STATUS status;
   v_U32_t service_interval;
   v_U32_t suspension_interval;
   v_U8_t uapsd_mask;
   v_U8_t ActiveTspec = INVALID_TSPEC;

   if (acType >= WLANTL_MAX_AC)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Invalid AC: %d", __func__, acType);
      return;
   }

   pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];

   // have we previously enabled UAPSD?
   if (pAc->wmmAcUapsdInfoValid == VOS_TRUE)
   {
      uapsd_mask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;

      //Finding uapsd_mask as per AC
      uapsd_mask = uapsd_mask & (1 << (WLANTL_AC_VO - acType));

      sme_QosTspecActive((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), acType,
                         pAdapter->sessionId, &ActiveTspec);

      //Call WLANTL_EnableUAPSDForAC only when static uapsd mask is present and
      // no active tspecs. TODO: Need to change naming convention as Enable
      // UAPSD function is called in hdd_wmm_disable_tl_uapsd. Purpose of
      // calling WLANTL_EnableUAPSDForAC is to update UAPSD intervals to fw

      if(uapsd_mask && !ActiveTspec)
      {
         switch(acType)
         {
         case WLANTL_AC_VO:
            service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
            suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
            break;
         case WLANTL_AC_VI:
            service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
            suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
            break;
         case WLANTL_AC_BE:
            service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
            suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
            break;
         case WLANTL_AC_BK:
            service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
            suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
            break;
         default:
            VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                    "%s: Invalid AC %d", __func__, acType );
            return;
         }

         status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                  (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                   acType,
                   pAc->wmmAcTspecInfo.ts_info.tid,
                   pAc->wmmAcTspecInfo.ts_info.up,
                   service_interval,
                   suspension_interval,
                   pAc->wmmAcTspecInfo.ts_info.direction);

         if ( !VOS_IS_STATUS_SUCCESS( status ) )
         {
            VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                    "%s: Failed to update U-APSD params for AC=%d",
                    __func__, acType );
         }
         else
         {
            // TL no longer has valid UAPSD info
            pAc->wmmAcUapsdInfoValid = VOS_FALSE;
            VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Updated UAPSD params in TL for AC=%d",
                   __func__,
                   acType);
         }
      }
   }
}

#endif

/**
  @brief hdd_wmm_free_context() - function which frees a QoS context

  @param pQosContext : [in] the pointer the QoS instance control block

  @return
  None
*/
static void hdd_wmm_free_context (hdd_wmm_qos_context_t* pQosContext)
{
   v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
   hdd_context_t *pHddCtx = NULL;

   if (NULL == pVosContext)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                FL("pVosContext is NULL"));
      return;
   }

   pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
   if (NULL == pHddCtx)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                FL("HddCtx is NULL"));
      return;
   }

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered, context %pK",
             __func__, pQosContext);

   // take the wmmLock since we're manipulating the context list
   mutex_lock(&pHddCtx->wmmLock);

   if (unlikely((NULL == pQosContext) ||
                (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
   {
      // must have been freed in another thread
      mutex_unlock(&pHddCtx->wmmLock);
      return;
   }

   // make sure nobody thinks this is a valid context
   pQosContext->magic = 0;

   // unlink the context
   list_del(&pQosContext->node);

   // done manipulating the list
   mutex_unlock(&pHddCtx->wmmLock);

   // reclaim memory
   kfree(pQosContext);

}

#ifndef WLAN_MDM_CODE_REDUCTION_OPT
/**
  @brief hdd_wmm_notify_app() - function which notifies an application
                                changes in state of it flow

  @param pQosContext : [in] the pointer the QoS instance control block

  @return
  None
*/
#define MAX_NOTIFY_LEN 50
static void hdd_wmm_notify_app (hdd_wmm_qos_context_t* pQosContext)
{
   hdd_adapter_t* pAdapter;
   union iwreq_data wrqu;
   char buf[MAX_NOTIFY_LEN+1];
   v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
   hdd_context_t *pHddCtx = NULL;

   if (NULL == pVosContext)
   {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                   FL("pVosContext is NULL"));
         return;
   }

   pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
   if (NULL == pHddCtx)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                   FL("HddCtx is NULL"));
      return;
   }

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered, context %pK",
             __func__, pQosContext);

   mutex_lock(&pHddCtx->wmmLock);
   if (unlikely((NULL == pQosContext) ||
                (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
   {
      mutex_unlock(&pHddCtx->wmmLock);
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Invalid QoS Context",
                __func__);
      return;
   }
   // get pointer to the adapter
   pAdapter = pQosContext->pAdapter;
   mutex_unlock(&pHddCtx->wmmLock);

   // create the event
   memset(&wrqu, 0, sizeof(wrqu));
   memset(buf, 0, sizeof(buf));

   snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]",
            (unsigned int)pQosContext->handle,
            (unsigned int)pQosContext->lastStatus);

   wrqu.data.pointer = buf;
   wrqu.data.length = strlen(buf);



   // send the event
   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
             "%s: Sending [%s]", __func__, buf);
   wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
}


/**
  @brief hdd_wmm_is_access_allowed() - function which determines if access
  is allowed for the given AC.  this is designed to be called during SME
  callback processing since that is when access can be granted or removed

  @param pAdapter    : [in] pointer to adapter context
  @param pAc         : [in] pointer to the per-AC status

  @return            : VOS_TRUE - access is allowed
                     : VOS_FALSE - access is not allowed
  None
*/
static v_BOOL_t hdd_wmm_is_access_allowed(hdd_adapter_t* pAdapter,
                                          hdd_wmm_ac_status_t* pAc)
{
   // if we don't want QoS or the AP doesn't support QoS
   // or we don't want to do implicit QoS
   // or if AP doesn't require admission for this AC
   // then we have access
   if (!hdd_wmm_is_active(pAdapter) ||
       !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled ||
       !pAc->wmmAcAccessRequired)
   {
      return VOS_TRUE;
   }

   // if implicit QoS has already completed, successfully or not,
   // then access is allowed
   if (pAc->wmmAcAccessGranted || pAc->wmmAcAccessFailed)
   {
      return VOS_TRUE;
   }

   // admission is required and implicit QoS hasn't completed
   // however explicit QoS may have completed and we'll have
   // a Tspec
   // if we don't have a Tspec then access is not allowed
   if (!pAc->wmmAcTspecValid)
   {
      return VOS_FALSE;
   }

   // we have a Tspec -- does it allow upstream or bidirectional traffic?
   // if it only allows downstream traffic then access is not allowed
   if (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK)
   {
      return VOS_FALSE;
   }

   // we meet all of the criteria for access
   return VOS_TRUE;
}

#ifdef FEATURE_WLAN_ESE
/**
  @brief hdd_wmm_inactivity_timer_cb() - timer handler function which is
  called for every inactivity interval per AC. This function gets the
  current transmitted packets on the given AC, and checks if there where
  any TX activity from the previous interval. If there was no traffic
  then it would delete the TS that was negotiated on that AC.

  @param pUserData   : [in] pointer to pQosContext

  @return            : NONE
*/
void hdd_wmm_inactivity_timer_cb( v_PVOID_t pUserData )
{
    hdd_wmm_qos_context_t* pQosContext = (hdd_wmm_qos_context_t*)pUserData;
    hdd_adapter_t* pAdapter;
    hdd_wmm_ac_status_t *pAc;
    hdd_wlan_wmm_status_e status;
    VOS_STATUS vos_status;
    v_U32_t currentTrafficCnt = 0;
    WLANTL_ACEnumType acType = 0;
    v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
    hdd_context_t *pHddCtx = NULL;

    ENTER();
    if (NULL == pVosContext)
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                  "%s: Invalid VOS Context", __func__);
        return;
    }

    pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
    if (0 != (wlan_hdd_validate_context(pHddCtx)))
    {
        return;
    }

    mutex_lock(&pHddCtx->wmmLock);
    if (unlikely((NULL == pQosContext) ||
                (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
    {
        mutex_unlock(&pHddCtx->wmmLock);
        VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                  "%s: Invalid QoS Context",
                  __func__);
        return;
    }
    mutex_unlock(&pHddCtx->wmmLock);

    acType = pQosContext->acType;
    pAdapter = pQosContext->pAdapter;
    if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
    {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                  FL("invalid pAdapter: %pK"), pAdapter);
        return;
    }

    pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];

    // Get the Tx stats for this AC.
    currentTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];

    VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
            FL("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d"),
            acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt);
    if (pAc->wmmPrevTrafficCnt == currentTrafficCnt)
    {
        // If there is no traffic activity, delete the TSPEC for this AC
        status = hdd_wmm_delts(pAdapter, pQosContext->handle);
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                FL("Deleted TS on AC %d, due to inactivity with status = %d!!!"),
                acType, status);
    }
    else
    {
        pAc->wmmPrevTrafficCnt = currentTrafficCnt;
        if (pAc->wmmInactivityTimer.state == VOS_TIMER_STATE_STOPPED)
        {
            // Restart the timer
            vos_status = vos_timer_start(&pAc->wmmInactivityTimer, pAc->wmmInactivityTime);
            if (!VOS_IS_STATUS_SUCCESS(vos_status))
            {
                VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                        FL("Restarting inactivity timer failed on AC %d"), acType);
            }
        }
        else
        {
            VOS_ASSERT(vos_timer_getCurrentState(
                        &pAc->wmmInactivityTimer) == VOS_TIMER_STATE_STOPPED);
        }
    }

    EXIT();
    return;
}


/**
  @brief hdd_wmm_enable_inactivity_timer() - function to enable the
  traffic inactivity timer for the given AC, if the inactivity_interval
  specified in the ADDTS parameters is non-zero

  @param pQosContext   : [in] pointer to pQosContext
  @param inactivityTime: [in] value of the inactivity interval in millisecs

  @return              : VOS_STATUS_E_FAILURE
                         VOS_STATUS_SUCCESS
*/
VOS_STATUS hdd_wmm_enable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext, v_U32_t inactivityTime)
{
    VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;
    hdd_adapter_t* pAdapter = pQosContext->pAdapter;
    WLANTL_ACEnumType acType = pQosContext->acType;
    hdd_wmm_ac_status_t *pAc;

    pAdapter = pQosContext->pAdapter;
    pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];


    // If QoS-Tspec is successfully setup and if the inactivity timer is non-zero,
    // a traffic inactivity timer needs to be started for the given AC
    vos_status = vos_timer_init(
            &pAc->wmmInactivityTimer,
            VOS_TIMER_TYPE_SW,
            hdd_wmm_inactivity_timer_cb,
            (v_PVOID_t)pQosContext );
    if ( !VOS_IS_STATUS_SUCCESS(vos_status))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                FL("Initializing inactivity timer failed on AC %d"), acType);
        return vos_status;
    }

    // Start the inactivity timer
    vos_status = vos_timer_start(
            &pAc->wmmInactivityTimer,
            inactivityTime);
    if ( !VOS_IS_STATUS_SUCCESS(vos_status))
    {
        VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                FL("Starting inactivity timer failed on AC %d"), acType);
        return vos_status;
    }
    pAc->wmmInactivityTime = inactivityTime;
    // Initialize the current tx traffic count on this AC
    pAc->wmmPrevTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType];

    return vos_status;
}

/**
  @brief hdd_wmm_enable_inactivity_timer() - function to disable the
  traffic inactivity timer for the given AC. This would be called when
  deleting the TS.

  @param pQosContext   : [in] pointer to pQosContext

  @return              : VOS_STATUS_E_FAILURE
                         VOS_STATUS_SUCCESS
*/
VOS_STATUS hdd_wmm_disable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext)
{
    hdd_adapter_t* pAdapter = pQosContext->pAdapter;
    WLANTL_ACEnumType acType = pQosContext->acType;
    hdd_wmm_ac_status_t *pAc  = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
    VOS_STATUS vos_status = VOS_STATUS_E_FAILURE;

    // Clear the timer and the counter
    pAc->wmmInactivityTime = 0;
    pAc->wmmPrevTrafficCnt = 0;
    vos_timer_stop(&pAc->wmmInactivityTimer);
    vos_status = vos_timer_destroy(&pAc->wmmInactivityTimer);

    return vos_status;
}
#endif // FEATURE_WLAN_ESE

/**
  @brief hdd_wmm_sme_callback() - callback registered by HDD with SME for receiving
  QoS notifications. Even though this function has a static scope it gets called
  externally through some function pointer magic (so there is a need for
  rigorous parameter checking)

  @param hHal : [in] the HAL handle
  @param HddCtx : [in] the HDD specified handle
  @param pCurrentQosInfo : [in] the TSPEC params
  @param SmeStatus : [in] the QoS related SME status

  @return
  eHAL_STATUS_SUCCESS if all good, eHAL_STATUS_FAILURE otherwise
*/
static eHalStatus hdd_wmm_sme_callback (tHalHandle hHal,
                                        void * hddCtx,
                                        sme_QosWmmTspecInfo* pCurrentQosInfo,
                                        sme_QosStatusType smeStatus,
                                        v_U32_t qosFlowId)
{
   hdd_wmm_qos_context_t* pQosContext = hddCtx;
   hdd_adapter_t* pAdapter;
   WLANTL_ACEnumType acType;
   hdd_wmm_ac_status_t *pAc;
   VOS_STATUS status;
   v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
   hdd_context_t *pHddCtx = NULL;

   if (NULL == pVosContext)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                   FL("pVosContext is NULL"));
      return eHAL_STATUS_FAILURE;
   }

   pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
   if (NULL == pHddCtx)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                   FL("HddCtx is NULL"));
      return eHAL_STATUS_FAILURE;
   }


   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered, context %pK",
             __func__, pQosContext);

   mutex_lock(&pHddCtx->wmmLock);
   if (unlikely((NULL == pQosContext) ||
                (HDD_WMM_CTX_MAGIC != pQosContext->magic)))
   {
      mutex_unlock(&pHddCtx->wmmLock);
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Invalid QoS Context",
                __func__);
      return eHAL_STATUS_FAILURE;
   }
   mutex_unlock(&pHddCtx->wmmLock);

   pAdapter = pQosContext->pAdapter;
   acType = pQosContext->acType;
   pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: status %d flowid %d info %pK",
             __func__, smeStatus, qosFlowId, pCurrentQosInfo);

   switch (smeStatus)
   {

   case SME_QOS_STATUS_SETUP_SUCCESS_IND:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                "%s: Setup is complete",
                __func__);

      // there will always be a TSPEC returned with this status, even if
      // a TSPEC is not exchanged OTA
      if (pCurrentQosInfo)
      {
         pAc->wmmAcTspecValid = VOS_TRUE;
         memcpy(&pAc->wmmAcTspecInfo,
                pCurrentQosInfo,
                sizeof(pAc->wmmAcTspecInfo));
      }

      if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
      {

         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Implicit Qos, notifying TL for TL AC %d",
                   __func__, acType);

         // this was triggered by implicit QoS so we know packets are pending
         // update state
         pAc->wmmAcAccessAllowed = VOS_TRUE;
         pAc->wmmAcAccessGranted = VOS_TRUE;
         pAc->wmmAcAccessPending = VOS_FALSE;

         // notify TL that packets are pending
         status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                        (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                                        acType );

         if ( !VOS_IS_STATUS_SUCCESS( status ) )
         {
            VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                       "%s: Failed to signal TL for AC=%d",
                       __func__, acType );
         }
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Explicit Qos, notifying userspace",
                   __func__);

         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
         hdd_wmm_notify_app(pQosContext);
      }

#ifdef FEATURE_WLAN_ESE
      // Check if the inactivity interval is specified
      if (pCurrentQosInfo && pCurrentQosInfo->inactivity_interval) {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                 "%s: Inactivity timer value = %d for AC=%d",
                 __func__, pCurrentQosInfo->inactivity_interval, acType);
         hdd_wmm_enable_inactivity_timer(pQosContext, pCurrentQosInfo->inactivity_interval);
      }
#endif // FEATURE_WLAN_ESE

      // notify TL to enable trigger frames if necessary
      hdd_wmm_enable_tl_uapsd(pQosContext);

      break;

   case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                "%s: Setup is complete (U-APSD set previously)",
                __func__);

      if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
      {

         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Implicit Qos, notifying TL",
                   __func__);

         // this was triggered by implicit QoS so we know packets are pending
         // update state
         pAc->wmmAcAccessAllowed = VOS_TRUE;
         pAc->wmmAcAccessGranted = VOS_TRUE;
         pAc->wmmAcAccessPending = VOS_FALSE;

         // notify TL that packets are pending
         status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                        (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                                        acType );

         if ( !VOS_IS_STATUS_SUCCESS( status ) )
         {
            VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                       "%s: Failed to signal TL for AC=%d",
                       __func__, acType );
         }
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Explicit Qos, notifying userspace",
                   __func__);

         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
         hdd_wmm_notify_app(pQosContext);
      }

      break;

   case SME_QOS_STATUS_SETUP_FAILURE_RSP:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Setup failed",
                __func__);
      // QoS setup failed

      if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
      {

         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Implicit Qos, notifying TL",
                   __func__);

         // we note the failure, but we also mark access as allowed so that
         // the packets will flow.  Note that the MAC will "do the right thing"
         pAc->wmmAcAccessPending = VOS_FALSE;
         pAc->wmmAcAccessFailed = VOS_TRUE;
         pAc->wmmAcAccessAllowed = VOS_TRUE;

         // this was triggered by implicit QoS so we know packets are pending
         status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                        (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                                        acType );

         if ( !VOS_IS_STATUS_SUCCESS( status ) )
         {
            VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                       "%s: Failed to signal TL for AC=%d",
                       __func__, acType );
         }
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Explicit Qos, notifying userspace",
                   __func__);

         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED;
         hdd_wmm_notify_app(pQosContext);
      }

#ifdef FEATURE_WLAN_ESE
      hdd_wmm_disable_inactivity_timer(pQosContext);
#endif
      /* Setting up QoS Failed, QoS context can be released.
       * SME is releasing this flow information and if HDD doen't release this context,
       * next time if application uses the same handle to set-up QoS, HDD (as it has
       * QoS context for this handle) will issue Modify QoS request to SME but SME will
       * reject as no it has no information for this flow.
       */
      hdd_wmm_free_context(pQosContext);
      break;

   case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Setup Invalid Params, notify TL",
                __func__);
      // QoS setup failed

      if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
      {

         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Implicit Qos, notifying TL",
                   __func__);

         // we note the failure, but we also mark access as allowed so that
         // the packets will flow.  Note that the MAC will "do the right thing"
         pAc->wmmAcAccessPending = VOS_FALSE;
         pAc->wmmAcAccessFailed = VOS_TRUE;
         pAc->wmmAcAccessAllowed = VOS_TRUE;

         // this was triggered by implicit QoS so we know packets are pending
         status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                        (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                                        acType );

         if ( !VOS_IS_STATUS_SUCCESS( status ) )
         {
            VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                       "%s: Failed to signal TL for AC=%d",
                       __func__, acType );
         }
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Explicit Qos, notifying userspace",
                   __func__);

         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
         hdd_wmm_notify_app(pQosContext);
      }
      break;

   case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
      VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                 "%s: Setup failed, not a QoS AP",
                 __func__);
      if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Explicit Qos, notifying userspace",
                   __func__);

         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
         hdd_wmm_notify_app(pQosContext);
      }
      break;

   case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                "%s: Setup pending",
                __func__);
      // not a callback status -- ignore if we get it
      break;

   case SME_QOS_STATUS_SETUP_MODIFIED_IND:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                "%s: Setup modified",
                __func__);
      if (pCurrentQosInfo)
      {
         // update the TSPEC
         pAc->wmmAcTspecValid = VOS_TRUE;
         memcpy(&pAc->wmmAcTspecInfo,
                pCurrentQosInfo,
                sizeof(pAc->wmmAcTspecInfo));

         if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
         {
            VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                      "%s: Explicit Qos, notifying userspace",
                      __func__);

            // this was triggered by an application
            pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFIED;
            hdd_wmm_notify_app(pQosContext);
         }

         // need to tell TL to update its UAPSD handling
         hdd_wmm_enable_tl_uapsd(pQosContext);
      }
      break;

   case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
      if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
      {

         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Implicit Qos, notifying TL",
                   __func__);

         // this was triggered by implicit QoS so we know packets are pending
         pAc->wmmAcAccessPending = VOS_FALSE;
         pAc->wmmAcAccessGranted = VOS_TRUE;
         pAc->wmmAcAccessAllowed = VOS_TRUE;

         // notify TL that packets are pending
         status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                        (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                                        acType );

         if ( !VOS_IS_STATUS_SUCCESS( status ) )
         {
            VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                       "%s: Failed to signal TL for AC=%d",
                       __func__, acType );
         }
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Explicit Qos, notifying userspace",
                   __func__);

         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
         hdd_wmm_notify_app(pQosContext);
      }
      break;

   case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
      // nothing to do for now
      break;

   case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Setup successful but U-APSD failed",
                __func__);

      if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
      {

         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Implicit Qos, notifying TL",
                   __func__);

         // QoS setup was successful but setting U=APSD failed
         // Since the OTA part of the request was successful, we don't mark
         // this as a failure.
         // the packets will flow.  Note that the MAC will "do the right thing"
         pAc->wmmAcAccessGranted = VOS_TRUE;
         pAc->wmmAcAccessAllowed = VOS_TRUE;
         pAc->wmmAcAccessFailed = VOS_FALSE;
         pAc->wmmAcAccessPending = VOS_FALSE;

         // this was triggered by implicit QoS so we know packets are pending
         status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                        (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                                        acType );

         if ( !VOS_IS_STATUS_SUCCESS( status ) )
         {
            VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                       "%s: Failed to signal TL for AC=%d",
                       __func__, acType );
         }
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Explicit Qos, notifying userspace",
                   __func__);

         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED;
         hdd_wmm_notify_app(pQosContext);
      }

      // Since U-APSD portion failed disabled trigger frame generation
      hdd_wmm_disable_tl_uapsd(pQosContext);

      break;

   case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                "%s: Release is complete",
                __func__);

      if (pCurrentQosInfo)
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: flows still active",
                   __func__);

         // there is still at least one flow active for this AC
         // so update the AC state
         memcpy(&pAc->wmmAcTspecInfo,
                pCurrentQosInfo,
                sizeof(pAc->wmmAcTspecInfo));

         // need to tell TL to update its UAPSD handling
         hdd_wmm_enable_tl_uapsd(pQosContext);
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: last flow",
                   __func__);

         // this is the last flow active for this AC so update the AC state
         pAc->wmmAcTspecValid = VOS_FALSE;

         // need to tell TL to update its UAPSD handling
         hdd_wmm_disable_tl_uapsd(pQosContext);
      }

      if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Explicit Qos, notifying userspace",
                   __func__);

         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;
         hdd_wmm_notify_app(pQosContext);
      }

#ifdef FEATURE_WLAN_ESE
      hdd_wmm_disable_inactivity_timer(pQosContext);
#endif
      // we are done with this flow
      hdd_wmm_free_context(pQosContext);
      break;

   case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                "%s: Release failure",
                __func__);

      // we don't need to update our state or TL since nothing has changed
      if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Explicit Qos, notifying userspace",
                   __func__);

         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
         hdd_wmm_notify_app(pQosContext);
      }

      break;

   case SME_QOS_STATUS_RELEASE_QOS_LOST_IND:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                "%s: QOS Lost indication received",
                __func__);

      // current TSPEC is no longer valid
      pAc->wmmAcTspecValid = VOS_FALSE;

      // need to tell TL to update its UAPSD handling
      hdd_wmm_disable_tl_uapsd(pQosContext);

      if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle)
      {
         // we no longer have implicit access granted
         pAc->wmmAcAccessGranted = VOS_FALSE;
         pAc->wmmAcAccessFailed = VOS_FALSE;
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                   "%s: Explicit Qos, notifying userspace",
                   __func__);

         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_LOST;
         hdd_wmm_notify_app(pQosContext);
      }

#ifdef FEATURE_WLAN_ESE
      hdd_wmm_disable_inactivity_timer(pQosContext);
#endif
      // we are done with this flow
      hdd_wmm_free_context(pQosContext);
      break;

   case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                "%s: Release pending",
                __func__);
      // not a callback status -- ignore if we get it
      break;

   case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Release Invalid Params",
                __func__);
      if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
      {
         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
         hdd_wmm_notify_app(pQosContext);
      }
      break;

   case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                "%s: Modification is complete, notify TL",
                __func__);

      // there will always be a TSPEC returned with this status, even if
      // a TSPEC is not exchanged OTA
      if (pCurrentQosInfo)
      {
         pAc->wmmAcTspecValid = VOS_TRUE;
         memcpy(&pAc->wmmAcTspecInfo,
                pCurrentQosInfo,
                sizeof(pAc->wmmAcTspecInfo));
      }

      if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
      {
         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS;
         hdd_wmm_notify_app(pQosContext);
      }

      // notify TL to enable trigger frames if necessary
      hdd_wmm_enable_tl_uapsd(pQosContext);

      break;

   case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
      if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
      {
         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
         hdd_wmm_notify_app(pQosContext);
      }
      break;

   case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
      // the flow modification failed so we'll leave in place
      // whatever existed beforehand

      if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
      {
         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
         hdd_wmm_notify_app(pQosContext);
      }
      break;

   case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                "%s: modification pending",
                __func__);
      // not a callback status -- ignore if we get it
      break;

   case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
      // the flow modification was successful but no QoS changes required

      if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
      {
         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
         hdd_wmm_notify_app(pQosContext);
      }
      break;

   case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
      // invalid params -- notify the application
      if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
      {
         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
         hdd_wmm_notify_app(pQosContext);
      }
      break;

   case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING:
      // nothing to do for now.  when APSD is established we'll have work to do
      break;

   case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Modify successful but U-APSD failed",
                __func__);

      // QoS modification was successful but setting U=APSD failed.
      // This will always be an explicit QoS instance, so all we can
      // do is notify the application and let it clean up.
      if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle)
      {
         // this was triggered by an application
         pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED;
         hdd_wmm_notify_app(pQosContext);
      }

      // Since U-APSD portion failed disabled trigger frame generation
      hdd_wmm_disable_tl_uapsd(pQosContext);

      break;

   case SME_QOS_STATUS_HANDING_OFF:
      // no roaming so we won't see this
      break;

   case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND:
      // need to tell TL to stop trigger frame generation
      hdd_wmm_disable_tl_uapsd(pQosContext);
      break;

   case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND:
      // need to tell TL to start sending trigger frames again
      hdd_wmm_enable_tl_uapsd(pQosContext);
      break;

   default:
      VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                 "%s: unexpected SME Status=%d",
                 __func__, smeStatus );
      VOS_ASSERT(0);
   }

   // our access to the particular access category may have changed.
   // some of the implicit QoS cases above may have already set this
   // prior to invoking TL (so that we will properly service the
   // Tx queues) but let's consistently handle all cases here
   pAc->wmmAcAccessAllowed = hdd_wmm_is_access_allowed(pAdapter, pAc);

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
             "%s: complete, access for TL AC %d is%sallowed",
             __func__,
             acType,
             pAc->wmmAcAccessAllowed ? " " : " not ");

   return eHAL_STATUS_SUCCESS;
}
#endif

/**========================================================================
  @brief hdd_wmmps_helper() - Function to set uapsd psb dynamically

  @param pAdapter     : [in] pointer to adapter structure

  @param ptr          : [in] pointer to command buffer

  @return             : Zero on success, appropriate error on failure.
  =======================================================================*/
int hdd_wmmps_helper(hdd_adapter_t *pAdapter, tANI_U8 *ptr)
{
   if (NULL == pAdapter)
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                 "%s: pAdapter is NULL", __func__);
       return -EINVAL;
   }
   if (NULL == ptr)
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                 "%s: ptr is NULL", __func__);
       return -EINVAL;
   }
   /* convert ASCII to integer */
   pAdapter->configuredPsb = ptr[9] - '0';
   pAdapter->psbChanged = HDD_PSB_CHANGED;

   return 0;
}

/**============================================================================
  @brief hdd_wmm_do_implicit_qos() - Function which will attempt to setup
  QoS for any AC requiring it

  @param work     : [in]  pointer to work structure

  @return         : void
  ===========================================================================*/
static void __hdd_wmm_do_implicit_qos(struct work_struct *work)
{
   hdd_wmm_qos_context_t* pQosContext =
      container_of(work, hdd_wmm_qos_context_t, wmmAcSetupImplicitQos);
   hdd_adapter_t* pAdapter;
   WLANTL_ACEnumType acType;
   hdd_wmm_ac_status_t *pAc;
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
   VOS_STATUS status;
   sme_QosStatusType smeStatus;
#endif
   sme_QosWmmTspecInfo qosInfo;
   v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
   hdd_context_t *pHddCtx = NULL;
   int ret = 0;

   if (NULL == pVosContext)
   {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                   FL("pVosContext is NULL"));
         return;
   }

   pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);

   ret = wlan_hdd_validate_context(pHddCtx);
   if (0 != ret)
   {
       hddLog(LOGE, FL("HDD context is invalid"));
       return;
   }

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered, context %pK",
             __func__, pQosContext);

   mutex_lock(&pHddCtx->wmmLock);
   if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic))
   {
      mutex_unlock(&pHddCtx->wmmLock);
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Invalid QoS Context",
                __func__);
      return;
   }
   mutex_unlock(&pHddCtx->wmmLock);

   pAdapter = pQosContext->pAdapter;
   acType = pQosContext->acType;
   pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: pAdapter %pK acType %d",
             __func__, pAdapter, acType);

   if (!pAc->wmmAcAccessNeeded)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: AC %d doesn't need service",
                __func__, acType);
      pQosContext->magic = 0;
      kfree(pQosContext);
      return;
   }

   pAc->wmmAcAccessPending = VOS_TRUE;
   pAc->wmmAcAccessNeeded = VOS_FALSE;

   memset(&qosInfo, 0, sizeof(qosInfo));

   qosInfo.ts_info.psb = pAdapter->configuredPsb;

   switch (acType)
   {
   case WLANTL_AC_VO:
      qosInfo.ts_info.up = SME_QOS_WMM_UP_VO;
      /* Check if there is any valid configuration from framework */
      if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
      {
          qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
                                  SME_QOS_UAPSD_VO) ? 1 : 0;
      }
      qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVo;
      qosInfo.ts_info.tid = 255;
      qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVo;
      qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVo;
      qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv;
      qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVo;
      qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVo;
      qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv;
      break;
   case WLANTL_AC_VI:
      qosInfo.ts_info.up = SME_QOS_WMM_UP_VI;
      /* Check if there is any valid configuration from framework */
      if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
      {
          qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
                                  SME_QOS_UAPSD_VI) ? 1 : 0;
      }
      qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVi;
      qosInfo.ts_info.tid = 255;
      qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVi;
      qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVi;
      qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv;
      qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVi;
      qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVi;
      qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv;
      break;
   case WLANTL_AC_BE:
      qosInfo.ts_info.up = SME_QOS_WMM_UP_BE;
      /* Check if there is any valid configuration from framework */
      if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
      {
          qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
                                  SME_QOS_UAPSD_BE) ? 1 : 0;
      }
      qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBe;
      qosInfo.ts_info.tid = 255;
      qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBe;
      qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBe;
      qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv;
      qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBe;
      qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBe;
      qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv;
      break;
   case WLANTL_AC_BK:
      qosInfo.ts_info.up = SME_QOS_WMM_UP_BK;
      /* Check if there is any valid configuration from framework */
      if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb)
      {
          qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask &
                                  SME_QOS_UAPSD_BK) ? 1 : 0;
      }
      qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBk;
      qosInfo.ts_info.tid = 255;
      qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBk;
      qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBk;
      qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv;
      qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBk;
      qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBk;
      qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv;
      break;
   default:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Invalid AC %d", __func__, acType );
      return;
   }
#ifdef FEATURE_WLAN_ESE
   qosInfo.inactivity_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraInactivityInterval;
#endif
   qosInfo.ts_info.burst_size_defn = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->burstSizeDefinition;

   switch ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->tsInfoAckPolicy)
   {
     case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
       qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
       break;

     case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
       qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
       break;

     default:
       // unknown
       qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
   }

   if(qosInfo.ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)
   {
     if(!sme_QosIsTSInfoAckPolicyValid((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), &qosInfo, pAdapter->sessionId))
     {
       qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
     }
   }

   mutex_lock(&pHddCtx->wmmLock);
   list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
   mutex_unlock(&pHddCtx->wmmLock);

#ifndef WLAN_MDM_CODE_REDUCTION_OPT
   smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
                               pAdapter->sessionId,
                               &qosInfo,
                               hdd_wmm_sme_callback,
                               pQosContext,
                               qosInfo.ts_info.up,
                               &pQosContext->qosFlowId);

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
             "%s: sme_QosSetupReq returned %d flowid %d",
             __func__, smeStatus, pQosContext->qosFlowId);

   // need to check the return values and act appropriately
   switch (smeStatus)
   {
   case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
   case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
      // setup is pending, so no more work to do now.
      // all further work will be done in hdd_wmm_sme_callback()
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                "%s: Setup is pending, no further work",
                __func__);

      break;


   case SME_QOS_STATUS_SETUP_FAILURE_RSP:
      // we can't tell the difference between when a request fails because
      // AP rejected it versus when SME encountered an internal error

      // in either case SME won't ever reference this context so
      // free the record
      hdd_wmm_free_context(pQosContext);

      // fall through and start packets flowing
   case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
      // no ACM in effect, no need to setup U-APSD
   case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
      // no ACM in effect, U-APSD is desired but was already setup

      // for these cases everything is already setup so we can
      // signal TL that it has work to do
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                "%s: Setup is complete, notify TL",
                __func__);

      pAc->wmmAcAccessAllowed = VOS_TRUE;
      pAc->wmmAcAccessGranted = VOS_TRUE;
      pAc->wmmAcAccessPending = VOS_FALSE;

      status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                     (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                                     acType );

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

      break;


   default:
      VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                 "%s: unexpected SME Status=%d",
                 __func__, smeStatus );
      VOS_ASSERT(0);
   }
#endif

}

static void hdd_wmm_do_implicit_qos(struct work_struct *work)
{
    vos_ssr_protect(__func__);
    __hdd_wmm_do_implicit_qos( work );
    vos_ssr_unprotect(__func__);
}

/**============================================================================
  @brief hdd_wmm_init() - Function which will initialize the WMM configuation
  and status to an initial state.  The configuration can later be overwritten
  via application APIs

  @param pAdapter : [in]  pointer to Adapter context

  @return         : VOS_STATUS_SUCCESS if successful
                  : other values if failure

  ===========================================================================*/
VOS_STATUS hdd_wmm_init ( hdd_adapter_t *pAdapter )
{
   sme_QosWmmUpType* hddWmmDscpToUpMap = pAdapter->hddWmmDscpToUpMap;
   v_U8_t dscp;

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered", __func__);

   // DSCP to User Priority Lookup Table
   for (dscp = 0; dscp <= WLAN_MAX_DSCP; dscp++)
   {
      hddWmmDscpToUpMap[dscp] = SME_QOS_WMM_UP_BE;
   }
   hddWmmDscpToUpMap[8]  = SME_QOS_WMM_UP_BK;
   hddWmmDscpToUpMap[16] = SME_QOS_WMM_UP_RESV;
   hddWmmDscpToUpMap[24] = SME_QOS_WMM_UP_EE;
   hddWmmDscpToUpMap[32] = SME_QOS_WMM_UP_CL;
   hddWmmDscpToUpMap[40] = SME_QOS_WMM_UP_VI;
   hddWmmDscpToUpMap[48] = SME_QOS_WMM_UP_VO;
   hddWmmDscpToUpMap[56] = SME_QOS_WMM_UP_NC;
   return VOS_STATUS_SUCCESS;
}

/**============================================================================
  @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation
  and status to an initial state.  The configuration can later be overwritten
  via application APIs

  @param pAdapter : [in]  pointer to Adapter context

  @return         : VOS_STATUS_SUCCESS if succssful
                  : other values if failure

  ===========================================================================*/
VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter )
{
   hdd_wmm_ac_status_t *pAcStatus;
   WLANTL_ACEnumType acType;

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered", __func__);

   pAdapter->hddWmmStatus.wmmQap = VOS_FALSE;
   INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList);

   for (acType = 0; acType < WLANTL_MAX_AC; acType++)
   {
      pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
      pAcStatus->wmmAcAccessRequired = VOS_FALSE;
      pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
      pAcStatus->wmmAcAccessPending = VOS_FALSE;
      pAcStatus->wmmAcAccessFailed = VOS_FALSE;
      pAcStatus->wmmAcAccessGranted = VOS_FALSE;
      pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
      pAcStatus->wmmAcTspecValid = VOS_FALSE;
      pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
   }
   // Invalid value(0xff) to indicate psb not configured through framework initially.
   pAdapter->configuredPsb = HDD_PSB_CFG_INVALID;

   return VOS_STATUS_SUCCESS;
}

/**============================================================================
  @brief hdd_wmm_adapter_clear() - Function which will clear the WMM status
  for all the ACs

  @param pAdapter : [in]  pointer to Adapter context

  @return         : VOS_STATUS_SUCCESS if succssful
                  : other values if failure

  ===========================================================================*/
VOS_STATUS hdd_wmm_adapter_clear( hdd_adapter_t *pAdapter )
{
   hdd_wmm_ac_status_t *pAcStatus;
   WLANTL_ACEnumType acType;
   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered", __func__);
   for (acType = 0; acType < WLANTL_MAX_AC; acType++)
   {
      pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
      pAcStatus->wmmAcAccessRequired = VOS_FALSE;
      pAcStatus->wmmAcAccessNeeded = VOS_FALSE;
      pAcStatus->wmmAcAccessPending = VOS_FALSE;
      pAcStatus->wmmAcAccessFailed = VOS_FALSE;
      pAcStatus->wmmAcAccessGranted = VOS_FALSE;
      pAcStatus->wmmAcAccessAllowed = VOS_FALSE;
      pAcStatus->wmmAcTspecValid = VOS_FALSE;
      pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE;
   }
   return VOS_STATUS_SUCCESS;
}

/**============================================================================
  @brief hdd_wmm_close() - Function which will perform any necessary work to
  to clean up the WMM functionality prior to the kernel module unload

  @param pAdapter : [in]  pointer to adapter context

  @return         : VOS_STATUS_SUCCESS if succssful
                  : other values if failure

  ===========================================================================*/
VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter )
{
   hdd_wmm_qos_context_t* pQosContext;
   v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
   hdd_context_t *pHddCtx = NULL;

   if (NULL == pVosContext)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                   FL("pVosContext is NULL"));
      return VOS_STATUS_E_FAILURE;
   }

   pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
   if (NULL == pHddCtx)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                   FL("HddCtx is NULL"));
      return VOS_STATUS_E_FAILURE;
   }

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered", __func__);

   // free any context records that we still have linked
   while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList))
   {
      pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList,
                                     hdd_wmm_qos_context_t, node);
#ifdef FEATURE_WLAN_ESE
      hdd_wmm_disable_inactivity_timer(pQosContext);
#endif
   mutex_lock(&pHddCtx->wmmLock);
   if (pQosContext->handle == HDD_WMM_HANDLE_IMPLICIT
       && pQosContext->magic == HDD_WMM_CTX_MAGIC)
   {

      vos_flush_work(&pQosContext->wmmAcSetupImplicitQos);
   }
   mutex_unlock(&pHddCtx->wmmLock);

      hdd_wmm_free_context(pQosContext);
   }

   return VOS_STATUS_SUCCESS;
}

/**============================================================================
  @brief hdd_is_dhcp_packet() - Function which will check OS packet for
  DHCP packet

  @param skb      : [in]  pointer to OS packet (sk_buff)
  @return         : VOS_TRUE if the OS packet is DHCP packet
                  : otherwise VOS_FALSE
  ===========================================================================*/
v_BOOL_t hdd_is_dhcp_packet(struct sk_buff *skb)
{
   if (*((u16*)((u8*)skb->data+34)) == DHCP_SOURCE_PORT ||
       *((u16*)((u8*)skb->data+34)) == DHCP_DESTINATION_PORT)
      return VOS_TRUE;

   return VOS_FALSE;
}

/**============================================================================
  @brief hdd_skb_is_eapol_or_wai_packet() - Function which will check OS packet
  for Eapol/Wapi packet

  @param skb      : [in]  pointer to OS packet (sk_buff)
  @return         : VOS_TRUE if the OS packet is an Eapol or a Wapi packet
                  : otherwise VOS_FALSE
  ===========================================================================*/
v_BOOL_t hdd_skb_is_eapol_or_wai_packet(struct sk_buff *skb)
{
    if ((*((u16*)((u8*)skb->data+HDD_ETHERTYPE_802_1_X_FRAME_OFFSET))
         == vos_cpu_to_be16(HDD_ETHERTYPE_802_1_X))
#ifdef FEATURE_WLAN_WAPI
         || (*((u16*)((u8*)skb->data+HDD_ETHERTYPE_802_1_X_FRAME_OFFSET))
         == vos_cpu_to_be16(HDD_ETHERTYPE_WAI))
#endif
       )
       return VOS_TRUE;

    return VOS_FALSE;
}

/**============================================================================
  @brief hdd_log_ip_addr() - Function to log IP header src and dst address
  @param skb      : [in]  pointer to OS packet (sk_buff)
  @return         : none
  ===========================================================================*/
void hdd_log_ip_addr(struct sk_buff *skb)
{
   union generic_ethhdr *pHdr;
   struct iphdr *pIpHdr;
   unsigned char * pPkt;
   char *buf;

   pPkt = skb->data;
   pHdr = (union generic_ethhdr *)pPkt;

   if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
   {
      pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];

      buf = (char *)&pIpHdr->saddr;
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
               "%s: src addr %d:%d:%d:%d", __func__,
               buf[0], buf[1], buf[2], buf[3]);

      buf = (char *)&pIpHdr->daddr;
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
               "%s: dst addr %d:%d:%d:%d", __func__,
               buf[0], buf[1], buf[2], buf[3]);
   }
   else if (pHdr->eth_II.h_proto ==  htons(ETH_P_IPV6))
   {
      pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];

      buf = (char *)&pIpHdr->saddr;
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
               "%s: src addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf));

      buf = (char *)&pIpHdr->daddr;
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
               "%s: dst addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf));
   }
   else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
            (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
            (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
            (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL))
   {
      if (pHdr->eth_8023.h_proto == htons(ETH_P_IP))
      {
         pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];

         buf = (char *)&pIpHdr->saddr;
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                  "%s: src addr %d:%d:%d:%d", __func__,
                  buf[0], buf[1], buf[2], buf[3]);

         buf = (char *)&pIpHdr->daddr;
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                  "%s: dst addr %d:%d:%d:%d", __func__,
                  buf[0], buf[1], buf[2], buf[3]);
      }
      else if (pHdr->eth_8023.h_proto == htons(ETH_P_IPV6))
      {
         pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];

         buf = (char *)&pIpHdr->saddr;
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
               "%s: src addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf));

         buf = (char *)&pIpHdr->daddr;
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: dst addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf));
      }
   }
}

/**============================================================================
  @brief hdd_get_arp_src_ip() - Function to get ARP src IP addr
  @param skb      : [in]  pointer to OS packet (sk_buff)
  @return         : IP addr
  ===========================================================================*/
uint32_t  hdd_get_arp_src_ip(struct sk_buff *skb)
{
   struct arphdr *arp;
   unsigned char *arp_ptr;
   uint32_t src_ip;

#define ARP_HDR_SIZE ( sizeof(__be16)*3 + sizeof(unsigned char)*2 )
#define ARP_SENDER_HW_ADDRESS_SZ (6)
#define ARP_SENDER_IP_ADDRESS_SZ (4)

   arp = (struct arphdr *)skb->data;

   arp_ptr = (unsigned char *)arp + ARP_HDR_SIZE;
   arp_ptr += ARP_SENDER_HW_ADDRESS_SZ;

   memcpy(&src_ip, arp_ptr, ARP_SENDER_IP_ADDRESS_SZ);

   src_ip=ntohl(src_ip);

   return src_ip;

#undef ARP_HDR_SIZE
#undef ARP_SENDER_HW_ADDRESS_SZ
#undef ARP_SENDER_IP_ADDRESS_SZ
}

/**============================================================================
  @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet
  into a WMM AC based on either 802.1Q or DSCP

  @param pAdapter : [in]  pointer to adapter context
  @param skb      : [in]  pointer to OS packet (sk_buff)
  @param pAcType  : [out] pointer to WMM AC type of OS packet

  @return         : None
  ===========================================================================*/
v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter,
                                struct sk_buff *skb,
                                WLANTL_ACEnumType* pAcType,
                                sme_QosWmmUpType *pUserPri)
{
   unsigned char * pPkt;
   union generic_ethhdr *pHdr;
   struct iphdr *pIpHdr;
   unsigned char tos;
   unsigned char dscp;
   sme_QosWmmUpType userPri;
   WLANTL_ACEnumType acType;

   // this code is executed for every packet therefore
   // all debug code is kept conditional

#ifdef HDD_WMM_DEBUG
   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered", __func__);
#endif // HDD_WMM_DEBUG

   pPkt = skb->data;
   pHdr = (union generic_ethhdr *)pPkt;

#ifdef HDD_WMM_DEBUG
   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: proto/length is 0x%04x",
             __func__, pHdr->eth_II.h_proto);
#endif // HDD_WMM_DEBUG

   if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
   {
      if (pHdr->eth_II.h_proto == htons(ETH_P_IP))
      {
         // case 1: Ethernet II IP packet
         pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)];
         tos = pIpHdr->tos;
#ifdef HDD_WMM_DEBUG
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                   "%s: Ethernet II IP Packet, tos is %d",
                   __func__, tos);
#endif // HDD_WMM_DEBUG

      }
      else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
               (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
               (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
               (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
               (pHdr->eth_8023.h_proto == htons(ETH_P_IP)))
      {
         // case 2: 802.3 LLC/SNAP IP packet
         pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)];
         tos = pIpHdr->tos;
#ifdef HDD_WMM_DEBUG
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                   "%s: 802.3 LLC/SNAP IP Packet, tos is %d",
                   __func__, tos);
#endif // HDD_WMM_DEBUG
      }
      else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q))
      {
         // VLAN tagged

         if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP))
         {
            // case 3: Ethernet II vlan-tagged IP packet
            pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)];
            tos = pIpHdr->tos;
#ifdef HDD_WMM_DEBUG
            VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                      "%s: Ethernet II VLAN tagged IP Packet, tos is %d",
                      __func__, tos);
#endif // HDD_WMM_DEBUG
         }
         else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) &&
                  (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) &&
                  (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) &&
                  (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) &&
                  (pHdr->eth_8023v.h_proto == htons(ETH_P_IP)))
         {
            // case 4: 802.3 LLC/SNAP vlan-tagged IP packet
            pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)];
            tos = pIpHdr->tos;
#ifdef HDD_WMM_DEBUG
            VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                      "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
                      __func__, tos);
#endif // HDD_WMM_DEBUG
         }
         else
         {
            // default
#ifdef HDD_WMM_DEBUG
            VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
                      "%s: VLAN tagged Unhandled Protocol, using default tos",
                      __func__);
#endif // HDD_WMM_DEBUG
            tos = 0;
         }
      }
      else
      {
          v_BOOL_t toggleArpBDRates =
                        (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->toggleArpBDRates;
          // default
#ifdef HDD_WMM_DEBUG
          VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
                  "%s: Unhandled Protocol, using default tos",
                  __func__);
#endif // HDD_WMM_DEBUG
          //Give the highest priority to 802.1x packet
          if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
              tos = 0xC0;
          else if (toggleArpBDRates &&
                   pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_ARP))
          {
              tos = TID3;
          }
          else
              tos = 0;
      }

      dscp = (tos>>2) & 0x3f;
      userPri = pAdapter->hddWmmDscpToUpMap[dscp];

#ifdef HDD_WMM_DEBUG
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                "%s: tos is %d, dscp is %d, up is %d",
                __func__, tos, dscp, userPri);
#endif // HDD_WMM_DEBUG

   }
   else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis)
   {
      if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q))
      {
         // VLAN tagged
         userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7;
#ifdef HDD_WMM_DEBUG
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                   "%s: Tagged frame, UP is %d",
                   __func__, userPri);
#endif // HDD_WMM_DEBUG
      }
      else
      {
          // not VLAN tagged, use default
#ifdef HDD_WMM_DEBUG
          VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
                  "%s: Untagged frame, using default UP",
                  __func__);
#endif // HDD_WMM_DEBUG
          //Give the highest priority to 802.1x packet
          if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X))
              userPri = SME_QOS_WMM_UP_VO;
          else
              userPri = SME_QOS_WMM_UP_BE;
      }
   }
   else
   {
      // default
#ifdef HDD_WMM_DEBUG
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Unknown classification scheme, using default UP",
                __func__);
#endif // HDD_WMM_DEBUG
      userPri = SME_QOS_WMM_UP_BE;
   }

   acType = hddWmmUpToAcMap[userPri];

#ifdef HDD_WMM_DEBUG
   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
             "%s: UP is %d, AC is %d",
             __func__, userPri, acType);
#endif // HDD_WMM_DEBUG

   *pUserPri = userPri;
   *pAcType = acType;

   return;
}

/**============================================================================
  @brief hdd_hostapd_select_quueue() - Function which will classify the packet
         according to linux qdisc expectation.


  @param dev      : [in]  pointer to net_device structure
  @param skb      : [in]  pointer to os packet

  @return         : Qdisc queue index
  ===========================================================================*/
v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0))
                                 , void *accel_priv
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
                                 , select_queue_fallback_t fallbac
#endif
)
{
   WLANTL_ACEnumType ac;
   sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
   v_USHORT_t queueIndex;
   v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
   hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   v_U8_t STAId;
   v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
   ptSapContext pSapCtx = NULL;
   int status = 0;

   status = wlan_hdd_validate_context(pHddCtx);
   if (status !=0 )
   {
       VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  FL("called during WDReset/unload"));
       skb->priority = SME_QOS_WMM_UP_BE;
       return HDD_LINUX_AC_BE;
   }

   pSapCtx = VOS_GET_SAP_CB(pVosContext);
   if(pSapCtx == NULL){
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                 FL("psapCtx is NULL"));
       STAId = HDD_WLAN_INVALID_STA_ID;
       goto done;
   }
   /*Get the Station ID*/
   STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress);
   if (STAId == HDD_WLAN_INVALID_STA_ID || STAId >= WLAN_MAX_STA_COUNT) {
       VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
                 "%s: Failed to find right station", __func__);
       goto done;
   }

   spin_lock_bh( &pSapCtx->staInfo_lock );
   if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
                   "%s: Station MAC address does not matching", __func__);

      STAId = HDD_WLAN_INVALID_STA_ID;
      goto release_lock;
   }
   if (pSapCtx->aStaInfo[STAId].isUsed && pSapCtx->aStaInfo[STAId].isQosEnabled && (HDD_WMM_USER_MODE_NO_QOS != pHddCtx->cfg_ini->WmmMode))
   {
      /* Get the user priority from IP header & corresponding AC */
      hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
      //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue
      if (pSapCtx->aStaInfo[STAId].vosLowResource && hdd_is_dhcp_packet(skb))
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
                    "%s: Making priority of DHCP packet as VOICE", __func__);
         up = SME_QOS_WMM_UP_VO;
         ac = hddWmmUpToAcMap[up];
      }
   }

release_lock:
    spin_unlock_bh( &pSapCtx->staInfo_lock );
done:
   skb->priority = up;
   if(skb->priority < SME_QOS_WMM_UP_MAX)
         queueIndex = hddLinuxUpToAcMap[skb->priority];
   else
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                 "%s: up=%d is going beyond max value", __func__, up);
      queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
   }

   return queueIndex;
}

/**============================================================================
  @brief hdd_wmm_select_quueue() - Function which will classify the packet
         according to linux qdisc expectation.


  @param dev      : [in]  pointer to net_device structure
  @param skb      : [in]  pointer to os packet

  @return         : Qdisc queue index
  ===========================================================================*/
v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
{
   WLANTL_ACEnumType ac;
   sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
   v_USHORT_t queueIndex;
   hdd_adapter_t *pAdapter =  WLAN_HDD_GET_PRIV_PTR(dev);
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
   int status = 0;

   status = wlan_hdd_validate_context(pHddCtx);
   if (status !=0) {
       skb->priority = SME_QOS_WMM_UP_BE;
       return HDD_LINUX_AC_BE;
   }

   /*Get the Station ID*/
   if (WLAN_HDD_IBSS == pAdapter->device_mode)
   {
       v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
       v_U8_t STAId;

       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))
       {
           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                     "%s: Failed to find right station pDestMacAddress: "
                     MAC_ADDRESS_STR , __func__,
                     MAC_ADDR_ARRAY(pDestMacAddress->bytes));
           goto done;
       }
   }
   /* All traffic will get equal opportuniy to transmit data frames. */
   /* Get the user priority from IP header & corresponding AC */
   hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);

   /* If 3/4th of BE AC Tx queue is full,
    * then place the DHCP packet in VOICE AC queue.
    * Doing this for IBSS alone, since for STA interface
    * types, these packets will be queued to the new queue.
    */
   if ((WLAN_HDD_IBSS == pAdapter->device_mode) &&
       pAdapter->isVosLowResource && hdd_is_dhcp_packet(skb))
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
                "%s: BestEffort Tx Queue is 3/4th full"
                " Make DHCP packet's pri as VO", __func__);
      up = SME_QOS_WMM_UP_VO;
      ac = hddWmmUpToAcMap[up];
   }

done:
   skb->priority = up;
   if(skb->priority < SME_QOS_WMM_UP_MAX)
         queueIndex = hddLinuxUpToAcMap[skb->priority];
   else
   {
       VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
                 "%s: up=%d is going beyond max value", __func__, up);
      queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE];
   }

   if ((WLAN_HDD_IBSS != pAdapter->device_mode) &&
       (hdd_is_dhcp_packet(skb) ||
        hdd_skb_is_eapol_or_wai_packet(skb)))
   {
       /* If the packet is a DHCP packet or a Eapol packet or
        * a Wapi packet, then queue it to the new queue for
        * STA interfaces alone.
        */
       queueIndex = WLANTL_AC_HIGH_PRIO;
       VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                 "%s: up=%d QIndex:%d", __func__, up, queueIndex);
   }

   return queueIndex;
}

/**==========================================================================
  @brief hdd_wmm_acquire_access_required() - Function which will determine
  acquire admittance for a WMM AC is required or not based on psb configuration
  done in framework

  @param pAdapter : [in]  pointer to adapter structure

  @param acType  : [in]  WMM AC type of OS packet

  @return        : void
  ===========================================================================*/
void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
                                     WLANTL_ACEnumType acType)
{
/* Each bit in the LSB nibble indicates 1 AC.
 * Clearing the particular bit in LSB nibble to indicate
 * access required
 */
   switch(acType)
   {
   case WLANTL_AC_BK:
      pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK; /* clear first bit */
      break;
   case WLANTL_AC_BE:
      pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK; /* clear second bit */
      break;
   case WLANTL_AC_VI:
      pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK; /* clear third bit */
      break;
   case WLANTL_AC_VO:
      pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK; /* clear fourth bit */
      break;
   default:
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
               "%s: Invalid AC Type", __func__);
     break;
   }
}

/**============================================================================
  @brief hdd_wmm_acquire_access() - Function which will attempt to acquire
  admittance for a WMM AC

  @param pAdapter : [in]  pointer to adapter context
  @param acType   : [in]  WMM AC type of OS packet
  @param pGranted : [out] pointer to boolean flag when indicates if access
                          has been granted or not

  @return         : VOS_STATUS_SUCCESS if succssful
                  : other values if failure
  ===========================================================================*/
VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter,
                                   WLANTL_ACEnumType acType,
                                   v_BOOL_t * pGranted )
{
   hdd_wmm_qos_context_t *pQosContext;

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered for AC %d", __func__, acType);

   if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
   {
      // either we don't want QoS or the AP doesn't support QoS
      // or we don't want to do implicit QoS
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                "%s: QoS not configured on both ends ", __func__);

      pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
      *pGranted = VOS_TRUE;
      return VOS_STATUS_SUCCESS;
   }

   // do we already have an implicit QoS request pending for this AC?
   if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) ||
       (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending))
   {
      // request already pending so we need to wait for that response
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                "%s: Implicit QoS for TL AC %d already scheduled",
                __func__, acType);

      *pGranted = VOS_FALSE;
      return VOS_STATUS_SUCCESS;
   }

   // did we already fail to establish implicit QoS for this AC?
   // (if so, access should have been granted when the failure was handled)
   if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed)
   {
      // request previously failed
      // allow access, but we'll be downgraded
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                "%s: Implicit QoS for TL AC %d previously failed",
                __func__, acType);

      pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
      *pGranted = VOS_TRUE;
      return VOS_STATUS_SUCCESS;
   }

   // we need to establish implicit QoS
   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
             "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %pK",
             __func__, acType, pAdapter);

   pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE;

   pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC);
   if (NULL == pQosContext)
   {
      // no memory for QoS context.  Nothing we can do but let data flow
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Unable to allocate context", __func__);
      pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE;
      *pGranted = VOS_TRUE;
      return VOS_STATUS_SUCCESS;
   }

   pQosContext->acType = acType;
   pQosContext->pAdapter = pAdapter;
   pQosContext->qosFlowId = 0;
   pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
   pQosContext->magic = HDD_WMM_CTX_MAGIC;
   vos_init_work(&pQosContext->wmmAcSetupImplicitQos,
             hdd_wmm_do_implicit_qos);

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
             "%s: Scheduling work for AC %d, context %pK",
             __func__, acType, pQosContext);

   schedule_work(&pQosContext->wmmAcSetupImplicitQos);

   // caller will need to wait until the work takes place and
   // TSPEC negotiation completes
   *pGranted = VOS_FALSE;
   return VOS_STATUS_SUCCESS;
}

/**============================================================================
  @brief hdd_wmm_assoc() - Function which will handle the housekeeping
  required by WMM when association takes place

  @param pAdapter : [in]  pointer to adapter context
  @param pRoamInfo: [in]  pointer to roam information
  @param eBssType : [in]  type of BSS

  @return         : VOS_STATUS_SUCCESS if succssful
                  : other values if failure
  ===========================================================================*/
VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter,
                          tCsrRoamInfo *pRoamInfo,
                          eCsrRoamBssType eBssType )
{
   tANI_U8 uapsdMask;
   VOS_STATUS status;
   hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);

   // when we associate we need to notify TL if it needs to enable
   // UAPSD for any access categories

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered", __func__);

   if (pRoamInfo->fReassocReq)
   {
      // when we reassociate we should continue to use whatever
      // parameters were previously established.  if we are
      // reassociating due to a U-APSD change for a particular
      // Access Category, then the change will be communicated
      // to HDD via the QoS callback associated with the given
      // flow, and U-APSD parameters will be updated there

      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                "%s: Reassoc so no work, Exiting", __func__);

      return VOS_STATUS_SUCCESS;
   }

   // get the negotiated UAPSD Mask
   uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask;

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask);

   if (uapsdMask & HDD_AC_VO)
   {
      status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                        (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                                        WLANTL_AC_VO,
                                        7,
                                        7,
                                        (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv,
                                        (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv,
                                        WLANTL_BI_DIR );

      VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
   }

   if (uapsdMask & HDD_AC_VI)
   {
      status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                        (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                                        WLANTL_AC_VI,
                                        5,
                                        5,
                                        (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv,
                                        (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv,
                                        WLANTL_BI_DIR );

      VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
   }

   if (uapsdMask & HDD_AC_BK)
   {
      status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                        (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                                        WLANTL_AC_BK,
                                        2,
                                        2,
                                        (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv,
                                        (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv,
                                        WLANTL_BI_DIR );

      VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
   }

   if (uapsdMask & HDD_AC_BE)
   {
      status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
                                        (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0],
                                        WLANTL_AC_BE,
                                        3,
                                        3,
                                        (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv,
                                        (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv,
                                        WLANTL_BI_DIR );

      VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ));
   }

   status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal,
       pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId);

   if (!VOS_IS_STATUS_SUCCESS( status ))
   {
       hdd_wmm_init( pAdapter );
   }

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Exiting", __func__);

   return VOS_STATUS_SUCCESS;
}



static const v_U8_t acmMaskBit[WLANTL_MAX_AC] =
   {
      0x4, /* WLANTL_AC_BK */
      0x8, /* WLANTL_AC_BE */
      0x2, /* WLANTL_AC_VI */
      0x1  /* WLANTL_AC_VO */
   };

/**============================================================================
  @brief hdd_wmm_connect() - Function which will handle the housekeeping
  required by WMM when a connection is established

  @param pAdapter : [in]  pointer to adapter context
  @param pRoamInfo: [in]  pointer to roam information
  @param eBssType : [in]  type of BSS

  @return         : VOS_STATUS_SUCCESS if succssful
                  : other values if failure
  ===========================================================================*/
VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter,
                            tCsrRoamInfo *pRoamInfo,
                            eCsrRoamBssType eBssType )
{
   int ac;
   v_BOOL_t qap;
   v_BOOL_t qosConnection;
   v_U8_t acmMask;

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered", __func__);

   if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) &&
       pRoamInfo &&
       pRoamInfo->u.pConnectedProfile)
   {
      qap = pRoamInfo->u.pConnectedProfile->qap;
      qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection;
      acmMask = pRoamInfo->u.pConnectedProfile->acm_mask;
   }
   else
   {
      /* TODO: if a non-qos IBSS peer joins the group make qap and qosConnection false.
       */
      qap = VOS_TRUE;
      qosConnection = VOS_TRUE;
      acmMask = 0x0;
   }

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: qap is %d, qosConnection is %d, acmMask is 0x%x",
             __func__, qap, qosConnection, acmMask);

   pAdapter->hddWmmStatus.wmmQap = qap;
   pAdapter->hddWmmStatus.wmmQosConnection = qosConnection;

   for (ac = 0; ac < WLANTL_MAX_AC; ac++)
   {
      if (qap &&
          qosConnection &&
          (acmMask & acmMaskBit[ac]))
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                   "%s: ac %d on",
                   __func__, ac);

         // admission is required
         pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE;
         //Mark wmmAcAccessAllowed as True if implicit Qos is disabled as there
         //is no need to hold packets in queue during hdd_tx_fetch_packet_cbk
         if (!(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled)
              pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed =
                                                                     VOS_TRUE;
         else
              pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed =
                                                                    VOS_FALSE;
         pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE;

         /* Making TSPEC invalid here so downgrading can be happen while roaming
          * It is expected this will be SET in hdd_wmm_sme_callback,once sme is
          * done with the AddTspec.Here we avoid 11r and ccx based association.
            This change is done only when reassoc to different AP.
          */
         VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                      FL( "fReassocReq = %d"
#if defined (FEATURE_WLAN_ESE)
                          "isESEAssoc = %d"
#endif
#if defined (WLAN_FEATURE_VOWIFI_11R)
                          "is11rAssoc = %d"
#endif
                        ),
                        pRoamInfo->fReassocReq
#if defined (FEATURE_WLAN_ESE)
                        ,pRoamInfo->isESEAssoc
#endif
#if defined (WLAN_FEATURE_VOWIFI_11R)
                        ,pRoamInfo->is11rAssoc
#endif
                  );

         if ( !pRoamInfo->fReassocReq
#if defined (WLAN_FEATURE_VOWIFI_11R)
            &&
            !pRoamInfo->is11rAssoc
#endif
#if defined (FEATURE_WLAN_ESE)
            &&
            !pRoamInfo->isESEAssoc
#endif
            )
         {
            pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid = VOS_FALSE;
         }
      }
      else
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                   "%s: ac %d off",
                   __func__, ac);
         // admission is not required so access is allowed
         pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE;
         pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE;
      }

   }

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Exiting", __func__);

   return VOS_STATUS_SUCCESS;
}

/**============================================================================
  @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the
  initial value of the UAPSD mask based upon the device configuration

  @param pAdapter  : [in]  pointer to adapter context
  @param pUapsdMask: [in]  pointer to where the UAPSD Mask is to be stored

  @return         : VOS_STATUS_SUCCESS if succssful
                  : other values if failure
  ===========================================================================*/
VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter,
                                   tANI_U8 *pUapsdMask )
{
   tANI_U8 uapsdMask;

   if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
   {
      // no QOS then no UAPSD
      uapsdMask = 0;
   }
   else
   {
      // start with the default mask
      uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;

      // disable UAPSD for any ACs with a 0 Service Interval
      if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 )
      {
         uapsdMask &= ~HDD_AC_VO;
      }

      if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 )
      {
         uapsdMask &= ~HDD_AC_VI;
      }

      if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 )
      {
         uapsdMask &= ~HDD_AC_BK;
      }

      if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 )
      {
         uapsdMask &= ~HDD_AC_BE;
      }
   }

   // return calculated mask
   *pUapsdMask = uapsdMask;
   return VOS_STATUS_SUCCESS;
}


/**============================================================================
  @brief hdd_wmm_is_active() - Function which will determine if WMM is
  active on the current connection

  @param pAdapter  : [in]  pointer to adapter context

  @return         : VOS_TRUE if WMM is enabled
                  : VOS_FALSE if WMM is not enabled
  ===========================================================================*/
v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter )
{
   if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
       (!pAdapter->hddWmmStatus.wmmQap))
   {
      return VOS_FALSE;
   }
   else
   {
      return VOS_TRUE;
   }
}

/**============================================================================
  @brief hdd_wmm_addts() - Function which will add a traffic spec at the
  request of an application

  @param pAdapter  : [in]  pointer to adapter context
  @param handle    : [in]  handle to uniquely identify a TS
  @param pTspec    : [in]  pointer to the traffic spec

  @return          : HDD_WLAN_WMM_STATUS_*
  ===========================================================================*/
hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter,
                                     v_U32_t handle,
                                     sme_QosWmmTspecInfo* pTspec )
{
   hdd_wmm_qos_context_t *pQosContext;
   hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
   sme_QosStatusType smeStatus;
#endif
   v_BOOL_t found = VOS_FALSE;
   v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
   hdd_context_t *pHddCtx = NULL;

   if (NULL == pVosContext)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                   FL("pVosContext is NULL"));
      return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
   }

   pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
   if (NULL == pHddCtx)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                   FL("HddCtx is NULL"));
      return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
   }

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered with handle 0x%x", __func__, handle);

   // see if a context already exists with the given handle
   mutex_lock(&pHddCtx->wmmLock);
   list_for_each_entry(pQosContext,
                       &pAdapter->hddWmmStatus.wmmContextList,
                       node)
   {
      if (pQosContext->handle == handle)
      {
         found = VOS_TRUE;
         break;
      }
   }
   mutex_unlock(&pHddCtx->wmmLock);
   if (found)
   {
      // record with that handle already exists
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Record already exists with handle 0x%x",
                __func__, handle);

      /* Application is trying to modify some of the Tspec params. Allow it */
      smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
                                  pTspec,
                                  pQosContext->qosFlowId);

      // need to check the return value and act appropriately
      switch (smeStatus)
      {
        case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP:
          status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING;
          break;
        case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
          status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD;
          break;
        case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY:
          status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING;
          break;
        case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP:
          status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM;
          break;
        case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP:
          status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
          break;
        case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
          status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
          break;
        default:
          // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes
          VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                     "%s: unexpected SME Status=%d", __func__, smeStatus );
          VOS_ASSERT(0);
          return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
      }

      mutex_lock(&pHddCtx->wmmLock);
      if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
      {
          pQosContext->lastStatus = status;
      }
      mutex_unlock(&pHddCtx->wmmLock);
      return status;
   }

   pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL);
   if (NULL == pQosContext)
   {
      // no memory for QoS context.  Nothing we can do
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Unable to allocate QoS context", __func__);
      return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE;
   }

   // we assume the tspec has already been validated by the caller

   pQosContext->handle = handle;
   if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE)
      pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
   else {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: ts_info.up (%d) larger than max value (%d), "
                "use default acType (%d)",
                __func__, pTspec->ts_info.up,
                HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hddWmmUpToAcMap[0]);
      pQosContext->acType = hddWmmUpToAcMap[0];
   }

   pQosContext->pAdapter = pAdapter;
   pQosContext->qosFlowId = 0;

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
             "%s: Setting up QoS, context %pK",
             __func__, pQosContext);

   mutex_lock(&pHddCtx->wmmLock);
   pQosContext->magic = HDD_WMM_CTX_MAGIC;
   list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
   mutex_unlock(&pHddCtx->wmmLock);

#ifndef WLAN_MDM_CODE_REDUCTION_OPT
   smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
                               pAdapter->sessionId,
                               pTspec,
                               hdd_wmm_sme_callback,
                               pQosContext,
                               pTspec->ts_info.up,
                               &pQosContext->qosFlowId);

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
             "%s: sme_QosSetupReq returned %d flowid %d",
             __func__, smeStatus, pQosContext->qosFlowId);

   // need to check the return value and act appropriately
   switch (smeStatus)
   {
   case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP:
      status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
      break;
   case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP:
      status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD;
      break;
   case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY:
      status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING;
      break;
   case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING:
      status = HDD_WLAN_WMM_STATUS_SETUP_PENDING;
      break;
   case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
      hdd_wmm_free_context(pQosContext);
      return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
   case SME_QOS_STATUS_SETUP_FAILURE_RSP:
      // we can't tell the difference between when a request fails because
      // AP rejected it versus when SME encounterd an internal error
      hdd_wmm_free_context(pQosContext);
      return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
   case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP:
      hdd_wmm_free_context(pQosContext);
      return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM;
   default:
      // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes
      hdd_wmm_free_context(pQosContext);
      VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                 "%s: unexpected SME Status=%d", __func__, smeStatus );
      VOS_ASSERT(0);
      return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
   }
#endif

   // we were successful, save the status
   mutex_lock(&pHddCtx->wmmLock);
   if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
   {
         pQosContext->lastStatus = status;
   }
   mutex_unlock(&pHddCtx->wmmLock);

   return status;
}

/**============================================================================
  @brief hdd_wmm_delts() - Function which will delete a traffic spec at the
  request of an application

  @param pAdapter  : [in]  pointer to adapter context
  @param handle    : [in]  handle to uniquely identify a TS

  @return          : HDD_WLAN_WMM_STATUS_*
  ===========================================================================*/
hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter,
                                     v_U32_t handle )
{
   hdd_wmm_qos_context_t *pQosContext;
   v_BOOL_t found = VOS_FALSE;
   WLANTL_ACEnumType acType = 0;
   v_U32_t qosFlowId = 0;
   hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ;
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
   sme_QosStatusType smeStatus;
#endif
   v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
   hdd_context_t *pHddCtx = NULL;

   if (NULL == pVosContext)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                   FL("pVosContext is NULL"));
      return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
   }

   pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
   if (NULL == pHddCtx)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                   FL("HddCtx is NULL"));
      return HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
   }

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered with handle 0x%x", __func__, handle);

   // locate the context with the given handle
   mutex_lock(&pHddCtx->wmmLock);
   list_for_each_entry(pQosContext,
                       &pAdapter->hddWmmStatus.wmmContextList,
                       node)
   {
      if (pQosContext->handle == handle)
      {
         found = VOS_TRUE;
         acType = pQosContext->acType;
         qosFlowId = pQosContext->qosFlowId;
         break;
      }
   }
   mutex_unlock(&pHddCtx->wmmLock);

   if (VOS_FALSE == found)
   {
      // we didn't find the handle
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                "%s: handle 0x%x not found", __func__, handle);
      return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
   }


   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: found handle 0x%x, flow %d, AC %d, context %pK",
             __func__, handle, qosFlowId, acType, pQosContext);

#ifndef WLAN_MDM_CODE_REDUCTION_OPT
   smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId );

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: SME flow %d released, SME status %d",
             __func__, qosFlowId, smeStatus);

   switch(smeStatus)
   {
   case SME_QOS_STATUS_RELEASE_SUCCESS_RSP:
      // this flow is the only one on that AC, so go ahead and update
      // our TSPEC state for the AC
      pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE;

      // need to tell TL to stop trigger timer, etc
      hdd_wmm_disable_tl_uapsd(pQosContext);

#ifdef FEATURE_WLAN_ESE
      // disable the inactivity timer
      hdd_wmm_disable_inactivity_timer(pQosContext);
#endif
      // we are done with this context
      hdd_wmm_free_context(pQosContext);

      // SME must not fire any more callbacks for this flow since the context
      // is no longer valid

      return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS;

   case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP:
      // do nothing as we will get a response from SME
      status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING;
      break;

   case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
      // nothing we can do with the existing flow except leave it
      status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
      break;

   case SME_QOS_STATUS_RELEASE_FAILURE_RSP:
      // nothing we can do with the existing flow except leave it
      status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;

   default:
      // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes
      VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                 "%s: unexpected SME Status=%d", __func__, smeStatus );
      VOS_ASSERT(0);
      status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
   }

#endif
   mutex_lock(&pHddCtx->wmmLock);
   if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
   {
         pQosContext->lastStatus = status;
   }
   mutex_unlock(&pHddCtx->wmmLock);
   return status;
}

/**============================================================================
  @brief hdd_wmm_checkts() - Function which will return the status of a traffic
  spec at the request of an application

  @param pAdapter  : [in]  pointer to adapter context
  @param handle    : [in]  handle to uniquely identify a TS

  @return          : HDD_WLAN_WMM_STATUS_*
  ===========================================================================*/
hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter,
                                       v_U32_t handle )
{
   hdd_wmm_qos_context_t *pQosContext;
   hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;
   v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
   hdd_context_t *pHddCtx = NULL;

   if (NULL == pVosContext)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                   FL("pVosContext is NULL"));
      return HDD_WLAN_WMM_STATUS_LOST;
   }

   pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
   if (NULL == pHddCtx)
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                   FL("HddCtx is NULL"));
      return HDD_WLAN_WMM_STATUS_LOST;
   }

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
             "%s: Entered with handle 0x%x", __func__, handle);

   // locate the context with the given handle
   mutex_lock(&pHddCtx->wmmLock);
   list_for_each_entry(pQosContext,
                       &pAdapter->hddWmmStatus.wmmContextList,
                       node)
   {
      if (pQosContext->handle == handle)
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW,
                   "%s: found handle 0x%x, context %pK",
                   __func__, handle, pQosContext);

         status = pQosContext->lastStatus;
         break;
      }
   }
   mutex_unlock(&pHddCtx->wmmLock);
   return status;
}
