瀏覽代碼

qcacmn: Add DFS coverage for overlapping ETSI channels

Add DFS coverage for channel plus width combinations
for overlapping channels in ETSI domain.

Change-Id: Id55f6b42a7ae3bad45c334ff5163a9458b825cd6
CRs-Fixed: 2291635
Shaakir Mohamed 6 年之前
父節點
當前提交
fa4d383541

+ 61 - 4
umac/dfs/core/src/dfs.h

@@ -310,10 +310,6 @@
 #define NUM_BINS 128
 #define THOUSAND 1000
 
-/* Check if the dfs current channel is 5.8GHz */
-#define DFS_CURCHAN_IS_58GHz(freq) \
-	((((freq) >= 5745) && ((freq) <= 5865)) ? true : false)
-
 /* ETSI11_WORLD regdmn pair id */
 #define ETSI11_WORLD_REGDMN_PAIR_ID 0x26
 #define ETSI12_WORLD_REGDMN_PAIR_ID 0x28
@@ -323,6 +319,9 @@
 /* Array offset to ETSI legacy pulse */
 #define ETSI_LEGACY_PULSE_ARR_OFFSET 2
 
+#define ETSI_RADAR_EN302_502_FREQ_LOWER 5725
+#define ETSI_RADAR_EN302_502_FREQ_UPPER 5865
+
 #define DFS_NOL_ADD_CHAN_LOCKED(dfs, freq, timeout)         \
 	do {                                                \
 		WLAN_DFSNOL_LOCK(dfs);                      \
@@ -2129,6 +2128,64 @@ static inline int dfs_set_thresholds(struct wlan_dfs *dfs,
 }
 #endif
 
+/**
+ * dfs_check_intersect_excl() - Check whether curfreq falls within lower_freq
+ * and upper_freq, exclusively.
+ * @low_freq : lower bound frequency value.
+ * @high_freq: upper bound frequency value.
+ * @chan_freq: Current frequency value to be checked.
+ *
+ * Return: returns true if overlap found, else returns false.
+ */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
+bool dfs_check_intersect_excl(int low_freq, int high_freq, int chan_freq);
+#else
+static inline bool dfs_check_intersect_excl(int low_freq, int high_freq,
+					    int chan_freq)
+{
+		return false;
+}
+#endif
+
+/**
+ * dfs_check_etsi_overlap() - Check whether given frequency centre/channel
+ * width entry overlap with frequency spread in any way.
+ * @center_freq         : current channel centre frequency.
+ * @chan_width          : current channel width.
+ * @en302_502_freq_low  : overlap frequency lower bound.
+ * @en302_502_freq_high : overlap frequency upper bound.
+ *
+ * Return: returns 1 if overlap found, else returns 0.
+ */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
+int dfs_check_etsi_overlap(int center_freq, int chan_width,
+			   int en302_502_freq_low, int en302_502_freq_high);
+#else
+static inline int dfs_check_etsi_overlap(int center_freq, int chan_width,
+					 int en302_502_freq_low,
+					 int en302_502_freq_high)
+{
+		return 0;
+}
+#endif
+
+/**
+ * dfs_is_en302_502_applicable() - Check whether current channel frequecy spread
+ *					overlaps with EN 302 502 radar type
+ *					frequency range.
+ *@dfs: Pointer to wlan_dfs structure.
+ *
+ * Return: returns true if overlap found, else returns false.
+ */
+#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD)
+bool dfs_is_en302_502_applicable(struct wlan_dfs *dfs);
+#else
+static inline bool dfs_is_en302_502_applicable(struct wlan_dfs *dfs)
+{
+		return false;
+}
+#endif
+
 /**
  * dfs_set_current_channel() - Set DFS current channel.
  * @dfs: Pointer to wlan_dfs structure.

+ 1 - 10
umac/dfs/core/src/filtering/ar5212_radar.c

@@ -171,8 +171,6 @@ void dfs_get_radars_for_ar5212(struct wlan_dfs *dfs)
 {
 	struct wlan_dfs_radar_tab_info rinfo;
 	int dfsdomain = DFS_FCC_DOMAIN;
-	uint16_t ch_freq;
-	uint16_t regdmn;
 
 	qdf_mem_zero(&rinfo, sizeof(rinfo));
 	dfsdomain = utils_get_dfsdomain(dfs->dfs_pdev_obj);
@@ -190,14 +188,7 @@ void dfs_get_radars_for_ar5212(struct wlan_dfs *dfs)
 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "DFS_ETSI_DOMAIN_5412");
 		rinfo.dfsdomain = DFS_ETSI_DOMAIN;
 
-		ch_freq = dfs->dfs_curchan->dfs_ch_freq;
-		regdmn = utils_dfs_get_cur_rd(dfs->dfs_pdev_obj);
-
-		if (((regdmn == ETSI11_WORLD_REGDMN_PAIR_ID) ||
-		    (regdmn == ETSI12_WORLD_REGDMN_PAIR_ID) ||
-		    (regdmn == ETSI13_WORLD_REGDMN_PAIR_ID) ||
-		    (regdmn == ETSI14_WORLD_REGDMN_PAIR_ID)) &&
-		    DFS_CURCHAN_IS_58GHz(ch_freq)) {
+		if (dfs_is_en302_502_applicable(dfs)) {
 			rinfo.dfs_radars = ar5212_etsi_radars;
 			rinfo.numradars = QDF_ARRAY_SIZE(ar5212_etsi_radars);
 		} else {

+ 1 - 10
umac/dfs/core/src/filtering/ar5416_radar.c

@@ -115,8 +115,6 @@ void dfs_get_radars_for_ar5416(struct wlan_dfs *dfs)
 {
 	struct wlan_dfs_radar_tab_info rinfo;
 	int dfsdomain = DFS_FCC_DOMAIN;
-	uint16_t ch_freq;
-	uint16_t regdmn;
 
 	qdf_mem_zero(&rinfo, sizeof(rinfo));
 	dfsdomain = utils_get_dfsdomain(dfs->dfs_pdev_obj);
@@ -134,14 +132,7 @@ void dfs_get_radars_for_ar5416(struct wlan_dfs *dfs)
 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "DFS_ETSI_DOMAIN_5416");
 		rinfo.dfsdomain = DFS_ETSI_DOMAIN;
 
-		ch_freq = dfs->dfs_curchan->dfs_ch_freq;
-		regdmn = utils_dfs_get_cur_rd(dfs->dfs_pdev_obj);
-
-		if (((regdmn == ETSI11_WORLD_REGDMN_PAIR_ID) ||
-		    (regdmn == ETSI12_WORLD_REGDMN_PAIR_ID) ||
-		    (regdmn == ETSI13_WORLD_REGDMN_PAIR_ID) ||
-		    (regdmn == ETSI14_WORLD_REGDMN_PAIR_ID)) &&
-		    DFS_CURCHAN_IS_58GHz(ch_freq)) {
+		if (dfs_is_en302_502_applicable(dfs)) {
 			rinfo.dfs_radars = ar5416_etsi_radars;
 			rinfo.numradars = QDF_ARRAY_SIZE(ar5416_etsi_radars);
 		} else {

+ 1 - 10
umac/dfs/core/src/filtering/ar9300_radar.c

@@ -170,8 +170,6 @@ void dfs_get_radars_for_ar9300(struct wlan_dfs *dfs)
 {
 	struct wlan_dfs_radar_tab_info rinfo;
 	int dfsdomain = DFS_FCC_DOMAIN;
-	uint16_t ch_freq;
-	uint16_t regdmn;
 
 	qdf_mem_zero(&rinfo, sizeof(rinfo));
 	dfsdomain = utils_get_dfsdomain(dfs->dfs_pdev_obj);
@@ -192,14 +190,7 @@ void dfs_get_radars_for_ar9300(struct wlan_dfs *dfs)
 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "DFS_ETSI_DOMAIN_9300");
 		rinfo.dfsdomain = DFS_ETSI_DOMAIN;
 
-		ch_freq = dfs->dfs_curchan->dfs_ch_freq;
-		regdmn = utils_dfs_get_cur_rd(dfs->dfs_pdev_obj);
-
-		if (((regdmn == ETSI11_WORLD_REGDMN_PAIR_ID) ||
-		    (regdmn == ETSI12_WORLD_REGDMN_PAIR_ID) ||
-		    (regdmn == ETSI13_WORLD_REGDMN_PAIR_ID) ||
-		    (regdmn == ETSI14_WORLD_REGDMN_PAIR_ID)) &&
-		    DFS_CURCHAN_IS_58GHz(ch_freq)) {
+		if (dfs_is_en302_502_applicable(dfs)) {
 			rinfo.dfs_radars = ar9300_etsi_radars;
 			rinfo.numradars = QDF_ARRAY_SIZE(ar9300_etsi_radars);
 		} else {

+ 82 - 0
umac/dfs/core/src/filtering/dfs_init.c

@@ -22,6 +22,9 @@
 
 #include "../dfs.h"
 #include "wlan_dfs_lmac_api.h"
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_reg_services_api.h>
+#include "wlan_dfs_utils_api.h"
 
 /**
  * dfs_reset_filtertype() - Reset filtertype.
@@ -406,3 +409,82 @@ void dfs_clear_stats(struct wlan_dfs *dfs)
 	dfs->wlan_dfs_stats.last_reset_tstamp =
 	    lmac_get_tsf64(dfs->dfs_pdev_obj);
 }
+
+bool dfs_check_intersect_excl(int low_freq, int high_freq, int center_freq)
+{
+	return ((center_freq > low_freq) && (center_freq < high_freq));
+}
+
+int dfs_check_etsi_overlap(int center_freq, int chan_width,
+			   int en302_502_freq_low, int en302_502_freq_high)
+{
+	int chan_freq_low;
+	int chan_freq_high;
+
+	/* Calculate low/high frequency ranges */
+	chan_freq_low = center_freq - (chan_width / 2);
+	chan_freq_high = center_freq + (chan_width / 2);
+
+	return ((chan_freq_high == en302_502_freq_low) ||
+		dfs_check_intersect_excl(en302_502_freq_low,
+					 en302_502_freq_high,
+					 chan_freq_low) ||
+		dfs_check_intersect_excl(en302_502_freq_low,
+					 en302_502_freq_high,
+					 chan_freq_high));
+}
+
+bool dfs_is_en302_502_applicable(struct wlan_dfs *dfs)
+{
+	int chan_freq;
+	int chan_width;
+	int overlap = 0;
+	uint16_t regdmn;
+	struct wlan_objmgr_vdev *vdev = NULL;
+	struct wlan_channel *bss_chan = NULL;
+
+	/* Get centre frequency */
+	chan_freq = dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg1;
+	vdev = wlan_objmgr_pdev_get_first_vdev(dfs->dfs_pdev_obj, WLAN_DFS_ID);
+	if (!vdev) {
+		dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,  "vdev is NULL");
+		return false;
+	}
+
+	bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID);
+	/* Grab width */
+	chan_width = wlan_reg_get_bw_value(bss_chan->ch_width);
+
+	if (WLAN_IS_CHAN_11AC_VHT80_80(dfs->dfs_curchan)) {
+		/* HT80_80 mode has 2 segments and each segment must
+		 * be checked for control channel first.
+		 */
+		overlap = dfs_check_etsi_overlap(
+				chan_freq, chan_width / 2,
+				ETSI_RADAR_EN302_502_FREQ_LOWER,
+				ETSI_RADAR_EN302_502_FREQ_UPPER);
+
+		/* check for extension channel */
+		chan_freq = utils_dfs_chan_to_freq(
+				dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2);
+
+		overlap += dfs_check_etsi_overlap(
+				chan_freq, chan_width / 2,
+				ETSI_RADAR_EN302_502_FREQ_LOWER,
+				ETSI_RADAR_EN302_502_FREQ_UPPER);
+	} else {
+		overlap = dfs_check_etsi_overlap(
+				chan_freq, chan_width,
+				ETSI_RADAR_EN302_502_FREQ_LOWER,
+				ETSI_RADAR_EN302_502_FREQ_UPPER);
+	}
+
+	regdmn = utils_dfs_get_cur_rd(dfs->dfs_pdev_obj);
+
+	return(((regdmn == ETSI11_WORLD_REGDMN_PAIR_ID) ||
+		(regdmn == ETSI12_WORLD_REGDMN_PAIR_ID) ||
+		(regdmn == ETSI13_WORLD_REGDMN_PAIR_ID) ||
+		(regdmn == ETSI14_WORLD_REGDMN_PAIR_ID)) &&
+	       overlap);
+}

