浏览代码

qcacmn: Trim ACS channel list based on the concurrent connections

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.

Change-Id: Ibd580a7afdcdfc5fb4398ada547565e229d59c70
CRs-Fixed: 2193720
Tushnim Bhattacharyya 7 年之前
父节点
当前提交
0f7b9cd898

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

@@ -2244,4 +2244,15 @@ bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(
  * Return: true if sta is connected in 2g else false
  */
 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
+ * @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);
 #endif /* __WLAN_POLICY_MGR_API_H */

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

@@ -2820,3 +2820,86 @@ 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)
+{
+	uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
+	uint32_t index, 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;
+	}
+
+	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) {
+		index = 0;
+		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) {
+			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];
+	}
+}