Quellcode durchsuchen

qcacmn: Prevent random channel selection to choose UNII1 channels

Spur or leakage transmissions is observed in Spruce HW in
frequencies from 5260MHz to 5320MHz when one of the following
conditions is true,
i) The AP is transmitting in 52/56/60/64 in 80MHz mode and then the  AP
moves to the adjacent channel 36/44/48 in 80MHz mode and starts
transmitting.
ii) The AP is transmitting in 36/44/48/52/56/60/64 in 160MHz mode and then
the  AP moves to the adjacent channel 36/44/48 in 80MHz mode and starts
transmitting.
In order to prevent random channel selection to cause spur restrict the
above given channel movements for Spruce target alone.

Change-Id: I27b558ec5544076430f66c84b056ab65f9e43c8c
CRs-Fixed: 2975473
Vignesh U vor 4 Jahren
Ursprung
Commit
171c65dccd

+ 23 - 0
umac/dfs/core/src/dfs_random_chan_sel.h

@@ -126,6 +126,29 @@
 #define DFS_IS_CHAN_JAPAN_INDOOR_FREQ(_ch)(((_ch) >= 5180)  && ((_ch) <= 5320))
 #define DFS_IS_CHAN_JAPAN_OUTDOOR_FREQ(_ch)(((_ch) >= 5500) && ((_ch) <= 5720))
 #define DFS_IS_CHAN_JAPAN_W53_FREQ(_ch)    (((_ch) >= 5260)  && ((_ch) <= 5320))
+/*
+ * Spur or leakage transmissions is observed in Spruce HW in
+ * frequencies from 5260MHz to 5320MHz when one of the following
+ * conditions is true,
+ * i) The AP is transmitting in 52/56/60/64 in 80MHz mode and then the  AP
+ * moves to the adjacent channel 36/44/48 in 80MHz mode and starts
+ * transmitting.
+ * ii) The AP is transmitting in 36/44/48/52/56/60/64 in 160MHz mode and then
+ * the  AP moves to the adjacent channel 36/44/48 in 80MHz mode and starts
+ * transmitting.
+ * Hence, center frequencies from 5260MHz to 5320MHz in Spruce HW are called
+ * Spruce Spur 80MHz Frequencies and, center frequencies from 5180MHz and
+ * 5320MHz except 5200MHz are called Spruce Spur 160MHz Frequencies.
+ */
+/* Channels 52/56/60/64 in 80MHz */
+#define DFS_IS_CHAN_SPRUCE_SPUR_FREQ_80MHZ(_ch) \
+		(((_ch) >= 5260) && ((_ch) <= 5320))
+/* 36/44/48/52/56/60/64 in 160MHz mode */
+#define DFS_IS_CHAN_SPRUCE_SPUR_FREQ_160MHZ(_ch) \
+		(((_ch) >= 5180) && ((_ch) <= 5320) && ((_ch) != 5200))
+/* Avoid channels 36/44/48 */
+#define DFS_IS_SPRUCE_SPUR_AVOID_FREQS(_ch) \
+		(((_ch) >= 5180) && ((_ch) <= 5240) && ((_ch) != 5200))
 #endif
 
 /**

+ 26 - 0
umac/dfs/core/src/misc/dfs_random_chan_sel.c

@@ -1457,6 +1457,7 @@ uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs,
 	uint16_t *leakage_adjusted_lst;
 	uint16_t final_lst[NUM_CHANNELS] = {0};
 	uint8_t *chan_wd = (uint8_t *)&chan_params->ch_width;
+	bool flag_no_spur_leakage_adj_chans = false;
 
 	if (!chan_list || !chan_cnt) {
 		dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
@@ -1481,6 +1482,8 @@ uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs,
 				 dfs_region, acs_info);
 	flag_no_weather = (dfs_region == DFS_ETSI_REGION) ?
 		flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0;
+	flag_no_spur_leakage_adj_chans =
+	    flags & DFS_RANDOM_CH_FLAG_NO_SPRUCE_SPUR_ADJ_CH;
 
 	/* list adjusted after leakage has been marked */
 	leakage_adjusted_lst = qdf_mem_malloc(random_chan_cnt *
@@ -1566,6 +1569,29 @@ uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs,
 			continue;
 		}
 
+		/*
+		 * Spur or leakage transmissions is observed in Spruce HW in
+		 * frequencies from 5260MHz to 5320MHz when one of the following
+		 * conditions is true,
+		 * i) The AP is transmitting in 52/56/60/64 in 80MHz mode and
+		 * then the AP moves to the adjacent channel 36/44/48 in 80MHz
+		 * mode and starts transmitting.
+		 * ii) The AP is transmitting in 36/44/48/52/56/60/64 in 160MHz
+		 * mode and then the  AP moves to the adjacent channel 36/44/48
+		 * in 80MHz mode and starts transmitting.
+		 *
+		 * The random channel selection algorithm prevents the channel
+		 * movement mentioned above, thereby eliminating the leakage.
+		 */
+		if (flag_no_spur_leakage_adj_chans &&
+		    DFS_IS_SPRUCE_SPUR_AVOID_FREQS(target_freq) &&
+		    *chan_wd == DFS_CH_WIDTH_80MHZ) {
+			dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
+				  "skip spruce spur causing (adjacent) channel=%hu",
+				  target_freq);
+			continue;
+		}
+
 		if (target_freq)
 			break;
 	} while (true);

