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

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

/**
 * DOC: HDD WMM
 *
 * 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 <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 <linux/ipv6.h>
#include <wlan_hdd_tx_rx.h>
#include <wlan_hdd_wmm.h>
#include <wlan_hdd_ether.h>
#include <wlan_hdd_hostapd.h>
#include <wlan_hdd_softap_tx_rx.h>
#include <cds_sched.h>
#include "sme_api.h"

#define WLAN_HDD_MAX_DSCP 0x3f

#define HDD_WMM_UP_TO_AC_MAP_SIZE 8

const uint8_t hdd_wmm_up_to_ac_map[] = {
	SME_AC_BE,
	SME_AC_BK,
	SME_AC_BK,
	SME_AC_BE,
	SME_AC_VI,
	SME_AC_VI,
	SME_AC_VO,
	SME_AC_VO
};

/**
 * enum hdd_wmm_linuxac: AC/Queue Index values for Linux Qdisc to
 * operate on different traffic.
 */
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
enum hdd_wmm_linuxac {
	HDD_LINUX_AC_VO = 0,
	HDD_LINUX_AC_VI = 1,
	HDD_LINUX_AC_BE = 2,
	HDD_LINUX_AC_BK = 3,
	HDD_LINUX_AC_HI_PRIO = 4,
};

void wlan_hdd_process_peer_unauthorised_pause(hdd_adapter_t *adapter)
{
	/* Enable HI_PRIO queue */
	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VO);
	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VI);
	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BE);
	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BK);
	netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_HI_PRIO);

}
#else
enum hdd_wmm_linuxac {
	HDD_LINUX_AC_VO = 0,
	HDD_LINUX_AC_VI = 1,
	HDD_LINUX_AC_BE = 2,
	HDD_LINUX_AC_BK = 3
};

void wlan_hdd_process_peer_unauthorised_pause(hdd_adapter_t *adapter)
{
	return;
}
#endif

/* Linux based UP -> AC Mapping */
const uint8_t hdd_linux_up_to_ac_map[HDD_WMM_UP_TO_AC_MAP_SIZE] = {
	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
};

static sme_tspec_dir_type get_convert_to_sme_dir(sme_QosWmmDirType dir)
{
	switch (dir) {
	case SME_QOS_WMM_TS_DIR_UPLINK:
		return SME_TX_DIR;
	case SME_QOS_WMM_TS_DIR_DOWNLINK:
		return SME_RX_DIR;
	case SME_QOS_WMM_TS_DIR_RESV:
	case SME_QOS_WMM_TS_DIR_BOTH:
	default:
		return SME_BI_DIR;
	}

	return SME_BI_DIR;
}


#ifndef WLAN_MDM_CODE_REDUCTION_OPT
/**
 * hdd_wmm_enable_tl_uapsd() - function which decides whether and
 * how to update UAPSD parameters in TL
 *
 * @pQosContext: [in] the pointer the QoS instance control block
 *
 * Return: None
 */
static void hdd_wmm_enable_tl_uapsd(struct hdd_wmm_qos_context *pQosContext)
{
	hdd_adapter_t *pAdapter = pQosContext->pAdapter;
	sme_ac_enum_type acType = pQosContext->acType;
	struct hdd_wmm_ac_status *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
	hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
	QDF_STATUS status;
	uint32_t service_interval;
	uint32_t suspension_interval;
	sme_QosWmmDirType direction;
	bool psb;

	/* The TSPEC must be valid */
	if (pAc->wmmAcTspecValid == false) {
		hdd_err("Invoked with invalid TSPEC");
		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 */
		hdd_debug("No service interval supplied");
		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)) {
		hdd_debug("No change in U-APSD parameters");
		return;
	}
	/* everything is in place to notify TL */
	status =
		sme_enable_uapsd_for_ac((WLAN_HDD_GET_CTX(pAdapter))->pcds_context,
					   (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,
					   get_convert_to_sme_dir(direction),
					   psb, pAdapter->sessionId,
					   pHddCtx->config->DelayedTriggerFrmInt);

	if (!QDF_IS_STATUS_SUCCESS(status)) {
		hdd_err("Failed to enable U-APSD for AC=%d", acType);
		return;
	}
	/* stash away the parameters that were used */
	pAc->wmmAcUapsdInfoValid = true;
	pAc->wmmAcUapsdServiceInterval = service_interval;
	pAc->wmmAcUapsdSuspensionInterval = suspension_interval;
	pAc->wmmAcUapsdDirection = direction;
	pAc->wmmAcIsUapsdEnabled = psb;

	hdd_debug("Enabled UAPSD in TL srv_int=%d susp_int=%d dir=%d AC=%d",
		   service_interval, suspension_interval, direction, acType);

}

/**
 * hdd_wmm_disable_tl_uapsd() - function which decides whether
 * to disable UAPSD parameters in TL
 *
 * @pQosContext: [in] the pointer the QoS instance control block
 *
 * Return: None
 */
static void hdd_wmm_disable_tl_uapsd(struct hdd_wmm_qos_context *pQosContext)
{
	hdd_adapter_t *pAdapter = pQosContext->pAdapter;
	sme_ac_enum_type acType = pQosContext->acType;
	struct hdd_wmm_ac_status *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
	QDF_STATUS status;

	/* have we previously enabled UAPSD? */
	if (pAc->wmmAcUapsdInfoValid == true) {
		status =
			sme_disable_uapsd_for_ac((WLAN_HDD_GET_CTX(pAdapter))->
						    pcds_context,
						    (WLAN_HDD_GET_STATION_CTX_PTR
							     (pAdapter))->conn_info.staId[0],
						    acType, pAdapter->sessionId);

		if (!QDF_IS_STATUS_SUCCESS(status)) {
			hdd_err("Failed to disable U-APSD for AC=%d", acType);
		} else {
			/* TL no longer has valid UAPSD info */
			pAc->wmmAcUapsdInfoValid = false;
			hdd_debug("Disabled UAPSD in TL for AC=%d", acType);
		}
	}
}

#endif

/**
 * hdd_wmm_free_context() - function which frees a QoS context
 *
 * @pQosContext: [in] the pointer the QoS instance control block
 *
 * Return: None
 */
