qcacld-3.0: Add support to send beacon report resp err to AP

Currently, If STA doesn't send beacon report response to
AP, AP will not be able to know the reason why sta did not
send beacon report as no reason code is defined in
IEEE802.11-2016 standard.

Fix is to send beacon report err to AP based on enable_bcn_rpt_err_vsie
ini and err code. The userspace can requests the driver
to stop reporting additional Err reason in beacon
report response dynamically thus ini check along with error_code
is introduced before sending Err reason. Add INI support
enable_bcn_rpt_err_vsie to make this ini configurable. Default value
of this ini is 0. Err reason will be sent to AP which will
be helpful for AP to take actions based on additional err reasons.

Change-Id: If03cd2a1413b8d93bc0bb4942c48f1aed9248390
CRs-Fixed: 2614447
diff --git a/Kbuild b/Kbuild
index 4e9155f..09b3436 100644
--- a/Kbuild
+++ b/Kbuild
@@ -2228,6 +2228,7 @@
 cppflags-$(CONFIG_DIRECT_BUF_RX_ENABLE) += -DDBR_MULTI_SRNG_ENABLE
 cppflags-$(CONFIG_WMI_CMD_STRINGS) += -DWMI_CMD_STRINGS
 cppflags-$(CONFIG_WLAN_FEATURE_TWT) += -DWLAN_SUPPORT_TWT
+cppflags-$(CONFIG_WLAN_FEATURE_BCN_RPT_VSIE) += -DWLAN_FEATURE_BCN_RPT_VSIE
 
 cppflags-$(CONFIG_WLAN_DISABLE_EXPORT_SYMBOL) += -DWLAN_DISABLE_EXPORT_SYMBOL
 cppflags-$(CONFIG_WIFI_POS_CONVERGED) += -DWIFI_POS_CONVERGED
diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c
index dcc1866..8dfa486 100644
--- a/components/mlme/core/src/wlan_mlme_main.c
+++ b/components/mlme/core/src/wlan_mlme_main.c
@@ -1355,6 +1355,26 @@
 		      sizeof(product_details->model_number));
 }
 
+#ifdef WLAN_FEATURE_BCN_RPT_VSIE
+/**
+ * mlme_init_bcn_rpt_err_vsi: To fill rpt_err_vsi INI
+ * @psoc: psoc
+ * @sta: sta config
+ *
+ * @return None
+ */
+static void mlme_init_bcn_rpt_err_vsi(struct wlan_objmgr_psoc *psoc,
+				      struct wlan_mlme_sta_cfg *sta)
+{
+	sta->bcn_rpt_err_vsie = cfg_get(psoc, CFG_ENABLE_BCN_RPT_ERR_VSIE);
+}
+#else
+static inline void mlme_init_bcn_rpt_err_vsi(struct wlan_objmgr_psoc *psoc,
+					     struct wlan_mlme_sta_cfg *sta)
+{
+}
+#endif
+
 static void mlme_init_sta_cfg(struct wlan_objmgr_psoc *psoc,
 			      struct wlan_mlme_sta_cfg *sta)
 {
@@ -1391,6 +1411,7 @@
 	sta->allow_tpc_from_ap = cfg_get(psoc, CFG_TX_POWER_CTRL);
 	sta->sta_keepalive_method =
 		cfg_get(psoc, CFG_STA_KEEPALIVE_METHOD);
+	mlme_init_bcn_rpt_err_vsi(psoc, sta);
 }
 
 static void mlme_init_stats_cfg(struct wlan_objmgr_psoc *psoc,
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_sta.h b/components/mlme/dispatcher/inc/cfg_mlme_sta.h
index 63643aa..e12d4c9 100644
--- a/components/mlme/dispatcher/inc/cfg_mlme_sta.h
+++ b/components/mlme/dispatcher/inc/cfg_mlme_sta.h
@@ -431,6 +431,33 @@
 			MLME_STA_KEEPALIVE_GRAT_ARP, \
 			CFG_VALUE_OR_DEFAULT, \
 			"Which keepalive method to use")
