Browse Source

qcacld-3.0: Add null check for frequency list in rrm scan done callback

When multiple measurement requests are received in a single beacon
report request, multiple iterative scans are triggered for each
request for the frequency list provided in the request. This results
in free of rrm context global frequency list by the second
request rrm scan in the iter measurement timer start failure path
and was accessed by the scan done callback of the 1st measurement
request.

Add null check for rrm context frequency list and also if the
timer is already running, send measurement done indication for
that request.

Change-Id: I149ba47872095228595cd52535fb76c422eefba7
CRs-Fixed: 2648618
Pragaspathi Thilagaraj 5 years ago
parent
commit
24c7af6849

+ 2 - 1
core/mac/inc/ani_global.h

@@ -679,7 +679,8 @@ struct mgmt_frm_reg_info {
 };
 
 typedef struct sRrmContext {
-	tRrmSMEContext rrmSmeContext;
+	struct rrm_config_param rrmConfig;
+	tRrmSMEContext rrmSmeContext[MAX_MEASUREMENT_REQUEST];
 	tRrmPEContext rrmPEContext;
 } tRrmContext, *tpRrmContext;
 

+ 9 - 2
core/mac/src/pe/include/rrm_global.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, 2014-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2012, 2014-2020 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -27,6 +27,9 @@
 
    ========================================================================*/
 