static void hdd_wmm_free_context(struct hdd_wmm_qos_context *pQosContext)
{
	hdd_adapter_t *pAdapter;

	hdd_debug("Entered, context %p", 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 */
	qdf_mem_free(pQosContext);

}

#ifndef WLAN_MDM_CODE_REDUCTION_OPT
/**
 * hdd_wmm_notify_app() - function which notifies an application
 *			  of changes in state of it flow
 *
 * @pQosContext: [in] the pointer the QoS instance control block
 *
 * Return: None
 */
#define MAX_NOTIFY_LEN 50
static void hdd_wmm_notify_app(struct hdd_wmm_qos_context *pQosContext)
{
	hdd_adapter_t *pAdapter;
	union iwreq_data wrqu;
	char buf[MAX_NOTIFY_LEN + 1];

	hdd_debug("Entered, context %p", pQosContext);

	if (unlikely((NULL == pQosContext) ||
		     (HDD_WMM_CTX_MAGIC != pQosContext->magic))) {
		hdd_err("Invalid QoS Context");
		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 */
	hdd_debug("Sending [%s]", buf);
	wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
}

#ifdef FEATURE_WLAN_ESE
/**
 * hdd_wmm_inactivity_timer_cb() - inactivity timer callback function
 *
 * @user_data: opaque user data registered with the timer.  In the
 * case of this timer, the associated wmm QoS context is registered.
 *
 * This timer handler function is called for every inactivity interval
 * per AC. This function gets the current transmitted packets on the
 * given AC, and checks if there was any TX activity from the previous
 * interval. If there was no traffic then it would delete the TS that
 * was negotiated on that AC.
 *
 * Return: None
 */
static void hdd_wmm_inactivity_timer_cb(void *user_data)
{
	struct hdd_wmm_qos_context *pQosContext = user_data;
	hdd_adapter_t *pAdapter;
	struct hdd_wmm_ac_status *pAc;
	hdd_wlan_wmm_status_e status;
	QDF_STATUS qdf_status;
	uint32_t currentTrafficCnt = 0;
	sme_ac_enum_type acType = pQosContext->acType;

	pAdapter = pQosContext->pAdapter;
	if ((NULL == pAdapter) ||
	    (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
		hdd_err("invalid pAdapter: %p", pAdapter);
		return;
	}

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

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

	hdd_warn("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d",
		 acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt);
	if (pAc->wmmPrevTrafficCnt == currentTrafficCnt) {
		/* there is no traffic activity, delete the TSPEC for this AC */
		status = hdd_wmm_delts(pAdapter, pQosContext->handle);
		hdd_warn("Deleted TS on AC %d, due to inactivity with status = %d!!!",
			 acType, status);
	} else {
		pAc->wmmPrevTrafficCnt = currentTrafficCnt;
		if (pAc->wmmInactivityTimer.state == QDF_TIMER_STATE_STOPPED) {
			/* Restart the timer */
			qdf_status =
				qdf_mc_timer_start(&pAc->wmmInactivityTimer,
						   pAc->wmmInactivityTime);
			if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
				hdd_err("Restarting inactivity timer failed on AC %d",
					acType);
			}
		} else {
			QDF_ASSERT(qdf_mc_timer_get_current_state
					   (&pAc->wmmInactivityTimer) ==
				   QDF_TIMER_STATE_STOPPED);
		}
	}

	return;
}

/**
 * hdd_wmm_enable_inactivity_timer() -
 *	function to enable the traffic inactivity timer for the given AC
 *
 * @pQosContext: [in] pointer to pQosContext
 * @inactivityTime: [in] value of the inactivity interval in millisecs
 *
 * When a QoS-Tspec is successfully setup, if the inactivity interval
 * time specified in the AddTS parameters is non-zero, this function
 * is invoked to start a traffic inactivity timer for the given AC.
 *
 * Return: QDF_STATUS enumeration
 */
static QDF_STATUS
hdd_wmm_enable_inactivity_timer(struct hdd_wmm_qos_context *pQosContext,
				uint32_t inactivityTime)
{
	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
	hdd_adapter_t *pAdapter = pQosContext->pAdapter;
	sme_ac_enum_type acType = pQosContext->acType;
	struct hdd_wmm_ac_status *pAc;

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

	qdf_status = qdf_mc_timer_init(&pAc->wmmInactivityTimer,
				       QDF_TIMER_TYPE_SW,
				       hdd_wmm_inactivity_timer_cb,
				       pQosContext);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hdd_err("Initializing inactivity timer failed on AC %d",
			  acType);
		return qdf_status;
	}
	/* Start the inactivity timer */
	qdf_status = qdf_mc_timer_start(&pAc->wmmInactivityTimer,
					inactivityTime);
	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
		hdd_err("Starting inactivity timer failed on AC %d",
			  acType);
		qdf_status = qdf_mc_timer_destroy(&pAc->wmmInactivityTimer);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			hdd_err("Failed to destroy inactivity timer");
		}
		return qdf_status;
	}
	pAc->wmmInactivityTime = inactivityTime;
	/* Initialize the current tx traffic count on this AC */
	pAc->wmmPrevTrafficCnt =
		pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->
								    acType];
	pQosContext->is_inactivity_timer_running = true;
	return qdf_status;
}

/**
 * hdd_wmm_disable_inactivity_timer() -
 *	function to disable the traffic inactivity timer for the given AC.
 *
 * @pQosContext: [in] pointer to pQosContext
 *
 * This function is invoked to disable the traffic inactivity timer
 * for the given AC.  This is normally done when the TS is deleted.
 *
 * Return: QDF_STATUS enumeration
 */
static QDF_STATUS
hdd_wmm_disable_inactivity_timer(struct hdd_wmm_qos_context *pQosContext)
{
	hdd_adapter_t *pAdapter = pQosContext->pAdapter;
	sme_ac_enum_type acType = pQosContext->acType;
	struct hdd_wmm_ac_status *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;

	/* Clear the timer and the counter */
	pAc->wmmInactivityTime = 0;
	pAc->wmmPrevTrafficCnt = 0;

	if (pQosContext->is_inactivity_timer_running == true) {
		pQosContext->is_inactivity_timer_running = false;
		qdf_status = qdf_mc_timer_stop(&pAc->wmmInactivityTimer);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
			hdd_err("Failed to stop inactivity timer");
			return qdf_status;
		}
		qdf_status = qdf_mc_timer_destroy(&pAc->wmmInactivityTimer);
		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
			hdd_err("Failed to destroy inactivity timer:Timer started");
	}

	return qdf_status;
}
#endif /* FEATURE_WLAN_ESE */

/**
 * hdd_wmm_sme_callback() - callback for QoS notifications
 *
 * @hHal: [in] the HAL handle
 * @hddCtx : [in] the HDD specified handle
 * @pCurrentQosInfo : [in] the TSPEC params
 * @smeStatus : [in] the QoS related SME status
 * @qosFlowId: [in] the unique identifier of the flow
 *
 * This callback is 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).
 *
 * Return: QDF_STATUS enumeration
 */
