Quellcode durchsuchen

qcacld-3.0: Allow pre-cac on 5 GHz with 160 MHz bandwidth

If pre-cac channel from userspace is Non DFS channel but
the pre-cac bandwidth is set to 160 MHz which cover DFS channel
range, we still allow the request instead of reject it.

Change-Id: I9a0778855bf6659fab20ae0cc82a17d652b0d282
CRs-Fixed: 3748905
Liangwei Dong vor 1 Jahr
Ursprung
Commit
e0e1d4b396

+ 42 - 8
components/pre_cac/core/src/wlan_pre_cac_main.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -284,7 +284,8 @@ void pre_cac_get_vdev_id(struct wlan_objmgr_psoc *psoc,
 
 int pre_cac_validate_and_get_freq(struct wlan_objmgr_pdev *pdev,
 				  uint32_t chan_freq,
-				  uint32_t *pre_cac_chan_freq)
+				  uint32_t *pre_cac_chan_freq,
+				  enum phy_ch_width cac_ch_width)
 {
 	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
 	uint32_t len = CFG_VALID_CHANNEL_LIST_LEN;
@@ -293,6 +294,8 @@ int pre_cac_validate_and_get_freq(struct wlan_objmgr_pdev *pdev,
 	uint32_t weight_len = 0;
 	QDF_STATUS status;
 	uint32_t i;
+	bool is_ch_dfs = false;
+	struct ch_params ch_params;
 
 	pre_cac_stop(psoc);
 
@@ -320,33 +323,64 @@ int pre_cac_validate_and_get_freq(struct wlan_objmgr_pdev *pdev,
 							 freq_list, &len,
 							 pcl_weights,
 							 weight_len);
+try_next_bw:
 		for (i = 0; i < len; i++) {
-			if (wlan_reg_is_dfs_for_freq(pdev,
-						     freq_list[i])) {
+			is_ch_dfs = false;
+			qdf_mem_zero(&ch_params, sizeof(ch_params));
+			ch_params.ch_width = cac_ch_width;
+			wlan_reg_set_create_punc_bitmap(&ch_params, true);
+			if (wlan_reg_is_5ghz_ch_freq(freq_list[i]) &&
+			    wlan_reg_get_5g_bonded_channel_state_for_pwrmode(
+					pdev, freq_list[i], &ch_params,
+				REG_CURRENT_PWR_MODE) == CHANNEL_STATE_DFS)
+				is_ch_dfs = true;
+
+			if (is_ch_dfs) {
 				*pre_cac_chan_freq = freq_list[i];
 				break;
 			}
 		}
 
+		if (*pre_cac_chan_freq == 0 &&
+		    cac_ch_width != CH_WIDTH_20MHZ &&
+		    wlan_get_next_lower_bandwidth(cac_ch_width)
+						!= CH_WIDTH_INVALID) {
+			cac_ch_width =
+				wlan_get_next_lower_bandwidth(cac_ch_width);
+			pre_cac_debug("try next bw %d", cac_ch_width);
+			goto try_next_bw;
+		}
+
 		if (*pre_cac_chan_freq == 0) {
 			pre_cac_err("unable to find outdoor channel");
 			return -EINVAL;
 		}
 	} else {
+		qdf_mem_zero(&ch_params, sizeof(ch_params));
+		ch_params.ch_width = cac_ch_width;
+		wlan_reg_set_create_punc_bitmap(&ch_params, true);
+		if (wlan_reg_is_5ghz_ch_freq(chan_freq) &&
+		    wlan_reg_get_5g_bonded_channel_state_for_pwrmode(
+				pdev, chan_freq, &ch_params,
+				REG_CURRENT_PWR_MODE) == CHANNEL_STATE_DFS)
+			is_ch_dfs = true;
+
 		/* Only when driver selects a channel, check is done for
 		 * unnsafe and NOL channels. When user provides a fixed channel
 		 * the user is expected to take care of this.
 		 */
 		if (!wlan_mlme_is_channel_valid(psoc, chan_freq) ||
-		    !wlan_reg_is_dfs_for_freq(pdev, chan_freq)) {
-			pre_cac_err("Invalid channel for pre cac:%d",
-				    chan_freq);
+		    !is_ch_dfs) {
+			pre_cac_err("Invalid channel for pre cac:%d dfs %d",
+				    chan_freq, is_ch_dfs);
 			return -EINVAL;
 		}
 		*pre_cac_chan_freq = chan_freq;
 	}
 
-	pre_cac_debug("selected pre cac channel:%d", *pre_cac_chan_freq);
+	pre_cac_debug("selected pre cac channel:%d bw %d", *pre_cac_chan_freq,
+		      cac_ch_width);
+
 	return 0;
 }
 

+ 4 - 2
components/pre_cac/core/src/wlan_pre_cac_main.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -233,6 +233,7 @@ void pre_cac_clear_work(struct wlan_objmgr_psoc *psoc);
  * @pdev: pdev object manager
  * @chan_freq: Channel frequency requested by userspace
  * @pre_cac_chan_freq: Pointer to the pre CAC channel frequency storage
+ * @cac_ch_width: bandwidth of channel frequency pre_cac_chan_freq
  *
  * Validates the channel provided by userspace. If user provided channel 0,
  * a valid outdoor channel must be selected from the regulatory channel.
@@ -241,7 +242,8 @@ void pre_cac_clear_work(struct wlan_objmgr_psoc *psoc);
  */
 int pre_cac_validate_and_get_freq(struct wlan_objmgr_pdev *pdev,
 				  uint32_t chan_freq,
-				  uint32_t *pre_cac_chan_freq);
+				  uint32_t *pre_cac_chan_freq,
+				  enum phy_ch_width cac_ch_width);
 
 /**
  * pre_cac_set_status() - Set pre cac status

+ 6 - 3
components/pre_cac/dispatcher/inc/wlan_pre_cac_ucfg_api.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -77,6 +77,7 @@ bool ucfg_pre_cac_is_active(struct wlan_objmgr_psoc *psoc);
  * @pdev: pdev object manager
  * @chan_freq: Channel frequency requested by userspace
  * @pre_cac_chan_freq: Pointer to the pre CAC channel frequency storage
+ * @cac_ch_width: bandwidth of channel frequency pre_cac_chan_freq
  *
  * Validates the channel provided by userspace. If user provided channel 0,
  * a valid outdoor channel must be selected from the regulatory channel.
@@ -85,7 +86,8 @@ bool ucfg_pre_cac_is_active(struct wlan_objmgr_psoc *psoc);
  */
 int ucfg_pre_cac_validate_and_get_freq(struct wlan_objmgr_pdev *pdev,
 				       uint32_t chan_freq,
-				       uint32_t *pre_cac_chan_freq);
+				       uint32_t *pre_cac_chan_freq,
+				       enum phy_ch_width cac_ch_width);
 
 #if defined(FEATURE_SAP_COND_CHAN_SWITCH)
 /**
@@ -226,7 +228,8 @@ ucfg_pre_cac_is_active(struct wlan_objmgr_psoc *psoc)
 static inline int
 ucfg_pre_cac_validate_and_get_freq(struct wlan_objmgr_pdev *pdev,
 				   uint32_t chan_freq,
-				   uint32_t *pre_cac_chan_freq)
+				   uint32_t *pre_cac_chan_freq,
+				   enum phy_ch_width cac_ch_width)
 {
 	return 0;
 }

+ 5 - 3
components/pre_cac/dispatcher/src/wlan_pre_cac_ucfg_api.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022, 2024, Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -73,10 +73,12 @@ void ucfg_pre_cac_get_vdev_id(struct wlan_objmgr_psoc *psoc,
 
 int ucfg_pre_cac_validate_and_get_freq(struct wlan_objmgr_pdev *pdev,
 				       uint32_t chan_freq,
-				       uint32_t *pre_cac_chan_freq)
+				       uint32_t *pre_cac_chan_freq,
+				       enum phy_ch_width cac_ch_width)
 {
 	return pre_cac_validate_and_get_freq(pdev, chan_freq,
-					     pre_cac_chan_freq);
+					     pre_cac_chan_freq,
+					     cac_ch_width);
 }
 
 #if defined(FEATURE_SAP_COND_CHAN_SWITCH)

+ 15 - 3
core/hdd/src/wlan_hdd_pre_cac.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -267,10 +267,22 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx,
 		return -EINVAL;
 	}
 
-	hdd_debug("channel: %d", chan_freq);
+	cac_ch_width = wlansap_get_max_bw_by_phymode(hdd_ap_ctx->sap_context);
+	if (cac_ch_width > DEFAULT_PRE_CAC_BANDWIDTH)
+		cac_ch_width = DEFAULT_PRE_CAC_BANDWIDTH;
+	if (chan_freq) {
+		qdf_mem_zero(&chandef, sizeof(struct cfg80211_chan_def));
+		if (wlan_set_def_pre_cac_chan(hdd_ctx, chan_freq, &chandef,
+					      &channel_type, &cac_ch_width)) {
+			hdd_err("failed to set pre_cac channel %d", chan_freq);
+			return -EINVAL;
+		}
+	}
+	hdd_debug("channel: %d bw: %d", chan_freq, cac_ch_width);
 
 	ret = ucfg_pre_cac_validate_and_get_freq(hdd_ctx->pdev, chan_freq,
-						 &pre_cac_chan_freq);
+						 &pre_cac_chan_freq,
+						 cac_ch_width);
 	if (ret != 0) {
 		hdd_err("can't validate pre-cac channel");
 		goto release_intf_addr_and_return_failure;

+ 1 - 0
core/sap/src/sap_module.c

@@ -1327,6 +1327,7 @@ wlansap_5g_original_bw_validate(
 	enum phy_ch_width ch_width)
 {
 	if (sap_context->csa_reason != CSA_REASON_USER_INITIATED &&
+	    sap_context->csa_reason != CSA_REASON_PRE_CAC_SUCCESS &&
 	    WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq) &&
 	    ch_width >= CH_WIDTH_160MHZ &&
 	    sap_context->ch_width_orig < CH_WIDTH_160MHZ)