/*
 * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
 *
 * 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 lim_process_action_frame.cc contains the code
 * for processing Action Frame.
 * Author:      Michael Lui
 * Date:        05/23/03
 * History:-
 * Date           Modified by    Modification Information
 * --------------------------------------------------------------------
 *
 */
#include "cds_api.h"
#include "wni_api.h"
#include "sir_api.h"
#include "ani_global.h"
#include "wni_cfg.h"
#include "sch_api.h"
#include "utils_api.h"
#include "lim_types.h"
#include "lim_utils.h"
#include "lim_assoc_utils.h"
#include "lim_security_utils.h"
#include "lim_ser_des_utils.h"
#include "lim_send_sme_rsp_messages.h"
#include "parser_api.h"
#include "lim_admit_control.h"
#include "wmm_apsd.h"
#include "lim_send_messages.h"
#include "rrm_api.h"
#include "lim_session_utils.h"
#include "wlan_policy_mgr_api.h"
#include "wma_types.h"
#include "wma.h"
#include <cdp_txrx_cmn.h>
#include <cdp_txrx_peer_ops.h>
#include "dot11f.h"

static last_processed_msg rrm_link_action_frm;

/**-----------------------------------------------------------------
   \fn     lim_stop_tx_and_switch_channel
   \brief  Stops the transmission if channel switch mode is silent and
   starts the channel switch timer.

   \param  mac
   \return NONE
   -----------------------------------------------------------------*/
void lim_stop_tx_and_switch_channel(struct mac_context *mac, uint8_t sessionId)
{
	struct pe_session *pe_session;
	QDF_STATUS status;

	pe_session = pe_find_session_by_session_id(mac, sessionId);

	if (!pe_session) {
		pe_err("Session: %d not active", sessionId);
		return;
	}

	if (pe_session->ftPEContext.pFTPreAuthReq) {
		pe_debug("Avoid Switch Channel req during pre auth");
		return;
	}

	mac->lim.lim_timers.gLimChannelSwitchTimer.sessionId = sessionId;
	status = policy_mgr_check_and_set_hw_mode_for_channel_switch(mac->psoc,
				pe_session->smeSessionId,
				pe_session->gLimChannelSwitch.sw_target_freq,
				POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA);

	/*
	 * If status is QDF_STATUS_E_FAILURE, mean HW mode change was required
	 * but driver failed to set HW mode so ignore CSA for the channel.
	 * If status is QDF_STATUS_SUCCESS mean HW mode change was required
	 * and was sucessfully changed so the channel switch will continue after
	 * HW mode change completion.
	 * If status is QDF_STATUS_E_NOSUPPORT or QDF_STATUS_E_ALREADY, mean
	 * DBS is not supported or required HW mode is already set, so
	 * So contunue with CSA from here.
	 */
	if (status == QDF_STATUS_E_FAILURE) {
		pe_err("Failed to set required HW mode for channel %d freq %d, ignore CSA",
		       pe_session->gLimChannelSwitch.primaryChannel,
		       pe_session->gLimChannelSwitch.sw_target_freq);
		return;
	}

	if (QDF_IS_STATUS_SUCCESS(status)) {
		pe_info("Channel change will continue after HW mode change");
		return;
	}
	/* change the channel immediately only if
	 * the channel switch count is 0
	 */
	if (pe_session->gLimChannelSwitch.switchCount == 0) {
		lim_process_channel_switch_timeout(mac);
		return;
	}
	MTRACE(mac_trace
		       (mac, TRACE_CODE_TIMER_ACTIVATE, sessionId,
		       eLIM_CHANNEL_SWITCH_TIMER));

	if (tx_timer_activate(&mac->lim.lim_timers.gLimChannelSwitchTimer) !=
	    TX_SUCCESS) {
		pe_err("tx_timer_activate failed");
	}
	return;
}

/**------------------------------------------------------------
   \fn     lim_start_channel_switch
   \brief  Switches the channel if switch count == 0, otherwise
   starts the timer for channel switch and stops BG scan
   and heartbeat timer tempororily.

   \param  mac
   \param  pe_session
   \return NONE
   ------------------------------------------------------------*/
QDF_STATUS lim_start_channel_switch(struct mac_context *mac,
				       struct pe_session *pe_session)
{
	pe_debug("Starting the channel switch");

	/*If channel switch is already running and it is on a different session, just return */
	/*This need to be removed for MCC */
	if ((lim_is_chan_switch_running(mac) &&
	     pe_session->gLimSpecMgmt.dot11hChanSwState !=
	     eLIM_11H_CHANSW_RUNNING) || pe_session->csaOffloadEnable) {
		pe_warn("Ignoring channel switch on session: %d",
			pe_session->peSessionId);
		return QDF_STATUS_SUCCESS;
	}

	/* Deactivate and change reconfigure the timeout value */
	/* lim_deactivate_and_change_timer(mac, eLIM_CHANNEL_SWITCH_TIMER); */
	MTRACE(mac_trace
		       (mac, TRACE_CODE_TIMER_DEACTIVATE, pe_session->peSessionId,
		       eLIM_CHANNEL_SWITCH_TIMER));
	if (tx_timer_deactivate(&mac->lim.lim_timers.gLimChannelSwitchTimer) !=
	    QDF_STATUS_SUCCESS) {
		pe_err("tx_timer_deactivate failed!");
		return QDF_STATUS_E_FAILURE;
	}

	if (tx_timer_change(&mac->lim.lim_timers.gLimChannelSwitchTimer,
			    pe_session->gLimChannelSwitch.switchTimeoutValue,
			    0) != TX_SUCCESS) {
		pe_err("tx_timer_change failed");
		return QDF_STATUS_E_FAILURE;
	}

	/* Prepare for 11h channel switch */
	lim_prepare_for11h_channel_switch(mac, pe_session);

	/** Dont add any more statements here as we posted finish scan request
	 * to HAL, wait till we get the response
	 */
	return QDF_STATUS_SUCCESS;
}

/**
 *  __lim_process_channel_switch_action_frame() - to process channel switch
 * @mac_ctx: Pointer to Global MAC structure
 * @rx_pkt_info: A pointer to packet info structure
 *
 * This routine will be called to process channel switch action frame
 *
 * Return: None
 */

static void __lim_process_channel_switch_action_frame(struct mac_context *mac_ctx,
			  uint8_t *rx_pkt_info, struct pe_session *session)
{
	tpSirMacMgmtHdr mac_hdr;
	uint8_t *body_ptr;
	tDot11fChannelSwitch *chnl_switch_frame;
	uint16_t bcn_period;
	uint32_t val, frame_len, status;
	tLimChannelSwitchInfo *ch_switch_params;
	struct sDot11fIEWiderBWChanSwitchAnn *wbw_chnlswitch_ie = NULL;
	struct sLimWiderBWChannelSwitch *lim_wbw_chnlswitch_info = NULL;
	struct sDot11fIEsec_chan_offset_ele *sec_chnl_offset = NULL;

	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);

	pe_debug("Received Channel switch action frame");
	if (!session->lim11hEnable)
		return;

	chnl_switch_frame = qdf_mem_malloc(sizeof(*chnl_switch_frame));
	if (!chnl_switch_frame)
		return;

	/* Unpack channel switch frame */
	status = dot11f_unpack_channel_switch(mac_ctx, body_ptr, frame_len,
			chnl_switch_frame, false);

	if (DOT11F_FAILED(status)) {
		pe_err("Failed to unpack and parse (0x%08x, %d bytes)",
			status, frame_len);
		qdf_mem_free(chnl_switch_frame);
		return;
	} else if (DOT11F_WARNED(status)) {
		pe_warn("warning: unpack 11h-CHANSW Req(0x%08x, %d bytes)",
			status, frame_len);
	}

	if (qdf_mem_cmp((uint8_t *) &session->bssId,
			(uint8_t *) &mac_hdr->sa, sizeof(tSirMacAddr))) {
		pe_warn("Rcvd action frame not from our BSS, dropping");
		qdf_mem_free(chnl_switch_frame);
		return;
	}
	/* copy the beacon interval from session */
	val = session->beaconParams.beaconInterval;
	ch_switch_params = &session->gLimChannelSwitch;
	bcn_period = (uint16_t)val;
	ch_switch_params->primaryChannel =
		chnl_switch_frame->ChanSwitchAnn.newChannel;
	ch_switch_params->sw_target_freq = wlan_reg_legacy_chan_to_freq
			(mac_ctx->pdev,
			chnl_switch_frame->ChanSwitchAnn.newChannel);
	ch_switch_params->switchCount =
		chnl_switch_frame->ChanSwitchAnn.switchCount;
	ch_switch_params->switchTimeoutValue =
		SYS_MS_TO_TICKS(bcn_period) *
		session->gLimChannelSwitch.switchCount;
	ch_switch_params->switchMode =
		chnl_switch_frame->ChanSwitchAnn.switchMode;

	/* Only primary channel switch element is present */
	ch_switch_params->state = eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
	ch_switch_params->ch_width = CH_WIDTH_20MHZ;

	if (chnl_switch_frame->WiderBWChanSwitchAnn.present
			&& session->vhtCapability) {
		wbw_chnlswitch_ie = &chnl_switch_frame->WiderBWChanSwitchAnn;
		session->gLimWiderBWChannelSwitch.newChanWidth =
			wbw_chnlswitch_ie->newChanWidth;
		session->gLimWiderBWChannelSwitch.newCenterChanFreq0 =
			wbw_chnlswitch_ie->newCenterChanFreq0;
		session->gLimWiderBWChannelSwitch.newCenterChanFreq1 =
			wbw_chnlswitch_ie->newCenterChanFreq1;
	}
	pe_debug("Rcv Chnl Swtch Frame: Timeout in %d ticks",
		session->gLimChannelSwitch.switchTimeoutValue);
	if (session->htSupportedChannelWidthSet) {
		sec_chnl_offset = &chnl_switch_frame->sec_chan_offset_ele;
		if (sec_chnl_offset->secondaryChannelOffset ==
				PHY_DOUBLE_CHANNEL_LOW_PRIMARY) {
			ch_switch_params->state =
				eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
			ch_switch_params->ch_width = CH_WIDTH_40MHZ;
			ch_switch_params->ch_center_freq_seg0 =
				ch_switch_params->primaryChannel + 2;
		} else if (sec_chnl_offset->secondaryChannelOffset ==
				PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) {
			ch_switch_params->state =
				eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
			ch_switch_params->ch_width = CH_WIDTH_40MHZ;
			ch_switch_params->ch_center_freq_seg0 =
				ch_switch_params->primaryChannel - 2;

		}
		if (session->vhtCapability &&
			chnl_switch_frame->WiderBWChanSwitchAnn.present) {
			wbw_chnlswitch_ie =
				&chnl_switch_frame->WiderBWChanSwitchAnn;
			ch_switch_params->ch_width =
				wbw_chnlswitch_ie->newChanWidth + 1;
			lim_wbw_chnlswitch_info =
				&session->gLimWiderBWChannelSwitch;
			ch_switch_params->ch_center_freq_seg0 =
				lim_wbw_chnlswitch_info->newCenterChanFreq0;
			ch_switch_params->ch_center_freq_seg1 =
				lim_wbw_chnlswitch_info->newCenterChanFreq1;

		}
	}

	if (CH_WIDTH_20MHZ == ch_switch_params->ch_width) {
		session->htSupportedChannelWidthSet =
			WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
		session->htRecommendedTxWidthSet =
			session->htSupportedChannelWidthSet;
	}

	if (QDF_STATUS_SUCCESS != lim_start_channel_switch(mac_ctx, session))
		pe_err("Could not start channel switch");

	qdf_mem_free(chnl_switch_frame);
	return;
}