static QDF_STATUS hdd_wmm_sme_callback(tHalHandle hHal,
				       void *hddCtx,
				       sme_QosWmmTspecInfo *pCurrentQosInfo,
				       sme_QosStatusType smeStatus,
				       uint32_t qosFlowId)
{
	struct hdd_wmm_qos_context *pQosContext = hddCtx;
	hdd_adapter_t *pAdapter;
	sme_ac_enum_type acType;
	struct hdd_wmm_ac_status *pAc;

	hdd_debug("Entered, context %p", pQosContext);

	if (unlikely((NULL == pQosContext) ||
		     (HDD_WMM_CTX_MAGIC != pQosContext->magic))) {
		hdd_err("Invalid QoS Context");
		return QDF_STATUS_E_FAILURE;
	}

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

	hdd_info("status %d flowid %d info %p",
		 smeStatus, qosFlowId, pCurrentQosInfo);

	switch (smeStatus) {

	case SME_QOS_STATUS_SETUP_SUCCESS_IND:
		hdd_info("Setup is complete");

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

		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {

			hdd_debug("Explicit Qos, notifying user space");

			/* 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) {
			hdd_debug("Inactivity timer value = %d for AC=%d",
				  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:
		hdd_debug("Setup is complete (U-APSD set previously)");

		pAc->wmmAcAccessAllowed = true;
		pAc->wmmAcAccessGranted = true;
		pAc->wmmAcAccessPending = false;

		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {

			hdd_debug("Explicit Qos, notifying user space");

			/* 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:
		hdd_err("Setup failed");
		/* QoS setup failed */

		pAc->wmmAcAccessPending = false;
		pAc->wmmAcAccessFailed = true;
		pAc->wmmAcAccessAllowed = false;
		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {

			hdd_debug("Explicit Qos, notifying user space");

			/* 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
		 * doesn'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 now
		 * it has no information for this flow.
		 */
		hdd_wmm_free_context(pQosContext);
		break;

	case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP:
		hdd_err("Setup Invalid Params, notify TL");
		/* QoS setup failed */
		pAc->wmmAcAccessAllowed = false;

		if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) {

			/* 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 = false;
			pAc->wmmAcAccessFailed = true;
			pAc->wmmAcAccessAllowed = true;

		} else {
			hdd_debug("Explicit Qos, notifying user space");

			/* 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:
		hdd_err("Setup failed, not a QoS AP");
		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
			hdd_debug("Explicit Qos, notifying user space");

			/* 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:
		hdd_debug("Setup pending");
		/* not a callback status -- ignore if we get it */
		break;

	case SME_QOS_STATUS_SETUP_MODIFIED_IND:
		hdd_debug("Setup modified");
		if (pCurrentQosInfo) {
			/* update the TSPEC */
			pAc->wmmAcTspecValid = true;
			memcpy(&pAc->wmmAcTspecInfo,
			       pCurrentQosInfo, sizeof(pAc->wmmAcTspecInfo));

			if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
				hdd_debug("Explicit Qos, notifying user space");

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

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

		} else {
			hdd_debug("Explicit Qos, notifying user space");

			/* 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:
		hdd_err("Setup successful but U-APSD failed");

		if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) {

			/* 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 = true;
			pAc->wmmAcAccessAllowed = true;
			pAc->wmmAcAccessFailed = false;
			pAc->wmmAcAccessPending = false;

		} else {
			hdd_debug("Explicit Qos, notifying user space");

			/* 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:
		hdd_debug("Release is complete");

		if (pCurrentQosInfo) {
			hdd_debug("flows still active");

			/* 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 {
			hdd_debug("last flow");

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

			/* DELTS is successful, do not allow */
			pAc->wmmAcAccessAllowed = false;

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

		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
			hdd_debug("Explicit Qos, notifying user space");

			/* 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:
		hdd_debug("Release failure");

		/* we don't need to update our state or TL since
		 * nothing has changed
		 */
		if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) {
			hdd_debug("Explicit Qos, notifying user space");

			/* 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:
		hdd_debug("QOS Lost indication received");

		/* current TSPEC is no longer valid */
		pAc->wmmAcTspecValid = false;
		/* AP has sent DELTS, do not allow */
		pAc->wmmAcAccessAllowed = 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 = false;
			pAc->wmmAcAccessFailed = false;
		} else {
			hdd_info("Explicit Qos, notifying user space");

			/* 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:
		hdd_info("Release pending");
		/* not a callback status -- ignore if we get it */
		break;

	case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP:
		hdd_err("Release Invalid Params");
		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:
		hdd_info("Modification is complete, notify TL");

		/* there will always be a TSPEC returned with this
		 * status, even if a TSPEC is not exchanged OTA
		 */
		if (pCurrentQosInfo) {
			pAc->wmmAcTspecValid = 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:
		hdd_info("modification pending");
		/* 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:
		hdd_err("Modify successful but U-APSD failed");

		/* 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:
		hdd_err("unexpected SME Status=%d", smeStatus);
		QDF_ASSERT(0);
	}

	/* if Tspec only allows downstream traffic then access is not
	 * allowed
	 */
	if (pAc->wmmAcTspecValid &&
	    (pAc->wmmAcTspecInfo.ts_info.direction ==
	     SME_QOS_WMM_TS_DIR_DOWNLINK)) {
		pAc->wmmAcAccessAllowed = false;
	}
	/* if we have valid Tpsec or if ACM bit is not set, allow access */
	if ((pAc->wmmAcTspecValid &&
	     (pAc->wmmAcTspecInfo.ts_info.direction !=
	      SME_QOS_WMM_TS_DIR_DOWNLINK)) || !pAc->wmmAcAccessRequired) {
		pAc->wmmAcAccessAllowed = true;
	}

	hdd_debug("complete, access for TL AC %d is%sallowed",
		   acType, pAc->wmmAcAccessAllowed ? " " : " not ");

	return QDF_STATUS_SUCCESS;
}
#endif

/**
 * hdd_wmmps_helper() - Function to set uapsd psb dynamically
 *
 * @pAdapter: [in] pointer to adapter structure
 * @ptr: [in] pointer to command buffer
 *
 * Return: Zero on success, appropriate error on failure.
 */
int hdd_wmmps_helper(hdd_adapter_t *pAdapter, uint8_t *ptr)
{
	if (NULL == pAdapter) {
		hdd_err("pAdapter is NULL");
		return -EINVAL;
	}
	if (NULL == ptr) {
		hdd_err("ptr is NULL");
		return -EINVAL;
	}
	/* convert ASCII to integer */
	pAdapter->configuredPsb = ptr[9] - '0';
	pAdapter->psbChanged = HDD_PSB_CHANGED;

	return 0;
}

/**
 * __hdd_wmm_do_implicit_qos() - Function which will attempt to setup
 *				QoS for any AC requiring it.
 * @work: [in] pointer to work structure.
 *
 * Return: none
 */
static void __hdd_wmm_do_implicit_qos(struct work_struct *work)
{
	struct hdd_wmm_qos_context *pQosContext =
		container_of(work, struct hdd_wmm_qos_context, wmmAcSetupImplicitQos);
	hdd_adapter_t *pAdapter;
	sme_ac_enum_type acType;
	struct hdd_wmm_ac_status *pAc;
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
	sme_QosStatusType smeStatus;
#endif
	sme_QosWmmTspecInfo qosInfo;
	hdd_context_t *hdd_ctx;

	hdd_debug("Entered, context %p", pQosContext);

	if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic)) {
		hdd_err("Invalid QoS Context");
		return;
	}

	pAdapter = pQosContext->pAdapter;

	hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
	if (wlan_hdd_validate_context(hdd_ctx))
		return;

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

	hdd_info("pAdapter %p acType %d", pAdapter, acType);

	if (!pAc->wmmAcAccessNeeded) {
		hdd_err("AC %d doesn't need service", acType);
		pQosContext->magic = 0;
		qdf_mem_free(pQosContext);
		return;
	}

	pAc->wmmAcAccessPending = true;
	pAc->wmmAcAccessNeeded = false;

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

	qosInfo.ts_info.psb = pAdapter->configuredPsb;

	switch (acType) {
	case SME_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))->config->
				 UapsdMask & SME_QOS_UAPSD_VO) ? 1 : 0;
		}
		qosInfo.ts_info.direction =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraDirAcVo;
		qosInfo.ts_info.tid = 255;
		qosInfo.mean_data_rate =
			(WLAN_HDD_GET_CTX(pAdapter))->config->
			InfraMeanDataRateAcVo;
		qosInfo.min_phy_rate =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraMinPhyRateAcVo;
		qosInfo.min_service_interval =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraUapsdVoSrvIntv;
		qosInfo.nominal_msdu_size =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraNomMsduSizeAcVo;
		qosInfo.surplus_bw_allowance =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraSbaAcVo;
		qosInfo.suspension_interval =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraUapsdVoSuspIntv;
		break;
	case SME_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))->config->
				 UapsdMask & SME_QOS_UAPSD_VI) ? 1 : 0;
		}
		qosInfo.ts_info.direction =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraDirAcVi;
		qosInfo.ts_info.tid = 255;
		qosInfo.mean_data_rate =
			(WLAN_HDD_GET_CTX(pAdapter))->config->
			InfraMeanDataRateAcVi;
		qosInfo.min_phy_rate =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraMinPhyRateAcVi;
		qosInfo.min_service_interval =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraUapsdViSrvIntv;
		qosInfo.nominal_msdu_size =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraNomMsduSizeAcVi;
		qosInfo.surplus_bw_allowance =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraSbaAcVi;
		qosInfo.suspension_interval =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraUapsdViSuspIntv;
		break;
	default:
	case SME_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))->config->
				 UapsdMask & SME_QOS_UAPSD_BE) ? 1 : 0;
		}
		qosInfo.ts_info.direction =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraDirAcBe;
		qosInfo.ts_info.tid = 255;
		qosInfo.mean_data_rate =
			(WLAN_HDD_GET_CTX(pAdapter))->config->
			InfraMeanDataRateAcBe;
		qosInfo.min_phy_rate =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraMinPhyRateAcBe;
		qosInfo.min_service_interval =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraUapsdBeSrvIntv;
		qosInfo.nominal_msdu_size =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraNomMsduSizeAcBe;
		qosInfo.surplus_bw_allowance =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraSbaAcBe;
		qosInfo.suspension_interval =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraUapsdBeSuspIntv;
		break;
	case SME_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))->config->
				 UapsdMask & SME_QOS_UAPSD_BK) ? 1 : 0;
		}
		qosInfo.ts_info.direction =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraDirAcBk;
		qosInfo.ts_info.tid = 255;
		qosInfo.mean_data_rate =
			(WLAN_HDD_GET_CTX(pAdapter))->config->
			InfraMeanDataRateAcBk;
		qosInfo.min_phy_rate =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraMinPhyRateAcBk;
		qosInfo.min_service_interval =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraUapsdBkSrvIntv;
		qosInfo.nominal_msdu_size =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraNomMsduSizeAcBk;
		qosInfo.surplus_bw_allowance =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraSbaAcBk;
		qosInfo.suspension_interval =
			(WLAN_HDD_GET_CTX(pAdapter))->config->InfraUapsdBkSuspIntv;
		break;
	}