+ 1 - 10
umac/dfs/core/src/filtering/dfs_partial_offload_radar.c

@@ -291,8 +291,6 @@ void dfs_get_po_radars(struct wlan_dfs *dfs)
 	int i;
 	uint32_t target_type;
 	int dfsdomain = DFS_FCC_DOMAIN;
-	uint16_t ch_freq;
-	uint16_t regdmn;
 
 	/* Fetch current radar patterns from the lmac */
 	qdf_mem_zero(&rinfo, sizeof(rinfo));
@@ -336,14 +334,7 @@ void dfs_get_po_radars(struct wlan_dfs *dfs)
 		dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "ETSI domain");
 		rinfo.dfsdomain = DFS_ETSI_DOMAIN;
 
-		ch_freq = dfs->dfs_curchan->dfs_ch_freq;
-		regdmn = utils_dfs_get_cur_rd(dfs->dfs_pdev_obj);
-
-		if (((regdmn == ETSI11_WORLD_REGDMN_PAIR_ID) ||
-		    (regdmn == ETSI12_WORLD_REGDMN_PAIR_ID) ||
-		    (regdmn == ETSI13_WORLD_REGDMN_PAIR_ID) ||
-		    (regdmn == ETSI14_WORLD_REGDMN_PAIR_ID)) &&
-		    DFS_CURCHAN_IS_58GHz(ch_freq)) {
+		if (dfs_is_en302_502_applicable(dfs)) {
 			rinfo.dfs_radars = dfs_etsi_radars;
 			rinfo.numradars = QDF_ARRAY_SIZE(dfs_etsi_radars);
 		} else {