Преглед изворни кода

qcacld-3.0: Use the operating class table no for AP's country IE for RRM

Currently when an RRM scan is issued for beacon report request from the
connected AP, we use the current scan country code to get the op class
table for the country.

However, the AP can specify which table to use in the country IE's 3rd
byte of the country field which is not parsed and stored in the scan
country code.

For RRM Scan for beacon report request, use the 3rd byte to get the table
number from the connected AP's beacon and if no table number is present,
then use the op class table based on the country code.

Change-Id: I0911ac908d1c71676f7c1450ab260eaa732ddcb9
CRs-Fixed: 2435942
Vignesh Viswanathan пре 6 година
родитељ
комит
687af4646e
3 измењених фајлова са 67 додато и 3 уклоњено
  1. 1 0
      core/sme/inc/csr_api.h
  2. 10 0
      core/sme/src/csr/csr_api_roam.c
  3. 56 3
      core/sme/src/rrm/sme_rrm.c

+ 1 - 0
core/sme/inc/csr_api.h

@@ -862,6 +862,7 @@ typedef struct tagCsrRoamConnectedProfile {
 	tCsrEncryptionList EncryptionInfo;
 	eCsrEncryptionType mcEncryptionType;
 	tCsrEncryptionList mcEncryptionInfo;
+	uint8_t country_code[WNI_CFG_COUNTRY_CODE_LEN];
 	uint32_t vht_channel_width;
 	tCsrKeys Keys;
 	/*

+ 10 - 0
core/sme/src/csr/csr_api_roam.c

@@ -8661,6 +8661,16 @@ QDF_STATUS csr_roam_save_connected_information(struct mac_context *mac,
 				p_ext_cap->proxy_arp_service;
 		}
 
+		if (pIesTemp->Country.present) {
+			qdf_mem_copy(pConnectProfile->country_code,
+				     pIesTemp->Country.country,
+				     WNI_CFG_COUNTRY_CODE_LEN);
+			sme_debug("Storing country in connected info, %c%c 0x%x",
+				  pConnectProfile->country_code[0],
+				  pConnectProfile->country_code[1],
+				  pConnectProfile->country_code[2]);
+		}
+
 		if (!pIes)
 			/* Free memory if it allocated locally */
 			qdf_mem_free(pIesTemp);

+ 56 - 3
core/sme/src/rrm/sme_rrm.c

@@ -959,9 +959,41 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 	tpSirBeaconReportReqInd pBeaconReq = (tpSirBeaconReportReqInd) pMsgBuf;
 	tpRrmSMEContext pSmeRrmContext = &mac->rrm.rrmSmeContext;
 	uint32_t len = 0, i = 0;
+	uint8_t num_chan = 0;
+	uint8_t country[WNI_CFG_COUNTRY_CODE_LEN];
+	uint32_t session_id;
+	struct csr_roam_session *session;
+	QDF_STATUS status;
+
+	status = csr_roam_get_session_id_from_bssid(mac, (struct qdf_mac_addr *)
+						    pBeaconReq->bssId,
+						    &session_id);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("sme session ID not found for bssid");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	session = CSR_GET_SESSION(mac, session_id);
+	if (!session) {
+		sme_err("Invalid session id %d", session_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_mem_zero(country, WNI_CFG_COUNTRY_CODE_LEN);
+	if (session->connectedProfile.country_code[0])
+		qdf_mem_copy(country, session->connectedProfile.country_code,
+			     WNI_CFG_COUNTRY_CODE_LEN);
+	else
+		country[2] = OP_CLASS_GLOBAL;
+
+	sme_debug("Channel = %d", pBeaconReq->channelInfo.channelNum);
+
+	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;
 
-	sme_debug("Received Beacon report request ind Channel = %d",
-		pBeaconReq->channelInfo.channelNum);
 
 	if (pBeaconReq->channelList.numChannels >
 	    SIR_ESE_MAX_MEAS_IE_REQS) {
@@ -987,7 +1019,28 @@ QDF_STATUS sme_rrm_process_beacon_report_req_ind(struct mac_context *mac,
 
 		csr_get_cfg_valid_channels(mac, pSmeRrmContext->channelList.
 					ChannelList, &len);
-		pSmeRrmContext->channelList.numOfChannels = (uint8_t) len;
+		/* List all the channels in the requested RC */
+		wlan_reg_dmn_print_channels_in_opclass(country,
+				pBeaconReq->channelInfo.regulatoryClass);
+
+		for (i = 0; i < len; i++) {
+			if (wlan_reg_dmn_get_opclass_from_channel(country,
+			    pSmeRrmContext->channelList.ChannelList[i],
+			    BWALL) ==
+			    pBeaconReq->channelInfo.regulatoryClass) {
+				pSmeRrmContext->channelList.
+				ChannelList[num_chan] =
+				pSmeRrmContext->channelList.ChannelList[i];
+				num_chan++;
+			}
+		}
+		pSmeRrmContext->channelList.numOfChannels = num_chan;
+		if (pSmeRrmContext->channelList.numOfChannels == 0) {
+			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;
+		}
 	} else {
 		len = 0;
 		pSmeRrmContext->channelList.numOfChannels = 0;