#ifdef FEATURE_WLAN_ESE
	qosInfo.inactivity_interval =
		(WLAN_HDD_GET_CTX(pAdapter))->config->InfraInactivityInterval;
#endif
	qosInfo.ts_info.burst_size_defn =
		(WLAN_HDD_GET_CTX(pAdapter))->config->burstSizeDefinition;

	switch ((WLAN_HDD_GET_CTX(pAdapter))->config->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_qos_is_ts_info_ack_policy_valid
			    ((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_qos_setup_req(WLAN_HDD_GET_HAL_CTX(pAdapter),
				      pAdapter->sessionId,
				      &qosInfo,
				      hdd_wmm_sme_callback,
				      pQosContext,
				      qosInfo.ts_info.up,
				      &pQosContext->qosFlowId);

	hdd_debug("sme_qos_setup_req returned %d flowid %d",
		   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()
		 */
		hdd_info("Setup is pending, no further work");

		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
		 */
		hdd_info("Setup is complete, notify TL");

		pAc->wmmAcAccessAllowed = true;
		pAc->wmmAcAccessGranted = true;
		pAc->wmmAcAccessPending = false;

		break;

	default:
		hdd_err("unexpected SME Status=%d", smeStatus);
		QDF_ASSERT(0);
	}
#endif

}

/**
 * hdd_wmm_do_implicit_qos() - SSR wraper function for hdd_wmm_do_implicit_qos
 * @work: pointer to work_struct
 *
 * Return: none
 */
static void hdd_wmm_do_implicit_qos(struct work_struct *work)
{
	cds_ssr_protect(__func__);
	__hdd_wmm_do_implicit_qos(work);
	cds_ssr_unprotect(__func__);
}

/**
 * hdd_wmm_init() - initialize the WMM DSCP configuation
 * @pAdapter : [in]  pointer to Adapter context
 *
 * This function will initialize the WMM DSCP configuation of an
 * adapter to an initial state.  The configuration can later be
 * overwritten via application APIs or via QoS Map sent OTA.
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS hdd_wmm_init(hdd_adapter_t *pAdapter)
{
	sme_QosWmmUpType *hddWmmDscpToUpMap = pAdapter->hddWmmDscpToUpMap;
	uint8_t dscp;

	ENTER();
	/* DSCP to User Priority Lookup Table
	 * By default use the 3 Precedence bits of DSCP as the User Priority
	 */
	for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++) {
		hddWmmDscpToUpMap[dscp] = dscp >> 3;
	}

	/* Special case for Expedited Forwarding (DSCP 46) */
	hddWmmDscpToUpMap[46] = SME_QOS_WMM_UP_VO;

	return QDF_STATUS_SUCCESS;
}