+#ifdef WLAN_FEATURE_BCN_RPT_VSIE
+/*
+ * <ini>
+ * enable_bcn_rpt_err_vsie - Enable/Disable ini for beacon report Err reasons
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to send vendor specific error reasons in beacon report
+ * response frame in case driver rejects the beacon report measurement request
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_BCN_RPT_ERR_VSIE CFG_INI_BOOL( \
+		"enable_bcn_rpt_err_vsie", \
+		0, \
+		"To Enable err vsie in beacon report rsp")
+#define ENABLE_BCN_RPT_ERR_VSIE_ALL CFG(CFG_ENABLE_BCN_RPT_ERR_VSIE)
+#else
+#define ENABLE_BCN_RPT_ERR_VSIE_ALL
+#endif
 
 #define CFG_STA_ALL \
 	CFG(CFG_INFRA_STA_KEEP_ALIVE_PERIOD) \
@@ -449,6 +476,6 @@
 	CFG(CFG_STA_KEEPALIVE_METHOD) \
 	CFG(CFG_WT_CNF_TIMEOUT) \
 	CFG(CFG_CURRENT_RSSI) \
-	CFG(CFG_TX_POWER_CTRL)
-
+	CFG(CFG_TX_POWER_CTRL) \
+	ENABLE_BCN_RPT_ERR_VSIE_ALL
 #endif /* CFG_MLME_STA_H__ */
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
index a7be0be..f2e8f9f 100644
--- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
+++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
@@ -1343,6 +1343,7 @@
  * @force_rsne_override:            Force rsnie override from user
  * @single_tid:                     Set replay counter for all TID
  * @allow_tpc_from_ap:              Support for AP power constraint