+#define MAX_MEASUREMENT_REQUEST 2
+#define DEFAULT_RRM_IDX 0
+
 typedef enum eRrmRetStatus {
 	eRRM_SUCCESS,
 	eRRM_INCAPABLE,
@@ -49,6 +52,7 @@ struct sir_channel_info {
 typedef struct sSirBeaconReportReqInd {
 	uint16_t messageType;   /* eWNI_SME_BEACON_REPORT_REQ_IND */
 	uint16_t length;
+	uint8_t measurement_idx;
 	tSirMacAddr bssId;
 	uint16_t measurementDuration[SIR_ESE_MAX_MEAS_IE_REQS]; /* ms */
 	uint16_t randomizationInterval; /* ms */
@@ -66,6 +70,7 @@ typedef struct sSirBeaconReportReqInd {
 typedef struct sSirBeaconReportXmitInd {
 	uint16_t messageType;   /* eWNI_SME_BEACON_REPORT_RESP_XMIT_IND */
 	uint16_t length;
+	uint8_t measurement_idx;
 	tSirMacAddr bssId;
 	uint16_t uDialogToken;
 	uint8_t fMeasureDone;
@@ -131,6 +136,7 @@ typedef struct sSirNeighborReportInd {
 	uint16_t messageType;   /* eWNI_SME_NEIGHBOR_REPORT_IND */
 	uint16_t length;
 	uint8_t sessionId;
+	uint8_t measurement_idx;
 	uint16_t numNeighborReports;
 	tSirMacAddr bssId;      /* For the session. */
 	tSirNeighborBssDescription sNeighborBssDescription[1];
@@ -148,6 +154,7 @@ typedef struct sRRMBeaconReportRequestedIes {
 #define BEACON_REPORTING_DETAIL_ALL_FF_IE 2
 
 typedef struct sRRMReq {
+	uint8_t measurement_idx; /* Index of the measurement report in frame */
 	uint8_t dialog_token;   /* In action frame; */
 	uint8_t token;          /* Within individual request; */
 	uint8_t type;
@@ -211,7 +218,7 @@ typedef struct sRrmPEContext {
 	/* Dialog token for the request initiated from station. */
 	uint8_t DialogToken;
 	uint16_t prev_rrm_report_seq_num;
-	tpRRMReq pCurrentReq;
+	tpRRMReq pCurrentReq[MAX_MEASUREMENT_REQUEST];
 } tRrmPEContext, *tpRrmPEContext;
 
 /* 2008 11k spec reference: 18.4.8.5 RCPI Measurement */

+ 2 - 1
core/mac/src/pe/lim/lim_process_action_frame.c

@@ -1287,7 +1287,8 @@ __lim_process_radio_measure_request(struct mac_context *mac, uint8_t *pRxPacketI
 			 HIGH_SEQ_NUM_OFFSET) |
 			pHdr->seqControl.seqNumLo);
 	if (curr_seq_num == mac->rrm.rrmPEContext.prev_rrm_report_seq_num &&
-	    mac->rrm.rrmPEContext.pCurrentReq) {
+	    (mac->rrm.rrmPEContext.pCurrentReq[DEFAULT_RRM_IDX] ||
+	     mac->rrm.rrmPEContext.pCurrentReq[DEFAULT_RRM_IDX + 1])) {
 		pe_err("rrm report req frame, seq num: %d is already in progress, drop it",
 			curr_seq_num);
 		return;

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

@@ -8399,7 +8399,7 @@ QDF_STATUS lim_get_capability_info(struct mac_context *mac, uint16_t *pcap,
 	if (mac->mlme_cfg->scoring.apsd_enabled)
 		pcap_info->apsd = 1;
 
-	pcap_info->rrm = mac->rrm.rrmSmeContext.rrmConfig.rrm_enabled;
+	pcap_info->rrm = mac->rrm.rrmConfig.rrm_enabled;
 	pe_debug("RRM: %d", pcap_info->rrm);
 	/* DSSS-OFDM */
 	/* FIXME : no config defined yet. */

+ 55 - 29
core/mac/src/pe/rrm/rrm_api.c

@@ -390,6 +390,7 @@ rrm_process_neighbor_report_response(struct mac_context *mac,
 
 	pSmeNeighborRpt->messageType = eWNI_SME_NEIGHBOR_REPORT_IND;
 	pSmeNeighborRpt->length = length;
+	pSmeNeighborRpt->measurement_idx = DEFAULT_RRM_IDX;
 	pSmeNeighborRpt->sessionId = pe_session->smeSessionId;
 	pSmeNeighborRpt->numNeighborReports = pNeighborRep->num_NeighborReport;
 	qdf_mem_copy(pSmeNeighborRpt->bssId, pe_session->bssId,
@@ -657,6 +658,7 @@ rrm_process_beacon_report_req(struct mac_context *mac,
 	psbrr->msgSource = eRRM_MSG_SOURCE_11K;
 	psbrr->randomizationInterval =
 		SYS_TU_TO_MS(pBeaconReq->measurement_request.Beacon.randomization);
+	psbrr->measurement_idx = pCurrentReq->measurement_idx;
 
 	if (!wlan_reg_is_6ghz_supported(mac->pdev) &&
 	    (wlan_reg_is_6ghz_op_class(mac->pdev,
@@ -690,11 +692,12 @@ rrm_process_beacon_report_req(struct mac_context *mac,
 	} else {
 		psbrr->channel_info.chan_freq = 0;
 	}
-	sme_debug("opclass %d, ch %d freq %d AP's country code %c%c 0x%x",
+	sme_debug("opclass %d, ch %d freq %d AP's country code %c%c 0x%x index:%d",
 		  psbrr->channel_info.reg_class,
 		  psbrr->channel_info.chan_num,
 		  psbrr->channel_info.chan_freq,
-		  country[0], country[1], country[2]);
+		  country[0], country[1], country[2],
+		  psbrr->measurement_idx);
 
 	psbrr->measurementDuration[0] = measDuration;
 	psbrr->fMeasurementtype[0] =
@@ -895,7 +898,9 @@ rrm_process_beacon_report_xmit(struct mac_context *mac_ctx,
 	tSirMacRadioMeasureReport *report = NULL;
 	tSirMacBeaconReport *beacon_report;
 	struct bss_description *bss_desc;
-	tpRRMReq curr_req = mac_ctx->rrm.rrmPEContext.pCurrentReq;
+	tpRRMReq curr_req =
+		mac_ctx->rrm.rrmPEContext.
+		pCurrentReq[beacon_xmit_ind->measurement_idx];
 	struct pe_session *session_entry;
 	uint8_t session_id, counter;
 	uint8_t i, j, offset = 0;
@@ -905,7 +910,6 @@ rrm_process_beacon_report_xmit(struct mac_context *mac_ctx,
 	uint8_t frag_id = 0;
 	uint8_t num_frames, num_reports_in_frame;
 
-	pe_debug("Received beacon report xmit indication");
 
 	if (!beacon_xmit_ind) {
 		pe_err("Received beacon_xmit_ind is NULL in PE");
@@ -918,6 +922,9 @@ rrm_process_beacon_report_xmit(struct mac_context *mac_ctx,
 		goto end;
 	}
 
+	pe_debug("Received beacon report xmit indication on idx:%d",
+		 beacon_xmit_ind->measurement_idx);
+
 	if ((beacon_xmit_ind->numBssDesc) || curr_req->sendEmptyBcnRpt) {
 		beacon_xmit_ind->numBssDesc = (beacon_xmit_ind->numBssDesc ==
 			RRM_BCN_RPT_NO_BSS_INFO) ? RRM_BCN_RPT_MIN_RPT :
@@ -1090,13 +1097,19 @@ end:
 	return status;
 }
 
-static void rrm_process_beacon_request_failure(struct mac_context *mac,
-					       struct pe_session *pe_session,
-					       tSirMacAddr peer,
-					       tRrmRetStatus status)
+static void
+rrm_process_beacon_request_failure(struct mac_context *mac,
+				   struct pe_session *pe_session,
+				   tSirMacAddr peer,
+				   tRrmRetStatus status, uint8_t index)
 {
 	tpSirMacRadioMeasureReport pReport = NULL;
-	tpRRMReq pCurrentReq = mac->rrm.rrmPEContext.pCurrentReq;
+	tpRRMReq pCurrentReq = mac->rrm.rrmPEContext.pCurrentReq[index];
+
+	if (!pCurrentReq) {
+		pe_err("Current request is NULL");
+		return;
+	}
 
 	pReport = qdf_mem_malloc(sizeof(tSirMacRadioMeasureReport));
 	if (!pReport)
@@ -1134,7 +1147,6 @@ static void rrm_process_beacon_request_failure(struct mac_context *mac,
  * @mac_ctx: Global pointer to MAC context
  * @peer: Macaddress of the peer requesting the radio measurement
  * @session_entry: session entry
- * @curr_req: Pointer to RRM request
  * @radiomes_report: Pointer to radio measurement report
  * @rrm_req: Array of Measurement request IEs
  * @num_report: No.of reports
@@ -1147,15 +1159,16 @@ static void rrm_process_beacon_request_failure(struct mac_context *mac,
  */
 static
 QDF_STATUS rrm_process_beacon_req(struct mac_context *mac_ctx, tSirMacAddr peer,
-				  struct pe_session *session_entry, tpRRMReq curr_req,
+				  struct pe_session *session_entry,
 				  tpSirMacRadioMeasureReport *radiomes_report,
 				  tDot11fRadioMeasurementRequest *rrm_req,
 				  uint8_t *num_report, int index)
 {
 	tRrmRetStatus rrm_status = eRRM_SUCCESS;
 	tpSirMacRadioMeasureReport report;
+	tpRRMReq curr_req;
 
-	if (curr_req) {
+	if (index  >= MAX_MEASUREMENT_REQUEST) {
 		if (!*radiomes_report) {
 			/*
 			 * Allocate memory to send reports for
@@ -1176,22 +1189,30 @@ QDF_STATUS rrm_process_beacon_req(struct mac_context *mac_ctx, tSirMacAddr peer,
 		(*num_report)++;
 		return QDF_STATUS_SUCCESS;
 	} else {
+		curr_req = mac_ctx->rrm.rrmPEContext.pCurrentReq[index];
+		if (curr_req) {
+			qdf_mem_free(curr_req);
+			curr_req = NULL;
+		}
+
 		curr_req = qdf_mem_malloc(sizeof(*curr_req));
 		if (!curr_req) {
-				qdf_mem_free(*radiomes_report);
+			qdf_mem_free(*radiomes_report);
+			mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = NULL;
 			return QDF_STATUS_E_NOMEM;
 		}
-		pe_debug("Processing Beacon Report request");
+		pe_debug("Processing Beacon Report request %d", index);
 		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;
+		curr_req->measurement_idx = index;
+		mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = 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);
+				session_entry, peer, rrm_status, index);
 			rrm_cleanup(mac_ctx);
 		}
 	}
@@ -1262,7 +1283,6 @@ rrm_process_radio_measurement_request(struct mac_context *mac_ctx,
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	tpSirMacRadioMeasureReport report = NULL;
 	uint8_t num_report = 0;
-	tpRRMReq curr_req = mac_ctx->rrm.rrmPEContext.pCurrentReq;
 
 	if (!rrm_req->num_MeasurementRequest) {
 		report = qdf_mem_malloc(sizeof(tSirMacRadioMeasureReport));
@@ -1299,9 +1319,10 @@ rrm_process_radio_measurement_request(struct mac_context *mac_ctx,
 		case SIR_MAC_RRM_BEACON_TYPE:
 			/* Process beacon request. */
 			status = rrm_process_beacon_req(mac_ctx, peer,
-				 session_entry, curr_req, &report, rrm_req,
-				 &num_report, i);
-			if (QDF_STATUS_SUCCESS != status)
+							session_entry, &report,
+							rrm_req, &num_report,
+							i);
+			if (QDF_IS_STATUS_ERROR(status))
 				return status;
 			break;
 		case SIR_MAC_RRM_LCI_TYPE:
@@ -1392,7 +1413,8 @@ QDF_STATUS rrm_initialize(struct mac_context *mac)
 {
 	tpRRMCaps pRRMCaps = &mac->rrm.rrmPEContext.rrmEnabledCaps;
 
-	mac->rrm.rrmPEContext.pCurrentReq = NULL;
+	mac->rrm.rrmPEContext.pCurrentReq[0] = NULL;
+	mac->rrm.rrmPEContext.pCurrentReq[1] = NULL;
 	mac->rrm.rrmPEContext.txMgmtPower = 0;
 	mac->rrm.rrmPEContext.DialogToken = 0;
 
@@ -1435,17 +1457,21 @@ QDF_STATUS rrm_initialize(struct mac_context *mac)
 
 QDF_STATUS rrm_cleanup(struct mac_context *mac)
 {
-	if (mac->rrm.rrmPEContext.pCurrentReq) {
-		if (mac->rrm.rrmPEContext.pCurrentReq->request.Beacon.reqIes.
-		    pElementIds) {
-			qdf_mem_free(mac->rrm.rrmPEContext.pCurrentReq->
-				     request.Beacon.reqIes.pElementIds);
-		}
+	uint8_t i;
 
-		qdf_mem_free(mac->rrm.rrmPEContext.pCurrentReq);
+	for (i = 0; i < MAX_MEASUREMENT_REQUEST; i++) {
+		if (mac->rrm.rrmPEContext.pCurrentReq[i]) {
+			if (mac->rrm.rrmPEContext.pCurrentReq[i]->request.
+			    Beacon.reqIes.pElementIds)
+				qdf_mem_free(mac->rrm.rrmPEContext.
+					     pCurrentReq[i]->request.Beacon.
+					     reqIes.pElementIds);
+
+			qdf_mem_free(mac->rrm.rrmPEContext.pCurrentReq[i]);
+		}
+		mac->rrm.rrmPEContext.pCurrentReq[i] = NULL;
 	}
 
-	mac->rrm.rrmPEContext.pCurrentReq = NULL;
 	return QDF_STATUS_SUCCESS;
 }
 

+ 1 - 1
core/mac/src/pe/sch/sch_beacon_gen.c

@@ -437,7 +437,7 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess
 			}
 		}
 	}
-	if (mac_ctx->rrm.rrmSmeContext.rrmConfig.rrm_enabled)
+	if (mac_ctx->rrm.rrmConfig.rrm_enabled)
 		populate_dot11f_rrm_ie(mac_ctx, &bcn_2->RRMEnabledCap,
 			session);
 

+ 3 - 2
core/sme/inc/sme_rrm_internal.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, 2014-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2012, 2014-2018, 2020 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -64,6 +64,7 @@ typedef struct sRrmSMEContext {
 	uint16_t token;
 	struct qdf_mac_addr sessionBssId;
 	uint8_t regClass;
+	uint8_t measurement_idx;
 	/* list of all channels to be measured. */
 	tCsrChannelInfo channelList;
 	uint8_t currentIndex;
@@ -74,7 +75,7 @@ typedef struct sRrmSMEContext {
 	uint16_t randnIntvl;
 	uint16_t duration[SIR_ESE_MAX_MEAS_IE_REQS];
 	uint8_t measMode[SIR_ESE_MAX_MEAS_IE_REQS];
-	struct rrm_config_param rrmConfig;
+	uint32_t scan_id;
 	qdf_mc_timer_t IterMeasTimer;
 	tDblLinkList neighborReportCache;
 	tRrmNeighborRequestControlInfo neighborReqControlInfo;

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

@@ -826,12 +826,12 @@ void sme_update_fine_time_measurement_capab(mac_handle_t mac_handle,
 
 	if (!val) {
 		mac_ctx->rrm.rrmPEContext.rrmEnabledCaps.fine_time_meas_rpt = 0;
-		((tpRRMCaps)mac_ctx->rrm.rrmSmeContext.
-			rrmConfig.rm_capability)->fine_time_meas_rpt = 0;
+		((tpRRMCaps)mac_ctx->rrm.rrmConfig.
+			rm_capability)->fine_time_meas_rpt = 0;
 	} else {
 		mac_ctx->rrm.rrmPEContext.rrmEnabledCaps.fine_time_meas_rpt = 1;
-		((tpRRMCaps)mac_ctx->rrm.rrmSmeContext.
-			rrmConfig.rm_capability)->fine_time_meas_rpt = 1;
+		((tpRRMCaps)mac_ctx->rrm.rrmConfig.
+			rm_capability)->fine_time_meas_rpt = 1;
 	}
 
 	/* Inform this RRM IE change to FW */
@@ -1643,7 +1643,7 @@ QDF_STATUS sme_set_ese_beacon_request(mac_handle_t mac_handle,
 	const tCsrEseBeaconReqParams *bcn_req = NULL;
 	uint8_t counter = 0;
 	struct csr_roam_session *session = CSR_GET_SESSION(mac, sessionId);
-	tpRrmSMEContext sme_rrm_ctx = &mac->rrm.rrmSmeContext;
+	tpRrmSMEContext sme_rrm_ctx = &mac->rrm.rrmSmeContext[0];
 
 	if (sme_rrm_ctx->eseBcnReqInProgress == true) {
 		sme_err("A Beacon Report Req is already in progress");
@@ -1671,6 +1671,7 @@ QDF_STATUS sme_set_ese_beacon_request(mac_handle_t mac_handle,
 	sme_bcn_rpt_req->channel_info.chan_num = 255;
 	sme_bcn_rpt_req->channel_list.num_channels = in_req->numBcnReqIe;
 	sme_bcn_rpt_req->msgSource = eRRM_MSG_SOURCE_ESE_UPLOAD;
+	sme_bcn_rpt_req->measurement_idx = 0;
 
 	for (counter = 0; counter < in_req->numBcnReqIe; counter++) {
 		bcn_req = &in_req->bcnReq[counter];
@@ -3402,7 +3403,7 @@ QDF_STATUS sme_oem_update_capability(mac_handle_t mac_handle,
 	struct mac_context *pmac = MAC_CONTEXT(mac_handle);
 	uint8_t *bytes;
 
-	bytes = pmac->rrm.rrmSmeContext.rrmConfig.rm_capability;
+	bytes = pmac->rrm.rrmConfig.rm_capability;
 
 	if (cap->ftm_rr)
 		bytes[4] |= RM_CAP_FTM_RANGE_REPORT;
@@ -3430,7 +3431,7 @@ QDF_STATUS sme_oem_get_capability(mac_handle_t mac_handle,
 	struct mac_context *pmac = MAC_CONTEXT(mac_handle);
 	uint8_t *bytes;
 
-	bytes = pmac->rrm.rrmSmeContext.rrmConfig.rm_capability;
+	bytes = pmac->rrm.rrmConfig.rm_capability;
 
 	cap->ftm_rr = bytes[4] & RM_CAP_FTM_RANGE_REPORT;
 	cap->lci_capability = bytes[4] & RM_CAP_CIVIC_LOC_MEASUREMENT;

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

@@ -16189,7 +16189,7 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId,
 
 		/* Fill rrm config parameters */
 		qdf_mem_copy(&csr_join_req->rrm_config,
-			     &mac->rrm.rrmSmeContext.rrmConfig,
+			     &mac->rrm.rrmConfig,
 			     sizeof(struct rrm_config_param));
 
 		pAP_capabilityInfo =

+ 258 - 158
core/sme/src/rrm/sme_rrm.c

@@ -112,46 +112,45 @@ static void rrm_indicate_neighbor_report_result(struct mac_context *mac,
 	void *callbackContext;
 
 	/* Reset the neighbor response pending status */
-	mac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending =
-		false;
+	mac->rrm.rrmSmeContext[DEFAULT_RRM_IDX].
+	neighborReqControlInfo.isNeighborRspPending = false;
 
 	/* Stop the timer if it is already running.
 	 *  The timer should be running only in the SUCCESS case.
 	 */
 	if (QDF_TIMER_STATE_RUNNING ==
-	    qdf_mc_timer_get_current_state(&mac->rrm.rrmSmeContext.
+	    qdf_mc_timer_get_current_state(&mac->rrm.rrmSmeContext[DEFAULT_RRM_IDX].
 					   neighborReqControlInfo.
 					   neighborRspWaitTimer)) {
 		sme_debug("No entry in neighbor report cache");
-		qdf_mc_timer_stop(&mac->rrm.rrmSmeContext.
+		qdf_mc_timer_stop(&mac->rrm.rrmSmeContext[DEFAULT_RRM_IDX].
 				  neighborReqControlInfo.neighborRspWaitTimer);
 	}
 	callback =
-		mac->rrm.rrmSmeContext.neighborReqControlInfo.
+		mac->rrm.rrmSmeContext[DEFAULT_RRM_IDX].neighborReqControlInfo.
 		neighborRspCallbackInfo.neighborRspCallback;
 	callbackContext =
-		mac->rrm.rrmSmeContext.neighborReqControlInfo.
+		mac->rrm.rrmSmeContext[DEFAULT_RRM_IDX].neighborReqControlInfo.
 		neighborRspCallbackInfo.neighborRspCallbackContext;
 
 	/* Reset the callback and the callback context before calling the
 	 * callback. It is very likely that there may be a registration in
 	 * callback itself.
 	 */
-	mac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.
-	neighborRspCallback = NULL;
-	mac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.
-	neighborRspCallbackContext = NULL;
+	mac->rrm.rrmSmeContext[DEFAULT_RRM_IDX].neighborReqControlInfo.
+		neighborRspCallbackInfo.neighborRspCallback = NULL;
+	mac->rrm.rrmSmeContext[DEFAULT_RRM_IDX].neighborReqControlInfo.
+		neighborRspCallbackInfo.neighborRspCallbackContext = NULL;
 
 	/* Call the callback with the status received from caller */
 	if (callback)
 		callback(callbackContext, qdf_status);
-
-
 }
 
 /**
  * sme_RrmBeaconReportXmitInd () - Send beacon report
  * @mac_ctx  Pointer to mac context
+ * @measurement_index: Measurement index
  * @result_arr scan results
  * @msrmnt_status flag to indicate that the measurement is done.
  * @bss_count  bss count
@@ -163,8 +162,8 @@ static void rrm_indicate_neighbor_report_result(struct mac_context *mac,
 
 static QDF_STATUS
 sme_rrm_send_beacon_report_xmit_ind(struct mac_context *mac_ctx,
-	tCsrScanResultInfo **result_arr, uint8_t msrmnt_status,
-	uint8_t bss_count)
+	uint8_t measurement_index, tCsrScanResultInfo **result_arr,
+	uint8_t msrmnt_status, uint8_t bss_count)
 {
 	struct bss_description *bss_desc = NULL;
 	tpSirBeaconReportXmitInd beacon_rep;
@@ -173,7 +172,8 @@ sme_rrm_send_beacon_report_xmit_ind(struct mac_context *mac_ctx,
 	uint8_t  i = 0, j = 0, counter = 0;
 	tCsrScanResultInfo *cur_result = NULL;
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
-	tpRrmSMEContext rrm_ctx = &mac_ctx->rrm.rrmSmeContext;
+	tpRrmSMEContext rrm_ctx =
+			&mac_ctx->rrm.rrmSmeContext[measurement_index];
 	struct bss_description *tmp_bss_desc[SIR_BCN_REPORT_MAX_BSS_DESC] = {0};
 
 	if (!result_arr && !msrmnt_status) {
@@ -192,6 +192,7 @@ sme_rrm_send_beacon_report_xmit_ind(struct mac_context *mac_ctx,
 
 		beacon_rep->messageType = eWNI_SME_BEACON_REPORT_RESP_XMIT_IND;
 		beacon_rep->length = length;
+		beacon_rep->measurement_idx = measurement_index;
 		beacon_rep->uDialogToken = rrm_ctx->token;
 		beacon_rep->duration = rrm_ctx->duration[0];
 		beacon_rep->regClass = rrm_ctx->regClass;
@@ -253,6 +254,7 @@ sme_rrm_send_beacon_report_xmit_ind(struct mac_context *mac_ctx,
 /**
  * sme_ese_send_beacon_req_scan_results () - Send beacon report
  * @mac_ctx: Pointer to mac context
+ * @measurement_index: Measurement request index
  * @session_id: session id
  * @freq: channel frequency
  * @result_arr: scan results
@@ -268,8 +270,9 @@ sme_rrm_send_beacon_report_xmit_ind(struct mac_context *mac_ctx,
  * Return: status
  */
 static QDF_STATUS sme_ese_send_beacon_req_scan_results(
-	struct mac_context *mac_ctx, uint32_t session_id,
-	uint32_t freq, tCsrScanResultInfo **result_arr,
+	struct mac_context *mac_ctx, uint8_t measurement_index,
+	uint32_t session_id, uint32_t freq,
+	tCsrScanResultInfo **result_arr,
 	uint8_t msrmnt_status, uint8_t bss_count)
 {
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
@@ -279,7 +282,8 @@ static QDF_STATUS sme_ese_send_beacon_req_scan_results(
 	uint32_t out_ie_len = 0;
 	uint8_t bss_counter = 0;
 	tCsrScanResultInfo *cur_result = NULL;
-	tpRrmSMEContext rrm_ctx = &mac_ctx->rrm.rrmSmeContext;
+	tpRrmSMEContext rrm_ctx =
+		&mac_ctx->rrm.rrmSmeContext[measurement_index];
 	struct csr_roam_info *roam_info;
 	struct ese_bcn_report_rsp bcn_rpt_rsp;
 	struct ese_bcn_report_rsp *bcn_report = &bcn_rpt_rsp;
@@ -419,6 +423,7 @@ void sme_reset_ese_bcn_req_in_progress(tpRrmSMEContext sme_rrm_ctx)
 /**
  * sme_rrm_send_scan_result() - to get scan result and send the beacon report
  * @mac_ctx: pointer to mac context
+ * @measurement_index: Measurement request number
  * @num_chan: number of channels
  * @freq_list: list of channel frequencies to fetch the result from
  * @measurementdone: Flag to indicate measurement done or no
@@ -429,6 +434,7 @@ void sme_reset_ese_bcn_req_in_progress(tpRrmSMEContext sme_rrm_ctx)
  * Return: QDF_STATUS
  */
 static QDF_STATUS sme_rrm_send_scan_result(struct mac_context *mac_ctx,
+					   uint8_t measurement_index,
 					   uint8_t num_chan,
 					   uint32_t *freq_list,
 					   uint8_t measurementdone)
@@ -441,7 +447,8 @@ static QDF_STATUS sme_rrm_send_scan_result(struct mac_context *mac_ctx,
 	struct scan_result_list *result_list;
 	QDF_STATUS status;
 	uint8_t num_scan_results, counter = 0;
-	tpRrmSMEContext rrm_ctx = &mac_ctx->rrm.rrmSmeContext;
+	tpRrmSMEContext rrm_ctx =
+		&mac_ctx->rrm.rrmSmeContext[measurement_index];
 	uint32_t session_id;
 	struct csr_roam_info *roam_info = NULL;
 	tSirScanType scan_type;
@@ -511,12 +518,14 @@ static QDF_STATUS sme_rrm_send_scan_result(struct mac_context *mac_ctx,
 #ifdef FEATURE_WLAN_ESE
 		if (eRRM_MSG_SOURCE_ESE_UPLOAD == rrm_ctx->msgSource)
 			status = sme_ese_send_beacon_req_scan_results(mac_ctx,
-					session_id, freq_list[0],
-					NULL, measurementdone, 0);
+					measurement_index, session_id,
+					freq_list[0], NULL,
+					measurementdone, 0);
 		else
 #endif /* FEATURE_WLAN_ESE */
 			status = sme_rrm_send_beacon_report_xmit_ind(mac_ctx,
-					NULL, measurementdone, 0);
+							measurement_index, NULL,
+							measurementdone, 0);
 		return status;
 	}
 	scan_results = sme_scan_result_get_first(mac_handle, result_handle);
@@ -524,14 +533,13 @@ static QDF_STATUS sme_rrm_send_scan_result(struct mac_context *mac_ctx,
 #ifdef FEATURE_WLAN_ESE
 		if (eRRM_MSG_SOURCE_ESE_UPLOAD == rrm_ctx->msgSource) {
 			status = sme_ese_send_beacon_req_scan_results(mac_ctx,
-					session_id,
-					freq_list[0],
-					NULL,
-					measurementdone,
-					0);
+					measurement_index, session_id,
+					freq_list[0], NULL,
+					measurementdone, 0);
 		} else
 #endif /* FEATURE_WLAN_ESE */
 			status = sme_rrm_send_beacon_report_xmit_ind(mac_ctx,
+						measurement_index,
 						NULL, measurementdone, 0);
 	}
 
@@ -621,14 +629,14 @@ static QDF_STATUS sme_rrm_send_scan_result(struct mac_context *mac_ctx,
 #ifdef FEATURE_WLAN_ESE
 		if (eRRM_MSG_SOURCE_ESE_UPLOAD == rrm_ctx->msgSource)
 			status = sme_ese_send_beacon_req_scan_results(mac_ctx,
-					session_id, freq_list[0],
-					scanresults_arr, measurementdone,
-					counter);
+					measurement_index, session_id,
+					freq_list[0], scanresults_arr,
+					measurementdone, counter);
 		else
 #endif /* FEATURE_WLAN_ESE */
 			status = sme_rrm_send_beacon_report_xmit_ind(mac_ctx,
-					scanresults_arr, measurementdone,
-					counter);
+					measurement_index, scanresults_arr,
+					measurementdone, counter);
 	}
 
 rrm_send_scan_results_done:
@@ -644,6 +652,7 @@ rrm_send_scan_results_done:
 /**
  * sme_rrm_scan_request_callback() -Sends the beacon report xmit to PE
  * @mac_handle: Opaque handle to the MAC context
+ * @pSmeRrmContext: SME rrm context for measurement request
  * @sessionId: session id
  * @scanId: Scan ID.
  * @status: CSR Status.
@@ -654,14 +663,13 @@ rrm_send_scan_results_done:
  *
  * Return : 0 for success, non zero for failure
  */
-static QDF_STATUS sme_rrm_scan_request_callback(mac_handle_t mac_handle,
+static QDF_STATUS sme_rrm_scan_request_callback(struct mac_context *mac,
+						tpRrmSMEContext pSmeRrmContext,
 						uint8_t sessionId,
 						uint32_t scanId,
 						eCsrScanStatus status)
 {
 	uint16_t interval;
-	struct mac_context *mac = MAC_CONTEXT(mac_handle);
-	tpRrmSMEContext pSmeRrmContext = &mac->rrm.rrmSmeContext;
 	uint32_t time_tick;
 	QDF_STATUS qdf_status;
 	uint32_t session_id;
@@ -685,10 +693,41 @@ static QDF_STATUS sme_rrm_scan_request_callback(mac_handle_t mac_handle,
 	 * within randomization interval.
 	 */
 	freq_list = pSmeRrmContext->channelList.freq_list;
+	if (!freq_list) {
+		sme_err("[802.11 RRM]: Global freq list is null");
+		pSmeRrmContext->channelList.numOfChannels = 0;
+		sme_reset_ese_bcn_req_in_progress(pSmeRrmContext);
+		return QDF_STATUS_E_FAILURE;
+	}
+
 	ch_idx = pSmeRrmContext->currentIndex;
 	num_chan = pSmeRrmContext->channelList.numOfChannels;
 	if (((ch_idx + 1) < num_chan) && valid_result) {
-		sme_rrm_send_scan_result(mac, 1, &freq_list[ch_idx], false);
+		if (QDF_TIMER_STATE_RUNNING ==
+		    qdf_mc_timer_get_current_state(
+				      &pSmeRrmContext->IterMeasTimer)) {
+			/*
+			 * Measurement random timer is already running, this
+			 * should not happen because the driver doesn't support
+			 * multiple measurements simultaneously. Also for
+			 * multiple measurements on a single report, the
+			 * channels in op class should be appended to the global
+			 * frequency list
+			 */
+			sme_err("[802.11 RRM]: meas timer is already running");
+			sme_rrm_send_scan_result(mac,
+					pSmeRrmContext->measurement_idx,
+					1, &freq_list[ch_idx], true);
+			qdf_mem_free(pSmeRrmContext->channelList.freq_list);
+			pSmeRrmContext->channelList.freq_list = NULL;
+			pSmeRrmContext->channelList.numOfChannels = 0;
+			sme_reset_ese_bcn_req_in_progress(pSmeRrmContext);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		sme_rrm_send_scan_result(mac, pSmeRrmContext->measurement_idx,
+					 1, &freq_list[ch_idx], false);
+
 		/* Advance the current index. */
 		pSmeRrmContext->currentIndex++;
 		/* start the timer to issue next request. */
@@ -705,6 +744,7 @@ static QDF_STATUS sme_rrm_scan_request_callback(mac_handle_t mac_handle,
 		if (QDF_IS_STATUS_ERROR(qdf_status)) {
 			qdf_mem_free(pSmeRrmContext->channelList.freq_list);
 			pSmeRrmContext->channelList.freq_list = NULL;
+			pSmeRrmContext->channelList.numOfChannels = 0;
 			sme_reset_ese_bcn_req_in_progress(pSmeRrmContext);
 		}
 
@@ -712,9 +752,11 @@ static QDF_STATUS sme_rrm_scan_request_callback(mac_handle_t mac_handle,
 		/* Done with the measurement. Clean up all context and send a
 		 * message to PE with measurement done flag set.
 		 */
-		sme_rrm_send_scan_result(mac, 1, &freq_list[ch_idx], true);
+		sme_rrm_send_scan_result(mac, pSmeRrmContext->measurement_idx,
+					 1, &freq_list[ch_idx], true);
 		qdf_mem_free(pSmeRrmContext->channelList.freq_list);
 		pSmeRrmContext->channelList.freq_list = NULL;
+		pSmeRrmContext->channelList.numOfChannels = 0;
 		sme_reset_ese_bcn_req_in_progress(pSmeRrmContext);
 	}
 
@@ -724,21 +766,22 @@ static QDF_STATUS sme_rrm_scan_request_callback(mac_handle_t mac_handle,
 static void sme_rrm_scan_event_callback(struct wlan_objmgr_vdev *vdev,
 			struct scan_event *event, void *arg)
 {
+	struct mac_context *mac_ctx;
 	uint32_t scan_id;
-	uint8_t session_id;
+	uint8_t session_id, i;
 	eCsrScanStatus scan_status = eCSR_SCAN_FAILURE;
-	mac_handle_t mac_handle;
 	bool success = false;
+	tpRrmSMEContext smerrmctx;
 
-	session_id = wlan_vdev_get_id(vdev);
-	scan_id = event->scan_id;
-	mac_handle = cds_get_context(QDF_MODULE_ID_SME);
-	if (!mac_handle) {
-		QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_FATAL,
-			  FL("invalid h_hal"));
+	mac_ctx = (struct mac_context *)arg;
+	if (!mac_ctx) {
+		sme_err("invalid mac_ctx");
 		return;
 	}
 
+	session_id = wlan_vdev_get_id(vdev);
+	scan_id = event->scan_id;
+
 	qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_SME, event->type,
 		   event->vdev_id, event->scan_id);
 
@@ -748,11 +791,21 @@ static void sme_rrm_scan_event_callback(struct wlan_objmgr_vdev *vdev,
 	if (success)
 		scan_status = eCSR_SCAN_SUCCESS;
 
-	sme_rrm_scan_request_callback(mac_handle, session_id,
+	for (i = 0; i < MAX_MEASUREMENT_REQUEST; i++) {
+		smerrmctx = &mac_ctx->rrm.rrmSmeContext[i];
+		if (smerrmctx->scan_id == scan_id)
+			break;
+
+		if (i == (MAX_MEASUREMENT_REQUEST - 1))
+			return;
+	}
+
+	sme_debug("Scan completed for scan_id:%d measurement_idx:%d",
+		  scan_id, smerrmctx->measurement_idx);
+	sme_rrm_scan_request_callback(mac_ctx, smerrmctx, session_id,
 				      scan_id, scan_status);
 }
 
-
 /**
  * sme_rrm_issue_scan_req() - To issue rrm scan request
  * @mac_ctx: pointer to mac context
@@ -761,10 +814,11 @@ static void sme_rrm_scan_event_callback(struct wlan_objmgr_vdev *vdev,
  *
  * Return: QDF_STATUS
  */
-static QDF_STATUS sme_rrm_issue_scan_req(struct mac_context *mac_ctx)
+static QDF_STATUS
+sme_rrm_issue_scan_req(struct mac_context *mac_ctx, uint8_t idx)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
-	tpRrmSMEContext sme_rrm_ctx = &mac_ctx->rrm.rrmSmeContext;
+	tpRrmSMEContext sme_rrm_ctx = &mac_ctx->rrm.rrmSmeContext[idx];
 	uint32_t session_id;
 	tSirScanType scan_type;
 	uint8_t ch_idx;
@@ -781,7 +835,8 @@ static QDF_STATUS sme_rrm_issue_scan_req(struct mac_context *mac_ctx)
 
 	if ((sme_rrm_ctx->currentIndex) >=
 			sme_rrm_ctx->channelList.numOfChannels) {
-		sme_rrm_send_beacon_report_xmit_ind(mac_ctx, NULL, true, 0);
+		sme_rrm_send_beacon_report_xmit_ind(mac_ctx, idx, NULL,
+						    true, 0);
 		sme_debug("done with the complete ch lt. finish and fee now");
 		goto free_ch_lst;
 	}
@@ -818,6 +873,10 @@ static QDF_STATUS sme_rrm_issue_scan_req(struct mac_context *mac_ctx)
 		}
 		ucfg_scan_init_default_params(vdev, req);
 		req->scan_req.scan_id = ucfg_scan_get_scan_id(mac_ctx->psoc);
+		sme_rrm_ctx->scan_id = req->scan_req.scan_id;
+
+		sme_debug("RRM_SCN: rrm_idx:%d scan_id:%d",
+			  sme_rrm_ctx->measurement_idx, sme_rrm_ctx->scan_id);
 		req->scan_req.scan_f_passive =
 				(scan_type == eSIR_ACTIVE_SCAN) ? false : true;
 		req->scan_req.vdev_id = wlan_vdev_get_id(vdev);
@@ -924,11 +983,11 @@ static QDF_STATUS sme_rrm_issue_scan_req(struct mac_context *mac_ctx)
 		freq_list = sme_rrm_ctx->channelList.freq_list;
 		ch_idx = sme_rrm_ctx->currentIndex;
 		if ((ch_idx + 1) < sme_rrm_ctx->channelList.numOfChannels) {
-			sme_rrm_send_scan_result(mac_ctx, 1,
+			sme_rrm_send_scan_result(mac_ctx, idx, 1,
 						 &freq_list[ch_idx], false);
 			/* Advance the current index. */
 			sme_rrm_ctx->currentIndex++;
-			sme_rrm_issue_scan_req(mac_ctx);
+			sme_rrm_issue_scan_req(mac_ctx, idx);
 #ifdef FEATURE_WLAN_ESE
 			sme_rrm_ctx->eseBcnReqInProgress = false;
 #endif
@@ -938,7 +997,7 @@ static QDF_STATUS sme_rrm_issue_scan_req(struct mac_context *mac_ctx)
 			 * Done with the measurement. Clean up all context and
 			 * send a message to PE with measurement done flag set.
 			 */
-			sme_rrm_send_scan_result(mac_ctx, 1,
+			sme_rrm_send_scan_result(mac_ctx, idx, 1,
 						 &freq_list[ch_idx], true);
 			goto free_ch_lst;
 		}
@@ -951,7 +1010,7 @@ static QDF_STATUS sme_rrm_issue_scan_req(struct mac_context *mac_ctx)
 	 * and PE will not handle subsequent Beacon requests
 	 */
 send_ind:
-	sme_rrm_send_beacon_report_xmit_ind(mac_ctx, NULL, true, 0);
+	sme_rrm_send_beacon_report_xmit_ind(mac_ctx, idx, NULL, true, 0);
 free_ch_lst:
 	qdf_mem_free(sme_rrm_ctx->channelList.freq_list);
 	sme_rrm_ctx->channelList.freq_list = NULL;
@@ -1023,7 +1082,7 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 						 void *msg_buf)
 {
 	tpSirBeaconReportReqInd beacon_req = (tpSirBeaconReportReqInd)msg_buf;
-	tpRrmSMEContext sme_rrm_ctx = &mac->rrm.rrmSmeContext;
+	tpRrmSMEContext sme_rrm_ctx;
 	uint32_t len = 0, i = 0;
 	uint8_t country[WNI_CFG_COUNTRY_CODE_LEN];
 	uint32_t session_id;
@@ -1034,6 +1093,8 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 	uint32_t *rrm_freq_list;
 	uint32_t bcn_chan_freq;
 
+	sme_rrm_ctx = &mac->rrm.rrmSmeContext[beacon_req->measurement_idx];
+
 	status = csr_roam_get_session_id_from_bssid(mac, (struct qdf_mac_addr *)
 						    beacon_req->bssId,
 						    &session_id);
@@ -1056,7 +1117,8 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 	else
 		country[2] = OP_CLASS_GLOBAL;
 
-	sme_debug("Request Reg class %d, AP's country code %c%c 0x%x, channel = %d",
+	sme_debug("RRM_SCN: Index:%d Request Reg class %d, AP's country code %c%c 0x%x, channel = %d",
+		  beacon_req->measurement_idx,
 		  beacon_req->channel_info.reg_class,
 		  country[0], country[1], country[2],
 		  beacon_req->channel_info.chan_num);
@@ -1172,7 +1234,7 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 	sme_rrm_ctx->regClass = beacon_req->channel_info.reg_class;
 	sme_rrm_ctx->randnIntvl =
 		QDF_MAX(beacon_req->randomizationInterval,
-			sme_rrm_ctx->rrmConfig.max_randn_interval);
+			mac->rrm.rrmConfig.max_randn_interval);
 	sme_rrm_ctx->currentIndex = 0;
 	sme_rrm_ctx->msgSource = beacon_req->msgSource;
 	qdf_mem_copy((uint8_t *)&sme_rrm_ctx->measMode,
@@ -1188,7 +1250,7 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 		  sme_rrm_ctx->duration[0],
 		  sme_rrm_get_meas_mode_string(sme_rrm_ctx->measMode[0]));
 
-	return sme_rrm_issue_scan_req(mac);
+	return sme_rrm_issue_scan_req(mac, beacon_req->measurement_idx);
 
 cleanup:
 	if (beacon_req->msgSource == eRRM_MSG_SOURCE_11K) {
@@ -1199,7 +1261,8 @@ cleanup:
 		/* copy measurement bssid */
 		qdf_mem_copy(sme_rrm_ctx->bssId, beacon_req->macaddrBssid,
 			     sizeof(tSirMacAddr));
-		sme_rrm_send_beacon_report_xmit_ind(mac, NULL, true, 0);
+		sme_rrm_send_beacon_report_xmit_ind(mac,
+			     sme_rrm_ctx->measurement_idx, NULL, true, 0);
 	}
 
 	return status;
@@ -1234,7 +1297,7 @@ QDF_STATUS sme_rrm_neighbor_report_request(struct mac_context *mac, uint8_t
 
 	/* If already a report is pending, return failure */
 	if (true ==
-	    mac->rrm.rrmSmeContext.neighborReqControlInfo.
+	    mac->rrm.rrmSmeContext[0].neighborReqControlInfo.
 	    isNeighborRspPending) {
 		sme_err("Neighbor request already pending.. Not allowed");
 		return QDF_STATUS_E_AGAIN;
@@ -1245,7 +1308,7 @@ QDF_STATUS sme_rrm_neighbor_report_request(struct mac_context *mac, uint8_t
 		return QDF_STATUS_E_NOMEM;
 
 	rrm_ll_purge_neighbor_cache(mac,
-			    &mac->rrm.rrmSmeContext.neighborReportCache);
+			    &mac->rrm.rrmSmeContext[0].neighborReportCache);
 
 	pMsg->messageType = eWNI_SME_NEIGHBOR_REPORT_REQ_IND;
 	pMsg->length = sizeof(tSirNeighborReportReqInd);
@@ -1261,16 +1324,17 @@ QDF_STATUS sme_rrm_neighbor_report_request(struct mac_context *mac, uint8_t
 	/* Neighbor report request message sent successfully to PE.
 	 * Now register the callbacks
 	 */
-	mac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.
-	neighborRspCallback = callbackInfo->neighborRspCallback;
-	mac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.
-	neighborRspCallbackContext =
-		callbackInfo->neighborRspCallbackContext;
-	mac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending =
+	mac->rrm.rrmSmeContext[0].neighborReqControlInfo.
+		neighborRspCallbackInfo.neighborRspCallback =
+			callbackInfo->neighborRspCallback;
+	mac->rrm.rrmSmeContext[0].neighborReqControlInfo.
+		neighborRspCallbackInfo.neighborRspCallbackContext =
+			callbackInfo->neighborRspCallbackContext;
+	mac->rrm.rrmSmeContext[0].neighborReqControlInfo.isNeighborRspPending =
 		true;
 
 	/* Start neighbor response wait timer now */
-	qdf_mc_timer_start(&mac->rrm.rrmSmeContext.neighborReqControlInfo.
+	qdf_mc_timer_start(&mac->rrm.rrmSmeContext[0].neighborReqControlInfo.
 			   neighborRspWaitTimer, callbackInfo->timeout);
 
 	return QDF_STATUS_SUCCESS;
@@ -1363,7 +1427,9 @@ check_11r_assoc:
 
 /**
  * rrm_store_neighbor_rpt_by_roam_score()-store Neighbor BSS descriptor
+ * @mac: Pointer to mac context
  * @pNeighborReportDesc - Neighbor BSS Descriptor node to be stored in cache
+ * @index: RRM sme context index
  *
  * This API is called to store a given
  * Neighbor BSS descriptor to the neighbor cache. This function
@@ -1373,9 +1439,10 @@ check_11r_assoc:
  * Return: void.
  */
 static void rrm_store_neighbor_rpt_by_roam_score(struct mac_context *mac,
-				tpRrmNeighborReportDesc pNeighborReportDesc)
+				tpRrmNeighborReportDesc pNeighborReportDesc,
+				uint8_t index)
 {
-	tpRrmSMEContext pSmeRrmContext = &mac->rrm.rrmSmeContext;
+	tpRrmSMEContext pSmeRrmContext = &mac->rrm.rrmSmeContext[0];
 	tListElem *pEntry;
 	tRrmNeighborReportDesc *pTempNeighborReportDesc;
 
@@ -1451,11 +1518,11 @@ static QDF_STATUS sme_rrm_process_neighbor_report(struct mac_context *mac,
 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
 
 	/* Purge the cache on reception of unsolicited neighbor report */
-	if (!mac->rrm.rrmSmeContext.neighborReqControlInfo.
-			isNeighborRspPending)
+	if (!mac->rrm.rrmSmeContext[neighbor_rpt->measurement_idx].
+	    neighborReqControlInfo.isNeighborRspPending)
 		rrm_ll_purge_neighbor_cache(mac,
-					    &mac->rrm.rrmSmeContext.
-					    neighborReportCache);
+			&mac->rrm.rrmSmeContext[neighbor_rpt->measurement_idx].
+			neighborReportCache);
 
 	for (i = 0; i < neighbor_rpt->numNeighborReports; i++) {
 		neighbor_rpt_desc =
@@ -1485,8 +1552,9 @@ static QDF_STATUS sme_rrm_process_neighbor_report(struct mac_context *mac,
 		rrm_calculate_neighbor_ap_roam_score(mac, neighbor_rpt_desc);
 
 		if (neighbor_rpt_desc->roamScore > 0) {
-			rrm_store_neighbor_rpt_by_roam_score(mac,
-							     neighbor_rpt_desc);
+			rrm_store_neighbor_rpt_by_roam_score(
+					mac, neighbor_rpt_desc,
+					neighbor_rpt->measurement_idx);
 		} else {
 			sme_err("Roam score of BSSID  " QDF_MAC_ADDR_STR
 				" is 0, Ignoring..",
@@ -1501,7 +1569,9 @@ static QDF_STATUS sme_rrm_process_neighbor_report(struct mac_context *mac,
 	}
 end:
 
-	if (!csr_ll_count(&mac->rrm.rrmSmeContext.neighborReportCache))
+	if (!csr_ll_count(
+		&mac->rrm.rrmSmeContext[neighbor_rpt->measurement_idx].
+		neighborReportCache))
 		qdf_status = QDF_STATUS_E_FAILURE;
 
 	rrm_indicate_neighbor_report_result(mac, qdf_status);
@@ -1554,14 +1624,24 @@ QDF_STATUS sme_rrm_msg_processor(struct mac_context *mac, uint16_t msg_type,
  *
  * Return: NULL
  */
-static void rrm_iter_meas_timer_handle(void *userData)
+static void rrm_iter_meas_timer_handle(void *data)
 {
-	struct mac_context *mac = (struct mac_context *) userData;
+	struct mac_context *mac;
+	mac_handle_t mac_handle = cds_get_context(QDF_MODULE_ID_SME);
+	tpRrmSMEContext sme_rrm_ctx = (tpRrmSMEContext)data;
+
+	mac = MAC_CONTEXT(mac_handle);
+	if (!mac) {
+		sme_err("Mac ctx is NULL");
+		return;
+	}
 
 	sme_debug("Randomization timer expired...send on next channel");
+
 	/* Issue a scan req for next channel. */
-	sme_rrm_issue_scan_req(mac);
+	sme_rrm_issue_scan_req(mac, sme_rrm_ctx->measurement_idx);
 }
+
 /**
  * rrm_neighbor_rsp_timeout_handler() - Timer handler to handlet the timeout
  * @mac - The handle returned by mac_open.
@@ -1587,12 +1667,12 @@ static void rrm_neighbor_rsp_timeout_handler(void *userData)
  */
 static void rrm_change_default_config_param(struct mac_context *mac)
 {
-	mac->rrm.rrmSmeContext.rrmConfig.rrm_enabled =
+	mac->rrm.rrmConfig.rrm_enabled =
 			mac->mlme_cfg->rrm_config.rrm_enabled;
-	mac->rrm.rrmSmeContext.rrmConfig.max_randn_interval =
+	mac->rrm.rrmConfig.max_randn_interval =
 			mac->mlme_cfg->rrm_config.rrm_rand_interval;
 
-	qdf_mem_copy(&mac->rrm.rrmSmeContext.rrmConfig.rm_capability,
+	qdf_mem_copy(&mac->rrm.rrmConfig.rm_capability,
 		     &mac->mlme_cfg->rrm_config.rm_capability,
 		     RMENABLEDCAP_MAX_LEN);
 }
@@ -1609,38 +1689,46 @@ QDF_STATUS rrm_open(struct mac_context *mac)
 {
 
 	QDF_STATUS qdf_status;
-	tpRrmSMEContext pSmeRrmContext = &mac->rrm.rrmSmeContext;
+	tpRrmSMEContext pSmeRrmContext;
 	QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
+	uint8_t i;
 
-	pSmeRrmContext->rrmConfig.max_randn_interval = 50;        /* ms */
+	mac->rrm.rrmConfig.max_randn_interval = 50;        /* ms */
 
-	qdf_status = qdf_mc_timer_init(&pSmeRrmContext->IterMeasTimer,
-				       QDF_TIMER_TYPE_SW,
-				       rrm_iter_meas_timer_handle,
-					(void *)mac);
+	for (i = 0; i < MAX_MEASUREMENT_REQUEST; i++) {
+		pSmeRrmContext = &mac->rrm.rrmSmeContext[i];
 
-	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
-		sme_err("Fail to init measurement timer");
-		return QDF_STATUS_E_FAILURE;
-	}
+		qdf_status = qdf_mc_timer_init(&pSmeRrmContext->IterMeasTimer,
+					       QDF_TIMER_TYPE_SW,
+					       rrm_iter_meas_timer_handle,
+					       (void *)pSmeRrmContext);
 
-	qdf_status =
-		qdf_mc_timer_init(&pSmeRrmContext->neighborReqControlInfo.
-				  neighborRspWaitTimer, QDF_TIMER_TYPE_SW,
-				  rrm_neighbor_rsp_timeout_handler,
-					(void *)mac);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			sme_err("Fail to init measurement timer");
+			return QDF_STATUS_E_FAILURE;
+		}
 
-	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
-		sme_err("Fail to init neighbor rsp wait timer");
-		return QDF_STATUS_E_FAILURE;
-	}
+		qdf_status =
+		    qdf_mc_timer_init(&pSmeRrmContext->neighborReqControlInfo.
+				      neighborRspWaitTimer, QDF_TIMER_TYPE_SW,
+				      rrm_neighbor_rsp_timeout_handler,
+				      (void *)mac);
 
-	pSmeRrmContext->neighborReqControlInfo.isNeighborRspPending = false;
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+			sme_err("Fail to init neighbor rsp wait timer");
+			return QDF_STATUS_E_FAILURE;
+		}
 
-	qdf_ret_status = csr_ll_open(&pSmeRrmContext->neighborReportCache);
-	if (QDF_STATUS_SUCCESS != qdf_ret_status) {
-		sme_err("Fail to open neighbor cache result");
-		return QDF_STATUS_E_FAILURE;
+		pSmeRrmContext->measurement_idx = i;
+		pSmeRrmContext->neighborReqControlInfo.isNeighborRspPending =
+						false;
+
+		qdf_ret_status =
+			csr_ll_open(&pSmeRrmContext->neighborReportCache);
+		if (QDF_STATUS_SUCCESS != qdf_ret_status) {
+			sme_err("Fail to open neighbor cache result");
+			return QDF_STATUS_E_FAILURE;
+		}
 	}
 
 	rrm_change_default_config_param(mac);
@@ -1661,81 +1749,93 @@ QDF_STATUS rrm_open(struct mac_context *mac)
 
 QDF_STATUS rrm_close(struct mac_context *mac)
 {
-
 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
-	tpRrmSMEContext pSmeRrmContext = &mac->rrm.rrmSmeContext;
-
-	if (QDF_TIMER_STATE_RUNNING ==
-	    qdf_mc_timer_get_current_state(&pSmeRrmContext->IterMeasTimer)) {
-		qdf_status = qdf_mc_timer_stop(&pSmeRrmContext->IterMeasTimer);
-		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
-			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
-				  FL("Timer stop fail"));
+	tpRrmSMEContext pSmeRrmContext;
+	uint8_t i;
+
+	for (i = 0; i < MAX_MEASUREMENT_REQUEST; i++) {
+		pSmeRrmContext = &mac->rrm.rrmSmeContext[i];
+		if (QDF_TIMER_STATE_RUNNING ==
+		    qdf_mc_timer_get_current_state(
+			    &pSmeRrmContext->IterMeasTimer)) {
+			qdf_status = qdf_mc_timer_stop(
+					&pSmeRrmContext->IterMeasTimer);
+			if (QDF_IS_STATUS_ERROR(qdf_status))
+				sme_err("Timer stop fail");
 		}
-	}
 
-	if (pSmeRrmContext->channelList.freq_list) {
-		qdf_mem_free(pSmeRrmContext->channelList.freq_list);
-		pSmeRrmContext->channelList.freq_list = NULL;
-		pSmeRrmContext->channelList.numOfChannels = 0;
-	}
-
-	qdf_status = qdf_mc_timer_destroy(&pSmeRrmContext->IterMeasTimer);
-	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
-
-		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
-			  FL("Fail to destroy timer"));
-
-	}
+		if (pSmeRrmContext->channelList.freq_list) {
+			qdf_mem_free(pSmeRrmContext->channelList.freq_list);
+			pSmeRrmContext->channelList.freq_list = NULL;
+			pSmeRrmContext->channelList.numOfChannels = 0;
+		}
 
-	if (QDF_TIMER_STATE_RUNNING ==
-	    qdf_mc_timer_get_current_state(&pSmeRrmContext->
-					   neighborReqControlInfo.
-					   neighborRspWaitTimer)) {
-		qdf_status = qdf_mc_timer_stop(&pSmeRrmContext->
-					neighborReqControlInfo.
-					  neighborRspWaitTimer);
-		if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
-			QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
-				  FL("Timer stop fail"));
+		qdf_status =
+			qdf_mc_timer_destroy(&pSmeRrmContext->IterMeasTimer);
+		if (QDF_IS_STATUS_ERROR(qdf_status))
+			sme_err("Fail to destroy timer");
+
+		if (QDF_TIMER_STATE_RUNNING ==
+		    qdf_mc_timer_get_current_state(&pSmeRrmContext->
+						   neighborReqControlInfo.
+						   neighborRspWaitTimer)) {
+			qdf_status = qdf_mc_timer_stop(&pSmeRrmContext->
+						neighborReqControlInfo.
+						neighborRspWaitTimer);
+			if (QDF_IS_STATUS_ERROR(qdf_status))
+				sme_err("Timer stop fail");
 		}
-	}
 
-	qdf_status =
-		qdf_mc_timer_destroy(&pSmeRrmContext->neighborReqControlInfo.
-				     neighborRspWaitTimer);
-	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
-		QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
-			  FL("Fail to destroy timer"));
+		qdf_status = qdf_mc_timer_destroy(
+				&pSmeRrmContext->neighborReqControlInfo.
+				neighborRspWaitTimer);
+		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+			sme_err("Fail to destroy timer");
 
+		rrm_ll_purge_neighbor_cache(
+				mac, &pSmeRrmContext->neighborReportCache);
+		csr_ll_close(&pSmeRrmContext->neighborReportCache);
 	}
 
-	rrm_ll_purge_neighbor_cache(mac, &pSmeRrmContext->neighborReportCache);
-
-	csr_ll_close(&pSmeRrmContext->neighborReportCache);
-
 	return qdf_status;
 
 }
 
 QDF_STATUS rrm_start(struct mac_context *mac_ctx)
 {
-	tpRrmSMEContext smerrmctx = &mac_ctx->rrm.rrmSmeContext;
+	tpRrmSMEContext smerrmctx;
+	wlan_scan_requester req_id;
+	uint8_t i;
+
 
 	/* Register with scan component */
-	smerrmctx->req_id = ucfg_scan_register_requester(mac_ctx->psoc,
-					"RRM",
-					sme_rrm_scan_event_callback,
-					smerrmctx);
+	req_id = ucfg_scan_register_requester(mac_ctx->psoc,
+					      "RRM",
+					      sme_rrm_scan_event_callback,
+					      mac_ctx);
+
+	for (i = 0; i < MAX_MEASUREMENT_REQUEST; i++) {
+		smerrmctx = &mac_ctx->rrm.rrmSmeContext[i];
+		smerrmctx->req_id = req_id;
+	}
 
 	return QDF_STATUS_SUCCESS;
 }
 
 QDF_STATUS rrm_stop(struct mac_context *mac_ctx)
 {
-	tpRrmSMEContext smerrmctx = &mac_ctx->rrm.rrmSmeContext;
+	tpRrmSMEContext smerrmctx;
+	wlan_scan_requester req_id;
+	uint8_t i;
+
+	for (i = 0; i < MAX_MEASUREMENT_REQUEST; i++) {
+		smerrmctx = &mac_ctx->rrm.rrmSmeContext[i];
+		req_id = smerrmctx->req_id;
+		smerrmctx->req_id = 0;
+	}
 
-	ucfg_scan_unregister_requester(mac_ctx->psoc, smerrmctx->req_id);
+	ucfg_scan_unregister_requester(mac_ctx->psoc,
+				       req_id);
 
 	return QDF_STATUS_SUCCESS;
 }

+ 1 - 1
core/wma/src/wma_scan_roam.c

@@ -3923,7 +3923,7 @@ QDF_STATUS wma_roam_scan_fill_self_caps(tp_wma_handle wma_handle,
 	if (mac->mlme_cfg->scoring.apsd_enabled)
 		selfCaps.apsd = 1;
 
-	selfCaps.rrm = mac->rrm.rrmSmeContext.rrmConfig.rrm_enabled;
+	selfCaps.rrm = mac->rrm.rrmConfig.rrm_enabled;
 
 	val = mac->mlme_cfg->feature_flags.enable_block_ack;
 	selfCaps.delayedBA =