Browse Source

qcacld-3.0: Update master channel list from set wifi config

Initially, if hotspot starts in world mode, it can come up in
2.4 GHz only. Later, the correct regulatory domain gets configured
in the host driver.
Even if this new reg domain supports higher bands and better channels,
the SAP will not be able to move since the ACS list configured
initially is for world mode(only 2.4 GHz channels).

To fix this, after the initial ACS userspace will configure the
ACS channels as per the band preference. Upon new country change,
the host driver will use this updated list to switch to a higher/
better band.

Change-Id: I60524e60798df656b86cbd883a31b00ccd210bc6
CRs-Fixed: 3453679
Sheenam Monga 1 year ago
parent
commit
136e98f779

+ 10 - 0
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -5440,4 +5440,14 @@ bool policy_mgr_is_beaconing_mode(enum policy_mgr_con_mode mode);
 
 bool policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(struct wlan_objmgr_psoc *psoc);
 
+/**
+ * policy_mgr_reset_sap_mandatory_channels() - Reset the SAP mandatory channels
+ * @psoc: psoc object
+ *
+ * Resets the SAP mandatory channel list and the length of the list
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+policy_mgr_reset_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc);
 #endif /* __WLAN_POLICY_MGR_API_H */

+ 0 - 11
components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c

@@ -4741,17 +4741,6 @@ policy_mgr_get_current_pref_hw_mode_dual_dbs(
 	return next_action;
 }
 
-QDF_STATUS policy_mgr_reset_sap_mandatory_channels(
-		struct policy_mgr_psoc_priv_obj *pm_ctx)
-{
-	pm_ctx->sap_mandatory_channels_len = 0;
-	qdf_mem_zero(pm_ctx->sap_mandatory_channels,
-		     QDF_ARRAY_SIZE(pm_ctx->sap_mandatory_channels) *
-		     sizeof(*pm_ctx->sap_mandatory_channels));
-
-	return QDF_STATUS_SUCCESS;
-}
-
 void policy_mgr_add_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc,
 				       uint32_t ch_freq)
 {

+ 19 - 0
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -11711,3 +11711,22 @@ bool policy_mgr_get_nan_sap_scc_on_lte_coex_chnl(struct wlan_objmgr_psoc *psoc)
 	return pm_ctx->cfg.nan_sap_scc_on_lte_coex_chnl;
 }
 
+QDF_STATUS
+policy_mgr_reset_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc)
+{
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	pm_ctx->sap_mandatory_channels_len = 0;
+	qdf_mem_zero(pm_ctx->sap_mandatory_channels,
+		     QDF_ARRAY_SIZE(pm_ctx->sap_mandatory_channels) *
+		     sizeof(*pm_ctx->sap_mandatory_channels));
+
+	return QDF_STATUS_SUCCESS;
+}
+

+ 0 - 24
components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h

@@ -937,30 +937,6 @@ enum policy_mgr_conc_next_action
 		policy_mgr_get_current_pref_hw_mode_dual_dbs(
 		struct wlan_objmgr_psoc *psoc);
 
-/**
- * policy_mgr_reset_sap_mandatory_channels() - Reset the SAP mandatory channels
- * @pm_ctx: policy mgr context
- *
- * Resets the SAP mandatory channel list and the length of the list
- *
- * Return: QDF_STATUS
- */
-QDF_STATUS policy_mgr_reset_sap_mandatory_channels(
-		struct policy_mgr_psoc_priv_obj *pm_ctx);
-
-/**
- * policy_mgr_dump_freq_range_per_mac() - Function to print frequency range
- * for both MAC 0 and MAC1 for given Hw mode
- *
- * @freq_range: Policy Mgr context
- * @hw_mode: HW mode
- *
- * This Function will print frequency range for both MAC 0 and MAC1 for given
- * Hw mode
- *
- * Return: void
- *
- */
 void
 policy_mgr_dump_freq_range_per_mac(struct policy_mgr_freq_range *freq_range,
 				   enum policy_mgr_mode hw_mode);

+ 2 - 2
components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c

@@ -530,7 +530,7 @@ QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc)
 	policy_mgr_set_dynamic_mcc_adaptive_sch(psoc, enable_mcc_adaptive_sch);
 	pm_ctx->hw_mode_change_in_progress = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS;
 	/* reset sap mandatory channels */