/**
 * lim_process_ext_channel_switch_action_frame()- Process ECSA Action
 * Frames.
 * @mac_ctx: pointer to global mac structure
 * @rx_packet_info: rx packet meta information
 * @session_entry: Session entry.
 *
 * This function is called when ECSA action frame is received.
 *
 * Return: void
 */
static void
lim_process_ext_channel_switch_action_frame(struct mac_context *mac_ctx,
		uint8_t *rx_packet_info, struct pe_session *session_entry)
{

	tpSirMacMgmtHdr         hdr;
	uint8_t                 *body;
	tDot11fext_channel_switch_action_frame *ext_channel_switch_frame;
	uint32_t                frame_len;
	uint32_t                status;
	uint32_t                target_freq;

	hdr = WMA_GET_RX_MAC_HEADER(rx_packet_info);
	body = WMA_GET_RX_MPDU_DATA(rx_packet_info);
	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_packet_info);

	pe_debug("Received EXT Channel switch action frame");

	ext_channel_switch_frame =
		 qdf_mem_malloc(sizeof(*ext_channel_switch_frame));
	if (!ext_channel_switch_frame)
		return;

	/* Unpack channel switch frame */
	status = dot11f_unpack_ext_channel_switch_action_frame(mac_ctx,
			body, frame_len, ext_channel_switch_frame, false);

	if (DOT11F_FAILED(status)) {
		pe_err("Failed to parse CHANSW action frame (0x%08x, len %d):",
			status, frame_len);
		qdf_mem_free(ext_channel_switch_frame);
		return;
	} else if (DOT11F_WARNED(status)) {
		pe_debug("There were warnings while unpacking CHANSW Request (0x%08x, %d bytes):",
		  status, frame_len);
	}

	if (!wlan_reg_is_6ghz_supported(mac_ctx->pdev) &&
	    (wlan_reg_is_6ghz_op_class(mac_ctx->pdev,
				       ext_channel_switch_frame->
				       ext_chan_switch_ann_action.op_class))) {
		pe_err("channel belongs to 6 ghz spectrum, abort");
		qdf_mem_free(ext_channel_switch_frame);
		return;
	}

	target_freq =
		wlan_reg_chan_opclass_to_freq(ext_channel_switch_frame->ext_chan_switch_ann_action.new_channel,
					      ext_channel_switch_frame->ext_chan_switch_ann_action.op_class,
					      false);

	/* Free ext_channel_switch_frame here as its no longer needed */
	qdf_mem_free(ext_channel_switch_frame);
	/*
	 * Now, validate if channel change is required for the passed
	 * channel and if is valid in the current regulatory domain,
	 * and no concurrent session is running.
	 */
	if (!(session_entry->curr_op_freq != target_freq &&
	      ((wlan_reg_get_channel_state_for_freq(mac_ctx->pdev, target_freq) ==
		  CHANNEL_STATE_ENABLE) ||
	       (wlan_reg_get_channel_state_for_freq(mac_ctx->pdev, target_freq) ==
		  CHANNEL_STATE_DFS &&
		!policy_mgr_concurrent_open_sessions_running(
			mac_ctx->psoc))))) {
		pe_err("Channel freq: %d is not valid", target_freq);
		return;
	}

	if (session_entry->opmode == QDF_P2P_GO_MODE) {

		struct sir_sme_ext_cng_chan_ind *ext_cng_chan_ind;
		struct scheduler_msg mmh_msg = {0};

		ext_cng_chan_ind = qdf_mem_malloc(sizeof(*ext_cng_chan_ind));
		if (!ext_cng_chan_ind)
			return;

		ext_cng_chan_ind->session_id =
					session_entry->smeSessionId;

		/* No need to extract op mode as BW will be decided in
		 *  in SAP FSM depending on previous BW.
		 */
		ext_cng_chan_ind->new_chan_freq = target_freq;

		mmh_msg.type = eWNI_SME_EXT_CHANGE_CHANNEL_IND;
		mmh_msg.bodyptr = ext_cng_chan_ind;
		mmh_msg.bodyval = 0;
		lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg);
	}
	return;
} /*** end lim_process_ext_channel_switch_action_frame() ***/

/**
 * __lim_process_operating_mode_action_frame() - To process op mode frames
 * @mac_ctx: pointer to mac context
 * @rx_pkt_info: pointer to received packet info
 * @session: pointer to session
 *
 * This routine is called to process operating mode action frames
 *
 * Return: None
 */
static void __lim_process_operating_mode_action_frame(struct mac_context *mac_ctx,
			uint8_t *rx_pkt_info, struct pe_session *session)
{

	tpSirMacMgmtHdr mac_hdr;
	uint8_t *body_ptr;
	tDot11fOperatingMode *operating_mode_frm;
	uint32_t frame_len;
	uint32_t status;
	tpDphHashNode sta_ptr;
	uint16_t aid;
	uint8_t oper_mode;
	uint8_t cb_mode;
	uint8_t ch_bw = 0;
	uint8_t skip_opmode_update = false;

	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);

	pe_debug("Received Operating Mode action frame");

	/*
	 * Ignore opmode change during channel change The opmode will be updated
	 * with the beacons on new channel once the AP move to new channel.
	 */
	if (session->ch_switch_in_progress) {
		pe_debug("Ignore opmode change as channel switch is in progress");
		return;
	}
	operating_mode_frm = qdf_mem_malloc(sizeof(*operating_mode_frm));
	if (!operating_mode_frm)
		return;

	/* Unpack channel switch frame */
	status = dot11f_unpack_operating_mode(mac_ctx, body_ptr, frame_len,
			operating_mode_frm, false);
	if (DOT11F_FAILED(status)) {
		pe_err("Failed to unpack and parse (0x%08x, %d bytes)",
			status, frame_len);
		qdf_mem_free(operating_mode_frm);
		return;
	} else if (DOT11F_WARNED(status)) {
		pe_warn("warnings while unpacking (0x%08x, %d bytes):",
			status, frame_len);
	}
	sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
			&session->dph.dphHashTable);

	if (!sta_ptr) {
		pe_err("Station context not found");
		goto end;
	}

	if (wlan_reg_is_24ghz_ch_freq(session->curr_op_freq))
		cb_mode = mac_ctx->roam.configParam.channelBondingMode24GHz;
	else
		cb_mode = mac_ctx->roam.configParam.channelBondingMode5GHz;
	/*
	 * Do not update the channel bonding mode if channel bonding
	 * mode is disabled in INI.
	 */
	if (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == cb_mode) {
		pe_debug("channel bonding disabled");
		goto update_nss;
	}

	if (sta_ptr->htSupportedChannelWidthSet) {
		if (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ <
				sta_ptr->vhtSupportedChannelWidthSet)
			oper_mode = eHT_CHANNEL_WIDTH_160MHZ;
		else
			oper_mode = sta_ptr->vhtSupportedChannelWidthSet + 1;
	} else {
		oper_mode = eHT_CHANNEL_WIDTH_20MHZ;
	}

	if ((oper_mode == eHT_CHANNEL_WIDTH_80MHZ) &&
			(operating_mode_frm->OperatingMode.chanWidth >
				eHT_CHANNEL_WIDTH_80MHZ))
		skip_opmode_update = true;

	if (!skip_opmode_update && (oper_mode !=
		operating_mode_frm->OperatingMode.chanWidth)) {
		uint32_t fw_vht_ch_wd = wma_get_vht_ch_width();

		pe_debug("received Chanwidth: %d",
			 operating_mode_frm->OperatingMode.chanWidth);

		pe_debug(" MAC: %0x:%0x:%0x:%0x:%0x:%0x",
			mac_hdr->sa[0], mac_hdr->sa[1], mac_hdr->sa[2],
			mac_hdr->sa[3], mac_hdr->sa[4], mac_hdr->sa[5]);

		if (operating_mode_frm->OperatingMode.chanWidth >=
				eHT_CHANNEL_WIDTH_160MHZ
				&& (fw_vht_ch_wd >= eHT_CHANNEL_WIDTH_160MHZ)) {
			sta_ptr->vhtSupportedChannelWidthSet =
				WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ;
			sta_ptr->htSupportedChannelWidthSet =
				eHT_CHANNEL_WIDTH_40MHZ;
			ch_bw = eHT_CHANNEL_WIDTH_160MHZ;
		} else if (operating_mode_frm->OperatingMode.chanWidth >=
				eHT_CHANNEL_WIDTH_80MHZ) {
			sta_ptr->vhtSupportedChannelWidthSet =
				WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ;
			sta_ptr->htSupportedChannelWidthSet =
				eHT_CHANNEL_WIDTH_40MHZ;
			ch_bw = eHT_CHANNEL_WIDTH_80MHZ;
		} else if (operating_mode_frm->OperatingMode.chanWidth ==
				eHT_CHANNEL_WIDTH_40MHZ) {
			sta_ptr->vhtSupportedChannelWidthSet =
				WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
			sta_ptr->htSupportedChannelWidthSet =
				eHT_CHANNEL_WIDTH_40MHZ;
			ch_bw = eHT_CHANNEL_WIDTH_40MHZ;
		} else if (operating_mode_frm->OperatingMode.chanWidth ==
				eHT_CHANNEL_WIDTH_20MHZ) {
			sta_ptr->vhtSupportedChannelWidthSet =
				WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ;
			sta_ptr->htSupportedChannelWidthSet =
				eHT_CHANNEL_WIDTH_20MHZ;
			ch_bw = eHT_CHANNEL_WIDTH_20MHZ;
		}
		lim_check_vht_op_mode_change(mac_ctx, session, ch_bw,
					     mac_hdr->sa);
	}