+ * @bcn_rpt_err_vsie:               beacon report error vsie
  */
 struct wlan_mlme_sta_cfg {
 	uint32_t sta_keep_alive_period;
@@ -1362,6 +1363,9 @@
 	bool single_tid;
 	bool allow_tpc_from_ap;
 	enum station_keepalive_method sta_keepalive_method;
+#ifdef WLAN_FEATURE_BCN_RPT_VSIE
+	bool bcn_rpt_err_vsie;
+#endif
 };
 
 /**
diff --git a/configs/default_defconfig b/configs/default_defconfig
index 701cf65..e229fdc 100644
--- a/configs/default_defconfig
+++ b/configs/default_defconfig
@@ -179,6 +179,9 @@
 #Flag to enable set coex configuration
 CONFIG_QCACLD_FEATURE_COEX_CONFIG := n
 
+#Flag to enable beacon report err vsie
+CONFIG_WLAN_FEATURE_BCN_RPT_VSIE := y
+
 #Flag to enable get hw capability
 ifeq ($(CONFIG_ARCH_QCS40X), y)
 CONFIG_QCACLD_FEATURE_HW_CAPABILITY := y
diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h
index 3770a25..2d31813 100644
--- a/core/mac/inc/sir_mac_prot_def.h
+++ b/core/mac/inc/sir_mac_prot_def.h
@@ -1538,6 +1538,35 @@
 	} report;
 
 } tSirMacRadioMeasureReport, *tpSirMacRadioMeasureReport;
+/**
+ * enum beacon_report_status_code - Beacon Report response error
+ * @BCN_RPT_ERR_UNSPECIFIED: unspecified error
+ * @BCN_RPT_ERR_RRM_FEATURE_DISABLED: AP sets Radio Measurement subfield
+ * to 0 in Capability Information element
+ * @BCN_RPT_ERR_NOT_SUPPORTED_PARAMETERS: STA does not support
+ * parameters in the Beacon Report request
+ * @BCN_RPT_ERR_TEMPORARILY_UNAVAILABLE: Memory allocation Failure
+ * @BCN_RPT_ERR_VALIDATION_FAILED_IN_A_REQUEST_FRAME: Beacon Report
+ * request has invalid format
+ * @BCN_RPT_ERR_PREVIOUS_REQUEST_PROGRESS: New Beacon Report request is sent
+ * by AP before completion of previous beacon request
+ * @BCN_RPT_ERR_MAXIMUM_MEASUREMENT_DURATION_EXCCEED: Requested measurement
+ * duration greater than  Measurement Duration of STA
+ * @BCN_RPT_ERR_NOT_SUPPORTED_REPORT_BITS: AP sends not supported report bits
+ *  in Table 9-81 in IEEE802.11-2016
+ * @BCN_RPT_SUCCESS: Success
+ */
+enum beacon_report_status_code {
+	BCN_RPT_ERR_UNSPECIFIED,
+	BCN_RPT_ERR_RRM_FEATURE_DISABLED,
+	BCN_RPT_ERR_NOT_SUPPORTED_PARAMETERS,
+	BCN_RPT_ERR_TEMPORARILY_UNAVAILABLE,
+	BCN_RPT_ERR_VALIDATION_FAILED_IN_A_REQUEST_FRAME,
+	BCN_RPT_ERR_PREVIOUS_REQUEST_PROGRESS,
+	BCN_RPT_ERR_MAXIMUM_MEASUREMENT_DURATION_EXCCEED,
+	BCN_RPT_ERR_NOT_SUPPORTED_REPORT_BITS,
+	BCN_RPT_SUCCESS,
+};
 
 #ifdef WLAN_FEATURE_11AX
 struct he_cap_network_endian {
diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h
index 606236f..ae482b9 100644
--- a/core/mac/src/pe/include/lim_session.h
+++ b/core/mac/src/pe/include/lim_session.h
@@ -124,6 +124,12 @@
 #define ADAPTIVE_11R_DATA_LEN      0x04
 #define ADAPTIVE_11R_OUI_DATA     "\x00\x00\x00\x01"
 
+#define BEACON_RPT_ERR_VSIE_STA_IE_LEN         0x08
+#define BEACON_RPT_ERR_VSIE_STA_OUI            "\x00\x00\x0f\x22"
+#define BEACON_RPT_ERR_VSIE_OUI_LEN            0X04
+#define BEACON_RPT_ERR_VSIE_DATA_LEN           0x03
+#define BEACON_RPT_ERR_VSIE_OUI_DATA           "\x05\x01\x01"
+
 /**
  * struct pe_session - per-vdev PE context
  * @available: true if the entry is available, false if it is in use
diff --git a/core/mac/src/pe/include/rrm_api.h b/core/mac/src/pe/include/rrm_api.h
index cc1c8dc..5615ecd 100644
--- a/core/mac/src/pe/include/rrm_api.h
+++ b/core/mac/src/pe/include/rrm_api.h
@@ -43,12 +43,25 @@
 							  *pLinkReq,
 						struct pe_session *
 							  pe_session);
-
+/*
+ * rrm_process_radio_measurement_request - Processes the Radio Resource
+ * Measurement request
+ *
+ * @mac_ctx: Global pointer to MAC context
+ * @peer: Macaddress of the peer requesting the radio measurement.
+ * @rrm_req: Array of Measurement request IEs
+ * @session_entry: session entry.
+ * @error_code: beacon report resp error code
+ *
+ * Return: QDF_STATUS
+ */
 QDF_STATUS
 rrm_process_radio_measurement_request(struct mac_context *mac_ctx,
 				      tSirMacAddr peer,
 				      tDot11fRadioMeasurementRequest *rrm_req,
-				      struct pe_session *session_entry);
+				      struct pe_session *session_entry,
+				      enum beacon_report_status_code
+				      error_code);
 
 QDF_STATUS rrm_process_neighbor_report_response(struct mac_context *mac,
 						tDot11fNeighborReportResponse
diff --git a/core/mac/src/pe/lim/lim_process_action_frame.c b/core/mac/src/pe/lim/lim_process_action_frame.c
index 7cc212b..22ea995 100644
--- a/core/mac/src/pe/lim/lim_process_action_frame.c
+++ b/core/mac/src/pe/lim/lim_process_action_frame.c
@@ -1320,7 +1320,7 @@
 	/* Call rrm function to handle the request. */
 
 	rrm_process_radio_measurement_request(mac, pHdr->sa, frm,
-					      pe_session);
+					      pe_session, BCN_RPT_SUCCESS);
 err:
 	qdf_mem_free(frm);
 }
diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c
index 231300e..85a3226 100644
--- a/core/mac/src/pe/lim/lim_send_management_frames.c
+++ b/core/mac/src/pe/lim/lim_send_management_frames.c
@@ -4479,6 +4479,102 @@
 	return status_code;
 } /* End lim_send_link_report_action_frame. */
 
