/*
 * Copyright (c) 2012-2015 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


#define WLAN_HDD_MAX_DSCP 0x3f

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

#define HDD_WMM_UP_TO_AC_MAP_SIZE 8

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;

   if (NULL != pVosContext)
   {
      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 %p",
             __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;

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

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

    acType = pQosContext->acType;
    pAdapter = pQosContext->pAdapter;
    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);
        }
    }

    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;

   if (NULL != pVosContext)
   {
      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 %p",
             __func__, pQosContext);

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

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

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

      // 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;
   int ret = 0;

   if (NULL != pVosContext)
   {
      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;
      }
   }

   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 %p",
             __func__, pQosContext);

   mutex_lock(&pHddCtx->wmmLock);
   if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic))
   {
      VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR,
                "%s: Invalid QoS Context",
                __func__);
      mutex_unlock(&pHddCtx->wmmLock);
      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 %p 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_HDD_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;

   if (NULL != pVosContext)
   {
      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
#ifdef WLAN_OPEN_SOURCE
   mutex_lock(&pHddCtx->wmmLock);
   if (pQosContext->handle == HDD_WMM_HANDLE_IMPLICIT
       && pQosContext->magic == HDD_WMM_CTX_MAGIC)
   {

      cancel_work_sync(&pQosContext->wmmAcSetupImplicitQos);
   }
   mutex_unlock(&pHddCtx->wmmLock);
#endif
      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_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
      {
          // 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
              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)
{
   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_U8_t *pSTAId = (v_U8_t *)(((v_U8_t *)(skb->data)) - 1);
   v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
   ptSapContext pSapCtx = NULL;
   pSapCtx = VOS_GET_SAP_CB(pVosContext);
   if(pSapCtx == NULL){
       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
                 FL("psapCtx is NULL"));
       *pSTAId = HDD_WLAN_INVALID_STA_ID;
       goto done;
   }
   /*Get the Station ID*/
   if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &STAId))
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO,
            "%s: Failed to find right station", __func__);
      *pSTAId = HDD_WLAN_INVALID_STA_ID;
      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__);

      *pSTAId = 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];
      }
   }
   *pSTAId = STAId;

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

   if (vos_is_logp_in_progress(VOS_MODULE_ID_HDD, NULL)) {
       VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                  FL("called during WDReset"));
       skb->priority = SME_QOS_WMM_UP_BE;
       return HDD_LINUX_AC_BE;
   }

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

       if ( VOS_STATUS_SUCCESS !=
            hdd_Ibss_GetStaId(&pAdapter->sessionCtx.station,
                               pDestMacAddress, pSTAId))
       {
          *pSTAId = HDD_WLAN_INVALID_STA_ID;
          if ( !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 %p",
             __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;
   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 %p",
             __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;
         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;
   if (NULL != pVosContext)
   {
      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 %p",
             __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;

   if (NULL != pVosContext)
   {
      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 %p",
             __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;

   if (NULL != pVosContext)
   {
      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 %p",
                   __func__, handle, pQosContext);

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