Browse Source

qcacld-3.0: Fix e_sme_command_nss_update stuck issue

Update NSS command is remove once driver receive the tx completion
event for the beacon. If SAP is in CAC wait state driver will not
get the tx completion for the beacon and the update NSS will timeout
after 30 sec and the serialization cmds queues will get stuck.

To avoid this remove the update NSS command from active queue as
soon as beacon is sent to firmware

Change-Id: I6f5b6bce91bdfacd4621020f313be25f74696b9d
CRs-Fixed: 2332302
Abhishek Singh 6 years ago
parent
commit
fc740bed63

+ 26 - 6
core/mac/inc/sir_api.h

@@ -5226,14 +5226,34 @@ struct sir_nss_update_request {
 };
 
 /**
- * struct sir_beacon_tx_complete_rsp
+ * enum sir_bcn_update_reason: bcn update reason
+ * @REASON_DEFAULT: reason default
+ * @REASON_NSS_UPDATE: If NSS is updated
+ * @REASON_CONFIG_UPDATE: Config update
+ * @REASON_SET_HT2040: HT2040 update
+ * @REASON_COLOR_CHANGE: Color change
+ * @REASON_CHANNEL_SWITCH: channel switch
+ */
+enum sir_bcn_update_reason {
+	REASON_DEFAULT = 0,
+	REASON_NSS_UPDATE = 1,
+	REASON_CONFIG_UPDATE = 2,
+	REASON_SET_HT2040 = 3,
+	REASON_COLOR_CHANGE = 4,
+	REASON_CHANNEL_SWITCH = 5,
+};
+
+/**
+ * struct sir_bcn_update_rsp
  *
- * @session_id: session for which beacon update happened
- * @tx_status: status of the beacon tx from FW
+ * @vdev_id: session for which bcn was updated
+ * @reason: bcn update reason
+ * @status: status of the beacon sent to FW
  */