+#ifdef WLAN_FEATURE_BCN_RPT_VSIE
+/**
+ * lim_fill_beacon_report_error_vsie: To fill beacon report error vsie
+ * @param pe_session: session
+ * @param ie_buf: double pointer that holds address of error vsie
+ * @param error_code: beacon_report_status_code
+ *
+ * @return QDF_STATUS: success/failure
+ */
+static QDF_STATUS
+lim_fill_beacon_report_error_vsie(struct pe_session *pe_session,
+				  uint8_t **ie_buf, uint8_t *ie_len,
+				  enum beacon_report_status_code
+				  error_code)
+{
+	uint8_t *buf = NULL, *vsie_ie = NULL;
+
+	/*
+	 * Vendor specific IE to be advertised in beacon report response
+	 * req:
+	 * Type     0xDD
+	 * Length   0x0A
+	 * OUI      0x00 0x00 0x0F
+	 * Type     0x22
+	 * subtype  0x05
+	 * Version  0x01
+	 * Length   0x01
+	 * Data     0x00-0x07 (beacon report error)
+	 * supported)
+	 */
+	vsie_ie = qdf_mem_malloc(BEACON_RPT_ERR_VSIE_STA_IE_LEN + 2);
+	if (!vsie_ie)
+		return QDF_STATUS_E_FAILURE;
+
+	/* Fill the Vendor IE Type (0xDD) */
+	buf = vsie_ie;
+	*buf = WLAN_ELEMID_VENDOR;
+	buf++;
+
+	/* Fill the Vendor IE length (0x0A) */
+	*buf = BEACON_RPT_ERR_VSIE_STA_IE_LEN;
+	buf++;
+
+	/*
+	 * Fill the vsie Vendor specific OUI(0x00 0x00 0x0F 0x22)
+	 */
+	qdf_mem_copy(buf, BEACON_RPT_ERR_VSIE_STA_OUI,
+		     BEACON_RPT_ERR_VSIE_OUI_LEN);
+	buf += BEACON_RPT_ERR_VSIE_OUI_LEN;
+
+	/*
+	 * Fill Subtype version and length (0x05 0x01 0x01)
+	 */
+	qdf_mem_copy(buf, BEACON_RPT_ERR_VSIE_OUI_DATA,
+		     BEACON_RPT_ERR_VSIE_DATA_LEN);
+	buf += BEACON_RPT_ERR_VSIE_DATA_LEN;
+
+	/* Fill error code */
+	*buf = error_code;
+
+	*ie_len = BEACON_RPT_ERR_VSIE_STA_IE_LEN + 2;
+	*ie_buf = vsie_ie;
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static QDF_STATUS
+lim_fill_beacon_report_error_vsie(struct pe_session *pe_session,
+				  uint8_t **ie_buf, uint8_t *ie_len,
+				  enum beacon_report_status_code
+				  error_code)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+#ifdef WLAN_FEATURE_BCN_RPT_VSIE
+static bool
+lim_check_bcn_rpt_err_vsie_status(struct mac_context *mac,
+				  enum beacon_report_status_code error_code)
+{
+	if (mac->mlme_cfg->sta.bcn_rpt_err_vsie && error_code !=
+	    BCN_RPT_SUCCESS) {
+		return true;
+	}
+
+	return false;
+}
+#else
+static bool
+lim_check_bcn_rpt_err_vsie_status(struct mac_context *mac,
+				  enum beacon_report_status_code error_code)
+{
+	return false;
+}
+#endif
+
 QDF_STATUS
 lim_send_radio_measure_report_action_frame(struct mac_context *mac,
 				uint8_t dialog_token,
@@ -4486,18 +4582,23 @@
 				bool is_last_frame,
 				tpSirMacRadioMeasureReport pRRMReport,
 				tSirMacAddr peer,
-				struct pe_session *pe_session)
+				struct pe_session *pe_session,
+				enum beacon_report_status_code error_code)
 {
 	QDF_STATUS status_code = QDF_STATUS_SUCCESS;
 	uint8_t *pFrame;
 	tpSirMacMgmtHdr pMacHdr;
-	uint32_t nBytes, nPayload, nStatus;
+	uint32_t nPayload, nStatus;
+	uint32_t nBytes = 0;
 	void *pPacket;
 	QDF_STATUS qdf_status;
 	uint8_t i;
 	uint8_t txFlag = 0;
 	uint8_t smeSessionId = 0;
 	bool is_last_report = false;
+	uint8_t *bcn_rpt_err_vsie = NULL;
+	uint8_t vs_ie_len = 0;
+	bool bcn_rpt_err_vsie_enable = false;
 
 	tDot11fRadioMeasurementReport *frm =
 		qdf_mem_malloc(sizeof(tDot11fRadioMeasurementReport));
@@ -4510,6 +4611,9 @@
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	bcn_rpt_err_vsie_enable = lim_check_bcn_rpt_err_vsie_status(mac,
+								    error_code);
+
 	smeSessionId = pe_session->smeSessionId;
 
 
@@ -4541,6 +4645,15 @@
 						     &pRRMReport[i].report.
 						     beaconReport,
 						     is_last_report);