/**
 * hdd_wmm_adapter_init() - initialize the WMM configuration of an adapter
 * @pAdapter: [in]  pointer to Adapter context
 *
 * This function will initialize the WMM configuation and status of an
 * adapter to an initial state.  The configuration can later be
 * overwritten via application APIs
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS hdd_wmm_adapter_init(hdd_adapter_t *pAdapter)
{
	struct hdd_wmm_ac_status *pAcStatus;
	sme_ac_enum_type acType;

	ENTER();

	pAdapter->hddWmmStatus.wmmQap = false;
	INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList);
	mutex_init(&pAdapter->hddWmmStatus.wmmLock);

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

	return QDF_STATUS_SUCCESS;
}

/**
 * hdd_wmm_adapter_clear() - Function which will clear the WMM status
 * for all the ACs
 *
 * @pAdapter: [in]  pointer to Adapter context
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS hdd_wmm_adapter_clear(hdd_adapter_t *pAdapter)
{
	struct hdd_wmm_ac_status *pAcStatus;
	sme_ac_enum_type acType;

	ENTER();
	for (acType = 0; acType < WLAN_MAX_AC; acType++) {
		pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType];
		pAcStatus->wmmAcAccessRequired = false;
		pAcStatus->wmmAcAccessNeeded = false;
		pAcStatus->wmmAcAccessPending = false;
		pAcStatus->wmmAcAccessFailed = false;
		pAcStatus->wmmAcAccessGranted = false;
		pAcStatus->wmmAcAccessAllowed = false;
		pAcStatus->wmmAcTspecValid = false;
		pAcStatus->wmmAcUapsdInfoValid = false;
	}
	return QDF_STATUS_SUCCESS;
}

/**
 * hdd_wmm_close() - WMM close function
 * @pAdapter: [in]  pointer to adapter context
 *
 * Function which will perform any necessary work to to clean up the
 * WMM functionality prior to the kernel module unload.
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS hdd_wmm_adapter_close(hdd_adapter_t *pAdapter)
{
	struct hdd_wmm_qos_context *pQosContext;

	ENTER();
	/* free any context records that we still have linked */
	while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList)) {
		pQosContext =
			list_first_entry(&pAdapter->hddWmmStatus.wmmContextList,
					 struct hdd_wmm_qos_context, node);
#ifdef FEATURE_WLAN_ESE
		hdd_wmm_disable_inactivity_timer(pQosContext);
#endif
		if (pQosContext->handle == HDD_WMM_HANDLE_IMPLICIT
			&& pQosContext->magic == HDD_WMM_CTX_MAGIC)
			cds_flush_work(&pQosContext->wmmAcSetupImplicitQos);

		hdd_wmm_free_context(pQosContext);
	}

	return QDF_STATUS_SUCCESS;
}

/**
 * hdd_wmm_classify_pkt() - Function which will classify an OS packet
 * into a WMM AC based on DSCP
 *
 * @adapter: adapter upon which the packet is being transmitted
 * @skb: pointer to network buffer
 * @user_pri: user priority of the OS packet
 * @is_eapol: eapol packet flag
 *
 * Return: None
 */
static
void hdd_wmm_classify_pkt(hdd_adapter_t *adapter,
			  struct sk_buff *skb,
			  sme_QosWmmUpType *user_pri,
			  bool *is_eapol)
{
	unsigned char dscp;
	unsigned char tos;
	union generic_ethhdr *eth_hdr;
	struct iphdr *ip_hdr;
	struct ipv6hdr *ipv6hdr;
	unsigned char *pkt;

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

#ifdef HDD_WMM_DEBUG
	ENTER();
#endif /* HDD_WMM_DEBUG */

	pkt = skb->data;
	eth_hdr = (union generic_ethhdr *)pkt;

#ifdef HDD_WMM_DEBUG
	hdd_debug("proto is 0x%04x", skb->protocol);
#endif /* HDD_WMM_DEBUG */

	if (eth_hdr->eth_II.h_proto == htons(ETH_P_IP)) {
		/* case 1: Ethernet II IP packet */
		ip_hdr = (struct iphdr *)&pkt[sizeof(eth_hdr->eth_II)];
		tos = ip_hdr->tos;
#ifdef HDD_WMM_DEBUG
		hdd_info("Ethernet II IP Packet, tos is %d", tos);
#endif /* HDD_WMM_DEBUG */

	} else if (eth_hdr->eth_II.h_proto == htons(ETH_P_IPV6)) {
		ipv6hdr = ipv6_hdr(skb);
		tos = ntohs(*(const __be16 *)ipv6hdr) >> 4;
#ifdef HDD_WMM_DEBUG
		hdd_info("Ethernet II IPv6 Packet, tos is %d", tos);
#endif /* HDD_WMM_DEBUG */
	} else if ((ntohs(eth_hdr->eth_II.h_proto) < WLAN_MIN_PROTO) &&
		  (eth_hdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) &&
		  (eth_hdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) &&
		  (eth_hdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) &&
		  (eth_hdr->eth_8023.h_proto == htons(ETH_P_IP))) {
		/* case 2: 802.3 LLC/SNAP IP packet */
		ip_hdr = (struct iphdr *)&pkt[sizeof(eth_hdr->eth_8023)];
		tos = ip_hdr->tos;
#ifdef HDD_WMM_DEBUG
		hdd_info("802.3 LLC/SNAP IP Packet, tos is %d", tos);
#endif /* HDD_WMM_DEBUG */
	} else if (eth_hdr->eth_II.h_proto == htons(ETH_P_8021Q)) {
		/* VLAN tagged */

		if (eth_hdr->eth_IIv.h_vlan_encapsulated_proto ==
			htons(ETH_P_IP)) {
			/* case 3: Ethernet II vlan-tagged IP packet */
			ip_hdr =
				(struct iphdr *)
				&pkt[sizeof(eth_hdr->eth_IIv)];
			tos = ip_hdr->tos;
#ifdef HDD_WMM_DEBUG
			hdd_info("Ethernet II VLAN tagged IP Packet, tos is %d",
				 tos);
#endif /* HDD_WMM_DEBUG */
		} else
		if ((ntohs(eth_hdr->eth_IIv.h_vlan_encapsulated_proto)
			< WLAN_MIN_PROTO)
		    && (eth_hdr->eth_8023v.h_snap.dsap ==
			WLAN_SNAP_DSAP)
			&& (eth_hdr->eth_8023v.h_snap.ssap ==
			WLAN_SNAP_SSAP)
			&& (eth_hdr->eth_8023v.h_snap.ctrl ==
			WLAN_SNAP_CTRL)
			&& (eth_hdr->eth_8023v.h_proto ==
			htons(ETH_P_IP))) {
			/* case 4: 802.3 LLC/SNAP vlan-tagged IP packet */
			ip_hdr =
				(struct iphdr *)
				&pkt[sizeof(eth_hdr->eth_8023v)];
			tos = ip_hdr->tos;
#ifdef HDD_WMM_DEBUG
			hdd_info("802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d",
				 tos);
#endif /* HDD_WMM_DEBUG */
		} else {
			/* default */
#ifdef HDD_WMM_DEBUG
			hdd_warn("VLAN tagged Unhandled Protocol, using default tos");
#endif /* HDD_WMM_DEBUG */
			tos = 0;
		}
	} else {
		/* default */
#ifdef HDD_WMM_DEBUG
		hdd_warn("Unhandled Protocol, using default tos");
#endif /* HDD_WMM_DEBUG */
		/* Give the highest priority to 802.1x packet */
		if (eth_hdr->eth_II.h_proto ==
			htons(HDD_ETHERTYPE_802_1_X)) {
			tos = 0xC0;
			*is_eapol = true;
		} else
			tos = 0;
	}

	dscp = (tos >> 2) & 0x3f;
	*user_pri = adapter->hddWmmDscpToUpMap[dscp];

#ifdef HDD_WMM_DEBUG
	hdd_debug("tos is %d, dscp is %d, up is %d", tos, dscp, *user_pri);
#endif /* HDD_WMM_DEBUG */

	return;
}

