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
This commit is contained in:
Shaakir Mohamed
2018-08-08 16:55:28 -07:00
committed by nshrivas
parent d7d1d6707f
commit fa4d383541
6 changed files with 147 additions and 44 deletions

View File

@@ -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.

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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);
}

View File

@@ -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 {