+
+			if (bcn_rpt_err_vsie_enable) {
+				lim_fill_beacon_report_error_vsie
+						 (pe_session,
+						  &bcn_rpt_err_vsie,
+						  &vs_ie_len, error_code);
+				nBytes = vs_ie_len;
+			}
+
 			frm->MeasurementReport[i].incapable =
 				pRRMReport[i].incapable;
 			frm->MeasurementReport[i].refused =
@@ -4566,13 +4679,15 @@
 		/* We'll fall back on the worst case scenario: */
 		nPayload = sizeof(tDot11fLinkMeasurementReport);
 		qdf_mem_free(frm);
+		qdf_mem_free(bcn_rpt_err_vsie);
 		return QDF_STATUS_E_FAILURE;
 	} else if (DOT11F_WARNED(nStatus)) {
 		pe_warn("Warnings while calculating the size for Radio Measure Report (0x%08x)",
 			nStatus);
 	}
 
-	nBytes = nPayload + sizeof(tSirMacMgmtHdr);
+	nBytes += nPayload + sizeof(tSirMacMgmtHdr);
+
 
 	qdf_status =
 		cds_packet_alloc((uint16_t) nBytes, (void **)&pFrame,
@@ -4581,6 +4696,7 @@
 		pe_nofl_err("TX: [802.11 RRM] Allocation of %d bytes failed for RM"
 			   "Report", nBytes);
 		qdf_mem_free(frm);
+		qdf_mem_free(bcn_rpt_err_vsie);
 		return QDF_STATUS_E_FAILURE;
 	}
 	/* Paranoia: */
@@ -4616,6 +4732,11 @@
 			nStatus);
 	}
 
+	if (bcn_rpt_err_vsie_enable) {
+		qdf_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload,
+			     bcn_rpt_err_vsie, vs_ie_len);
+	}
+
 	pe_nofl_info("TX: %s seq_no:%d dialog_token:%d no. of APs:%d is_last_rpt:%d num_report: %d peer:%pM",
 		     frm->MeasurementReport[0].type == SIR_MAC_RRM_BEACON_TYPE ?
 		     "[802.11 BCN_RPT]" : "[802.11 RRM]",
@@ -4645,10 +4766,12 @@
 	}
 
 	qdf_mem_free(frm);
+	qdf_mem_free(bcn_rpt_err_vsie);
 	return status_code;
 
 returnAfterError:
 	qdf_mem_free(frm);
+	qdf_mem_free(bcn_rpt_err_vsie);
 	cds_packet_free((void *)pPacket);
 	return status_code;
 }
diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h
index 64cef15..04ee519 100644
--- a/core/mac/src/pe/lim/lim_types.h
+++ b/core/mac/src/pe/lim/lim_types.h
@@ -676,6 +676,7 @@
  * @pRRMReport: Pointer to the RRM report structure
  * @peer: MAC address of the peer
  * @pe_session: Pointer to the PE session entry
+ * @beacon_report_status_code: error_code
  *
  * Return: Ret Status
  */
@@ -686,7 +687,8 @@
 				bool is_last_frame,
 				tpSirMacRadioMeasureReport pRRMReport,
 				tSirMacAddr peer,
-				struct pe_session *pe_session);
+				struct pe_session *pe_session,
+				enum beacon_report_status_code error_code);
 
 #ifdef FEATURE_WLAN_TDLS
 void lim_init_tdls_data(struct mac_context *, struct pe_session *);
diff --git a/core/mac/src/pe/rrm/rrm_api.c b/core/mac/src/pe/rrm/rrm_api.c
index f24dc24..0f315a6 100644
--- a/core/mac/src/pe/rrm/rrm_api.c
+++ b/core/mac/src/pe/rrm/rrm_api.c
@@ -466,28 +466,24 @@
 }
 
 #define ABS(x)      ((x < 0) ? -x : x)