update_nss:
	if (sta_ptr->vhtSupportedRxNss !=
			(operating_mode_frm->OperatingMode.rxNSS + 1)) {
		sta_ptr->vhtSupportedRxNss =
			operating_mode_frm->OperatingMode.rxNSS + 1;
		lim_set_nss_change(mac_ctx, session, sta_ptr->vhtSupportedRxNss,
			mac_hdr->sa);
	}

end:
	qdf_mem_free(operating_mode_frm);
	return;
}

/**
 * __lim_process_gid_management_action_frame() - To process group-id mgmt frames
 * @mac_ctx: Pointer to mac context
 * @rx_pkt_info: Rx packet info
 * @session: pointer to session
 *
 * This routine will be called to process group id management frames
 *
 * Return: none
 */
static void
__lim_process_gid_management_action_frame(struct mac_context *mac_ctx,
					  uint8_t *rx_pkt_info,
					  struct pe_session *session)
{
	uint8_t *body_ptr;
	uint16_t aid;
	uint32_t frame_len, status, membership = 0, usr_position = 0;
	uint32_t *mem_lower, *mem_upper, *mem_cur;
	tpSirMacMgmtHdr mac_hdr;
	tDot11fVHTGidManagementActionFrame *gid_mgmt_frame;
	tpDphHashNode sta_ptr;
	struct sDot11fFfVhtMembershipStatusArray *vht_member_status = NULL;
	struct sDot11fFfVhtUserPositionArray *vht_user_position = NULL;

	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);

	pe_debug("Received GID Management action frame");
	gid_mgmt_frame = qdf_mem_malloc(sizeof(*gid_mgmt_frame));
	if (!gid_mgmt_frame)
		return;

	/* Unpack Gid Management Action frame */
	status = dot11f_unpack_vht_gid_management_action_frame(mac_ctx,
			body_ptr, frame_len, gid_mgmt_frame, false);
	if (DOT11F_FAILED(status)) {
		pe_err("Fail to parse an Grp id frame (0x%08x, %d bytes):",
			status, frame_len);
		qdf_mem_free(gid_mgmt_frame);
		return;
	} else if (DOT11F_WARNED(status)) {
		pe_warn("warnings while unpacking Grp id frm (0x%08x, %d bytes):",
		 status, frame_len);
	}
	sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
			&session->dph.dphHashTable);
	if (!sta_ptr) {
		pe_err("Failed to get STA entry from hash table");
		goto out;
	}

	pe_debug(" MAC: %0x:%0x:%0x:%0x:%0x:%0x",
		mac_hdr->sa[0], mac_hdr->sa[1], mac_hdr->sa[2],
		mac_hdr->sa[3], mac_hdr->sa[4], mac_hdr->sa[5]);
	vht_member_status = &gid_mgmt_frame->VhtMembershipStatusArray;
	mem_lower =  (uint32_t *) vht_member_status->membershipStatusArray;
	mem_upper = (uint32_t *) &vht_member_status->membershipStatusArray[4];

	if (*mem_lower && *mem_upper) {
		pe_err("rcved frame with mult group ID set");
		goto out;
	}
	if (*mem_lower) {
		mem_cur = mem_lower;
	} else if (*mem_upper) {
		mem_cur = mem_upper;
		membership += sizeof(uint32_t);
	} else {
		pe_err("rcved Gid frame with no group ID set");
		goto out;
	}
	while (!(*mem_cur & 1)) {
		*mem_cur >>= 1;
		++membership;
	}
	if (*mem_cur) {
		pe_err("rcved frame with mult group ID set");
		goto out;
	}

	/*Just read the last two bits */
	vht_user_position = &gid_mgmt_frame->VhtUserPositionArray;
	usr_position = vht_user_position->userPositionArray[membership] & 0x3;
	lim_check_membership_user_position(mac_ctx, session, membership,
			usr_position);
out:
	qdf_mem_free(gid_mgmt_frame);
	return;
}

static void
__lim_process_add_ts_req(struct mac_context *mac, uint8_t *pRxPacketInfo,
			 struct pe_session *pe_session)
{
}

/**
 * __lim_process_add_ts_rsp() - To process add ts response frame
 * @mac_ctx: pointer to mac context
 * @rx_pkt_info: Received packet info
 * @session: pointer to session
 *
 * This routine is to handle add ts response frame
 *
 * Return: none
 */
static void __lim_process_add_ts_rsp(struct mac_context *mac_ctx,
		uint8_t *rx_pkt_info, struct pe_session *session)
{
	tSirAddtsRspInfo addts;
	QDF_STATUS retval;
	tpSirMacMgmtHdr mac_hdr;
	tpDphHashNode sta_ptr;
	uint16_t aid;
	uint32_t frameLen;
	uint8_t *body_ptr;
	tpLimTspecInfo tspec_info;
	uint8_t ac;
	tpDphHashNode sta_ds_ptr = NULL;
	uint8_t rsp_reqd = 1;
	uint32_t cfg_len;
	tSirMacAddr peer_macaddr;

	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
	frameLen = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);

	pe_warn("Recv AddTs Response");
	if (LIM_IS_AP_ROLE(session)) {
		pe_warn("AddTsRsp recvd at AP: ignoring");
		return;
	}

	sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
				&session->dph.dphHashTable);
	if (!sta_ptr) {
		pe_err("Station context not found - ignoring AddTsRsp");
		return;
	}

	retval = sir_convert_addts_rsp2_struct(mac_ctx, body_ptr,
			frameLen, &addts);
	if (retval != QDF_STATUS_SUCCESS) {
		pe_err("AddTsRsp parsing failed %d", retval);
		return;
	}
	/*
	 * don't have to check for qos/wme capabilities since we wouldn't have
	 * this flag set otherwise
	 */
	if (!mac_ctx->lim.gLimAddtsSent) {
		/* we never sent an addts request! */
		pe_warn("rx AddTsRsp but no req was ever sent-ignoring");
		return;
	}

	if (mac_ctx->lim.gLimAddtsReq.req.dialogToken != addts.dialogToken) {
		pe_warn("token mismatch got: %d exp: %d - ignoring",
			addts.dialogToken,
			mac_ctx->lim.gLimAddtsReq.req.dialogToken);
		return;
	}

	/*
	 * for successful addts response, try to add the classifier.
	 * if this fails for any reason, we should send a delts request to the
	 * ap for now, its ok not to send a delts since we are going to add
	 * support for multiple tclas soon and until then we won't send any
	 * addts requests with multiple tclas elements anyway.
	 * In case of addClassifier failure, we just let the addts timer run out
	 */
	if (((addts.tspec.tsinfo.traffic.accessPolicy ==
		SIR_MAC_ACCESSPOLICY_HCCA) ||
		(addts.tspec.tsinfo.traffic.accessPolicy ==
			SIR_MAC_ACCESSPOLICY_BOTH)) &&
		(addts.status == eSIR_MAC_SUCCESS_STATUS)) {
		/* add the classifier - this should always succeed */
		if (addts.numTclas > 1) {
			/* currently no support for multiple tclas elements */
			pe_err("Sta: %d Too many Tclas: %d 1 supported",
				aid, addts.numTclas);
			return;
		} else if (addts.numTclas == 1) {
			pe_debug("Response from STA: %d tsid: %d UP: %d OK!",
				aid, addts.tspec.tsinfo.traffic.tsid,
				addts.tspec.tsinfo.traffic.userPrio);
		}
	}
	pe_debug("Recv AddTsRsp: tsid: %d UP: %d status: %d",
		addts.tspec.tsinfo.traffic.tsid,
		addts.tspec.tsinfo.traffic.userPrio, addts.status);

	/* deactivate the response timer */
	lim_deactivate_and_change_timer(mac_ctx, eLIM_ADDTS_RSP_TIMER);

	if (addts.status != eSIR_MAC_SUCCESS_STATUS) {
		pe_debug("Recv AddTsRsp: tsid: %d UP: %d status: %d",
			addts.tspec.tsinfo.traffic.tsid,
			addts.tspec.tsinfo.traffic.userPrio, addts.status);
		lim_send_sme_addts_rsp(mac_ctx, true, addts.status, session,
				       addts.tspec, session->smeSessionId);

		/* clear the addts flag */
		mac_ctx->lim.gLimAddtsSent = false;

		return;
	}
#ifdef FEATURE_WLAN_ESE
	if (addts.tsmPresent) {
		pe_debug("TSM IE Present");
		session->eseContext.tsm.tid =
			addts.tspec.tsinfo.traffic.userPrio;
		qdf_mem_copy(&session->eseContext.tsm.tsmInfo,
			     &addts.tsmIE, sizeof(struct ese_tsm_ie));
		lim_send_sme_tsm_ie_ind(mac_ctx, session, addts.tsmIE.tsid,
					addts.tsmIE.state,
					addts.tsmIE.msmt_interval);
	}
