qcacld-3.0: Initial snapshot of ihelium wlan driver
qcacld-3.0: Initial snapshot of ihelium wlan driver
to match code-scanned SU Release 5.0.0.139. This is
open-source version of wlan for next Android release.
Change-Id: Icf598ca97da74f84bea607e4e902d1889806f507
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
new file mode 100644
index 0000000..e27113c
--- /dev/null
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
@@ -0,0 +1,2370 @@
+/*
+ * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ *
+ * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
+ *
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file was originally distributed by Qualcomm Atheros, Inc.
+ * under proprietary terms before Copyright ownership was assigned
+ * to the Linux Foundation.
+ */
+
+/*
+ * This file lim_send_sme_rspMessages.cc contains the functions
+ * for sending SME response/notification messages to applications
+ * above MAC software.
+ * Author: Chandra Modumudi
+ * Date: 02/13/02
+ * History:-
+ * Date Modified by Modification Information
+ * --------------------------------------------------------------------
+ */
+
+#include "cdf_types.h"
+#include "wni_api.h"
+#include "sir_common.h"
+#include "ani_global.h"
+
+#include "wni_cfg.h"
+#include "sys_def.h"
+#include "cfg_api.h"
+
+#include "sch_api.h"
+#include "utils_api.h"
+#include "lim_utils.h"
+#include "lim_security_utils.h"
+#include "lim_ser_des_utils.h"
+#include "lim_send_sme_rsp_messages.h"
+#include "lim_ibss_peer_mgmt.h"
+#include "lim_session_utils.h"
+#include "lim_types.h"
+#include "sir_api.h"
+
+static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx,
+ tpPESession session_entry, tSirResultCodes result_code,
+ tpSirSmeJoinRsp sme_join_rsp);
+
+/**
+ * lim_send_sme_rsp() - Send Response to upper layers
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_type: Indicates message type
+ * @result_code: Indicates the result of previously issued
+ * eWNI_SME_msg_type_REQ message
+ *
+ * This function is called by lim_process_sme_req_messages() to send
+ * eWNI_SME_START_RSP, eWNI_SME_STOP_BSS_RSP
+ * or eWNI_SME_SWITCH_CHL_RSP messages to applications above MAC
+ * Software.
+ *
+ * Return: None
+ */
+
+void
+lim_send_sme_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
+ tSirResultCodes result_code, uint8_t sme_session_id,
+ uint16_t sme_transaction_id)
+{
+ tSirMsgQ msg;
+ tSirSmeRsp *sme_rsp;
+
+ lim_log(mac_ctx, LOG1, FL("Sending message %s with reasonCode %s"),
+ lim_msg_str(msg_type), lim_result_code_str(result_code));
+
+ sme_rsp = cdf_mem_malloc(sizeof(tSirSmeRsp));
+ if (NULL == sme_rsp) {
+ /* Buffer not available. Log error */
+ CDF_TRACE(CDF_MODULE_ID_PE, LOGP,
+ FL("call to AllocateMemory failed for eWNI_SME_*_RSP"));
+ return;
+ }
+
+ sme_rsp->messageType = msg_type;
+ sme_rsp->length = sizeof(tSirSmeRsp);
+ sme_rsp->statusCode = result_code;
+
+ sme_rsp->sessionId = sme_session_id;
+ sme_rsp->transactionId = sme_transaction_id;
+
+ msg.type = msg_type;
+ msg.bodyptr = sme_rsp;
+ msg.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(mac_ctx, sme_session_id, msg.type));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ switch (msg_type) {
+ case eWNI_SME_STOP_BSS_RSP:
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_STOP_BSS_RSP_EVENT,
+ NULL, (uint16_t) result_code, 0);
+ break;
+ }
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT);
+}
+
+
+
+/**
+ * lim_send_sme_roc_rsp() - Send Response to SME
+ * @mac_ctx: Pointer to Global MAC structure
+ * @status: Resume link status
+ * @result_code: Result of the ROC request
+ * @sme_session_id: SME sesson Id
+ * @scan_id: Scan Identifier
+ *
+ * This function is called to send ROC rsp
+ * message to SME.
+ *
+ * Return: None
+ */
+void
+lim_send_sme_roc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
+ tSirResultCodes result_code, uint8_t sme_session_id,
+ uint32_t scan_id)
+{
+ tSirMsgQ msg;
+ struct sir_roc_rsp *sme_rsp;
+
+ lim_log(mac_ctx, LOG1,
+ FL("Sending message %s with reasonCode %s scanId %d"),
+ lim_msg_str(msg_type), lim_result_code_str(result_code),
+ scan_id);
+
+ sme_rsp = cdf_mem_malloc(sizeof(struct sir_roc_rsp));
+ if (NULL == sme_rsp) {
+ CDF_TRACE(CDF_MODULE_ID_PE, LOGP,
+ FL("call to AllocateMemory failed for eWNI_SME_*_RSP"));
+ return;
+ }
+
+ sme_rsp->message_type = msg_type;
+ sme_rsp->length = sizeof(struct sir_roc_rsp);
+ sme_rsp->status = result_code;
+
+ sme_rsp->session_id = sme_session_id;
+ sme_rsp->scan_id = scan_id;
+
+ msg.type = msg_type;
+ msg.bodyptr = sme_rsp;
+ msg.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(mac_ctx, sme_session_id, msg.type));
+ lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT);
+}
+
+
+/**
+ * lim_send_sme_join_reassoc_rsp_after_resume() - Send Response to SME
+ * @mac_ctx Pointer to Global MAC structure
+ * @status Resume link status
+ * @ctx context passed while calling resmune link.
+ * (join response to be sent)
+ *
+ * This function is called to send Join/Reassoc rsp
+ * message to SME after the resume link.
+ *
+ * Return: None
+ */
+static void lim_send_sme_join_reassoc_rsp_after_resume(tpAniSirGlobal mac_ctx,
+ CDF_STATUS status, uint32_t *ctx)
+{
+ tSirMsgQ msg;
+ tpSirSmeJoinRsp sme_join_rsp = (tpSirSmeJoinRsp) ctx;
+
+ msg.type = sme_join_rsp->messageType;
+ msg.bodyptr = sme_join_rsp;
+ msg.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(mac_ctx, NO_SESSION, msg.type));
+ lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT);
+}
+
+/**
+ * lim_handle_join_rsp_status() - Handle the response.
+ * @mac_ctx: Pointer to Global MAC structure
+ * @session_entry: PE Session Info
+ * @result_code: Indicates the result of previously issued
+ * eWNI_SME_msgType_REQ message
+ * @sme_join_rsp The received response.
+ *
+ * This function will handle both the success and failure status
+ * of the received response.
+ *
+ * Return: None
+ */
+static void lim_handle_join_rsp_status(tpAniSirGlobal mac_ctx,
+ tpPESession session_entry, tSirResultCodes result_code,
+ tpSirSmeJoinRsp sme_join_rsp)
+{
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+ tSirSmeHTProfile *ht_profile;
+#endif
+ if (result_code == eSIR_SME_SUCCESS) {
+ if (session_entry->beacon != NULL) {
+ sme_join_rsp->beaconLength = session_entry->bcnLen;
+ cdf_mem_copy(sme_join_rsp->frames,
+ session_entry->beacon,
+ sme_join_rsp->beaconLength);
+ cdf_mem_free(session_entry->beacon);
+ session_entry->beacon = NULL;
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOG1, FL("Beacon=%d"),
+ session_entry->bcnLen);
+#endif
+ }
+ if (session_entry->assocReq != NULL) {
+ sme_join_rsp->assocReqLength =
+ session_entry->assocReqLen;
+ cdf_mem_copy(sme_join_rsp->frames +
+ session_entry->bcnLen, session_entry->assocReq,
+ sme_join_rsp->assocReqLength);
+ cdf_mem_free(session_entry->assocReq);
+ session_entry->assocReq = NULL;
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx,
+ LOG1, FL("AssocReq=%d"),
+ session_entry->assocReqLen);
+#endif
+ }
+ if (session_entry->assocRsp != NULL) {
+ sme_join_rsp->assocRspLength =
+ session_entry->assocRspLen;
+ cdf_mem_copy(sme_join_rsp->frames +
+ session_entry->bcnLen +
+ session_entry->assocReqLen,
+ session_entry->assocRsp,
+ sme_join_rsp->assocRspLength);
+ cdf_mem_free(session_entry->assocRsp);
+ session_entry->assocRsp = NULL;
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ if (session_entry->ricData != NULL) {
+ sme_join_rsp->parsedRicRspLen =
+ session_entry->RICDataLen;
+ cdf_mem_copy(sme_join_rsp->frames +
+ session_entry->bcnLen +
+ session_entry->assocReqLen +
+ session_entry->assocRspLen,
+ session_entry->ricData,
+ sme_join_rsp->parsedRicRspLen);
+ cdf_mem_free(session_entry->ricData);
+ session_entry->ricData = NULL;
+ lim_log(mac_ctx, LOG1, FL("RicLength=%d"),
+ sme_join_rsp->parsedRicRspLen);
+ }
+#endif
+#ifdef FEATURE_WLAN_ESE
+ if (session_entry->tspecIes != NULL) {
+ sme_join_rsp->tspecIeLen =
+ session_entry->tspecLen;
+ cdf_mem_copy(sme_join_rsp->frames +
+ session_entry->bcnLen +
+ session_entry->assocReqLen +
+ session_entry->assocRspLen +
+ session_entry->RICDataLen,
+ session_entry->tspecIes,
+ sme_join_rsp->tspecIeLen);
+ cdf_mem_free(session_entry->tspecIes);
+ session_entry->tspecIes = NULL;
+ lim_log(mac_ctx, LOG1, FL("ESE-TspecLen=%d"),
+ session_entry->tspecLen);
+ }
+#endif
+ sme_join_rsp->aid = session_entry->limAID;
+#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
+ lim_log(mac_ctx, LOG1, FL("AssocRsp=%d"),
+ session_entry->assocRspLen);
+#endif
+ sme_join_rsp->vht_channel_width =
+ session_entry->ch_width;
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+ if (session_entry->cc_switch_mode !=
+ CDF_MCC_TO_SCC_SWITCH_DISABLE) {
+ ht_profile = &sme_join_rsp->HTProfile;
+ ht_profile->htSupportedChannelWidthSet =
+ session_entry->htSupportedChannelWidthSet;
+ ht_profile->htRecommendedTxWidthSet =
+ session_entry->htRecommendedTxWidthSet;
+ ht_profile->htSecondaryChannelOffset =
+ session_entry->htSecondaryChannelOffset;
+ ht_profile->dot11mode = session_entry->dot11mode;
+ ht_profile->htCapability = session_entry->htCapability;
+#ifdef WLAN_FEATURE_11AC
+ ht_profile->vhtCapability =
+ session_entry->vhtCapability;
+ ht_profile->vhtTxChannelWidthSet =
+ session_entry->vhtTxChannelWidthSet;
+ ht_profile->apCenterChan = session_entry->ch_center_freq_seg0;
+ ht_profile->apChanWidth = session_entry->ch_width;
+#endif
+ }
+#endif
+ } else {
+ if (session_entry->beacon != NULL) {
+ cdf_mem_free(session_entry->beacon);
+ session_entry->beacon = NULL;
+ }
+ if (session_entry->assocReq != NULL) {
+ cdf_mem_free(session_entry->assocReq);
+ session_entry->assocReq = NULL;
+ }
+ if (session_entry->assocRsp != NULL) {
+ cdf_mem_free(session_entry->assocRsp);
+ session_entry->assocRsp = NULL;
+ }
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ if (session_entry->ricData != NULL) {
+ cdf_mem_free(session_entry->ricData);
+ session_entry->ricData = NULL;
+ }
+#endif
+#ifdef FEATURE_WLAN_ESE
+ if (session_entry->tspecIes != NULL) {
+ cdf_mem_free(session_entry->tspecIes);
+ session_entry->tspecIes = NULL;
+ }
+#endif
+ }
+}
+/**
+ * lim_send_sme_join_reassoc_rsp() - Send Response to Upper Layers
+ * @mac_ctx: Pointer to Global MAC structure
+ * @msg_type: Indicates message type
+ * @result_code: Indicates the result of previously issued
+ * eWNI_SME_msgType_REQ message
+ * @prot_status_code: Protocol Status Code
+ * @session_entry: PE Session Info
+ * @sme_session_id: SME Session ID
+ * @sme_transaction_id: SME Transaction ID
+ *
+ * This function is called by lim_process_sme_req_messages() to send
+ * eWNI_SME_JOIN_RSP or eWNI_SME_REASSOC_RSP messages to applications
+ * above MAC Software.
+ *
+ * Return: None
+ */
+
+void
+lim_send_sme_join_reassoc_rsp(tpAniSirGlobal mac_ctx, uint16_t msg_type,
+ tSirResultCodes result_code, uint16_t prot_status_code,
+ tpPESession session_entry, uint8_t sme_session_id,
+ uint16_t sme_transaction_id)
+{
+ tpSirSmeJoinRsp sme_join_rsp;
+ uint32_t rsp_len;
+ tpDphHashNode sta_ds = NULL;
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ if (msg_type == eWNI_SME_REASSOC_RSP)
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_REASSOC_RSP_EVENT,
+ session_entry, (uint16_t) result_code, 0);
+ else
+ lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_JOIN_RSP_EVENT,
+ session_entry, (uint16_t) result_code, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_log(mac_ctx, LOG1, FL("Sending message %s with reasonCode %s"),
+ lim_msg_str(msg_type), lim_result_code_str(result_code));
+
+ if (session_entry == NULL) {
+ rsp_len = sizeof(tSirSmeJoinRsp);
+ sme_join_rsp = cdf_mem_malloc(rsp_len);
+ if (NULL == sme_join_rsp) {
+ lim_log(mac_ctx, LOGP,
+ FL("Mem Alloc fail - JOIN/REASSOC_RSP"));
+ return;
+ }
+
+ cdf_mem_set((uint8_t *) sme_join_rsp, rsp_len, 0);
+ sme_join_rsp->beaconLength = 0;
+ sme_join_rsp->assocReqLength = 0;
+ sme_join_rsp->assocRspLength = 0;
+ } else {
+ rsp_len = session_entry->assocReqLen +
+ session_entry->assocRspLen + session_entry->bcnLen +
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ session_entry->RICDataLen +
+#endif
+#ifdef FEATURE_WLAN_ESE
+ session_entry->tspecLen +
+#endif
+ sizeof(tSirSmeJoinRsp) - sizeof(uint8_t);
+ sme_join_rsp = cdf_mem_malloc(rsp_len);
+ if (NULL == sme_join_rsp) {
+ lim_log(mac_ctx, LOGP,
+ FL("MemAlloc fail - JOIN/REASSOC_RSP"));
+ return;
+ }
+ cdf_mem_set((uint8_t *) sme_join_rsp, rsp_len, 0);
+ if (result_code == eSIR_SME_SUCCESS) {
+ sta_ds = dph_get_hash_entry(mac_ctx,
+ DPH_STA_HASH_INDEX_PEER,
+ &session_entry->dph.dphHashTable);
+ if (sta_ds == NULL) {
+ lim_log(mac_ctx, LOGE,
+ FL("Get Self Sta Entry fail"));
+ } else {
+ /* Pass the peer's staId */
+ sme_join_rsp->staId = sta_ds->staIndex;
+ sme_join_rsp->ucastSig =
+ sta_ds->ucUcastSig;
+ sme_join_rsp->bcastSig =
+ sta_ds->ucBcastSig;
+ sme_join_rsp->timingMeasCap =
+ sta_ds->timingMeasCap;
+#ifdef FEATURE_WLAN_TDLS
+ sme_join_rsp->tdls_prohibited =
+ session_entry->tdls_prohibited;
+ sme_join_rsp->tdls_chan_swit_prohibited =
+ session_entry->tdls_chan_swit_prohibited;
+#endif
+ }
+ }
+ sme_join_rsp->beaconLength = 0;
+ sme_join_rsp->assocReqLength = 0;
+ sme_join_rsp->assocRspLength = 0;
+#ifdef WLAN_FEATURE_VOWIFI_11R
+ sme_join_rsp->parsedRicRspLen = 0;
+#endif
+#ifdef FEATURE_WLAN_ESE
+ sme_join_rsp->tspecIeLen = 0;
+#endif
+
+ lim_handle_join_rsp_status(mac_ctx, session_entry, result_code,
+ sme_join_rsp);
+ }
+
+ sme_join_rsp->messageType = msg_type;
+ sme_join_rsp->length = (uint16_t) rsp_len;
+ sme_join_rsp->statusCode = result_code;
+ sme_join_rsp->protStatusCode = prot_status_code;
+
+ sme_join_rsp->sessionId = sme_session_id;
+ sme_join_rsp->transactionId = sme_transaction_id;
+
+ lim_send_sme_join_reassoc_rsp_after_resume(mac_ctx, CDF_STATUS_SUCCESS,
+ (uint32_t *)sme_join_rsp);
+}
+
+/**
+ * lim_send_sme_start_bss_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to send eWNI_SME_START_BSS_RSP
+ * message to applications above MAC Software.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param msgType Indicates message type
+ * @param resultCode Indicates the result of previously issued
+ * eWNI_SME_msgType_REQ message
+ *
+ * @return None
+ */
+
+void
+lim_send_sme_start_bss_rsp(tpAniSirGlobal pMac,
+ uint16_t msgType, tSirResultCodes resultCode,
+ tpPESession psessionEntry, uint8_t smesessionId,
+ uint16_t smetransactionId)
+{
+
+ uint16_t size = 0;
+ tSirMsgQ mmhMsg;
+ tSirSmeStartBssRsp *pSirSmeRsp;
+ uint16_t ieLen;
+ uint16_t ieOffset, curLen;
+
+ PELOG1(lim_log(pMac, LOG1, FL("Sending message %s with reasonCode %s"),
+ lim_msg_str(msgType), lim_result_code_str(resultCode));
+ )
+
+ size = sizeof(tSirSmeStartBssRsp);
+
+ if (psessionEntry == NULL) {
+ pSirSmeRsp = cdf_mem_malloc(size);
+ if (NULL == pSirSmeRsp) {
+ /* / Buffer not available. Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for eWNI_SME_START_BSS_RSP"));
+ return;
+ }
+ cdf_mem_set((uint8_t *) pSirSmeRsp, size, 0);
+
+ } else {
+ /* subtract size of beaconLength + Mac Hdr + Fixed Fields before SSID */
+ ieOffset = sizeof(tAniBeaconStruct) + SIR_MAC_B_PR_SSID_OFFSET;
+ ieLen = psessionEntry->schBeaconOffsetBegin
+ + psessionEntry->schBeaconOffsetEnd - ieOffset;
+ /* calculate the memory size to allocate */
+ size += ieLen;
+
+ pSirSmeRsp = cdf_mem_malloc(size);
+ if (NULL == pSirSmeRsp) {
+ /* / Buffer not available. Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for eWNI_SME_START_BSS_RSP"));
+
+ return;
+ }
+ cdf_mem_set((uint8_t *) pSirSmeRsp, size, 0);
+ size = sizeof(tSirSmeStartBssRsp);
+ if (resultCode == eSIR_SME_SUCCESS) {
+
+ sir_copy_mac_addr(pSirSmeRsp->bssDescription.bssId,
+ psessionEntry->bssId);
+
+ /* Read beacon interval from session */
+ pSirSmeRsp->bssDescription.beaconInterval =
+ (uint16_t) psessionEntry->beaconParams.
+ beaconInterval;
+ pSirSmeRsp->bssType = psessionEntry->bssType;
+
+ if (cfg_get_capability_info
+ (pMac, &pSirSmeRsp->bssDescription.capabilityInfo,
+ psessionEntry)
+ != eSIR_SUCCESS)
+ lim_log(pMac, LOGP,
+ FL
+ ("could not retrieve Capabilities value"));
+
+ lim_get_phy_mode(pMac,
+ (uint32_t *) &pSirSmeRsp->bssDescription.
+ nwType, psessionEntry);
+
+ pSirSmeRsp->bssDescription.channelId =
+ psessionEntry->currentOperChannel;
+
+ curLen = psessionEntry->schBeaconOffsetBegin - ieOffset;
+ cdf_mem_copy((uint8_t *) &pSirSmeRsp->bssDescription.
+ ieFields,
+ psessionEntry->pSchBeaconFrameBegin +
+ ieOffset, (uint32_t) curLen);
+
+ cdf_mem_copy(((uint8_t *) &pSirSmeRsp->bssDescription.
+ ieFields) + curLen,
+ psessionEntry->pSchBeaconFrameEnd,
+ (uint32_t) psessionEntry->
+ schBeaconOffsetEnd);
+
+ /* subtracting size of length indicator itself and size of pointer to ieFields */
+ pSirSmeRsp->bssDescription.length =
+ sizeof(tSirBssDescription) - sizeof(uint16_t) -
+ sizeof(uint32_t) + ieLen;
+ /* This is the size of the message, subtracting the size of the pointer to ieFields */
+ size += ieLen - sizeof(uint32_t);
+#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
+ if (psessionEntry->cc_switch_mode
+ != CDF_MCC_TO_SCC_SWITCH_DISABLE) {
+ pSirSmeRsp->HTProfile.
+ htSupportedChannelWidthSet =
+ psessionEntry->htSupportedChannelWidthSet;
+ pSirSmeRsp->HTProfile.htRecommendedTxWidthSet =
+ psessionEntry->htRecommendedTxWidthSet;
+ pSirSmeRsp->HTProfile.htSecondaryChannelOffset =
+ psessionEntry->htSecondaryChannelOffset;
+ pSirSmeRsp->HTProfile.dot11mode =
+ psessionEntry->dot11mode;
+ pSirSmeRsp->HTProfile.htCapability =
+ psessionEntry->htCapability;
+#ifdef WLAN_FEATURE_11AC
+ pSirSmeRsp->HTProfile.vhtCapability =
+ psessionEntry->vhtCapability;
+ pSirSmeRsp->HTProfile.vhtTxChannelWidthSet =
+ psessionEntry->vhtTxChannelWidthSet;
+ pSirSmeRsp->HTProfile.apCenterChan =
+ psessionEntry->ch_center_freq_seg0;
+ pSirSmeRsp->HTProfile.apChanWidth =
+ psessionEntry->ch_width;
+#endif
+ }
+#endif
+ }
+
+ }
+
+ pSirSmeRsp->messageType = msgType;
+ pSirSmeRsp->length = size;
+
+ /* Update SME session Id and transaction Id */
+ pSirSmeRsp->sessionId = smesessionId;
+ pSirSmeRsp->transactionId = smetransactionId;
+ pSirSmeRsp->statusCode = resultCode;
+ if (psessionEntry != NULL)
+ pSirSmeRsp->staId = psessionEntry->staId; /* else it will be always zero smeRsp StaID = 0 */
+
+ mmhMsg.type = msgType;
+ mmhMsg.bodyptr = pSirSmeRsp;
+ mmhMsg.bodyval = 0;
+ if (psessionEntry == NULL) {
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+ } else {
+ MTRACE(mac_trace_msg_tx
+ (pMac, psessionEntry->peSessionId, mmhMsg.type));
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_START_BSS_RSP_EVENT,
+ psessionEntry, (uint16_t) resultCode, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+} /*** end lim_send_sme_start_bss_rsp() ***/
+
+#define LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED 20
+#define LIM_SIZE_OF_EACH_BSS 400 /* this is a rough estimate */
+
+/**
+ * lim_send_sme_scan_rsp() - Send scan response to SME
+ * @pMac: Pointer to Global MAC structure
+ * @length: Indicates length of message
+ * @resultCode: Indicates the result of previously issued
+ * eWNI_SME_SCAN_REQ message
+ * @scan_id: scan identifier
+ *
+ * This function is called by lim_process_sme_req_messages() to send
+ * eWNI_SME_SCAN_RSP message to applications above MAC
+ *
+ * return: None
+ */
+
+void
+lim_send_sme_scan_rsp(tpAniSirGlobal pMac, tSirResultCodes resultCode,
+ uint8_t smesessionId, uint16_t smetranscationId,
+ uint32_t scan_id)
+{
+ lim_log(pMac, LOG1,
+ FL("Sending message SME_SCAN_RSP reasonCode %s scanId %d"),
+ lim_result_code_str(resultCode), scan_id);
+ lim_post_sme_scan_rsp_message(pMac, resultCode, smesessionId,
+ smetranscationId, scan_id);
+}
+
+/**
+ * lim_post_sme_scan_rsp_message()
+ *
+ ***FUNCTION:
+ * This function is called by lim_send_sme_scan_rsp() to send
+ * eWNI_SME_SCAN_RSP message with failed result code
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param length Indicates length of message
+ * @param resultCode failed result code
+ *
+ * @return None
+ */
+
+void
+lim_post_sme_scan_rsp_message(tpAniSirGlobal pMac,
+ tSirResultCodes resultCode, uint8_t smesessionId,
+ uint16_t smetransactionId,
+ uint32_t scan_id)
+{
+ tpSirSmeScanRsp pSirSmeScanRsp;
+ tSirMsgQ mmhMsg;
+
+ lim_log(pMac, LOG1, FL("send SME_SCAN_RSP (reasonCode %s)."),
+ lim_result_code_str(resultCode));
+
+ pSirSmeScanRsp = cdf_mem_malloc(sizeof(tSirSmeScanRsp));
+ if (NULL == pSirSmeScanRsp) {
+ lim_log(pMac, LOGP,
+ FL("AllocateMemory failed for eWNI_SME_SCAN_RSP"));
+ return;
+ }
+ cdf_mem_set((void *)pSirSmeScanRsp, sizeof(tSirSmeScanRsp), 0);
+
+ pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP;
+ pSirSmeScanRsp->statusCode = resultCode;
+
+ /*Update SME session Id and transaction Id */
+ pSirSmeScanRsp->sessionId = smesessionId;
+ pSirSmeScanRsp->transcationId = smetransactionId;
+ pSirSmeScanRsp->scan_id = scan_id;
+
+ mmhMsg.type = eWNI_SME_SCAN_RSP;
+ mmhMsg.bodyptr = pSirSmeScanRsp;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_SCAN_RSP_EVENT, NULL,
+ (uint16_t) resultCode, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+
+} /*** lim_post_sme_scan_rsp_message ***/
+
+#ifdef FEATURE_OEM_DATA_SUPPORT
+
+/**
+ * lim_send_sme_oem_data_rsp()
+ *
+ ***FUNCTION:
+ * This function is called by lim_process_sme_req_messages() to send
+ * eWNI_SME_OEM_DATA_RSP message to applications above MAC
+ * Software.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param pMsgBuf Indicates the mlm message
+ * @param resultCode Indicates the result of previously issued
+ * eWNI_SME_OEM_DATA_RSP message
+ *
+ * @return None
+ */
+
+void lim_send_sme_oem_data_rsp(tpAniSirGlobal pMac, uint32_t *pMsgBuf,
+ tSirResultCodes resultCode)
+{
+ tSirMsgQ mmhMsg;
+ tSirOemDataRsp *pSirSmeOemDataRsp = NULL;
+ tLimMlmOemDataRsp *pMlmOemDataRsp = NULL;
+ uint16_t msgLength;
+
+ /* get the pointer to the mlm message */
+ pMlmOemDataRsp = (tLimMlmOemDataRsp *) (pMsgBuf);
+
+ msgLength = sizeof(tSirOemDataRsp);
+
+ /* now allocate memory for the char buffer */
+ pSirSmeOemDataRsp = cdf_mem_malloc(msgLength);
+ if (NULL == pSirSmeOemDataRsp) {
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for pSirSmeOemDataRsp"));
+ return;
+ }
+#if defined (ANI_LITTLE_BYTE_ENDIAN)
+ sir_store_u16_n((uint8_t *) &pSirSmeOemDataRsp->length, msgLength);
+ sir_store_u16_n((uint8_t *) &pSirSmeOemDataRsp->messageType,
+ eWNI_SME_OEM_DATA_RSP);
+#else
+ pSirSmeOemDataRsp->length = msgLength;
+ pSirSmeOemDataRsp->messageType = eWNI_SME_OEM_DATA_RSP;
+#endif
+
+ cdf_mem_copy(pSirSmeOemDataRsp->oemDataRsp, pMlmOemDataRsp->oemDataRsp,
+ OEM_DATA_RSP_SIZE);
+
+ /* Now free the memory from MLM Rsp Message */
+ cdf_mem_free(pMlmOemDataRsp);
+
+ mmhMsg.type = eWNI_SME_OEM_DATA_RSP;
+ mmhMsg.bodyptr = pSirSmeOemDataRsp;
+ mmhMsg.bodyval = 0;
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+ return;
+} /*** lim_send_sme_oem_data_rsp ***/
+
+#endif
+
+void lim_send_sme_disassoc_deauth_ntf(tpAniSirGlobal pMac,
+ CDF_STATUS status, uint32_t *pCtx)
+{
+ tSirMsgQ mmhMsg;
+ tSirMsgQ *pMsg = (tSirMsgQ *) pCtx;
+
+ mmhMsg.type = pMsg->type;
+ mmhMsg.bodyptr = pMsg;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+}
+
+/**
+ * lim_send_sme_disassoc_ntf()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_DISASSOC_RSP/IND message to host
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * This function is used for sending eWNI_SME_DISASSOC_CNF,
+ * or eWNI_SME_DISASSOC_IND to host depending on
+ * disassociation trigger.
+ *
+ * @param peerMacAddr Indicates the peer MAC addr to which
+ * disassociate was initiated
+ * @param reasonCode Indicates the reason for Disassociation
+ * @param disassocTrigger Indicates the trigger for Disassociation
+ * @param aid Indicates the STAID. This parameter is
+ * present only on AP.
+ *
+ * @return None
+ */
+void
+lim_send_sme_disassoc_ntf(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ tSirResultCodes reasonCode,
+ uint16_t disassocTrigger,
+ uint16_t aid,
+ uint8_t smesessionId,
+ uint16_t smetransactionId, tpPESession psessionEntry)
+{
+
+ uint8_t *pBuf;
+ tSirSmeDisassocRsp *pSirSmeDisassocRsp;
+ tSirSmeDisassocInd *pSirSmeDisassocInd;
+ uint32_t *pMsg;
+ bool failure = false;
+
+ lim_log(pMac, LOG1, FL("Disassoc Ntf with trigger : %d reasonCode: %d"),
+ disassocTrigger, reasonCode);
+
+ switch (disassocTrigger) {
+ case eLIM_PEER_ENTITY_DISASSOC:
+ if (reasonCode != eSIR_SME_STA_NOT_ASSOCIATED) {
+ failure = true;
+ goto error;
+ }
+
+ case eLIM_HOST_DISASSOC:
+ /**
+ * Disassociation response due to
+ * host triggered disassociation
+ */
+
+ pSirSmeDisassocRsp = cdf_mem_malloc(sizeof(tSirSmeDisassocRsp));
+ if (NULL == pSirSmeDisassocRsp) {
+ /* Log error */
+ lim_log(pMac, LOGP, FL("Memory allocation failed"));
+ failure = true;
+ goto error;
+ }
+ lim_log(pMac, LOG1, FL("send eWNI_SME_DISASSOC_RSP with "
+ "retCode: %d for " MAC_ADDRESS_STR),
+ reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
+ pSirSmeDisassocRsp->messageType = eWNI_SME_DISASSOC_RSP;
+ pSirSmeDisassocRsp->length = sizeof(tSirSmeDisassocRsp);
+ /* sessionId */
+ pBuf = (uint8_t *) &pSirSmeDisassocRsp->sessionId;
+ *pBuf = smesessionId;
+ pBuf++;
+
+ /* transactionId */
+ lim_copy_u16(pBuf, smetransactionId);
+ pBuf += sizeof(uint16_t);
+
+ /* statusCode */
+ lim_copy_u32(pBuf, reasonCode);
+ pBuf += sizeof(tSirResultCodes);
+
+ /* peerMacAddr */
+ cdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+ /* Clear Station Stats */
+ /* for sta, it is always 1, IBSS is handled at halInitSta */
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_RSP_EVENT,
+ psessionEntry, (uint16_t) reasonCode, 0);
+#endif
+ pMsg = (uint32_t *) pSirSmeDisassocRsp;
+ break;
+
+ default:
+ /**
+ * Disassociation indication due to Disassociation
+ * frame reception from peer entity or due to
+ * loss of link with peer entity.
+ */
+ pSirSmeDisassocInd = cdf_mem_malloc(sizeof(tSirSmeDisassocInd));
+ if (NULL == pSirSmeDisassocInd) {
+ /* Log error */
+ lim_log(pMac, LOGP, FL("Memory allocation failed"));
+ failure = true;
+ goto error;
+ }
+ lim_log(pMac, LOG1, FL("send eWNI_SME_DISASSOC_IND with "
+ "retCode: %d for " MAC_ADDRESS_STR),
+ reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
+ pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND;
+ pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd);
+
+ /* Update SME session Id and Transaction Id */
+ pSirSmeDisassocInd->sessionId = smesessionId;
+ pSirSmeDisassocInd->transactionId = smetransactionId;
+ pSirSmeDisassocInd->reasonCode = reasonCode;
+ pBuf = (uint8_t *) &pSirSmeDisassocInd->statusCode;
+
+ lim_copy_u32(pBuf, reasonCode);
+ pBuf += sizeof(tSirResultCodes);
+
+ cdf_mem_copy(pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+ cdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT,
+ psessionEntry, (uint16_t) reasonCode, 0);
+#endif
+ pMsg = (uint32_t *) pSirSmeDisassocInd;
+
+ break;
+ }
+
+error:
+ /* Delete the PE session Created */
+ if ((psessionEntry != NULL) &&
+ (LIM_IS_STA_ROLE(psessionEntry) ||
+ LIM_IS_BT_AMP_STA_ROLE(psessionEntry))) {
+ pe_delete_session(pMac, psessionEntry);
+ }
+
+ if (false == failure)
+ lim_send_sme_disassoc_deauth_ntf(pMac, CDF_STATUS_SUCCESS,
+ (uint32_t *) pMsg);
+} /*** end lim_send_sme_disassoc_ntf() ***/
+
+/** -----------------------------------------------------------------
+ \brief lim_send_sme_disassoc_ind() - sends SME_DISASSOC_IND
+
+ After receiving disassociation frame from peer entity, this
+ function sends a eWNI_SME_DISASSOC_IND to SME with a specific
+ reason code.
+
+ \param pMac - global mac structure
+ \param pStaDs - station dph hash node
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+void
+lim_send_sme_disassoc_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpPESession psessionEntry)
+{
+ tSirMsgQ mmhMsg;
+ tSirSmeDisassocInd *pSirSmeDisassocInd;
+
+ pSirSmeDisassocInd = cdf_mem_malloc(sizeof(tSirSmeDisassocInd));
+ if (NULL == pSirSmeDisassocInd) {
+ lim_log(pMac, LOGP,
+ FL("AllocateMemory failed for eWNI_SME_DISASSOC_IND"));
+ return;
+ }
+
+ pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND;
+ pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd);
+
+ pSirSmeDisassocInd->sessionId = psessionEntry->smeSessionId;
+ pSirSmeDisassocInd->transactionId = psessionEntry->transactionId;
+ pSirSmeDisassocInd->statusCode = pStaDs->mlmStaContext.disassocReason;
+ pSirSmeDisassocInd->reasonCode = pStaDs->mlmStaContext.disassocReason;
+
+ cdf_mem_copy(pSirSmeDisassocInd->bssId, psessionEntry->bssId,
+ sizeof(tSirMacAddr));
+
+ cdf_mem_copy(pSirSmeDisassocInd->peerMacAddr, pStaDs->staAddr,
+ sizeof(tSirMacAddr));
+
+ pSirSmeDisassocInd->staId = pStaDs->staIndex;
+
+ mmhMsg.type = eWNI_SME_DISASSOC_IND;
+ mmhMsg.bodyptr = pSirSmeDisassocInd;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT, psessionEntry,
+ 0, (uint16_t) pStaDs->mlmStaContext.disassocReason);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+} /*** end lim_send_sme_disassoc_ind() ***/
+
+/** -----------------------------------------------------------------
+ \brief lim_send_sme_deauth_ind() - sends SME_DEAUTH_IND
+
+ After receiving deauthentication frame from peer entity, this
+ function sends a eWNI_SME_DEAUTH_IND to SME with a specific
+ reason code.
+
+ \param pMac - global mac structure
+ \param pStaDs - station dph hash node
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+void
+lim_send_sme_deauth_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpPESession psessionEntry)
+{
+ tSirMsgQ mmhMsg;
+ tSirSmeDeauthInd *pSirSmeDeauthInd;
+
+ pSirSmeDeauthInd = cdf_mem_malloc(sizeof(tSirSmeDeauthInd));
+ if (NULL == pSirSmeDeauthInd) {
+ lim_log(pMac, LOGP,
+ FL("AllocateMemory failed for eWNI_SME_DEAUTH_IND "));
+ return;
+ }
+
+ pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND;
+ pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd);
+
+ pSirSmeDeauthInd->sessionId = psessionEntry->smeSessionId;
+ pSirSmeDeauthInd->transactionId = psessionEntry->transactionId;
+ if (eSIR_INFRA_AP_MODE == psessionEntry->bssType) {
+ pSirSmeDeauthInd->statusCode =
+ (tSirResultCodes) pStaDs->mlmStaContext.cleanupTrigger;
+ } else {
+ /* Need to indicatet he reascon code over the air */
+ pSirSmeDeauthInd->statusCode =
+ (tSirResultCodes) pStaDs->mlmStaContext.disassocReason;
+ }
+ /* BSSID */
+ cdf_mem_copy(pSirSmeDeauthInd->bssId, psessionEntry->bssId,
+ sizeof(tSirMacAddr));
+ /* peerMacAddr */
+ cdf_mem_copy(pSirSmeDeauthInd->peerMacAddr, pStaDs->staAddr,
+ sizeof(tSirMacAddr));
+ pSirSmeDeauthInd->reasonCode = pStaDs->mlmStaContext.disassocReason;
+
+ pSirSmeDeauthInd->staId = pStaDs->staIndex;
+
+ mmhMsg.type = eWNI_SME_DEAUTH_IND;
+ mmhMsg.bodyptr = pSirSmeDeauthInd;
+ mmhMsg.bodyval = 0;
+
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT, psessionEntry,
+ 0, pStaDs->mlmStaContext.cleanupTrigger);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+} /*** end lim_send_sme_deauth_ind() ***/
+
+#ifdef FEATURE_WLAN_TDLS
+/**
+ * lim_send_sme_tdls_del_sta_ind()
+ *
+ ***FUNCTION:
+ * This function is called to send the TDLS STA context deletion to SME.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to global MAC structure
+ * @param pStaDs - Pointer to internal STA Datastructure
+ * @param psessionEntry - Pointer to the session entry
+ * @param reasonCode - Reason for TDLS sta deletion
+ * @return None
+ */
+void
+lim_send_sme_tdls_del_sta_ind(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
+ tpPESession psessionEntry, uint16_t reasonCode)
+{
+ tSirMsgQ mmhMsg;
+ tSirTdlsDelStaInd *pSirTdlsDelStaInd;
+
+ pSirTdlsDelStaInd = cdf_mem_malloc(sizeof(tSirTdlsDelStaInd));
+ if (NULL == pSirTdlsDelStaInd) {
+ lim_log(pMac, LOGP,
+ FL
+ ("AllocateMemory failed for eWNI_SME_TDLS_DEL_STA_IND "));
+ return;
+ }
+ /* messageType */
+ pSirTdlsDelStaInd->messageType = eWNI_SME_TDLS_DEL_STA_IND;
+ pSirTdlsDelStaInd->length = sizeof(tSirTdlsDelStaInd);
+
+ /* sessionId */
+ pSirTdlsDelStaInd->sessionId = psessionEntry->smeSessionId;
+
+ /* peerMacAddr */
+ cdf_mem_copy(pSirTdlsDelStaInd->peerMac, pStaDs->staAddr,
+ sizeof(tSirMacAddr));
+
+ /* staId */
+ lim_copy_u16((uint8_t *) (&pSirTdlsDelStaInd->staId),
+ (uint16_t) pStaDs->staIndex);
+
+ /* reasonCode */
+ lim_copy_u16((uint8_t *) (&pSirTdlsDelStaInd->reasonCode), reasonCode);
+
+ mmhMsg.type = eWNI_SME_TDLS_DEL_STA_IND;
+ mmhMsg.bodyptr = pSirTdlsDelStaInd;
+ mmhMsg.bodyval = 0;
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+} /*** end lim_send_sme_tdls_del_sta_ind() ***/
+
+/**
+ * lim_send_sme_tdls_delete_all_peer_ind()
+ *
+ ***FUNCTION:
+ * This function is called to send the eWNI_SME_TDLS_DEL_ALL_PEER_IND
+ * message to SME.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to global MAC structure
+ * @param psessionEntry - Pointer to the session entry
+ * @return None
+ */
+void
+lim_send_sme_tdls_delete_all_peer_ind(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+ tSirMsgQ mmhMsg;
+ tSirTdlsDelAllPeerInd *pSirTdlsDelAllPeerInd;
+
+ pSirTdlsDelAllPeerInd = cdf_mem_malloc(sizeof(tSirTdlsDelAllPeerInd));
+ if (NULL == pSirTdlsDelAllPeerInd) {
+ lim_log(pMac, LOGP,
+ FL
+ ("AllocateMemory failed for eWNI_SME_TDLS_DEL_ALL_PEER_IND"));
+ return;
+ }
+ /* messageType */
+ pSirTdlsDelAllPeerInd->messageType = eWNI_SME_TDLS_DEL_ALL_PEER_IND;
+ pSirTdlsDelAllPeerInd->length = sizeof(tSirTdlsDelAllPeerInd);
+
+ /* sessionId */
+ pSirTdlsDelAllPeerInd->sessionId = psessionEntry->smeSessionId;
+
+ mmhMsg.type = eWNI_SME_TDLS_DEL_ALL_PEER_IND;
+ mmhMsg.bodyptr = pSirTdlsDelAllPeerInd;
+ mmhMsg.bodyval = 0;
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+} /*** end lim_send_sme_tdls_delete_all_peer_ind() ***/
+
+/**
+ * lim_send_sme_mgmt_tx_completion()
+ *
+ ***FUNCTION:
+ * This function is called to send the eWNI_SME_MGMT_FRM_TX_COMPLETION_IND
+ * message to SME.
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac - Pointer to global MAC structure
+ * @param psessionEntry - Pointer to the session entry
+ * @param txCompleteStatus - TX Complete Status of Mgmt Frames
+ * @return None
+ */
+void
+lim_send_sme_mgmt_tx_completion(tpAniSirGlobal pMac,
+ tpPESession psessionEntry, uint32_t txCompleteStatus)
+{
+ tSirMsgQ mmhMsg;
+ tSirMgmtTxCompletionInd *pSirMgmtTxCompletionInd;
+
+ pSirMgmtTxCompletionInd =
+ cdf_mem_malloc(sizeof(tSirMgmtTxCompletionInd));
+ if (NULL == pSirMgmtTxCompletionInd) {
+ lim_log(pMac, LOGP,
+ FL
+ ("AllocateMemory failed for eWNI_SME_MGMT_FRM_TX_COMPLETION_IND"));
+ return;
+ }
+ /* messageType */
+ pSirMgmtTxCompletionInd->messageType =
+ eWNI_SME_MGMT_FRM_TX_COMPLETION_IND;
+ pSirMgmtTxCompletionInd->length = sizeof(tSirMgmtTxCompletionInd);
+
+ /* sessionId */
+ pSirMgmtTxCompletionInd->sessionId = psessionEntry->smeSessionId;
+
+ pSirMgmtTxCompletionInd->txCompleteStatus = txCompleteStatus;
+
+ mmhMsg.type = eWNI_SME_MGMT_FRM_TX_COMPLETION_IND;
+ mmhMsg.bodyptr = pSirMgmtTxCompletionInd;
+ mmhMsg.bodyval = 0;
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+} /*** end lim_send_sme_tdls_delete_all_peer_ind() ***/
+
+void lim_send_sme_tdls_event_notify(tpAniSirGlobal pMac, uint16_t msgType,
+ void *events)
+{
+ tSirMsgQ mmhMsg;
+
+ switch (msgType) {
+ case SIR_HAL_TDLS_SHOULD_DISCOVER:
+ mmhMsg.type = eWNI_SME_TDLS_SHOULD_DISCOVER;
+ break;
+ case SIR_HAL_TDLS_SHOULD_TEARDOWN:
+ mmhMsg.type = eWNI_SME_TDLS_SHOULD_TEARDOWN;
+ break;
+ case SIR_HAL_TDLS_PEER_DISCONNECTED:
+ mmhMsg.type = eWNI_SME_TDLS_PEER_DISCONNECTED;
+ break;
+ }
+
+ mmhMsg.bodyptr = events;
+ mmhMsg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+}
+#endif /* FEATURE_WLAN_TDLS */
+
+/**
+ * lim_send_sme_deauth_ntf()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_DISASSOC_RSP/IND message to host
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * This function is used for sending eWNI_SME_DEAUTH_CNF or
+ * eWNI_SME_DEAUTH_IND to host depending on deauthentication trigger.
+ *
+ * @param peerMacAddr Indicates the peer MAC addr to which
+ * deauthentication was initiated
+ * @param reasonCode Indicates the reason for Deauthetication
+ * @param deauthTrigger Indicates the trigger for Deauthetication
+ * @param aid Indicates the STAID. This parameter is present
+ * only on AP.
+ *
+ * @return None
+ */
+void
+lim_send_sme_deauth_ntf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ tSirResultCodes reasonCode, uint16_t deauthTrigger,
+ uint16_t aid, uint8_t smesessionId,
+ uint16_t smetransactionId)
+{
+ uint8_t *pBuf;
+ tSirSmeDeauthRsp *pSirSmeDeauthRsp;
+ tSirSmeDeauthInd *pSirSmeDeauthInd;
+ tpPESession psessionEntry;
+ uint8_t sessionId;
+ uint32_t *pMsg;
+
+ psessionEntry = pe_find_session_by_bssid(pMac, peerMacAddr, &sessionId);
+ switch (deauthTrigger) {
+ case eLIM_PEER_ENTITY_DEAUTH:
+ return;
+
+ case eLIM_HOST_DEAUTH:
+ /**
+ * Deauthentication response to host triggered
+ * deauthentication.
+ */
+ pSirSmeDeauthRsp = cdf_mem_malloc(sizeof(tSirSmeDeauthRsp));
+ if (NULL == pSirSmeDeauthRsp) {
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for eWNI_SME_DEAUTH_RSP"));
+
+ return;
+ }
+ lim_log(pMac, LOG1, FL("send eWNI_SME_DEAUTH_RSP with "
+ "retCode: %d for" MAC_ADDRESS_STR),
+ reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
+ pSirSmeDeauthRsp->messageType = eWNI_SME_DEAUTH_RSP;
+ pSirSmeDeauthRsp->length = sizeof(tSirSmeDeauthRsp);
+ pSirSmeDeauthRsp->statusCode = reasonCode;
+ pSirSmeDeauthRsp->sessionId = smesessionId;
+ pSirSmeDeauthRsp->transactionId = smetransactionId;
+
+ pBuf = (uint8_t *) pSirSmeDeauthRsp->peerMacAddr;
+ cdf_mem_copy(pBuf, peerMacAddr, sizeof(tSirMacAddr));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_RSP_EVENT,
+ psessionEntry, 0, (uint16_t) reasonCode);
+#endif
+ pMsg = (uint32_t *) pSirSmeDeauthRsp;
+
+ break;
+
+ default:
+ /**
+ * Deauthentication indication due to Deauthentication
+ * frame reception from peer entity or due to
+ * loss of link with peer entity.
+ */
+ pSirSmeDeauthInd = cdf_mem_malloc(sizeof(tSirSmeDeauthInd));
+ if (NULL == pSirSmeDeauthInd) {
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for eWNI_SME_DEAUTH_Ind"));
+
+ return;
+ }
+ lim_log(pMac, LOG1, FL("send eWNI_SME_DEAUTH_IND with "
+ "retCode: %d for " MAC_ADDRESS_STR),
+ reasonCode, MAC_ADDR_ARRAY(peerMacAddr));
+ pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND;
+ pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd);
+ pSirSmeDeauthInd->reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON;
+
+ /* sessionId */
+ pBuf = (uint8_t *) &pSirSmeDeauthInd->sessionId;
+ *pBuf++ = smesessionId;
+
+ /* transaction ID */
+ lim_copy_u16(pBuf, smetransactionId);
+ pBuf += sizeof(uint16_t);
+
+ /* status code */
+ lim_copy_u32(pBuf, reasonCode);
+ pBuf += sizeof(tSirResultCodes);
+
+ /* bssId */
+ cdf_mem_copy(pBuf, psessionEntry->bssId, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+ /* peerMacAddr */
+ cdf_mem_copy(pSirSmeDeauthInd->peerMacAddr, peerMacAddr,
+ sizeof(tSirMacAddr));
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT,
+ psessionEntry, 0, (uint16_t) reasonCode);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+ pMsg = (uint32_t *) pSirSmeDeauthInd;
+
+ break;
+ }
+
+ /*Delete the PE session created */
+ if (psessionEntry != NULL) {
+ pe_delete_session(pMac, psessionEntry);
+ }
+
+ lim_send_sme_disassoc_deauth_ntf(pMac, CDF_STATUS_SUCCESS,
+ (uint32_t *) pMsg);
+
+} /*** end lim_send_sme_deauth_ntf() ***/
+
+/**
+ * lim_send_sme_wm_status_change_ntf() - Send Notification
+ * @mac_ctx: Global MAC Context
+ * @status_change_code: Indicates the change in the wireless medium.
+ * @status_change_info: Indicates the information associated with
+ * change in the wireless medium.
+ * @info_len: Indicates the length of status change information
+ * being sent.
+ * @session_id SessionID
+ *
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_WM_STATUS_CHANGE_NTF message to host.
+ *
+ * Return: None
+ */
+void
+lim_send_sme_wm_status_change_ntf(tpAniSirGlobal mac_ctx,
+ tSirSmeStatusChangeCode status_change_code,
+ uint32_t *status_change_info, uint16_t info_len, uint8_t session_id)
+{
+ tSirMsgQ msg;
+ tSirSmeWmStatusChangeNtf *wm_status_change_ntf;
+
+ wm_status_change_ntf = cdf_mem_malloc(sizeof(tSirSmeWmStatusChangeNtf));
+ if (NULL == wm_status_change_ntf) {
+ lim_log(mac_ctx, LOGE,
+ FL("Mem Alloc failed - eWNI_SME_WM_STATUS_CHANGE_NTF"));
+ return;
+ }
+
+ msg.type = eWNI_SME_WM_STATUS_CHANGE_NTF;
+ msg.bodyval = 0;
+ msg.bodyptr = wm_status_change_ntf;
+
+ switch (status_change_code) {
+ case eSIR_SME_RADAR_DETECTED:
+ break;
+ default:
+ wm_status_change_ntf->messageType =
+ eWNI_SME_WM_STATUS_CHANGE_NTF;
+ wm_status_change_ntf->statusChangeCode = status_change_code;
+ wm_status_change_ntf->length = sizeof(tSirSmeWmStatusChangeNtf);
+ wm_status_change_ntf->sessionId = session_id;
+ if (sizeof(wm_status_change_ntf->statusChangeInfo) >=
+ info_len) {
+ cdf_mem_copy(
+ (uint8_t *) &wm_status_change_ntf->statusChangeInfo,
+ (uint8_t *) status_change_info, info_len);
+ }
+ lim_log(mac_ctx, LOGE,
+ FL("**---** StatusChg: code 0x%x, length %d **---**"),
+ status_change_code, info_len);
+ break;
+ }
+
+ MTRACE(mac_trace_msg_tx(mac_ctx, session_id, msg.type));
+ if (eSIR_SUCCESS != lim_sys_process_mmh_msg_api(mac_ctx, &msg, ePROT)) {
+ cdf_mem_free(wm_status_change_ntf);
+ lim_log(mac_ctx, LOGP,
+ FL("lim_sys_process_mmh_msg_api failed"));
+ }
+
+} /*** end lim_send_sme_wm_status_change_ntf() ***/
+
+/**
+ * lim_send_sme_set_context_rsp()
+ *
+ ***FUNCTION:
+ * This function is called by limProcessSmeMessages() to send
+ * eWNI_SME_SETCONTEXT_RSP message to host
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param peerMacAddr Indicates the peer MAC addr to which
+ * setContext was performed
+ * @param aid Indicates the aid corresponding to the peer MAC
+ * address
+ * @param resultCode Indicates the result of previously issued
+ * eWNI_SME_SETCONTEXT_RSP message
+ *
+ * @return None
+ */
+void
+lim_send_sme_set_context_rsp(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr, uint16_t aid,
+ tSirResultCodes resultCode,
+ tpPESession psessionEntry, uint8_t smesessionId,
+ uint16_t smetransactionId)
+{
+
+ uint8_t *pBuf;
+ tSirMsgQ mmhMsg;
+ tSirSmeSetContextRsp *pSirSmeSetContextRsp;
+
+ pSirSmeSetContextRsp = cdf_mem_malloc(sizeof(tSirSmeSetContextRsp));
+ if (NULL == pSirSmeSetContextRsp) {
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for SmeSetContextRsp"));
+
+ return;
+ }
+
+ pSirSmeSetContextRsp->messageType = eWNI_SME_SETCONTEXT_RSP;
+ pSirSmeSetContextRsp->length = sizeof(tSirSmeSetContextRsp);
+ pSirSmeSetContextRsp->statusCode = resultCode;
+
+ pBuf = pSirSmeSetContextRsp->peerMacAddr;
+
+ cdf_mem_copy(pBuf, (uint8_t *) peerMacAddr, sizeof(tSirMacAddr));
+ pBuf += sizeof(tSirMacAddr);
+
+ /* Update SME session and transaction Id */
+ pSirSmeSetContextRsp->sessionId = smesessionId;
+ pSirSmeSetContextRsp->transactionId = smetransactionId;
+
+ mmhMsg.type = eWNI_SME_SETCONTEXT_RSP;
+ mmhMsg.bodyptr = pSirSmeSetContextRsp;
+ mmhMsg.bodyval = 0;
+ if (NULL == psessionEntry) {
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+ } else {
+ MTRACE(mac_trace_msg_tx
+ (pMac, psessionEntry->peSessionId, mmhMsg.type));
+ }
+
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT,
+ psessionEntry, (uint16_t) resultCode, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+} /*** end lim_send_sme_set_context_rsp() ***/
+
+/**
+ * lim_send_sme_neighbor_bss_ind()
+ *
+ ***FUNCTION:
+ * This function is called by lim_lookup_nadd_hash_entry() to send
+ * eWNI_SME_NEIGHBOR_BSS_IND message to host
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * This function is used for sending eWNI_SME_NEIGHBOR_BSS_IND to
+ * host upon detecting new BSS during background scanning if CFG
+ * option is enabled for sending such indication
+ *
+ * @param pMac - Pointer to Global MAC structure
+ * @return None
+ */
+
+void
+lim_send_sme_neighbor_bss_ind(tpAniSirGlobal pMac, tLimScanResultNode *pBssDescr)
+{
+ tSirMsgQ msgQ;
+ uint32_t val;
+ tSirSmeNeighborBssInd *pNewBssInd;
+
+ if ((pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_WT_SCAN_STATE) ||
+ ((pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_WT_SCAN_STATE) &&
+ pMac->lim.gLimRspReqd)) {
+ /* LIM is not in background scan state OR */
+ /* current scan is initiated by HDD. */
+ /* No need to send new BSS indication to HDD */
+ return;
+ }
+
+ if (wlan_cfg_get_int(pMac, WNI_CFG_NEW_BSS_FOUND_IND, &val) !=
+ eSIR_SUCCESS) {
+ lim_log(pMac, LOGP,
+ FL("could not get NEIGHBOR_BSS_IND from CFG"));
+
+ return;
+ }
+
+ if (val == 0)
+ return;
+
+ /**
+ * Need to indicate new BSSs found during
+ * background scanning to host.
+ * Allocate buffer for sending indication.
+ * Length of buffer is length of BSS description
+ * and length of header itself
+ */
+ val = pBssDescr->bssDescription.length + sizeof(uint16_t) +
+ sizeof(uint32_t) + sizeof(uint8_t);
+ pNewBssInd = cdf_mem_malloc(val);
+ if (NULL == pNewBssInd) {
+ /* Log error */
+ lim_log(pMac, LOGP,
+ FL
+ ("call to AllocateMemory failed for eWNI_SME_NEIGHBOR_BSS_IND"));
+
+ return;
+ }
+
+ pNewBssInd->messageType = eWNI_SME_NEIGHBOR_BSS_IND;
+ pNewBssInd->length = (uint16_t) val;
+ pNewBssInd->sessionId = 0;
+
+ cdf_mem_copy((uint8_t *) pNewBssInd->bssDescription,
+ (uint8_t *) &pBssDescr->bssDescription,
+ pBssDescr->bssDescription.length + sizeof(uint16_t));
+
+ msgQ.type = eWNI_SME_NEIGHBOR_BSS_IND;
+ msgQ.bodyptr = pNewBssInd;
+ msgQ.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msgQ.type));
+ lim_sys_process_mmh_msg_api(pMac, &msgQ, ePROT);
+} /*** end lim_send_sme_neighbor_bss_ind() ***/
+
+/** -----------------------------------------------------------------
+ \brief lim_send_sme_addts_rsp() - sends SME ADDTS RSP
+ \ This function sends a eWNI_SME_ADDTS_RSP to SME.
+ \ SME only looks at rc and tspec field.
+ \param pMac - global mac structure
+ \param rspReqd - is SmeAddTsRsp required
+ \param status - status code of SME_ADD_TS_RSP
+ \return tspec
+ \sa
+ ----------------------------------------------------------------- */
+void
+lim_send_sme_addts_rsp(tpAniSirGlobal pMac, uint8_t rspReqd, uint32_t status,
+ tpPESession psessionEntry, tSirMacTspecIE tspec,
+ uint8_t smesessionId, uint16_t smetransactionId)
+{
+ tpSirAddtsRsp rsp;
+ tSirMsgQ mmhMsg;
+
+ if (!rspReqd)
+ return;
+
+ rsp = cdf_mem_malloc(sizeof(tSirAddtsRsp));
+ if (NULL == rsp) {
+ lim_log(pMac, LOGP, FL("AllocateMemory failed for ADDTS_RSP"));
+ return;
+ }
+
+ cdf_mem_set((uint8_t *) rsp, sizeof(*rsp), 0);
+ rsp->messageType = eWNI_SME_ADDTS_RSP;
+ rsp->rc = status;
+ rsp->rsp.status = (enum eSirMacStatusCodes)status;
+ rsp->rsp.tspec = tspec;
+ /* Update SME session Id and transcation Id */
+ rsp->sessionId = smesessionId;
+ rsp->transactionId = smetransactionId;
+
+ mmhMsg.type = eWNI_SME_ADDTS_RSP;
+ mmhMsg.bodyptr = rsp;
+ mmhMsg.bodyval = 0;
+ if (NULL == psessionEntry) {
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+ } else {
+ MTRACE(mac_trace_msg_tx
+ (pMac, psessionEntry->peSessionId, mmhMsg.type));
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_ADDTS_RSP_EVENT, psessionEntry, 0,
+ 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+}
+
+void
+lim_send_sme_delts_rsp(tpAniSirGlobal pMac, tpSirDeltsReq delts, uint32_t status,
+ tpPESession psessionEntry, uint8_t smesessionId,
+ uint16_t smetransactionId)
+{
+ tpSirDeltsRsp rsp;
+ tSirMsgQ mmhMsg;
+
+ lim_log(pMac, LOGW, "SendSmeDeltsRsp (aid %d, tsid %d, up %d) status %d",
+ delts->aid,
+ delts->req.tsinfo.traffic.tsid,
+ delts->req.tsinfo.traffic.userPrio, status);
+ if (!delts->rspReqd)
+ return;
+
+ rsp = cdf_mem_malloc(sizeof(tSirDeltsRsp));
+ if (NULL == rsp) {
+ /* Log error */
+ lim_log(pMac, LOGP, FL("AllocateMemory failed for DELTS_RSP"));
+ return;
+ }
+ cdf_mem_set((uint8_t *) rsp, sizeof(*rsp), 0);
+
+ if (psessionEntry != NULL) {
+
+ rsp->aid = delts->aid;
+ cdf_mem_copy((uint8_t *) &rsp->macAddr[0],
+ (uint8_t *) &delts->macAddr[0], 6);
+ cdf_mem_copy((uint8_t *) &rsp->rsp, (uint8_t *) &delts->req,
+ sizeof(tSirDeltsReqInfo));
+ }
+
+ rsp->messageType = eWNI_SME_DELTS_RSP;
+ rsp->rc = status;
+
+ /* Update SME session Id and transcation Id */
+ rsp->sessionId = smesessionId;
+ rsp->transactionId = smetransactionId;
+
+ mmhMsg.type = eWNI_SME_DELTS_RSP;
+ mmhMsg.bodyptr = rsp;
+ mmhMsg.bodyval = 0;
+ if (NULL == psessionEntry) {
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+ } else {
+ MTRACE(mac_trace_msg_tx
+ (pMac, psessionEntry->peSessionId, mmhMsg.type));
+ }
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DELTS_RSP_EVENT, psessionEntry,
+ (uint16_t) status, 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+}
+
+void
+lim_send_sme_delts_ind(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts, uint16_t aid,
+ tpPESession psessionEntry)
+{
+ tpSirDeltsRsp rsp;
+ tSirMsgQ mmhMsg;
+
+ lim_log(pMac, LOGW, "SendSmeDeltsInd (aid %d, tsid %d, up %d)",
+ aid, delts->tsinfo.traffic.tsid, delts->tsinfo.traffic.userPrio);
+
+ rsp = cdf_mem_malloc(sizeof(tSirDeltsRsp));
+ if (NULL == rsp) {
+ /* Log error */
+ lim_log(pMac, LOGP, FL("AllocateMemory failed for DELTS_IND"));
+ return;
+ }
+ cdf_mem_set((uint8_t *) rsp, sizeof(*rsp), 0);
+
+ rsp->messageType = eWNI_SME_DELTS_IND;
+ rsp->rc = eSIR_SUCCESS;
+ rsp->aid = aid;
+ cdf_mem_copy((uint8_t *) &rsp->rsp, (uint8_t *) delts, sizeof(*delts));
+
+ /* Update SME session Id and SME transaction Id */
+
+ rsp->sessionId = psessionEntry->smeSessionId;
+ rsp->transactionId = psessionEntry->transactionId;
+
+ mmhMsg.type = eWNI_SME_DELTS_IND;
+ mmhMsg.bodyptr = rsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, mmhMsg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
+ lim_diag_event_report(pMac, WLAN_PE_DIAG_DELTS_IND_EVENT, psessionEntry, 0,
+ 0);
+#endif /* FEATURE_WLAN_DIAG_SUPPORT */
+
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+}
+
+/**
+ * lim_send_sme_pe_statistics_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to send 802.11 statistics response to HDD.
+ * This function posts the result back to HDD. This is a response to
+ * HDD's request for statistics.
+ *
+ ***PARAMS:
+ *
+ ***LOGIC:
+ *
+ ***ASSUMPTIONS:
+ * NA
+ *
+ ***NOTE:
+ * NA
+ *
+ * @param pMac Pointer to Global MAC structure
+ * @param p80211Stats Statistics sent in response
+ * @param resultCode TODO:
+ *
+ *
+ * @return none
+ */
+
+void
+lim_send_sme_pe_statistics_rsp(tpAniSirGlobal pMac, uint16_t msgType, void *stats)
+{
+ tSirMsgQ mmhMsg;
+ uint8_t sessionId;
+ tAniGetPEStatsRsp *pPeStats = (tAniGetPEStatsRsp *) stats;
+ tpPESession pPeSessionEntry;
+
+ /* Get the Session Id based on Sta Id */
+ pPeSessionEntry =
+ pe_find_session_by_sta_id(pMac, pPeStats->staId, &sessionId);
+
+ /* Fill the Session Id */
+ if (NULL != pPeSessionEntry) {
+ /* Fill the Session Id */
+ pPeStats->sessionId = pPeSessionEntry->smeSessionId;
+ }
+
+ pPeStats->msgType = eWNI_SME_GET_STATISTICS_RSP;
+
+ /* msgType should be WMA_GET_STATISTICS_RSP */
+ mmhMsg.type = eWNI_SME_GET_STATISTICS_RSP;
+
+ mmhMsg.bodyptr = stats;
+ mmhMsg.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, mmhMsg.type));
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+ return;
+
+} /*** end lim_send_sme_pe_statistics_rsp() ***/
+
+#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
+/**
+ * lim_send_sme_pe_ese_tsm_rsp()
+ *
+ ***FUNCTION:
+ * This function is called to send tsm stats response to HDD.
+ * This function posts the result back to HDD. This is a response to
+ * HDD's request to get tsm stats.
+ *
+ ***PARAMS:
+ * @param pMac - Pointer to global pMac structure
+ * @param pStats - Pointer to TSM Stats
+ *
+ * @return none
+ */
+
+void lim_send_sme_pe_ese_tsm_rsp(tpAniSirGlobal pMac, tAniGetTsmStatsRsp *pStats)
+{
+ tSirMsgQ mmhMsg;
+ uint8_t sessionId;
+ tAniGetTsmStatsRsp *pPeStats = (tAniGetTsmStatsRsp *) pStats;
+ tpPESession pPeSessionEntry = NULL;
+
+ /* Get the Session Id based on Sta Id */
+ pPeSessionEntry =
+ pe_find_session_by_sta_id(pMac, pPeStats->staId, &sessionId);
+
+ /* Fill the Session Id */
+ if (NULL != pPeSessionEntry) {
+ /* Fill the Session Id */
+ pPeStats->sessionId = pPeSessionEntry->smeSessionId;
+ } else {
+ PELOGE(lim_log
+ (pMac, LOGE, FL("Session not found for the Sta id(%d)"),
+ pPeStats->staId);
+ )
+ return;
+ }
+
+ pPeStats->msgType = eWNI_SME_GET_TSM_STATS_RSP;
+ pPeStats->tsmMetrics.RoamingCount
+ = pPeSessionEntry->eseContext.tsm.tsmMetrics.RoamingCount;
+ pPeStats->tsmMetrics.RoamingDly
+ = pPeSessionEntry->eseContext.tsm.tsmMetrics.RoamingDly;
+
+ mmhMsg.type = eWNI_SME_GET_TSM_STATS_RSP;
+ mmhMsg.bodyptr = pStats;
+ mmhMsg.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(pMac, sessionId, mmhMsg.type));
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+ return;
+} /*** end lim_send_sme_pe_ese_tsm_rsp() ***/
+
+#endif /* FEATURE_WLAN_ESE) && FEATURE_WLAN_ESE_UPLOAD */
+
+void
+lim_send_sme_ibss_peer_ind(tpAniSirGlobal pMac,
+ tSirMacAddr peerMacAddr,
+ uint16_t staIndex,
+ uint8_t ucastIdx,
+ uint8_t bcastIdx,
+ uint8_t *beacon,
+ uint16_t beaconLen, uint16_t msgType, uint8_t sessionId)
+{
+ tSirMsgQ mmhMsg;
+ tSmeIbssPeerInd *pNewPeerInd;
+
+ pNewPeerInd = cdf_mem_malloc(sizeof(tSmeIbssPeerInd) + beaconLen);
+ if (NULL == pNewPeerInd) {
+ PELOGE(lim_log(pMac, LOGE, FL("Failed to allocate memory"));)
+ return;
+ }
+
+ cdf_mem_set((void *)pNewPeerInd, (sizeof(tSmeIbssPeerInd) + beaconLen),
+ 0);
+
+ cdf_mem_copy((uint8_t *) pNewPeerInd->peerAddr,
+ peerMacAddr, sizeof(tSirMacAddr));
+ pNewPeerInd->staId = staIndex;
+ pNewPeerInd->ucastSig = ucastIdx;
+ pNewPeerInd->bcastSig = bcastIdx;
+ pNewPeerInd->mesgLen = sizeof(tSmeIbssPeerInd) + beaconLen;
+ pNewPeerInd->mesgType = msgType;
+ pNewPeerInd->sessionId = sessionId;
+
+ if (beacon != NULL) {
+ cdf_mem_copy((void *)((uint8_t *) pNewPeerInd +
+ sizeof(tSmeIbssPeerInd)), (void *)beacon,
+ beaconLen);
+ }
+
+ mmhMsg.type = msgType;
+ mmhMsg.bodyptr = pNewPeerInd;
+ MTRACE(mac_trace_msg_tx(pMac, sessionId, mmhMsg.type));
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+}
+
+/**
+ * lim_handle_csa_offload_msg() - Handle CSA offload message
+ * @mac_ctx: pointer to global adapter context
+ * @msg: Message pointer.
+ *
+ * Return: None
+ */
+void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
+{
+ tpPESession session_entry;
+ tSirMsgQ mmh_msg;
+ tpCSAOffloadParams csa_params = (tpCSAOffloadParams) (msg->bodyptr);
+ tpSmeCsaOffloadInd csa_offload_ind;
+ tpDphHashNode sta_ds = NULL;
+ uint8_t session_id;
+ uint16_t aid = 0;
+ tLimWiderBWChannelSwitchInfo *chnl_switch_info = NULL;
+
+ if (!csa_params) {
+ lim_log(mac_ctx, LOGE, FL("limMsgQ body ptr is NULL"));
+ return;
+ }
+
+ session_entry =
+ pe_find_session_by_bssid(mac_ctx,
+ csa_params->bssId, &session_id);
+ if (!session_entry) {
+ lim_log(mac_ctx, LOGE,
+ FL("Session does not exist"));
+ goto err;
+ }
+
+ sta_ds = dph_lookup_hash_entry(mac_ctx, session_entry->bssId, &aid,
+ &session_entry->dph.dphHashTable);
+
+ if (!sta_ds) {
+ lim_log(mac_ctx, LOGE,
+ FL("sta_ds does not exist"));
+ goto err;
+ }
+
+ if (LIM_IS_STA_ROLE(session_entry)) {
+ session_entry->gLimChannelSwitch.switchMode =
+ csa_params->switchmode;
+ /* timer already started by firmware, switch immediately */
+ session_entry->gLimChannelSwitch.switchCount = 0;
+ session_entry->gLimChannelSwitch.primaryChannel =
+ csa_params->channel;
+ session_entry->gLimChannelSwitch.state =
+ eLIM_CHANNEL_SWITCH_PRIMARY_ONLY;
+ session_entry->gLimChannelSwitch.ch_width = CH_WIDTH_20MHZ;
+
+ if (session_entry->vhtCapability &&
+ session_entry->htSupportedChannelWidthSet) {
+ chnl_switch_info =
+ &session_entry->gLimWiderBWChannelSwitch;
+ if (csa_params->ies_present_flag & lim_wbw_ie_present) {
+ chnl_switch_info->newChanWidth =
+ csa_params->new_ch_width;
+ chnl_switch_info->newCenterChanFreq0 =
+ csa_params->new_ch_freq_seg1;
+ chnl_switch_info->newCenterChanFreq1 =
+ csa_params->new_ch_freq_seg2;
+ session_entry->gLimChannelSwitch.state =
+ eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+ session_entry->gLimChannelSwitch.ch_width =
+ csa_params->new_ch_width + 1;
+ }
+ } else if (session_entry->htSupportedChannelWidthSet) {
+ if (csa_params->sec_chan_offset) {
+ session_entry->gLimChannelSwitch.ch_width =
+ CH_WIDTH_40MHZ;
+ session_entry->gLimChannelSwitch.state =
+ eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY;
+ } else {
+ session_entry->htSupportedChannelWidthSet =
+ WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
+ session_entry->htRecommendedTxWidthSet =
+ session_entry->htSupportedChannelWidthSet;
+ }
+ }
+ lim_log(mac_ctx, LOG1, FL("new ch width = %d"),
+ session_entry->gLimChannelSwitch.ch_width);
+
+ lim_prepare_for11h_channel_switch(mac_ctx, session_entry);
+ csa_offload_ind = cdf_mem_malloc(sizeof(tSmeCsaOffloadInd));
+ if (NULL == csa_offload_ind) {
+ lim_log(mac_ctx, LOGE,
+ FL("memalloc fail eWNI_SME_CSA_OFFLOAD_EVENT"));
+ goto err;
+ }
+
+ cdf_mem_set(csa_offload_ind, sizeof(tSmeCsaOffloadInd), 0);
+ csa_offload_ind->mesgType = eWNI_SME_CSA_OFFLOAD_EVENT;
+ csa_offload_ind->mesgLen = sizeof(tSmeCsaOffloadInd);
+ cdf_mem_copy(csa_offload_ind->bssId, session_entry->bssId,
+ sizeof(tSirMacAddr));
+ mmh_msg.type = eWNI_SME_CSA_OFFLOAD_EVENT;
+ mmh_msg.bodyptr = csa_offload_ind;
+ mmh_msg.bodyval = 0;
+ lim_log(mac_ctx, LOG1,
+ FL("Sending eWNI_SME_CSA_OFFLOAD_EVENT to SME. "));
+ MTRACE(mac_trace_msg_tx
+ (mac_ctx, session_entry->peSessionId, mmh_msg.type));
+#ifdef FEATURE_WLAN_DIAG_SUPPORT
+ lim_diag_event_report(mac_ctx,
+ WLAN_PE_DIAG_SWITCH_CHL_IND_EVENT, session_entry,
+ eSIR_SUCCESS, eSIR_SUCCESS);
+#endif
+ lim_sys_process_mmh_msg_api(mac_ctx, &mmh_msg, ePROT);
+ }
+
+err:
+ cdf_mem_free(csa_params);
+}
+
+/*--------------------------------------------------------------------------
+ \brief pe_delete_session() - Handle the Delete BSS Response from HAL.
+
+ \param pMac - pointer to global adapter context
+ \param sessionId - Message pointer.
+
+ \sa
+ --------------------------------------------------------------------------*/
+
+void lim_handle_delete_bss_rsp(tpAniSirGlobal pMac, tpSirMsgQ MsgQ)
+{
+ tpPESession psessionEntry;
+ tpDeleteBssParams pDelBss = (tpDeleteBssParams) (MsgQ->bodyptr);
+
+ psessionEntry =
+ pe_find_session_by_session_id(pMac, pDelBss->sessionId);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL("Session Does not exist for given sessionID %d"),
+ pDelBss->sessionId);
+ return;
+ }
+ if (LIM_IS_IBSS_ROLE(psessionEntry)) {
+ lim_ibss_del_bss_rsp(pMac, MsgQ->bodyptr, psessionEntry);
+ } else if (LIM_IS_UNKNOWN_ROLE(psessionEntry)) {
+ lim_process_sme_del_bss_rsp(pMac, MsgQ->bodyval, psessionEntry);
+ }
+
+ else
+ lim_process_mlm_del_bss_rsp(pMac, MsgQ, psessionEntry);
+
+}
+
+#ifdef WLAN_FEATURE_VOWIFI_11R
+/** -----------------------------------------------------------------
+ \brief lim_send_sme_aggr_qos_rsp() - sends SME FT AGGR QOS RSP
+ \ This function sends a eWNI_SME_FT_AGGR_QOS_RSP to SME.
+ \ SME only looks at rc and tspec field.
+ \param pMac - global mac structure
+ \param rspReqd - is SmeAddTsRsp required
+ \param status - status code of eWNI_SME_FT_AGGR_QOS_RSP
+ \return tspec
+ \sa
+ ----------------------------------------------------------------- */
+void
+lim_send_sme_aggr_qos_rsp(tpAniSirGlobal pMac, tpSirAggrQosRsp aggrQosRsp,
+ uint8_t smesessionId)
+{
+ tSirMsgQ mmhMsg;
+
+ mmhMsg.type = eWNI_SME_FT_AGGR_QOS_RSP;
+ mmhMsg.bodyptr = aggrQosRsp;
+ mmhMsg.bodyval = 0;
+ MTRACE(mac_trace_msg_tx(pMac, smesessionId, mmhMsg.type));
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+ return;
+}
+#endif
+
+void lim_send_sme_max_assoc_exceeded_ntf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr,
+ uint8_t smesessionId)
+{
+ tSirMsgQ mmhMsg;
+ tSmeMaxAssocInd *pSmeMaxAssocInd;
+
+ pSmeMaxAssocInd = cdf_mem_malloc(sizeof(tSmeMaxAssocInd));
+ if (NULL == pSmeMaxAssocInd) {
+ PELOGE(lim_log(pMac, LOGE, FL("Failed to allocate memory"));)
+ return;
+ }
+ cdf_mem_set((void *)pSmeMaxAssocInd, sizeof(tSmeMaxAssocInd), 0);
+ cdf_mem_copy((uint8_t *) pSmeMaxAssocInd->peerMac,
+ (uint8_t *) peerMacAddr, sizeof(tSirMacAddr));
+ pSmeMaxAssocInd->mesgType = eWNI_SME_MAX_ASSOC_EXCEEDED;
+ pSmeMaxAssocInd->mesgLen = sizeof(tSmeMaxAssocInd);
+ pSmeMaxAssocInd->sessionId = smesessionId;
+ mmhMsg.type = pSmeMaxAssocInd->mesgType;
+ mmhMsg.bodyptr = pSmeMaxAssocInd;
+ PELOG1(lim_log(pMac, LOG1, FL("msgType %s peerMacAddr " MAC_ADDRESS_STR
+ " sme session id %d"),
+ "eWNI_SME_MAX_ASSOC_EXCEEDED",
+ MAC_ADDR_ARRAY(peerMacAddr));
+ )
+ MTRACE(mac_trace_msg_tx(pMac, smesessionId, mmhMsg.type));
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+ return;
+}
+
+/** -----------------------------------------------------------------
+ \brief lim_send_sme_dfs_event_notify() - sends
+ eWNI_SME_DFS_RADAR_FOUND
+ After receiving WMI_PHYERR_EVENTID indication frame from FW, this
+ function sends a eWNI_SME_DFS_RADAR_FOUND to SME to notify
+ that a RADAR is found on current operating channel and SAP-
+ has to move to a new channel.
+ \param pMac - global mac structure
+ \param msgType - message type received from lower layer
+ \param event - event data received from lower layer
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+void
+lim_send_sme_dfs_event_notify(tpAniSirGlobal pMac, uint16_t msgType, void *event)
+{
+ tSirMsgQ mmhMsg;
+ mmhMsg.type = eWNI_SME_DFS_RADAR_FOUND;
+ mmhMsg.bodyptr = event;
+ mmhMsg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ return;
+}
+
+/*--------------------------------------------------------------------------
+ \brief lim_send_dfs_chan_sw_ie_update()
+ This timer handler updates the channel switch IE in beacon template
+
+ \param pMac - pointer to global adapter context
+ \return - channel to scan from valid session else zero.
+ \sa
+ --------------------------------------------------------------------------*/
+static void
+lim_send_dfs_chan_sw_ie_update(tpAniSirGlobal pMac, tpPESession psessionEntry)
+{
+
+ /* Update the beacon template and send to FW */
+ if (sch_set_fixed_beacon_fields(pMac, psessionEntry) != eSIR_SUCCESS) {
+ PELOGE(lim_log(pMac, LOGE, FL("Unable to set CSA IE in beacon"));)
+ return;
+ }
+
+ /* Send update beacon template message */
+ lim_send_beacon_ind(pMac, psessionEntry);
+ PELOG1(lim_log(pMac, LOG1,
+ FL(" Updated CSA IE, IE COUNT = %d"),
+ psessionEntry->gLimChannelSwitch.switchCount);
+ )
+
+ return;
+}
+
+/** -----------------------------------------------------------------
+ \brief lim_send_sme_ap_channel_switch_resp() - sends
+ eWNI_SME_CHANNEL_CHANGE_RSP
+ After receiving WMA_SWITCH_CHANNEL_RSP indication this
+ function sends a eWNI_SME_CHANNEL_CHANGE_RSP to SME to notify
+ that the Channel change has been done to the specified target
+ channel in the Channel change request
+ \param pMac - global mac structure
+ \param psessionEntry - session info
+ \param pChnlParams - Channel switch params
+ --------------------------------------------------------------------*/
+void
+lim_send_sme_ap_channel_switch_resp(tpAniSirGlobal pMac,
+ tpPESession psessionEntry,
+ tpSwitchChannelParams pChnlParams)
+{
+ tSirMsgQ mmhMsg;
+ tpSwitchChannelParams pSmeSwithChnlParams;
+ uint8_t channelId;
+
+ pSmeSwithChnlParams = (tSwitchChannelParams *)
+ cdf_mem_malloc(sizeof(tSwitchChannelParams));
+ if (NULL == pSmeSwithChnlParams) {
+ lim_log(pMac, LOGP,
+ FL("AllocateMemory failed for pSmeSwithChnlParams\n"));
+ return;
+ }
+
+ cdf_mem_set((void *)pSmeSwithChnlParams,
+ sizeof(tSwitchChannelParams), 0);
+
+ cdf_mem_copy(pSmeSwithChnlParams, pChnlParams,
+ sizeof(tSwitchChannelParams));
+
+ channelId = pSmeSwithChnlParams->channelNumber;
+
+ /*
+ * Pass the sme sessionID to SME instead
+ * PE session ID.
+ */
+ pSmeSwithChnlParams->peSessionId = psessionEntry->smeSessionId;
+
+ mmhMsg.type = eWNI_SME_CHANNEL_CHANGE_RSP;
+ mmhMsg.bodyptr = (void *)pSmeSwithChnlParams;
+ mmhMsg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+
+ /*
+ * We should start beacon transmission only if the new
+ * channel after channel change is Non-DFS. For a DFS
+ * channel, PE will receive an explicit request from
+ * upper layers to start the beacon transmission .
+ */
+
+ if (CHANNEL_STATE_DFS != cds_get_channel_state(channelId)) {
+ if (channelId == psessionEntry->currentOperChannel) {
+ lim_apply_configuration(pMac, psessionEntry);
+ lim_send_beacon_ind(pMac, psessionEntry);
+ } else {
+ PELOG1(lim_log(pMac, LOG1,
+ FL
+ ("Failed to Transmit Beacons on channel = %d"
+ "after AP channel change response"),
+ psessionEntry->bcnLen);
+ )
+ }
+ }
+ return;
+}
+
+/** -----------------------------------------------------------------
+ \brief lim_process_beacon_tx_success_ind() - This function is used
+ explicitely to handle successful beacon transmission indication
+ from the FW. This is a generic event generated by the FW afer the
+ first beacon is sent out after the beacon template update by the
+ host
+ \param pMac - global mac structure
+ \param psessionEntry - session info
+ \return none
+ \sa
+ ----------------------------------------------------------------- */
+void
+lim_process_beacon_tx_success_ind(tpAniSirGlobal pMac, uint16_t msgType, void *event)
+{
+ /* Currently, this event is used only for DFS channel switch announcement
+ * IE update in the template. If required to be used for other IE updates
+ * add appropriate code by introducing a state variable
+ */
+ tpPESession psessionEntry;
+ tSirMsgQ mmhMsg;
+ tSirSmeCSAIeTxCompleteRsp *pChanSwTxResponse;
+ struct sir_beacon_tx_complete_rsp *beacon_tx_comp_rsp_ptr;
+ uint8_t length = sizeof(tSirSmeCSAIeTxCompleteRsp);
+ tpSirFirstBeaconTxCompleteInd pBcnTxInd =
+ (tSirFirstBeaconTxCompleteInd *) event;
+
+ psessionEntry = pe_find_session_by_bss_idx(pMac, pBcnTxInd->bssIdx);
+ if (psessionEntry == NULL) {
+ lim_log(pMac, LOGE,
+ FL("Session Does not exist for given sessionID"));
+ return;
+ }
+
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ true == psessionEntry->dfsIncludeChanSwIe) {
+ /* Send only 5 beacons with CSA IE Set in when a radar is detected */
+ if (psessionEntry->gLimChannelSwitch.switchCount > 0) {
+ /*
+ * Send the next beacon with updated CSA IE count
+ */
+ lim_send_dfs_chan_sw_ie_update(pMac, psessionEntry);
+ /* Decrement the IE count */
+ psessionEntry->gLimChannelSwitch.switchCount--;
+ } else {
+ /* Done with CSA IE update, send response back to SME */
+ psessionEntry->gLimChannelSwitch.switchCount = 0;
+ if (pMac->sap.SapDfsInfo.disable_dfs_ch_switch == false)
+ psessionEntry->gLimChannelSwitch.switchMode = 0;
+ psessionEntry->dfsIncludeChanSwIe = false;
+ psessionEntry->dfsIncludeChanWrapperIe = false;
+
+ pChanSwTxResponse = (tSirSmeCSAIeTxCompleteRsp *)
+ cdf_mem_malloc(length);
+
+ if (NULL == pChanSwTxResponse) {
+ lim_log(pMac, LOGP,
+ FL
+ ("AllocateMemory failed for tSirSmeCSAIeTxCompleteRsp"));
+ return;
+ }
+
+ cdf_mem_set((void *)pChanSwTxResponse, length, 0);
+ pChanSwTxResponse->sessionId =
+ psessionEntry->smeSessionId;
+ pChanSwTxResponse->chanSwIeTxStatus =
+ CDF_STATUS_SUCCESS;
+
+ mmhMsg.type = eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND;
+ mmhMsg.bodyptr = pChanSwTxResponse;
+ mmhMsg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ }
+ }
+
+ if (LIM_IS_AP_ROLE(psessionEntry) &&
+ psessionEntry->gLimOperatingMode.present) {
+ /* Done with nss update, send response back to SME */
+ psessionEntry->gLimOperatingMode.present = 0;
+ beacon_tx_comp_rsp_ptr = (struct sir_beacon_tx_complete_rsp *)
+ cdf_mem_malloc(sizeof(*beacon_tx_comp_rsp_ptr));
+ if (NULL == beacon_tx_comp_rsp_ptr) {
+ lim_log(pMac, LOGP,
+ FL
+ ("AllocateMemory failed for beacon_tx_comp_rsp_ptr"));
+ return;
+ }
+ cdf_mem_set((void *)beacon_tx_comp_rsp_ptr,
+ sizeof(*beacon_tx_comp_rsp_ptr), 0);
+ beacon_tx_comp_rsp_ptr->session_id =
+ psessionEntry->smeSessionId;
+ beacon_tx_comp_rsp_ptr->tx_status = CDF_STATUS_SUCCESS;
+ mmhMsg.type = eWNI_SME_NSS_UPDATE_RSP;
+ mmhMsg.bodyptr = beacon_tx_comp_rsp_ptr;
+ mmhMsg.bodyval = 0;
+ lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
+ }
+ return;
+}