Parcourir la source

qcacld-3.0: Fix AP AP start fail

2 SAP start ACS but different channel range at almost
same time. First SAP selected and started on DFS channel
5260, second SAP select and start on MCC channel of 5180,
policy_mgr_allow_concurrency in
__wlan_hdd_cfg80211_start_ap check fail and abort the second
SAP start because of MCC not allowed for DFS channel SAP.
Refine the logic in API policy_mgr_is_ap_ap_mcc_allow
to cover this case, try to override 2nd SAP channel
to avoid start failure.

Change-Id: Ie483e1fc68f73ce87d14f647ee6fe27b015b5a79
CRs-Fixed: 3512135
Liangwei Dong il y a 1 an
Parent
commit
5c49e57e75

+ 9 - 3
components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h

@@ -4995,9 +4995,13 @@ bool policy_mgr_is_sta_chan_valid_for_connect_and_roam(
  * @pdev: pdev object
  * @vdev: vdev object of new SAP or P2P GO
  * @ch_freq: channel frequency of up coming vdev
- * @ch_wdith: channel width
+ * @ch_width: channel width
+ * @con_vdev_id: concurrent SAP/GO vdev id
+ * @con_freq: concurrent SAP/GO home channel.
  *
- * Check if AP AP MCC allow or not when new SAP or P2P GO creating
+ * Check if AP AP MCC allow or not when new SAP or P2P GO creating.
+ * If not allowed, the concurrency SAP/GO vdev and channel will
+ * be returned.
  *
  * Return: True if the target allow AP AP MCC,
  *         False otherwise.
@@ -5006,7 +5010,9 @@ bool policy_mgr_is_ap_ap_mcc_allow(struct wlan_objmgr_psoc *psoc,
 				   struct wlan_objmgr_pdev *pdev,
 				   struct wlan_objmgr_vdev *vdev,
 				   uint32_t ch_freq,
-				   enum phy_ch_width ch_wdith);
+				   enum phy_ch_width ch_width,
+				   uint8_t *con_vdev_id,
+				   uint32_t *con_freq);
 
 /**
  * policy_mgr_any_other_vdev_on_same_mac_as_freq() - Function to check

+ 49 - 34
components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c

@@ -10195,30 +10195,53 @@ bool policy_mgr_is_ap_ap_mcc_allow(struct wlan_objmgr_psoc *psoc,
 				   struct wlan_objmgr_pdev *pdev,
 				   struct wlan_objmgr_vdev *vdev,
 				   uint32_t ch_freq,
-				   enum phy_ch_width ch_wdith)
+				   enum phy_ch_width ch_width,
+				   uint8_t *con_vdev_id,
+				   uint32_t *con_freq)
 {
 	enum QDF_OPMODE mode;
 	enum policy_mgr_con_mode con_mode;
-	uint8_t mcc_to_scc_switch;
-	uint32_t num_connections;
-	bool is_dfs_ch = false;
-	struct ch_params ch_params;
 	union conc_ext_flag conc_ext_flags;
+	uint32_t cc_count, i;
+	uint32_t op_freq[MAX_NUMBER_OF_CONC_CONNECTIONS * 2];
+	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS * 2];
 
 	if (!psoc || !vdev || !pdev) {
 		policy_mgr_debug("psoc or vdev or pdev is NULL");
 		return false;
 	}
+	cc_count = policy_mgr_get_mode_specific_conn_info(psoc,
+							  &op_freq[0],
+							  &vdev_id[0],
+							  PM_SAP_MODE);
+	if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
+		cc_count = cc_count +
+				policy_mgr_get_mode_specific_conn_info(
+					psoc,
+					&op_freq[cc_count],
+					&vdev_id[cc_count],
+					PM_P2P_GO_MODE);
+	for (i = 0 ; i < cc_count; i++) {
+		if (ch_freq == op_freq[i])
+			break;
+		if (!policy_mgr_is_hw_dbs_capable(psoc))
+			break;
+		if (wlan_reg_is_same_band_freqs(ch_freq, op_freq[i]) &&
+		    !policy_mgr_are_sbs_chan(psoc, ch_freq, op_freq[i]))
+			break;
+	}
+	/* If same band MCC SAP/GO not present, return true,
+	 * no AP to AP channel override
+	 */
+	if (i >= cc_count)
+		return true;
+
+	*con_freq = op_freq[i];
+	*con_vdev_id = vdev_id[i];
 
 	mode = wlan_vdev_mlme_get_opmode(vdev);
 	con_mode = policy_mgr_convert_device_mode_to_qdf_type(mode);
