Ver Fonte

qcacmn: Add logic to force SCC in SAP+STA concurrency - Part 2

If STA is up on a a DFS or passive or LTE unsafe channel & SAP is
comings up that causes MCC, move SAP to the other band if DBS
is supported. This logic is enabled only if gWlanMccToSccSwitchMode
is set to QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION.

Change-Id: I5d393a21301f3fa838f7cf38620fb1d57ae1d57a
CRs-Fixed: 2063060
Tushnim Bhattacharyya há 7 anos atrás
pai
commit
6efce6c5dd

+ 36 - 0
umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -1947,4 +1947,40 @@ QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config(
  */
 bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
 		uint8_t channel);
+
+/**
+ * policy_mgr_is_force_scc() - checks if SCC needs to be
+ * mandated
+ * @psoc: PSOC object information
+ *
+ * This function checks if SCC needs to be mandated or not
+ *
+ * Return: True if SCC to be mandated, false otherwise
+ */
+bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * policy_mgr_valid_sap_conc_channel_check() - checks & updates
+ * the channel SAP to come up on in case of STA+SAP concurrency
+ * @psoc: PSOC object information
+ * @con_ch: pointer to the channel on which sap will come up
+ * @sap_ch: initial channel for SAP
+ *
+ * This function checks & updates the channel SAP to come up on in
+ * case of STA+SAP concurrency
+ * Return: Success if SAP can come up on a channel
+ */
+QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
+	struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch);
+
+/**
+ * policy_mgr_get_alternate_channel_for_sap() - Get an alternate
+ * channel to move the SAP to
+ * @psoc: PSOC object information
+ *
+ * This function returns an alternate channel for SAP to move to
+ * Return: The new channel for SAP
+ */
+uint8_t policy_mgr_get_alternate_channel_for_sap(
+	struct wlan_objmgr_psoc *psoc);
 #endif /* __WLAN_POLICY_MGR_API_H */

+ 73 - 0
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c

@@ -728,6 +728,79 @@ static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc,
 		return true;
 }
 
+QDF_STATUS policy_mgr_valid_sap_conc_channel_check(
+	struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch)
+{
+	uint8_t channel = *con_ch;
+	uint8_t temp_channel = 0;
+	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;
+	}
+
+	/*
+	 * if force SCC is set, Check if conc channel is DFS
+	 * or passive or part of LTE avoided channel list.
+	 * In that case move SAP to other band if DBS is supported,
+	 * return otherwise
+	 */
+	if (!policy_mgr_is_force_scc(psoc))
+		return QDF_STATUS_SUCCESS;
+
+	/*
+	 * if interference is 0, check if it is DBS case. If DBS case
+	 * return from here. If SCC, check further if SAP can move to
+	 * STA's channel.
+	 */
+	if (!channel &&
+		(sap_ch != policy_mgr_mode_specific_get_channel(
+			psoc, PM_STA_MODE)))
+		return QDF_STATUS_SUCCESS;
+	else if (!channel)
+		channel = sap_ch;
+
+	if (policy_mgr_valid_sta_channel_check(psoc, channel)) {
+		if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) ||
+			wlan_reg_is_passive_or_disable_ch(
+				pm_ctx->pdev, channel) ||
+			!policy_mgr_is_safe_channel(psoc, channel)) {
+			if (policy_mgr_is_hw_dbs_capable(psoc)) {
+				temp_channel =
+				policy_mgr_get_alternate_channel_for_sap(psoc);
+				policy_mgr_debug("temp_channel is %d",
+					temp_channel);
+				if (temp_channel) {
+					channel = temp_channel;
+				} else {
+					if (WLAN_REG_IS_5GHZ_CH(channel))
+						channel = PM_24_GHZ_CHANNEL_6;
+					else
+						channel = PM_5_GHZ_CHANNEL_36;
+				}
+				if (!policy_mgr_is_safe_channel(
+					psoc, channel)) {
+					policy_mgr_warn(
+						"Can't have concurrency on %d as it is not safe",
+						channel);
+					return QDF_STATUS_E_FAILURE;
+				}
+			} else {
+				policy_mgr_warn("Can't have concurrency on %d",
+					channel);
+				return QDF_STATUS_E_FAILURE;
+			}
+		}
+	}
+
+	if (channel != sap_ch)
+		*con_ch = channel;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * policy_mgr_check_concurrent_intf_and_restart_sap() - Check
  * concurrent change intf