-	status = policy_mgr_reset_sap_mandatory_channels(pm_ctx);
+	status = policy_mgr_reset_sap_mandatory_channels(psoc);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		policy_mgr_err("failed to reset mandatory channels");
 		return status;
@@ -683,7 +683,7 @@ QDF_STATUS policy_mgr_psoc_disable(struct wlan_objmgr_psoc *psoc)
 
 	/* reset sap mandatory channels */
 	if (QDF_IS_STATUS_ERROR(
-		policy_mgr_reset_sap_mandatory_channels(pm_ctx))) {
+		policy_mgr_reset_sap_mandatory_channels(psoc))) {
 		policy_mgr_err("failed to reset sap mandatory channels");
 		status = QDF_STATUS_E_FAILURE;
 		QDF_ASSERT(0);

+ 59 - 0
core/hdd/src/wlan_hdd_cfg80211.c

@@ -8241,6 +8241,8 @@ const struct nla_policy wlan_hdd_wifi_config_policy[
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_EMLSR_MODE_SWITCH] = {
 		.type = NLA_U8},
 	[QCA_WLAN_VENDOR_ATTR_CONFIG_UL_MU_CONFIG] = {.type = NLA_U8},
+	[QCA_WLAN_VENDOR_ATTR_CONFIG_AP_ALLOWED_FREQ_LIST] = {
+		.type = NLA_NESTED},
 };
 
 static const struct nla_policy
@@ -11357,6 +11359,61 @@ hdd_trigger_epcs_function(struct wlan_hdd_link_info *link_info,
 }
 #endif
 
+/**
+ * hdd_set_master_channel_list() - set master channel list from set wifi
+ * attribute
+ * @link_info: hdd link info
+ * @attr: Pointer to struct nlattr
+ *
+ * Return: 0 on success, else error number
+ */
+static int
+hdd_set_master_channel_list(struct wlan_hdd_link_info *link_info,
+			    const struct nlattr *attr)
+{
+	struct sap_config *sap_config;
+	qdf_freq_t freq;
+	uint16_t count = 0;
+	qdf_freq_t *freq_list;
+	struct nlattr *nested_attr;
+	int tmp, ret = 0;
+
+	if (link_info->adapter->device_mode != QDF_SAP_MODE) {
+		hdd_debug("command not received for sap");
+		return -EINVAL;
+	}
+	freq_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(qdf_freq_t));
+	if (!freq_list)
+		return -ENOMEM;
+
+	sap_config = &link_info->adapter->deflink->session.ap.sap_config;
+
+	nla_for_each_nested(nested_attr, attr, tmp) {
+		freq = nla_get_u32(nested_attr);
+		if (!freq) {
+			hdd_err("invalid freq");
+			ret = -EINVAL;
+			goto out;
+		}
+		freq_list[count] = freq;
+		count++;
+		if (count >= NUM_CHANNELS)
+			break;
+	}
+	if (!count) {
+		hdd_err("no valid freq found");
+		ret = -EINVAL;
+		goto out;
+	}
+	ret = wlansap_update_sap_chan_list(sap_config, freq_list, count);
+	if (ret)
+		hdd_err("sap chan list update failure");
+out:
+	qdf_mem_free(freq_list);
+
+	return ret;
+}
+
 /**
  * typedef independent_setter_fn - independent attribute handler
  * @link_info: Link info pointer in HDD adapter
@@ -11502,6 +11559,8 @@ static const struct independent_setters independent_setters[] = {
 	 hdd_set_emlsr_mode},
 	{QCA_WLAN_VENDOR_ATTR_CONFIG_UL_MU_CONFIG,
 	 hdd_set_ul_mu_config},
+	{QCA_WLAN_VENDOR_ATTR_CONFIG_AP_ALLOWED_FREQ_LIST,
+	 hdd_set_master_channel_list},
 };
 
 #ifdef WLAN_FEATURE_ELNA

+ 10 - 0
core/sap/inc/sap_api.h

@@ -1924,6 +1924,16 @@ void wlansap_process_chan_info_event(struct sap_context *sap_ctx,
 void wlansap_update_ll_lt_sap_acs_result(struct sap_context *sap_ctx,
 					 qdf_freq_t last_acs_freq);
 
+/**
+ * wlansap_update_sap_chan_list() - set channel list of sap
+ * @sap_config: sap config
+ * @freq_list: freq list sent by userspace
+ * @count: valid freq count
+ *
+ * Return: 0 on success, else error number
+ */
+int wlansap_update_sap_chan_list(struct sap_config *sap_config,
+				 qdf_freq_t *freq_list, uint16_t count);
 #ifdef __cplusplus
 }
 #endif