/**
 * __hdd_get_queue_index() - get queue index
 * @up: user priority
 *
 * Return: queue_index
 */
static uint16_t __hdd_get_queue_index(uint16_t up)
{
	if (qdf_unlikely(up >= ARRAY_SIZE(hdd_linux_up_to_ac_map)))
		return HDD_LINUX_AC_BE;
	return hdd_linux_up_to_ac_map[up];
}

#ifdef QCA_LL_TX_FLOW_CONTROL_V2
/**
 * hdd_get_queue_index() - get queue index
 * @up: user priority
 * @is_eapol: is_eapol flag
 *
 * Return: queue_index
 */
static
uint16_t hdd_get_queue_index(uint16_t up, bool is_eapol)
{
	if (qdf_unlikely(is_eapol == true))
		return HDD_LINUX_AC_HI_PRIO;
	return __hdd_get_queue_index(up);
}
#else
static
uint16_t hdd_get_queue_index(uint16_t up, bool is_eapol)
{
	return __hdd_get_queue_index(up);
}
#endif


/**
 * hdd_hostapd_select_queue() - Function which will classify the packet
 *       according to linux qdisc expectation.
 *
 * @dev: [in] pointer to net_device structure
 * @skb: [in] pointer to os packet
 *
 * Return: Qdisc queue index
 */
uint16_t hdd_hostapd_select_queue(struct net_device *dev, struct sk_buff *skb
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
				  , void *accel_priv
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
				  , select_queue_fallback_t fallback
#endif

)
{
	sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
	uint16_t queueIndex;
	hdd_adapter_t *adapter = (hdd_adapter_t *) netdev_priv(dev);
	hdd_context_t *hddctx = WLAN_HDD_GET_CTX(adapter);
	bool is_eapol = false;
	int status = 0;
	status = wlan_hdd_validate_context(hddctx);

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

	/* Get the user priority from IP header */
	hdd_wmm_classify_pkt(adapter, skb, &up, &is_eapol);
	skb->priority = up;
	queueIndex = hdd_get_queue_index(skb->priority, is_eapol);

	return queueIndex;
}

/**
 * hdd_wmm_select_queue() - Function which will classify the packet
 *       according to linux qdisc expectation.
 *
 * @dev: [in] pointer to net_device structure
 * @skb: [in] pointer to os packet
 *
 * Return: Qdisc queue index
 */
uint16_t hdd_wmm_select_queue(struct net_device *dev, struct sk_buff *skb)
{
	sme_QosWmmUpType up = SME_QOS_WMM_UP_BE;
	uint16_t queueIndex;
	hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
	bool is_eapol = false;
	hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
	int status;

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

	/* Get the user priority from IP header */
	hdd_wmm_classify_pkt(pAdapter, skb, &up, &is_eapol);
	skb->priority = up;
	queueIndex = hdd_get_queue_index(skb->priority, is_eapol);

	return queueIndex;
}

/**
 * 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
 *
 * @pAdapter: [in] pointer to adapter structure
 * @acType: [in] WMM AC type of OS packet
 *
 * Return: void
 */
void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter,
				     sme_ac_enum_type acType)
{
	/* Each bit in the LSB nibble indicates 1 AC.
	 * Clearing the particular bit in LSB nibble to indicate
	 * access required
	 */
	switch (acType) {
	case SME_AC_BK:
		/* clear first bit */
		pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK;
		break;
	case SME_AC_BE:
		/* clear second bit */
		pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK;
		break;
	case SME_AC_VI:
		/* clear third bit */
		pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK;
		break;
	case SME_AC_VO:
		/* clear fourth bit */
		pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK;
		break;
	default:
		hdd_err("Invalid AC Type");
		break;
	}
}

/**
 * hdd_wmm_acquire_access() - Function which will attempt to acquire
 * admittance for a WMM AC
 *
 * @pAdapter: [in]  pointer to adapter context
 * @acType: [in]  WMM AC type of OS packet
 * @pGranted: [out] pointer to bool flag when indicates if access
 *	      has been granted or not
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS hdd_wmm_acquire_access(hdd_adapter_t *pAdapter,
				  sme_ac_enum_type acType, bool *pGranted)
{
	struct hdd_wmm_qos_context *pQosContext;

	QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
		  "%s: Entered for AC %d", __func__, acType);

	if (!hdd_wmm_is_active(pAdapter) ||
	    !(WLAN_HDD_GET_CTX(pAdapter))->config->bImplicitQosEnabled ||
	    !pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessRequired) {
		/* either we don't want QoS or the AP doesn't support
		 * QoS or we don't want to do implicit QoS
		 */
		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
			  "%s: QoS not configured on both ends ", __func__);

		*pGranted =
			pAdapter->hddWmmStatus.wmmAcStatus[acType].
			wmmAcAccessAllowed;

		return QDF_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
		 */
		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
			  "%s: Implicit QoS for TL AC %d already scheduled",
			  __func__, acType);

		*pGranted = false;
		return QDF_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
		 */
		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
			  "%s: Implicit QoS for TL AC %d previously failed",
			  __func__, acType);

		if (!pAdapter->hddWmmStatus.wmmAcStatus[acType].
		    wmmAcAccessRequired) {
			pAdapter->hddWmmStatus.wmmAcStatus[acType].
			wmmAcAccessAllowed = true;
			*pGranted = true;
		} else {
			pAdapter->hddWmmStatus.wmmAcStatus[acType].
			wmmAcAccessAllowed = false;
			*pGranted = false;
		}

		return QDF_STATUS_SUCCESS;
	}
	/* we need to establish implicit QoS */
	QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
		  "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p",
		  __func__, acType, pAdapter);

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

	pQosContext = qdf_mem_malloc(sizeof(*pQosContext));
	if (NULL == pQosContext) {
		/* no memory for QoS context.  Nothing we can do but
		 * let data flow
		 */
		QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
			  "%s: Unable to allocate context", __func__);
		pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed =
			true;
		*pGranted = true;
		return QDF_STATUS_SUCCESS;
	}

	pQosContext->acType = acType;
	pQosContext->pAdapter = pAdapter;
	pQosContext->qosFlowId = 0;
	pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT;
	pQosContext->magic = HDD_WMM_CTX_MAGIC;
	pQosContext->is_inactivity_timer_running = false;

	INIT_WORK(&pQosContext->wmmAcSetupImplicitQos, hdd_wmm_do_implicit_qos);

	QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
		  "%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 = false;
	return QDF_STATUS_SUCCESS;
}

