From 68431d3ea55c1849d9a6d0f65608d7fd1dd817b7 Mon Sep 17 00:00:00 2001 From: Shashikala Prabhu Date: Mon, 16 Oct 2017 21:30:01 +0530 Subject: [PATCH] qcacmn: Add support to use new random channel algorithm 1) Add support to use new random channel selection algorithm from converged DFS component. 2) Move random channel filtering flags from dfs_internal.h to dfs_ioctl.h as these flags are common between MLME and DFS component. Change-Id: I5ef789dd9e9c28706f1c581997a646a80caec5ee CRs-Fixed: 2120265 --- umac/cmn_services/dfs/inc/dfs_ioctl.h | 22 ++++ umac/dfs/core/src/dfs_internal.h | 5 - umac/dfs/core/src/dfs_random_chan_sel.h | 27 +---- umac/dfs/core/src/misc/dfs_random_chan_sel.c | 55 ++++++---- umac/dfs/dispatcher/src/wlan_dfs_utils_api.c | 108 ++++++++++++++++++- 5 files changed, 167 insertions(+), 50 deletions(-) diff --git a/umac/cmn_services/dfs/inc/dfs_ioctl.h b/umac/cmn_services/dfs/inc/dfs_ioctl.h index 6f0e2147f4c8..c9522c10f148 100644 --- a/umac/cmn_services/dfs/inc/dfs_ioctl.h +++ b/umac/cmn_services/dfs/inc/dfs_ioctl.h @@ -122,4 +122,26 @@ struct dfs_ioctl_params { #define DFS_IOCTL_PARAM_NOVAL 65535 #define DFS_IOCTL_PARAM_ENABLE 0x8000 +/* Random channel flags */ +/* Flag to exclude current operating channels */ +#define DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH 0x0001 /* 0000 0000 0000 0001 */ + +/* Flag to exclude weather channels */ +#define DFS_RANDOM_CH_FLAG_NO_WEATHER_CH 0x0002 /* 0000 0000 0000 0010 */ + +/* Flag to exclude indoor channels */ +#define DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH 0x0004 /* 0000 0000 0000 0100 */ + +/* Flag to exclude outdoor channels */ +#define DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH 0x0008 /* 0000 0000 0000 1000 */ + +/* Flag to exclude dfs channels */ +#define DFS_RANDOM_CH_FLAG_NO_DFS_CH 0x0010 /* 0000 0000 0001 0000 */ + +/* Flag to exclude all 5GHz channels */ +#define DFS_RANDOM_CH_FLAG_NO_5GHZ_CH 0x0020 /* 0000 0000 0010 0000 */ + +/* Flag to exclude all 2.4GHz channels */ +#define DFS_RANDOM_CH_FLAG_NO_2GHZ_CH 0x0040 /* 0000 0000 0100 0000 */ + #endif /* _DFS_IOCTL_H_ */ diff --git a/umac/dfs/core/src/dfs_internal.h b/umac/dfs/core/src/dfs_internal.h index 6f4918e47902..863402db1d30 100644 --- a/umac/dfs/core/src/dfs_internal.h +++ b/umac/dfs/core/src/dfs_internal.h @@ -51,11 +51,6 @@ enum DFS_DOMAIN { /* CAPABILITY: the device support STA DFS */ #define IEEE80211_CEXT_STADFS 0x00000040 -#define IEEE80211_SELECT_NONDFS_AND_DFS 0 -#define IEEE80211_SELECT_NONDFS_ONLY 1 -#define IEEE80211_SELECT_NXT_CH_POST_RADAR_DETECT 0 -#define IEEE80211_SELECT_APRIORI_NXT_CH 1 - /** * dfs_ieee80211_chan2freq() - Convert channel to frequency value. * @chan: Pointer to dfs_ieee80211_channel structure. diff --git a/umac/dfs/core/src/dfs_random_chan_sel.h b/umac/dfs/core/src/dfs_random_chan_sel.h index 99f6a3c7cc32..ea8b23f381be 100644 --- a/umac/dfs/core/src/dfs_random_chan_sel.h +++ b/umac/dfs/core/src/dfs_random_chan_sel.h @@ -75,28 +75,6 @@ /* Max channel width */ #define DFS_CH_WIDTH_MAX 8 -/* Random channel flags */ -/* Flag to exclude current operating channels */ -#define DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH 0x0001 /* 0000 0000 0000 0001 */ - -/* Flag to exclude weather channels */ -#define DFS_RANDOM_CH_FLAG_NO_WEATHER_CH 0x0002 /* 0000 0000 0000 0010 */ - -/* Flag to exclude indoor channels */ -#define DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH 0x0004 /* 0000 0000 0000 0100 */ - -/* Flag to exclude outdoor channels */ -#define DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH 0x0008 /* 0000 0000 0000 1000 */ - -/* Flag to exclude dfs channels */ -#define DFS_RANDOM_CH_FLAG_NO_DFS_CH 0x0010 /* 0000 0000 0001 0000 */ - -/* Flag to exclude all 5GHz channels */ -#define DFS_RANDOM_CH_FLAG_NO_5GHZ_CH 0x0020 /* 0000 0000 0010 0000 */ - -/* Flag to exclude all 2.4GHz channels */ -#define DFS_RANDOM_CH_FLAG_NO_2GHZ_CH 0x0040 /* 0000 0000 0100 0000 */ - /* Next 5GHz channel number */ #define DFS_80_NUM_SUB_CHANNNEL 4 @@ -124,9 +102,12 @@ /* Bitmap mask for 40MHz higher */ #define DFS_40MHZ_MASK_H 0x0C -/* Adjacent weather radar channel */ +/* Adjacent weather radar channel frequency */ #define DFS_ADJACENT_WEATHER_RADAR_CHANNEL 5580 +/* Adjacent weather radar channel number */ +#define DFS_ADJACENT_WEATHER_RADAR_CHANNEL_NUM 116 + /* Max 2.4 GHz channel number */ #define DFS_MAX_24GHZ_CHANNEL 14 diff --git a/umac/dfs/core/src/misc/dfs_random_chan_sel.c b/umac/dfs/core/src/misc/dfs_random_chan_sel.c index a6e3f4442034..6ee0567d9505 100644 --- a/umac/dfs/core/src/misc/dfs_random_chan_sel.c +++ b/umac/dfs/core/src/misc/dfs_random_chan_sel.c @@ -415,7 +415,7 @@ static void dfs_apply_rules(struct wlan_dfs *dfs, struct dfs_acs_info *acs_info) { struct dfs_ieee80211_channel *chan; - uint16_t flag_no_wheather = 0; + uint16_t flag_no_weather = 0; uint16_t flag_no_lower_5g = 0; uint16_t flag_no_upper_5g = 0; uint16_t flag_no_dfs_chan = 0; @@ -424,7 +424,7 @@ static void dfs_apply_rules(struct wlan_dfs *dfs, int i; dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "flags %d", flags); - flag_no_wheather = (dfs_region == DFS_ETSI_REGION_VAL) ? + flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ? flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; flag_no_lower_5g = (dfs_region == DFS_MKK_REGION_VAL) ? @@ -447,6 +447,17 @@ static void dfs_apply_rules(struct wlan_dfs *dfs, continue; } + if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) { + /* TODO : Skip all HT20 channels in the given mode */ + if (chan->dfs_ch_ieee == + dfs->dfs_curchan->dfs_ch_ieee) { + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "skip %d current operating channel\n", + chan->dfs_ch_ieee); + continue; + } + } + if (acs_info && (acs_info->acs_mode == 1) && ((chan->dfs_ch_ieee < acs_info->start_ch) || (chan->dfs_ch_ieee > acs_info->end_ch))) { @@ -474,31 +485,17 @@ static void dfs_apply_rules(struct wlan_dfs *dfs, continue; } - if (flag_no_wheather) { - /* - * We should also avoid this channel in HT40 mode as - * extension channel will be on 5600. - */ - /* TODO check if reg updating chan->dfs_ch_flags for - * IEEE80211_CHAN_11NA_HT40PLUS - */ + if (flag_no_weather) { if (DFS_IS_CHANNEL_WEATHER_RADAR(chan->dfs_ch_freq)) { dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "skip weather channel=%d", chan->dfs_ch_ieee); continue; - } else if (DFS_ADJACENT_WEATHER_RADAR_CHANNEL == - chan->dfs_ch_freq && (chan->dfs_ch_flags & - IEEE80211_CHAN_11NA_HT40PLUS)) { - dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, - "skip weather adjacent ch=%d", - chan->dfs_ch_ieee); - continue; } } if (flag_no_lower_5g && - DFS_IS_CHAN_JAPAN_INDOOR(chan->dfs_ch_freq)) { + DFS_IS_CHAN_JAPAN_INDOOR(chan->dfs_ch_ieee)) { dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "skip indoor channel=%d", chan->dfs_ch_ieee); @@ -506,7 +503,7 @@ static void dfs_apply_rules(struct wlan_dfs *dfs, } if (flag_no_upper_5g && - DFS_IS_CHAN_JAPAN_OUTDOOR(chan->dfs_ch_freq)) { + DFS_IS_CHAN_JAPAN_OUTDOOR(chan->dfs_ch_ieee)) { dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "skip outdoor channel=%d", chan->dfs_ch_ieee); continue; @@ -542,6 +539,7 @@ uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs, uint8_t target_ch = 0; uint8_t *random_chan_list = NULL; uint32_t random_chan_cnt = 0; + uint16_t flag_no_weather = 0; if (!ch_list || !ch_cnt) { dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, @@ -569,6 +567,9 @@ uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs, dfs_apply_rules(dfs, flags, random_chan_list, &random_chan_cnt, ch_list, ch_cnt, dfs_region, acs_info); + flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ? + flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; + do { if (*ch_wd == DFS_CH_WIDTH_20MHZ) { target_ch = dfs_get_rand_from_lst( @@ -580,6 +581,22 @@ uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs, &cur_chan->dfs_ch_vhtop_ch_freq_seg2, random_chan_list, random_chan_cnt); + + /* + * When flag_no_weather is set, avoid usage of Adjacent + * weather radar channel in HT40 mode as extension channel + * will be on 5600. + */ + if (flag_no_weather && + (target_ch == + DFS_ADJACENT_WEATHER_RADAR_CHANNEL_NUM) && + (*ch_wd == DFS_CH_WIDTH_40MHZ)) { + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "skip weather adjacent ch=%d\n", + target_ch); + continue; + } + if (target_ch) break; } while (true); diff --git a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c index 76381aa08bdc..1dc4a295ddee 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c @@ -24,6 +24,7 @@ #include "wlan_dfs_utils_api.h" #include "../../core/src/dfs.h" #include "../../core/src/dfs_zero_cac.h" +#include #include "../../core/src/dfs_random_chan_sel.h" #ifdef QCA_DFS_USE_POLICY_MANAGER #include "wlan_policy_mgr_api.h" @@ -421,6 +422,13 @@ static void utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev *pdev, return; } +/** + * utils_dfs_get_chan_list() - Get channel list from regdb based on current + * operating channel. + * @pdev: Pointer to DFS pdev object. + * @chan_list: Pointer to current channel list + * @num_chan: number of channels in the current channel list. + */ #ifndef QCA_DFS_USE_POLICY_MANAGER static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, struct dfs_ieee80211_channel *chan_list, uint32_t *num_chan) @@ -436,8 +444,11 @@ static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(struct regulatory_channel)); - if (cur_chan_list == NULL) + if (!cur_chan_list) { dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "fail to alloc"); + *num_chan = 0; + return; + } if (wlan_reg_get_current_chan_list( pdev, cur_chan_list) != QDF_STATUS_SUCCESS) { @@ -450,9 +461,12 @@ static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, for (i = 0; i < NUM_CHANNELS; i++) { state = cur_chan_list[i].state; if (state == CHANNEL_STATE_DFS || - state == CHANNEL_STATE_ENABLE) { + state == CHANNEL_STATE_ENABLE) { chan_list[j].dfs_ch_ieee = cur_chan_list[i].chan_num; chan_list[j].dfs_ch_freq = cur_chan_list[i].center_freq; + if (state == CHANNEL_STATE_DFS) + chan_list[j].dfs_ch_flagext = + IEEE80211_CHAN_DFS; j++; } } @@ -461,7 +475,82 @@ static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, return; } + +/** + * utils_dfs_get_channel_list() - Get channel list from regdb component based + * on current channel list. + * @pdev: Pointer to pdev structure. + * @chan_list: Pointer to regdb channel list. + * @num_chan: number of channels. + * + * Get regdb channel list based on dfs current channel. + * ex: When AP is operating in 5GHz channel, filter 2.4GHz and 4.9GHZ channels + * so that the random channel function does not select either 2.4GHz or 4.9GHz + * channel. + */ +static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, + struct dfs_ieee80211_channel *chan_list, uint32_t *num_chan) +{ + struct dfs_ieee80211_channel *tmp_chan_list = NULL; + struct wlan_dfs *dfs; + bool is_curchan_5g; + bool is_curchan_24g; + bool is_curchan_49g; + uint32_t chan_num; + uint32_t center_freq; + uint16_t flagext; + int i, j = 0; + + dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); + return; + } + + tmp_chan_list = qdf_mem_malloc(*num_chan * sizeof(*tmp_chan_list)); + if (!tmp_chan_list) { + dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, "mem alloc failed"); + return; + } + + utils_dfs_get_chan_list(pdev, tmp_chan_list, num_chan); + + chan_num = dfs->dfs_curchan->dfs_ch_ieee; + center_freq = dfs->dfs_curchan->dfs_ch_freq; + is_curchan_5g = WLAN_REG_IS_5GHZ_CH(chan_num); + is_curchan_24g = WLAN_REG_IS_24GHZ_CH(chan_num); + is_curchan_49g = WLAN_REG_IS_49GHZ_FREQ(center_freq); + + for (i = 0; i < *num_chan; i++) { + chan_num = tmp_chan_list[i].dfs_ch_ieee; + center_freq = tmp_chan_list[i].dfs_ch_freq; + flagext = tmp_chan_list[i].dfs_ch_flagext; + + if ((is_curchan_5g) && WLAN_REG_IS_5GHZ_CH(chan_num)) { + chan_list[j].dfs_ch_ieee = chan_num; + chan_list[j].dfs_ch_freq = center_freq; + chan_list[j].dfs_ch_flagext = flagext; + j++; + } else if ((is_curchan_24g) && + WLAN_REG_IS_24GHZ_CH(chan_num)) { + chan_list[j].dfs_ch_ieee = chan_num; + chan_list[j].dfs_ch_freq = center_freq; + j++; + } else if ((is_curchan_49g) && + WLAN_REG_IS_49GHZ_FREQ(center_freq)) { + chan_list[j].dfs_ch_ieee = chan_num; + chan_list[j].dfs_ch_freq = center_freq; + j++; + } + } + + *num_chan = j; + + qdf_mem_free(tmp_chan_list); +} + #else + static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, struct dfs_ieee80211_channel *chan_list, uint32_t *num_chan) { @@ -507,6 +596,19 @@ static void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, *num_chan = i; dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "num channels %d", i); } + +/** + * utils_dfs_get_channel_list() - Wrapper function to get channel list from + * regdb component. + * @pdev: Pointer to pdev structure. + * @chan_list: Pointer to regdb channel list. + * @num_chan: number of channels. + */ +static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, + struct dfs_ieee80211_channel *chan_list, uint32_t *num_chan) +{ + utils_dfs_get_chan_list(pdev, chan_list, num_chan); +} #endif QDF_STATUS utils_dfs_get_random_channel( @@ -545,7 +647,7 @@ QDF_STATUS utils_dfs_get_random_channel( goto random_chan_error; } - utils_dfs_get_chan_list(pdev, chan_list, &num_chan); + utils_dfs_get_channel_list(pdev, chan_list, &num_chan); if (!num_chan) { dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "zero channels"); goto random_chan_error;