-struct sir_beacon_tx_complete_rsp {
-	uint8_t session_id;
-	uint8_t tx_status;
+struct sir_bcn_update_rsp {
+	uint8_t vdev_id;
+	enum sir_bcn_update_reason reason;
+	QDF_STATUS status;
 };
 
 /**

+ 2 - 0
core/mac/src/include/sir_params.h

@@ -686,6 +686,8 @@ struct sir_mgmt_msg {
 #define SIR_HAL_SEND_ADDBA_REQ              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 398)
 #define SIR_HAL_GET_ROAM_SCAN_STATS         (SIR_HAL_ITC_MSG_TYPES_BEGIN + 399)
 #define SIR_HAL_SEND_AP_VDEV_UP             (SIR_HAL_ITC_MSG_TYPES_BEGIN + 400)
+#define SIR_HAL_SEND_BCN_RSP                (SIR_HAL_ITC_MSG_TYPES_BEGIN + 401)
+
 #define SIR_HAL_MSG_TYPES_END               (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
 
 /* CFG message types */

+ 25 - 5
core/mac/src/pe/include/sch_api.h

@@ -56,9 +56,17 @@ QDF_STATUS sch_set_fixed_beacon_fields(tpAniSirGlobal pMac,
 void sch_process_message(tpAniSirGlobal pMac,
 			 struct scheduler_msg *pSchMsg);
 
-/* / The beacon Indication handler function */
-void sch_process_pre_beacon_ind(tpAniSirGlobal pMac,
-				struct scheduler_msg *limMsg);
+/**
+ * sch_process_pre_beacon_ind() - Process the PreBeacon Indication from the Lim
+ * @pMac: pointer to mac structure
+ * @msg: schedular msg
+ * @reason: beaon update reason
+ *
+ * return: success: QDF_STATUS_SUCCESS failure: QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS sch_process_pre_beacon_ind(tpAniSirGlobal pMac,
+				      struct scheduler_msg *msg,
+				      enum sir_bcn_update_reason reason);
 
 /* / Post a message to the scheduler message queue */
 QDF_STATUS sch_post_message(tpAniSirGlobal pMac,
@@ -75,8 +83,20 @@ void sch_generate_tim(tpAniSirGlobal, uint8_t **, uint16_t *, uint8_t);
 
 void sch_set_beacon_interval(tpAniSirGlobal pMac, tpPESession psessionEntry);
 
-QDF_STATUS sch_send_beacon_req(tpAniSirGlobal, uint8_t *, uint16_t,
-			       tpPESession psessionEntry);
+/**
+ * sch_send_beacon_req() - send beacon update req to wma
+ * @mac_ctx: pointer to mac structure
+ * @bcn_payload: beacon payload
+ * @size: beacon size
+ * @session:pe session
+ * @reason: beaon update reason
+ *
+ * return: success: QDF_STATUS_SUCCESS failure: QDF_STATUS_E_FAILURE
+ */
+QDF_STATUS sch_send_beacon_req(tpAniSirGlobal mac_ctx, uint8_t *bcn_payload,
+			       uint16_t size, tpPESession session,
+			       enum sir_bcn_update_reason reason);
+
 
 QDF_STATUS lim_update_probe_rsp_template_ie_bitmap_beacon1(tpAniSirGlobal,
 							   tDot11fBeacon1 *,

+ 7 - 1
core/mac/src/pe/lim/lim_process_message_queue.c

@@ -1750,7 +1750,8 @@ static void lim_process_messages(tpAniSirGlobal mac_ctx,
 		break;
 	case SIR_LIM_BEACON_GEN_IND:
 		if (mac_ctx->lim.gLimSystemRole != eLIM_AP_ROLE)
-			sch_process_pre_beacon_ind(mac_ctx, msg);
+			sch_process_pre_beacon_ind(mac_ctx,
+						   msg, REASON_DEFAULT);
 		break;
 	case SIR_LIM_DELETE_STA_CONTEXT_IND:
 		lim_delete_sta_context(mac_ctx, msg);
@@ -2053,6 +2054,11 @@ static void lim_process_messages(tpAniSirGlobal mac_ctx,
 		lim_send_csa_restart_req(mac_ctx, msg->bodyval);
 		break;
 #endif
+	case WMA_SEND_BCN_RSP:
+		lim_send_bcn_rsp(mac_ctx, (tpSendbeaconParams)msg->bodyptr);
+		qdf_mem_free((void *)msg->bodyptr);
+		msg->bodyptr = NULL;
+		break;
 	default:
 		qdf_mem_free((void *)msg->bodyptr);
 		msg->bodyptr = NULL;

+ 7 - 7
core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c

@@ -3307,25 +3307,25 @@ free:
 	qdf_mem_free(body);
 }
 
-void lim_send_beacon_ind(tpAniSirGlobal pMac, tpPESession psessionEntry)
+QDF_STATUS lim_send_beacon_ind(tpAniSirGlobal pMac, tpPESession psessionEntry,
+			       enum sir_bcn_update_reason reason)
 {
 	tBeaconGenParams *pBeaconGenParams = NULL;
 	struct scheduler_msg limMsg = {0};
 	/** Allocate the Memory for Beacon Pre Message and for Stations in PoweSave*/
-	if (psessionEntry == NULL) {
+	if (!psessionEntry) {
 		pe_err("Error:Unable to get the PESessionEntry");
-		return;
+		return QDF_STATUS_E_INVAL;
 	}
 	pBeaconGenParams = qdf_mem_malloc(sizeof(*pBeaconGenParams));
-	if (NULL == pBeaconGenParams) {
+	if (!pBeaconGenParams) {
 		pe_err("Unable to allocate memory during sending beaconPreMessage");
-		return;
+		return QDF_STATUS_E_NOMEM;
 	}
 	qdf_mem_copy((void *)pBeaconGenParams->bssId,
 		     (void *)psessionEntry->bssId, QDF_MAC_ADDR_SIZE);
 	limMsg.bodyptr = pBeaconGenParams;
-	sch_process_pre_beacon_ind(pMac, &limMsg);
-	return;
+	return sch_process_pre_beacon_ind(pMac, &limMsg, reason);
 }
 
 void lim_process_rx_channel_status_event(tpAniSirGlobal mac_ctx, void *buf)

+ 76 - 11
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -3799,7 +3799,7 @@ static void lim_process_sme_update_config(tpAniSirGlobal mac_ctx,
 
 	if (LIM_IS_AP_ROLE(pe_session)) {
 		sch_set_fixed_beacon_fields(mac_ctx, pe_session);
-		lim_send_beacon_ind(mac_ctx, pe_session);
+		lim_send_beacon_ind(mac_ctx, pe_session, REASON_CONFIG_UPDATE);
 	}
 }
 
@@ -4091,7 +4091,7 @@ static void __lim_process_sme_set_ht2040_mode(tpAniSirGlobal pMac,
 
 	/* Update beacon */
 	sch_set_fixed_beacon_fields(pMac, psessionEntry);
-	lim_send_beacon_ind(pMac, psessionEntry);
+	lim_send_beacon_ind(pMac, psessionEntry, REASON_SET_HT2040);
 
 	/* update OP Mode for each associated peer */
 	for (staId = 0; staId < psessionEntry->dph.dphHashTable.size; staId++) {
@@ -5900,6 +5900,56 @@ static void lim_process_ext_change_channel(tpAniSirGlobal mac_ctx,
 				0, session_entry);
 }
 
+/**
+ * lim_nss_update_rsp() - send NSS update response to SME
+ * @mac_ctx Pointer to Global MAC structure
+ * @vdev_id: vdev id
+ * @status: nss update status
+ *
+ * Return: None
+ */
+static void lim_nss_update_rsp(tpAniSirGlobal mac_ctx,
+			       uint8_t vdev_id, QDF_STATUS status)
+{
+	struct scheduler_msg msg = {0};
+	struct sir_bcn_update_rsp *nss_rsp;
+	QDF_STATUS qdf_status;
+
+	nss_rsp = qdf_mem_malloc(sizeof(*nss_rsp));
+	if (!nss_rsp) {
+		pe_err("AllocateMemory failed for nss_rsp");
+		return;
+	}
+
+	nss_rsp->vdev_id = vdev_id;
+	nss_rsp->status = status;
+	nss_rsp->reason = REASON_NSS_UPDATE;
+
+	msg.type = eWNI_SME_NSS_UPDATE_RSP;
+	msg.bodyptr = nss_rsp;
+	msg.bodyval = 0;
+	qdf_status = scheduler_post_message(QDF_MODULE_ID_PE, QDF_MODULE_ID_SME,
+					    QDF_MODULE_ID_SME, &msg);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		pe_err("Failed to post eWNI_SME_NSS_UPDATE_RSP");
+		qdf_mem_free(nss_rsp);
+	}
+}
+
+void lim_send_bcn_rsp(tpAniSirGlobal mac_ctx, tpSendbeaconParams rsp)
+{
+	if (!rsp) {
+		pe_err("rsp is NULL");
+		return;
+	}
+
+	pe_debug("Send beacon resp status %d for reason %d",
+		 rsp->status, rsp->reason);
+
+	if (rsp->reason == REASON_NSS_UPDATE)
+		lim_nss_update_rsp(mac_ctx, rsp->vdev_id, rsp->status);
+}
+
 /**
  * lim_process_nss_update_request() - process sme nss update req
  *
@@ -5916,25 +5966,28 @@ static void lim_process_nss_update_request(tpAniSirGlobal mac_ctx,
 {
 	struct sir_nss_update_request *nss_update_req_ptr;
 	tpPESession session_entry = NULL;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	uint8_t vdev_id;
 
-	if (msg_buf == NULL) {
+	if (!msg_buf) {
 		pe_err("Buffer is Pointing to NULL");
 		return;
 	}
 
 	nss_update_req_ptr = (struct sir_nss_update_request *)msg_buf;
+	vdev_id = nss_update_req_ptr->vdev_id;
 	session_entry = pe_find_session_by_sme_session_id(mac_ctx,
 				nss_update_req_ptr->vdev_id);
-	if (session_entry == NULL) {
+	if (!session_entry) {
 		pe_err("Session not found for given session_id %d",
 			nss_update_req_ptr->vdev_id);
-		return;
+		goto end;
 	}
 
 	if (session_entry->valid && !LIM_IS_AP_ROLE(session_entry)) {
 		pe_err("Invalid SystemRole %d",
 			GET_LIM_SYSTEM_ROLE(session_entry));
-		return;
+		goto end;
 	}
 
 	/* populate nss field in the beacon */
@@ -5946,16 +5999,28 @@ static void lim_process_nss_update_request(tpAniSirGlobal mac_ctx,
 			(session_entry->ch_width > CH_WIDTH_80MHZ))
 		session_entry->gLimOperatingMode.chanWidth = CH_WIDTH_80MHZ;
 
-	pe_debug("ch width %hu", session_entry->gLimOperatingMode.chanWidth);
+	pe_debug("ch width %d Rx NSS %d",
+		 session_entry->gLimOperatingMode.chanWidth,
+		 session_entry->gLimOperatingMode.rxNSS);
 
 	/* Send nss update request from here */
-	if (sch_set_fixed_beacon_fields(mac_ctx, session_entry) !=
-			QDF_STATUS_SUCCESS) {
+	status = sch_set_fixed_beacon_fields(mac_ctx, session_entry);
+	if (QDF_IS_STATUS_ERROR(status)) {
 		pe_err("Unable to set op mode IE in beacon");
-		return;
+		goto end;
 	}
 
-	lim_send_beacon_ind(mac_ctx, session_entry);
+	status = lim_send_beacon_ind(mac_ctx, session_entry, REASON_NSS_UPDATE);
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return;
+
+	pe_err("Unable to send beacon");
+end:
+	/*
+	 * send resp only in case of failure,
+	 * success case response will be from wma.
+	 */
+	lim_nss_update_rsp(mac_ctx, vdev_id, status);
 }
 
 /**

+ 1 - 1
core/mac/src/pe/lim/lim_send_messages.c

@@ -133,7 +133,7 @@ QDF_STATUS lim_send_beacon_params(tpAniSirGlobal pMac,
 		pe_err("Posting WMA_UPDATE_BEACON_IND, reason=%X",
 			retCode);
 	}
-	lim_send_beacon_ind(pMac, psessionEntry);
+	lim_send_beacon_ind(pMac, psessionEntry, REASON_DEFAULT);
 	return retCode;
 }
 

+ 3 - 22
core/mac/src/pe/lim/lim_send_sme_rsp_messages.c

@@ -2352,7 +2352,7 @@ lim_send_bss_color_change_ie_update(tpAniSirGlobal mac_ctx,
 	}
 
 	/* Send update beacon template message */
-	lim_send_beacon_ind(mac_ctx, session);
+	lim_send_beacon_ind(mac_ctx, session, REASON_COLOR_CHANGE);
 	pe_debug("Updated BSS color change countdown = %d",
 		 session->he_bss_color_change.countdown);
 }
@@ -2406,11 +2406,8 @@ lim_process_beacon_tx_success_ind(tpAniSirGlobal mac_ctx, uint16_t msgType,
 				  void *event)
 {
 	tpPESession session;
-	struct scheduler_msg msg = {0};
-	struct sir_beacon_tx_complete_rsp *bcn_tx_comp_rsp;
 	tpSirFirstBeaconTxCompleteInd bcn_ind =
 		(tSirFirstBeaconTxCompleteInd *) event;
-	QDF_STATUS status;
 
 	session = pe_find_session_by_bss_idx(mac_ctx, bcn_ind->bssIdx);
 	if (!session) {
@@ -2433,25 +2430,9 @@ lim_process_beacon_tx_success_ind(tpAniSirGlobal mac_ctx, uint16_t msgType,
 		lim_process_ap_ecsa_timeout(session);
 
 
-	if (session->gLimOperatingMode.present) {
-		/* Done with nss update, send response back to SME */
+	if (session->gLimOperatingMode.present)
+		/* Done with nss update */
 		session->gLimOperatingMode.present = 0;
-		bcn_tx_comp_rsp = qdf_mem_malloc(sizeof(*bcn_tx_comp_rsp));
-		if (!bcn_tx_comp_rsp)
-			return;
-		bcn_tx_comp_rsp->session_id = session->smeSessionId;
-		bcn_tx_comp_rsp->tx_status = QDF_STATUS_SUCCESS;
-		msg.type = eWNI_SME_NSS_UPDATE_RSP;
-		msg.bodyptr = bcn_tx_comp_rsp;
-		msg.bodyval = 0;
-		status = scheduler_post_message(QDF_MODULE_ID_PE,
-						QDF_MODULE_ID_SME,
-						QDF_MODULE_ID_SME, &msg);
-		if (QDF_IS_STATUS_ERROR(status)) {
-			sme_err("Failed to post eWNI_SME_NSS_UPDATE_RSP");
-			qdf_mem_free(bcn_tx_comp_rsp);
-		}
-	}
 
 	lim_handle_bss_color_change_ie(mac_ctx, session);
 

+ 16 - 12
core/mac/src/pe/lim/lim_types.h

@@ -926,20 +926,15 @@ lim_get_ielen_from_bss_description(tpSirBssDescription pBssDescr)
 } /*** end lim_get_ielen_from_bss_description() ***/
 
 /**
- * lim_send_beacon_ind()
+ * lim_send_beacon_ind() - send the beacon indication
+ * @mac_ctx: pointer to mac structure
+ * @session: pe session
+ * @reason: beacon update reason
  *
- ***FUNCTION:
- * This function is called  to send the beacon indication
- * number being scanned.
- *
- ***PARAMS:
- *
- ***LOGIC:
- *
- ***ASSUMPTIONS:
+ * return: success: QDF_STATUS_SUCCESS failure: QDF_STATUS_E_FAILURE
  */
-
-void lim_send_beacon_ind(tpAniSirGlobal pMac, tpPESession psessionEntry);
+QDF_STATUS lim_send_beacon_ind(tpAniSirGlobal mac_ctx, tpPESession session,
+			       enum sir_bcn_update_reason reason);
 
 void
 lim_send_vdev_restart(tpAniSirGlobal pMac, tpPESession psessionEntry,
@@ -1017,6 +1012,15 @@ QDF_STATUS lim_process_sme_del_all_tdls_peers(tpAniSirGlobal p_mac,
 }
 #endif
 
+/**
+ * lim_send_bcn_rsp() - handle beacon send response
+ * @mac_ctx Pointer to Global MAC structure
+ * @rsp: beacon send response
+ *
+ * Return: None
+ */
+void lim_send_bcn_rsp(tpAniSirGlobal mac_ctx, tpSendbeaconParams rsp);
+
 /**
  * lim_process_rx_channel_status_event() - processes
  * event WDA_RX_CHN_STATUS_EVENT

+ 5 - 4
core/mac/src/pe/lim/lim_utils.c

@@ -5440,7 +5440,8 @@ void lim_update_beacon(tpAniSirGlobal mac_ctx)
 			if (false == mac_ctx->sap.SapDfsInfo.
 					is_dfs_cac_timer_running)
 				lim_send_beacon_ind(mac_ctx,
-						&mac_ctx->lim.gpSession[i]);
+						&mac_ctx->lim.gpSession[i],
+						REASON_DEFAULT);
 		}
 	}
 }
@@ -8298,7 +8299,7 @@ lim_send_dfs_chan_sw_ie_update(tpAniSirGlobal mac_ctx, tpPESession session)
 	}
 
 	/* Send update beacon template message */
-	lim_send_beacon_ind(mac_ctx, session);
+	lim_send_beacon_ind(mac_ctx, session, REASON_CHANNEL_SWITCH);
 	pe_debug("Updated CSA IE, IE COUNT: %d",
 		 session->gLimChannelSwitch.switchCount);
 }
@@ -8537,7 +8538,7 @@ QDF_STATUS lim_ap_mlme_vdev_update_beacon(struct vdev_mlme_obj *vdev_mlme,
 		return QDF_STATUS_SUCCESS;
 
 	if (op == BEACON_INIT)
-		lim_send_beacon_ind(session->mac_ctx, session);
+		lim_send_beacon_ind(session->mac_ctx, session, REASON_DEFAULT);
 	else if (op == BEACON_CSA)
 		lim_send_csa_restart_resp(session->mac_ctx, session);
 
@@ -8683,7 +8684,7 @@ void lim_send_start_bss_confirm(tpAniSirGlobal mac_ctx,
 
 void lim_send_beacon(tpAniSirGlobal mac_ctx, tpPESession session)
 {
-	lim_send_beacon_ind(mac_ctx, session);
+	lim_send_beacon_ind(mac_ctx, session, REASON_DEFAULT);
 }
 
 void lim_ndi_mlme_vdev_up_transition(tpPESession session)

+ 7 - 30
core/mac/src/pe/sch/sch_api.c

@@ -76,42 +76,16 @@ QDF_STATUS sch_post_message(tpAniSirGlobal pMac, struct scheduler_msg *pMsg)
 	return QDF_STATUS_SUCCESS;
 }
 
-/* --------------------------------------------------------------------------- */
-
-/**
- * sch_send_beacon_req
- *
- * FUNCTION:
- *
- * LOGIC:
- * 1) SCH received SIR_SCH_BEACON_GEN_IND
- * 2) SCH updates TIM IE and other beacon related IE's
- * 3) SCH sends WMA_SEND_BEACON_REQ to HAL. HAL then copies the beacon
- *    template to memory
- *
- * ASSUMPTIONS:
- * Memory allocation is reqd to send this message and SCH allocates memory.
- * The assumption is that HAL will "free" this memory.
- *
- * NOTE:
- *
- * @param pMac global
- *
- * @param beaconPayload
- *
- * @param size - Length of the beacon
- *
- * @return QDF_STATUS
- */
 QDF_STATUS sch_send_beacon_req(tpAniSirGlobal pMac, uint8_t *beaconPayload,
-			       uint16_t size, tpPESession psessionEntry)
+			       uint16_t size, tpPESession psessionEntry,
+			       enum sir_bcn_update_reason reason)
 {
 	struct scheduler_msg msgQ = {0};
 	tpSendbeaconParams beaconParams = NULL;
 	QDF_STATUS retCode;
 
-	pe_debug("Indicating HAL to copy the beacon template [%d bytes] to memory",
-		size);
+	pe_debug("Indicating HAL to copy the beacon template [%d bytes] to memory, reason %d",
+		size, reason);
 
 	if (LIM_IS_AP_ROLE(psessionEntry) &&
 	   (pMac->sch.schObject.fBeaconChanged)) {
@@ -151,6 +125,9 @@ QDF_STATUS sch_send_beacon_req(tpAniSirGlobal pMac, uint8_t *beaconPayload,
 		}
 	}
 
+	beaconParams->vdev_id = psessionEntry->smeSessionId;
+	beaconParams->reason = reason;
+
 	/* p2pIeOffset should be atleast greater than timIeOffset */
 	if ((pMac->sch.schObject.p2pIeOffset != 0) &&
 	    (pMac->sch.schObject.p2pIeOffset <

+ 32 - 46
core/mac/src/pe/sch/sch_beacon_gen.c

@@ -889,26 +889,20 @@ void set_probe_rsp_ie_bitmap(uint32_t *IeBitmap, uint32_t pos)
 	IeBitmap[index] = temp;
 }
 
-/* -------------------------------------------------------------------- */
 /**
- * write_beacon_to_memory
+ * write_beacon_to_memory() - send the beacon to the wma
+ * @pMac: pointer to mac structure
+ * @size: Size of the beacon to write to memory
+ * @length: Length field of the beacon to write to memory
+ * @psessionEntry: pe session
+ * @reason: beacon update reason
  *
- * FUNCTION:
- *
- * LOGIC:
- *
- * ASSUMPTIONS:
- *
- * NOTE:
- *
- * @param None
- * @param size    Size of the beacon to write to memory
- * @param length Length field of the beacon to write to memory
- * @return None
+ * return: success: QDF_STATUS_SUCCESS failure: QDF_STATUS_E_FAILURE
  */
-
-static void write_beacon_to_memory(tpAniSirGlobal pMac, uint16_t size,
-				   uint16_t length, tpPESession psessionEntry)
+static QDF_STATUS write_beacon_to_memory(tpAniSirGlobal pMac, uint16_t size,
+					 uint16_t length,
+					 tpPESession psessionEntry,
+					 enum sir_bcn_update_reason reason)
 {
 	uint16_t i;
 	tpAniBeaconStruct pBeacon;
@@ -931,7 +925,7 @@ static void write_beacon_to_memory(tpAniSirGlobal pMac, uint16_t size,
 		pBeacon->beaconLength = (uint32_t) size - sizeof(uint32_t);
 
 	if (!pMac->sch.schObject.fBeaconChanged)
-		return;
+		return QDF_STATUS_E_FAILURE;
 
 	/*
 	 * Copy beacon data to SoftMAC shared memory...
@@ -940,12 +934,13 @@ static void write_beacon_to_memory(tpAniSirGlobal pMac, uint16_t size,
 
 	size = (size + 3) & (~3);
 	status = sch_send_beacon_req(pMac, psessionEntry->pSchBeaconFrameBegin,
-				     size, psessionEntry);
+				     size, psessionEntry, reason);
 	if (QDF_IS_STATUS_ERROR(status))
 		pe_err("sch_send_beacon_req() returned an error %d, size %d",
 		       status, size);
-
 	pMac->sch.schObject.fBeaconChanged = 0;
+
+	return status;
 }
 
 /**
@@ -1000,31 +995,19 @@ void sch_generate_tim(tpAniSirGlobal pMac, uint8_t **pPtr, uint16_t *timLength,
 
 	*pPtr = ptr;
 }
-/* -------------------------------------------------------------------- */
-/**
- * @function: SchProcessPreBeaconInd
- *
- * @brief : Process the PreBeacon Indication from the Lim
- *
- * ASSUMPTIONS:
- *
- * NOTE:
- *
- * @param : pMac - tpAniSirGlobal
- *
- * @return None
- */
 
-void sch_process_pre_beacon_ind(tpAniSirGlobal pMac,
-				struct scheduler_msg *limMsg)
+QDF_STATUS sch_process_pre_beacon_ind(tpAniSirGlobal pMac,
+				      struct scheduler_msg *limMsg,
+				      enum sir_bcn_update_reason reason)
 {
 	tpBeaconGenParams pMsg = (tpBeaconGenParams) limMsg->bodyptr;
 	uint32_t beaconSize;
 	tpPESession psessionEntry;
 	uint8_t sessionId;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
 
 	psessionEntry = pe_find_session_by_bssid(pMac, pMsg->bssId, &sessionId);
-	if (psessionEntry == NULL) {
+	if (!psessionEntry) {
 		pe_err("session lookup fails");
 		goto end;
 	}
@@ -1043,12 +1026,13 @@ void sch_process_pre_beacon_ind(tpAniSirGlobal pMac,
 	case eLIM_STA_IN_IBSS_ROLE:
 		/* generate IBSS parameter set */
 		if (psessionEntry->statypeForBss == STA_ENTRY_SELF)
-			write_beacon_to_memory(pMac, (uint16_t) beaconSize,
-					       (uint16_t) beaconSize,
-					       psessionEntry);
+			status =
+			    write_beacon_to_memory(pMac, (uint16_t) beaconSize,
+						   (uint16_t) beaconSize,
+						   psessionEntry, reason);
 		else
 			pe_err("can not send beacon for PEER session entry");
-			break;
+		break;
 
 	case eLIM_AP_ROLE: {
 		uint8_t *ptr =
@@ -1060,9 +1044,10 @@ void sch_process_pre_beacon_ind(tpAniSirGlobal pMac,
 			sch_generate_tim(pMac, &ptr, &timLength,
 					 psessionEntry->dtimPeriod);
 			beaconSize += 2 + timLength;
-			write_beacon_to_memory(pMac, (uint16_t) beaconSize,
-					       (uint16_t) beaconSize,
-					       psessionEntry);
+			status =
+			    write_beacon_to_memory(pMac, (uint16_t) beaconSize,
+						   (uint16_t) beaconSize,
+						   psessionEntry, reason);
 		} else
 			pe_err("can not send beacon for PEER session entry");
 			}
@@ -1074,6 +1059,7 @@ void sch_process_pre_beacon_ind(tpAniSirGlobal pMac,
 	}
 
 end:
-		qdf_mem_free(pMsg);
+	qdf_mem_free(pMsg);
 
-	}
+	return status;
+}

+ 8 - 4
core/sme/src/common/sme_api.c

@@ -2420,15 +2420,19 @@ static QDF_STATUS sme_process_nss_update_resp(tpAniSirGlobal mac, uint8_t *msg)
 	tSmeCmd *command = NULL;
 	bool found;
 	policy_mgr_nss_update_cback callback = NULL;
-	struct sir_beacon_tx_complete_rsp *param;
+	struct sir_bcn_update_rsp *param;
 
-	param = (struct sir_beacon_tx_complete_rsp *)msg;
+	param = (struct sir_bcn_update_rsp *)msg;
 	if (!param)
 		sme_err("nss update resp param is NULL");
 		/* Not returning. Need to check if active command list
 		 * needs to be freed
 		 */
 
+	if (param && param->reason != REASON_NSS_UPDATE) {
+		sme_err("reason not NSS update");
+		return QDF_STATUS_E_INVAL;
+	}
 	entry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK);
 	if (!entry) {
 		sme_err("No cmd found in active list");
@@ -2452,8 +2456,8 @@ static QDF_STATUS sme_process_nss_update_resp(tpAniSirGlobal mac, uint8_t *msg)
 			sme_err("Callback failed since nss update params is NULL");
 		else
 			callback(command->u.nss_update_cmd.context,
-				param->tx_status,
-				param->session_id,
+				param->status,
+				param->vdev_id,
 				command->u.nss_update_cmd.next_action,
 				command->u.nss_update_cmd.reason,
 				command->u.nss_update_cmd.original_vdev_id);

+ 7 - 7
core/sme/src/csr/csr_api_roam.c

@@ -21514,7 +21514,7 @@ void csr_process_nss_update_req(tpAniSirGlobal mac, tSmeCmd *command)
 	struct sir_nss_update_request *msg;
 	QDF_STATUS status;
 	struct scheduler_msg msg_return = {0};
-	struct sir_beacon_tx_complete_rsp *param;
+	struct sir_bcn_update_rsp *param;
 	struct csr_roam_session *session;
 
 
@@ -21541,19 +21541,19 @@ void csr_process_nss_update_req(tpAniSirGlobal mac, tSmeCmd *command)
 	sme_debug("Posting eWNI_SME_NSS_UPDATE_REQ to PE");
 
 	status = umac_send_mb_message_to_mac(msg);
-	if (QDF_STATUS_SUCCESS != status) {
-		sme_err("Posting to PE failed");
+	if (QDF_IS_STATUS_SUCCESS(status))
 		return;
-	}
-	return;
+
+	sme_err("Posting to PE failed");
 fail:
 	param = qdf_mem_malloc(sizeof(*param));
 	if (!param)
 		return;
 
 	sme_err("Sending nss update fail response to SME");
-	param->tx_status = QDF_STATUS_E_FAILURE;
-	param->session_id = command->u.nss_update_cmd.session_id;
+	param->status = QDF_STATUS_E_FAILURE;
+	param->vdev_id = command->u.nss_update_cmd.session_id;
+	param->reason = REASON_NSS_UPDATE;
 	msg_return.type = eWNI_SME_NSS_UPDATE_RSP;
 	msg_return.bodyptr = param;
 	msg_return.bodyval = 0;

+ 6 - 0
core/wma/inc/wma_if.h

@@ -712,6 +712,7 @@ typedef struct sBeaconGenParams {
 
 /**
  * struct tSendbeaconParams - send beacon parameters
+ * vdev_id: vdev id
  * @bssId: BSSID mac address
  * @beacon: beacon data
  * @beaconLength: beacon length of template
@@ -719,8 +720,11 @@ typedef struct sBeaconGenParams {
  * @p2pIeOffset: P2P IE offset
  * @csa_count_offset: Offset of Switch count field in CSA IE
  * @ecsa_count_offset: Offset of Switch count field in ECSA IE
+ * @reason: bcn update reason
+ * @status: beacon send status
  */
 typedef struct {
+	uint8_t vdev_id;
 	tSirMacAddr bssId;
 	uint8_t beacon[SIR_MAX_BEACON_SIZE];
 	uint32_t beaconLength;
@@ -728,6 +732,8 @@ typedef struct {
 	uint16_t p2pIeOffset;
 	uint32_t csa_count_offset;
 	uint32_t ecsa_count_offset;
+	enum sir_bcn_update_reason reason;
+	QDF_STATUS status;
 } tSendbeaconParams, *tpSendbeaconParams;
 
 /**

+ 1 - 0
core/wma/inc/wma_types.h

@@ -142,6 +142,7 @@
 #define WMA_DELETE_BSS_RSP             SIR_HAL_DELETE_BSS_RSP
 #define WMA_DELETE_BSS_HO_FAIL_RSP     SIR_HAL_DELETE_BSS_HO_FAIL_RSP
 #define WMA_SEND_BEACON_REQ            SIR_HAL_SEND_BEACON_REQ
+#define WMA_SEND_BCN_RSP               SIR_HAL_SEND_BCN_RSP
 #define WMA_SEND_PROBE_RSP_TMPL        SIR_HAL_SEND_PROBE_RSP_TMPL
 
 #define WMA_SET_BSSKEY_REQ             SIR_HAL_SET_BSSKEY_REQ

+ 0 - 1
core/wma/src/wma_main.c

@@ -7914,7 +7914,6 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg)
 		break;
 	case WMA_SEND_BEACON_REQ:
 		wma_send_beacon(wma_handle, (tpSendbeaconParams) msg->bodyptr);
-		qdf_mem_free(msg->bodyptr);
 		break;
 	case WMA_SEND_AP_VDEV_UP:
 		wma_set_ap_vdev_up(wma_handle, msg->bodyval);

+ 11 - 4
core/wma/src/wma_mgmt.c

@@ -2914,11 +2914,13 @@ void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info)
 	uint8_t *p2p_ie;
 	struct sAniBeaconStruct *beacon;
 
+	WMA_LOGD("Beacon update reason %d", bcn_info->reason);
 	beacon = (struct sAniBeaconStruct *) (bcn_info->beacon);
 	vdev = wma_find_vdev_by_addr(wma, beacon->macHdr.sa, &vdev_id);
 	if (!vdev) {
 		WMA_LOGE("%s : failed to get vdev handle", __func__);
-		return;
+		status = QDF_STATUS_E_INVAL;
+		goto send_rsp;
 	}
 
 	if (wmi_service_enabled(wma->wmi_handle,
@@ -2928,7 +2930,7 @@ void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info)
 		if (QDF_IS_STATUS_ERROR(status)) {
 			WMA_LOGE("%s : wmi_unified_bcn_tmpl_send Failed ",
 				 __func__);
-			return;
+			goto send_rsp;
 		}
 
 		if (bcn_info->p2pIeOffset) {
@@ -2939,18 +2941,23 @@ void wma_send_beacon(tp_wma_handle wma, tpSendbeaconParams bcn_info)
 							 p2p_ie) < 0) {
 				WMA_LOGE("%s : wmi_unified_bcn_tmpl_send Failed ",
 					__func__);
-				return;
+				status = QDF_STATUS_E_INVAL;
+				goto send_rsp;
 			}
 		}
 	}
 	status = wma_store_bcn_tmpl(wma, vdev_id, bcn_info);
 	if (status != QDF_STATUS_SUCCESS) {
 		WMA_LOGE("%s : wma_store_bcn_tmpl Failed", __func__);
-		return;
+		goto send_rsp;
 	}
 #ifndef CONFIG_VDEV_SM
 	wma_set_ap_vdev_up(wma, vdev_id);
 #endif
+
+send_rsp:
+	bcn_info->status = status;
+	wma_send_msg(wma, WMA_SEND_BCN_RSP, (void *)bcn_info, 0);
 }
 
 /**