#endif
	/*
	 * Since AddTS response was successful, check for the PSB flag
	 * and directional flag inside the TS Info field.
	 * An AC is trigger enabled AC if the PSB subfield is set to 1
	 * in the uplink direction.
	 * An AC is delivery enabled AC if the PSB subfield is set to 1
	 * in the downlink direction.
	 * An AC is trigger and delivery enabled AC if the PSB subfield
	 * is set to 1 in the bi-direction field.
	 */
	if (addts.tspec.tsinfo.traffic.psb == 1)
		lim_set_tspec_uapsd_mask_per_session(mac_ctx, session,
						     &addts.tspec.tsinfo,
						     SET_UAPSD_MASK);
	else
		lim_set_tspec_uapsd_mask_per_session(mac_ctx, session,
						     &addts.tspec.tsinfo,
						     CLEAR_UAPSD_MASK);

	/*
	 * ADDTS success, so AC is now admitted. We shall now use the default
	 * EDCA parameters as advertised by AP and send the updated EDCA params
	 * to HAL.
	 */
	ac = upToAc(addts.tspec.tsinfo.traffic.userPrio);
	if (addts.tspec.tsinfo.traffic.direction ==
	    SIR_MAC_DIRECTION_UPLINK) {
		session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |=
			(1 << ac);
	} else if (addts.tspec.tsinfo.traffic.direction ==
		   SIR_MAC_DIRECTION_DNLINK) {
		session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |=
			(1 << ac);
	} else if (addts.tspec.tsinfo.traffic.direction ==
		   SIR_MAC_DIRECTION_BIDIR) {
		session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |=
			(1 << ac);
		session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |=
			(1 << ac);
	}
	lim_set_active_edca_params(mac_ctx, session->gLimEdcaParams,
				   session);
	sta_ds_ptr = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
				   &session->dph.dphHashTable);
	if (sta_ds_ptr)
		lim_send_edca_params(mac_ctx, session->gLimEdcaParamsActive,
				     session->vdev_id, false);
	else
		pe_err("Self entry missing in Hash Table");
	sir_copy_mac_addr(peer_macaddr, session->bssId);
	/* if schedule is not present then add TSPEC with svcInterval as 0. */
	if (!addts.schedulePresent)
		addts.schedule.svcInterval = 0;
	if (QDF_STATUS_SUCCESS !=
	    lim_tspec_add(mac_ctx, sta_ptr->staAddr, sta_ptr->assocId,
		&addts.tspec, addts.schedule.svcInterval, &tspec_info)) {
		pe_err("Adding entry in lim Tspec Table failed");
		lim_send_delts_req_action_frame(mac_ctx, peer_macaddr, rsp_reqd,
						&addts.tspec.tsinfo,
						&addts.tspec, session);
		mac_ctx->lim.gLimAddtsSent = false;
		return;
		/*
		 * Error handling. send the response with error status.
		 * need to send DelTS to tear down the TSPEC status.
		 */
	}
	if ((addts.tspec.tsinfo.traffic.accessPolicy !=
			SIR_MAC_ACCESSPOLICY_EDCA) ||
		((upToAc(addts.tspec.tsinfo.traffic.userPrio) < QCA_WLAN_AC_ALL))) {
#ifdef FEATURE_WLAN_ESE
		retval = lim_send_hal_msg_add_ts(mac_ctx,
				tspec_info->idx,
				addts.tspec, session->peSessionId,
				addts.tsmIE.msmt_interval);
#else
		retval = lim_send_hal_msg_add_ts(mac_ctx,
				tspec_info->idx,
				addts.tspec, session->peSessionId);
#endif
		if (QDF_STATUS_SUCCESS != retval) {
			lim_admit_control_delete_ts(mac_ctx, sta_ptr->assocId,
				&addts.tspec.tsinfo, NULL, &tspec_info->idx);

			/* Send DELTS action frame to AP */
			cfg_len = sizeof(tSirMacAddr);
			lim_send_delts_req_action_frame(mac_ctx, peer_macaddr,
					rsp_reqd, &addts.tspec.tsinfo,
					&addts.tspec, session);
			lim_send_sme_addts_rsp(mac_ctx, true, retval,
					session, addts.tspec,
					session->smeSessionId);
			mac_ctx->lim.gLimAddtsSent = false;
			return;
		}
		pe_debug("AddTsRsp received successfully UP: %d TSID: %d",
			addts.tspec.tsinfo.traffic.userPrio,
			addts.tspec.tsinfo.traffic.tsid);
	} else {
		pe_debug("AddTsRsp received successfully UP: %d TSID: %d",
			addts.tspec.tsinfo.traffic.userPrio,
			addts.tspec.tsinfo.traffic.tsid);
		pe_debug("no ACM: Bypass sending WMA_ADD_TS_REQ to HAL");
		lim_send_sme_addts_rsp(mac_ctx, true, eSIR_SME_SUCCESS,
				       session, addts.tspec,
				       session->smeSessionId);
	}
	/* clear the addts flag */
	mac_ctx->lim.gLimAddtsSent = false;
	return;
}

/**
 * __lim_process_del_ts_req() - To process del ts response frame
 * @mac_ctx: pointer to mac context
 * @rx_pkt_info: Received packet info
 * @session: pointer to session
 *
 * This routine is to handle del ts request frame
 *
 * Return: none
 */
static void __lim_process_del_ts_req(struct mac_context *mac_ctx,
		uint8_t *rx_pkt_info, struct pe_session *session)
{
	QDF_STATUS retval;
	struct delts_req_info delts;
	tpSirMacMgmtHdr mac_hdr;
	tpDphHashNode sta_ptr;
	uint32_t frame_len;
	uint16_t aid;
	uint8_t *body_ptr;
	uint8_t ts_status;
	struct mac_ts_info *tsinfo;
	uint8_t tspec_idx;
	uint8_t ac;
	tpDphHashNode sta_ds_ptr = NULL;

	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);

	sta_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa, &aid,
				      &session->dph.dphHashTable);
	if (!sta_ptr) {
		pe_err("Station context not found - ignoring DelTs");
		return;
	}
	/* parse the delts request */
	retval = sir_convert_delts_req2_struct(mac_ctx, body_ptr,
			frame_len, &delts);
	if (retval != QDF_STATUS_SUCCESS) {
		pe_err("DelTs parsing failed %d", retval);
		return;
	}

	if (delts.wmeTspecPresent) {
		if ((!session->limWmeEnabled) || (!sta_ptr->wmeEnabled)) {
			pe_warn("Ignore delts req: wme not enabled");
			return;
		}
		pe_debug("WME Delts received");
	} else if ((session->limQosEnabled) && sta_ptr->lleEnabled) {
		pe_debug("11e QoS Delts received");
	} else if ((session->limWsmEnabled) && sta_ptr->wsmEnabled) {
		pe_debug("WSM Delts received");
	} else {
		pe_warn("Ignoring delts request: qos not enabled/capable");
		return;
	}

	tsinfo = delts.wmeTspecPresent ? &delts.tspec.tsinfo : &delts.tsinfo;

	/* if no Admit Control, ignore the request */
	if (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) {
		if (upToAc(tsinfo->traffic.userPrio) >= QCA_WLAN_AC_ALL) {
			pe_warn("DelTs with UP: %d has no AC - ignoring req",
				tsinfo->traffic.userPrio);
			return;
		}
	}

	if (!LIM_IS_AP_ROLE(session))
		lim_send_sme_delts_ind(mac_ctx, &delts, aid, session);

	/* try to delete the TS */
	if (QDF_STATUS_SUCCESS !=
	    lim_admit_control_delete_ts(mac_ctx, sta_ptr->assocId, tsinfo,
				&ts_status, &tspec_idx)) {
		pe_warn("Unable to Delete TS");
		return;
	} else if (!((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA)
			|| (tsinfo->traffic.accessPolicy ==
					SIR_MAC_ACCESSPOLICY_BOTH))){
		/* send message to HAL to delete TS */
		if (QDF_STATUS_SUCCESS != lim_send_hal_msg_del_ts(mac_ctx,
						tspec_idx,
						delts, session->peSessionId,
						session->bssId)) {
			pe_warn("DelTs with UP: %d failed ignoring request",
				tsinfo->traffic.userPrio);
			return;
		}
	}
	/*
	 * We successfully deleted the TSPEC. Update the dynamic UAPSD Mask.
	 * The AC for this TSPEC is no longer trigger enabled if this Tspec
	 * was set-up in uplink direction only.
	 * The AC for this TSPEC is no longer delivery enabled if this Tspec
	 * was set-up in downlink direction only.
	 * The AC for this TSPEC is no longer triiger enabled and delivery
	 * enabled if this Tspec was a bidirectional TSPEC.
	 */
	lim_set_tspec_uapsd_mask_per_session(mac_ctx, session,
					     tsinfo, CLEAR_UAPSD_MASK);
	/*
	 * We're deleting the TSPEC.
	 * The AC for this TSPEC is no longer admitted in uplink/downlink
	 * direction if this TSPEC was set-up in uplink/downlink direction only.
	 * The AC for this TSPEC is no longer admitted in both uplink and
	 * downlink directions if this TSPEC was a bi-directional TSPEC.
	 * If ACM is set for this AC and this AC is admitted only in downlink
	 * direction, PE needs to downgrade the EDCA parameter
	 * (for the AC for which TS is being deleted) to the
	 * next best AC for which ACM is not enabled, and send the
	 * updated values to HAL.
	 */
	ac = upToAc(tsinfo->traffic.userPrio);
	if (tsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK) {
		session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &=
			~(1 << ac);
	} else if (tsinfo->traffic.direction ==
		   SIR_MAC_DIRECTION_DNLINK) {
		session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &=
			~(1 << ac);
	} else if (tsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR) {
		session->gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &=
			~(1 << ac);
		session->gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &=
			~(1 << ac);
	}
	lim_set_active_edca_params(mac_ctx, session->gLimEdcaParams,
				   session);
	sta_ds_ptr = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
				   &session->dph.dphHashTable);
	if (sta_ds_ptr)
		lim_send_edca_params(mac_ctx, session->gLimEdcaParamsActive,
				     session->vdev_id, false);
	else
		pe_err("Self entry missing in Hash Table");

	pe_debug("DeleteTS succeeded");
#ifdef FEATURE_WLAN_ESE
	lim_send_sme_tsm_ie_ind(mac_ctx, session, 0, 0, 0);
#endif
}

/**
 * __lim_process_qos_map_configure_frame() - to process QoS map configure frame
 * @mac_ctx: pointer to mac context
 * @rx_pkt_info: pointer to received packet info
 * @session: pointer to session
 *
 * This routine will called to process qos map configure frame
 *
 * Return: none
 */
static void __lim_process_qos_map_configure_frame(struct mac_context *mac_ctx,
			uint8_t *rx_pkt_info, struct pe_session *session)
{
	tpSirMacMgmtHdr mac_hdr;
	uint32_t frame_len;
	uint8_t *body_ptr;
	QDF_STATUS retval;

	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
	retval = sir_convert_qos_map_configure_frame2_struct(mac_ctx,
				body_ptr, frame_len, &session->QosMapSet);
	if (retval != QDF_STATUS_SUCCESS) {
		pe_err("QosMapConfigure frame parsing fail %d", retval);
		return;
	}
	lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType,
				    (uint8_t *)mac_hdr,
				    frame_len + sizeof(tSirMacMgmtHdr), 0,
				    WMA_GET_RX_FREQ(rx_pkt_info), session,
				    WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
				    RXMGMT_FLAG_NONE);
}