+ 4 - 1
umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2016-2021 The Linux Foundation. All rights reserved.
  * Copyright (c) 2010, Atheros Communications Inc.
  * All Rights Reserved.
  *
@@ -214,6 +214,9 @@ struct dfs_bangradar_params {
 /* Flag to exclude all 6GHz channels */
 #define DFS_RANDOM_CH_FLAG_NO_6GHZ_CH          0x00400 /* 0000 0100 0000 0000 */
 
+/* Flag to exclude spruce spur adjacent channels */
+#define DFS_RANDOM_CH_FLAG_NO_SPRUCE_SPUR_ADJ_CH \
+		0x0800 /* 0000 1000 0000 0000 */
 /**
  * struct wlan_dfs_caps - DFS capability structure.
  * @wlan_dfs_ext_chan_ok:         Can radar be detected on the extension chan?

+ 28 - 0
umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h

@@ -225,6 +225,34 @@ QDF_STATUS utils_dfs_stacac_stop(struct wlan_objmgr_pdev *pdev);
  */
 QDF_STATUS utils_dfs_get_usenol(struct wlan_objmgr_pdev *pdev,
 		uint16_t *usenol);
+/*
+ * utils_dfs_radar_disable() - Disables the radar.
+ * @pdev: Pointer to DFS pdev object.
+ *
+ * Return: true if Spruce spur WAR is applicable else false.
+ *
+ * Spur or leakage transmissions is observed in Spruce HW in
+ * frequencies from 5260MHz to 5320MHz when one of the following
+ * conditions is true,
+ * i) The AP is transmitting in 52/56/60/64 in 80MHz mode and then the  AP
+ * moves to the adjacent channel 36/44/48 in 80MHz mode and starts
+ * transmitting.
+ * ii) The AP is transmitting in 36/44/48/52/56/60/64 in 160MHz mode and then
+ * the  AP moves to the adjacent channel 36/44/48 in 80MHz mode and starts
+ * transmitting.
+ *
+ * Hence, the spruce spur WAR becomes applicable when,
+ * a) the target is Spruce,
+ * b) the primary channel is 52/56/60/64, and the home channel width is 80MHz.
+ * c) or, the primary channel is 36/44/48/52/56/60/64 and the home channel width
+ *    is 160MHz.
+ *
+ * When the conditions (a) and (b) or (c) is true, random channel selection
+ * should make sure to prevent moving to the adjacent channels 36/44/48 in
+ * 80MHz mode. Failing to do so will cause spur transmissions in channel 52
+ * through 64.
+ */
+bool utils_dfs_is_spruce_spur_war_applicable(struct wlan_objmgr_pdev *pdev);
 
 /**
  * utils_dfs_radar_disable() - Disables the radar.

+ 56 - 0
umac/dfs/dispatcher/src/wlan_dfs_utils_api.c

@@ -319,6 +319,62 @@ QDF_STATUS utils_dfs_get_usenol(struct wlan_objmgr_pdev *pdev, uint16_t *usenol)
 }
 qdf_export_symbol(utils_dfs_get_usenol);
 
+bool utils_dfs_is_spruce_spur_war_applicable(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_dfs *dfs;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_lmac_if_tx_ops *tx_ops;
+	uint32_t target_type;
+	struct wlan_lmac_if_target_tx_ops *tgt_tx_ops;
+	qdf_freq_t cur_freq;
+
+	dfs = wlan_pdev_get_dfs_obj(pdev);
+	if (!dfs)
+		return false;
+
+	psoc = dfs->dfs_soc_obj->psoc;
+
+	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
+	if (!tx_ops) {
+		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "tx_ops is NULL");
+		return false;
+	}
+
+	tgt_tx_ops = &tx_ops->target_tx_ops;
+	target_type = lmac_get_target_type(dfs->dfs_pdev_obj);
+
+	/* Is the target Spruce? */
+	if (!tgt_tx_ops->tgt_is_tgt_type_qcn6122)
+		return false;
+
+	if (!tgt_tx_ops->tgt_is_tgt_type_qcn6122(target_type))
+		return false;
+
+	cur_freq = dfs->dfs_curchan->dfs_ch_freq;
+
+	/* Is the current channel width 80MHz? */
+	if (WLAN_IS_CHAN_MODE_80(dfs->dfs_curchan)) {
+		/* is the primary channel 52/56/60/64? */
+		bool is_chan_spur_80mhzfreq =
+		    DFS_IS_CHAN_SPRUCE_SPUR_FREQ_80MHZ(cur_freq);
+		if (is_chan_spur_80mhzfreq)
+			return true;
+		return false;
+	}
+
+	/* If the current channel width is not 80, is it 160MHz? */
+	if (WLAN_IS_CHAN_MODE_160(dfs->dfs_curchan)) {
+		/* is the primary channel 36/44/48/52/56/60/64? */
+		bool is_chan_spur_160mhz_freq =
+		    DFS_IS_CHAN_SPRUCE_SPUR_FREQ_160MHZ(cur_freq);
+		if (is_chan_spur_160mhz_freq)
+			return true;
+		return false;
+	}
+
+	return false;
+}
+
 QDF_STATUS utils_dfs_radar_disable(struct wlan_objmgr_pdev *pdev)
 {
 	struct wlan_dfs *dfs;