diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index a4a7fc9b93..f38d9ed1c4 100644 --- a/umac/dfs/core/src/dfs.h +++ b/umac/dfs/core/src/dfs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013, 2016-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2005-2006 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for any @@ -922,11 +922,7 @@ struct dfs_event_log { * @wlan_dfswaittimer: Dfs wait timer. * @wlan_dfstesttimer: Dfs mute test timer. * @wlan_dfs_debug_timer: Dfs debug timer. - * @dfs_bangradar: Radar simulation on entire segment. - * @dfs_enh_bangradar: Radar (Chirp or non-chirp) simulation on - * particular frequency. - * @dfs_second_segment_bangradar: Bangaradar on second segment of - * VHT80_80/160. + * @dfs_bangradar_type: Radar simulation type. * @is_radar_found_on_secondary_seg: Radar on second segment. * @dfs_radar_found_for_fo: Radar found event for FO(Full Offload) is * received. @@ -1073,9 +1069,7 @@ struct wlan_dfs { os_timer_t wlan_dfswaittimer; os_timer_t wlan_dfstesttimer; os_timer_t wlan_dfs_debug_timer; - uint8_t dfs_bangradar; - bool dfs_enh_bangradar; - bool dfs_second_segment_bangradar; + enum dfs_bangradar_types dfs_bangradar_type; bool is_radar_found_on_secondary_seg; bool dfs_radar_found_for_fo; bool is_radar_during_precac; diff --git a/umac/dfs/core/src/filtering/dfs_process_radarevent.c b/umac/dfs/core/src/filtering/dfs_process_radarevent.c index 41abd0f7ce..fb2bfb323c 100644 --- a/umac/dfs/core/src/filtering/dfs_process_radarevent.c +++ b/umac/dfs/core/src/filtering/dfs_process_radarevent.c @@ -579,7 +579,7 @@ static inline void dfs_radarfound_reset_vars( * @dfs: Pointer to wlan_dfs structure. * @chan: Current channel. * @rs: Pointer to dfs_state. - * Return: if bangradar then return 0. Otherwise, return 1. + * Return: if bangradar then return 1. Otherwise, return 0. */ static inline int dfs_handle_bangradar( struct wlan_dfs *dfs, @@ -589,42 +589,38 @@ static inline int dfs_handle_bangradar( int *retval) { - if (dfs->dfs_enh_bangradar || dfs->dfs_bangradar) { - /* - * Bangradar will always simulate radar found on - * the primary channel. - * - * Enhanced Bangradar will save the params in dfs - * and simulate radar on given frequency - */ + if (dfs->dfs_bangradar_type) { + if (dfs->dfs_bangradar_type >= DFS_INVALID_BANGRADAR_TYPE) { + dfs_debug(dfs, WLAN_DEBUG_DFS, + "Invalid bangradar type"); + return 1; + } + /* All bangradars are processed similarly. + * arguments for the bangradar are already stored in + * respective dfs structures. + */ + *rs = &dfs->dfs_radar[dfs->dfs_curchan_radindex]; - if (dfs->dfs_enh_bangradar) - *seg_id = dfs->dfs_seg_id; - dfs_debug(dfs, WLAN_DEBUG_DFS, - "bangradar %d, Enhanced Bangradar %d", - dfs->dfs_bangradar, dfs->dfs_enh_bangradar); + if (dfs->dfs_seg_id == SEG_ID_SECONDARY) { + if (dfs_is_precac_timer_running(dfs) || + WLAN_IS_CHAN_11AC_VHT160(chan) || + WLAN_IS_CHAN_11AC_VHT80_80(chan)) { + dfs->is_radar_found_on_secondary_seg = 1; + dfs_debug(dfs, WLAN_DEBUG_DFS, + "bangradar on 2nd segment cfreq = %u", + dfs->dfs_precac_secondary_freq); + } else { + dfs_debug(dfs, WLAN_DEBUG_DFS, + "No second segment"); + return 1; + } + } + *seg_id = dfs->dfs_seg_id; + dfs_debug(dfs, WLAN_DEBUG_DFS, "bangradar %d", + dfs->dfs_bangradar_type); *retval = 1; return 1; } - - if (dfs->dfs_second_segment_bangradar) { - if (dfs_is_precac_timer_running(dfs) || - WLAN_IS_CHAN_11AC_VHT160(chan) || - WLAN_IS_CHAN_11AC_VHT80_80(chan)) { - dfs->is_radar_found_on_secondary_seg = 1; - *rs = &dfs->dfs_radar[dfs->dfs_curchan_radindex]; - dfs_debug(dfs, WLAN_DEBUG_DFS, - "second segment bangradar on cfreq = %u", - dfs->dfs_precac_secondary_freq); - *retval = 1; - *seg_id = SEG_ID_SECONDARY; - } else { - dfs_debug(dfs, WLAN_DEBUG_DFS, - "Do not process the second segment bangradar"); - } - return 1; - } - return 0; } diff --git a/umac/dfs/core/src/misc/dfs.c b/umac/dfs/core/src/misc/dfs.c index c72765cbac..86aa6b79da 100644 --- a/umac/dfs/core/src/misc/dfs.c +++ b/umac/dfs/core/src/misc/dfs.c @@ -315,7 +315,7 @@ int dfs_control(struct wlan_dfs *dfs, { struct wlan_dfs_phyerr_param peout; struct dfs_ioctl_params *dfsparams; - struct dfs_bangradar_enh_params *bangradar_enh_params; + struct dfs_bangradar_params *bangradar_params; int error = 0; uint32_t val = 0; struct dfsreq_nolinfo *nol; @@ -370,43 +370,67 @@ int dfs_control(struct wlan_dfs *dfs, dfsparams->dfs_maxlen)) error = -EINVAL; break; - case DFS_BANGRADAR_ENH: - if (insize < sizeof(struct dfs_bangradar_enh_params) || + case DFS_BANGRADAR: + /* + * Handle all types of Bangradar here. + * Bangradar arguments: + * seg_id : Segment ID where radar should be injected. + * is_chirp : Is chirp radar or non chirp radar. + * freq_offset : Frequency offset from center frequency. + * + * Type 1 (DFS_BANGRADAR_FOR_ALL_SUBCHANS): To add all subchans. + * Type 2 (DFS_BANGRADAR_FOR_ALL_SUBCHANS_OF_SEGID): To add all + * subchans of given segment_id. + * Type 3 (DFS_BANGRADAR_FOR_SPECIFIC_SUBCHANS): To add specific + * subchans based on the arguments. + * + * The arguments will already be filled in the indata structure + * based on the type. + * If an argument is not specified by user, it will be set to + * default (0) in the indata already and correspondingly, + * the type will change. + */ + if (insize < sizeof(struct dfs_bangradar_params) || !indata) { dfs_debug(dfs, WLAN_DEBUG_DFS1, "insize = %d, expected = %zu bytes, indata = %pK", insize, - sizeof(struct dfs_bangradar_enh_params), + sizeof(struct dfs_bangradar_params), indata); error = -EINVAL; break; } - bangradar_enh_params = - (struct dfs_bangradar_enh_params *)indata; - if (bangradar_enh_params) { - if (abs(bangradar_enh_params->freq_offset) > + bangradar_params = (struct dfs_bangradar_params *)indata; + if (bangradar_params) { + if (abs(bangradar_params->freq_offset) > FREQ_OFFSET_BOUNDARY_FOR_80MHZ) { dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "Frequency Offset out of bound"); error = -EINVAL; break; + } else if (bangradar_params->seg_id > + SEG_ID_SECONDARY) { + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Illegal segment ID"); + error = -EINVAL; + break; } - dfs->dfs_seg_id = bangradar_enh_params->seg_id; - dfs->dfs_is_chirp = bangradar_enh_params->is_chirp; - dfs->dfs_freq_offset = - bangradar_enh_params->freq_offset; + dfs->dfs_bangradar_type = + bangradar_params->bangradar_type; + dfs->dfs_seg_id = bangradar_params->seg_id; + dfs->dfs_is_chirp = bangradar_params->is_chirp; + dfs->dfs_freq_offset = bangradar_params->freq_offset; if (dfs->dfs_is_offload_enabled) { error = dfs_fill_emulate_bang_radar_test (dfs, dfs->dfs_seg_id, &dfs_unit_test); } else { - dfs->dfs_enh_bangradar = true; - dfs->dfs_bangradar = 0; error = dfs_start_host_based_bangradar(dfs); } } else { - dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "bangradar_enh_params is NULL"); + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "bangradar_params is NULL"); } break; @@ -677,16 +701,6 @@ int dfs_control(struct wlan_dfs *dfs, case DFS_SHOW_NOLHISTORY: dfs_print_nolhistory(dfs); break; - case DFS_BANGRADAR: - dfs->dfs_bangradar = 1; - if (dfs->dfs_is_offload_enabled) { - error = dfs_fill_emulate_bang_radar_test(dfs, - SEG_ID_PRIMARY, - &dfs_unit_test); - } else { - error = dfs_start_host_based_bangradar(dfs); - } - break; case DFS_SHOW_PRECAC_LISTS: dfs_print_precaclists(dfs); dfs_print_etsi_precaclists(dfs); @@ -695,16 +709,6 @@ int dfs_control(struct wlan_dfs *dfs, dfs_reset_precac_lists(dfs); dfs_reset_etsi_precac_lists(dfs); break; - case DFS_SECOND_SEGMENT_BANGRADAR: - if (dfs->dfs_is_offload_enabled) { - error = dfs_fill_emulate_bang_radar_test(dfs, - SEG_ID_SECONDARY, - &dfs_unit_test); - } else { - dfs->dfs_second_segment_bangradar = 1; - error = dfs_start_host_based_bangradar(dfs); - } - break; default: error = -EINVAL; } 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 3b73b66a96..a3e34fb7dd 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 @@ -517,18 +517,23 @@ uint8_t dfs_get_bonding_channels(struct wlan_dfs *dfs, return nchannels; } +static inline void dfs_reset_bangradar(struct wlan_dfs *dfs) +{ + dfs->dfs_bangradar_type = DFS_NO_BANGRADAR; +} + int dfs_radarevent_basic_sanity(struct wlan_dfs *dfs, struct dfs_channel *chan) { - if (!(dfs->dfs_second_segment_bangradar || - dfs_is_precac_timer_running(dfs))) + if (!(dfs->dfs_seg_id == SEG_ID_SECONDARY && + dfs_is_precac_timer_running(dfs))) if (!(WLAN_IS_PRIMARY_OR_SECONDARY_CHAN_DFS(chan))) { dfs_debug(dfs, WLAN_DEBUG_DFS2, "radar event on non-DFS chan"); if (!(dfs->dfs_is_offload_enabled)) { dfs_reset_radarq(dfs); dfs_reset_alldelaylines(dfs); - dfs->dfs_bangradar = 0; + dfs_reset_bangradar(dfs); } return 0; } @@ -559,13 +564,6 @@ int dfs_second_segment_radar_disable(struct wlan_dfs *dfs) return 0; } -static inline void dfs_reset_bangradar(struct wlan_dfs *dfs) -{ - dfs->dfs_bangradar = 0; - dfs->dfs_second_segment_bangradar = 0; - dfs->dfs_enh_bangradar = false; -} - /* dfs_prepare_nol_ie_bitmap: Create a Bitmap from the radar found subchannels * to be sent along with RCSA. * @@ -693,7 +691,6 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, QDF_STATUS status; uint32_t freq_center; uint32_t radarfound_freq; - struct dfs_channel *dfs_curchan; if (!dfs->dfs_curchan) { dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs->dfs_curchan is NULL"); @@ -719,21 +716,7 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, } dfs_compute_radar_found_cfreq(dfs, radar_found, &freq_center); - - if (dfs->dfs_bangradar || dfs->dfs_second_segment_bangradar) { - dfs_curchan = dfs->dfs_curchan; - if (radar_found->segment_id == SEG_ID_SECONDARY) - if (dfs_is_precac_timer_running(dfs)) - radarfound_freq = - dfs->dfs_precac_secondary_freq; - else - radarfound_freq = - dfs_curchan->dfs_ch_vhtop_ch_freq_seg2; - else - radarfound_freq = dfs->dfs_curchan->dfs_ch_freq; - } else { - radarfound_freq = freq_center + dfs->dfs_freq_offset; - } + radarfound_freq = freq_center + dfs->dfs_freq_offset; if (radar_found->segment_id == SEG_ID_SECONDARY) dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, @@ -752,11 +735,14 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, return QDF_STATUS_SUCCESS; } + if (dfs->dfs_bangradar_type == DFS_BANGRADAR_FOR_ALL_SUBCHANS) + num_channels = dfs_get_bonding_channels_without_seg_info( + dfs->dfs_curchan, channels); /* BW reduction is dependent on subchannel marking */ - - if ((dfs->dfs_use_nol_subchannel_marking || - (dfs->dfs_use_nol_subchannel_marking && dfs->dfs_bw_reduced)) && - !(dfs->dfs_bangradar || dfs->dfs_second_segment_bangradar)) + else if ((dfs->dfs_use_nol_subchannel_marking) && + (!(dfs->dfs_bangradar_type) || + (dfs->dfs_bangradar_type == + DFS_BANGRADAR_FOR_SPECIFIC_SUBCHANS))) num_channels = dfs_find_radar_affected_subchans(dfs, radar_found, channels, diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h b/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h index 99cdd9edfa..bd5db0a119 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_ioctl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2016-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2010, Atheros Communications Inc. * All Rights Reserved. * @@ -48,19 +48,17 @@ #define DFS_GET_CAC_VALID_TIME 20 #define DFS_SET_CAC_VALID_TIME 21 #define DFS_SHOW_NOLHISTORY 22 -#define DFS_SECOND_SEGMENT_BANGRADAR 23 -#define DFS_SHOW_PRECAC_LISTS 24 -#define DFS_RESET_PRECAC_LISTS 25 -#define DFS_BANGRADAR_ENH 26 -#define DFS_SET_DISABLE_RADAR_MARKING 27 -#define DFS_GET_DISABLE_RADAR_MARKING 28 +#define DFS_SHOW_PRECAC_LISTS 23 +#define DFS_RESET_PRECAC_LISTS 24 +#define DFS_SET_DISABLE_RADAR_MARKING 25 +#define DFS_GET_DISABLE_RADAR_MARKING 26 /* * Spectral IOCTLs use DFS_LAST_IOCTL as the base. * This must always be the last IOCTL in DFS and have * the highest value. */ -#define DFS_LAST_IOCTL 29 +#define DFS_LAST_IOCTL 27 #ifndef DFS_CHAN_MAX #define DFS_CHAN_MAX 1023 @@ -122,13 +120,40 @@ struct dfs_ioctl_params { int32_t dfs_maxlen; }; -/** - * struct dfs_bangradar_enh_params - DFS enhanced bangradr params. - * @seg_id: Segment ID information. - * @is_chirp: Chirp radar or not. - * @freq_offset: Frequency offset at which radar was found. +/* Types of Bangradar commands: + * @DFS_BANGRADAR_FOR_ALL_SUBCHANS : Bangradar with no arguments. + * All the subchannels in the current + * channel shall be added. + * @DFS_BANGRADAR_FOR_ALL_SUBCHANS_OF_SEGID : Bangradar with 1 (seg_id) argument + * All subchannels of the specific + * seg_id shall be added. + * @DFS_BANGRADAR_FOR_SPECIFIC_SUBCHANS : Bangradar with all (segment ID, + * is_chirp and frequency offset) + * arguments. + * Only radar infected subchannels + * of the specific seg_id shall be + * added. + * + * (Unless all arguments are given, we cannot determine which specific + * subchannels to simulate the radar on, hence simulate in all subchans). */ -struct dfs_bangradar_enh_params { +enum dfs_bangradar_types { + DFS_NO_BANGRADAR = 0, + DFS_BANGRADAR_FOR_ALL_SUBCHANS, + DFS_BANGRADAR_FOR_ALL_SUBCHANS_OF_SEGID, + DFS_BANGRADAR_FOR_SPECIFIC_SUBCHANS, + DFS_INVALID_BANGRADAR_TYPE +}; + +/** + * struct dfs_bangradar_params - DFS bangradar params. + * @bangradar_type: Type of Bangradar. + * @seg_id: Segment ID information. + * @is_chirp: Chirp radar or not. + * @freq_offset: Frequency offset at which radar was found. + */ +struct dfs_bangradar_params { + enum dfs_bangradar_types bangradar_type; uint8_t seg_id; uint8_t is_chirp; int32_t freq_offset;