#ifdef ANI_SUPPORT_11H
static void
__lim_process_basic_meas_req(struct mac_context *mac,
			     tpSirMacMeasReqActionFrame pMeasReqFrame,
			     tSirMacAddr peerMacAddr, struct pe_session *pe_session)
{
	if (lim_send_meas_report_frame(mac, pMeasReqFrame,
				       peerMacAddr, pe_session) !=
					 QDF_STATUS_SUCCESS) {
		pe_err("fail to send Basic Meas report");
		return;
	}
}
static void
__lim_process_cca_meas_req(struct mac_context *mac,
			   tpSirMacMeasReqActionFrame pMeasReqFrame,
			   tSirMacAddr peerMacAddr, struct pe_session *pe_session)
{
	if (lim_send_meas_report_frame(mac, pMeasReqFrame,
				       peerMacAddr, pe_session) !=
					 QDF_STATUS_SUCCESS) {
		pe_err("fail to send CCA Meas report");
		return;
	}
}
static void
__lim_process_rpi_meas_req(struct mac_context *mac,
			   tpSirMacMeasReqActionFrame pMeasReqFrame,
			   tSirMacAddr peerMacAddr, struct pe_session *pe_session)
{
	if (lim_send_meas_report_frame(mac, pMeasReqFrame,
				       peerMacAddr, pe_session) !=
					 QDF_STATUS_SUCCESS) {
		pe_err("fail to send RPI Meas report");
		return;
	}
}
static void
__lim_process_measurement_request_frame(struct mac_context *mac,
					uint8_t *pRxPacketInfo,
					struct pe_session *pe_session)
{
	tpSirMacMgmtHdr pHdr;
	uint8_t *pBody;
	tpSirMacMeasReqActionFrame pMeasReqFrame;
	uint32_t frameLen;

	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
	frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);

	pMeasReqFrame = qdf_mem_malloc(sizeof(tSirMacMeasReqActionFrame));
	if (!pMeasReqFrame)
		return;

	if (sir_convert_meas_req_frame2_struct(mac, pBody, pMeasReqFrame, frameLen)
	    != QDF_STATUS_SUCCESS) {
		pe_warn("Rcv invalid Measurement Request Action Frame");
		return;
	}
	switch (pMeasReqFrame->measReqIE.measType) {
	case SIR_MAC_BASIC_MEASUREMENT_TYPE:
		__lim_process_basic_meas_req(mac, pMeasReqFrame, pHdr->sa,
					     pe_session);
		break;
	case SIR_MAC_CCA_MEASUREMENT_TYPE:
		__lim_process_cca_meas_req(mac, pMeasReqFrame, pHdr->sa,
					   pe_session);
		break;
	case SIR_MAC_RPI_MEASUREMENT_TYPE:
		__lim_process_rpi_meas_req(mac, pMeasReqFrame, pHdr->sa,
					   pe_session);
		break;
	default:
		pe_warn("Unknown Measurement Type: %d",
			       pMeasReqFrame->measReqIE.measType);
		break;
	}
} /*** end limProcessMeasurementRequestFrame ***/
static void
__lim_process_tpc_request_frame(struct mac_context *mac, uint8_t *pRxPacketInfo,
				struct pe_session *pe_session)
{
	tpSirMacMgmtHdr pHdr;
	uint8_t *pBody;
	tpSirMacTpcReqActionFrame pTpcReqFrame;
	uint32_t frameLen;

	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
	frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
	pe_debug("****LIM: Processing TPC Request from peer ****");

	pTpcReqFrame = qdf_mem_malloc(sizeof(tSirMacTpcReqActionFrame));
	if (!pTpcReqFrame)
		return;

	if (sir_convert_tpc_req_frame2_struct(mac, pBody, pTpcReqFrame, frameLen) !=
	    QDF_STATUS_SUCCESS) {
		pe_warn("Rcv invalid TPC Req Action Frame");
		return;
	}
	if (lim_send_tpc_report_frame(mac,
				      pTpcReqFrame,
				      pHdr->sa, pe_session) != QDF_STATUS_SUCCESS) {
		pe_err("fail to send TPC Report Frame");
		return;
	}
}
#endif

static void
__lim_process_sm_power_save_update(struct mac_context *mac, uint8_t *pRxPacketInfo,
				   struct pe_session *pe_session)
{

	tpSirMacMgmtHdr pHdr;
	tDot11fSMPowerSave frmSMPower;
	tSirMacHTMIMOPowerSaveState state;
	tpDphHashNode pSta;
	uint16_t aid;
	uint32_t frameLen, nStatus;
	uint8_t *pBody;

	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
	frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);

	pSta =
		dph_lookup_hash_entry(mac, pHdr->sa, &aid,
				      &pe_session->dph.dphHashTable);
	if (!pSta) {
		pe_err("STA context not found - ignoring UpdateSM PSave Mode from");
		lim_print_mac_addr(mac, pHdr->sa, LOGE);
		return;
	}

	/**Unpack the received frame */
	nStatus = dot11f_unpack_sm_power_save(mac, pBody, frameLen,
					      &frmSMPower, false);

	if (DOT11F_FAILED(nStatus)) {
		pe_err("Failed to unpack and parse a Update SM Power (0x%08x, %d bytes):",
			nStatus, frameLen);
		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
				   pBody, frameLen);
		return;
	} else if (DOT11F_WARNED(nStatus)) {
		pe_debug("There were warnings while unpacking a SMPower Save update (0x%08x, %d bytes):",
			nStatus, frameLen);
	}

	pe_debug("Received SM Power save Mode update Frame with PS_Enable: %d"
		   "PS Mode: %d", frmSMPower.SMPowerModeSet.PowerSave_En,
		frmSMPower.SMPowerModeSet.Mode);

	/** Update in the DPH Table about the Update in the SM Power Save mode*/
	if (frmSMPower.SMPowerModeSet.PowerSave_En
	    && frmSMPower.SMPowerModeSet.Mode)
		state = eSIR_HT_MIMO_PS_DYNAMIC;
	else if ((frmSMPower.SMPowerModeSet.PowerSave_En)
		 && (frmSMPower.SMPowerModeSet.Mode == 0))
		state = eSIR_HT_MIMO_PS_STATIC;
	else if ((frmSMPower.SMPowerModeSet.PowerSave_En == 0)
		 && (frmSMPower.SMPowerModeSet.Mode == 0))
		state = eSIR_HT_MIMO_PS_NO_LIMIT;
	else {
		pe_warn("Received SM Power save Mode update Frame with invalid mode");
		return;
	}

	if (state == pSta->htMIMOPSState) {
		pe_err("The PEER is already set in the same mode");
		return;
	}

	/** Update in the HAL Station Table for the Update of the Protection Mode */
	pSta->htMIMOPSState = state;
	lim_post_sm_state_update(mac, pSta->htMIMOPSState,
				 pSta->staAddr, pe_session->smeSessionId);
}


static void
__lim_process_radio_measure_request(struct mac_context *mac, uint8_t *pRxPacketInfo,
				    struct pe_session *pe_session)
{
	tpSirMacMgmtHdr pHdr;
	tDot11fRadioMeasurementRequest *frm;
	uint32_t frameLen, nStatus;
	uint8_t *pBody;
	uint16_t curr_seq_num;

	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
	frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);

	if (!pe_session) {
		return;
	}

	curr_seq_num = ((pHdr->seqControl.seqNumHi <<
			 HIGH_SEQ_NUM_OFFSET) |
			pHdr->seqControl.seqNumLo);
	if (curr_seq_num == mac->rrm.rrmPEContext.prev_rrm_report_seq_num &&
	    mac->rrm.rrmPEContext.pCurrentReq) {
		pe_err("rrm report req frame, seq num: %d is already in progress, drop it",
			curr_seq_num);
		return;
	}
	/* Save seq no of currently processing rrm report req frame */
	mac->rrm.rrmPEContext.prev_rrm_report_seq_num = curr_seq_num;
	lim_send_sme_mgmt_frame_ind(mac, pHdr->fc.subType, (uint8_t *)pHdr,
				    frameLen + sizeof(tSirMacMgmtHdr), 0,
				    WMA_GET_RX_FREQ(pRxPacketInfo), pe_session,
				    WMA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo),
				    RXMGMT_FLAG_NONE);

	frm = qdf_mem_malloc(sizeof(*frm));
	if (!frm)
		return;

	/**Unpack the received frame */
	nStatus = dot11f_unpack_radio_measurement_request(mac, pBody,
							  frameLen, frm, false);

	if (DOT11F_FAILED(nStatus)) {
		pe_err("Failed to unpack and parse a Radio Measure request (0x%08x, %d bytes):",
			nStatus, frameLen);
		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
				   pBody, frameLen);
		goto err;
	} else if (DOT11F_WARNED(nStatus)) {
		pe_debug("Warnings while unpacking a Radio Measure request (0x%08x, %d bytes):",
			 nStatus, frameLen);
	}
	/* Call rrm function to handle the request. */

	rrm_process_radio_measurement_request(mac, pHdr->sa, frm,
					      pe_session, BCN_RPT_SUCCESS);
err:
	qdf_mem_free(frm);
}

static QDF_STATUS
__lim_process_link_measurement_req(struct mac_context *mac, uint8_t *pRxPacketInfo,
				   struct pe_session *pe_session)
{
	tpSirMacMgmtHdr pHdr;
	tDot11fLinkMeasurementRequest frm;
	uint32_t frameLen, nStatus;
	uint8_t *pBody;

	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
	frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);

	if (!pe_session) {
		return QDF_STATUS_E_FAILURE;
	}

	/**Unpack the received frame */
	nStatus =
		dot11f_unpack_link_measurement_request(mac, pBody, frameLen,
						       &frm, false);

	if (DOT11F_FAILED(nStatus)) {
		pe_err("Failed to unpack and parse a Link Measure request (0x%08x, %d bytes):",
			nStatus, frameLen);
		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
				   pBody, frameLen);
		return QDF_STATUS_E_FAILURE;
	} else if (DOT11F_WARNED(nStatus)) {
		pe_debug("There were warnings while unpacking a Link Measure request (0x%08x, %d bytes):",
			nStatus, frameLen);
	}
	/* Call rrm function to handle the request. */

	return rrm_process_link_measurement_request(mac, pRxPacketInfo, &frm,
					     pe_session);

}