-	qdf_mem_zero(&ch_params, sizeof(ch_params));
-	ch_params.ch_width = ch_wdith;
-	if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
-	    wlan_reg_get_5g_bonded_channel_state_for_pwrmode(
-			pdev, ch_freq, &ch_params,
-			REG_CURRENT_PWR_MODE) == CHANNEL_STATE_DFS)
-		is_dfs_ch = true;
+
 	/*
 	 * For 3Vif concurrency we only support SCC in same MAC
 	 * in below combination:
@@ -10226,30 +10249,22 @@ bool policy_mgr_is_ap_ap_mcc_allow(struct wlan_objmgr_psoc *psoc,
 	 * 3 beaconing entities in SCC.
 	 */
 	conc_ext_flags.value = policy_mgr_get_conc_ext_flags(vdev, false);
-	num_connections = policy_mgr_get_connection_count(psoc);
-	if (num_connections > 1 &&
-	    (mode == QDF_P2P_GO_MODE || mode == QDF_SAP_MODE) &&
-	    !policy_mgr_allow_new_home_channel(psoc, con_mode, ch_freq,
-					       num_connections, is_dfs_ch,
-					       conc_ext_flags.value))
+	if (!policy_mgr_allow_concurrency(
+			psoc, con_mode, ch_freq,
+			policy_mgr_get_bw(ch_width),
+			conc_ext_flags.value,
+			wlan_vdev_get_id(vdev))) {
+		policy_mgr_debug("AP AP mcc not allowed, try to override 2nd SAP/GO chan");
+		return false;
+	}
+	/* For SCC case & bandwdith > 20, the center frequency have to be
+	 * same to avoid target MCC on different center frequency even though
+	 * primary channel are same.
+	 */
+	if (*con_freq == ch_freq && wlan_reg_get_bw_value(ch_width) > 20)
 		return false;
 