+ 136 - 27
core/sap/src/sap_module.c

@@ -3747,11 +3747,111 @@ uint32_t wlansap_get_safe_channel_from_pcl_for_sap(struct sap_context *sap_ctx)
 	return wlansap_get_2g_first_safe_chan_freq(sap_ctx);
 }
 
+int wlansap_update_sap_chan_list(struct sap_config *sap_config,
+				 qdf_freq_t *freq_list, uint16_t count)
+{
+	uint32_t *acs_cfg_freq_list;
+	uint32_t *master_freq_list;
+
+	acs_cfg_freq_list = qdf_mem_malloc(count * sizeof(uint32_t));
+	if (!acs_cfg_freq_list)
+		return -ENOMEM;
+	if (sap_config->acs_cfg.ch_list_count) {
+		qdf_mem_free(sap_config->acs_cfg.freq_list);
+		sap_config->acs_cfg.freq_list = NULL;
+		sap_config->acs_cfg.ch_list_count = 0;
+	}
+	sap_config->acs_cfg.freq_list = acs_cfg_freq_list;
+
+	master_freq_list = qdf_mem_malloc(count * sizeof(uint32_t));
+	if (!master_freq_list)
+		return -ENOMEM;
+
+	if (sap_config->acs_cfg.master_ch_list_count) {
+		qdf_mem_free(sap_config->acs_cfg.master_freq_list);
+		sap_config->acs_cfg.master_freq_list = NULL;
+		sap_config->acs_cfg.master_ch_list_count = 0;
+	}
+	sap_config->acs_cfg.master_freq_list = master_freq_list;
+
+	qdf_mem_copy(sap_config->acs_cfg.freq_list, freq_list,
+		     sizeof(freq_list[0]) * count);
+	qdf_mem_copy(sap_config->acs_cfg.master_freq_list, freq_list,
+		     sizeof(freq_list[0]) * count);
+	sap_config->acs_cfg.master_ch_list_count = count;
+	sap_config->acs_cfg.ch_list_count = count;
+	sap_dump_acs_channel(&sap_config->acs_cfg);
+
+	return 0;
+}
+
+/**
+ * wlansap_get_valid_freq() - To get valid freq for sap csa
+ * @psoc: psoc object
+ * @sap_ctx: sap context
+ * @freq: pointer to valid freq
+ *
+ * Return: None
+ */
+static
+void wlansap_get_valid_freq(struct wlan_objmgr_psoc *psoc,
+			    struct sap_context *sap_ctx,
+			    qdf_freq_t *freq)
+{
+	uint8_t i, j;
+	struct mac_context *mac;
+	struct sir_pcl_list pcl = {0};
+	uint32_t *pcl_freqs;
+	QDF_STATUS status;
+	uint32_t pcl_len = 0;
+
+	pcl_freqs =  qdf_mem_malloc(NUM_CHANNELS * sizeof(uint32_t));
+	if (!pcl_freqs)
+		return;
+
+	mac = sap_get_mac_context();
+	if (!mac) {
+		sap_err("Invalid MAC context");
+		goto done;
+	}
+	status = policy_mgr_reset_sap_mandatory_channels(psoc);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sap_err("failed to reset mandatory channels");
+		goto done;
+	}
+	status = policy_mgr_get_pcl_for_vdev_id(mac->psoc, PM_SAP_MODE,
+						pcl_freqs, &pcl_len,
+						pcl.weight_list,
+						NUM_CHANNELS,
+						sap_ctx->sessionId);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sap_err("Get PCL failed for session %d", sap_ctx->sessionId);
+		goto done;
+	}
+	for (i = 0; i < pcl_len; i++) {
+		for (j = 0; j < sap_ctx->acs_cfg->master_ch_list_count; j++) {
+			/*
+			 * To keep valid freq list order same as pcl weightage
+			 * order pcl list index is compared with all the freq
+			 * provided by set wifi config.
+			 */
+			if (sap_ctx->acs_cfg->master_freq_list[j] ==
+			    pcl_freqs[i]) {
+				*freq = pcl_freqs[i];
+				goto done;
+			}
+		}
+	}
+done:
+	qdf_mem_free(pcl_freqs);
+	pcl_freqs = NULL;
+}
+
 qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx,
 					  enum sap_csa_reason_code *csa_reason)
 {
 	uint32_t restart_freq;
-	enum phy_ch_width restart_ch_width;
 	uint16_t intf_ch_freq;
 	uint32_t phy_mode;
 	struct mac_context *mac;
@@ -3760,6 +3860,7 @@ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx,
 	enum reg_wifi_band sap_band;
 	enum band_info band;
 	bool sta_sap_scc_on_indoor_channel;
+	qdf_freq_t freq = 0;
 
 	if (!sap_ctx) {
 		sap_err("sap_ctx NULL parameter");
@@ -3782,7 +3883,6 @@ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx,
 		sap_err("Failed to get current band config");
 		return 0;
 	}
-
 	sta_sap_scc_on_indoor_channel =
 		policy_mgr_get_sta_sap_scc_allowed_on_indoor_chnl(mac->psoc);
 	sap_band = wlan_reg_freq_to_band(sap_ctx->chan_freq);
@@ -3806,41 +3906,50 @@ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx,
 			sap_debug("use default chan 6");
 			restart_freq = TWOG_CHAN_6_IN_MHZ;
 		}
