Explorar el Código

qcacld-3.0: Consider Random 6 GHz channel if DCS triggers CSA

Currently, if Channel change is required via DCS then ACS
is triggered to select the best available channel . In case of
XR SAP optimization, SAP can not come on 2 GHz and frequencies
that can be shared by current SAP frequency on same MAC are
removed from scan list. As result of which frequencies
5/6 GHz in case of DBS and 5 GHz low/5 GHz high + 6 GHz based
on which 5 GHz range is shared with 2 GHz will be disacrded from scan
list. In short Scan can not be  triggered on freqeuncies of same MAC
on which SAP is up and can not come in MCC. So, if any other device
mode is up on 2 GHz on other MAC turning on SAP on other MAC can
cause MCC in case of SBS and DBS HW which is not preferred.

Fix is to start SAP on random 6 GHz channel when case CSA is required
due to DCS in case SAP can't come up on 2 GHz and scan can not be
triggered for same MAC on which SAP is enabled i.e ACS optimization
is enabled for XR SAP.

Change-Id: I0cb46a409e3ee04044f7a0b12addec464e87ef7d
CRs-Fixed: 3404097
Sheenam Monga hace 2 años
padre
commit
49a247ab1b

+ 13 - 0
components/mlme/core/inc/wlan_mlme_main.h

@@ -1674,4 +1674,17 @@ wlan_mlme_is_pmk_set_deferred(struct wlan_objmgr_psoc *psoc,
  */
 bool wlan_vdev_is_sae_auth_type(struct wlan_objmgr_vdev *vdev);
 #endif /* WLAN_FEATURE_SAE */
+
+/**
+ * wlan_get_rand_from_lst_for_freq()- Get random channel from a given channel
+ * list.
+ * @freq_lst: Frequency list
+ * @num_chan: number of channels
+ *
+ * Get random channel from given channel list.
+ *
+ * Return: channel frequency.
+ */
+uint16_t wlan_get_rand_from_lst_for_freq(uint16_t *freq_lst,
+					 uint8_t num_chan);
 #endif

+ 17 - 0
components/mlme/core/src/wlan_mlme_main.c

@@ -1538,6 +1538,23 @@ static bool is_sae_sap_enabled(struct wlan_objmgr_psoc *psoc)
 	return false;
 }
 #endif
+uint16_t wlan_get_rand_from_lst_for_freq(uint16_t *freq_lst,
+					 uint8_t num_chan)
+{
+	uint8_t i;
+	uint32_t rand_byte = 0;
+
+	if (!num_chan || !freq_lst) {
+		mlme_legacy_debug("invalid param freq_lst %pK, num_chan = %d",
+				  freq_lst, num_chan);
+		return 0;
+	}
+
+	get_random_bytes((uint8_t *)&rand_byte, 1);
+	i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_chan;
+
+	return freq_lst[i];
+}
 
 static void mlme_init_sap_cfg(struct wlan_objmgr_psoc *psoc,
 			      struct wlan_mlme_cfg_sap *sap_cfg)

+ 109 - 0
core/hdd/src/wlan_hdd_dcs.c

@@ -29,6 +29,7 @@
 #include <wlan_dlm_ucfg_api.h>
 #include <wlan_osif_priv.h>
 #include <wlan_objmgr_vdev_obj.h>
+#include <wlan_dcs_ucfg_api.h>
 
 /* Time(in milliseconds) before which the AP doesn't expect a connection */
 #define HDD_DCS_AWGN_BSS_RETRY_DELAY (5 * 60 * 1000)
@@ -147,6 +148,98 @@ static QDF_STATUS hdd_dcs_switch_chan_cb(struct wlan_objmgr_vdev *vdev,
 	return status;
 }
 