+ 16 - 0
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -2627,3 +2627,19 @@ QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config(
 
 	return QDF_STATUS_SUCCESS;
 }
+
+bool policy_mgr_is_force_scc(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 0;
+	}
+
+	return ((pm_ctx->user_cfg.mcc_to_scc_switch_mode ==
+		QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) ||
+			(pm_ctx->user_cfg.mcc_to_scc_switch_mode ==
+		QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL));
+}

+ 16 - 0
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h

@@ -43,6 +43,9 @@
 #define CONNECTION_UPDATE_TIMEOUT 1000
 #endif
 
+#define PM_24_GHZ_CHANNEL_6   (6)
+#define PM_5_GHZ_CHANNEL_36   (36)
+
 /**
  * Policy Mgr hardware mode list bit-mask definitions.
  * Bits 4:0, 31:29 are unused.
@@ -426,4 +429,17 @@ void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc,
 		struct regulatory_channel *chan_list,
 		struct avoid_freq_ind_data *avoid_freq_ind,
 		void *arg);
+
+/**
+ * policy_mgr_mode_specific_get_channel() - Get channel for a
+ * connection type
+ * @psoc: PSOC object information
+ * @chan_list: Connection type
+ *
+ * Get channel for a connection type
+ *
+ * Return: channel number
+ */
+uint8_t policy_mgr_mode_specific_get_channel(
+	struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode);
 #endif

+ 47 - 3
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c

@@ -41,7 +41,6 @@
 #include "qdf_trace.h"
 #include "wlan_objmgr_global_obj.h"
 
-#define PM_24_GHZ_CHANNEL_6   (6)
 /**
  * first_connection_pcl_table - table which provides PCL for the
  * very first connection in the system
@@ -1653,8 +1652,9 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
 		 */
 		for (i = 0; i < weight->saved_num_chan; i++) {
 			if (policy_mgr_allow_concurrency(psoc, PM_STA_MODE,
-						  weight->saved_chan_list[i],
-						  HW_MODE_20_MHZ)) {
+					weight->saved_chan_list[i],
+					HW_MODE_20_MHZ) &&
+					!policy_mgr_is_force_scc(psoc)) {
 				weight->weighed_valid_list[i] =
 					WEIGHT_OF_NON_PCL_CHANNELS;
 			}
@@ -1677,3 +1677,47 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
 
 	return QDF_STATUS_SUCCESS;
 }
+
+uint8_t policy_mgr_mode_specific_get_channel(
+	struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode)
+{
+	uint32_t conn_index;
+	uint8_t channel = 0;
+	struct policy_mgr_psoc_priv_obj *pm_ctx;
+
+	pm_ctx = policy_mgr_get_context(psoc);
+	if (!pm_ctx) {
+		policy_mgr_err("Invalid Context");
+		return channel;
+	}
+	/* provides the channel for the first matching mode type */
+	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].mode == mode) &&
+			pm_conc_connection_list[conn_index].in_use) {
+			channel = pm_conc_connection_list[conn_index].chan;
+			break;
+		}
+	}
+	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
+
+	return channel;
+}
+
+uint8_t policy_mgr_get_alternate_channel_for_sap(
+	struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t pcl_channels[QDF_MAX_NUM_CHAN];
+	uint8_t pcl_weight[QDF_MAX_NUM_CHAN];
+	uint8_t channel = 0;
+	uint32_t pcl_len;
+
+	if (QDF_STATUS_SUCCESS == policy_mgr_get_pcl(psoc, PM_SAP_MODE,
+		&pcl_channels[0], &pcl_len,
+		pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) {
+		channel = pcl_channels[0];
+	}
+
+	return channel;
+}