diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index 27927dc6331f..e0c330cba057 100644 --- a/umac/dfs/core/src/dfs.h +++ b/umac/dfs/core/src/dfs.h @@ -402,6 +402,11 @@ * in host. NOL timer can be configured by user. NOL in FW (for FO) is disabled. */ #define USENOL_ENABLE_NOL_HOST_DISABLE_NOL_FW 2 + +/* Non Agile detector IDs */ +#define DETECTOR_ID_0 0 +#define DETECTOR_ID_1 1 +/* Agile detector ID */ #define AGILE_DETECTOR_ID 2 /** @@ -1140,8 +1145,8 @@ struct wlan_dfs { struct dfs_soc_priv_obj *dfs_soc_obj; #if defined(QCA_SUPPORT_AGILE_DFS) || defined(ATH_SUPPORT_ZERO_CAC_DFS) uint8_t dfs_psoc_idx; - uint8_t dfs_agile_precac_freq; #endif + uint8_t dfs_agile_precac_freq; bool dfs_is_offload_enabled; int dfs_use_nol; qdf_spinlock_t dfs_nol_lock; diff --git a/umac/dfs/core/src/dfs_process_radar_found_ind.h b/umac/dfs/core/src/dfs_process_radar_found_ind.h index 2017742340e2..54a93ede644f 100644 --- a/umac/dfs/core/src/dfs_process_radar_found_ind.h +++ b/umac/dfs/core/src/dfs_process_radar_found_ind.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -138,16 +138,19 @@ void dfs_radarfound_action_generic(struct wlan_dfs *dfs, uint8_t seg_id); /** * dfs_get_bonding_channels() - Get bonding channels. - * @dfs: Pointer to wlan_dfs structure. - * @curchan: Pointer to dfs_channels to know width and primary channel. - * @segment_id: Segment id, useful for 80+80/160 MHz operating band. - * @channels: Pointer to save radar affected channels. + * @dfs: Pointer to wlan_dfs structure. + * @curchan: Pointer to dfs_channels to know width and primary channel. + * @segment_id: Segment id, useful for 80+80/160 MHz operating band. + * @detector_id: Detector id, used to find if radar is detected on + * Agile detector. + * @channels: Pointer to save radar affected channels. * * Return: Number of channels. */ uint8_t dfs_get_bonding_channels(struct wlan_dfs *dfs, struct dfs_channel *curchan, uint32_t segment_id, + uint8_t detector_id, uint8_t *channels); /** diff --git a/umac/dfs/core/src/misc/dfs_cac.c b/umac/dfs/core/src/misc/dfs_cac.c index ed540429cb15..140db5ae1df1 100644 --- a/umac/dfs/core/src/misc/dfs_cac.c +++ b/umac/dfs/core/src/misc/dfs_cac.c @@ -282,6 +282,7 @@ bool dfs_is_subset_channel(struct wlan_dfs *dfs, old_n_chans = dfs_get_bonding_channels(dfs, old_chan, SEG_ID_SECONDARY, + DETECTOR_ID_0, old_subchans); else old_n_chans = dfs_get_bonding_channels_without_seg_info( @@ -297,6 +298,7 @@ bool dfs_is_subset_channel(struct wlan_dfs *dfs, if (WLAN_IS_CHAN_DFS(new_chan)) new_n_chans = dfs_get_bonding_channels( dfs, new_chan, SEG_ID_SECONDARY, + DETECTOR_ID_0, new_subchans); else new_n_chans = dfs_get_bonding_channels_without_seg_info( diff --git a/umac/dfs/core/src/misc/dfs_nol.c b/umac/dfs/core/src/misc/dfs_nol.c index 5ebe1a9b961a..14af05cde94c 100644 --- a/umac/dfs/core/src/misc/dfs_nol.c +++ b/umac/dfs/core/src/misc/dfs_nol.c @@ -629,7 +629,10 @@ void dfs_remove_spoof_channel_from_nol(struct wlan_dfs *dfs) uint8_t channels[NUM_CHANNELS_160MHZ]; int i, nchans = 0; - nchans = dfs_get_bonding_channels(dfs, &dfs->dfs_radar_found_chan, 0, + nchans = dfs_get_bonding_channels(dfs, + &dfs->dfs_radar_found_chan, + SEG_ID_PRIMARY, + DETECTOR_ID_0, channels); WLAN_DFSNOL_LOCK(dfs); 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 b2c503477737..db33ea2cdcf5 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 @@ -333,7 +333,10 @@ dfs_compute_radar_found_cfreq(struct wlan_dfs *dfs, uint64_t flag; flag = curchan->dfs_ch_flags; - if (!radar_found->segment_id) { + if (radar_found->detector_id == AGILE_DETECTOR_ID) { + *freq_center = utils_dfs_chan_to_freq( + dfs->dfs_agile_precac_freq); + } else if (!radar_found->segment_id) { *freq_center = utils_dfs_chan_to_freq( curchan->dfs_ch_vhtop_ch_freq_seg1); } else { @@ -384,8 +387,8 @@ static uint8_t dfs_find_radar_affected_subchans(struct wlan_dfs *dfs, sidx = DFS_FREQ_OFFSET_TO_SIDX(radar_found->freq_offset); dfs_info(dfs, WLAN_DEBUG_DFS, - "seg=%d, sidx=%d, offset=%d, chirp=%d, flag=%d, f=%d", - radar_found->segment_id, sidx, + "seg=%d, det=%d, sidx=%d, offset=%d, chirp=%d, flag=%d, f=%d", + radar_found->segment_id, radar_found->detector_id, sidx, radar_found->freq_offset, radar_found->is_chirp, flag, freq_center); @@ -419,6 +422,7 @@ static uint8_t dfs_find_radar_affected_subchans(struct wlan_dfs *dfs, n_cur_subchans = dfs_get_bonding_channels(dfs, curchan, radar_found->segment_id, + radar_found->detector_id, cur_subchans); for (i = 0, num_radar_subchans = 0; i < DFS_NUM_FREQ_OFFSET; i++) { @@ -489,12 +493,15 @@ uint8_t dfs_get_bonding_channels_without_seg_info(struct dfs_channel *chan, uint8_t dfs_get_bonding_channels(struct wlan_dfs *dfs, struct dfs_channel *curchan, uint32_t segment_id, + uint8_t detector_id, uint8_t *channels) { uint8_t center_chan; uint8_t nchannels = 0; - if (!segment_id) + if (detector_id == AGILE_DETECTOR_ID) + center_chan = dfs->dfs_agile_precac_freq; + else if (!segment_id) center_chan = curchan->dfs_ch_vhtop_ch_freq_seg1; else { /* When precac is running "dfs_ch_vhtop_ch_freq_seg2" is @@ -515,7 +522,13 @@ uint8_t dfs_get_bonding_channels(struct wlan_dfs *dfs, channels[0] = center_chan - DFS_5GHZ_NEXT_CHAN_OFFSET; channels[1] = center_chan + DFS_5GHZ_NEXT_CHAN_OFFSET; } else if (WLAN_IS_CHAN_MODE_80(curchan) || - WLAN_IS_CHAN_MODE_80_80(curchan)) { + WLAN_IS_CHAN_MODE_80_80(curchan) || + detector_id == AGILE_DETECTOR_ID) { + /* If the current channel's bandwidth is 80/80+80/160Mhz, + * the corresponding agile Detector's bandwidth will be 80Mhz. + * Therefore, if radar is found on the agile detector find + * subchannels for 80Mhz bandwidth. + */ nchannels = 4; channels[0] = center_chan - DFS_5GHZ_2ND_CHAN_OFFSET; channels[1] = center_chan - DFS_5GHZ_NEXT_CHAN_OFFSET; @@ -609,6 +622,7 @@ static void dfs_prepare_nol_ie_bitmap(struct wlan_dfs *dfs, n_cur_subchans = dfs_get_bonding_channels(dfs, dfs->dfs_curchan, radar_found->segment_id, + radar_found->detector_id, cur_subchans); dfs->dfs_nol_ie_bandwidth = MIN_DFS_SUBCHAN_BW; dfs->dfs_nol_ie_startfreq = @@ -680,7 +694,8 @@ bool dfs_process_nol_ie_bitmap(struct wlan_dfs *dfs, uint8_t nol_ie_bandwidth, num_subchans = dfs_get_bonding_channels(dfs, dfs->dfs_curchan, - dfs->dfs_curchan->dfs_ch_freq, + SEG_ID_PRIMARY, + DETECTOR_ID_0, radar_subchans); should_nol_ie_be_sent = false; } else { @@ -722,13 +737,26 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, return QDF_STATUS_E_FAILURE; } - /* Check if the current channel is a non DFS channel */ - if (!dfs_radarevent_basic_sanity(dfs, dfs->dfs_curchan)) { + /* Check if the current channel is a non DFS channel + * If the current channel is non-DFS and the radar is from Agile + * Detector we need to process it since Agile Detector has a + * different channel. + */ + if (!dfs_radarevent_basic_sanity(dfs, dfs->dfs_curchan) && + !(radar_found->detector_id == AGILE_DETECTOR_ID)) { dfs_err(dfs, WLAN_DEBUG_DFS, "radar event on a non-DFS channel"); return QDF_STATUS_E_FAILURE; } + /* Sanity checks for radar on Agile detector */ + if (radar_found->detector_id == AGILE_DETECTOR_ID && + (!dfs->dfs_agile_precac_enable || !dfs->dfs_agile_precac_freq)) { + dfs_err(dfs, WLAN_DEBUG_DFS, + "radar on Agile detector when ADFS is not running"); + return QDF_STATUS_E_FAILURE; + } + /* For Full Offload, FW sends segment id,freq_offset and chirp * information and gets assigned when there is radar detect. In * case of radartool bangradar enhanced command and real radar @@ -743,7 +771,11 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, dfs_compute_radar_found_cfreq(dfs, radar_found, &freq_center); radarfound_freq = freq_center + radar_found->freq_offset; - if (radar_found->segment_id == SEG_ID_SECONDARY) + if (radar_found->detector_id == AGILE_DETECTOR_ID) + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Radar found on Agile detector freq=%d radar freq=%d", + freq_center, radarfound_freq); + else if (radar_found->segment_id == SEG_ID_SECONDARY) dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "Radar found on second segment.Radarfound Freq=%d MHz.Secondary Chan cfreq=%d MHz.", radarfound_freq, freq_center); @@ -777,32 +809,25 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, channels, freq_center); else - num_channels = dfs_get_bonding_channels(dfs, - dfs->dfs_curchan, - radar_found->segment_id, - channels); + num_channels = + dfs_get_bonding_channels(dfs, + dfs->dfs_curchan, + radar_found->segment_id, + radar_found->detector_id, + channels); dfs_reset_bangradar(dfs); - if (dfs->dfs_agile_precac_enable && radar_found->detector_id == - AGILE_DETECTOR_ID) { - dfs_debug(dfs, WLAN_DEBUG_DFS, - "%s: %d Radar found on agile detector:%d , STAY in Same operating Channel", - __func__, __LINE__, radar_found->detector_id); - dfs_mark_precac_nol(dfs, dfs->is_radar_found_on_secondary_seg, - radar_found->detector_id, channels, - num_channels); - return QDF_STATUS_SUCCESS; - } - status = dfs_radar_add_channel_list_to_nol(dfs, channels, num_channels); if (QDF_IS_STATUS_ERROR(status)) { dfs_err(dfs, WLAN_DEBUG_DFS, "radar event received on invalid channel"); return status; } + dfs->dfs_is_nol_ie_sent = false; - (dfs->is_radar_during_precac) ? + (dfs->is_radar_during_precac || + radar_found->detector_id == AGILE_DETECTOR_ID) ? (dfs->dfs_is_rcsa_ie_sent = false) : (dfs->dfs_is_rcsa_ie_sent = true); if (dfs->dfs_use_nol_subchannel_marking) { @@ -857,6 +882,11 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, dfs_mlme_start_rcsa(dfs->dfs_pdev_obj, &wait_for_csa); + /* If radar is found on preCAC or Agile CAC, return here since + * channel change is not required. + */ + if (radar_found->detector_id == AGILE_DETECTOR_ID) + return QDF_STATUS_SUCCESS; if (!dfs->dfs_is_offload_enabled && dfs->is_radar_found_on_secondary_seg) { dfs_second_segment_radar_disable(dfs);