Explorar o código

qcacld-3.0: Update ACS channel list with PCL

Current ACS logic sometimes selects MCC channel based on its
algo for SAP / GO which results in SAP / GO bring-up failures.
This issue is seen in below concurrency combinations:
1. SAP + SAP
2. SAP + P2P-GO
3. SAP + SAP + SAP
4. SAP + SAP + P2P-GO

So with this change driver restricts ACS scan to intersection of
PCL and ACS channel list.
This implementation will take care of existing STA + SAP case as well,
as PCL will have channels according to 1st connection being STA.

Change-Id: Ic715fb29533c20b63cffda8a82b7317904f0d291
CRs-Fixed: 2407289
Rachit Kankane %!s(int64=6) %!d(string=hai) anos
pai
achega
def2b174a2

+ 7 - 4
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -2673,15 +2673,18 @@ bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
 bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc);
 
 /**
- * policy_mgr_trim_acs_channel_list() - Trim the ACS channel list based
- * on the number of active station connections
+ * policy_mgr_trim_acs_channel_list() - Trims ACS channel list with
+ * intersection of PCL
+ * @pcl: preferred channel list
+ * @pcl_count: Preferred channel list count
  * @org_ch_list: ACS channel list from user space
  * @org_ch_list_count: ACS channel count from user space
  *
  * Return: None
  */
-void policy_mgr_trim_acs_channel_list(struct wlan_objmgr_psoc *psoc,
-		uint8_t *org_ch_list, uint8_t *org_ch_list_count);
+void policy_mgr_trim_acs_channel_list(uint8_t *pcl, uint8_t pcl_count,
+				      uint8_t *org_ch_list,
+				      uint8_t *org_ch_list_count);
 
 /**
  * policy_mgr_is_hwmode_set_for_given_chnl() - to check for given channel

+ 12 - 78
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -3302,93 +3302,27 @@ bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc)
 	return ret;
 }
 
-void policy_mgr_trim_acs_channel_list(struct wlan_objmgr_psoc *psoc,
-		uint8_t *org_ch_list, uint8_t *org_ch_list_count)
+void policy_mgr_trim_acs_channel_list(uint8_t *pcl, uint8_t pcl_count,
+				      uint8_t *org_ch_list,
+				      uint8_t *org_ch_list_count)
 {
-	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
-	uint32_t index = 0, count, i, ch_list_count;
-	uint8_t band_mask = 0, ch_5g = 0, ch_24g = 0;
-	uint8_t ch_list[QDF_MAX_NUM_CHAN];
-	struct policy_mgr_psoc_priv_obj *pm_ctx;
-
-	pm_ctx = policy_mgr_get_context(psoc);
-	if (!pm_ctx) {
-		policy_mgr_err("Invalid Context");
-		return;
-	}
+	uint16_t i, j, ch_list_count = 0;
 
 	if (*org_ch_list_count >= QDF_MAX_NUM_CHAN) {
 		policy_mgr_err("org_ch_list_count too big %d",
 			*org_ch_list_count);
 		return;
 	}
-	/*
-	 * if force SCC is enabled and there is a STA connection, trim the
-	 * ACS channel list on the band on which STA connection is present
-	 */
-	count = policy_mgr_mode_specific_connection_count(
-				psoc, PM_STA_MODE, list);
-	if (!(policy_mgr_is_force_scc(psoc) && count))
-		return;
-	while (index < count) {
-		if (WLAN_REG_IS_24GHZ_CH(
-			pm_conc_connection_list[list[index]].chan) &&
-			policy_mgr_is_safe_channel(psoc,
-			pm_conc_connection_list[list[index]].chan)) {
-			band_mask |= 1;
-			ch_24g = pm_conc_connection_list[list[index]].chan;
-		}
-		if (WLAN_REG_IS_5GHZ_CH(
-			pm_conc_connection_list[list[index]].chan) &&
-			policy_mgr_is_safe_channel(psoc,
-			pm_conc_connection_list[list[index]].chan) &&
-			!wlan_reg_is_dfs_ch(pm_ctx->pdev,
-			pm_conc_connection_list[list[index]].chan) &&
-			!wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev,
-			pm_conc_connection_list[list[index]].chan)) {
-			band_mask |= 2;
-			ch_5g = pm_conc_connection_list[list[index]].chan;
-		}
-		index++;
-	}
-	ch_list_count = 0;
-	if (band_mask == 1) {
-		ch_list[ch_list_count++] = ch_24g;
-		for (i = 0; i < *org_ch_list_count; i++) {
-			if (WLAN_REG_IS_24GHZ_CH(
-				org_ch_list[i]))
-				continue;
-			ch_list[ch_list_count++] =
-				org_ch_list[i];
-		}
-	} else if (band_mask == 2) {
-		if ((wlan_reg_get_channel_state(pm_ctx->pdev, ch_5g) ==
-			CHANNEL_STATE_DFS) &&
-		      policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc))
-			ch_list[ch_list_count++] = ch_5g;
-		else if (!(wlan_reg_get_channel_state(pm_ctx->pdev, ch_5g) ==
-			CHANNEL_STATE_DFS))
-			ch_list[ch_list_count++] = ch_5g;
-		for (i = 0; i < *org_ch_list_count; i++) {
-			if (WLAN_REG_IS_5GHZ_CH(
-				org_ch_list[i]))
-				continue;
-			ch_list[ch_list_count++] =
-				org_ch_list[i];
-		}
-	} else if (band_mask == 3) {
-		ch_list[ch_list_count++] = ch_24g;
-		ch_list[ch_list_count++] = ch_5g;
-	} else {
-		policy_mgr_debug("unexpected band_mask value %d",
-			band_mask);
-		return;
-	}
 
