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
This commit is contained in:
Shashikala Prabhu 2017-10-16 21:30:01 +05:30 • committed by snandini
commit 68431d3ea5
5 changed files with 167 additions and 50 deletions

View file

@ -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_ */

View file

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

View file

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

View file

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

View file

@ -24,6 +24,7 @@
#include "wlan_dfs_utils_api.h"
#include "../../core/src/dfs.h"
#include "../../core/src/dfs_zero_cac.h"
#include <wlan_reg_services_api.h>
#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;