Kaynağa Gözat

qcacld-3.0: Fix force SCC for MLO STA inactive case

Two mlo sta link vdev (2+6(LPI)) are started but hw mode is SMM (one
link maybe inactive in fw).
When start SAP on 5 GHz low, driver doesn't select force SCC channel for
such case. It left the SAP channel not changed (5 GHz 5220).
Since the 6 GHz STA link is on LPI mode, SAP is not allowed on
6 GHz (policy_mgr_modify_sap_pcl_for_6G_channels). Driver needs to
consider the PCL as well to select force SCC channel. Add new API
policy_mgr_get_pref_force_scc_freq to fix it.

Change-Id: I824de7168a26955caeeaff955a232c80baa13345
CRs-Fixed: 3280704
Liangwei Dong 2 yıl önce
ebeveyn
işleme
343b2e8d9e

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

@@ -4337,6 +4337,22 @@ bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc,
 				   enum policy_mgr_con_mode mode,
 				   uint8_t *mlo_vdev_lst, uint8_t *num_mlo);
 
+/**
+ * policy_mgr_is_mlo_in_mode_dbs() - Check whether MLO present is DBS
+ * @psoc: PSOC object information
+ * @mode: mlo mode to check
+ * @mlo_vdev_lst: Pointer to mlo vdev list, this function wil fill this with
+ *                list of mlo vdev
+ * @num_mlo: Pointer to number of mlo link, this function will fill this with
+ *           number of mlo links
+ *
+ * Return: True if MLO one link is on 2 GHz band and other links on
+ * 5/6 GHz band
+ */
+bool policy_mgr_is_mlo_in_mode_dbs(struct wlan_objmgr_psoc *psoc,
+				   enum policy_mgr_con_mode mode,
+				   uint8_t *mlo_vdev_lst, uint8_t *num_mlo);
+
 /**
  * policy_mgr_is_mlo_in_mode_emlsr() - Check whether current connection is eMLSR
  * @psoc: PSOC object information
@@ -4424,6 +4440,14 @@ bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc,
 	return false;
 }
 
+static inline
+bool policy_mgr_is_mlo_in_mode_dbs(struct wlan_objmgr_psoc *psoc,
+				   enum policy_mgr_con_mode mode,
+				   uint8_t *mlo_vdev_lst, uint8_t *num_mlo)
+{
+	return false;
+}
+
 static inline void
 policy_mgr_handle_ml_sta_links_on_vdev_up_csa(struct wlan_objmgr_psoc *psoc,
 					      enum QDF_OPMODE mode,

+ 119 - 115
components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c

@@ -3997,107 +3997,47 @@ bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc,
 	return true;
 }
 
-static qdf_freq_t
-policy_mgr_get_iface_5g_freq(struct wlan_objmgr_psoc *psoc,
-			     bool allow_6ghz)
-{
-	qdf_freq_t if_freq = 0;
-	struct policy_mgr_psoc_priv_obj *pm_ctx;
-	uint32_t conn_index;
-
-	pm_ctx = policy_mgr_get_context(psoc);
-	if (!pm_ctx) {
-		policy_mgr_err("Invalid Context");
-		return 0;
-	}
-
-	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
-	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
-		conn_index++) {
-		if (pm_conc_connection_list[conn_index].in_use &&
-		    (WLAN_REG_IS_5GHZ_CH_FREQ(
-				pm_conc_connection_list[conn_index].freq) ||
-		     (allow_6ghz && WLAN_REG_IS_6GHZ_CHAN_FREQ(
-				pm_conc_connection_list[conn_index].freq)))) {
-			if_freq = pm_conc_connection_list[conn_index].freq;
-			break;
-		}
-	}
-	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
-
-	return if_freq;
-}
-
-static qdf_freq_t
-policy_mgr_get_iface_2g_freq(struct wlan_objmgr_psoc *psoc)
-{
-	qdf_freq_t if_freq = 0;
-	struct policy_mgr_psoc_priv_obj *pm_ctx;
-	uint32_t conn_index;
-
-	pm_ctx = policy_mgr_get_context(psoc);
-	if (!pm_ctx) {
-		policy_mgr_err("Invalid Context");
-		return 0;
-	}
-
-	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
-	for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
-		conn_index++) {
-		if (pm_conc_connection_list[conn_index].in_use &&
-		    (WLAN_REG_IS_24GHZ_CH_FREQ(
-				pm_conc_connection_list[conn_index].freq))) {
-			if_freq = pm_conc_connection_list[conn_index].freq;
-			break;
-		}
-	}
-	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
-
-	return if_freq;
-}
-
-static qdf_freq_t
-policy_mgr_get_same_band_iface_frq(struct wlan_objmgr_psoc *psoc,
-				   qdf_freq_t ch_freq, bool allow_6ghz)
-{
-	return (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) ?
-		policy_mgr_get_iface_2g_freq(psoc) :
-		policy_mgr_get_iface_5g_freq(psoc, allow_6ghz));
-}
-
 /**
- * policy_mgr_check_force_scc_three_connection() - Check 3 connection cases
- * to find the force SCC channel for SAP/GO
+ * policy_mgr_get_pref_force_scc_freq() - Get preferred force SCC
+ * channel frequency
  * @psoc: Pointer to Psoc
- * @vdev_id: vdev id of SAP/GO
- * @intf_ch_freq: interference channel frequency
- * @sap_ch_freq: SAP/GO current home channel frequency
- * @acs_band: acs band perference
- * @allow_6ghz: interface supports 6Ghz band
+ * @vdev_id: vdev id
+ * @intf_ch_freq: prefer force scc frequency
+ * @sap_ch_freq: sap/go channel starting channel frequency
+ * @acs_band: acs band
+ * @allow_6ghz: allow 6 Ghz channel or not
+ * @allow_non_scc: allow non SCC channel or not
  *
- * This function gets the force SCC channel in 3 connections case.
+ * This API will consider protocol 6ghz allow flag - allow_6ghz.
+ * Also for regdomain, it will consider PCL allow or not.
+ * For example, if STA is on 6ghz LPI mode, SAP is not allowed
+ * force scc to 6ghz, see API
+ * policy_mgr_modify_sap_pcl_for_6G_channels.
  *
- * Return: QDF_STATUS_SUCCESS if success
+ * Return: QDF_STATUS_SUCCESS if get preferred force scc channel.
  */
 static QDF_STATUS