+#ifdef WLAN_FEATURE_SAP_ACS_OPTIMIZE
+/**
+ * hdd_get_bw_for_freq - get BW for provided freq
+ * @res_msg: resp msg with freq info
+ * @freq: freq for which BW is required
+ * @total_chan: total no of channels
+ *
+ * Return: bandwidth
+ */
+static enum phy_ch_width
+hdd_get_bw_for_freq(struct get_usable_chan_res_params *res_msg,
+		    uint16_t freq, uint16_t total_chan)
+{
+	uint16_t i;
+
+	for (i = 0; i < total_chan; i++) {
+		if (res_msg[i].freq == freq)
+			return res_msg[i].bw;
+	}
+	return CH_WIDTH_INVALID;
+}
+
+/**
+ * hdd_dcs_select_random_chan: To select random 6G channel
+ * for CSA
+ * @pdev: pdev object
+ * @vdev: vdevobject
+ *
+ * Return: success/failure
+ */
+static QDF_STATUS
+hdd_dcs_select_random_chan(struct wlan_objmgr_pdev *pdev,
+			   struct wlan_objmgr_vdev *vdev)
+{
+	struct get_usable_chan_req_params req_msg;
+	struct get_usable_chan_res_params *res_msg;
+	enum phy_ch_width tgt_width;
+	uint16_t final_lst[NUM_CHANNELS] = {0};
+	uint16_t intf_ch_freq = 0;
+	uint32_t count;
+	uint32_t i;
+	QDF_STATUS status = QDF_STATUS_E_EMPTY;
+
+	res_msg = qdf_mem_malloc(NUM_CHANNELS *
+			sizeof(*res_msg));
+
+	if (!res_msg) {
+		hdd_err("res_msg invalid");
+		return QDF_STATUS_E_NOMEM;
+	}
+	req_msg.band_mask = BIT(REG_BAND_6G);
+	req_msg.iface_mode_mask = BIT(NL80211_IFTYPE_AP);
+	req_msg.filter_mask = 0;
+	status = wlan_reg_get_usable_channel(pdev, req_msg, res_msg, &count);
+	if (QDF_STATUS_SUCCESS != status) {
+		hdd_err("get usable channel failed %d", status);
+		qdf_mem_free(res_msg);
+		return QDF_STATUS_E_INVAL;
+	}
+	hdd_debug("channel count %d for band %d", count, REG_BAND_6G);
+	for (i = 0; i < count; i++)
+		final_lst[i] = res_msg[i].freq;
+
+	intf_ch_freq = wlan_get_rand_from_lst_for_freq(final_lst, count);
+	if (!intf_ch_freq || intf_ch_freq > wlan_reg_max_6ghz_chan_freq()) {
+		hdd_debug("ch freq gt max 6g freq %d",
+			  wlan_reg_max_6ghz_chan_freq());
+		qdf_mem_free(res_msg);
+		return QDF_STATUS_E_INVAL;
+	}
+	tgt_width = hdd_get_bw_for_freq(res_msg, intf_ch_freq, count);
+	if (tgt_width >= CH_WIDTH_INVALID) {
+		qdf_mem_free(res_msg);
+		return QDF_STATUS_E_INVAL;
+	}
+	if (tgt_width > CH_WIDTH_160MHZ) {
+		hdd_debug("restrict max bw to 160");
+		tgt_width = CH_WIDTH_160MHZ;
+	}
+	qdf_mem_free(res_msg);
+	return ucfg_dcs_switch_chan(vdev, intf_ch_freq,
+				    tgt_width);
+}
+#else
+static inline QDF_STATUS
+hdd_dcs_select_random_chan(struct wlan_objmgr_pdev *pdev,
+			   struct wlan_objmgr_vdev *vdev)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+
 /**
  * hdd_dcs_cb() - hdd dcs specific callback
  * @psoc: psoc
@@ -166,6 +259,7 @@ static void hdd_dcs_cb(struct wlan_objmgr_psoc *psoc, uint8_t mac_id,
 	uint32_t count;
 	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
 	uint32_t index;
+	QDF_STATUS status;
 
 	/*
 	 * so far CAP_DCS_CWIM interference mitigation is not supported
@@ -198,6 +292,21 @@ static void hdd_dcs_cb(struct wlan_objmgr_psoc *psoc, uint8_t mac_id,
 			WLAN_HDD_GET_SAP_CTX_PTR(adapter))) {
 			hdd_debug("DCS triggers ACS on vdev_id=%u, mac_id=%u",
 				  list[index], mac_id);
+			/*
+			 * Select Random channel for low latency sap as
+			 * ACS can't select channel of same MAC from which
+			 * CSA is triggered because same MAC frequencies
+			 * will not be present in scan list and results and
+			 * selecting freq of other MAC may cause MCC with
+			 * other modes if present.
+			 */
+			if (wlan_mlme_get_ap_policy(adapter->vdev) !=
+			    HOST_CONCURRENT_AP_POLICY_UNSPECIFIED) {
+				status = hdd_dcs_select_random_chan(
+						hdd_ctx->pdev, adapter->vdev);
+				if (QDF_IS_STATUS_SUCCESS(status))
+					return;
+			}
 			wlan_hdd_cfg80211_start_acs(adapter);
 			return;
 		}