Browse Source

qcacld-3.0: Allow the driver to process multiple measurement req

As per requirement, the driver should able to process up to
MAX_MEASUREMENT_REQUEST (5) measurement request in a single
beacon report request.

Update driver logic to process up to 5 measurement request and
make sure the driver should not issue rrm scan for the duplicate
channel.

Change-Id: Iea3be8a0efef605852ac6b6b54dd06774ac0adac
CRs-Fixed: 2712112
Abhinav Kumar 4 years ago
parent
commit
7d3c309952

+ 18 - 0
core/mac/src/pe/include/rrm_api.h

@@ -90,6 +90,24 @@ QDF_STATUS
 rrm_process_beacon_report_xmit(struct mac_context *mac_ctx,
 			       tpSirBeaconReportXmitInd beacon_xmit_ind);
 
+/**
+ * rrm_reject_req - Reject rrm request
+ * @radiomes_report: radio measurement report
+ * @rrm_req: Array of Measurement request IEs
+ * @num_report: Num of report
+ * @index: Measurement index
+ * @measurement_type: Measurement Type
+ *
+ * Reject the Radio Resource Measurement request, if one is
+ * already in progress
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS rrm_reject_req(tpSirMacRadioMeasureReport *radiomes_report,
+			  tDot11fRadioMeasurementRequest *rrm_req,
+			  uint8_t *num_report, uint8_t index,
+			  uint8_t measurement_type);
+
 void lim_update_rrm_capability(struct mac_context *mac_ctx,
 			       struct join_req *join_req);
 #endif

+ 5 - 1
core/mac/src/pe/include/rrm_global.h

@@ -27,7 +27,9 @@
 
    ========================================================================*/
 
-#define MAX_MEASUREMENT_REQUEST 2
+#define MAX_MEASUREMENT_REQUEST      5
+#define MAX_NUM_CHANNELS             255
+
 #define DEFAULT_RRM_IDX 0
 
 typedef enum eRrmRetStatus {
@@ -219,6 +221,8 @@ typedef struct sRrmPEContext {
 	uint8_t DialogToken;
 	uint16_t prev_rrm_report_seq_num;
 	tpRRMReq pCurrentReq[MAX_MEASUREMENT_REQUEST];
+	uint32_t beacon_rpt_chan_list[MAX_NUM_CHANNELS];
+	uint8_t beacon_rpt_chan_num;
 } tRrmPEContext, *tpRrmPEContext;
 
 /* 2008 11k spec reference: 18.4.8.5 RCPI Measurement */

+ 93 - 48
core/mac/src/pe/rrm/rrm_api.c

@@ -1178,55 +1178,33 @@ QDF_STATUS rrm_process_beacon_req(struct mac_context *mac_ctx, tSirMacAddr peer,
 	tRrmRetStatus rrm_status = eRRM_SUCCESS;
 	tpSirMacRadioMeasureReport report;
 	tpRRMReq curr_req;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
-	if (index  >= MAX_MEASUREMENT_REQUEST ||
-	    mac_ctx->rrm.rrmPEContext.pCurrentReq[index]) {
-		if (!*radiomes_report) {
-			/*
-			 * Allocate memory to send reports for
-			 * any subsequent requests.
-			 */
-			*radiomes_report = qdf_mem_malloc(sizeof(*report) *
-				(rrm_req->num_MeasurementRequest - index));
-			if (!*radiomes_report)
-				return QDF_STATUS_E_NOMEM;
-			pe_debug("rrm beacon type refused of %d report in beacon table",
-				*num_report);
-		}
-		report = *radiomes_report;
-		report[*num_report].refused = 1;
-		report[*num_report].type = SIR_MAC_RRM_BEACON_TYPE;
-		report[*num_report].token =
-			rrm_req->MeasurementRequest[index].measurement_token;
-		(*num_report)++;
-		return QDF_STATUS_SUCCESS;
-	} else {
-		curr_req = mac_ctx->rrm.rrmPEContext.pCurrentReq[index];
-		if (curr_req) {
-			qdf_mem_free(curr_req);
-			mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = NULL;
-		}
+	if (index  >= MAX_MEASUREMENT_REQUEST) {
+		status = rrm_reject_req(&report, rrm_req, num_report, index,
+			       rrm_req->MeasurementRequest[index].
+							measurement_type);
+		return status;
+	}
 
-		curr_req = qdf_mem_malloc(sizeof(*curr_req));
-		if (!curr_req) {
-			qdf_mem_free(*radiomes_report);
-			mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = NULL;
-			return QDF_STATUS_E_NOMEM;
-		}
-		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;
-		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, index);
-			rrm_cleanup(mac_ctx, index);
-		}
+	curr_req = qdf_mem_malloc(sizeof(*curr_req));
+	if (!curr_req) {
+		mac_ctx->rrm.rrmPEContext.pCurrentReq[index] = NULL;
+		return QDF_STATUS_E_NOMEM;
+	}
+	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;
+	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, index);
+		rrm_cleanup(mac_ctx, index);
 	}
 
 	return QDF_STATUS_SUCCESS;