-/* -------------------------------------------------------------------- */
+
 /**
- * rrm_process_beacon_report_req
+ * rrm_process_beacon_report_req:  Processes the Beacon report request
+ * from the peer AP.
  *
- * FUNCTION:  Processes the Beacon report request from the peer AP.
+ * @pCurrentReq: pointer to the current Req comtext.
+ * @pBeaconReq: pointer to the beacon report request IE from the peer.
+ * @pe_session: session entry.
+ * @error_code: pointer to beacon report error_code
  *
- * LOGIC:
- *
- * ASSUMPTIONS:
- *
- * NOTE:
- *
- * @param pCurrentReq pointer to the current Req comtext.
- * @param pBeaconReq pointer to the beacon report request IE from the peer.
- * @param pe_session session entry.
- * @return None
+ * @return : eRRM status
  */
 static tRrmRetStatus
 rrm_process_beacon_report_req(struct mac_context *mac,
 			      tpRRMReq pCurrentReq,
 			      tDot11fIEMeasurementRequest *pBeaconReq,
-			      struct pe_session *pe_session)
+			      struct pe_session *pe_session,
+			      enum beacon_report_status_code *error_code)
 {
 	struct scheduler_msg mmh_msg = {0};
 	tpSirBeaconReportReqInd psbrr;
@@ -511,6 +507,7 @@
 		/* IEEE Std 802.11k-2008 Table 7-29g and section 11.10.8.1 */
 
 		pe_nofl_err("RX: [802.11 BCN_RPT] Dropping req: Reporting condition included is not zero");
+		*error_code = BCN_RPT_ERR_NOT_SUPPORTED_PARAMETERS;
 		return eRRM_INCAPABLE;
 	}
 
@@ -551,6 +548,7 @@
 	if (measDuration == 0 &&
 	    pBeaconReq->measurement_request.Beacon.meas_mode !=
 	    eSIR_BEACON_TABLE) {
+		*error_code = BCN_RPT_ERR_VALIDATION_FAILED_IN_A_REQUEST_FRAME;
 		pe_nofl_err("RX: [802.11 BCN_RPT] Invalid measurement duration");
 		return eRRM_REFUSED;
 	}
@@ -558,6 +556,8 @@
 	if (maxMeasduration < measDuration) {
 		if (pBeaconReq->durationMandatory) {
 			pe_nofl_err("RX: [802.11 BCN_RPT] Dropping the req: duration mandatory & maxduration > measduration");
+			*error_code =
+			      BCN_RPT_ERR_MAXIMUM_MEASUREMENT_DURATION_EXCCEED;
 			return eRRM_REFUSED;
 		} else
 			measDuration = maxMeasduration;
@@ -584,14 +584,18 @@
 		if (!pBeaconReq->measurement_request.Beacon.RequestedInfo.
 		    num_requested_eids) {
 			pe_debug("RX: [802.11 BCN_RPT]: Requested num of EID is 0");
+			*error_code =
+			      BCN_RPT_ERR_VALIDATION_FAILED_IN_A_REQUEST_FRAME;
 			return eRRM_FAILURE;
 		}
 		pCurrentReq->request.Beacon.reqIes.pElementIds =
 			qdf_mem_malloc(sizeof(uint8_t) *
 				       pBeaconReq->measurement_request.Beacon.
 				       RequestedInfo.num_requested_eids);
-		if (!pCurrentReq->request.Beacon.reqIes.pElementIds)
+		if (!pCurrentReq->request.Beacon.reqIes.pElementIds) {
+			*error_code = BCN_RPT_ERR_TEMPORARILY_UNAVAILABLE;
 			return eRRM_FAILURE;
+		}
 
 		pCurrentReq->request.Beacon.reqIes.num =
 			pBeaconReq->measurement_request.Beacon.RequestedInfo.
@@ -604,8 +608,10 @@
 
 	/* Prepare the request to send to SME. */
 	psbrr = qdf_mem_malloc(sizeof(tSirBeaconReportReqInd));
-	if (!psbrr)
+	if (!psbrr) {
+		*error_code = BCN_RPT_ERR_TEMPORARILY_UNAVAILABLE;
 		return eRRM_FAILURE;
+	}
 
 	/* Alloc memory for pSmeBcnReportReq, will be freed by other modules */
 	qdf_mem_copy(psbrr->bssId, pe_session->bssId,
@@ -621,6 +627,7 @@
 	    (wlan_reg_is_6ghz_op_class(mac->pdev,
 			 pBeaconReq->measurement_request.Beacon.regClass))) {
 		pe_nofl_err("RX: [802.11 BCN_RPT] Ch belongs to 6 ghz spectrum, abort");
+		*error_code = BCN_RPT_ERR_NOT_SUPPORTED_PARAMETERS;
 		qdf_mem_free(psbrr);
 		return eRRM_FAILURE;
 	}
@@ -661,6 +668,8 @@
 			    (wlan_reg_is_6ghz_op_class(mac->pdev,
 					    ie_ap_chan_rpt->regulatoryClass))) {
 				pe_nofl_err("RX: [802.11 BCN_RPT] Ch belongs to 6 ghz spectrum, abort");
+				*error_code =
+					BCN_RPT_ERR_NOT_SUPPORTED_PARAMETERS;
 				qdf_mem_free(psbrr);
 				return eRRM_FAILURE;
 			}