static void
__lim_process_neighbor_report(struct mac_context *mac, uint8_t *pRxPacketInfo,
			      struct pe_session *pe_session)
{
	tpSirMacMgmtHdr pHdr;
	tDot11fNeighborReportResponse *pFrm;
	uint32_t frameLen, nStatus;
	uint8_t *pBody;

	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
	frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);

	pFrm = qdf_mem_malloc(sizeof(tDot11fNeighborReportResponse));
	if (!pFrm)
		return;

	if (!pe_session) {
		qdf_mem_free(pFrm);
		return;
	}

	/**Unpack the received frame */
	nStatus =
		dot11f_unpack_neighbor_report_response(mac, pBody,
						       frameLen, pFrm, false);

	if (DOT11F_FAILED(nStatus)) {
		pe_err("Failed to unpack and parse a Neighbor report response (0x%08x, %d bytes):",
			nStatus, frameLen);
		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
				   pBody, frameLen);
		qdf_mem_free(pFrm);
		return;
	} else if (DOT11F_WARNED(nStatus)) {
		pe_debug("There were warnings while unpacking a Neighbor report response (0x%08x, %d bytes):",
			nStatus, frameLen);
	}

	/* Call rrm function to handle the request. */
	rrm_process_neighbor_report_response(mac, pFrm, pe_session);

	qdf_mem_free(pFrm);
}


#ifdef WLAN_FEATURE_11W
/**
 * limProcessSAQueryRequestActionFrame
 *
 ***FUNCTION:
 * This function is called by lim_process_action_frame() upon
 * SA query request Action frame reception.
 *
 ***LOGIC:
 *
 ***ASSUMPTIONS:
 *
 ***NOTE:
 *
 * @param  mac - Pointer to Global MAC structure
 * @param  *pRxPacketInfo - Handle to the Rx packet info
 * @param  pe_session - PE session entry
 *
 * @return None
 */
static void __lim_process_sa_query_request_action_frame(struct mac_context *mac,
							uint8_t *pRxPacketInfo,
							struct pe_session *pe_session)
{
	tpSirMacMgmtHdr pHdr;
	uint8_t *pBody;
	uint32_t frame_len;
	uint8_t transId[2];

	/* Prima  --- Below Macro not available in prima
	   pHdr = SIR_MAC_BD_TO_MPDUHEADER(pBd);
	   pBody = SIR_MAC_BD_TO_MPDUDATA(pBd); */

	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
	frame_len = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);

	if (frame_len < sizeof(struct sDot11fSaQueryReq)) {
		pe_err("Invalid frame length");
		return;
	}
	/* If this is an unprotected SA Query Request, then ignore it. */
	if (pHdr->fc.wep == 0)
		return;

	/* 11w offload is enabled then firmware should not fwd this frame */
	if (LIM_IS_STA_ROLE(pe_session) && mac->pmf_offload) {
		pe_err("11w offload enabled, SA Query req isn't expected");
		return;
	}

	/*Extract 11w trsansId from SA query request action frame
	   In SA query response action frame we will send same transId
	   In SA query request action frame:
	   Category       : 1 byte
	   Action         : 1 byte
	   Transaction ID : 2 bytes */
	qdf_mem_copy(&transId[0], &pBody[2], 2);

	/* Send 11w SA query response action frame */
	if (lim_send_sa_query_response_frame(mac,
					     transId,
					     pHdr->sa,
					     pe_session) != QDF_STATUS_SUCCESS) {
		pe_err("fail to send SA query response action frame");
		return;
	}
}

/**
 * __lim_process_sa_query_response_action_frame
 *
 ***FUNCTION:
 * This function is called by lim_process_action_frame() upon
 * SA query response Action frame reception.
 *
 ***LOGIC:
 *
 ***ASSUMPTIONS:
 *
 ***NOTE:
 *
 * @param  mac - Pointer to Global MAC structure
 * @param  *pRxPacketInfo - Handle to the Rx packet info
 * @param  pe_session - PE session entry
 * @return None
 */
static void __lim_process_sa_query_response_action_frame(struct mac_context *mac,
							 uint8_t *pRxPacketInfo,
							 struct pe_session *pe_session)
{
	tpSirMacMgmtHdr pHdr;
	uint32_t frame_len;
	uint8_t *pBody;
	tpDphHashNode pSta;
	uint16_t aid;
	uint16_t transId;
	uint8_t retryNum;

	pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
	frame_len = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
	pe_debug("SA Query Response received");

	if (frame_len < sizeof(struct sDot11fSaQueryRsp)) {
		pe_err("Invalid frame length");
		return;
	}
	/* When a station, supplicant handles SA Query Response.
	 * Forward to SME to HDD to wpa_supplicant.
	 */
	if (LIM_IS_STA_ROLE(pe_session)) {
		lim_send_sme_mgmt_frame_ind(mac, pHdr->fc.subType,
					    (uint8_t *)pHdr,
					    frame_len + sizeof(tSirMacMgmtHdr),
					    0,
					    WMA_GET_RX_FREQ(pRxPacketInfo),
					    pe_session,
					    WMA_GET_RX_RSSI_NORMALIZED(
					    pRxPacketInfo), RXMGMT_FLAG_NONE);
		return;
	}

	/* If this is an unprotected SA Query Response, then ignore it. */
	if (pHdr->fc.wep == 0)
		return;

	pSta =
		dph_lookup_hash_entry(mac, pHdr->sa, &aid,
				      &pe_session->dph.dphHashTable);
	if (!pSta)
		return;

	pe_debug("SA Query Response source addr:  %0x:%0x:%0x:%0x:%0x:%0x",
		pHdr->sa[0], pHdr->sa[1], pHdr->sa[2], pHdr->sa[3],
		pHdr->sa[4], pHdr->sa[5]);
	pe_debug("SA Query state for station: %d", pSta->pmfSaQueryState);

	if (DPH_SA_QUERY_IN_PROGRESS != pSta->pmfSaQueryState)
		return;

	/* Extract 11w trsansId from SA query response action frame
	   In SA query response action frame:
	   Category       : 1 byte
	   Action         : 1 byte
	   Transaction ID : 2 bytes */
	qdf_mem_copy(&transId, &pBody[2], 2);

	/* If SA Query is in progress with the station and the station
	   responds then the association request that triggered the SA
	   query is from a rogue station, just go back to initial state. */
	for (retryNum = 0; retryNum <= pSta->pmfSaQueryRetryCount; retryNum++)
		if (transId == pSta->pmfSaQueryStartTransId + retryNum) {
			pe_debug("Found matching SA Query Request - transaction ID: %d",
				transId);
			tx_timer_deactivate(&pSta->pmfSaQueryTimer);
			pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
			break;
		}
}
#endif

#ifdef WLAN_FEATURE_11W
/**
 * lim_drop_unprotected_action_frame
 *
 ***FUNCTION:
 * This function checks if an Action frame should be dropped since it is
 * a Robust Management Frame, it is unprotected, and it is received on a
 * connection where PMF is enabled.
 *
 ***LOGIC:
 *
 ***ASSUMPTIONS:
 *
 ***NOTE:
 *
 * @param  mac - Global MAC structure
 * @param  pe_session - PE session entry
 * @param  pHdr - Frame header
 * @param  category - Action frame category
 * @return true if frame should be dropped
 */

static bool
lim_drop_unprotected_action_frame(struct mac_context *mac, struct pe_session *pe_session,
				  tpSirMacMgmtHdr pHdr, uint8_t category)
{
	uint16_t aid;
	tpDphHashNode sta;
	bool rmfConnection = false;

	sta = dph_lookup_hash_entry(mac, pHdr->sa, &aid,
				    &pe_session->dph.dphHashTable);
	if (sta && sta->rmfEnabled)
		rmfConnection = true;

	if (rmfConnection && (pHdr->fc.wep == 0)) {
		pe_err("Dropping unprotected Action category: %d frame since RMF is enabled",
			category);
		return true;
	}

	return false;
}
#endif

/**
 * lim_process_addba_req() - process ADDBA Request
 * @mac_ctx: Pointer to Global MAC structure
 * @rx_pkt_info: A pointer to packet info structure
 * @session: PE session pointer
 *
 * This routine will be called to process ADDBA request action frame
 *
 * Return: None
 */
static void lim_process_addba_req(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
				  struct pe_session *session)
{
	tpSirMacMgmtHdr mac_hdr;
	uint8_t *body_ptr;
	tDot11faddba_req *addba_req;
	uint32_t frame_len, status;
	QDF_STATUS qdf_status;
	void *soc = cds_get_context(QDF_MODULE_ID_SOC);

	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);

	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO,
			   body_ptr, frame_len);

	addba_req = qdf_mem_malloc(sizeof(*addba_req));
	if (!addba_req)
		return;

	/* Unpack ADDBA request frame */
	status = dot11f_unpack_addba_req(mac_ctx, body_ptr, frame_len,
					 addba_req, false);

	if (DOT11F_FAILED(status)) {
		pe_err("Failed to unpack and parse (0x%08x, %d bytes)",
			status, frame_len);
		goto error;
	} else if (DOT11F_WARNED(status)) {
		pe_warn("warning: unpack addba Req(0x%08x, %d bytes)",
			status, frame_len);
	}

	qdf_status = cdp_addba_requestprocess(
					soc, mac_hdr->sa,
					session->vdev_id,
					addba_req->DialogToken.token,
					addba_req->addba_param_set.tid,
					addba_req->ba_timeout.timeout,
					addba_req->addba_param_set.buff_size,
					addba_req->ba_start_seq_ctrl.ssn);

	if (QDF_STATUS_SUCCESS == qdf_status) {
		qdf_status = lim_send_addba_response_frame(mac_ctx,
			mac_hdr->sa,
			addba_req->addba_param_set.tid,
			session,
			addba_req->addba_extn_element.present,
			addba_req->addba_param_set.amsdu_supp);
		if (qdf_status != QDF_STATUS_SUCCESS) {
			pe_err("Failed to send addba response frame");
			cdp_addba_resp_tx_completion(
					soc, mac_hdr->sa, session->vdev_id,
					addba_req->addba_param_set.tid,
					WMI_MGMT_TX_COMP_TYPE_DISCARD);
		}
	} else {
		pe_err_rl("Failed to process addba request");
	}

