qcacmn: Fix RADAR found on wrong channel

Problem 1:
When HOST receives RADAR found indication from target on wrong
channel ex: channel 68. Host does not add the channel to NOL,
but calls random channel function to choose new channel. It
leads to target assert and HOST crash.

Solution 1:
If channel is wrong, do not add it to NOL and do not call
random channel function.

Problem 2:
When Host receives RADAR indication from target, HOST prints
excess information. It floods the console log.

Solution 2:
Add debug bit mask for excess information.

Change-Id: Ib367ee80705d6b789e4e6823682e2f3c3096c9d9
CRs-Fixed: 2148940
This commit is contained in:
Shashikala Prabhu 2017-11-24 22:05:41 +05:30 • committed by snandini
commit fbeb761ef0
4 changed files with 74 additions and 47 deletions

View file

@ -464,16 +464,8 @@ static inline void dfs_radarfound_reset_vars(
dfs->wlan_dfs_stats.num_radar_detects++;
thischan = &rs->rs_chan;
if ((seg_id == SEG_ID_SECONDARY) &&
(dfs_is_precac_timer_running(dfs))) {
(dfs_is_precac_timer_running(dfs)))
dfs->is_radar_during_precac = 1;
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
"Radar found on second segment VHT80 freq=%d MHz",
dfs->dfs_precac_secondary_freq);
} else {
dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS,
"Radar found on channel %d (%d MHz)",
thischan->dfs_ch_ieee, thischan->dfs_ch_freq);
}
/*
* If event log is on then dump the radar event queue on

View file

@ -126,7 +126,7 @@
*
* Return: None
*/
static void dfs_radar_add_to_nol(struct wlan_dfs *dfs,
static QDF_STATUS dfs_radar_add_to_nol(struct wlan_dfs *dfs,
struct freqs_offsets *freq_offset)
{
int i;
@ -140,8 +140,8 @@ static void dfs_radar_add_to_nol(struct wlan_dfs *dfs,
continue;
if (!utils_is_dfs_ch(dfs->dfs_pdev_obj,
freq_offset->chan_num[i])) {
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
"ch=%d is not dfs skip",
dfs_info(dfs, WLAN_DEBUG_DFS,
"ch=%d is not dfs, skip",
freq_offset->chan_num[i]);
continue;
}
@ -149,13 +149,18 @@ static void dfs_radar_add_to_nol(struct wlan_dfs *dfs,
dfs_nol_addchan(dfs, (uint16_t)freq_offset->freq[i],
dfs->wlan_dfs_nol_timeout);
nollist[num_ch++] = last_chan;
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
dfs_info(dfs, WLAN_DEBUG_DFS,
"ch = %d Added to NOL", last_chan);
}
if (!num_ch)
return QDF_STATUS_E_FAILURE;
utils_dfs_reg_update_nol_ch(dfs->dfs_pdev_obj,
nollist, num_ch, DFS_NOL_SET);
dfs_nol_update(dfs);
utils_dfs_save_nol(dfs->dfs_pdev_obj);
return QDF_STATUS_SUCCESS;
}
/**
@ -325,7 +330,7 @@ static void dfs_find_radar_affected_subchans(
}
dfs_radar_chan_for_80(freq_offset, freq_center);
} else {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
dfs_err(dfs, WLAN_DEBUG_DFS,
"channel flag(%d) is invalid", flag);
return;
}
@ -333,7 +338,7 @@ static void dfs_find_radar_affected_subchans(
for (i = 0; i < DFS_NUM_FREQ_OFFSET; i++) {
freq_offset->chan_num[i] = utils_dfs_freq_to_chan(
freq_offset->freq[i]);
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "offset = %d, channel = %d",
dfs_info(dfs, WLAN_DEBUG_DFS, "offset = %d, channel = %d",
i, freq_offset->chan_num[i]);
}
}
@ -343,6 +348,7 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs,
{
struct freqs_offsets freq_offset;
bool wait_for_csa = false;
QDF_STATUS status;
if (!dfs->dfs_curchan) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs->dfs_curchan is NULL");
@ -351,7 +357,7 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs,
/* Check if the current channel is a non DFS channel */
if (!dfs_radarevent_basic_sanity(dfs, dfs->dfs_curchan)) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
dfs_err(dfs, WLAN_DEBUG_DFS,
"radar event on a non-DFS channel");
return QDF_STATUS_E_FAILURE;
}
@ -363,7 +369,22 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs,
dfs_find_radar_affected_subchans(dfs, radar_found, &freq_offset);
dfs_radar_add_to_nol(dfs, &freq_offset);
status = dfs_radar_add_to_nol(dfs, &freq_offset);
if (QDF_IS_STATUS_ERROR(status)) {
dfs_err(dfs, WLAN_DEBUG_DFS,
"radar event received on invalid channel");
return status;
}
if (radar_found->segment_id == SEG_ID_SECONDARY)
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
"Radar found on second segment VHT80 freq=%d MHz",
dfs->dfs_precac_secondary_freq);
else
dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS,
"Radar found on channel %d (%d MHz)",
dfs->dfs_curchan->dfs_ch_ieee,
dfs->dfs_curchan->dfs_ch_freq);
/*
* If precac is running and the radar found in secondary

View file

@ -32,6 +32,7 @@
/**
* dfs_populate_80mhz_available_channels()- Populate channels for 80MHz using
* bitmap
* @dfs: Pointer to DFS structure.
* @bitmap: bitmap
* @avail_chnl: prepared channel list
*
@ -40,8 +41,9 @@
* Return: channel count
*/
static uint8_t dfs_populate_80mhz_available_channels(
struct chan_bonding_bitmap *bitmap,
uint8_t *avail_chnl)
struct wlan_dfs *dfs,
struct chan_bonding_bitmap *bitmap,
uint8_t *avail_chnl)
{
uint8_t i = 0;
uint8_t chnl_count = 0;
@ -62,7 +64,7 @@ static uint8_t dfs_populate_80mhz_available_channels(
}
}
dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS,
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"channel count %d", chnl_count);
return chnl_count;
@ -71,6 +73,7 @@ static uint8_t dfs_populate_80mhz_available_channels(
/**
* dfs_populate_40mhz_available_channels()- Populate channels for 40MHz using
* bitmap
* @dfs: Pointer to DFS structure.
* @bitmap: bitmap
* @avail_chnl: prepared channel list
*
@ -79,8 +82,9 @@ static uint8_t dfs_populate_80mhz_available_channels(
* Return: channel count
*/
static uint8_t dfs_populate_40mhz_available_channels(
struct chan_bonding_bitmap *bitmap,
uint8_t *avail_chnl)
struct wlan_dfs *dfs,
struct chan_bonding_bitmap *bitmap,
uint8_t *avail_chnl)
{
uint8_t i = 0;
uint8_t chnl_count = 0;
@ -103,7 +107,8 @@ static uint8_t dfs_populate_40mhz_available_channels(
(DFS_NEXT_5GHZ_CHANNEL * 3);
}
}
dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS,
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"channel count %d", chnl_count);
return chnl_count;
@ -112,6 +117,7 @@ static uint8_t dfs_populate_40mhz_available_channels(
/**
* dfs_populate_available_channels()- Populate channels based on width and
* bitmap
* @dfs: Pointer to DFS structure.
* @bitmap: bitmap
* @ch_width: channel width
* @avail_chnl: prepared channel list
@ -121,21 +127,22 @@ static uint8_t dfs_populate_40mhz_available_channels(
* Return: channel count
*/
static uint8_t dfs_populate_available_channels(
struct chan_bonding_bitmap *bitmap,
uint8_t ch_width,
uint8_t *avail_chnl)
struct wlan_dfs *dfs,
struct chan_bonding_bitmap *bitmap,
uint8_t ch_width,
uint8_t *avail_chnl)
{
switch (ch_width) {
case DFS_CH_WIDTH_160MHZ:
case DFS_CH_WIDTH_80P80MHZ:
case DFS_CH_WIDTH_80MHZ:
return dfs_populate_80mhz_available_channels(
bitmap, avail_chnl);
dfs, bitmap, avail_chnl);
case DFS_CH_WIDTH_40MHZ:
return dfs_populate_40mhz_available_channels(
bitmap, avail_chnl);
dfs, bitmap, avail_chnl);
default:
dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"Invalid ch_width %d", ch_width);
break;
}
@ -145,6 +152,7 @@ static uint8_t dfs_populate_available_channels(
/**
* dfs_get_rand_from_lst()- Get random channel from a given channel list
* @dfs: Pointer to DFS structure.
* @ch_lst: channel list
* @num_ch: number of channels
*
@ -152,7 +160,10 @@ static uint8_t dfs_populate_available_channels(
*
* Return: channel number
*/
static uint8_t dfs_get_rand_from_lst(uint8_t *ch_lst, uint8_t num_ch)
static uint8_t dfs_get_rand_from_lst(
struct wlan_dfs *dfs,
uint8_t *ch_lst,
uint8_t num_ch)
{
uint8_t i;
uint32_t rand_byte = 0;
@ -167,7 +178,8 @@ static uint8_t dfs_get_rand_from_lst(uint8_t *ch_lst, uint8_t num_ch)
get_random_bytes((uint8_t *)&rand_byte, 1);
i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_ch;
dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "random channel %d", ch_lst[i]);
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"random channel %d", ch_lst[i]);
return ch_lst[i];
}
@ -246,18 +258,19 @@ static uint8_t dfs_find_ch_with_fallback(
}
/* populate available channel list from bitmap */
final_cnt = dfs_populate_available_channels(&ch_map, *ch_wd, final_lst);
final_cnt = dfs_populate_available_channels(dfs, &ch_map,
*ch_wd, final_lst);
/* If no valid ch bonding found, fallback */
if (final_cnt == 0) {
if ((*ch_wd == DFS_CH_WIDTH_160MHZ) ||
(*ch_wd == DFS_CH_WIDTH_80P80MHZ) ||
(*ch_wd == DFS_CH_WIDTH_80MHZ)) {
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"from [%d] to 40Mhz", *ch_wd);
*ch_wd = DFS_CH_WIDTH_40MHZ;
} else if (*ch_wd == DFS_CH_WIDTH_40MHZ) {
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"from 40Mhz to 20MHz");
*ch_wd = DFS_CH_WIDTH_20MHZ;
}
@ -268,7 +281,7 @@ static uint8_t dfs_find_ch_with_fallback(
if (((*ch_wd == DFS_CH_WIDTH_160MHZ) ||
(*ch_wd == DFS_CH_WIDTH_80P80MHZ)) &&
(final_cnt < DFS_MAX_20M_SUB_CH)) {
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"from [%d] to 80Mhz", *ch_wd);
*ch_wd = DFS_CH_WIDTH_80MHZ;
return 0;
@ -297,7 +310,7 @@ static uint8_t dfs_find_ch_with_fallback(
}
if ((flag == false) && (*ch_wd > DFS_CH_WIDTH_80MHZ)) {
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"from [%d] to 80Mhz", *ch_wd);
*ch_wd = DFS_CH_WIDTH_80MHZ;
return 0;
@ -339,12 +352,13 @@ static uint8_t dfs_find_ch_with_fallback(
*ch_wd = DFS_CH_WIDTH_80MHZ;
*center_freq_seg1 = sec_seg_ch;
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"Center frequency seg1 = %d", sec_seg_ch);
} else {
target_channel = dfs_get_rand_from_lst(final_lst, final_cnt);
target_channel = dfs_get_rand_from_lst(dfs,
final_lst, final_cnt);
}
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"target channel = %d", target_channel);
return target_channel;
@ -385,7 +399,7 @@ static bool dfs_freq_is_in_nol(struct wlan_dfs *dfs, uint32_t freq)
struct dfs_nolelem *nol;
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "null dfs");
return false;
}
@ -558,21 +572,21 @@ uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs,
uint16_t flag_no_weather = 0;
if (!ch_list || !ch_cnt) {
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"Invalid params %pK, ch_cnt=%d",
ch_list, ch_cnt);
return 0;
}
if (*ch_wd < DFS_CH_WIDTH_20MHZ || *ch_wd > DFS_CH_WIDTH_80P80MHZ) {
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"Invalid ch_wd %d", *ch_wd);
return 0;
}
random_chan_list = qdf_mem_malloc(ch_cnt * sizeof(*random_chan_list));
if (!random_chan_list) {
dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
dfs_alert(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"Memory allocation failed");
return 0;
}
@ -589,7 +603,7 @@ uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs,
do {
if (*ch_wd == DFS_CH_WIDTH_20MHZ) {
target_ch = dfs_get_rand_from_lst(
random_chan_list, random_chan_cnt);
dfs, random_chan_list, random_chan_cnt);
break;
}
@ -618,7 +632,7 @@ uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs,
} while (true);
qdf_mem_free(random_chan_list);
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "target_ch = %d", target_ch);
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "target_ch = %d", target_ch);
return target_ch;
}

View file

@ -647,7 +647,7 @@ QDF_STATUS utils_dfs_get_random_channel(
ch_params->center_freq_seg0 = cur_chan.dfs_ch_vhtop_ch_freq_seg1;
ch_params->center_freq_seg1 = cur_chan.dfs_ch_vhtop_ch_freq_seg2;
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"input width=%d", ch_params->ch_width);
if (*target_chan) {
@ -657,7 +657,7 @@ QDF_STATUS utils_dfs_get_random_channel(
status = QDF_STATUS_SUCCESS;
}
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"ch=%d, seg0=%d, seg1=%d, width=%d",
*target_chan, ch_params->center_freq_seg0,
ch_params->center_freq_seg1, ch_params->ch_width);