Parcourir la source

qcacld-3.0: Send xmit ind to PE on bcn report req processing failure

On failure in processing beacon report request in
sme_rrm_process_beacon_report_req_ind, xmit ind is
not sent to PE. This will result in all subsequent
beacon report requests to fail as current request
in PE is not freed. Beacon report request is received
with country code US-O and operating class 12. In this
scenario, third byte in country code is overwritten to
global_op_class which causes no channel to be populated
for scan as there is no operating class 12 in global op
class.

Fix is to send xmit ind to PE on failure in processing
beacon report req in SME for cleanup and not overwrite
the third byte in country code if value exceeds global
op value.

Change-Id: Ie07dbb1f45803cf93b45df2173f0ad064a194cb3
CRs-Fixed: 2439827
Yeshwanth Sriram Guntuka il y a 6 ans
Parent
commit
2c73ebd008
1 fichiers modifiés avec 33 ajouts et 24 suppressions
  1. 33 24
      core/sme/src/rrm/sme_rrm.c

+ 33 - 24
core/sme/src/rrm/sme_rrm.c

@@ -768,7 +768,7 @@ static QDF_STATUS sme_rrm_issue_scan_req(struct mac_context *mac_ctx)
 		sme_err("sme session ID not found for bssid= "QDF_MAC_ADDR_STR,
 			QDF_MAC_ADDR_ARRAY(sme_rrm_ctx->sessionBssId.bytes));
 		status = QDF_STATUS_E_FAILURE;
-		goto free_ch_lst;
+		goto send_ind;
 	}
 
 	if ((sme_rrm_ctx->currentIndex) >=
@@ -795,7 +795,7 @@ static QDF_STATUS sme_rrm_issue_scan_req(struct mac_context *mac_ctx)
 		req = qdf_mem_malloc(sizeof(*req));
 		if (!req) {
 			status = QDF_STATUS_E_NOMEM;
-			goto free_ch_lst;
+			goto send_ind;
 		}
 
 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
@@ -806,7 +806,7 @@ static QDF_STATUS sme_rrm_issue_scan_req(struct mac_context *mac_ctx)
 			sme_err("VDEV is null %d", session_id);
 			status = QDF_STATUS_E_INVAL;
 			qdf_mem_free(req);
-			goto free_ch_lst;
+			goto send_ind;
 		}
 		ucfg_scan_init_default_params(vdev, req);
 		req->scan_req.scan_id = ucfg_scan_get_scan_id(mac_ctx->psoc);
@@ -890,7 +890,7 @@ static QDF_STATUS sme_rrm_issue_scan_req(struct mac_context *mac_ctx)
 		status = ucfg_scan_start(req);
 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
 		if (QDF_IS_STATUS_ERROR(status))
-			goto free_ch_lst;
+			goto send_ind;
 
 		return status;
 	} else if (eSIR_BEACON_TABLE == scan_type) {
@@ -924,17 +924,16 @@ static QDF_STATUS sme_rrm_issue_scan_req(struct mac_context *mac_ctx)
 					sme_rrm_ctx->currentIndex], true);
 			goto free_ch_lst;
 		}
-	} else {
-		sme_err("Unknown beacon report req mode(%d)", scan_type);
-		/*
-		 * Indicate measurement completion to PE
-		 * If this is not done, pCurrentReq pointer will not be freed
-		 * and PE will not handle subsequent Beacon requests
-		 */
-		sme_rrm_send_beacon_report_xmit_ind(mac_ctx, NULL, true, 0);
-		goto free_ch_lst;
 	}
 
+	sme_err("Unknown beacon report req mode(%d)", scan_type);
+	/*
+	 * Indicate measurement completion to PE
+	 * If this is not done, pCurrentReq pointer will not be freed
+	 * and PE will not handle subsequent Beacon requests
+	 */
+send_ind:
+	sme_rrm_send_beacon_report_xmit_ind(mac_ctx, NULL, true, 0);
 free_ch_lst:
 	qdf_mem_free(sme_rrm_ctx->channelList.ChannelList);
 	sme_rrm_ctx->channelList.ChannelList = NULL;
@@ -970,13 +969,14 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 						    &session_id);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		sme_err("sme session ID not found for bssid");
-		return QDF_STATUS_E_FAILURE;
+		goto cleanup;
 	}
 
 	session = CSR_GET_SESSION(mac, session_id);
 	if (!session) {
 		sme_err("Invalid session id %d", session_id);
-		return QDF_STATUS_E_FAILURE;
+		status = QDF_STATUS_E_FAILURE;
+		goto cleanup;
 	}
 
 	qdf_mem_zero(country, WNI_CFG_COUNTRY_CODE_LEN);
@@ -991,15 +991,13 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 	sme_debug("Request Reg class %d, AP's country code %c%c 0x%x",
 		  pBeaconReq->channelInfo.regulatoryClass,
 		  country[0], country[1], country[2]);
-	if (country[2] > OP_CLASS_GLOBAL)
-		country[2] = OP_CLASS_GLOBAL;
-
 
 	if (pBeaconReq->channelList.numChannels >
 	    SIR_ESE_MAX_MEAS_IE_REQS) {
 		sme_err("Beacon report request numChannels:%u exceeds max num channels",
 			pBeaconReq->channelList.numChannels);
-		return QDF_STATUS_E_INVAL;
+		status = QDF_STATUS_E_INVAL;
+		goto cleanup;
 	}
 
 	/* section 11.10.8.1 (IEEE Std 802.11k-2008) */
@@ -1014,8 +1012,10 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 			pSmeRrmContext->channelList.ChannelList = NULL;
 		}
 		pSmeRrmContext->channelList.ChannelList = qdf_mem_malloc(len);
-		if (!pSmeRrmContext->channelList.ChannelList)
-			return QDF_STATUS_E_NOMEM;
+		if (!pSmeRrmContext->channelList.ChannelList) {
+			status = QDF_STATUS_E_NOMEM;
+			goto cleanup;
+		}
 
 		csr_get_cfg_valid_channels(mac, pSmeRrmContext->channelList.
 					ChannelList, &len);
@@ -1039,7 +1039,8 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 			qdf_mem_free(pSmeRrmContext->channelList.ChannelList);
 			pSmeRrmContext->channelList.ChannelList = NULL;
 			sme_err("No channels populated with requested operation class and current country, Hence abort the rrm operation");
-			return QDF_STATUS_E_FAILURE;
+			status = QDF_STATUS_E_FAILURE;
+			goto cleanup;
 		}
 	} else {
 		len = 0;
@@ -1059,8 +1060,10 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 			pSmeRrmContext->channelList.ChannelList = NULL;
 		}
 		pSmeRrmContext->channelList.ChannelList = qdf_mem_malloc(len);
-		if (!pSmeRrmContext->channelList.ChannelList)
-			return QDF_STATUS_E_NOMEM;
+		if (!pSmeRrmContext->channelList.ChannelList) {
+			status = QDF_STATUS_E_NOMEM;
+			goto cleanup;
+		}
 
 		if (pBeaconReq->channelInfo.channelNum != 255) {
 			if (csr_roam_is_channel_valid
@@ -1117,6 +1120,12 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 		pSmeRrmContext->randnIntvl, pSmeRrmContext->msgSource);
 
 	return sme_rrm_issue_scan_req(mac);
+
+cleanup:
+	if (pBeaconReq->msgSource == eRRM_MSG_SOURCE_11K)
+		sme_rrm_send_beacon_report_xmit_ind(mac, NULL, true, 0);
+
+	return status;
 }
 
 /**