/**
 * hdd_wmm_assoc() - Function which will handle the housekeeping
 * required by WMM when association takes place
 *
 * @pAdapter: [in]  pointer to adapter context
 * @pRoamInfo: [in]  pointer to roam information
 * @eBssType: [in]  type of BSS
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS hdd_wmm_assoc(hdd_adapter_t *pAdapter,
			 tCsrRoamInfo *pRoamInfo, eCsrRoamBssType eBssType)
{
	uint8_t uapsdMask;
	QDF_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
	 */

	ENTER();

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

		hdd_debug("Reassoc so no work, Exiting");

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

	hdd_debug("U-APSD mask is 0x%02x", (int)uapsdMask);

	if (uapsdMask & HDD_AC_VO) {
		status =
			sme_enable_uapsd_for_ac((WLAN_HDD_GET_CTX(pAdapter))->
						   pcds_context,
						   (WLAN_HDD_GET_STATION_CTX_PTR
							    (pAdapter))->conn_info.staId[0],
						   SME_AC_VO, 7, 7,
						   pHddCtx->config->InfraUapsdVoSrvIntv,
						   pHddCtx->config->InfraUapsdVoSuspIntv,
						   SME_BI_DIR, 1,
						   pAdapter->sessionId,
						   pHddCtx->config->DelayedTriggerFrmInt);

		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
	}

	if (uapsdMask & HDD_AC_VI) {
		status =
			sme_enable_uapsd_for_ac((WLAN_HDD_GET_CTX(pAdapter))->
						   pcds_context,
						   (WLAN_HDD_GET_STATION_CTX_PTR
							    (pAdapter))->conn_info.staId[0],
						   SME_AC_VI, 5, 5,
						   pHddCtx->config->InfraUapsdViSrvIntv,
						   pHddCtx->config->InfraUapsdViSuspIntv,
						   SME_BI_DIR, 1,
						   pAdapter->sessionId,
						   pHddCtx->config->DelayedTriggerFrmInt);

		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
	}

	if (uapsdMask & HDD_AC_BK) {
		status =
			sme_enable_uapsd_for_ac((WLAN_HDD_GET_CTX(pAdapter))->
						   pcds_context,
						   (WLAN_HDD_GET_STATION_CTX_PTR
							    (pAdapter))->conn_info.staId[0],
						   SME_AC_BK, 2, 2,
						   pHddCtx->config->InfraUapsdBkSrvIntv,
						   pHddCtx->config->InfraUapsdBkSuspIntv,
						   SME_BI_DIR, 1,
						   pAdapter->sessionId,
						   pHddCtx->config->DelayedTriggerFrmInt);

		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
	}

	if (uapsdMask & HDD_AC_BE) {
		status =
			sme_enable_uapsd_for_ac((WLAN_HDD_GET_CTX(pAdapter))->
						   pcds_context,
						   (WLAN_HDD_GET_STATION_CTX_PTR
							    (pAdapter))->conn_info.staId[0],
						   SME_AC_BE, 3, 3,
						   pHddCtx->config->InfraUapsdBeSrvIntv,
						   pHddCtx->config->InfraUapsdBeSuspIntv,
						   SME_BI_DIR, 1,
						   pAdapter->sessionId,
						   pHddCtx->config->DelayedTriggerFrmInt);

		QDF_ASSERT(QDF_IS_STATUS_SUCCESS(status));
	}

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

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

	EXIT();

	return QDF_STATUS_SUCCESS;
}

static const uint8_t acm_mask_bit[WLAN_MAX_AC] = {
	0x4,                    /* SME_AC_BK */
	0x8,                    /* SME_AC_BE */
	0x2,                    /* SME_AC_VI */
	0x1                     /* SME_AC_VO */
};

/**
 * hdd_wmm_connect() - Function which will handle the housekeeping
 * required by WMM when a connection is established
 *
 * @pAdapter : [in]  pointer to adapter context
 * @pRoamInfo: [in]  pointer to roam information
 * @eBssType : [in]  type of BSS
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS hdd_wmm_connect(hdd_adapter_t *pAdapter,
			   tCsrRoamInfo *pRoamInfo, eCsrRoamBssType eBssType)
{
	int ac;
	bool qap;
	bool qosConnection;
	uint8_t acmMask;

	ENTER();

	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 = true;
		qosConnection = true;
		acmMask = 0x0;
	}

	hdd_debug("qap is %d, qosConnection is %d, acmMask is 0x%x",
		 qap, qosConnection, acmMask);

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

	for (ac = 0; ac < WLAN_MAX_AC; ac++) {
		if (qap && qosConnection && (acmMask & acm_mask_bit[ac])) {
			hdd_debug("ac %d on", ac);

			/* admission is required */
			pAdapter->hddWmmStatus.wmmAcStatus[ac].
			wmmAcAccessRequired = true;
			pAdapter->hddWmmStatus.wmmAcStatus[ac].
			wmmAcAccessAllowed = false;
			pAdapter->hddWmmStatus.wmmAcStatus[ac].
			wmmAcAccessGranted = false;
			/* after reassoc if we have valid tspec, allow access */
			if (pAdapter->hddWmmStatus.wmmAcStatus[ac].
			    wmmAcTspecValid
			    && (pAdapter->hddWmmStatus.wmmAcStatus[ac].
				wmmAcTspecInfo.ts_info.direction !=
				SME_QOS_WMM_TS_DIR_DOWNLINK)) {
				pAdapter->hddWmmStatus.wmmAcStatus[ac].
				wmmAcAccessAllowed = true;
			}
			if (!pRoamInfo->fReassocReq &&
			    !sme_neighbor_roam_is11r_assoc(
			    WLAN_HDD_GET_HAL_CTX(pAdapter),
			    pAdapter->sessionId) &&
			    !sme_roam_is_ese_assoc(pRoamInfo)
			   ) {
				pAdapter->hddWmmStatus.wmmAcStatus[ac].
					wmmAcTspecValid = false;
				pAdapter->hddWmmStatus.wmmAcStatus[ac].
					wmmAcAccessAllowed = false;
			}
		} else {
			hdd_debug("ac %d off", ac);
			/* admission is not required so access is allowed */
			pAdapter->hddWmmStatus.wmmAcStatus[ac].
			wmmAcAccessRequired = false;
			pAdapter->hddWmmStatus.wmmAcStatus[ac].
			wmmAcAccessAllowed = true;
		}

	}

	EXIT();

	return QDF_STATUS_SUCCESS;
}