@@ -696,6 +705,7 @@
 	MTRACE(mac_trace(mac, TRACE_CODE_TX_SME_MSG,
 			 pe_session->peSessionId, mmh_msg.type));
 	lim_sys_process_mmh_msg_api(mac, &mmh_msg);
+	*error_code = BCN_RPT_SUCCESS;
 	return eRRM_SUCCESS;
 }
 
@@ -841,6 +851,8 @@
 	uint8_t rem_len = 0;
 	uint8_t frag_id = 0;
 	uint8_t num_frames, num_reports_in_frame;
+	enum beacon_report_status_code error_code =
+					BCN_RPT_SUCCESS;
 
 	pe_debug("Received beacon report xmit indication");
 
@@ -1006,7 +1018,8 @@
 				curr_req->dialog_token, num_reports_in_frame,
 				(j == num_frames - 1) ? true : false,
 				&report[report_index],
-				beacon_xmit_ind->bssId, session_entry);
+				beacon_xmit_ind->bssId, session_entry,
+				error_code);
 			report_index += num_reports_in_frame;
 		}
 		curr_req->sendEmptyBcnRpt = false;
@@ -1030,7 +1043,9 @@
 static void rrm_process_beacon_request_failure(struct mac_context *mac,
 					       struct pe_session *pe_session,
 					       tSirMacAddr peer,
-					       tRrmRetStatus status)
+					       tRrmRetStatus status,
+					       enum beacon_report_status_code
+					       error_code)
 {
 	tpSirMacRadioMeasureReport pReport = NULL;
 	tpRRMReq pCurrentReq = mac->rrm.rrmPEContext.pCurrentReq;
@@ -1060,7 +1075,7 @@
 						   pCurrentReq->dialog_token,
 						   1, true,
 						   pReport, peer,
-						   pe_session);
+						   pe_session, error_code);
 
 	qdf_mem_free(pReport);
 	return;
@@ -1076,6 +1091,7 @@
  * @rrm_req: Array of Measurement request IEs
  * @num_report: No.of reports
  * @index: Index for Measurement request
+ * @error_code: pointer beacon report resp error code
  *
  * Update structure sRRMReq and sSirMacRadioMeasureReport and pass it to
  * rrm_process_beacon_report_req().
@@ -1087,11 +1103,12 @@
 				  struct pe_session *session_entry, tpRRMReq curr_req,
 				  tpSirMacRadioMeasureReport *radiomes_report,
 				  tDot11fRadioMeasurementRequest *rrm_req,
-				  uint8_t *num_report, int index)
+				  uint8_t *num_report, int index,
+				  enum beacon_report_status_code
+				  *error_code)
 {
 	tRrmRetStatus rrm_status = eRRM_SUCCESS;
 	tpSirMacRadioMeasureReport report;
-
 	if (curr_req) {
 		if (!*radiomes_report) {
 			/*
@@ -1100,8 +1117,11 @@
 			 */
 			*radiomes_report = qdf_mem_malloc(sizeof(*report) *
 				(rrm_req->num_MeasurementRequest - index));
-			if (!*radiomes_report)
+			if (!*radiomes_report) {
+				*error_code =
+					BCN_RPT_ERR_TEMPORARILY_UNAVAILABLE;
 				return QDF_STATUS_E_NOMEM;
+			}
 			pe_debug("rrm beacon type refused of %d report in beacon table",
 				*num_report);
 		}
@@ -1111,26 +1131,28 @@
 		report[*num_report].token =
 			rrm_req->MeasurementRequest[index].measurement_token;
 		(*num_report)++;
+		*error_code = BCN_RPT_SUCCESS;
 		return QDF_STATUS_SUCCESS;
-	} else {
-		curr_req = qdf_mem_malloc(sizeof(*curr_req));
-		if (!curr_req) {
-				qdf_mem_free(*radiomes_report);
-			return QDF_STATUS_E_NOMEM;
-		}
-		pe_debug("Processing Beacon Report request");
-		curr_req->dialog_token = rrm_req->DialogToken.token;
-		curr_req->token = rrm_req->
-				  MeasurementRequest[index].measurement_token;
-		curr_req->sendEmptyBcnRpt = true;
-		mac_ctx->rrm.rrmPEContext.pCurrentReq = curr_req;
-		rrm_status = rrm_process_beacon_report_req(mac_ctx, curr_req,
-			&rrm_req->MeasurementRequest[index], session_entry);
-		if (eRRM_SUCCESS != rrm_status) {
-			rrm_process_beacon_request_failure(mac_ctx,
-				session_entry, peer, rrm_status);
-			rrm_cleanup(mac_ctx);
-		}
+	}
+	curr_req = qdf_mem_malloc(sizeof(*curr_req));
+	if (!curr_req) {
+		qdf_mem_free(*radiomes_report);
+		return QDF_STATUS_E_NOMEM;
+	}
+	pe_debug("Processing Beacon Report request");
+	curr_req->dialog_token = rrm_req->DialogToken.token;
+	curr_req->token =
+		rrm_req->MeasurementRequest[index].measurement_token;
+	curr_req->sendEmptyBcnRpt = true;
+	mac_ctx->rrm.rrmPEContext.pCurrentReq = curr_req;
+	rrm_status =
+	    rrm_process_beacon_report_req(mac_ctx, curr_req,
+					  &rrm_req->MeasurementRequest[index],
+					  session_entry, error_code);
+	if (eRRM_SUCCESS != rrm_status) {
+		rrm_process_beacon_request_failure(mac_ctx, session_entry, peer,
+						   rrm_status, *error_code);
+		rrm_cleanup(mac_ctx);
 	}
 
 	return QDF_STATUS_SUCCESS;
@@ -1177,15 +1199,15 @@
 	return QDF_STATUS_SUCCESS;
 }
 