-policy_mgr_check_force_scc_three_connection(struct wlan_objmgr_psoc *psoc,
-					    uint8_t vdev_id,
-					    qdf_freq_t *intf_ch_freq,
-					    qdf_freq_t sap_ch_freq,
-					    uint32_t acs_band,
-					    bool allow_6ghz)
+policy_mgr_get_pref_force_scc_freq(struct wlan_objmgr_psoc *psoc,
+				   uint8_t vdev_id,
+				   qdf_freq_t *intf_ch_freq,
+				   qdf_freq_t sap_ch_freq,
+				   uint32_t acs_band,
+				   bool allow_6ghz,
+				   bool allow_non_scc)
 {
 	struct policy_mgr_psoc_priv_obj *pm_ctx;
 	enum policy_mgr_con_mode mode;
 	QDF_STATUS status;
 	uint32_t i;
 	struct policy_mgr_pcl_list pcl;
-	bool allow_2ghz_only = true;
-	uint32_t scc_ch_freq_on_same_band = 0;
-	uint32_t scc_ch_freq_on_diff_band_freq = 0;
-	uint32_t scc_ch_freq_same_as_sap = 0;
+	bool allow_2ghz_only = false;
+	qdf_freq_t scc_ch_freq_on_same_band = 0;
+	qdf_freq_t scc_ch_freq_on_diff_band_freq = 0;
+	qdf_freq_t scc_ch_freq_same_as_sap = 0;
+	qdf_freq_t non_scc_ch_freq_on_same_band = 0;
+	qdf_freq_t non_scc_ch_freq_on_diff_band_freq = 0;
 	enum QDF_OPMODE op_mode;
-	uint32_t pcl_freq;
+	qdf_freq_t pcl_freq;
 
 	pm_ctx = policy_mgr_get_context(psoc);
 	if (!pm_ctx) {
@@ -4118,10 +4058,10 @@ policy_mgr_check_force_scc_three_connection(struct wlan_objmgr_psoc *psoc,
 		return QDF_STATUS_E_INVAL;
 	}
 
-	if (acs_band == QCA_ACS_MODE_IEEE80211ANY ||
-	    acs_band == QCA_ACS_MODE_IEEE80211A ||
-	    !WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq))
-		allow_2ghz_only = false;
+	if ((acs_band == QCA_ACS_MODE_IEEE80211B ||
+	     acs_band == QCA_ACS_MODE_IEEE80211G) &&
+	     WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq))
+		allow_2ghz_only = true;
 
 	/* qdf_conc_list_lock has been locked by caller.
 	 * The preferred force SCC channel is SAP original channel,
@@ -4140,10 +4080,19 @@ policy_mgr_check_force_scc_three_connection(struct wlan_objmgr_psoc *psoc,
 		if (allow_2ghz_only && !WLAN_REG_IS_24GHZ_CH_FREQ(pcl_freq))
 			continue;
 
-		if (!(pcl_freq == pm_conc_connection_list[0].freq ||
-		      pcl_freq == pm_conc_connection_list[1].freq ||
-		      pcl_freq == pm_conc_connection_list[2].freq))
+		if (!((pm_conc_connection_list[0].in_use &&
+		       (pcl_freq == pm_conc_connection_list[0].freq)) ||
+		      (pm_conc_connection_list[1].in_use &&
+		       (pcl_freq == pm_conc_connection_list[1].freq)) ||
+		      (pm_conc_connection_list[2].in_use &&
+		       (pcl_freq == pm_conc_connection_list[2].freq)))) {
+			if (!non_scc_ch_freq_on_same_band &&
+			    WLAN_REG_IS_SAME_BAND_FREQS(sap_ch_freq, pcl_freq))
+				non_scc_ch_freq_on_same_band = pcl_freq;
+			else if (!non_scc_ch_freq_on_diff_band_freq)
+				non_scc_ch_freq_on_diff_band_freq = pcl_freq;
 			continue;
+		}
 
 		if (sap_ch_freq == pcl_freq)
 			scc_ch_freq_same_as_sap = pcl_freq;
@@ -4160,14 +4109,50 @@ policy_mgr_check_force_scc_three_connection(struct wlan_objmgr_psoc *psoc,
 		*intf_ch_freq = scc_ch_freq_on_same_band;
 	else if (scc_ch_freq_on_diff_band_freq)
 		*intf_ch_freq = scc_ch_freq_on_diff_band_freq;
+	else if (allow_non_scc && non_scc_ch_freq_on_same_band)
+		*intf_ch_freq = non_scc_ch_freq_on_same_band;
+	else if (allow_non_scc && non_scc_ch_freq_on_diff_band_freq)
+		*intf_ch_freq = non_scc_ch_freq_on_diff_band_freq;
 	else
 		*intf_ch_freq = 0;
 
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * policy_mgr_check_force_scc_three_connection() - Check 3 connection cases
+ * to find the force SCC channel for SAP/GO
+ * @psoc: Pointer to Psoc
+ * @vdev_id: vdev id of SAP/GO
+ * @intf_ch_freq: interference channel frequency
+ * @sap_ch_freq: SAP/GO current home channel frequency
+ * @acs_band: acs band perference
+ * @allow_6ghz: interface supports 6Ghz band
+ *
+ * This function gets the force SCC channel in 3 connections case.
+ *
+ * Return: QDF_STATUS_SUCCESS if success
+ */
+static QDF_STATUS
+policy_mgr_check_force_scc_three_connection(struct wlan_objmgr_psoc *psoc,
+					    uint8_t vdev_id,
+					    qdf_freq_t *intf_ch_freq,
+					    qdf_freq_t sap_ch_freq,
+					    uint32_t acs_band,
+					    bool allow_6ghz)
+{
+	return policy_mgr_get_pref_force_scc_freq(psoc,
+						  vdev_id,
+						  intf_ch_freq,
+						  sap_ch_freq,
+						  acs_band,
+						  allow_6ghz,
+						  false);
+}
+
 static void
 policy_mgr_check_force_scc_two_connection(struct wlan_objmgr_psoc *psoc,
+					  uint8_t vdev_id,
 					  qdf_freq_t *intf_ch_freq,
 					  qdf_freq_t sap_ch_freq,
 					  uint8_t cc_mode,
@@ -4176,6 +4161,7 @@ policy_mgr_check_force_scc_two_connection(struct wlan_objmgr_psoc *psoc,
 					  bool allow_6ghz)
 {
 	bool sbs_mlo_present = false;
+	bool dbs_mlo_present = false;
 
 	/*
 	 * 1st:    2nd:           3rd(SAP):      Action:
@@ -4217,19 +4203,33 @@ policy_mgr_check_force_scc_two_connection(struct wlan_objmgr_psoc *psoc,
 		 * 5Ghz    5Ghz(SBS)   2Ghz        If acs is ALL band force SCC
 		 *                                 else start on 2.4Ghz
 		 * 5Ghz    5Ghz(SBS)   5Ghz        Force SCC to one of 5Ghz
+		 *
+		 * Need to consider protocol 6ghz allow flag - allow_6ghz.
+		 * Also for regdomain, need to consider PCL if STA is on 6ghz
+		 * LPI mode, SAP is not allowed started on 6ghz, see API
+		 * policy_mgr_modify_sap_pcl_for_6G_channels.
 		 */
-		if (acs_band == QCA_ACS_MODE_IEEE80211ANY ||
-		    !WLAN_REG_IS_24GHZ_CH_FREQ(sap_ch_freq))
-			*intf_ch_freq =
-				policy_mgr_get_iface_5g_freq(psoc, allow_6ghz);
-		else
-			*intf_ch_freq =
-				policy_mgr_get_same_band_iface_frq(psoc,
-								   sap_ch_freq,
-								   allow_6ghz);
+		policy_mgr_get_pref_force_scc_freq(psoc,
+						   vdev_id,
+						   intf_ch_freq,
+						   sap_ch_freq,
+						   acs_band,
+						   allow_6ghz,
+						   true);
 		return;
 	}
-	if (policy_mgr_is_current_hwmode_dbs(psoc)) {
+	/*
+	 * Check for dbs mlo present as if 1 link is inactive the
+	 * HW mode will be SMM and not dbs.
+	 */
+	if (policy_mgr_is_hw_dbs_capable(psoc) &&
+	    (policy_mgr_is_mlo_in_mode_dbs(psoc, PM_STA_MODE,
+					   NULL, NULL) ||
+	     policy_mgr_is_mlo_in_mode_dbs(psoc, PM_SAP_MODE,
+					   NULL, NULL)))
+		dbs_mlo_present = true;
+
+	if (policy_mgr_is_current_hwmode_dbs(psoc) || dbs_mlo_present) {
 		/*
 		 * 1st:    2nd:           3rd(SAP):      Action:
 		 * -------------------------------------------------
@@ -4240,16 +4240,19 @@ policy_mgr_check_force_scc_two_connection(struct wlan_objmgr_psoc *psoc,
 		 *                                       the freq (3 home
 		 *                                       channel will not be
 		 *                                       allowed)
+		 *
+		 * Need to consider protocol 6ghz allow flag - allow_6ghz.
+		 * Also for regdomain, need to consider PCL if STA is on 6ghz
+		 * LPI mode, SAP is not allowed started on 6ghz, see API
+		 * policy_mgr_modify_sap_pcl_for_6G_channels.
 		 */
-		/*
-		 * For DBS allow the 6Ghz as we may only have 1 5Ghz freq.
-		 * policy_mgr_valid_sap_conc_channel_check->
-		 * policy_mgr_check_6ghz_sap_conc will take care of switching to
-		 * other channel if 6Ghz is not allowed
-		 */
-		*intf_ch_freq =
-			policy_mgr_get_same_band_iface_frq(psoc, sap_ch_freq,
-							   true);
+		policy_mgr_get_pref_force_scc_freq(psoc,
+						   vdev_id,
+						   intf_ch_freq,
+						   sap_ch_freq,
+						   acs_band,
+						   allow_6ghz,
+						   true);
 		return;
 	}
 
@@ -4525,7 +4528,8 @@ sbs_check:
 							  cc_mode);
 		break;
 	case 2:
-		policy_mgr_check_force_scc_two_connection(psoc, intf_ch_freq,
+		policy_mgr_check_force_scc_two_connection(psoc, vdev_id,
+							  intf_ch_freq,
 							  sap_ch_freq,
 							  cc_mode,
 							  same_band_present,

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

@@ -4982,6 +4982,54 @@ bool policy_mgr_is_mlo_in_mode_sbs(struct wlan_objmgr_psoc *psoc,
 	return is_sbs_link;
 }
 
+bool policy_mgr_is_mlo_in_mode_dbs(struct wlan_objmgr_psoc *psoc,
+				   enum policy_mgr_con_mode mode,
+				   uint8_t *mlo_vdev_lst, uint8_t *num_mlo)
+{
+	uint32_t mode_num = 0;
+	uint8_t i, mlo_idx = 0;
+	struct wlan_objmgr_vdev *temp_vdev;
+	uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
+	bool has_2g_link = false;
+	bool has_5g_link = false;
+	qdf_freq_t mlo_freq;
+
+	mode_num = policy_mgr_get_mode_specific_conn_info(psoc, NULL,
+							  vdev_id_list, mode);
+	if (!mode_num || mode_num < 2)
+		return false;
+
+	for (i = 0; i < mode_num; i++) {
+		temp_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
+							psoc,
+							vdev_id_list[i],
+							WLAN_POLICY_MGR_ID);
+		if (!temp_vdev) {
+			policy_mgr_err("invalid vdev for id %d",
+				       vdev_id_list[i]);
+			return false;
+		}
+
+		if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) {
+			if (mlo_vdev_lst)
+				mlo_vdev_lst[mlo_idx] = vdev_id_list[i];
+			mlo_freq =
+				wlan_get_operation_chan_freq(temp_vdev);
+			if (wlan_reg_is_24ghz_ch_freq(mlo_freq))
+				has_2g_link = true;
+			else
+				has_5g_link = true;
+			mlo_idx++;
+		}
+		wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_POLICY_MGR_ID);
+	}
+
+	if (num_mlo)
+		*num_mlo = mlo_idx;
+
+	return has_2g_link && has_5g_link;
+}
+
 bool policy_mgr_is_curr_hwmode_emlsr(struct wlan_objmgr_psoc *psoc)
 {
 	struct policy_mgr_hw_mode_params hw_mode;