From fa4d38354194f658a89c3bd1d14915e154b2cecc Mon Sep 17 00:00:00 2001 From: Shaakir Mohamed Date: Wed, 8 Aug 2018 16:55:28 -0700 Subject: [PATCH] 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 --- umac/dfs/core/src/dfs.h | 65 ++++++++++++++- umac/dfs/core/src/filtering/ar5212_radar.c | 11 +-- umac/dfs/core/src/filtering/ar5416_radar.c | 11 +-- umac/dfs/core/src/filtering/ar9300_radar.c | 11 +-- umac/dfs/core/src/filtering/dfs_init.c | 82 +++++++++++++++++++ .../src/filtering/dfs_partial_offload_radar.c | 11 +-- 6 files changed, 147 insertions(+), 44 deletions(-) diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index 925c0026b4..c41a299bf1 100644 --- a/umac/dfs/core/src/dfs.h +++ b/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. diff --git a/umac/dfs/core/src/filtering/ar5212_radar.c b/umac/dfs/core/src/filtering/ar5212_radar.c index e28e154400..79a95c2101 100644 --- a/umac/dfs/core/src/filtering/ar5212_radar.c +++ b/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 { diff --git a/umac/dfs/core/src/filtering/ar5416_radar.c b/umac/dfs/core/src/filtering/ar5416_radar.c index d6995a0ef8..dab493ad23 100644 --- a/umac/dfs/core/src/filtering/ar5416_radar.c +++ b/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 { diff --git a/umac/dfs/core/src/filtering/ar9300_radar.c b/umac/dfs/core/src/filtering/ar9300_radar.c index d33f92346d..48443acc3c 100644 --- a/umac/dfs/core/src/filtering/ar9300_radar.c +++ b/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 { diff --git a/umac/dfs/core/src/filtering/dfs_init.c b/umac/dfs/core/src/filtering/dfs_init.c index 1ae8672aab..54d4447e06 100644 --- a/umac/dfs/core/src/filtering/dfs_init.c +++ b/umac/dfs/core/src/filtering/dfs_init.c @@ -22,6 +22,9 @@ #include "../dfs.h" #include "wlan_dfs_lmac_api.h" +#include +#include +#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); +} diff --git a/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c b/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c index db3bd30cc3..e1a508c174 100644 --- a/umac/dfs/core/src/filtering/dfs_partial_offload_radar.c +++ b/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 {