error:
	qdf_mem_free(addba_req);
	return;
}

/**
 * lim_process_delba_req() - process DELBA Request
 * @mac_ctx: Pointer to Global MAC structure
 * @rx_pkt_info: A pointer to packet info structure
 * @session: PE session pointer
 *
 * This routine will be called to process ADDBA request action frame
 *
 * Return: None
 */
static void lim_process_delba_req(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
				  struct pe_session *session)
{
	tpSirMacMgmtHdr mac_hdr;
	uint8_t *body_ptr;
	tDot11fdelba_req *delba_req;
	uint32_t frame_len, status;
	QDF_STATUS qdf_status;
	void *soc = cds_get_context(QDF_MODULE_ID_SOC);

	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);

	QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_INFO,
			   body_ptr, frame_len);

	delba_req = qdf_mem_malloc(sizeof(*delba_req));
	if (!delba_req)
		return;

	/* Unpack DELBA request frame */
	status = dot11f_unpack_delba_req(mac_ctx, body_ptr, frame_len,
					 delba_req, false);

	if (DOT11F_FAILED(status)) {
		pe_err("Failed to unpack and parse (0x%08x, %d bytes)",
			status, frame_len);
		goto error;
	} else if (DOT11F_WARNED(status)) {
		pe_warn("warning: unpack addba Req(0x%08x, %d bytes)",
			status, frame_len);
	}

	qdf_status = cdp_delba_process(soc, mac_hdr->sa, session->vdev_id,
			delba_req->delba_param_set.tid, delba_req->Reason.code);

	if (QDF_STATUS_SUCCESS != qdf_status)
		pe_err("Failed to process delba request");

error:
	qdf_mem_free(delba_req);
	return;
}

/**
 * lim_process_action_frame() - to process action frames
 * @mac_ctx: Pointer to Global MAC structure
 * @rx_pkt_info: A pointer to packet info structure
 *
 * This function is called by limProcessMessageQueue() upon
 * Action frame reception.
 *
 * Return: none
 */

void lim_process_action_frame(struct mac_context *mac_ctx,
		uint8_t *rx_pkt_info, struct pe_session *session)
{
	uint8_t *body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
	tpSirMacActionFrameHdr action_hdr = (tpSirMacActionFrameHdr) body_ptr;
#ifdef WLAN_FEATURE_11W
	tpSirMacMgmtHdr mac_hdr_11w = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
#endif
	tpSirMacMgmtHdr mac_hdr = NULL;
	int8_t rssi;
	uint32_t frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
	tpSirMacVendorSpecificFrameHdr vendor_specific;
	uint8_t oui[] = { 0x00, 0x00, 0xf0 };
	uint8_t dpp_oui[] = { 0x50, 0x6F, 0x9A, 0x1A };
	tpSirMacVendorSpecificPublicActionFrameHdr pub_action;

	if (frame_len < sizeof(*action_hdr)) {
		pe_debug("frame_len %d less than Action Frame Hdr size",
			 frame_len);
		return;
	}

#ifdef WLAN_FEATURE_11W
	if (lim_is_robust_mgmt_action_frame(action_hdr->category) &&
	   lim_drop_unprotected_action_frame(mac_ctx, session,
			mac_hdr_11w, action_hdr->category))
		return;
#endif

	switch (action_hdr->category) {
	case ACTION_CATEGORY_QOS:
		if ((session->limQosEnabled) ||
		    (action_hdr->actionID == QOS_MAP_CONFIGURE)) {
			switch (action_hdr->actionID) {
			case QOS_ADD_TS_REQ:
				__lim_process_add_ts_req(mac_ctx,
						(uint8_t *) rx_pkt_info,
						session);
				break;

			case QOS_ADD_TS_RSP:
				__lim_process_add_ts_rsp(mac_ctx,
						 (uint8_t *) rx_pkt_info,
						 session);
				break;

			case QOS_DEL_TS_REQ:
				__lim_process_del_ts_req(mac_ctx,
						(uint8_t *) rx_pkt_info,
						session);
				break;

			case QOS_MAP_CONFIGURE:
				__lim_process_qos_map_configure_frame(mac_ctx,
						(uint8_t *)rx_pkt_info,
						session);
				break;
			default:
				pe_warn("Qos action: %d not handled",
					action_hdr->actionID);
				break;
			}
			break;
		}
		break;

	case ACTION_CATEGORY_SPECTRUM_MGMT:
		switch (action_hdr->actionID) {
#ifdef ANI_SUPPORT_11H
		case ACTION_SPCT_MSR_REQ:
			if (session->lim11hEnable)
				__lim_process_measurement_request_frame(mac_ctx,
							rx_pkt_info,
							session);
			break;
		case ACTION_SPCT_TPC_REQ:
			if ((LIM_IS_STA_ROLE(session) ||
				LIM_IS_AP_ROLE(session)) &&
				session->lim11hEnable)
					__lim_process_tpc_request_frame(mac_ctx,
						rx_pkt_info, session);
			break;
#endif
		case ACTION_SPCT_CHL_SWITCH:
			if (LIM_IS_STA_ROLE(session))
				__lim_process_channel_switch_action_frame(
					mac_ctx, rx_pkt_info, session);
			break;
		default:
			pe_warn("Spectrum mgmt action id: %d not handled",
				action_hdr->actionID);
			break;
		}
		break;

	case ACTION_CATEGORY_WMM:
		if (!session->limWmeEnabled) {
			pe_warn("WME mode disabled - dropping frame: %d",
				action_hdr->actionID);
			break;
		}
		switch (action_hdr->actionID) {
		case QOS_ADD_TS_REQ:
			__lim_process_add_ts_req(mac_ctx,
				(uint8_t *) rx_pkt_info, session);
			break;

		case QOS_ADD_TS_RSP:
			__lim_process_add_ts_rsp(mac_ctx,
				(uint8_t *) rx_pkt_info, session);
			break;

		case QOS_DEL_TS_REQ:
			__lim_process_del_ts_req(mac_ctx,
				(uint8_t *) rx_pkt_info, session);
			break;

		case QOS_MAP_CONFIGURE:
			__lim_process_qos_map_configure_frame(mac_ctx,
				(uint8_t *)rx_pkt_info, session);
			break;

		default:
			pe_warn("WME action: %d not handled",
				action_hdr->actionID);
			break;
		}
		break;

	case ACTION_CATEGORY_HT:
		/** Type of HT Action to be performed*/
		switch (action_hdr->actionID) {
		case SIR_MAC_SM_POWER_SAVE:
			if (LIM_IS_AP_ROLE(session))
				__lim_process_sm_power_save_update(mac_ctx,
						(uint8_t *)rx_pkt_info,
						session);
			break;
		default:
			pe_warn("Action ID: %d not handled in HT category",
				action_hdr->actionID);
			break;
		}
		break;

	case ACTION_CATEGORY_WNM:
		pe_debug("WNM Action category: %d action: %d",
			action_hdr->category, action_hdr->actionID);
		switch (action_hdr->actionID) {
		case WNM_BSS_TM_QUERY:
		case WNM_BSS_TM_REQUEST:
		case WNM_BSS_TM_RESPONSE:
		case WNM_NOTIF_REQUEST:
		case WNM_NOTIF_RESPONSE:
			rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
			mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
			/* Forward to the SME to HDD to wpa_supplicant */
			lim_send_sme_mgmt_frame_ind(mac_ctx,
					mac_hdr->fc.subType,
					(uint8_t *) mac_hdr,
					frame_len + sizeof(tSirMacMgmtHdr),
					session->smeSessionId,
					WMA_GET_RX_FREQ(rx_pkt_info),
					session, rssi, RXMGMT_FLAG_NONE);
			break;
		default:
			pe_debug("Action ID: %d not handled in WNM category",
				action_hdr->actionID);
			break;
		}
		break;

	case ACTION_CATEGORY_RRM:
		/* Ignore RRM measurement request until DHCP is set */
		if (mac_ctx->rrm.rrmPEContext.rrmEnable &&
		    mac_ctx->roam.roamSession
		    [session->smeSessionId].dhcp_done) {
			switch (action_hdr->actionID) {
			case RRM_RADIO_MEASURE_REQ:
				__lim_process_radio_measure_request(mac_ctx,
						(uint8_t *)rx_pkt_info,
						session);
				break;
			case RRM_LINK_MEASUREMENT_REQ:
				if (!lim_is_valid_frame(
					&rrm_link_action_frm,
					rx_pkt_info))
					break;

				if (__lim_process_link_measurement_req(
						mac_ctx,
						(uint8_t *)rx_pkt_info,
						session) == QDF_STATUS_SUCCESS)
					lim_update_last_processed_frame(
							&rrm_link_action_frm,
							rx_pkt_info);

				break;
			case RRM_NEIGHBOR_RPT:
				__lim_process_neighbor_report(mac_ctx,
						(uint8_t *)rx_pkt_info,
						session);
				break;
			default:
				pe_warn("Action ID: %d not handled in RRM",
					action_hdr->actionID);
				break;

			}
		} else {
			/* Else we will just ignore the RRM messages. */
			pe_debug("RRM frm ignored, it is disabled in cfg: %d or DHCP not completed: %d",
			  mac_ctx->rrm.rrmPEContext.rrmEnable,
			  mac_ctx->roam.roamSession
			  [session->smeSessionId].dhcp_done);
		}
		break;

	case SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY:
		vendor_specific = (tpSirMacVendorSpecificFrameHdr) action_hdr;
		mac_hdr = NULL;

		mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);

		if (frame_len < sizeof(*vendor_specific)) {
			pe_debug("frame len %d less than Vendor Specific Hdr len",
				 frame_len);
			return;
		}

		/* Check if it is a vendor specific action frame. */
		if (LIM_IS_STA_ROLE(session) &&
		    (!qdf_mem_cmp(session->self_mac_addr,
					&mac_hdr->da[0], sizeof(tSirMacAddr)))
		    && IS_WES_MODE_ENABLED(mac_ctx)
		    && !qdf_mem_cmp(vendor_specific->Oui, oui, 3)) {
			pe_debug("Rcvd Vendor specific frame OUI: %x %x %x",
				vendor_specific->Oui[0],
				vendor_specific->Oui[1],
				vendor_specific->Oui[2]);
			/*
			 * Forward to the SME to HDD to wpa_supplicant
			 * type is ACTION
			 */
			lim_send_sme_mgmt_frame_ind(mac_ctx,
					mac_hdr->fc.subType,
					(uint8_t *) mac_hdr,
					frame_len +
					sizeof(tSirMacMgmtHdr),
					session->smeSessionId,
					WMA_GET_RX_FREQ(rx_pkt_info),
					session,
					WMA_GET_RX_RSSI_NORMALIZED(
					rx_pkt_info), RXMGMT_FLAG_NONE);
		} else {
			pe_debug("Dropping the vendor specific action frame"
					"beacause of (WES Mode not enabled "
					"(WESMODE: %d) or OUI mismatch "
					"(%02x %02x %02x) or not received with"
					"SelfSta address) system role: %d",
				IS_WES_MODE_ENABLED(mac_ctx),
				vendor_specific->Oui[0],
				vendor_specific->Oui[1],
				vendor_specific->Oui[2],
				GET_LIM_SYSTEM_ROLE(session));
		}
	break;
	case ACTION_CATEGORY_PUBLIC:
		mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);

		switch (action_hdr->actionID) {
		case SIR_MAC_ACTION_EXT_CHANNEL_SWITCH_ID:
			lim_process_ext_channel_switch_action_frame(mac_ctx,
							rx_pkt_info, session);
			break;
		case SIR_MAC_ACTION_VENDOR_SPECIFIC:
			pub_action =
				(tpSirMacVendorSpecificPublicActionFrameHdr)
				action_hdr;
			if (frame_len < sizeof(*pub_action)) {
				pe_debug("Received vendor specific public action frame of invalid len %d",
					 frame_len);
				return;
			}
			/*
			 * Check if it is a DPP public action frame and fall
			 * thru, else drop the frame.
			 */
			if (qdf_mem_cmp(pub_action->Oui, dpp_oui, 4)) {
				pe_debug("Unhandled public action frame (Vendor specific) OUI: %x %x %x %x",
					pub_action->Oui[0], pub_action->Oui[1],
					pub_action->Oui[2], pub_action->Oui[3]);
				break;
			}
			/* Fall through to send the frame to supplicant */
		case SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY:
		case SIR_MAC_ACTION_2040_BSS_COEXISTENCE:
		case SIR_MAC_ACTION_GAS_INITIAL_REQUEST:
		case SIR_MAC_ACTION_GAS_INITIAL_RESPONSE:
		case SIR_MAC_ACTION_GAS_COMEBACK_REQUEST:
		case SIR_MAC_ACTION_GAS_COMEBACK_RESPONSE:
			/*
			 * Forward to the SME to HDD to wpa_supplicant
			 * type is ACTION
			 */
			lim_send_sme_mgmt_frame_ind(mac_ctx,
					mac_hdr->fc.subType,
					(uint8_t *) mac_hdr,
					frame_len + sizeof(tSirMacMgmtHdr),
					session->smeSessionId,
					WMA_GET_RX_FREQ(rx_pkt_info), session,
					WMA_GET_RX_RSSI_NORMALIZED(
					rx_pkt_info), RXMGMT_FLAG_NONE);
			break;
		default:
			pe_debug("Unhandled public action frame: %d",
				 action_hdr->actionID);
			break;
		}
		break;