@@ -1273,6 +1251,37 @@ QDF_STATUS update_rrm_report(struct mac_context *mac_ctx,
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS rrm_reject_req(tpSirMacRadioMeasureReport *radiomes_report,
+			  tDot11fRadioMeasurementRequest *rrm_req,
+			  uint8_t *num_report, uint8_t index,
+			  uint8_t measurement_type)
+{
+	tpSirMacRadioMeasureReport report;
+
+	if (!*radiomes_report) {
+	/*
+	 * Allocate memory to send reports for
+	 * any subsequent requests.
+	 */
+		*radiomes_report = qdf_mem_malloc(sizeof(*report) *
+				(rrm_req->num_MeasurementRequest - index));
+		if (!*radiomes_report)
+			return QDF_STATUS_E_NOMEM;
+
+		pe_debug("rrm beacon refused of %d report, index: %d in beacon table",
+			 *num_report, index);
+	}
+	report = *radiomes_report;
+	report[*num_report].refused = 1;
+	report[*num_report].type = measurement_type;
+	report[*num_report].token =
+			rrm_req->MeasurementRequest[index].measurement_token;
+	(*num_report)++;
+
+	return QDF_STATUS_SUCCESS;
+
+}
+
 /* -------------------------------------------------------------------- */
 /**
  * rrm_process_radio_measurement_request - Process rrm request
@@ -1291,10 +1300,11 @@ rrm_process_radio_measurement_request(struct mac_context *mac_ctx,
 				      tDot11fRadioMeasurementRequest *rrm_req,
 				      struct pe_session *session_entry)
 {
-	uint8_t i;
+	uint8_t i, index;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	tpSirMacRadioMeasureReport report = NULL;
 	uint8_t num_report = 0;
+	bool reject = false;
 
 	if (!rrm_req->num_MeasurementRequest) {
 		report = qdf_mem_malloc(sizeof(tSirMacRadioMeasureReport));
@@ -1326,6 +1336,41 @@ rrm_process_radio_measurement_request(struct mac_context *mac_ctx,
 		goto end;
 	}
 
+	for(index = 0; index < MAX_MEASUREMENT_REQUEST; index++)
+	{
+	   if ( mac_ctx->rrm.rrmPEContext.pCurrentReq[index]) {
+			reject = true;
+			pe_debug("RRM req for index: %d is already in progress",
+				 index);
+			break;
+		}
+	}
+
+	if (reject == true)
+	{
+		for (i = 0; i < rrm_req->num_MeasurementRequest; i++) {
+			status =
+			    rrm_reject_req(&report, rrm_req, &num_report, i,
+					   rrm_req->MeasurementRequest[i].
+							measurement_type);
+			if (QDF_IS_STATUS_ERROR(status)) {
+				pe_debug("Fail to Reject rrm req for index: %d",
+					 i);
+				return status;
+			}
+		}
+
+		goto end;
+	}
+
+	/*
+	 * Clear global beacon_rpt_chan_list before processing every new
+	 * beacon report request.
+	 */
+	qdf_mem_zero(mac_ctx->rrm.rrmPEContext.beacon_rpt_chan_list,
+		     sizeof(uint8_t) * MAX_NUM_CHANNELS);
+	mac_ctx->rrm.rrmPEContext.beacon_rpt_chan_num = 0;
+
 	for (i = 0; i < rrm_req->num_MeasurementRequest; i++) {
 		switch (rrm_req->MeasurementRequest[i].measurement_type) {
 		case SIR_MAC_RRM_BEACON_TYPE:

+ 50 - 4
core/sme/src/rrm/sme_rrm.c

@@ -1100,17 +1100,19 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 {
 	tpSirBeaconReportReqInd beacon_req = (tpSirBeaconReportReqInd)msg_buf;
 	tpRrmSMEContext sme_rrm_ctx;
-	uint32_t len = 0, i = 0;
+	uint32_t len = 0, i = 0, j = 0;
 	uint8_t country[WNI_CFG_COUNTRY_CODE_LEN];
 	uint32_t session_id;
 	struct csr_roam_session *session;
 	QDF_STATUS status;
-	uint32_t num_chan;
+	uint32_t num_chan, local_num_channel;
 	bool chan_valid;
-	uint32_t *rrm_freq_list;
-	uint32_t bcn_chan_freq;
+	uint32_t *rrm_freq_list, *local_rrm_freq_list;
+	uint32_t bcn_chan_freq, local_bcn_chan_freq;
+	tRrmPEContext rrm_context;
 
 	sme_rrm_ctx = &mac->rrm.rrmSmeContext[beacon_req->measurement_idx];
+	rrm_context = mac->rrm.rrmPEContext;
 
 	status = csr_roam_get_session_id_from_bssid(mac, (struct qdf_mac_addr *)
 						    beacon_req->bssId,
@@ -1235,6 +1237,50 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 		sme_rrm_ctx->channelList.numOfChannels = num_chan;
 	}
 
+	local_rrm_freq_list = sme_rrm_ctx->channelList.freq_list;
+	local_num_channel = 0;
+	for (i = 0; i < sme_rrm_ctx->channelList.numOfChannels; i++) {
+		local_bcn_chan_freq = local_rrm_freq_list[i];
+		chan_valid = true;
+
+		if (beacon_req->measurement_idx > 0) {
+			for (j = 0; j < rrm_context.beacon_rpt_chan_num; j ++) {
+				if (rrm_context.beacon_rpt_chan_list[j] ==
+				    local_bcn_chan_freq) {
+				/*
+				 * Ignore this channel, As this is already
+				 * included in previous request
+				 */
+					chan_valid = false;
+					break;
+				}
+			}
+		}
+
+		if (chan_valid) {
+			rrm_context.
+			beacon_rpt_chan_list[rrm_context.beacon_rpt_chan_num] =
+							local_bcn_chan_freq;
+			rrm_context.beacon_rpt_chan_num++;
+
+			if (rrm_context.beacon_rpt_chan_num >=
+			    MAX_NUM_CHANNELS) {
+			    /* this should never happen */
+				sme_err("Reset beacon_rpt_chan_num : %d",
+					rrm_context.beacon_rpt_chan_num);
+				rrm_context.beacon_rpt_chan_num = 0;
+			}
+			local_rrm_freq_list[local_num_channel] =
+							local_bcn_chan_freq;
+			local_num_channel++;
+		}
+	}
+
+	if (local_num_channel == 0)
+		goto cleanup;
+
+	sme_rrm_ctx->channelList.numOfChannels = local_num_channel;
+
 	/* Copy session bssid */
 	qdf_mem_copy(sme_rrm_ctx->sessionBssId.bytes, beacon_req->bssId,
 		     sizeof(tSirMacAddr));