/*
 * Copyright (c) 2012-2013, 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.
 */
/*
 * Copyright (c) 2012, 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.
 */

/*============================================================================
  @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.


               Copyright (c) 2008-9 QUALCOMM Incorporated.
               All Rights Reserved.
               Qualcomm Confidential and Proprietary
============================================================================*/

/*---------------------------------------------------------------------------
  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>

// 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

static sme_QosWmmUpType hddWmmDscpToUpMap[WLAN_HDD_MAX_DSCP+1];

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 = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
   VOS_STATUS status;
   v_U32_t service_interval;
   v_U32_t suspension_interval;
   sme_QosWmmDirType direction;


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

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

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

   VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO,
             "%s: Enabled UAPSD in TL srv_int=%ld "
             "susp_int=%ld 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 = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
   VOS_STATUS status;


   // have we previously enabled UAPSD?
   if (pAc->wmmAcUapsdInfoValid == VOS_TRUE)
   {
      status = WLANTL_DisableUAPSDForAC((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 disable U-APSD 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: Disabled UAPSD 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)
{
   hdd_adapter_t* pAdapter;

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

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

   // get pointer to the adapter context
   pAdapter = pQosContext->pAdapter;

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

   // 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(&pAdapter->hddWmmStatus.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];

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

   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__);
      return;
   }


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

   // get pointer to the adapter
   pAdapter = pQosContext->pAdapter;

   // 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_CCX
/**
  @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 = 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\n"),
            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_CCX

/**
  @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;

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

   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__);
      return eHAL_STATUS_FAILURE;
   }

   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_CCX
      // 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\n",
                 __func__, pCurrentQosInfo->inactivity_interval, acType);
         hdd_wmm_enable_inactivity_timer(pQosContext, pCurrentQosInfo->inactivity_interval);
      }
#endif // FEATURE_WLAN_CCX

      // 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\n",
                 __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\n",
                 __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_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;

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

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

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

   switch (acType)
   {
   case WLANTL_AC_VO:
      qosInfo.ts_info.up = SME_QOS_WMM_UP_VO;
      qosInfo.ts_info.psb = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & 0x01;
      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;
      qosInfo.ts_info.psb = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & 0x02;
      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;
   default:
   case WLANTL_AC_BE:
      qosInfo.ts_info.up = SME_QOS_WMM_UP_BE;
      qosInfo.ts_info.psb = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & 0x08;
      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;
      qosInfo.ts_info.psb = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & 0x04;
      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;
   }
#ifdef FEATURE_WLAN_CCX
   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(&pAdapter->hddWmmStatus.wmmLock);
   list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
   mutex_unlock(&pAdapter->hddWmmStatus.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\n",
                 __func__, smeStatus );
      VOS_ASSERT(0);
   }
#endif

}

/**============================================================================
  @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 pHddCtx : [in]  pointer to HDD context

  @return         : VOS_STATUS_SUCCESS if succssful
                  : other values if failure

  ===========================================================================*/
VOS_STATUS hdd_wmm_init ( hdd_context_t* pHddCtx )
{
   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);
   mutex_init(&pAdapter->hddWmmStatus.wmmLock);

   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;

   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_CCX
      hdd_wmm_disable_inactivity_timer(pQosContext);
#endif
      hdd_wmm_free_context(pQosContext);
   }

   return VOS_STATUS_SUCCESS;
}

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

   /*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( &pAdapter->staInfo_lock );
   if (FALSE == vos_is_macaddr_equal(&pAdapter->aStaInfo[STAId].macAddrSTA, pDestMacAddress))
   {
      VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
                   "%s: Station MAC address does not matching", __func__);

      *pSTAId = HDD_WLAN_INVALID_STA_ID;
      goto release_lock;
   }
   if (pAdapter->aStaInfo[STAId].isUsed && pAdapter->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);
   }
   *pSTAId = STAId;

release_lock:
    spin_unlock_bh( &pAdapter->staInfo_lock );
done:
   skb->priority = up;
   queueIndex = hddLinuxUpToAcMap[skb->priority];

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

   /*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))
       {
          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));
          *pSTAId = HDD_WLAN_INVALID_STA_ID;
          goto done;
       }
   }
   // if we don't want QoS or the AP doesn't support Qos
   // All traffic will get equal opportuniy to transmit data frames.
   if( hdd_wmm_is_active(pAdapter) ) {
      /* Get the user priority from IP header & corresponding AC */
      hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
   }
done:
   skb->priority = up;
   queueIndex = hddLinuxUpToAcMap[skb->priority];

   return queueIndex;
}

/**============================================================================
  @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;

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

   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
   {
      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;
      }
      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;

   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(&pAdapter->hddWmmStatus.wmmLock);
   list_for_each_entry(pQosContext,
                       &pAdapter->hddWmmStatus.wmmContextList,
                       node)
   {
      if (pQosContext->handle == handle)
      {
         found = VOS_TRUE;
         break;
      }
   }
   mutex_unlock(&pAdapter->hddWmmStatus.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\n", __func__, smeStatus );
          VOS_ASSERT(0);
          return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
      }

      // we were successful, save the status
      pQosContext->lastStatus = status;
      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;
   pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up];
   pQosContext->pAdapter = pAdapter;
   pQosContext->qosFlowId = 0;
   pQosContext->magic = HDD_WMM_CTX_MAGIC;

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

   mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
   list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList);
   mutex_unlock(&pAdapter->hddWmmStatus.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\n", __func__, smeStatus );
      VOS_ASSERT(0);
      return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
   }
#endif

   // we were successful, save the status
   pQosContext->lastStatus = status;

   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

   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(&pAdapter->hddWmmStatus.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(&pAdapter->hddWmmStatus.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_CCX
      // 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\n", __func__, smeStatus );
      VOS_ASSERT(0);
      status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
   }

#endif
   pQosContext->lastStatus = status;
   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;

   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(&pAdapter->hddWmmStatus.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(&pAdapter->hddWmmStatus.wmmLock);
   return status;
}