#ifdef WLAN_FEATURE_11W
	case ACTION_CATEGORY_SA_QUERY:
		pe_debug("SA Query Action category: %d action: %d",
			action_hdr->category, action_hdr->actionID);
		switch (action_hdr->actionID) {
		case SA_QUERY_REQUEST:
			/**11w SA query request action frame received**/
			/* Respond directly to the incoming request in LIM */
			__lim_process_sa_query_request_action_frame(mac_ctx,
						(uint8_t *)rx_pkt_info,
						session);
			break;
		case SA_QUERY_RESPONSE:
			/**11w SA query response action frame received**/
			/* Handle based on the current SA Query state */
			__lim_process_sa_query_response_action_frame(mac_ctx,
						(uint8_t *)rx_pkt_info,
						session);
			break;
		default:
			break;
		}
		break;
#endif
	case ACTION_CATEGORY_VHT:
		if (!session->vhtCapability)
			break;
		switch (action_hdr->actionID) {
		case SIR_MAC_VHT_OPMODE_NOTIFICATION:
			__lim_process_operating_mode_action_frame(mac_ctx,
					rx_pkt_info, session);
			break;
		case SIR_MAC_VHT_GID_NOTIFICATION:
			/* Only if ini supports it */
			if (session->enableVhtGid)
				__lim_process_gid_management_action_frame(
					mac_ctx, rx_pkt_info, session);
			break;
		default:
			break;
		}
		break;
	case ACTION_CATEGORY_FST: {
		tpSirMacMgmtHdr     hdr;

		hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);

		pe_debug("Received FST MGMT action frame");
		/* Forward to the SME to HDD */
		lim_send_sme_mgmt_frame_ind(mac_ctx, hdr->fc.subType,
					    (uint8_t *)hdr,
					    frame_len + sizeof(tSirMacMgmtHdr),
					    session->smeSessionId,
					    WMA_GET_RX_FREQ(rx_pkt_info),
					    session,
					    WMA_GET_RX_RSSI_NORMALIZED(
					    rx_pkt_info), RXMGMT_FLAG_NONE);
		break;
	}
	case ACTION_CATEGORY_PROTECTED_DUAL_OF_PUBLIC_ACTION:
		pe_debug("Rcvd Protected Dual of Public Action: %d",
			action_hdr->actionID);
		switch (action_hdr->actionID) {
		case SIR_MAC_PDPA_GAS_INIT_REQ:
		case SIR_MAC_PDPA_GAS_INIT_RSP:
		case SIR_MAC_PDPA_GAS_COMEBACK_REQ:
		case SIR_MAC_PDPA_GAS_COMEBACK_RSP:
			mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
			rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
			lim_send_sme_mgmt_frame_ind(mac_ctx,
				mac_hdr->fc.subType, (uint8_t *) mac_hdr,
				frame_len + sizeof(tSirMacMgmtHdr),
				session->smeSessionId,
				WMA_GET_RX_FREQ(rx_pkt_info), session, rssi,
				RXMGMT_FLAG_NONE);
			break;
		default:
			pe_debug("Unhandled - Protected Dual Public Action");
			break;
		}
		break;
	case ACTION_CATEGORY_BACK:
		pe_debug("Rcvd Block Ack for %pM; action: %d",
			session->self_mac_addr, action_hdr->actionID);
		switch (action_hdr->actionID) {
		case ADDBA_REQUEST:
			lim_process_addba_req(mac_ctx, rx_pkt_info, session);
			break;
		case DELBA:
			lim_process_delba_req(mac_ctx, rx_pkt_info, session);
			break;
		default:
			pe_err("Unhandle BA action frame");
			break;
		}
		break;
	default:
		pe_warn("Action category: %d not handled",
			action_hdr->category);
		break;
	}
}

/**
 * lim_process_action_frame_no_session
 *
 ***FUNCTION:
 * This function is called by limProcessMessageQueue() upon
 * Action frame reception and no session.
 * Currently only public action frames can be received from
 * a non-associated station.
 *
 ***LOGIC:
 *
 ***ASSUMPTIONS:
 *
 ***NOTE:
 *
 * @param  mac - Pointer to Global MAC structure
 * @param  *pBd - A pointer to Buffer descriptor + associated PDUs
 * @return None
 */
void lim_process_action_frame_no_session(struct mac_context *mac, uint8_t *pBd)
{
	tpSirMacMgmtHdr mac_hdr = WMA_GET_RX_MAC_HEADER(pBd);
	uint32_t frame_len = WMA_GET_RX_PAYLOAD_LEN(pBd);
	uint8_t *pBody = WMA_GET_RX_MPDU_DATA(pBd);
	uint8_t dpp_oui[] = { 0x50, 0x6F, 0x9A, 0x1A };
	tpSirMacActionFrameHdr action_hdr = (tpSirMacActionFrameHdr) pBody;
	tpSirMacVendorSpecificPublicActionFrameHdr vendor_specific;

	pe_debug("Received an Action frame -- no session");

	if (frame_len < sizeof(*action_hdr)) {
		pe_debug("frame_len %d less than action frame header len",
			 frame_len);
		return;
	}

	switch (action_hdr->category) {
	case ACTION_CATEGORY_PUBLIC:
		switch (action_hdr->actionID) {
		case SIR_MAC_ACTION_VENDOR_SPECIFIC:
			vendor_specific =
				(tpSirMacVendorSpecificPublicActionFrameHdr)
				action_hdr;

			if (frame_len < sizeof(*vendor_specific)) {
				pe_debug("Received vendor specific public action frame of invalid len %d",
					 frame_len);
				return;
			}
			/*
			 * Check if it is a DPP public action frame and fall
			 * thru, else drop the frame.
			 */
			if (qdf_mem_cmp(vendor_specific->Oui, dpp_oui, 4)) {
				pe_debug("Unhandled public action frame (Vendor specific) OUI: %x %x %x %x",
					vendor_specific->Oui[0],
					vendor_specific->Oui[1],
					vendor_specific->Oui[2],
					vendor_specific->Oui[3]);
				break;
			}
			/* Fall through to send the frame to supplicant */
		case SIR_MAC_ACTION_GAS_INITIAL_REQUEST:
		case SIR_MAC_ACTION_GAS_INITIAL_RESPONSE:
		case SIR_MAC_ACTION_GAS_COMEBACK_REQUEST:
		case SIR_MAC_ACTION_GAS_COMEBACK_RESPONSE:
			/*
			 * Forward the GAS frames to  wpa_supplicant
			 * type is ACTION
			 */
			lim_send_sme_mgmt_frame_ind(mac,
					mac_hdr->fc.subType,
					(uint8_t *) mac_hdr,
					frame_len + sizeof(tSirMacMgmtHdr), 0,
					WMA_GET_RX_FREQ(pBd), NULL,
					WMA_GET_RX_RSSI_NORMALIZED(pBd),
					RXMGMT_FLAG_NONE);
			break;
		default:
			pe_warn("Unhandled public action frame: %x",
				       action_hdr->actionID);
			break;
		}
		break;
	default:
		pe_warn("Unhandled action frame without session: %x",
			       action_hdr->category);
		break;

	}
}