-		restart_ch_width = sap_ctx->ch_params.ch_width;
-		if (restart_ch_width > CH_WIDTH_40MHZ) {
-			sap_debug("set 40M when switch SAP to 2G");
-			restart_ch_width = CH_WIDTH_40MHZ;
-		}
 		*csa_reason = CSA_REASON_BAND_RESTRICTED;
-	} else if (sap_band == REG_BAND_2G && (band & BIT(REG_BAND_5G)) &&
-		   sap_ctx->chan_freq_before_switch_band) {
-		if (wlan_reg_is_enable_in_secondary_list_for_freq(
-				mac->pdev,
-				sap_ctx->chan_freq_before_switch_band)) {
-			restart_freq = sap_ctx->chan_freq_before_switch_band;
-			restart_ch_width = sap_ctx->chan_width_before_switch_band;
-			sap_debug("Restore chan freq: %d, width: %d",
-				  restart_freq, restart_ch_width);
-			*csa_reason = CSA_REASON_BAND_RESTRICTED;
-		} else {
-			enum reg_wifi_band pref_band;
+	} else if (sap_band == REG_BAND_2G && (band & BIT(REG_BAND_5G))) {
+		if (sap_ctx->chan_freq_before_switch_band) {
+			if (wlan_reg_is_enable_in_secondary_list_for_freq(
+			    mac->pdev,
+			    sap_ctx->chan_freq_before_switch_band)) {
+				restart_freq =
+					sap_ctx->chan_freq_before_switch_band;
+				sap_debug("Restore chan freq: %d",
+					  restart_freq);
+				*csa_reason = CSA_REASON_BAND_RESTRICTED;
+			} else {
+				enum reg_wifi_band pref_band;
 
-			pref_band = wlan_reg_freq_to_band(
+				pref_band =
+					wlan_reg_freq_to_band(
 					sap_ctx->chan_freq_before_switch_band);
-			restart_freq =
+				restart_freq =
 				policy_mgr_get_alternate_channel_for_sap(
 							mac->psoc,
 							sap_ctx->sessionId,
 							sap_ctx->chan_freq,
 							pref_band);
-			if (restart_freq) {
-				sap_debug("restart SAP on freq %d", restart_freq);
-				*csa_reason = CSA_REASON_BAND_RESTRICTED;
-			} else {
-				sap_debug("Did not get valid freq for band %d remain on same channel",
-					  pref_band);
+				if (restart_freq) {
+					sap_debug("restart SAP on freq %d",
+						  restart_freq);
+					*csa_reason =
+						CSA_REASON_BAND_RESTRICTED;
+				} else {
+					sap_debug("Did not get valid freq for band %d remain on same channel",
+						  pref_band);
+					return 0;
+				}
+			}
+		} else {
+			wlansap_get_valid_freq(mac->psoc, sap_ctx, &freq);
+			if (!freq) {
+				sap_debug("no valid freq found");
 				return 0;
 			}
+			restart_freq = freq;
+			sap_debug("restart SAP on freq %d",
+				  restart_freq);
+			*csa_reason = CSA_REASON_BAND_RESTRICTED;
 		}
 	} else if (wlan_reg_is_disable_for_pwrmode(mac->pdev,
 						   sap_ctx->chan_freq,