/**
 * hdd_wmm_get_uapsd_mask() - Function which will calculate the
 * initial value of the UAPSD mask based upon the device configuration
 *
 * @pAdapter  : [in]  pointer to adapter context
 * @pUapsdMask: [out] pointer to where the UAPSD Mask is to be stored
 *
 * Return: QDF_STATUS enumeration
 */
QDF_STATUS hdd_wmm_get_uapsd_mask(hdd_adapter_t *pAdapter,
				  uint8_t *pUapsdMask)
{
	uint8_t uapsdMask;

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

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

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

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

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

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

/**
 * hdd_wmm_is_active() - Function which will determine if WMM is
 * active on the current connection
 *
 * @pAdapter: [in]  pointer to adapter context
 *
 * Return: true if WMM is enabled, false if WMM is not enabled
 */
bool hdd_wmm_is_active(hdd_adapter_t *pAdapter)
{
	if ((!pAdapter->hddWmmStatus.wmmQosConnection) ||
	    (!pAdapter->hddWmmStatus.wmmQap)) {
		return false;
	} else {
		return true;
	}
}

/**
 * hdd_wmm_addts() - Function which will add a traffic spec at the
 * request of an application
 *
 * @pAdapter  : [in]  pointer to adapter context
 * @handle    : [in]  handle to uniquely identify a TS
 * @pTspec    : [in]  pointer to the traffic spec
 *
 * Return: HDD_WLAN_WMM_STATUS_*
 */
hdd_wlan_wmm_status_e hdd_wmm_addts(hdd_adapter_t *pAdapter,
				    uint32_t handle,
				    sme_QosWmmTspecInfo *pTspec)
{
	struct hdd_wmm_qos_context *pQosContext;
	hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS;
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
	sme_QosStatusType smeStatus;
#endif
	bool found = false;

	hdd_debug("Entered with handle 0x%x", 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 = true;
			break;
		}
	}
	mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
	if (found) {
		/* record with that handle already exists */
		hdd_err("Record already exists with handle 0x%x", handle);

		/* Application is trying to modify some of the Tspec
		 * params. Allow it
		 */
		smeStatus = sme_qos_modify_req(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
			 */
			hdd_err("unexpected SME Status=%d",
				  smeStatus);
			QDF_ASSERT(0);
			return HDD_WLAN_WMM_STATUS_MODIFY_FAILED;
		}

		/* we were successful, save the status */
		mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
		if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
			pQosContext->lastStatus = status;
		mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);

		return status;
	}

	pQosContext = qdf_mem_malloc(sizeof(*pQosContext));
	if (NULL == pQosContext) {
		/* no memory for QoS context.  Nothing we can do */
		hdd_err("Unable to allocate QoS context");
		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 = hdd_wmm_up_to_ac_map[pTspec->ts_info.up];
	else {
		hdd_err("ts_info.up (%d) larger than max value (%d), use default acType (%d)",
			pTspec->ts_info.up,
			HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hdd_wmm_up_to_ac_map[0]);
		pQosContext->acType = hdd_wmm_up_to_ac_map[0];
	}
	pQosContext->pAdapter = pAdapter;
	pQosContext->qosFlowId = 0;
	pQosContext->magic = HDD_WMM_CTX_MAGIC;
	pQosContext->is_inactivity_timer_running = false;

	hdd_debug("Setting up QoS, context %p", 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_qos_setup_req(WLAN_HDD_GET_HAL_CTX(pAdapter),
				      pAdapter->sessionId,
				      pTspec,
				      hdd_wmm_sme_callback,
				      pQosContext,
				      pTspec->ts_info.up,
				      &pQosContext->qosFlowId);

	hdd_debug("sme_qos_setup_req returned %d flowid %d",
		   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);
		hdd_err("unexpected SME Status=%d", smeStatus);
		QDF_ASSERT(0);
		return HDD_WLAN_WMM_STATUS_SETUP_FAILED;
	}
#endif

	/* we were successful, save the status */
	mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
	if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
		pQosContext->lastStatus = status;
	mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);

	return status;
}

/**
 * hdd_wmm_delts() - Function which will delete a traffic spec at the
 * request of an application
 *
 * @pAdapter: [in]  pointer to adapter context
 * @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, uint32_t handle)
{
	struct hdd_wmm_qos_context *pQosContext;
	bool found = false;
	sme_ac_enum_type acType = 0;
	uint32_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

	hdd_debug("Entered with handle 0x%x", 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 = true;
			acType = pQosContext->acType;
			qosFlowId = pQosContext->qosFlowId;
			break;
		}
	}
	mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);

	if (false == found) {
		/* we didn't find the handle */
		hdd_info("handle 0x%x not found", handle);
		return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM;
	}

	hdd_info("found handle 0x%x, flow %d, AC %d, context %p",
		 handle, qosFlowId, acType, pQosContext);

#ifndef WLAN_MDM_CODE_REDUCTION_OPT
	smeStatus =
		sme_qos_release_req(WLAN_HDD_GET_HAL_CTX(pAdapter),
				    pAdapter->sessionId, qosFlowId);

	hdd_info("SME flow %d released, SME status %d", 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 =
			false;
		pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed =
			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;
		break;

	default:
		/* we didn't get back one of the
		 * SME_QOS_STATUS_RELEASE_* status codes
		 */
		hdd_err("unexpected SME Status=%d", smeStatus);
		QDF_ASSERT(0);
		status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED;
	}

#endif
	mutex_lock(&pAdapter->hddWmmStatus.wmmLock);
	if (pQosContext->magic == HDD_WMM_CTX_MAGIC)
		pQosContext->lastStatus = status;
	mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);

	return status;
}

/**
 * hdd_wmm_checkts() - Function which will return the status of a traffic
 * spec at the request of an application
 *
 * @pAdapter: [in]  pointer to adapter context
 * @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, uint32_t handle)
{
	struct hdd_wmm_qos_context *pQosContext;
	hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST;

	hdd_debug("Entered with handle 0x%x", 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) {
			hdd_info("found handle 0x%x, context %p",
				 handle, pQosContext);

			status = pQosContext->lastStatus;
			break;
		}
	}
	mutex_unlock(&pAdapter->hddWmmStatus.wmmLock);
	return status;
}