-	policy_mgr_get_mcc_scc_switch(psoc, &mcc_to_scc_switch);
-	if (mode == QDF_P2P_GO_MODE &&
-	    policy_mgr_is_p2p_p2p_conc_supported(psoc))
-		return true;
-	if (!policy_mgr_concurrent_beaconing_sessions_running(psoc))
-		return true;
-	if (policy_mgr_dual_beacon_on_single_mac_mcc_capable(psoc))
-		return true;
-	if (!policy_mgr_dual_beacon_on_single_mac_scc_capable(psoc))
-		return true;
-	if ((mcc_to_scc_switch !=
-		QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) &&
-	    (mcc_to_scc_switch != QDF_MCC_TO_SCC_WITH_PREFERRED_BAND))
-		return true;
-
-	return false;
+	return true;
 }
 
 bool policy_mgr_any_other_vdev_on_same_mac_as_freq(

+ 5 - 71
core/hdd/src/wlan_hdd_hostapd.c

@@ -7357,39 +7357,6 @@ wlan_hdd_get_sap_ch_params(struct hdd_context *hdd_ctx,
 	return QDF_STATUS_SUCCESS;
 }
 
-/**
- * wlan_hdd_is_same_freq_seg() - Check freq segment is same or not
- * @chandef: channel of new SAP
- * @ch_params: channel parameters of existed SAP
- *
- * If two SAP on same channel, and channel type is NL80211_CHAN_HT40MINUS or
- * NL80211_CHAN_HT40PLUS, or channel offset is PHY_DOUBLE_CHANNEL_HIGH_PRIMARY
- * or PHY_DOUBLE_CHANNEL_LOW_PRIMARY, then check freq segment is same or not.
- *
- * Return: true if freq segment is same
- */
-static bool
-wlan_hdd_is_same_freq_seg(struct cfg80211_chan_def *chandef,
-			  struct ch_params *ch_params)
-{
-	if (!chandef || !ch_params)
-		return false;
-
-	/* they are equal if NL80211_CHAN_NO_HT or NL80211_CHAN_HT20 */
-	if (chandef->center_freq1 == chandef->chan->center_freq)
-		return true;
-
-	if ((ch_params->sec_ch_offset != PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) &&
-	    (ch_params->sec_ch_offset != PHY_DOUBLE_CHANNEL_LOW_PRIMARY))
-		return true;
-
-	if ((chandef->center_freq1 != ch_params->mhz_freq_seg0) ||
-	    (chandef->center_freq2 != ch_params->mhz_freq_seg1))
-		return false;
-
-	return true;
-}
-
 /**
  * wlan_hdd_is_ap_ap_force_scc_override() - force Same band SCC chan override
  * @adapter: SAP adapter pointer
@@ -7407,13 +7374,10 @@ wlan_hdd_is_ap_ap_force_scc_override(struct hdd_adapter *adapter,
 				     struct cfg80211_chan_def *new_chandef)
 {
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-	uint32_t cc_count, i;
-	uint32_t op_freq[MAX_NUMBER_OF_CONC_CONNECTIONS];
-	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
 	struct ch_params ch_params = {0};
 	enum nl80211_channel_type channel_type;
-	uint8_t con_vdev_id;
-	uint32_t con_freq;
+	uint8_t con_vdev_id = WLAN_INVALID_VDEV_ID;
+	uint32_t con_freq = 0;
 	struct ieee80211_channel *ieee_chan;
 	uint32_t freq;
 	QDF_STATUS status;
@@ -7431,7 +7395,8 @@ wlan_hdd_is_ap_ap_force_scc_override(struct hdd_adapter *adapter,
 	}
 	if (policy_mgr_is_ap_ap_mcc_allow(
 			hdd_ctx->psoc, hdd_ctx->pdev, vdev, freq,
-			hdd_map_nl_chan_width(chandef->width))) {
+			hdd_map_nl_chan_width(chandef->width),
+			&con_vdev_id, &con_freq)) {
 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
 		return false;
 	}
@@ -7439,39 +7404,8 @@ wlan_hdd_is_ap_ap_force_scc_override(struct hdd_adapter *adapter,
 
 	if (hdd_handle_p2p_go_for_3rd_ap_conc(hdd_ctx->psoc, adapter, freq))
 		return false;
-
-	cc_count = policy_mgr_get_mode_specific_conn_info(hdd_ctx->psoc,
-							  &op_freq[0],
-							  &vdev_id[0],
-							  PM_SAP_MODE);
-	if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS)
-		cc_count = cc_count +
-				policy_mgr_get_mode_specific_conn_info(
-					hdd_ctx->psoc,
-					&op_freq[cc_count],
-					&vdev_id[cc_count],
-					PM_P2P_GO_MODE);
-	for (i = 0 ; i < cc_count; i++) {
-		if (freq == op_freq[i]) {
-			status = wlan_hdd_get_sap_ch_params(hdd_ctx,
-							    vdev_id[i],
-							    op_freq[i],
-							    &ch_params);
-			if (QDF_IS_STATUS_SUCCESS(status) &&
-			    (!wlan_hdd_is_same_freq_seg(chandef, &ch_params)))
-				break;
-			continue;
-		}
-		if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc))
-			break;
-		if (wlan_reg_is_same_band_freqs(freq, op_freq[i]) &&
-		    !policy_mgr_are_sbs_chan(hdd_ctx->psoc, freq, op_freq[i]))
-			break;
-	}
-	if (i >= cc_count)
+	if (!con_freq)
 		return false;
-	con_freq = op_freq[i];
-	con_vdev_id = vdev_id[i];
 	ieee_chan = ieee80211_get_channel(hdd_ctx->wiphy,
 					  con_freq);
 	if (!ieee_chan) {