-/* -------------------------------------------------------------------- */
 /**
- * rrm_process_radio_measurement_request - Process rrm request
+ * rrm_process_radio_measurement_request - Processes the Radio Resource
+ * Measurement request
+ *
  * @mac_ctx: Global pointer to MAC context
  * @peer: Macaddress of the peer requesting the radio measurement.
  * @rrm_req: Array of Measurement request IEs
  * @session_entry: session entry.
- *
- * Processes the Radio Resource Measurement request.
+ * @error_code: beacon report resp error code
  *
  * Return: QDF_STATUS
  */
@@ -1193,7 +1215,9 @@
 rrm_process_radio_measurement_request(struct mac_context *mac_ctx,
 				      tSirMacAddr peer,
 				      tDot11fRadioMeasurementRequest *rrm_req,
-				      struct pe_session *session_entry)
+				      struct pe_session *session_entry,
+				      enum beacon_report_status_code
+				      error_code)
 {
 	uint8_t i;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
@@ -1208,9 +1232,10 @@
 		pe_err("RX: [802.11 RRM] No requestIes in the measurement request, sending incapable report");
 		report->incapable = 1;
 		num_report = 1;
+		error_code = BCN_RPT_ERR_VALIDATION_FAILED_IN_A_REQUEST_FRAME;
 		lim_send_radio_measure_report_action_frame(mac_ctx,
 			rrm_req->DialogToken.token, num_report, true,
-			report, peer, session_entry);
+			report, peer, session_entry, error_code);
 		qdf_mem_free(report);
 		return QDF_STATUS_E_FAILURE;
 	}
@@ -1226,6 +1251,7 @@
 		if (!report)
 			return QDF_STATUS_E_NOMEM;
 		report->incapable = 1;
+		error_code = BCN_RPT_ERR_PREVIOUS_REQUEST_PROGRESS;
 		report->type = rrm_req->MeasurementRequest[0].measurement_type;
 		num_report = 1;
 		goto end;
@@ -1237,7 +1263,7 @@
 			/* Process beacon request. */
 			status = rrm_process_beacon_req(mac_ctx, peer,
 				 session_entry, curr_req, &report, rrm_req,
-				 &num_report, i);
+				 &num_report, i, &error_code);
 			if (QDF_STATUS_SUCCESS != status)
 				return status;
 			break;
@@ -1249,6 +1275,7 @@
 			break;
 		default:
 			/* Send a report with incapabale bit set. */
+			error_code = BCN_RPT_ERR_UNSPECIFIED;
 			status = update_rrm_report(mac_ctx, &report, rrm_req,
 						   &num_report, i);
 			if (QDF_STATUS_SUCCESS != status)
@@ -1261,7 +1288,7 @@
 	if (report) {
 		lim_send_radio_measure_report_action_frame(mac_ctx,
 			rrm_req->DialogToken.token, num_report, true,
-			report, peer, session_entry);
+			report, peer, session_entry, error_code);
 		qdf_mem_free(report);
 	}
 	return status;