From fbeb761ef06926430d50806b5366fdc38e64d905 Mon Sep 17 00:00:00 2001 From: Shashikala Prabhu Date: Fri, 24 Nov 2017 22:05:41 +0530 Subject: [PATCH] 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 --- .../src/filtering/dfs_process_radarevent.c | 10 +-- .../src/misc/dfs_process_radar_found_ind.c | 37 +++++++--- umac/dfs/core/src/misc/dfs_random_chan_sel.c | 70 +++++++++++-------- umac/dfs/dispatcher/src/wlan_dfs_utils_api.c | 4 +- 4 files changed, 74 insertions(+), 47 deletions(-) diff --git a/umac/dfs/core/src/filtering/dfs_process_radarevent.c b/umac/dfs/core/src/filtering/dfs_process_radarevent.c index 8f57443a8ee3..713cedf32f21 100644 --- a/umac/dfs/core/src/filtering/dfs_process_radarevent.c +++ b/umac/dfs/core/src/filtering/dfs_process_radarevent.c @@ -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 diff --git a/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c b/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c index 87919853968d..731a76bc6cff 100644 --- a/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c +++ b/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c @@ -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 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 b11d557c1ddf..5f77564885ab 100644 --- a/umac/dfs/core/src/misc/dfs_random_chan_sel.c +++ b/umac/dfs/core/src/misc/dfs_random_chan_sel.c @@ -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; } diff --git a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c index 39540ff687bb..281247766fb4 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c @@ -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);