qcacld-3.0: Fix Beacon report invalid channel issue

11K test bed sends beacon report request for channel 48 with
invalid reg class 0 to DUT. So, driver gets chan_freq 0 by API
wlan_reg_chan_opclass_to_freq because of reg class 0.
To get correct channel freq for beacon report request, use new
API wlan_reg_country_chan_opclass_to_freq to
get freq from country operating class table firstly by (opclass,
channel number) pair. When the lookup is failed, the API will
try to look up by chan number only.

Change-Id: I5b56804c20d6fade17b2acaa0f7c261feebd6370
CRs-Fixed: 2603989
diff --git a/Kbuild b/Kbuild
index 79dff01..12409ea 100644
--- a/Kbuild
+++ b/Kbuild
@@ -2930,6 +2930,7 @@
 
 #Flag to enable/disable HOST_OPCLASS
 cppflags-$(CONFIG_HOST_OPCLASS) += -DHOST_OPCLASS
+cppflags-$(CONFIG_HOST_OPCLASS) += -DHOST_OPCLASS_EXT
 
 #Flag to enable/disable TARGET_11D_SCAN
 cppflags-$(CONFIG_TARGET_11D_SCAN) += -DTARGET_11D_SCAN
diff --git a/configs/qcs40x.snoc.perf_defconfig b/configs/qcs40x.snoc.perf_defconfig
index 6d87eec..0dd909d 100644
--- a/configs/qcs40x.snoc.perf_defconfig
+++ b/configs/qcs40x.snoc.perf_defconfig
@@ -26,6 +26,7 @@
 CONFIG_CONVERGED_P2P_ENABLE := y
 CONFIG_WLAN_POLICY_MGR_ENABLE := y
 CONFIG_SUPPORT_11AX := n
+CONFIG_HOST_OPCLASS := y
 CONFIG_HDD_INIT_WITH_RTNL_LOCK := y
 CONFIG_CONVERGED_TDLS_ENABLE := y
 CONFIG_WLAN_CONV_SPECTRAL_ENABLE := y
diff --git a/core/mac/src/pe/rrm/rrm_api.c b/core/mac/src/pe/rrm/rrm_api.c
index f24dc24..ef60356 100644
--- a/core/mac/src/pe/rrm/rrm_api.c
+++ b/core/mac/src/pe/rrm/rrm_api.c
@@ -465,6 +465,44 @@
 	return status;
 }
 
+/**
+ * rrm_get_country_code_from_connected_profile() - Get country code
+ * from connected profile
+ * @mac: Mac context
+ * @pe_session: pe session
+ * @country_code: country code
+ *
+ * Return: void
+ */
+static inline void
+rrm_get_country_code_from_connected_profile(
+				struct mac_context *mac,
+				struct pe_session *pe_session,
+				uint8_t country_code[WNI_CFG_COUNTRY_CODE_LEN])
+{
+	uint8_t id;
+	uint8_t *country;
+
+	qdf_mem_zero(country_code, sizeof(country_code[0]) *
+					WNI_CFG_COUNTRY_CODE_LEN);
+	if (!pe_session) {
+		pe_err("pe_session is NULL");
+		return;
+	}
+	id = pe_session->smeSessionId;
+	if (!CSR_IS_SESSION_VALID(mac, id)) {
+		pe_err("smeSessionId %d is invalid", id);
+		return;
+	}
+	country =
+		mac->roam.roamSession[id].connectedProfile.country_code;
+	if (country[0])
+		qdf_mem_copy(country_code, country, sizeof(country_code[0]) *
+						WNI_CFG_COUNTRY_CODE_LEN);
+	else
+		country_code[2] = OP_CLASS_GLOBAL;
+}
+
 #define ABS(x)      ((x < 0) ? -x : x)
 /* -------------------------------------------------------------------- */
 /**
@@ -501,6 +539,12 @@
 	char req_ssid[WLAN_SSID_MAX_LEN] = {0};
 	char ch_buf[RRM_CH_BUF_LEN];
 	char *tmp_buf = NULL;
+	uint8_t country[WNI_CFG_COUNTRY_CODE_LEN];
+
+	if (!pe_session) {
+		pe_err("pe_session is NULL");
+		return eRRM_INCAPABLE;
+	}
 
 	if (pBeaconReq->measurement_request.Beacon.BeaconReporting.present &&
 	    (pBeaconReq->measurement_request.Beacon.BeaconReporting.
@@ -625,14 +669,36 @@
 		return eRRM_FAILURE;
 	}
 
+	rrm_get_country_code_from_connected_profile(mac, pe_session,
+						    country);
 	psbrr->channel_info.chan_num =
 		pBeaconReq->measurement_request.Beacon.channel;
 	psbrr->channel_info.reg_class =
 		pBeaconReq->measurement_request.Beacon.regClass;
-	psbrr->channel_info.chan_freq =
-		wlan_reg_chan_opclass_to_freq(psbrr->channel_info.chan_num,
-					      psbrr->channel_info.reg_class,
-					      false);
+	if (psbrr->channel_info.chan_num &&
+	    psbrr->channel_info.chan_num != 255) {
+		psbrr->channel_info.chan_freq =
+			wlan_reg_country_chan_opclass_to_freq(
+				mac->pdev,
+				country,
+				psbrr->channel_info.chan_num,
+				psbrr->channel_info.reg_class,
+				false);
+		if (!psbrr->channel_info.chan_freq) {
+			pe_debug("invalid ch freq, chan_num %d",
+				  psbrr->channel_info.chan_num);
+			qdf_mem_free(psbrr);
+			return eRRM_FAILURE;
+		}
+	} else {
+		psbrr->channel_info.chan_freq = 0;
+	}
+	sme_debug("opclass %d, ch %d freq %d AP's country code %c%c 0x%x",
+		  psbrr->channel_info.reg_class,
+		  psbrr->channel_info.chan_num,
+		  psbrr->channel_info.chan_freq,
+		  country[0], country[1], country[2]);
+
 	psbrr->measurementDuration[0] = measDuration;
 	psbrr->fMeasurementtype[0] =
 		pBeaconReq->measurement_request.Beacon.meas_mode;