-	*org_ch_list_count = ch_list_count;
-	for (i = 0; i < *org_ch_list_count; i++)
-		org_ch_list[i] = ch_list[i];
+	policy_mgr_debug("Update ACS channels with PCL");
+	for (j = 0; j < *org_ch_list_count; j++)
+		for (i = 0; i < pcl_count; i++)
+			if (pcl[i] == org_ch_list[j]) {
+				org_ch_list[ch_list_count++] = pcl[i];
+				break;
+			}
 
+	*org_ch_list_count = ch_list_count;
 }
 
 uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc,

+ 2 - 2
components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h

@@ -902,7 +902,7 @@ pm_third_connection_pcl_dbs_2x2_table = {
 	[PM_STA_MODE] = {
 		PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
 		PM_24G_SCC_CH_SBS_CH},
-	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
 	[PM_P2P_CLIENT_MODE] = {
 		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
 	[PM_P2P_GO_MODE] = {
@@ -917,7 +917,7 @@ pm_third_connection_pcl_dbs_2x2_table = {
 	[PM_STA_MODE] = {
 		PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH,
 		PM_24G_SCC_CH_SBS_CH},
-	[PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G},
+	[PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G},
 	[PM_P2P_CLIENT_MODE] = {
 		PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE},
 	[PM_P2P_GO_MODE] = {

+ 47 - 48
core/hdd/src/wlan_hdd_cfg80211.c

@@ -2525,9 +2525,8 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
 	bool ht_enabled, ht40_enabled, vht_enabled;
 	uint8_t ch_width;
 	enum qca_wlan_vendor_acs_hw_mode hw_mode;
+	enum policy_mgr_con_mode pm_mode;
 	QDF_STATUS qdf_status;
-	uint8_t conc_channel;
-	mac_handle_t mac_handle;
 	bool skip_etsi13_srd_chan = false;
 	uint32_t auto_channel_select_weight =
 		cfg_default(CFG_AUTO_CHANNEL_SELECT_WEIGHT);
@@ -2737,12 +2736,15 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
 	}
 	hdd_debug("get pcl for DO_ACS vendor command");
 
+	pm_mode =
+	      policy_mgr_convert_device_mode_to_qdf_type(adapter->device_mode);
 	/* consult policy manager to get PCL */
-	qdf_status = policy_mgr_get_pcl(hdd_ctx->psoc, PM_SAP_MODE,
-				sap_config->acs_cfg.pcl_channels,
-				&sap_config->acs_cfg.pcl_ch_count,
-				sap_config->acs_cfg.pcl_channels_weight_list,
-				QDF_MAX_NUM_CHAN);
+	qdf_status = policy_mgr_get_pcl(hdd_ctx->psoc, pm_mode,
+					sap_config->acs_cfg.pcl_channels,
+					&sap_config->acs_cfg.pcl_ch_count,
+					sap_config->acs_cfg.
+					pcl_channels_weight_list,
+					QDF_MAX_NUM_CHAN);
 	if (qdf_status != QDF_STATUS_SUCCESS)
 		hdd_err("Get PCL failed");
 
@@ -2756,13 +2758,46 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
 				  sap_config->acs_cfg.
 				  pcl_channels_weight_list[i]);
 	}
+	sap_config->acs_cfg.band = hw_mode;
 
-	if (hw_mode == QCA_ACS_MODE_IEEE80211ANY)
-		policy_mgr_trim_acs_channel_list(hdd_ctx->psoc,
-			sap_config->acs_cfg.ch_list,
-			&sap_config->acs_cfg.ch_list_count);
+	qdf_status = ucfg_mlme_get_external_acs_policy(hdd_ctx->psoc,
+						       &is_external_acs_policy);
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+		hdd_err("get_external_acs_policy failed");
+
+	if (is_external_acs_policy &&
+	    policy_mgr_is_force_scc(hdd_ctx->psoc) &&
+	    policy_mgr_get_connection_count(hdd_ctx->psoc)) {
+		policy_mgr_trim_acs_channel_list(
+					sap_config->acs_cfg.pcl_channels,
+					sap_config->acs_cfg.pcl_ch_count,
+					sap_config->acs_cfg.ch_list,
+					&sap_config->acs_cfg.ch_list_count);
+
+		/* if it is only one channel, send ACS event to upper layer */
+		if (sap_config->acs_cfg.ch_list_count == 1) {
+			sap_config->acs_cfg.pri_ch =
+					sap_config->acs_cfg.ch_list[0];
+			wlan_sap_set_sap_ctx_acs_cfg(
+				WLAN_HDD_GET_SAP_CTX_PTR(adapter), sap_config);
+			sap_config_acs_result(hdd_ctx->mac_handle,
+					      WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+					      sap_config->acs_cfg.ht_sec_ch);
+			sap_config->ch_params.ch_width =
+					sap_config->acs_cfg.ch_width;
+			sap_config->ch_params.sec_ch_offset =
+					sap_config->acs_cfg.ht_sec_ch;
+			sap_config->ch_params.center_freq_seg0 =
+					sap_config->acs_cfg.vht_seg0_center_ch;
+			sap_config->ch_params.center_freq_seg1 =
+					sap_config->acs_cfg.vht_seg1_center_ch;
+			/*notify hostapd about channel override */
+			wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
+			ret = 0;
+			goto out;
+		}
+	}
 
-	sap_config->acs_cfg.band = hw_mode;
 	ret = wlan_hdd_set_acs_ch_range(sap_config, hw_mode,
 					   ht_enabled, vht_enabled);
 	if (ret) {
@@ -2827,42 +2862,6 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
 			hdd_debug("%d ", sap_config->acs_cfg.ch_list[i]);
 	}
 
-	conc_channel = policy_mgr_mode_specific_get_channel(hdd_ctx->psoc,
-							    PM_STA_MODE);
-
-	qdf_status = ucfg_mlme_get_external_acs_policy(hdd_ctx->psoc,
-						       &is_external_acs_policy);
-	if (!QDF_IS_STATUS_SUCCESS(qdf_status))
-		hdd_err("get_external_acs_policy failed");
-
-	if (is_external_acs_policy && conc_channel) {
-		if ((conc_channel >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
-		     sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211A) ||
-		     (conc_channel <= WLAN_REG_CH_NUM(CHAN_ENUM_14) &&
-		      (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211B ||
-		       sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211G))) {
-			sap_config->acs_cfg.pri_ch = conc_channel;
-			wlan_sap_set_sap_ctx_acs_cfg(
-				WLAN_HDD_GET_SAP_CTX_PTR(adapter), sap_config);
-			mac_handle = hdd_ctx->mac_handle;
-			sap_config_acs_result(mac_handle,
-					      WLAN_HDD_GET_SAP_CTX_PTR(adapter),
-					      sap_config->acs_cfg.ht_sec_ch);
-			sap_config->ch_params.ch_width =
-					sap_config->acs_cfg.ch_width;
-			sap_config->ch_params.sec_ch_offset =
-					sap_config->acs_cfg.ht_sec_ch;
-			sap_config->ch_params.center_freq_seg0 =
-					sap_config->acs_cfg.vht_seg0_center_ch;
-			sap_config->ch_params.center_freq_seg1 =
-					sap_config->acs_cfg.vht_seg1_center_ch;
-			/*notify hostapd about channel override */
-			wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
-			ret = 0;
-			goto out;
-		}
-	}
-
 	sap_config->acs_cfg.acs_mode = true;
 	if (test_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags)) {
 		/* ***Note*** Completion variable usage is not allowed