Przeglądaj źródła

qcacld-3.0: Check SAP+SAP SCC override with freq_seg0 and freq_seg1

Start one SAP on 5 GHz and one SAP on 2 GHz, and start third SAP with ACS
on 2 GHz band. Then, 3 SAP have different freq_seg0 after disable 5 GHz and
6 GHz band. Raise this change to check AP_AP SCC override with freq_seg0
and freq_seg1.

Change-Id: I720aff19a20e3d5ab9a2a31246e47308f7d09d0e
CRs-Fixed: 3165082
Wu Gao 2 lat temu
rodzic
commit
a076eddc21
1 zmienionych plików z 95 dodań i 21 usunięć
  1. 95 21
      core/hdd/src/wlan_hdd_hostapd.c

+ 95 - 21
core/hdd/src/wlan_hdd_hostapd.c

@@ -6866,9 +6866,77 @@ static void hdd_update_beacon_rate(struct hdd_adapter *adapter,
 #endif
 #endif
 
 
 /**
 /**
- * wlan_hdd_ap_ap_force_scc_override() - force Same band SCC chan override
+ * wlan_hdd_get_sap_ch_params() - Get channel parameters of SAP
+ * @hdd_ctx: HDD context pointer
+ * @vdev_id: vdev id
+ * @freq: channel frequency (MHz)
+ * @ch_params: pointer to channel parameters
+ *
+ * The function gets channel parameters of SAP by vdev id.
+ *
+ * Return: QDF_STATUS_SUCCESS if get channel parameters successful
+ */
+static QDF_STATUS
+wlan_hdd_get_sap_ch_params(struct hdd_context *hdd_ctx,
+			   uint8_t vdev_id, uint32_t freq,
+			   struct ch_params *ch_params)
+{
+	struct hdd_adapter *adapter;
+
+	if (!hdd_ctx || !ch_params) {
+		hdd_err("invalid hdd_ctx or ch_params");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
+	if (!adapter)
+		return QDF_STATUS_E_INVAL;
+
+	if (!wlan_sap_get_ch_params(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+				    ch_params))
+		wlan_reg_set_channel_params_for_freq(hdd_ctx->pdev,
+						     freq, 0,
+						     ch_params);
+	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
  * @adapter: SAP adapter pointer
- * @freq: SAP starting channel freq
+ * @chandef: SAP starting channel
  * @new_chandef: new override SAP channel
  * @new_chandef: new override SAP channel
  *
  *
  * The function will override the second SAP chan to the first SAP's home
  * The function will override the second SAP chan to the first SAP's home
@@ -6877,9 +6945,9 @@ static void hdd_update_beacon_rate(struct hdd_adapter *adapter,
  * Return: true if channel override
  * Return: true if channel override
  */
  */
 static bool
 static bool
-wlan_hdd_ap_ap_force_scc_override(struct hdd_adapter *adapter,
-				  uint32_t freq,
-				  struct cfg80211_chan_def *new_chandef)
+wlan_hdd_is_ap_ap_force_scc_override(struct hdd_adapter *adapter,
+				     struct cfg80211_chan_def *chandef,
+				     struct cfg80211_chan_def *new_chandef)
 {
 {
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	uint32_t cc_count, i;
 	uint32_t cc_count, i;
@@ -6887,17 +6955,18 @@ wlan_hdd_ap_ap_force_scc_override(struct hdd_adapter *adapter,
 	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
 	uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS];
 	struct ch_params ch_params;
 	struct ch_params ch_params;
 	enum nl80211_channel_type channel_type;
 	enum nl80211_channel_type channel_type;
-	struct hdd_adapter *con_adapter;
 	uint8_t con_vdev_id;
 	uint8_t con_vdev_id;
 	uint32_t con_freq;
 	uint32_t con_freq;
 	uint8_t mcc_to_scc_switch;
 	uint8_t mcc_to_scc_switch;
 	struct ieee80211_channel *ieee_chan;
 	struct ieee80211_channel *ieee_chan;
+	uint32_t freq;
+	QDF_STATUS status;
 
 
-	if (!hdd_ctx) {
-		hdd_err("hdd context is NULL");
+	if (!hdd_ctx || !chandef) {
+		hdd_err("hdd context or chandef is NULL");
 		return false;
 		return false;
 	}
 	}
-
+	freq = chandef->chan->center_freq;
 	if (adapter->device_mode == QDF_P2P_GO_MODE &&
 	if (adapter->device_mode == QDF_P2P_GO_MODE &&
 	    policy_mgr_is_p2p_p2p_conc_supported(hdd_ctx->psoc))
 	    policy_mgr_is_p2p_p2p_conc_supported(hdd_ctx->psoc))
 		return false;
 		return false;
@@ -6925,8 +6994,16 @@ wlan_hdd_ap_ap_force_scc_override(struct hdd_adapter *adapter,
 					&vdev_id[cc_count],
 					&vdev_id[cc_count],
 					PM_P2P_GO_MODE);
 					PM_P2P_GO_MODE);
 	for (i = 0 ; i < cc_count; i++) {
 	for (i = 0 ; i < cc_count; i++) {
-		if (freq == op_freq[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;
 			continue;
+		}
 		if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc))
 		if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc))
 			break;
 			break;
 		if (wlan_reg_is_same_band_freqs(freq, op_freq[i]) &&
 		if (wlan_reg_is_same_band_freqs(freq, op_freq[i]) &&
@@ -6937,9 +7014,6 @@ wlan_hdd_ap_ap_force_scc_override(struct hdd_adapter *adapter,
 		return false;
 		return false;
 	con_freq = op_freq[i];
 	con_freq = op_freq[i];
 	con_vdev_id = vdev_id[i];
 	con_vdev_id = vdev_id[i];
-	con_adapter = hdd_get_adapter_by_vdev(hdd_ctx, con_vdev_id);
-	if (!con_adapter)
-		return false;
 	ieee_chan = ieee80211_get_channel(hdd_ctx->wiphy,
 	ieee_chan = ieee80211_get_channel(hdd_ctx->wiphy,
 					  con_freq);
 					  con_freq);
 	if (!ieee_chan) {
 	if (!ieee_chan) {
@@ -6947,11 +7021,11 @@ wlan_hdd_ap_ap_force_scc_override(struct hdd_adapter *adapter,
 		return false;
 		return false;
 	}
 	}
 
 
-	if (!wlan_sap_get_ch_params(WLAN_HDD_GET_SAP_CTX_PTR(con_adapter),
-				    &ch_params))
-		wlan_reg_set_channel_params_for_freq(hdd_ctx->pdev,
-						     con_freq, 0,
-						     &ch_params);
+	status = wlan_hdd_get_sap_ch_params(hdd_ctx, con_vdev_id, con_freq,
+					    &ch_params);
+	if (QDF_IS_STATUS_ERROR(status))
+		return false;
+
 	switch (ch_params.sec_ch_offset) {
 	switch (ch_params.sec_ch_offset) {
 	case PHY_SINGLE_CHANNEL_CENTERED:
 	case PHY_SINGLE_CHANNEL_CENTERED:
 		channel_type = NL80211_CHAN_HT20;
 		channel_type = NL80211_CHAN_HT20;
@@ -7132,9 +7206,9 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
 	chandef = &params->chandef;
 	chandef = &params->chandef;
 	if ((adapter->device_mode == QDF_SAP_MODE ||
 	if ((adapter->device_mode == QDF_SAP_MODE ||
 	     adapter->device_mode == QDF_P2P_GO_MODE) &&
 	     adapter->device_mode == QDF_P2P_GO_MODE) &&
-	    wlan_hdd_ap_ap_force_scc_override(adapter,
-					      chandef->chan->center_freq,
-					      &new_chandef)) {
+	    wlan_hdd_is_ap_ap_force_scc_override(adapter,
+						 chandef,
+						 &new_chandef)) {
 		chandef = &new_chandef;
 		chandef = &new_chandef;
 		freq = (qdf_freq_t)chandef->chan->center_freq;
 		freq = (qdf_freq_t)chandef->chan->center_freq;
 		channel_width = wlan_hdd_get_channel_bw(chandef->width);
 		channel_width = wlan_hdd_get_channel_bw(chandef->width);