From 38da66f0dce64886fcf008f9cf186f3a644d76a4 Mon Sep 17 00:00:00 2001 From: Priyadarshnee S Date: Wed, 9 Oct 2019 14:33:18 +0530 Subject: [PATCH] qcacmn: Add frequency APIS in DFS Core, TGT DFS and DFS Utils To avoid "channel number" collision with the introduction of 6GHZ frequency band, add frequency-based APIs to DFS Core. Also, do not remove the old IEEE channel-number-based APIs that are still referenced. The DFS APIs of Target-IF layer and DFS UTILS in DFS dispatcher layer are included as a part of this change as they invoke DFS Core APIs and are dependent. CRs-Fixed: 2526372 Change-Id: I7a00ca5796e9c81527438c326c2d41de1147ffee --- umac/dfs/core/src/dfs.h | 83 +- .../core/src/dfs_process_radar_found_ind.h | 46 + umac/dfs/core/src/dfs_random_chan_sel.h | 80 + umac/dfs/core/src/dfs_zero_cac.h | 320 ++- umac/dfs/core/src/filtering/dfs_init.c | 52 + umac/dfs/core/src/filtering/dfs_phyerr_tlv.c | 57 + .../src/filtering/dfs_process_radarevent.c | 26 +- umac/dfs/core/src/filtering/dfs_radar.c | 172 ++ umac/dfs/core/src/misc/dfs.c | 72 + umac/dfs/core/src/misc/dfs_cac.c | 205 +- umac/dfs/core/src/misc/dfs_nol.c | 215 +- .../src/misc/dfs_process_radar_found_ind.c | 414 +++- umac/dfs/core/src/misc/dfs_random_chan_sel.c | 1935 ++++++++++++----- umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c | 107 + umac/dfs/dispatcher/src/wlan_dfs_utils_api.c | 372 ++++ 15 files changed, 3421 insertions(+), 735 deletions(-) diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index 7fab5611e617..cbafe405f9aa 100644 --- a/umac/dfs/core/src/dfs.h +++ b/umac/dfs/core/src/dfs.h @@ -689,9 +689,14 @@ struct dfs_filtertype { * @dfs_ch_flags: Channel flags. * @dfs_ch_flagext: Extended channel flags. * @dfs_ch_ieee: IEEE channel number. - * @dfs_ch_vhtop_ch_freq_seg1: Channel Center frequency. - * @dfs_ch_vhtop_ch_freq_seg2: Channel Center frequency applicable for 80+80MHz - * mode of operation. + * @dfs_ch_vhtop_ch_freq_seg1: IEEE Channel Center of primary segment + * @dfs_ch_vhtop_ch_freq_seg2: IEEE Channel Center applicable for 80+80MHz + * mode of operation. + * @dfs_ch_mhz_freq_seg1: Channel center frequency of primary segment in + * MHZ. + * @dfs_ch_mhz_freq_seg2: Channel center frequency of secondary segment + * in MHZ applicable only for 80+80MHZ mode of + * operation. */ struct dfs_channel { uint16_t dfs_ch_freq; @@ -700,6 +705,8 @@ struct dfs_channel { uint8_t dfs_ch_ieee; uint8_t dfs_ch_vhtop_ch_freq_seg1; uint8_t dfs_ch_vhtop_ch_freq_seg2; + uint16_t dfs_ch_mhz_freq_seg1; + uint16_t dfs_ch_mhz_freq_seg2; }; /** @@ -934,13 +941,21 @@ struct dfs_event_log { * @dfs_precac_lock: Lock to protect precac lists. * @dfs_precac_secondary_freq: Second segment freq for precac. * Applicable to only legacy chips. + * @dfs_precac_secondary_freq_mhz: Second segment freq in MHZ for precac. + * Applicable to only legacy chips. * @dfs_precac_primary_freq: PreCAC Primary freq applicable only to * legacy chips. + * @dfs_precac_primary_freq_mhz: PreCAC Primary freq in MHZ applicable only + * to legacy chips. * @dfs_defer_precac_channel_change: Defer precac channel change. * @dfs_precac_inter_chan: Intermediate non-DFS channel used while * doing precac. + * @dfs_precac_inter_chan_freq: Intermediate non-DFS freq used while + * doing precac. * @dfs_autoswitch_des_chan: Desired channel which has to be used * after precac. + * @dfs_autoswitch_des_chan_freq: Desired freq which has to be used + * after precac. * @dfs_autoswitch_des_mode: Desired PHY mode which has to be used * after precac. * @dfs_pre_cac_timeout_channel_change: Channel change due to precac timeout. @@ -988,6 +1003,7 @@ struct dfs_event_log { * @dfs_cac_started_chan: CAC started channel. * @dfs_pdev_obj: DFS pdev object. * @dfs_is_offload_enabled: Set if DFS offload enabled. + * @dfs_agile_precac_freq_mhz: Freq in MHZ configured on Agile DFS engine. * @dfs_use_nol: Use the NOL when radar found(default: TRUE) * @dfs_nol_lock: Lock to protect nol list. * @tx_leakage_threshold: Tx leakage threshold for dfs. @@ -1090,13 +1106,28 @@ struct wlan_dfs { bool dfs_radar_found_for_fo; bool is_radar_during_precac; qdf_spinlock_t dfs_precac_lock; + bool dfs_precac_enable; +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_precac_secondary_freq; uint8_t dfs_precac_primary_freq; +#endif +#ifdef CONFIG_CHAN_FREQ_API + uint16_t dfs_precac_secondary_freq_mhz; + uint16_t dfs_precac_primary_freq_mhz; +#endif uint8_t dfs_defer_precac_channel_change; #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_precac_inter_chan; uint8_t dfs_autoswitch_des_chan; +#endif enum wlan_phymode dfs_autoswitch_des_mode; +#endif +#ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT +#ifdef CONFIG_CHAN_FREQ_API + uint16_t dfs_precac_inter_chan_freq; + uint16_t dfs_autoswitch_des_chan_freq; +#endif #endif uint8_t dfs_pre_cac_timeout_channel_change:1; qdf_timer_t wlan_dfs_task_timer; @@ -1148,7 +1179,12 @@ struct wlan_dfs { #if defined(QCA_SUPPORT_AGILE_DFS) || defined(ATH_SUPPORT_ZERO_CAC_DFS) uint8_t dfs_psoc_idx; #endif +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_agile_precac_freq; +#endif +#ifdef CONFIG_CHAN_FREQ_API + uint16_t dfs_agile_precac_freq_mhz; +#endif bool dfs_is_offload_enabled; int dfs_use_nol; qdf_spinlock_t dfs_nol_lock; @@ -1963,9 +1999,23 @@ void dfs_detach(struct wlan_dfs *dfs); * @prevchan_ieee: Prevchan number. * @prevchan_flags: Prevchan flags. */ +#ifdef CONFIG_CHAN_NUM_API void dfs_cac_valid_reset(struct wlan_dfs *dfs, uint8_t prevchan_ieee, uint32_t prevchan_flags); +#endif + +/** + * dfs_cac_valid_reset_for_freq() - Cancels the dfs_cac_valid_timer timer. + * @dfs: Pointer to wlan_dfs structure. + * @prevchan_chan: Prevchan frequency + * @prevchan_flags: Prevchan flags. + */ +#ifdef CONFIG_CHAN_FREQ_API +void dfs_cac_valid_reset_for_freq(struct wlan_dfs *dfs, + uint16_t prevchan_freq, + uint32_t prevchan_flags); +#endif /** * dfs_cac_stop() - Clear the AP CAC timer. @@ -2318,6 +2368,7 @@ static inline bool dfs_is_en302_502_applicable(struct wlan_dfs *dfs) * @dfs_ch_vhtop_ch_freq_seg1: Channel Center frequency1. * @dfs_ch_vhtop_ch_freq_seg2: Channel Center frequency2. */ +#ifdef CONFIG_CHAN_NUM_API void dfs_set_current_channel(struct wlan_dfs *dfs, uint16_t dfs_ch_freq, uint64_t dfs_ch_flags, @@ -2325,7 +2376,33 @@ void dfs_set_current_channel(struct wlan_dfs *dfs, uint8_t dfs_ch_ieee, uint8_t dfs_ch_vhtop_ch_freq_seg1, uint8_t dfs_ch_vhtop_ch_freq_seg2); +#endif +#ifdef CONFIG_CHAN_FREQ_API +/** + * dfs_set_current_channel_for_freq() - Set DFS current channel. + * @dfs: Pointer to wlan_dfs structure. + * @dfs_chan_freq: Frequency in Mhz. + * @dfs_chan_flags: Channel flags. + * @dfs_chan_flagext: Extended channel flags. + * @dfs_chan_ieee: IEEE channel number. + * @dfs_chan_vhtop_freq_seg1: Channel Center frequency1. + * @dfs_chan_vhtop_freq_seg2: Channel Center frequency2. + * @dfs_chan_mhz_freq_seg1: Channel center frequency of primary segment in MHZ. + * @dfs_chan_mhz_freq_seg2: Channel center frequency of secondary segment in MHZ + * applicable only for 80+80MHZ mode of operation. + */ +void dfs_set_current_channel_for_freq(struct wlan_dfs *dfs, + uint16_t dfs_chan_freq, + uint64_t dfs_chan_flags, + uint16_t dfs_chan_flagext, + uint8_t dfs_chan_ieee, + uint8_t dfs_chan_vhtop_freq_seg1, + uint8_t dfs_chan_vhtop_freq_seg2, + uint16_t dfs_chan_mhz_freq_seg1, + uint16_t dfs_chan_mhz_freq_seg2); + +#endif /** * dfs_get_nol_chfreq_and_chwidth() - Get channel freq and width from NOL list. * @dfs_nol: Pointer to NOL channel entry. 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 6c0b8c7cf940..d41cc034a9eb 100644 --- a/umac/dfs/core/src/dfs_process_radar_found_ind.h +++ b/umac/dfs/core/src/dfs_process_radar_found_ind.h @@ -77,12 +77,21 @@ #define LEFT_CH 1 #define RIGHT_CH 2 +#ifdef CONFIG_CHAN_NUM_API /* Next channel number offset's from center channel number */ #define DFS_5GHZ_NEXT_CHAN_OFFSET 2 #define DFS_5GHZ_2ND_CHAN_OFFSET 6 #define DFS_5GHZ_3RD_CHAN_OFFSET 10 #define DFS_5GHZ_4TH_CHAN_OFFSET 14 +#endif +#ifdef CONFIG_CHAN_FREQ_API +/* Next channel frequency offsets from center channel frequency */ +#define DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET 10 +#define DFS_5GHZ_2ND_CHAN_FREQ_OFFSET 30 +#define DFS_5GHZ_3RD_CHAN_FREQ_OFFSET 50 +#define DFS_5GHZ_4TH_CHAN_FREQ_OFFSET 70 +#endif /* Max number of bonding channels in 160 MHz segment */ #define NUM_CHANNELS_160MHZ 8 @@ -149,11 +158,32 @@ void dfs_radarfound_action_generic(struct wlan_dfs *dfs, uint8_t seg_id); * * Return: Number of channels. */ +#ifdef CONFIG_CHAN_NUM_API 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); +#endif + +/** + * dfs_get_bonding_channels_for_freq() - 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. + * @detector_id: Detector id, used to find if radar is detected on + * Agile detector. + * @freq_list: Pointer to save radar affected channel's frequency. + * + * Return: Number of channels. + */ +#ifdef CONFIG_CHAN_FREQ_API +uint8_t dfs_get_bonding_channels_for_freq(struct wlan_dfs *dfs, + struct dfs_channel *curchan, + uint32_t segment_id, + uint8_t detector_id, + uint16_t *freq_list); +#endif /** * dfs_get_bonding_channels_without_seg_info() - Get bonding channels in chan @@ -162,8 +192,24 @@ uint8_t dfs_get_bonding_channels(struct wlan_dfs *dfs, * * Return: number of sub channels in the input channel. */ +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_get_bonding_channels_without_seg_info(struct dfs_channel *chan, uint8_t *channels); +#endif + +/** + * dfs_get_bonding_channel_without_seg_info_for_freq() - Get bonding channels + * in chan. + * @chan: Pointer to dfs_channel structure. + * @freq_list: channel array holding list of bonded channel's frequency. + * + * Return: number of sub channels in the input channel. + */ +#ifdef CONFIG_CHAN_FREQ_API +uint8_t +dfs_get_bonding_channel_without_seg_info_for_freq(struct dfs_channel *chan, + uint16_t *freq_list); +#endif /** * dfs_set_nol_subchannel_marking() - Set or unset NOL subchannel marking. diff --git a/umac/dfs/core/src/dfs_random_chan_sel.h b/umac/dfs/core/src/dfs_random_chan_sel.h index 9e3d462c9bc1..5b4faa5fb39e 100644 --- a/umac/dfs/core/src/dfs_random_chan_sel.h +++ b/umac/dfs/core/src/dfs_random_chan_sel.h @@ -69,9 +69,15 @@ /* Next 5GHz channel number */ #define DFS_80_NUM_SUB_CHANNEL 4 +/* Next 5GHz channel freq offset */ +#define DFS_80_NUM_SUB_CHANNEL_FREQ 20 + /* Next 5GHz channel number */ #define DFS_NEXT_5GHZ_CHANNEL 4 +/* Next 5GHz channel number */ +#define DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET 20 + /* Number of 20MHz channels in bitmap */ #define DFS_MAX_20M_SUB_CH 8 @@ -81,6 +87,9 @@ /* Start channel and center channel diff in 80Mhz */ #define DFS_80MHZ_START_CENTER_CH_DIFF 6 +/* Start channel and center channel freq diff in 80Mhz */ +#define DFS_80MHZ_START_CENTER_CH_FREQ_DIFF 30 + /* Max number of channels */ #define DFS_MAX_NUM_CHAN 128 @@ -102,6 +111,11 @@ /* Max 2.4 GHz channel number */ #define DFS_MAX_24GHZ_CHANNEL 14 +/* Max 2.4 GHz channel frequency */ +#define DFS_MAX_24GHZ_CHANNEL_FREQ 2484 + +/* Adjacent weather radar channel frequency */ +#define DFS_ADJACENT_WEATHER_RADAR_CHANNEL_FREQ 5580 /* Max valid channel number */ #define MAX_CHANNEL_NUM 184 @@ -121,20 +135,30 @@ #endif #define DFS_IS_CHANNEL_WEATHER_RADAR(_f) (((_f) >= 5600) && ((_f) <= 5650)) +#ifdef CONFIG_CHAN_NUM_API #define DFS_IS_CHAN_JAPAN_INDOOR(_ch) (((_ch) >= 36) && ((_ch) <= 64)) #define DFS_IS_CHAN_JAPAN_W53(_ch) (((_ch) >= 52) && ((_ch) <= 64)) #define DFS_IS_CHAN_JAPAN_OUTDOOR(_ch) (((_ch) >= 100) && ((_ch) <= 140)) +#endif + +#ifdef CONFIG_CHAN_FREQ_API +#define DFS_IS_CHAN_JAPAN_INDOOR_FREQ(_ch)(((_ch) >= 5180) && ((_ch) <= 5320)) +#define DFS_IS_CHAN_JAPAN_OUTDOOR_FREQ(_ch)(((_ch) >= 5500) && ((_ch) <= 5700)) +#define DFS_IS_CHAN_JAPAN_W53_FREQ(_ch) (((_ch) >= 5260) && ((_ch) <= 5320)) +#endif /** * struct chan_bonding_info - for holding channel bonding bitmap * @chan_map: channel map * @rsvd: reserved * @start_chan: start channel + * @start_chan_freq: start channel frequency in MHZ. */ struct chan_bonding_info { uint8_t chan_map:4; uint8_t rsvd:4; uint8_t start_chan; + uint16_t start_chan_freq; }; /** @@ -154,6 +178,7 @@ struct chan_bonding_bitmap { */ struct dfs_tx_leak_info { uint8_t leak_chan; + uint16_t leak_chan_freq; uint32_t leak_lvl; }; @@ -164,6 +189,7 @@ struct dfs_tx_leak_info { */ struct dfs_matrix_tx_leak_info { uint8_t channel; + uint16_t channel_freq; struct dfs_tx_leak_info chan_matrix[CHAN_ENUM_5720 - CHAN_ENUM_5180 + 1]; }; @@ -182,10 +208,32 @@ struct dfs_matrix_tx_leak_info { * * Return: QDF_STATUS */ +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS dfs_mark_leaking_ch(struct wlan_dfs *dfs, enum phy_ch_width ch_width, uint8_t temp_ch_lst_sz, uint8_t *temp_ch_lst); +#endif + +/** + * dfs_mark_leaking_chan_for_freq() - to mark channel leaking in to nol + * @dfs: dfs handler. + * @ch_width: channel width + * @temp_chan_lst_sz: the target channel list size. + * @temp_freq_lst: the target frequency channel list + * + * This function removes the channels from temp channel list that + * (if selected as target channel) will cause leakage in one of + * the NOL channels + * + * Return: QDF_STATUS + */ +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs, + enum phy_ch_width ch_width, + uint8_t temp_chan_lst_sz, + uint16_t *temp_freq_lst); +#endif /** * dfs_prepare_random_channel() - This function picks a random channel from @@ -206,6 +254,7 @@ QDF_STATUS dfs_mark_leaking_ch(struct wlan_dfs *dfs, * * Return: channel number, else zero. */ +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs, struct dfs_channel *ch_list, uint32_t ch_count, @@ -214,3 +263,34 @@ uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs, struct dfs_channel *cur_chan, uint8_t dfs_region, struct dfs_acs_info *acs_info); +#endif + +/** + * dfs_prepare_random_channel() - This function picks a random channel from + * the list of available channels. + * @dfs: dfs handler. + * @chan_list: channel list. + * @ch_count: Number of channels in given list. + * @flags: DFS_RANDOM_CH_FLAG_* + * @chan_wd: input channel width, used same variable to return new ch width. + * @cur_chan: current channel. + * @dfs_region: DFS region. + * @acs_info: acs channel range information. + * + * Function used to find random channel selection from a given list. + * First this function removes channels based on flags and then uses final + * list to find channel based on requested bandwidth, if requested bandwidth + * not available, it chooses next lower bandwidth and try. + * + * Return: channel frequency, else zero. + */ +#ifdef CONFIG_CHAN_FREQ_API +uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs, + struct dfs_channel *ch_list, + uint32_t chan_count, + uint32_t flags, + uint8_t *chan_wd, + struct dfs_channel *cur_chan, + uint8_t dfs_region, + struct dfs_acs_info *acs_info); +#endif diff --git a/umac/dfs/core/src/dfs_zero_cac.h b/umac/dfs/core/src/dfs_zero_cac.h index aab82ccc2fdb..405916fc8f5c 100644 --- a/umac/dfs/core/src/dfs_zero_cac.h +++ b/umac/dfs/core/src/dfs_zero_cac.h @@ -34,7 +34,10 @@ #include "dfs.h" #include +#ifdef CONFIG_CHAN_NUM_API #define VHT160_IEEE_FREQ_DIFF 16 +#endif + #define OCAC_SUCCESS 0 #define OCAC_RESET 1 #define OCAC_CANCEL 2 @@ -72,7 +75,8 @@ * the precac forest maintained. * @left_child: Pointer to the left child of the node. * @right_child: Pointer to the right child of the node. - * @ch_ieee: Center channel ieee value (BSTree node key value). + * @ch_ieee: Center channel ieee value. + * @ch_freq: Center channel frequency value (BSTree node key value). * @n_caced_subchs: Number of CACed subchannels of the ch_ieee. * @n_nol_subchs: Number of subchannels of the ch_ieee in NOL. * @n_valid_subchs: Number of subchannels of the ch_ieee available (as per @@ -83,6 +87,7 @@ struct precac_tree_node { struct precac_tree_node *left_child; struct precac_tree_node *right_child; uint8_t ch_ieee; + uint16_t ch_freq; uint8_t n_caced_subchs; uint8_t n_nol_subchs; uint8_t n_valid_subchs; @@ -109,12 +114,14 @@ enum precac_chan_state { * struct dfs_precac_entry - PreCAC entry. * @pe_list: PreCAC entry. * @vht80_ch_ieee: VHT80 centre channel IEEE value. + * @vht80_ch_freq: VHT80 centre channel frequency value. * @dfs: Pointer to wlan_dfs structure. * @tree_root: Tree root node with 80MHz channel key. */ struct dfs_precac_entry { TAILQ_ENTRY(dfs_precac_entry) pe_list; uint8_t vht80_ch_ieee; + uint16_t vht80_ch_freq; struct wlan_dfs *dfs; struct precac_tree_node *tree_root; }; @@ -197,14 +204,35 @@ void dfs_init_precac_list(struct wlan_dfs *dfs); * @precac_chan: Start thr precac timer in this channel. */ #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) +#ifdef CONFIG_CHAN_NUM_API void dfs_start_precac_timer(struct wlan_dfs *dfs, uint8_t precac_chan); +#endif + +/** + * dfs_start_precac_timer() - Start precac timer. + * @dfs: Pointer to wlan_dfs structure. + * @precac_chan_freq: Frequency to start precac timer. + */ +#ifdef CONFIG_CHAN_FREQ_API +void dfs_start_precac_timer_for_freq(struct wlan_dfs *dfs, + uint16_t precac_chan_freq); +#endif #else +#ifdef CONFIG_CHAN_NUM_API static inline void dfs_start_precac_timer(struct wlan_dfs *dfs, uint8_t precac_chan) { } #endif +#ifdef CONFIG_CHAN_FREQ_API +static inline +void dfs_start_precac_timer_for_freq(struct wlan_dfs *dfs, + uint16_t precac_chan_freq) +{ +} +#endif +#endif /** * dfs_cancel_precac_timer() - Cancel the precac timer. @@ -287,17 +315,49 @@ static inline bool dfs_is_precac_done(struct wlan_dfs *dfs, * * Return: True if intermediate channel needs to configure. False otherwise. */ +#ifdef CONFIG_CHAN_NUM_API bool dfs_decide_precac_preferred_chan(struct wlan_dfs *dfs, uint8_t *pref_chan, enum wlan_phymode mode); +#endif + +/** + * dfs_decide_precac_preferred_chan_for_freq() - Choose operating channel among + * configured DFS channel and + * intermediate channel based on + * precac status of configured + * DFS channel. + * @dfs: Pointer to wlan_dfs structure. + * @pref_chan: Configured DFS channel frequency + * @mode: Configured PHY mode. + * + * Return: True if intermediate channel needs to configure. False otherwise. + */ + +#ifdef CONFIG_CHAN_FREQ_API +bool +dfs_decide_precac_preferred_chan_for_freq(struct wlan_dfs *dfs, + uint16_t *pref_chan_freq, + enum wlan_phymode mode); +#endif #else +#ifdef CONFIG_CHAN_NUM_API static inline void dfs_decide_precac_preferred_chan(struct wlan_dfs *dfs, uint8_t *pref_chan, enum wlan_phymode mode) { } #endif +#ifdef CONFIG_CHAN_FREQ_API +static inline void +dfs_decide_precac_preferred_chan_for_freq(struct wlan_dfs *dfs, + uint8_t *pref_chan, + enum wlan_phymode mode) +{ +} +#endif +#endif /** * dfs_get_ieeechan_for_precac() - Get chan of required bandwidth from @@ -307,10 +367,27 @@ static inline void dfs_decide_precac_preferred_chan(struct wlan_dfs *dfs, * @exclude_sec_ch_ieee: Secondary channel IEEE to be excluded for preCAC. * @bandwidth: Bandwidth of requested channel. */ +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_get_ieeechan_for_precac(struct wlan_dfs *dfs, uint8_t exclude_pri_ch_ieee, uint8_t exclude_sec_ch_ieee, uint8_t bandwidth); +#endif + +/** + * dfs_get_ieeechan_for_precac_for_freq() - Get chan of required bandwidth from + * precac_list. + * @dfs: Pointer to wlan_dfs structure. + * @exclude_pri_chan_freq: Primary channel freq to be excluded for preCAC. + * @exclude_sec_chan_freq: Secondary channel freq to be excluded for preCAC. + * @bandwidth: Bandwidth of requested channel. + */ +#ifdef CONFIG_CHAN_FREQ_API +uint16_t dfs_get_ieeechan_for_precac_for_freq(struct wlan_dfs *dfs, + uint16_t exclude_pri_chan_freq, + uint16_t exclude_sec_chan_freq, + uint8_t bandwidth); +#endif /** * dfs_override_precac_timeout() - Override the default precac timeout. @@ -380,6 +457,7 @@ static inline int dfs_get_override_precac_timeout(struct wlan_dfs *dfs, * exhausted the VHT80_80/VHT160 comes back to VHT80 mode. */ #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) +#ifdef CONFIG_CHAN_NUM_API void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs, uint32_t chan_mode, uint8_t ch_freq_seg1, @@ -388,7 +466,32 @@ void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs, uint32_t *phy_mode, bool *dfs_set_cfreq2, bool *set_agile); +#endif + +/* + * dfs_find_vht80_chan_for_precac() - Find VHT80 channel for precac. + * @dfs: Pointer to wlan_dfs structure. + * @chan_mode: Channel mode. + * @ch_freq_seg1: Segment1 channel freq in mhz. + * @cfreq1: cfreq1. + * @cfreq2: cfreq2. + * @phy_mode: Precac phymode. + * @dfs_set_cfreq2: Precac cfreq2 + * @set_agile: Agile mode flag. + */ +#ifdef CONFIG_CHAN_FREQ_API +void dfs_find_vht80_chan_for_precac_for_freq(struct wlan_dfs *dfs, + uint32_t chan_mode, + uint16_t ch_freq_seg1_mhz, + uint32_t *cfreq1, + uint32_t *cfreq2, + uint32_t *phy_mode, + bool *dfs_set_cfreq2, + bool *set_agile); +#endif + #else +#ifdef CONFIG_CHAN_NUM_API static inline void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs, uint32_t chan_mode, uint8_t ch_freq_seg1, @@ -401,6 +504,21 @@ static inline void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs, } #endif +#ifdef CONFIG_CHAN_FREQ_API +static inline +void dfs_find_vht80_chan_for_precac_for_freq(struct wlan_dfs *dfs, + uint32_t chan_mode, + uint16_t ch_freq_seg1_mhz, + uint32_t *cfreq1, + uint32_t *cfreq2, + uint32_t *phy_mode, + bool *dfs_set_cfreq2, + bool *set_agile) +{ +} +#endif +#endif + #if defined(QCA_SUPPORT_AGILE_DFS) /** * dfs_find_pdev_for_agile_precac() - Find pdev to select channel for precac. @@ -436,10 +554,30 @@ void dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev, * Find an IEEE channel for agileCAC which is not the current operating * channels (indicated by pri_ch_ieee, sec_ch_ieee). */ +#ifdef CONFIG_CHAN_NUM_API void dfs_get_ieeechan_for_agilecac(struct wlan_dfs *dfs, uint8_t *ch_ieee, uint8_t pri_ch_ieee, uint8_t sec_ch_ieee); +#endif + +/** + * dfs_get_ieeechan_for_agilecac_for_freq() - Find chan freq for agile CAC. + * @dfs: Pointer to wlan_dfs structure. + * @chan_freq: Pointer to channel freq for agile set request. + * @pri_chan_freq: Current primary IEEE channel freq. + * @sec_chan_freq: Current secondary IEEE channel freq (in HT80_80 mode). + * + * Find an IEEE channel freq for agileCAC which is not the current operating + * channels (indicated by pri_chan_freq, sec_chan_freq). + */ +#ifdef CONFIG_CHAN_FREQ_API +void dfs_get_ieeechan_for_agilecac_for_freq(struct wlan_dfs *dfs, + uint16_t *chan_freq, + uint16_t pri_chan_freq, + uint16_t sec_chan_freq); +#endif + /** * dfs_agile_precac_start() - Start agile precac. * @dfs: Pointer to wlan_dfs structure. @@ -489,12 +627,24 @@ dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev, { } +#ifdef CONFIG_CHAN_NUM_API static inline void dfs_get_ieeechan_for_agilecac(struct wlan_dfs *dfs, uint8_t *ch_ieee, uint8_t pri_ch_ieee, uint8_t sec_ch_ieee) { } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +static inline void +dfs_get_ieeechan_for_agilecac_for_freq(struct wlan_dfs *dfs, + uint16_t *chan_freq, + uint16_t pri_chan_freq, + uint16_t sec_chan_freq) +{ +} +#endif static inline void dfs_agile_precac_start(struct wlan_dfs *dfs) { @@ -633,7 +783,22 @@ static inline uint32_t dfs_get_intermediate_chan(struct wlan_dfs *dfs) */ enum precac_chan_state dfs_get_precac_chan_state(struct wlan_dfs *dfs, uint8_t precac_chan); + +/** + * dfs_get_precac_chan_state_for_freq() - Get precac status of a given channel. + * @dfs: Pointer to wlan_dfs structure. + * @precac_chan: Channel freq for which precac state need to be checked. + */ + +#ifdef CONFIG_CHAN_FREQ_API +enum precac_chan_state +dfs_get_precac_chan_state_for_freq(struct wlan_dfs *dfs, + uint16_t precac_chan_freq); +#endif + #else + +#ifdef CONFIG_CHAN_NUM_API static inline enum precac_chan_state dfs_get_precac_chan_state(struct wlan_dfs *dfs, uint8_t precac_chan) @@ -642,6 +807,16 @@ dfs_get_precac_chan_state(struct wlan_dfs *dfs, } #endif +#ifdef CONFIG_CHAN_FREQ_API +static inline enum precac_chan_state +dfs_get_precac_chan_state_for_freq(struct wlan_dfs *dfs, + uint16_t precac_chan_freq) +{ + return PRECAC_REQUIRED; +} +#endif +#endif + /** * dfs_zero_cac_reset() - Reset Zero cac DFS variables. * @dfs: Pointer to wlan_dfs structure. @@ -658,8 +833,25 @@ void dfs_zero_cac_reset(struct wlan_dfs *dfs); * * True: If CAC is done on channel. * * False: If CAC is not done on channel. */ +#ifdef CONFIG_CHAN_NUM_API bool dfs_is_precac_done_on_ht20_40_80_chan(struct wlan_dfs *dfs, uint8_t chan); +#endif + +/** + * dfs_is_precac_done_on_ht20_40_80_chan_for_freq() - Is precac done on a + * VHT20/40/80 channel. + *@dfs: Pointer to wlan_dfs structure. + *@chan: Channel frequency + * + * Return: + * * True: If CAC is done on channel. + * * False: If CAC is not done on channel. + */ +#ifdef CONFIG_CHAN_FREQ_API +bool dfs_is_precac_done_on_ht20_40_80_chan_for_freq(struct wlan_dfs *dfs, + uint16_t chan_freq); +#endif /** * dfs_is_precac_done_on_ht8080_ht160_chan() - Is precac done on @@ -685,11 +877,30 @@ bool dfs_is_precac_done_on_ht8080_ht160_chan(struct wlan_dfs *dfs, * @primary_chan_ieee: Primary IEEE channel. * @secondary_chan_ieee: Secondary IEEE channel (in HT80_80 mode). */ +#ifdef CONFIG_CHAN_NUM_API void dfs_find_chwidth_and_center_chan(struct wlan_dfs *dfs, enum phy_ch_width *chwidth, uint8_t *primary_chan_ieee, uint8_t *secondary_chan_ieee); +#endif + +#ifdef CONFIG_CHAN_FREQ_API +/** + * dfs_find_chwidth_and_center_chan_for_freq() - Find the channel width enum and + * primary and secondary center channel + * value of the current channel. + * @dfs: Pointer to wlan_dfs structure. + * @chwidth: Channel width enum of current channel. + * @primary_chan_freq: Primary IEEE channel freq. + * @secondary_chan_freq: Secondary IEEE channel freq (in HT80_80 mode). + */ +void dfs_find_chwidth_and_center_chan_for_freq(struct wlan_dfs *dfs, + enum phy_ch_width *chwidth, + uint16_t *primary_chan_freq, + uint16_t *secondary_chan_freq); +#endif + /** * dfs_mark_precac_done() - Mark the channel as preCAC done. * @dfs: Pointer to wlan_dfs structure. @@ -697,10 +908,26 @@ void dfs_find_chwidth_and_center_chan(struct wlan_dfs *dfs, * @sec_ch_ieee: Secondary channel IEEE (only in HT80_80 mode). * @ch_width: Channel width enum. */ +#ifdef CONFIG_CHAN_NUM_API void dfs_mark_precac_done(struct wlan_dfs *dfs, uint8_t pri_ch_ieee, uint8_t sec_ch_ieee, enum phy_ch_width ch_width); +#endif + +#ifdef CONFIG_CHAN_FREQ_API +/** + * dfs_mark_precac_done_for_freq() - Mark the channel as preCAC done. + * @dfs: Pointer to wlan_dfs structure. + * @pri_chan_freq: Primary channel IEEE freq. + * @sec_chan_freq: Secondary channel IEEE freq(only in HT80_80 mode). + * @chan_width: Channel width enum. + */ +void dfs_mark_precac_done_for_freq(struct wlan_dfs *dfs, + uint16_t pri_chan_freq, + uint16_t sec_chan_freq, + enum phy_ch_width chan_width); +#endif /** * dfs_mark_precac_nol() - Mark the precac channel as radar. @@ -710,20 +937,50 @@ void dfs_mark_precac_done(struct wlan_dfs *dfs, * @channels: Array of radar found subchannels. * @num_channels: Number of radar found subchannels. */ +#ifdef CONFIG_CHAN_NUM_API void dfs_mark_precac_nol(struct wlan_dfs *dfs, uint8_t is_radar_found_on_secondary_seg, uint8_t detector_id, uint8_t *channels, uint8_t num_channels); +#endif + +/** + * dfs_mark_precac_nol_for_freq() - Mark the precac channel as radar. + * @dfs: Pointer to wlan_dfs structure. + * @is_radar_found_on_secondary_seg: Radar found on secondary seg for Cascade. + * @detector_id: detector id which found RADAR in HW. + * @freq_list: Array of radar found frequencies. + * @num_channels: Number of radar found subchannels. + */ +#ifdef CONFIG_CHAN_FREQ_API +void dfs_mark_precac_nol_for_freq(struct wlan_dfs *dfs, + uint8_t is_radar_found_on_secondary_seg, + uint8_t detector_id, + uint16_t *freq_list, + uint8_t num_channels); +#endif /** * dfs_unmark_precac_nol() - Unmark the precac channel as radar. * @dfs: Pointer to wlan_dfs structure. * @channel: channel marked as radar. */ +#ifdef CONFIG_CHAN_NUM_API void dfs_unmark_precac_nol(struct wlan_dfs *dfs, uint8_t channel); +#endif + +/** + * dfs_unmark_precac_nol_for_freq() - Unmark the precac channel as radar. + * @dfs: Pointer to wlan_dfs structure. + * @channel: channel freq marked as radar. + */ +#ifdef CONFIG_CHAN_FREQ_API +void dfs_unmark_precac_nol_for_freq(struct wlan_dfs *dfs, uint16_t chan_freq); +#endif #else +#ifdef CONFIG_CHAN_NUM_API static inline void dfs_find_chwidth_and_center_chan(struct wlan_dfs *dfs, enum phy_ch_width *chwidth, @@ -731,14 +988,37 @@ dfs_find_chwidth_and_center_chan(struct wlan_dfs *dfs, uint8_t *secondary_chan_ieee) { } +#endif +#ifdef CONFIG_CHAN_FREQ_API +static inline void +dfs_find_chwidth_and_center_chan_for_freq(struct wlan_dfs *dfs, + enum phy_ch_width *chwidth, + uint16_t *primary_chan_freq, + uint16_t *secondary_chan_freq) +{ +} +#endif + +#ifdef CONFIG_CHAN_NUM_API static inline void dfs_mark_precac_done(struct wlan_dfs *dfs, uint8_t pri_ch_ieee, uint8_t sec_ch_ieee, enum phy_ch_width ch_width) { } +#endif +#ifdef CONFIG_CHAN_FREQ_API +static inline void dfs_mark_precac_done_for_freq(struct wlan_dfs *dfs, + uint16_t pri_chan_freq, + uint16_t sec_chan_freq, + enum phy_ch_width chan_width) +{ +} +#endif + +#ifdef CONFIG_CHAN_NUM_API static inline void dfs_mark_precac_nol(struct wlan_dfs *dfs, uint8_t is_radar_found_on_secondary_seg, uint8_t detector_id, @@ -746,12 +1026,33 @@ static inline void dfs_mark_precac_nol(struct wlan_dfs *dfs, uint8_t num_channels) { } +#endif +#ifdef CONFIG_CHAN_FREQ_API +static inline void +dfs_mark_precac_nol_for_freq(struct wlan_dfs *dfs, + uint8_t is_radar_found_on_secondary_seg, + uint8_t detector_id, + uint16_t *freq, + uint8_t num_channels) +{ +} +#endif + +#ifdef CONFIG_CHAN_NUM_API static inline void dfs_unmark_precac_nol(struct wlan_dfs *dfs, uint8_t channel) { } #endif +#ifdef CONFIG_CHAN_FREQ_API +static inline void dfs_unmark_precac_nol_for_freq(struct wlan_dfs *dfs, + uint16_t chan_freq) +{ +} +#endif +#endif + /** * dfs_is_precac_timer_running() - Check whether precac timer is running. * @dfs: Pointer to wlan_dfs structure. @@ -764,4 +1065,21 @@ static inline bool dfs_is_precac_timer_running(struct wlan_dfs *dfs) return false; } #endif + +#ifdef CONFIG_CHAN_FREQ_API +#define VHT160_FREQ_DIFF 80 + +#define INITIAL_20_CHAN_FREQ_OFFSET -30 +#define INITIAL_40_CHAN_FREQ_OFFSET -20 +#define INITIAL_80_CHAN_FREQ_OFFSET 0 + +#define NEXT_20_CHAN_FREQ_OFFSET 20 +#define NEXT_40_CHAN_FREQ_OFFSET 40 +#define NEXT_80_CHAN_FREQ_OFFSET 80 + +#define WEATHER_CHAN_START_FREQ 5600 +#define WEATHER_CHAN_END_FREQ 5640 + +#endif + #endif /* _DFS_ZERO_CAC_H_ */ diff --git a/umac/dfs/core/src/filtering/dfs_init.c b/umac/dfs/core/src/filtering/dfs_init.c index a3b9516c336d..b5eaa3f40c14 100644 --- a/umac/dfs/core/src/filtering/dfs_init.c +++ b/umac/dfs/core/src/filtering/dfs_init.c @@ -431,6 +431,56 @@ int dfs_check_etsi_overlap(int center_freq, int chan_width, chan_freq_high)); } +#ifdef CONFIG_CHAN_FREQ_API +bool dfs_is_en302_502_applicable(struct wlan_dfs *dfs) +{ + int chan_freq; + int chan_width; + int overlap = 0; + struct wlan_objmgr_vdev *vdev = NULL; + struct wlan_channel *bss_chan = NULL; + + /* Get centre frequency */ + chan_freq = dfs->dfs_curchan->dfs_ch_mhz_freq_seg1; + vdev = wlan_objmgr_pdev_get_first_vdev(dfs->dfs_pdev_obj, WLAN_DFS_ID); + if (!vdev) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "vdev is NULL"); + return false; + } + + bss_chan = wlan_vdev_mlme_get_bss_chan(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_DFS_ID); + /* Grab width */ + chan_width = wlan_reg_get_bw_value(bss_chan->ch_width); + + if (WLAN_IS_CHAN_11AC_VHT80_80(dfs->dfs_curchan)) { + /* HT80_80 mode has 2 segments and each segment must + * be checked for control channel first. + */ + overlap = dfs_check_etsi_overlap( + chan_freq, chan_width / 2, + ETSI_RADAR_EN302_502_FREQ_LOWER, + ETSI_RADAR_EN302_502_FREQ_UPPER); + + /* check for extension channel */ + chan_freq = dfs->dfs_curchan->dfs_ch_mhz_freq_seg2; + + overlap += dfs_check_etsi_overlap( + chan_freq, chan_width / 2, + ETSI_RADAR_EN302_502_FREQ_LOWER, + ETSI_RADAR_EN302_502_FREQ_UPPER); + } else { + overlap = dfs_check_etsi_overlap( + chan_freq, chan_width, + ETSI_RADAR_EN302_502_FREQ_LOWER, + ETSI_RADAR_EN302_502_FREQ_UPPER); + } + + return(wlan_reg_is_regdmn_en302502_applicable(dfs->dfs_pdev_obj) && + overlap); +} +#else +#ifdef CONFIG_CHAN_NUM_API bool dfs_is_en302_502_applicable(struct wlan_dfs *dfs) { int chan_freq; @@ -480,3 +530,5 @@ bool dfs_is_en302_502_applicable(struct wlan_dfs *dfs) return(wlan_reg_is_regdmn_en302502_applicable(dfs->dfs_pdev_obj) && overlap); } +#endif +#endif diff --git a/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c b/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c index dec1a74bfe75..d67ea476962c 100644 --- a/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c +++ b/umac/dfs/core/src/filtering/dfs_phyerr_tlv.c @@ -445,6 +445,60 @@ static int dfs_tlv_parse_frame(struct wlan_dfs *dfs, * * Return: Returns the channel center. */ +#ifdef CONFIG_CHAN_FREQ_API +static int dfs_tlv_calc_freq_info(struct wlan_dfs *dfs, + struct rx_radar_status *rs) +{ + uint32_t chan_centre; + uint32_t chan_width; + int chan_offset; + + /* For now, just handle up to VHT80 correctly. */ + if (!dfs->dfs_curchan) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_curchan is null"); + return 0; + /* + * For now, the only 11ac channel with freq1/freq2 setup is + * VHT80. Should have a flag macro to check this! + */ + } else if (WLAN_IS_CHAN_11AC_VHT80(dfs->dfs_curchan)) { + /* + * 11AC, so cfreq1/cfreq2 are setup. + * If it's 80+80 this won't work - need to use seg + * appropriately! + */ + chan_centre = dfs->dfs_curchan->dfs_ch_mhz_freq_seg1; + } else { + /* + * HT20/HT40. + * This is hard-coded - it should be 5 or 10 for half/quarter + * appropriately. + */ + chan_width = 20; + + /* Grab default channel centre. */ + chan_centre = dfs->dfs_curchan->dfs_ch_freq; + + /* Calculate offset based on HT40U/HT40D and VHT40U/VHT40D. */ + if (WLAN_IS_CHAN_11N_HT40PLUS(dfs->dfs_curchan) || + (dfs->dfs_curchan->dfs_ch_flags & WLAN_CHAN_VHT40PLUS)) + chan_offset = chan_width; + else if (WLAN_IS_CHAN_11N_HT40MINUS(dfs->dfs_curchan) || + (dfs->dfs_curchan->dfs_ch_flags & + WLAN_CHAN_VHT40MINUS)) + chan_offset = -chan_width; + else + chan_offset = 0; + + /* Calculate new _real_ channel centre. */ + chan_centre += (chan_offset / 2); + } + + /* Return ev_chan_centre in MHz. */ + return chan_centre; +} +#else +#ifdef CONFIG_CHAN_NUM_API static int dfs_tlv_calc_freq_info(struct wlan_dfs *dfs, struct rx_radar_status *rs) { @@ -499,6 +553,9 @@ static int dfs_tlv_calc_freq_info(struct wlan_dfs *dfs, /* Return ev_chan_centre in MHz. */ return chan_centre; } +#endif +#endif + /** * dfs_tlv_calc_event_freq_pulse() - Calculate the centre frequency and diff --git a/umac/dfs/core/src/filtering/dfs_process_radarevent.c b/umac/dfs/core/src/filtering/dfs_process_radarevent.c index eab6ad0fc616..d63b98db9857 100644 --- a/umac/dfs/core/src/filtering/dfs_process_radarevent.c +++ b/umac/dfs/core/src/filtering/dfs_process_radarevent.c @@ -576,6 +576,28 @@ static inline void dfs_radarfound_reset_vars( } } +/* + * dfs_print_radar_found_freq() - Print radar found frequency. + * @dfs: Pointer to wlan_dfs. + */ +#ifdef CONFIG_CHAN_FREQ_API +static void dfs_print_radar_found_freq(struct wlan_dfs *dfs) +{ + dfs_debug(dfs, WLAN_DEBUG_DFS, + "bangradar on 2nd segment cfreq = %u", + dfs->dfs_precac_secondary_freq_mhz); +} +#else +#ifdef CONFIG_CHAN_NUM_API +static void dfs_print_radar_found_freq(struct wlan_dfs *dfs) +{ + dfs_debug(dfs, WLAN_DEBUG_DFS, + "bangradar on 2nd segment cfreq = %u", + dfs->dfs_precac_secondary_freq); +} +#endif +#endif + /** * dfs_handle_bangradar - Handle the case of bangradar * @dfs: Pointer to wlan_dfs structure. @@ -608,9 +630,7 @@ static inline int dfs_handle_bangradar( 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); + dfs_print_radar_found_freq(dfs); } else { dfs_debug(dfs, WLAN_DEBUG_DFS, "No second segment"); diff --git a/umac/dfs/core/src/filtering/dfs_radar.c b/umac/dfs/core/src/filtering/dfs_radar.c index 922a33a16213..fae38b0cd719 100644 --- a/umac/dfs/core/src/filtering/dfs_radar.c +++ b/umac/dfs/core/src/filtering/dfs_radar.c @@ -61,6 +61,80 @@ void dfs_phyerr_param_copy(struct wlan_dfs_phyerr_param *dst, qdf_mem_copy(dst, src, sizeof(*dst)); } +#ifdef CONFIG_CHAN_FREQ_API +struct dfs_state *dfs_getchanstate(struct wlan_dfs *dfs, uint8_t *index, + int ext_chan_flag) +{ + struct dfs_state *rs = NULL; + struct dfs_channel *ch, cmp_ch1; + int i; + QDF_STATUS err; + + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return NULL; + } + ch = &cmp_ch1; + if (ext_chan_flag) { + err = dfs_mlme_get_extchan_for_freq( + dfs->dfs_pdev_obj, + &ch->dfs_ch_freq, + &ch->dfs_ch_flags, + &ch->dfs_ch_flagext, + &ch->dfs_ch_ieee, + &ch->dfs_ch_vhtop_ch_freq_seg1, + &ch->dfs_ch_vhtop_ch_freq_seg2, + &ch->dfs_ch_mhz_freq_seg1, + &ch->dfs_ch_mhz_freq_seg2); + + if (err == QDF_STATUS_SUCCESS) { + dfs_debug(dfs, WLAN_DEBUG_DFS2, + "Extension channel freq = %u flags=0x%x", + ch->dfs_ch_freq, + ch->dfs_ch_flagext); + } else { + return NULL; + } + } else { + ch = dfs->dfs_curchan; + dfs_debug(dfs, WLAN_DEBUG_DFS2, + "Primary channel freq = %u flags=0x%x", + ch->dfs_ch_freq, ch->dfs_ch_flagext); + } + + for (i = 0; i < DFS_NUM_RADAR_STATES; i++) { + if ((dfs->dfs_radar[i].rs_chan.dfs_ch_freq == + ch->dfs_ch_freq) && + (dfs->dfs_radar[i].rs_chan.dfs_ch_flags == + ch->dfs_ch_flags)) { + if (index) + *index = (uint8_t)i; + return &dfs->dfs_radar[i]; + } + } + /* No existing channel found, look for first free channel state entry.*/ + for (i = 0; i < DFS_NUM_RADAR_STATES; i++) { + if (dfs->dfs_radar[i].rs_chan.dfs_ch_freq == 0) { + rs = &dfs->dfs_radar[i]; + /* Found one, set channel info and default thresholds.*/ + rs->rs_chan = *ch; + + /* Copy the parameters from the default set. */ + dfs_phyerr_param_copy(&rs->rs_param, + &dfs->dfs_defaultparams); + + if (index) + *index = (uint8_t)i; + + return rs; + } + } + dfs_debug(dfs, WLAN_DEBUG_DFS2, "No more radar states left."); + + return NULL; +} +#else +#ifdef CONFIG_CHAN_NUM_API struct dfs_state *dfs_getchanstate(struct wlan_dfs *dfs, uint8_t *index, int ext_chan_flag) { @@ -129,7 +203,103 @@ struct dfs_state *dfs_getchanstate(struct wlan_dfs *dfs, uint8_t *index, return NULL; } +#endif +#endif +#ifdef CONFIG_CHAN_FREQ_API +void dfs_radar_enable(struct wlan_dfs *dfs, int no_cac, uint32_t opmode) +{ + int is_ext_ch; + int is_fastclk = 0; + struct dfs_channel *exch, extchan; + QDF_STATUS err = QDF_STATUS_E_FAILURE; + + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + is_ext_ch = WLAN_IS_CHAN_11N_HT40(dfs->dfs_curchan); + lmac_dfs_disable(dfs->dfs_pdev_obj, no_cac); + /* + * In all modes, if the primary is DFS then we have to + * enable radar detection. In HT80_80, we can have + * primary non-DFS 80MHz with extension 80MHz DFS. + */ + if ((WLAN_IS_CHAN_DFS(dfs->dfs_curchan) || + ((WLAN_IS_CHAN_11AC_VHT160(dfs->dfs_curchan) || + WLAN_IS_CHAN_11AC_VHT80_80(dfs->dfs_curchan)) && + WLAN_IS_CHAN_DFS_CFREQ2(dfs->dfs_curchan))) || + (dfs_is_precac_timer_running(dfs))) { + struct dfs_state *rs_pri = NULL, *rs_ext = NULL; + uint8_t index_pri, index_ext; + + dfs->dfs_proc_phyerr |= DFS_AR_EN; + dfs->dfs_proc_phyerr |= DFS_RADAR_EN; + dfs->dfs_proc_phyerr |= DFS_SECOND_SEGMENT_RADAR_EN; + + exch = &extchan; + if (is_ext_ch) { + err = dfs_mlme_get_extchan_for_freq + ( + dfs->dfs_pdev_obj, + &exch->dfs_ch_freq, + &exch->dfs_ch_flags, + &exch->dfs_ch_flagext, + &exch->dfs_ch_ieee, + &exch->dfs_ch_vhtop_ch_freq_seg1, + &exch->dfs_ch_vhtop_ch_freq_seg2, + &exch->dfs_ch_mhz_freq_seg1, + &exch->dfs_ch_mhz_freq_seg2); + } + dfs_reset_alldelaylines(dfs); + + rs_pri = dfs_getchanstate(dfs, &index_pri, 0); + if (err == QDF_STATUS_SUCCESS) + rs_ext = dfs_getchanstate(dfs, &index_ext, 1); + + if (rs_pri && ((err == QDF_STATUS_E_FAILURE) || (rs_ext))) { + struct wlan_dfs_phyerr_param pe; + + qdf_mem_set(&pe, sizeof(pe), '\0'); + + if (index_pri != dfs->dfs_curchan_radindex) + dfs_reset_alldelaylines(dfs); + + dfs->dfs_curchan_radindex = (int16_t)index_pri; + + if (rs_ext) + dfs->dfs_extchan_radindex = (int16_t)index_ext; + + dfs_phyerr_param_copy(&pe, &rs_pri->rs_param); + dfs_debug(dfs, WLAN_DEBUG_DFS3, + "firpwr=%d, rssi=%d, height=%d, prssi=%d, inband=%d, relpwr=%d, relstep=%d, maxlen=%d", + pe.pe_firpwr, + pe.pe_rrssi, pe.pe_height, + pe.pe_prssi, pe.pe_inband, + pe.pe_relpwr, pe.pe_relstep, + pe.pe_maxlen); + + lmac_dfs_enable(dfs->dfs_pdev_obj, &is_fastclk, + &pe, dfs->dfsdomain); + dfs_debug(dfs, WLAN_DEBUG_DFS, + "Enabled radar detection on channel %d", + dfs->dfs_curchan->dfs_ch_freq); + + dfs->dur_multiplier = is_fastclk ? + DFS_FAST_CLOCK_MULTIPLIER : + DFS_NO_FAST_CLOCK_MULTIPLIER; + + dfs_debug(dfs, WLAN_DEBUG_DFS3, + "duration multiplier is %d", + dfs->dur_multiplier); + } else + dfs_debug(dfs, WLAN_DEBUG_DFS, + "No more radar states left"); + } +} +#else +#ifdef CONFIG_CHAN_NUM_API void dfs_radar_enable(struct wlan_dfs *dfs, int no_cac, uint32_t opmode) { int is_ext_ch; @@ -220,6 +390,8 @@ void dfs_radar_enable(struct wlan_dfs *dfs, int no_cac, uint32_t opmode) "No more radar states left"); } } +#endif +#endif int dfs_set_thresholds(struct wlan_dfs *dfs, const uint32_t threshtype, const uint32_t value) diff --git a/umac/dfs/core/src/misc/dfs.c b/umac/dfs/core/src/misc/dfs.c index 33f7c6331602..a1abe7ff9331 100644 --- a/umac/dfs/core/src/misc/dfs.c +++ b/umac/dfs/core/src/misc/dfs.c @@ -122,6 +122,28 @@ static inline void dfs_free_dfs_chan(struct dfs_channel *dfs_chan) * channel as RADAR and does not add the channel to NOL. It sends the CSA in * the current channel. */ +#ifdef CONFIG_CHAN_FREQ_API +static os_timer_func(dfs_testtimer_task) +{ + struct wlan_dfs *dfs = NULL; + + OS_GET_TIMER_ARG(dfs, struct wlan_dfs *); + dfs->wlan_dfstest = 0; + + /* + * Flip the channel back to the original channel. + * Make sure this is done properly with a CSA. + */ + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "go back to channel %d", + dfs->wlan_dfstest_ieeechan); + dfs_mlme_start_csa_for_freq(dfs->dfs_pdev_obj, + dfs->wlan_dfstest_ieeechan, + dfs->dfs_curchan->dfs_ch_freq, + dfs->dfs_curchan->dfs_ch_mhz_freq_seg2, + dfs->dfs_curchan->dfs_ch_flags); +} +#else +#ifdef CONFIG_CHAN_NUM_API static os_timer_func(dfs_testtimer_task) { struct wlan_dfs *dfs = NULL; @@ -141,6 +163,8 @@ static os_timer_func(dfs_testtimer_task) dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2, dfs->dfs_curchan->dfs_ch_flags); } +#endif +#endif int dfs_get_debug_info(struct wlan_dfs *dfs, void *data) { @@ -780,6 +804,7 @@ dfs_is_curchan_same_as_given_chan(struct dfs_channel *dfs_curchan, return false; } +#ifdef CONFIG_CHAN_NUM_API void dfs_set_current_channel(struct wlan_dfs *dfs, uint16_t dfs_ch_freq, uint64_t dfs_ch_flags, @@ -823,6 +848,53 @@ void dfs_set_current_channel(struct wlan_dfs *dfs, dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg1 = dfs_ch_vhtop_ch_freq_seg1; dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2 = dfs_ch_vhtop_ch_freq_seg2; } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +void dfs_set_current_channel_for_freq(struct wlan_dfs *dfs, + uint16_t dfs_chan_freq, + uint64_t dfs_chan_flags, + uint16_t dfs_chan_flagext, + uint8_t dfs_chan_ieee, + uint8_t dfs_chan_vhtop_freq_seg1, + uint8_t dfs_chan_vhtop_freq_seg2, + uint16_t dfs_chan_mhz_freq_seg1, + uint16_t dfs_chan_mhz_freq_seg2) + +{ + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + /* Check if the input parameters are the same as that of dfs_curchan */ + if (dfs_is_curchan_same_as_given_chan(dfs->dfs_curchan, + dfs_chan_freq, + dfs_chan_flags, + dfs_chan_flagext, + dfs_chan_vhtop_freq_seg1, + dfs_chan_vhtop_freq_seg2)) { + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, + "dfs_curchan already updated"); + return; + } + + /* Update dfs previous channel with the old dfs_curchan, if it exists */ + if (dfs->dfs_curchan->dfs_ch_freq) + qdf_mem_copy(dfs->dfs_prevchan, + dfs->dfs_curchan, + sizeof(struct dfs_channel)); + + dfs->dfs_curchan->dfs_ch_freq = dfs_chan_freq; + dfs->dfs_curchan->dfs_ch_flags = dfs_chan_flags; + dfs->dfs_curchan->dfs_ch_flagext = dfs_chan_flagext; + dfs->dfs_curchan->dfs_ch_ieee = dfs_chan_ieee; + dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg1 = dfs_chan_vhtop_freq_seg1; + dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2 = dfs_chan_vhtop_freq_seg2; + dfs->dfs_curchan->dfs_ch_mhz_freq_seg1 = dfs_chan_mhz_freq_seg1; + dfs->dfs_curchan->dfs_ch_mhz_freq_seg2 = dfs_chan_mhz_freq_seg2; +} +#endif void dfs_update_cur_chan_flags(struct wlan_dfs *dfs, uint64_t flags, diff --git a/umac/dfs/core/src/misc/dfs_cac.c b/umac/dfs/core/src/misc/dfs_cac.c index 31808c9c3857..7f35ea90ce6d 100644 --- a/umac/dfs/core/src/misc/dfs_cac.c +++ b/umac/dfs/core/src/misc/dfs_cac.c @@ -64,6 +64,7 @@ int dfs_get_override_cac_timeout(struct wlan_dfs *dfs, int *cac_timeout) return 0; } +#ifdef CONFIG_CHAN_NUM_API void dfs_cac_valid_reset(struct wlan_dfs *dfs, uint8_t prevchan_ieee, uint32_t prevchan_flags) @@ -79,6 +80,24 @@ void dfs_cac_valid_reset(struct wlan_dfs *dfs, } } } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +void dfs_cac_valid_reset_for_freq(struct wlan_dfs *dfs, + uint16_t prevchan_freq, + uint32_t prevchan_flags) +{ + if (dfs->dfs_cac_valid_time) { + if ((prevchan_freq != dfs->dfs_curchan->dfs_ch_freq) || + (prevchan_flags != dfs->dfs_curchan->dfs_ch_flags)) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, + "Cancelling timer & clearing cac_valid"); + qdf_timer_stop(&dfs->dfs_cac_valid_timer); + dfs->dfs_cac_valid = 0; + } + } +} +#endif /** * dfs_cac_valid_timeout() - Timeout function for dfs_cac_valid_timer @@ -108,6 +127,76 @@ static void dfs_clear_cac_started_chan(struct wlan_dfs *dfs) * * Sets dfs_cac_timer_running to 0 and dfs_cac_valid_timer. */ +#ifdef CONFIG_CHAN_FREQ_API +static os_timer_func(dfs_cac_timeout) +{ + struct wlan_dfs *dfs = NULL; + enum phy_ch_width ch_width = CH_WIDTH_INVALID; + uint16_t primary_chan_freq = 0, secondary_chan_freq = 0; + struct dfs_channel *dfs_curchan; + + OS_GET_TIMER_ARG(dfs, struct wlan_dfs *); + dfs->dfs_cac_timer_running = 0; + dfs_curchan = dfs->dfs_curchan; + + dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "cac expired, chan %d curr time %d", + dfs->dfs_curchan->dfs_ch_freq, + (qdf_system_ticks_to_msecs(qdf_system_ticks()) / 1000)); + + /* + * When radar is detected during a CAC we are woken up prematurely to + * switch to a new channel. Check the channel to decide how to act. + */ + if (WLAN_IS_CHAN_RADAR(dfs->dfs_curchan)) { + dfs_mlme_mark_dfs_for_freq(dfs->dfs_pdev_obj, + dfs_curchan->dfs_ch_ieee, + dfs_curchan->dfs_ch_freq, + dfs_curchan->dfs_ch_mhz_freq_seg2, + dfs_curchan->dfs_ch_flags); + dfs_debug(dfs, WLAN_DEBUG_DFS, + "CAC timer on channel %u (%u MHz) stopped due to radar", + dfs_curchan->dfs_ch_ieee, + dfs_curchan->dfs_ch_freq); + } else { + dfs_debug(dfs, WLAN_DEBUG_DFS, + "CAC timer on channel %u (%u MHz) expired; no radar detected", + dfs_curchan->dfs_ch_ieee, + dfs_curchan->dfs_ch_freq); + + /* On CAC completion, set the bit 'cac_valid'. + * CAC will not be re-done if this bit is reset. + * The flag will be reset when dfs_cac_valid_timer + * timesout. + */ + if (dfs->dfs_cac_valid_time) { + dfs->dfs_cac_valid = 1; + qdf_timer_mod(&dfs->dfs_cac_valid_timer, + dfs->dfs_cac_valid_time * 1000); + } + + dfs_find_chwidth_and_center_chan_for_freq(dfs, + &ch_width, + &primary_chan_freq, + &secondary_chan_freq); + /* Mark the current channel as preCAC done */ + dfs_mark_precac_done_for_freq(dfs, primary_chan_freq, + secondary_chan_freq, ch_width); + } + + dfs_clear_cac_started_chan(dfs); + /* Iterate over the nodes, processing the CAC completion event. */ + dfs_mlme_proc_cac(dfs->dfs_pdev_obj, 0); + + /* Send a CAC timeout, VAP up event to user space */ + dfs_mlme_deliver_event_up_after_cac(dfs->dfs_pdev_obj); + + if (dfs->dfs_defer_precac_channel_change == 1) { + dfs_mlme_channel_change_by_precac(dfs->dfs_pdev_obj); + dfs->dfs_defer_precac_channel_change = 0; + } +} +#else +#ifdef CONFIG_CHAN_NUM_API static os_timer_func(dfs_cac_timeout) { struct wlan_dfs *dfs = NULL; @@ -173,6 +262,8 @@ static os_timer_func(dfs_cac_timeout) dfs->dfs_defer_precac_channel_change = 0; } } +#endif +#endif void dfs_cac_timer_attach(struct wlan_dfs *dfs) { @@ -212,6 +303,31 @@ int dfs_is_ap_cac_timer_running(struct wlan_dfs *dfs) return dfs->dfs_cac_timer_running; } +#ifdef CONFIG_CHAN_FREQ_API +void dfs_start_cac_timer(struct wlan_dfs *dfs) +{ + int cac_timeout = 0; + struct dfs_channel *chan = dfs->dfs_curchan; + + cac_timeout = + dfs_mlme_get_cac_timeout_for_freq(dfs->dfs_pdev_obj, + chan->dfs_ch_freq, + chan->dfs_ch_mhz_freq_seg2, + chan->dfs_ch_flags); + + dfs->dfs_cac_started_chan = *chan; + + dfs_debug(dfs, WLAN_DEBUG_DFS, + "chan = %d cfreq2 = %d timeout = %d sec, curr_time = %d sec", + chan->dfs_ch_ieee, chan->dfs_ch_vhtop_ch_freq_seg2, + cac_timeout, + qdf_system_ticks_to_msecs(qdf_system_ticks()) / 1000); + + qdf_timer_mod(&dfs->dfs_cac_timer, cac_timeout * 1000); + dfs->dfs_cac_aborted = 0; +} +#else +#ifdef CONFIG_CHAN_NUM_API void dfs_start_cac_timer(struct wlan_dfs *dfs) { int cac_timeout = 0; @@ -233,6 +349,8 @@ void dfs_start_cac_timer(struct wlan_dfs *dfs) qdf_timer_mod(&dfs->dfs_cac_timer, cac_timeout * 1000); dfs->dfs_cac_aborted = 0; } +#endif +#endif void dfs_cancel_cac_timer(struct wlan_dfs *dfs) { @@ -266,11 +384,20 @@ void dfs_stacac_stop(struct wlan_dfs *dfs) dfs_clear_cac_started_chan(dfs); } +/* + * dfs_is_subset_channel_for_freq() - Find out if prev channel and current + * channel are subsets of each other. + * @old_subchans_freq: Pointer to previous sub-channels freq. + * @old_n_chans: Number of previous sub-channels. + * @new_subchans_freq: Pointer to new sub-channels freq. + * @new_n_chans: Number of new sub-channels + */ +#ifdef CONFIG_CHAN_FREQ_API static bool -dfs_is_subset_channel(uint8_t *old_subchans, - uint8_t old_n_chans, - uint8_t *new_subchans, - uint8_t new_n_chans) +dfs_is_subset_channel_for_freq(uint16_t *old_subchans_freq, + uint8_t old_n_chans, + uint16_t *new_subchans_freq, + uint8_t new_n_chans) { bool is_found; int i, j; @@ -284,7 +411,7 @@ dfs_is_subset_channel(uint8_t *old_subchans, for (i = 0; i < new_n_chans; i++) { is_found = false; for (j = 0; j < old_n_chans; j++) { - if (new_subchans[i] == old_subchans[j]) { + if (new_subchans_freq[i] == old_subchans_freq[j]) { is_found = true; break; } @@ -299,42 +426,40 @@ dfs_is_subset_channel(uint8_t *old_subchans, return is_found; } +#endif +#ifdef CONFIG_CHAN_FREQ_API static uint8_t -dfs_find_dfs_sub_channels(struct wlan_dfs *dfs, - struct dfs_channel *channel, - uint8_t *subchan_arr) +dfs_find_dfs_sub_channels_for_freq(struct wlan_dfs *dfs, + struct dfs_channel *chan, + uint16_t *subchan_arr) { - if (WLAN_IS_CHAN_MODE_160(channel) || - WLAN_IS_CHAN_MODE_80_80(channel)) { - if (WLAN_IS_CHAN_DFS(channel) && - WLAN_IS_CHAN_DFS_CFREQ2(channel)) - return - dfs_get_bonding_channels_without_seg_info(channel, - subchan_arr); - if (WLAN_IS_CHAN_DFS(channel)) - return dfs_get_bonding_channels(dfs, - channel, - SEG_ID_PRIMARY, - DETECTOR_ID_0, - subchan_arr); - if (WLAN_IS_CHAN_DFS_CFREQ2(channel)) - return dfs_get_bonding_channels(dfs, - channel, - SEG_ID_SECONDARY, - DETECTOR_ID_0, - subchan_arr); + if (WLAN_IS_CHAN_MODE_160(chan) || WLAN_IS_CHAN_MODE_80_80(chan)) { + if (WLAN_IS_CHAN_DFS(chan) && WLAN_IS_CHAN_DFS_CFREQ2(chan)) + return dfs_get_bonding_channel_without_seg_info_for_freq + (chan, subchan_arr); + if (WLAN_IS_CHAN_DFS(chan)) + return dfs_get_bonding_channels_for_freq(dfs, + chan, + SEG_ID_PRIMARY, + DETECTOR_ID_0, + subchan_arr); + if (WLAN_IS_CHAN_DFS_CFREQ2(chan)) + return dfs_get_bonding_channels_for_freq + (dfs, chan, SEG_ID_SECONDARY, + DETECTOR_ID_0, subchan_arr); /* All channels in 160/80_80 BW are non DFS, return 0 * as number of subchannels */ return 0; - } else if (WLAN_IS_CHAN_DFS(channel)) { - return dfs_get_bonding_channels_without_seg_info(channel, - subchan_arr); + } else if (WLAN_IS_CHAN_DFS(chan)) { + return dfs_get_bonding_channel_without_seg_info_for_freq + (chan, subchan_arr); } /* All channels are non DFS, return 0 as number of subchannels*/ return 0; } +#endif /* dfs_is_new_chan_subset_of_old_chan() - Find if new channel is subset of * old channel. @@ -344,28 +469,32 @@ dfs_find_dfs_sub_channels(struct wlan_dfs *dfs, * * Return: True if new channel is subset of old channel, else false. */ +#ifdef CONFIG_CHAN_FREQ_API static bool dfs_is_new_chan_subset_of_old_chan(struct wlan_dfs *dfs, struct dfs_channel *new_chan, struct dfs_channel *old_chan) { - uint8_t new_subchans[NUM_CHANNELS_160MHZ]; - uint8_t old_subchans[NUM_CHANNELS_160MHZ]; + uint16_t new_subchans[NUM_CHANNELS_160MHZ]; + uint16_t old_subchans[NUM_CHANNELS_160MHZ]; uint8_t n_new_subchans = 0; uint8_t n_old_subchans = 0; /* Given channel is the old channel. i.e. The channel which * should have the new channel as subset. */ - n_old_subchans = dfs_find_dfs_sub_channels(dfs, old_chan, old_subchans); + n_old_subchans = dfs_find_dfs_sub_channels_for_freq(dfs, old_chan, + old_subchans); /* cur_chan is the new channel to be check if subset of old channel */ - n_new_subchans = dfs_find_dfs_sub_channels(dfs, new_chan, new_subchans); + n_new_subchans = dfs_find_dfs_sub_channels_for_freq(dfs, new_chan, + new_subchans); - return dfs_is_subset_channel(old_subchans, - n_old_subchans, - new_subchans, - n_new_subchans); + return dfs_is_subset_channel_for_freq(old_subchans, + n_old_subchans, + new_subchans, + n_new_subchans); } +#endif bool dfs_is_cac_required(struct wlan_dfs *dfs, struct dfs_channel *cur_chan, diff --git a/umac/dfs/core/src/misc/dfs_nol.c b/umac/dfs/core/src/misc/dfs_nol.c index d71f55172e7b..b2a9831e9ae0 100644 --- a/umac/dfs/core/src/misc/dfs_nol.c +++ b/umac/dfs/core/src/misc/dfs_nol.c @@ -55,6 +55,64 @@ bool dfs_get_update_nol_flag(struct wlan_dfs *dfs) * * Clears the WLAN_CHAN_DFS_RADAR_FOUND flag for the NOL timeout channel. */ +/* Unused function */ +#ifdef CONFIG_CHAN_FREQ_API +static os_timer_func(dfs_nol_timeout) +{ + struct dfs_channel *c = NULL, lc; + unsigned long oldest, now; + struct wlan_dfs *dfs = NULL; + int i; + int nchans = 0; + + c = &lc; + + OS_GET_TIMER_ARG(dfs, struct wlan_dfs *); + dfs_mlme_get_dfs_ch_nchans(dfs->dfs_pdev_obj, &nchans); + + now = oldest = qdf_system_ticks(); + for (i = 0; i < nchans; i++) { + dfs_mlme_get_dfs_channels_for_freq + (dfs->dfs_pdev_obj, + &c->dfs_ch_freq, + &c->dfs_ch_flags, + &c->dfs_ch_flagext, + &c->dfs_ch_ieee, + &c->dfs_ch_vhtop_ch_freq_seg1, + &c->dfs_ch_vhtop_ch_freq_seg2, + &c->dfs_ch_mhz_freq_seg1, + &c->dfs_ch_mhz_freq_seg2, + i); + if (WLAN_IS_CHAN_RADAR(c)) { + if (qdf_system_time_after_eq(now, + dfs->dfs_nol_event[i] + + dfs_get_nol_timeout(dfs))) { + c->dfs_ch_flagext &= ~WLAN_CHAN_DFS_RADAR_FOUND; + if (c->dfs_ch_flags & WLAN_CHAN_DFS_RADAR) { + /* + * NB: do this here so we get only one + * msg instead of one for every channel + * table entry. + */ + dfs_debug(dfs, WLAN_DEBUG_DFS, + "radar on channel %u (%u MHz) cleared after timeout", + c->dfs_ch_ieee, + c->dfs_ch_freq); + } + } else if (dfs->dfs_nol_event[i] < oldest) { + oldest = dfs->dfs_nol_event[i]; + } + } + } + if (oldest != now) { + /* Arrange to process next channel up for a status change. */ + qdf_timer_mod(&dfs->dfs_nol_timer, + dfs_get_nol_timeout(dfs) - + qdf_system_ticks_to_msecs(qdf_system_ticks())); + } +} +#else +#ifdef CONFIG_CHAN_NUM_API static os_timer_func(dfs_nol_timeout) { struct dfs_channel *c = NULL, lc; @@ -108,6 +166,8 @@ static os_timer_func(dfs_nol_timeout) qdf_system_ticks_to_msecs(qdf_system_ticks())); } } +#endif +#endif /** * dfs_nol_elem_free_work_cb - Free NOL element @@ -227,6 +287,40 @@ static void dfs_nol_delete(struct wlan_dfs *dfs, * * When NOL times out, this function removes the channel from NOL list. */ +#ifdef CONFIG_CHAN_FREQ_API +static os_timer_func(dfs_remove_from_nol) +{ + struct dfs_nolelem *nol_arg; + struct wlan_dfs *dfs; + uint16_t delfreq; + uint16_t delchwidth; + uint8_t chan; + + OS_GET_TIMER_ARG(nol_arg, struct dfs_nolelem *); + + dfs = nol_arg->nol_dfs; + delfreq = nol_arg->nol_freq; + delchwidth = nol_arg->nol_chwidth; + + /* Delete the given NOL entry. */ + DFS_NOL_DELETE_CHAN_LOCKED(dfs, delfreq, delchwidth); + + /* Update the wireless stack with the new NOL. */ + dfs_nol_update(dfs); + + dfs_mlme_nol_timeout_notification(dfs->dfs_pdev_obj); + chan = utils_dfs_freq_to_chan(delfreq); + utils_dfs_deliver_event(dfs->dfs_pdev_obj, delfreq, + WLAN_EV_NOL_FINISHED); + dfs_debug(dfs, WLAN_DEBUG_DFS_NOL, + "remove channel %d from nol", chan); + utils_dfs_unmark_precac_nol_for_freq(dfs->dfs_pdev_obj, delfreq); + utils_dfs_reg_update_nol_chan_for_freq(dfs->dfs_pdev_obj, + &delfreq, 1, DFS_NOL_RESET); + utils_dfs_save_nol(dfs->dfs_pdev_obj); +} +#else +#ifdef CONFIG_CHAN_NUM_API static os_timer_func(dfs_remove_from_nol) { struct dfs_nolelem *nol_arg; @@ -258,6 +352,8 @@ static os_timer_func(dfs_remove_from_nol) &chan, 1, DFS_NOL_RESET); utils_dfs_save_nol(dfs->dfs_pdev_obj); } +#endif +#endif void dfs_print_nol(struct wlan_dfs *dfs) { @@ -344,6 +440,45 @@ void dfs_get_nol(struct wlan_dfs *dfs, } } +#ifdef CONFIG_CHAN_FREQ_API +void dfs_set_nol(struct wlan_dfs *dfs, + struct dfsreq_nolelem *dfs_nol, + int nchan) +{ +#define TIME_IN_MS 1000 + uint32_t nol_time_lft_ms; + struct dfs_channel chan; + int i; + + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + for (i = 0; i < nchan; i++) { + nol_time_lft_ms = + qdf_system_ticks_to_msecs(qdf_system_ticks() - + dfs_nol[i].nol_start_ticks); + + if (nol_time_lft_ms < dfs_nol[i].nol_timeout_ms) { + chan.dfs_ch_freq = dfs_nol[i].nol_freq; + chan.dfs_ch_flags = 0; + chan.dfs_ch_flagext = 0; + nol_time_lft_ms = + (dfs_nol[i].nol_timeout_ms - nol_time_lft_ms); + + DFS_NOL_ADD_CHAN_LOCKED(dfs, chan.dfs_ch_freq, + (nol_time_lft_ms / TIME_IN_MS)); + utils_dfs_reg_update_nol_chan_for_freq(dfs->dfs_pdev_obj, + &chan.dfs_ch_freq, + 1, DFS_NOL_SET); + } + } +#undef TIME_IN_MS + dfs_nol_update(dfs); +} +#else +#ifdef CONFIG_CHAN_NUM_API void dfs_set_nol(struct wlan_dfs *dfs, struct dfsreq_nolelem *dfs_nol, int nchan) @@ -381,6 +516,8 @@ void dfs_set_nol(struct wlan_dfs *dfs, #undef TIME_IN_MS dfs_nol_update(dfs); } +#endif +#endif void dfs_nol_addchan(struct wlan_dfs *dfs, uint16_t freq, @@ -438,8 +575,9 @@ void dfs_nol_addchan(struct wlan_dfs *dfs, } qdf_timer_init(NULL, - &elem->nol_timer, dfs_remove_from_nol, - elem, QDF_TIMER_TYPE_WAKE_APPS); + &elem->nol_timer, dfs_remove_from_nol, + elem, QDF_TIMER_TYPE_WAKE_APPS); + qdf_timer_mod(&elem->nol_timer, dfs_nol_timeout * TIME_IN_MS); /* Update the NOL counter. */ @@ -586,6 +724,42 @@ void dfs_getnol(struct wlan_dfs *dfs, void *dfs_nolinfo) DFS_GET_NOL_LOCKED(dfs, nolinfo->dfs_nol, &(nolinfo->dfs_ch_nchans)); } +#ifdef CONFIG_CHAN_FREQ_API +void dfs_clear_nolhistory(struct wlan_dfs *dfs) +{ + struct dfs_channel *chan_list; + int nchans = 0; + bool sta_opmode; + + if (!dfs->dfs_is_stadfs_enabled) + return; + + sta_opmode = dfs_mlme_is_opmode_sta(dfs->dfs_pdev_obj); + if (!sta_opmode) + return; + + nchans = dfs_get_num_chans(); + + chan_list = qdf_mem_malloc(nchans * sizeof(*chan_list)); + if (!chan_list) + return; + + utils_dfs_get_nol_history_chan_list(dfs->dfs_pdev_obj, + (void *)chan_list, &nchans); + if (!nchans) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "zero chans"); + qdf_mem_free(chan_list); + return; + } + + utils_dfs_reg_update_nol_history_chan_for_freq(dfs->dfs_pdev_obj, + (void *)chan_list, nchans, + DFS_NOL_HISTORY_RESET); + + qdf_mem_free(chan_list); +} +#else +#ifdef CONFIG_CHAN_NUM_API void dfs_clear_nolhistory(struct wlan_dfs *dfs) { struct dfs_channel *chan_list; @@ -619,8 +793,42 @@ void dfs_clear_nolhistory(struct wlan_dfs *dfs) qdf_mem_free(chan_list); } +#endif +#endif -#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) && \ + defined(CONFIG_CHAN_FREQ_API) +void dfs_remove_spoof_channel_from_nol(struct wlan_dfs *dfs) +{ + struct dfs_nolelem *nol; + uint16_t freq_list[NUM_CHANNELS_160MHZ]; + int i, nchans = 0; + + nchans = dfs_get_bonding_channels_for_freq(dfs, + &dfs->dfs_radar_found_chan, + SEG_ID_PRIMARY, + DETECTOR_ID_0, + freq_list); + + WLAN_DFSNOL_LOCK(dfs); + for (i = 0; i < nchans && i < NUM_CHANNELS_160MHZ; i++) { + nol = dfs->dfs_nol; + while (nol) { + if (nol->nol_freq == freq_list[i]) { + OS_SET_TIMER(&nol->nol_timer, 0); + break; + } + nol = nol->nol_next; + } + } + WLAN_DFSNOL_UNLOCK(dfs); + + utils_dfs_reg_update_nol_chan_for_freq(dfs->dfs_pdev_obj, + freq_list, nchans, DFS_NOL_RESET); +} +#else +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) && \ + defined(CONFIG_CHAN_NUM_API) void dfs_remove_spoof_channel_from_nol(struct wlan_dfs *dfs) { struct dfs_nolelem *nol; @@ -651,3 +859,4 @@ void dfs_remove_spoof_channel_from_nol(struct wlan_dfs *dfs) channels, nchans, DFS_NOL_RESET); } #endif +#endif 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 d29468842da6..bba638f946c1 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 @@ -150,22 +150,24 @@ int dfs_get_nol_subchannel_marking(struct wlan_dfs *dfs, } /** - * dfs_radar_add_channel_list_to_nol()- Add given channels to nol + * dfs_radar_add_channel_list_to_nol_for_freq()- Add given channels to nol * @dfs: Pointer to wlan_dfs structure. - * @channels: Pointer to the channel list. + * @freq_list: Pointer to list of frequency. * @num_channels: Number of channels in the list. * * Add list of channels to nol, only if the channel is dfs. * * Return: QDF_STATUS */ -static QDF_STATUS dfs_radar_add_channel_list_to_nol(struct wlan_dfs *dfs, - uint8_t *channels, - uint8_t num_channels) +#ifdef CONFIG_CHAN_FREQ_API +static QDF_STATUS +dfs_radar_add_channel_list_to_nol_for_freq(struct wlan_dfs *dfs, + uint16_t *freq_list, + uint8_t num_channels) { int i; - uint8_t last_chan = 0; - uint8_t nollist[NUM_CHANNELS_160MHZ]; + uint16_t last_chan_freq = 0; + uint16_t nol_freq_list[NUM_CHANNELS_160MHZ]; uint8_t num_ch = 0; if (num_channels > NUM_CHANNELS_160MHZ) { @@ -175,26 +177,25 @@ static QDF_STATUS dfs_radar_add_channel_list_to_nol(struct wlan_dfs *dfs, } for (i = 0; i < num_channels; i++) { - if (channels[i] == 0 || - channels[i] == last_chan) + if (freq_list[i] == 0 || + freq_list[i] == last_chan_freq) continue; - if (!utils_is_dfs_ch(dfs->dfs_pdev_obj, channels[i])) { + if (!utils_is_dfs_chan_for_freq(dfs->dfs_pdev_obj, + freq_list[i])) { dfs_info(dfs, WLAN_DEBUG_DFS, "ch=%d is not dfs, skip", - channels[i]); + freq_list[i]); continue; } - last_chan = channels[i]; + last_chan_freq = freq_list[i]; DFS_NOL_ADD_CHAN_LOCKED(dfs, - (uint16_t)utils_dfs_chan_to_freq(channels[i]), - dfs->wlan_dfs_nol_timeout); - nollist[num_ch++] = last_chan; + freq_list[i], + dfs->wlan_dfs_nol_timeout); + nol_freq_list[num_ch++] = last_chan_freq; utils_dfs_deliver_event(dfs->dfs_pdev_obj, - (uint16_t) - utils_dfs_chan_to_freq(channels[i]), + freq_list[i], WLAN_EV_NOL_STARTED); - dfs_info(dfs, WLAN_DEBUG_DFS_NOL, "ch=%d Added to NOL, freq= %hu", - last_chan, - (uint16_t)utils_dfs_chan_to_freq(last_chan)); + dfs_info(dfs, WLAN_DEBUG_DFS_NOL, "ch=%d Added to NOL", + last_chan_freq); } if (!num_ch) { @@ -203,21 +204,22 @@ static QDF_STATUS dfs_radar_add_channel_list_to_nol(struct wlan_dfs *dfs, return QDF_STATUS_E_FAILURE; } - utils_dfs_reg_update_nol_ch(dfs->dfs_pdev_obj, - nollist, num_ch, DFS_NOL_SET); + utils_dfs_reg_update_nol_chan_for_freq(dfs->dfs_pdev_obj, + nol_freq_list, num_ch, + DFS_NOL_SET); if (dfs->dfs_is_stadfs_enabled) if (dfs_mlme_is_opmode_sta(dfs->dfs_pdev_obj)) - utils_dfs_reg_update_nol_history_ch( - dfs->dfs_pdev_obj, nollist, num_ch, - DFS_NOL_HISTORY_SET); + utils_dfs_reg_update_nol_history_chan_for_freq( + dfs->dfs_pdev_obj, nol_freq_list, + num_ch, DFS_NOL_HISTORY_SET); dfs_nol_update(dfs); utils_dfs_save_nol(dfs->dfs_pdev_obj); return QDF_STATUS_SUCCESS; } - +#endif /** * dfs_radar_chan_for_80()- Find frequency offsets for 80MHz * @freq_offset: freq offset @@ -323,6 +325,56 @@ static void dfs_radar_chan_for_20(struct freqs_offsets *freq_offset, * @radar_found: Pointer to radar_found_info. * @freq_center: Pointer to retrieve the value of radar found cfreq. */ +#ifdef CONFIG_CHAN_FREQ_API +static void +dfs_compute_radar_found_cfreq(struct wlan_dfs *dfs, + struct radar_found_info *radar_found, + uint32_t *freq_center) +{ + struct dfs_channel *curchan = dfs->dfs_curchan; + + /* Radar found on agile detector ID. + * Applicable to chips that have a separate agile radar detector + * engine. + */ + if (radar_found->detector_id == AGILE_DETECTOR_ID) { + *freq_center = dfs->dfs_agile_precac_freq_mhz; + } else if (!radar_found->segment_id) { + *freq_center = curchan->dfs_ch_mhz_freq_seg1; + } else { + /* Radar found on secondary segment by the HW when + * preCAC was running. It (dfs_precac_enable) is specific to + * legacy chips. + */ + if (dfs_is_precac_timer_running(dfs) && + dfs_is_legacy_precac_enabled(dfs)) { + *freq_center = dfs->dfs_precac_secondary_freq_mhz; + } else { + /* Radar found on secondary segment by the HW, when preCAC + * was not running in legacy chips or preCAC was running + * in Lithium chips. + */ + *freq_center = curchan->dfs_ch_mhz_freq_seg2; + if (WLAN_IS_CHAN_MODE_160(curchan)) { + /* If center frequency of entire 160 band + * is less than center frequency of primary + * segment, then the center frequency of + * secondary segment is -40 of center + * frequency of entire 160 segment. + */ + if (curchan->dfs_ch_mhz_freq_seg2 < + curchan->dfs_ch_mhz_freq_seg1) + *freq_center -= + DFS_160MHZ_SECOND_SEG_OFFSET; + else + *freq_center += + DFS_160MHZ_SECOND_SEG_OFFSET; + } + } + } +} +#else +#ifdef CONFIG_CHAN_NUM_API static void dfs_compute_radar_found_cfreq(struct wlan_dfs *dfs, struct radar_found_info @@ -375,28 +427,31 @@ dfs_compute_radar_found_cfreq(struct wlan_dfs *dfs, } } } +#endif +#endif /** - * dfs_find_radar_affected_subchans() - Finds radar affected sub channels. + * dfs_find_radar_affected_subchans_for_freq() - Find radar affected sub chans. * @dfs: Pointer to wlan_dfs structure. * @radar_found: Pointer to radar_found structure. - * @channels: Pointer to save radar affected channels. + * @freq_list: Pointer to save radar affected channels. * @freq_center: Freq_center of the radar affected chan. * * Return: Number of channels. */ -static uint8_t dfs_find_radar_affected_subchans(struct wlan_dfs *dfs, - struct radar_found_info - *radar_found, - uint8_t *channels, - uint32_t freq_center) +#ifdef CONFIG_CHAN_FREQ_API +static uint8_t +dfs_find_radar_affected_subchans_for_freq(struct wlan_dfs *dfs, + struct radar_found_info *radar_found, + uint16_t *freq_list, + uint32_t freq_center) { int i, j; uint8_t num_radar_subchans; uint32_t flag; int32_t sidx; - uint8_t candidate_subchan; - uint8_t cur_subchans[NUM_CHANNELS_160MHZ]; + uint16_t candidate_subchan_freq; + uint16_t cur_subchans[NUM_CHANNELS_160MHZ]; uint8_t n_cur_subchans; struct dfs_channel *curchan = dfs->dfs_curchan; struct freqs_offsets freq_offset; @@ -443,28 +498,31 @@ static uint8_t dfs_find_radar_affected_subchans(struct wlan_dfs *dfs, return 0; } - n_cur_subchans = dfs_get_bonding_channels(dfs, curchan, - radar_found->segment_id, - radar_found->detector_id, - cur_subchans); + n_cur_subchans = + dfs_get_bonding_channels_for_freq(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++) { - candidate_subchan = utils_dfs_freq_to_chan(freq_offset.freq[i]); + candidate_subchan_freq = freq_offset.freq[i]; for (j = 0; j < n_cur_subchans; j++) { - if (cur_subchans[j] == candidate_subchan) { - channels[num_radar_subchans++] = - candidate_subchan; + if (cur_subchans[j] == candidate_subchan_freq) { + freq_list[num_radar_subchans++] = + candidate_subchan_freq; dfs_info(dfs, WLAN_DEBUG_DFS, "offset=%d, channel=%d", num_radar_subchans, - channels[num_radar_subchans - 1]); + freq_list[num_radar_subchans - 1]); break; } } } return num_radar_subchans; } +#endif +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_get_bonding_channels_without_seg_info(struct dfs_channel *chan, uint8_t *channels) { @@ -512,7 +570,136 @@ uint8_t dfs_get_bonding_channels_without_seg_info(struct dfs_channel *chan, return nchannels; } +#endif +/* + * dfs_get_bonding_channel_without_seg_info_for_freq() - Get bonding frequency + * list. + * @chan: Pointer to dfs_channel. + * @freq_list: Pointer to frequency list. + */ +#ifdef CONFIG_CHAN_FREQ_API +uint8_t +dfs_get_bonding_channel_without_seg_info_for_freq(struct dfs_channel *chan, + uint16_t *freq_list) +{ + uint16_t center_freq; + uint8_t nchannels = 0; + + center_freq = chan->dfs_ch_mhz_freq_seg1; + + if (WLAN_IS_CHAN_MODE_20(chan)) { + nchannels = 1; + freq_list[0] = center_freq; + } else if (WLAN_IS_CHAN_MODE_40(chan)) { + nchannels = 2; + freq_list[0] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[1] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + } else if (WLAN_IS_CHAN_MODE_80(chan)) { + nchannels = 4; + freq_list[0] = center_freq - DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[1] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[2] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[3] = center_freq + DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + } else if (WLAN_IS_CHAN_MODE_80_80(chan)) { + nchannels = 8; + freq_list[0] = center_freq - DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[1] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[2] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[3] = center_freq + DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + center_freq = chan->dfs_ch_mhz_freq_seg2; + freq_list[4] = center_freq - DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[5] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[6] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[7] = center_freq + DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + } else if (WLAN_IS_CHAN_MODE_160(chan)) { + nchannels = 8; + center_freq = chan->dfs_ch_mhz_freq_seg2; + freq_list[0] = center_freq - DFS_5GHZ_4TH_CHAN_FREQ_OFFSET; + freq_list[1] = center_freq - DFS_5GHZ_3RD_CHAN_FREQ_OFFSET; + freq_list[2] = center_freq - DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[3] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[4] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[5] = center_freq + DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[6] = center_freq + DFS_5GHZ_3RD_CHAN_FREQ_OFFSET; + freq_list[7] = center_freq + DFS_5GHZ_4TH_CHAN_FREQ_OFFSET; + } + + return nchannels; +} +#endif + +/* + * dfs_get_bonding_channels_for_freq() - Get bonding channel frequency. + * @dfs: Pointer to wlan_dfs. + * @curchan: Pointer to dfs_channel. + * @segment_id: Segment ID. + * @detector_id: Detector ID. + * @freq_list: Pointer to frequency list. + */ +#ifdef CONFIG_CHAN_FREQ_API +uint8_t dfs_get_bonding_channels_for_freq(struct wlan_dfs *dfs, + struct dfs_channel *curchan, + uint32_t segment_id, + uint8_t detector_id, + uint16_t *freq_list) +{ + uint16_t center_freq; + uint8_t nchannels = 0; + + if (detector_id == AGILE_DETECTOR_ID) + center_freq = dfs->dfs_agile_precac_freq_mhz; + else if (!segment_id) + center_freq = curchan->dfs_ch_mhz_freq_seg1; + else { + /* When precac is running "dfs_ch_vhtop_ch_freq_seg2" is + * zero and "dfs_precac_secondary_freq" holds the secondary + * frequency. + */ + if (dfs_is_precac_timer_running(dfs)) + center_freq = dfs->dfs_precac_secondary_freq_mhz; + else + center_freq = curchan->dfs_ch_mhz_freq_seg2; + } + + if (WLAN_IS_CHAN_MODE_20(curchan)) { + nchannels = 1; + freq_list[0] = center_freq; + } else if (WLAN_IS_CHAN_MODE_40(curchan)) { + nchannels = 2; + freq_list[0] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[1] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + } else if (WLAN_IS_CHAN_MODE_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; + freq_list[0] = center_freq - DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[1] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[2] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[3] = center_freq + DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + } else if (WLAN_IS_CHAN_MODE_160(curchan)) { + nchannels = 8; + center_freq = curchan->dfs_ch_mhz_freq_seg2; + freq_list[0] = center_freq - DFS_5GHZ_4TH_CHAN_FREQ_OFFSET; + freq_list[1] = center_freq - DFS_5GHZ_3RD_CHAN_FREQ_OFFSET; + freq_list[2] = center_freq - DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[3] = center_freq - DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[4] = center_freq + DFS_5GHZ_NEXT_CHAN_FREQ_OFFSET; + freq_list[5] = center_freq + DFS_5GHZ_2ND_CHAN_FREQ_OFFSET; + freq_list[6] = center_freq + DFS_5GHZ_3RD_CHAN_FREQ_OFFSET; + freq_list[7] = center_freq + DFS_5GHZ_4TH_CHAN_FREQ_OFFSET; + } + + return nchannels; +} +#endif + +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_get_bonding_channels(struct wlan_dfs *dfs, struct dfs_channel *curchan, uint32_t segment_id, @@ -583,6 +770,7 @@ uint8_t dfs_get_bonding_channels(struct wlan_dfs *dfs, return nchannels; } +#endif static inline void dfs_reset_bangradar(struct wlan_dfs *dfs) { @@ -633,34 +821,31 @@ int dfs_second_segment_radar_disable(struct wlan_dfs *dfs) /* dfs_prepare_nol_ie_bitmap: Create a Bitmap from the radar found subchannels * to be sent along with RCSA. - * - * Get the subchannels affected by radar and all the channels in current - * channel. - * start from the first bit pointing to first subchannel in the current - * channel, set as 1 if radar affected, 0 if unaffected. - * If the number of subchannels increases (future cases), the bitmap should - * be an array of required size. - * - * Please change macro "MIN_DFS_SUBCHAN_BW" when NOL logic changes. + * @dfs: Pointer to wlan_dfs. + * @radar_found: Pointer to radar_found_info. + * @in_sub_channels: Pointer to Sub-channels. + * @n_in_sub_channels: Number of sub-channels. */ -static void dfs_prepare_nol_ie_bitmap(struct wlan_dfs *dfs, - struct radar_found_info *radar_found, - uint8_t *in_sub_channels, - uint8_t n_in_sub_channels) +#ifdef CONFIG_CHAN_FREQ_API +static void +dfs_prepare_nol_ie_bitmap_for_freq(struct wlan_dfs *dfs, + struct radar_found_info *radar_found, + uint16_t *in_sub_channels, + uint8_t n_in_sub_channels) { - uint8_t cur_subchans[NUM_CHANNELS_160MHZ]; + uint16_t cur_subchans[NUM_CHANNELS_160MHZ]; uint8_t n_cur_subchans; uint8_t i; uint8_t j; uint8_t bits = 0x01; - n_cur_subchans = dfs_get_bonding_channels(dfs, dfs->dfs_curchan, - radar_found->segment_id, - radar_found->detector_id, - cur_subchans); + n_cur_subchans = + dfs_get_bonding_channels_for_freq(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 = - (uint16_t)utils_dfs_chan_to_freq(cur_subchans[0]); + dfs->dfs_nol_ie_startfreq = cur_subchans[0]; /* Search through the array list of radar affected subchannels * to find if the subchannel in our current channel has radar hit. @@ -676,6 +861,7 @@ static void dfs_prepare_nol_ie_bitmap(struct wlan_dfs *dfs, bits <<= 1; } } +#endif void dfs_fetch_nol_ie_info(struct wlan_dfs *dfs, uint8_t *nol_ie_bandwidth, @@ -711,12 +897,13 @@ static void dfs_reset_nol_ie_bitmap(struct wlan_dfs *dfs) dfs->dfs_nol_ie_bitmap = 0; } +#ifdef CONFIG_CHAN_FREQ_API bool dfs_process_nol_ie_bitmap(struct wlan_dfs *dfs, uint8_t nol_ie_bandwidth, uint16_t nol_ie_startfreq, uint8_t nol_ie_bitmap) { uint8_t num_subchans; uint8_t bits = 0x01; - uint8_t radar_subchans[NUM_CHANNELS_160MHZ]; + uint16_t radar_subchans[NUM_CHANNELS_160MHZ]; bool should_nol_ie_be_sent = true; qdf_mem_zero(radar_subchans, sizeof(radar_subchans)); @@ -726,11 +913,11 @@ bool dfs_process_nol_ie_bitmap(struct wlan_dfs *dfs, uint8_t nol_ie_bandwidth, * can't be sent to uplink. */ num_subchans = - dfs_get_bonding_channels(dfs, - dfs->dfs_curchan, - SEG_ID_PRIMARY, - DETECTOR_ID_0, - radar_subchans); + dfs_get_bonding_channels_for_freq(dfs, + dfs->dfs_curchan, + SEG_ID_PRIMARY, + DETECTOR_ID_0, + radar_subchans); should_nol_ie_be_sent = false; } else { /* Add the NOL IE information in DFS structure so that RCSA @@ -744,29 +931,34 @@ bool dfs_process_nol_ie_bitmap(struct wlan_dfs *dfs, uint8_t nol_ie_bandwidth, for (num_subchans = 0; num_subchans < NUM_CHANNELS_160MHZ; num_subchans++) { if (nol_ie_bitmap & bits) { - radar_subchans[num_subchans] = - utils_dfs_freq_to_chan(frequency); + radar_subchans[num_subchans] = frequency; } bits <<= 1; frequency += nol_ie_bandwidth; } } - dfs_radar_add_channel_list_to_nol(dfs, radar_subchans, num_subchans); + dfs_radar_add_channel_list_to_nol_for_freq(dfs, radar_subchans, + num_subchans); return should_nol_ie_be_sent; } +#endif +#ifdef CONFIG_CHAN_FREQ_API QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, struct radar_found_info *radar_found) { bool wait_for_csa = false; - uint8_t channels[NUM_CHANNELS_160MHZ]; + uint16_t freq_list[NUM_CHANNELS_160MHZ]; uint8_t num_channels; QDF_STATUS status; uint32_t freq_center; uint32_t radarfound_freq; + struct dfs_channel *dfs_curchan; - if (!dfs->dfs_curchan) { + dfs_curchan = dfs->dfs_curchan; + + if (!dfs_curchan) { dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs->dfs_curchan is NULL"); return QDF_STATUS_E_FAILURE; } @@ -776,7 +968,7 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, * Detector we need to process it since Agile Detector has a * different channel. */ - if (!dfs_radarevent_basic_sanity(dfs, dfs->dfs_curchan) && + if (!dfs_radarevent_basic_sanity(dfs, dfs_curchan) && !(radar_found->detector_id == AGILE_DETECTOR_ID)) { dfs_err(dfs, WLAN_DEBUG_DFS, "radar event on a non-DFS channel"); @@ -785,8 +977,8 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, /* Sanity checks for radar on Agile detector */ if (radar_found->detector_id == AGILE_DETECTOR_ID && - (!dfs_is_agile_precac_enabled(dfs) || - !dfs->dfs_agile_precac_freq)) { + (!dfs_is_agile_precac_enabled(dfs) || !dfs->dfs_agile_precac_freq_mhz)) + { dfs_err(dfs, WLAN_DEBUG_DFS, "radar on Agile detector when ADFS is not running"); return QDF_STATUS_E_FAILURE; @@ -809,7 +1001,7 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, 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); + 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.", @@ -818,11 +1010,10 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "Radar found on channel=%d, freq=%d MHz. Primary beaconning chan:%d, freq=%d MHz.", utils_dfs_freq_to_chan(radarfound_freq), - radarfound_freq, dfs->dfs_curchan->dfs_ch_ieee, - dfs->dfs_curchan->dfs_ch_freq); + radarfound_freq, dfs_curchan->dfs_ch_ieee, + dfs_curchan->dfs_ch_freq); - utils_dfs_deliver_event(dfs->dfs_pdev_obj, - radarfound_freq, + utils_dfs_deliver_event(dfs->dfs_pdev_obj, radarfound_freq, WLAN_EV_RADAR_DETECTED); if (!dfs->dfs_use_nol) { @@ -832,28 +1023,29 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, } if (dfs->dfs_bangradar_type == DFS_BANGRADAR_FOR_ALL_SUBCHANS) - num_channels = dfs_get_bonding_channels_without_seg_info( - dfs->dfs_curchan, channels); + num_channels = + dfs_get_bonding_channel_without_seg_info_for_freq + (dfs_curchan, freq_list); /* BW reduction is dependent on subchannel marking */ 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, - freq_center); - else + (dfs->dfs_bangradar_type == + DFS_BANGRADAR_FOR_SPECIFIC_SUBCHANS))) num_channels = - dfs_get_bonding_channels(dfs, - dfs->dfs_curchan, - radar_found->segment_id, - radar_found->detector_id, - channels); + dfs_find_radar_affected_subchans_for_freq(dfs, + radar_found, + freq_list, + freq_center); + else + num_channels = dfs_get_bonding_channels_for_freq + (dfs, dfs_curchan, radar_found->segment_id, + radar_found->detector_id, freq_list); dfs_reset_bangradar(dfs); - status = dfs_radar_add_channel_list_to_nol(dfs, channels, num_channels); + status = dfs_radar_add_channel_list_to_nol_for_freq(dfs, + freq_list, + num_channels); if (QDF_IS_STATUS_ERROR(status)) { dfs_err(dfs, WLAN_DEBUG_DFS, "radar event received on invalid channel"); @@ -867,8 +1059,8 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, (dfs->dfs_is_rcsa_ie_sent = true); if (dfs->dfs_use_nol_subchannel_marking) { dfs_reset_nol_ie_bitmap(dfs); - dfs_prepare_nol_ie_bitmap(dfs, radar_found, channels, - num_channels); + dfs_prepare_nol_ie_bitmap_for_freq(dfs, radar_found, freq_list, + num_channels); dfs->dfs_is_nol_ie_sent = true; } @@ -892,12 +1084,11 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, dfs_debug(dfs, WLAN_DEBUG_DFS, "%s: %d Radar found on dfs detector:%d", __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); - + dfs_mark_precac_nol_for_freq(dfs, + dfs->is_radar_found_on_secondary_seg, + radar_found->detector_id, + freq_list, + num_channels); /* * This calls into the umac DFS code, which sets the umac * related radar flags and begins the channel change @@ -947,11 +1138,12 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, dfs_second_segment_radar_disable(dfs); } - dfs_mlme_mark_dfs(dfs->dfs_pdev_obj, - dfs->dfs_curchan->dfs_ch_ieee, - dfs->dfs_curchan->dfs_ch_freq, - dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2, - dfs->dfs_curchan->dfs_ch_flags); + dfs_mlme_mark_dfs_for_freq(dfs->dfs_pdev_obj, + dfs->dfs_curchan->dfs_ch_ieee, + dfs->dfs_curchan->dfs_ch_freq, + dfs->dfs_curchan->dfs_ch_mhz_freq_seg2, + dfs->dfs_curchan->dfs_ch_flags); return QDF_STATUS_SUCCESS; } +#endif 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 b6115fae869c..fb8b2e0bb373 100644 --- a/umac/dfs/core/src/misc/dfs_random_chan_sel.c +++ b/umac/dfs/core/src/misc/dfs_random_chan_sel.c @@ -35,681 +35,681 @@ /* channel tx leakage table - ht80 */ struct dfs_matrix_tx_leak_info ht80_chan[] = { - {52, - {{36, 148}, {40, 199}, - {44, 193}, {48, 197}, - {52, DFS_TX_LEAKAGE_MIN}, {56, 153}, - {60, 137}, {64, 134}, - {100, 358}, {104, 350}, - {108, 404}, {112, 344}, - {116, 424}, {120, 429}, - {124, 437}, {128, 435}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {52, 5260, + {{36, 5180, 148}, {40, 5200, 199}, + {44, 5520, 193}, {48, 5240, 197}, + {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, 153}, + {60, 5300, 137}, {64, 5320, 134}, + {100, 5500, 358}, {104, 5520, 350}, + {108, 5540, 404}, {112, 5560, 344}, + {116, 5580, 424}, {120, 5600, 429}, + {124, 5620, 437}, {128, 5640, 435}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {56, - {{36, 171}, {40, 178}, - {44, 171}, {48, 178}, - {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, - {60, DFS_TX_LEAKAGE_MIN}, {64, 280}, - {100, 351}, {104, 376}, - {108, 362}, {112, 362}, - {116, 403}, {120, 397}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {56, 5280, + {{36, 5180, 171}, {40, 5200, 178}, + {44, 5220, 171}, {48, 5240, 178}, + {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, 280}, + {100, 5500, 351}, {104, 5520, 376}, + {108, 5540, 362}, {112, 5560, 362}, + {116, 5580, 403}, {120, 5600, 397}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {60, - {{36, 156}, {40, 146}, - {44, DFS_TX_LEAKAGE_MIN}, {48, DFS_TX_LEAKAGE_MIN}, - {52, 180}, {56, DFS_TX_LEAKAGE_MIN}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, 376}, {104, 360}, - {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, - {116, 395}, {120, 399}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {60,5300, + {{36, 5180, 156}, {40, 5200, 146}, + {44, 5220, DFS_TX_LEAKAGE_MIN}, {48, 5240, DFS_TX_LEAKAGE_MIN}, + {52, 5260, 180}, {56, 5280, DFS_TX_LEAKAGE_MIN}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, 376}, {104, 5520, 360}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, + {116, 5580, 395}, {120, 5600, 399}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {64, - {{36, 217}, {40, 221}, - {44, DFS_TX_LEAKAGE_MIN}, {48, DFS_TX_LEAKAGE_MIN}, - {52, 176}, {56, 176}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, 384}, {104, 390}, - {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, - {116, 375}, {120, 374}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {64, 5320, + {{36, 5180, 217}, {40, 5200, 221}, + {44, 5220, DFS_TX_LEAKAGE_MIN}, {48, 5240, DFS_TX_LEAKAGE_MIN}, + {52, 5260, 176}, {56, 5280, 176}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, 384}, {104, 5520, 390}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, + {116, 5580, 375}, {120, 5600, 374}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {100, - {{36, 357}, {40, 326}, - {44, 321}, {48, 326}, - {52, 378}, {56, 396}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, 196}, {112, 116}, - {116, 166}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {100, 5500, + {{36, 5180, 357}, {40, 5200, 326}, + {44, 5220, 321}, {48, 5240, 326}, + {52, 5260, 378}, {56, 5280, 396}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, 196}, {112, 5560, 116}, + {116, 5580, 166}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {104, - {{36, 325}, {40, 325}, - {44, 305}, {48, 352}, - {52, 411}, {56, 411}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, 460}, - {116, 198}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {104, 5520, + {{36, 5180, 325}, {40, 5200, 325}, + {44, 5220, 305}, {48, 5240, 352}, + {52, 5260, 411}, {56, 5280, 411}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, 460}, + {116, 5580, 198}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {108, - {{36, 304}, {40, 332}, - {44, 310}, {48, 335}, - {52, 431}, {56, 391}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 280}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, 185}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {108, 5540, + {{36,5180, 304}, {40, 5200, 332}, + {44, 5220, 310}, {48, 5240, 335}, + {52, 5260, 431}, {56, 5280, 391}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 280}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, 185}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {112, - {{36, 327}, {40, 335}, - {44, 331}, {48, 345}, - {52, 367}, {56, 401}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 131}, {104, 132}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, 189}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {112,5560, + {{36, 5180, 327}, {40, 5200, 335}, + {44, 5220, 331}, {48, 5240, 345}, + {52, 5260, 367}, {56, 5280, 401}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 131}, {104, 5520, 132}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, 189}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {116, - {{36, 384}, {40, 372}, - {44, 389}, {48, 396}, - {52, 348}, {56, 336}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 172}, {104, 169}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {116, 5580, + {{36, 5180, 384}, {40, 5200, 372}, + {44, 5220, 389}, {48, 5240, 396}, + {52, 5260, 348}, {56, 5280, 336}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 172}, {104, 5520, 169}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {120, - {{36, 395}, {40, 419}, - {44, 439}, {48, 407}, - {52, 321}, {56, 334}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 134}, {104, 186}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, 159}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {120, 5600, + {{36, 5180, 395}, {40, 5200, 419}, + {44, 5220, 439}, {48, 5240, 407}, + {52, 5260, 321}, {56, 5280, 334}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 134}, {104, 5520, 186}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 159}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {124, - {{36, 469}, {40, 433}, - {44, 434}, {48, 435}, - {52, 332}, {56, 345}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 146}, {104, 177}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, 350}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, 138}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {124, 5620, + {{36, 5180, 469}, {40, 5200, 433}, + {44, 5220, 434}, {48, 5240, 435}, + {52, 5260, 332}, {56, 5280, 345}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 146}, {104, 5520, 177}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, 350}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 138}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {128, - {{36, 408}, {40, 434}, - {44, 449}, {48, 444}, - {52, 341}, {56, 374}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 205}, {104, 208}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, 142}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {128, 5640, + {{36, 5180, 408}, {40, 5200, 434}, + {44, 5220, 449}, {48, 5240, 444}, + {52, 5260, 341}, {56, 5280, 374}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 205}, {104, 5520, 208}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, 142}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {132, - {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX}, - {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {132, 5660, + {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, + {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {136, - {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX}, - {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {136, 5680, + {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, + {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {140, - {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX}, - {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {140, 5700, + {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, + {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {144, - {{36, DFS_TX_LEAKAGE_MAX}, {40, DFS_TX_LEAKAGE_MAX}, - {44, DFS_TX_LEAKAGE_MAX}, {48, DFS_TX_LEAKAGE_MAX}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {144, 5720, + {{36, 5180, DFS_TX_LEAKAGE_MAX}, {40, 5200, DFS_TX_LEAKAGE_MAX}, + {44, 5220, DFS_TX_LEAKAGE_MAX}, {48, 5240, DFS_TX_LEAKAGE_MAX}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, }; /* channel tx leakage table - ht40 */ struct dfs_matrix_tx_leak_info ht40_chan[] = { - {52, - {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, - {44, 230}, {48, 230}, - {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, - {60, DFS_TX_LEAKAGE_AUTO_MIN}, {64, DFS_TX_LEAKAGE_AUTO_MIN}, - {100, 625}, {104, 323}, - {108, 646}, {112, 646}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {52, 5260, + {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, + {44, 5220, 230}, {48, 5240, 230}, + {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, + {60, 5300, DFS_TX_LEAKAGE_AUTO_MIN}, {64, 5320, DFS_TX_LEAKAGE_AUTO_MIN}, + {100, 5500, 625}, {104, 5520, 323}, + {108, 5540, 646}, {112, 5560, 646}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {56, - {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, - {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, DFS_TX_LEAKAGE_AUTO_MIN}, - {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, 611}, {104, 611}, - {108, 617}, {112, 617}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {56, 5280, + {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, + {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN}, + {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, 611}, {104, 5520, 611}, + {108, 5540, 617}, {112, 5560, 617}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {60, - {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, - {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, DFS_TX_LEAKAGE_AUTO_MIN}, - {52, 190}, {56, 190}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, 608}, {104, 608}, - {108, 623}, {112, 623}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {60, 5300, + {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, + {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN}, + {52, 5260, 190}, {56, 5280, 190}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, 608}, {104, 5520, 608}, + {108, 5540, 623}, {112, 5560, 623}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {64, - {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, - {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, DFS_TX_LEAKAGE_AUTO_MIN}, - {52, 295}, {56, 295}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, 594}, {104, 594}, - {108, 625}, {112, 625}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {64, 5320, + {{36, 5180, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, + {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, DFS_TX_LEAKAGE_AUTO_MIN}, + {52, 5260, 295}, {56, 5280, 295}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, 594}, {104, 5520, 594}, + {108, 5540, 625}, {112, 5560, 625}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {100, - {{36, 618}, {40, 618}, - {44, 604}, {48, 604}, - {52, 596}, {56, 596}, - {60, 584}, {64, 584}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, 299}, {112, 299}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, - {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, - {132, 538}, {136, 538}, - {140, 598}, - {144, DFS_TX_LEAKAGE_MIN} + {100, 5500, + {{36, 5180, 618}, {40, 5200, 618}, + {44, 5220, 604}, {48, 5240, 604}, + {52, 5260, 596}, {56, 5280, 596}, + {60, 5300, 584}, {64, 5320, 584}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, 299}, {112, 5560, 299}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, + {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, + {132, 5660, 538}, {136,5680, 538}, + {140, 5700, 598}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {104, - {{36, 636}, {40, 636}, - {44, 601}, {48, 601}, - {52, 616}, {56, 616}, - {60, 584}, {64, 584}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, - {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, - {132, 553}, {136, 553}, - {140, 568}, - {144, DFS_TX_LEAKAGE_MIN} + {104, 5520, + {{36, 5180, 636}, {40, 5200, 636}, + {44, 5220, 601}, {48, 5240, 601}, + {52, 5260, 616}, {56, 5280, 616}, + {60, 5300, 584}, {64, 5320, 584}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, + {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, + {132, 5660, 553}, {136, 5680, 553}, + {140, 5700, 568}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {108, - {{36, 600}, {40, 600}, - {44, 627}, {48, 627}, - {52, 611}, {56, 611}, - {60, 611}, {64, 611}, - {100, 214}, {104, 214}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, - {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, - {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, - {140, 534}, - {144, DFS_TX_LEAKAGE_MIN} + {108, 5540, + {{36, 5180, 600}, {40, 5200, 600}, + {44, 5220, 627}, {48, 5240, 627}, + {52, 5260, 611}, {56, 5280, 611}, + {60, 5300, 611}, {64, 5320, 611}, + {100, 5500, 214}, {104, 5520, 214}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, + {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, + {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, + {140, 5700, 534}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {112, - {{36, 645}, {40, 645}, - {44, 641}, {48, 641}, - {52, 618}, {56, 618}, - {60, 612}, {64, 612}, - {100, 293}, {104, 293}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, - {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, - {140, 521}, - {144, DFS_TX_LEAKAGE_MIN} + {112, 5560, + {{36, 5180, 645}, {40, 5200, 645}, + {44, 5220, 641}, {48, 5240, 641}, + {52, 5260, 618}, {56, 5280, 618}, + {60, 5300, 612}, {64, 5320, 612}, + {100, 5500, 293}, {104, 5520, 293}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, + {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, + {140, 5700, 521}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {116, - {{36, 661}, {40, 661}, - {44, 624}, {48, 624}, - {52, 634}, {56, 634}, - {60, 611}, {64, 611}, - {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN}, - {108, 217}, {112, 217}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, - {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, - {140, DFS_TX_LEAKAGE_AUTO_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {116, 5580, + {{36, 5180, 661}, {40, 5200, 661}, + {44, 5220, 624}, {48, 5240, 624}, + {52, 5260, 634}, {56, 5280, 634}, + {60, 5300, 611}, {64, 5320, 611}, + {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, + {108, 5540, 217}, {112, 5560, 217}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, + {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, + {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {120, - {{36, 667}, {40, 667}, - {44, 645}, {48, 645}, - {52, 633}, {56, 633}, - {60, 619}, {64, 619}, - {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN}, - {108, 291}, {112, 291}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, - {140, DFS_TX_LEAKAGE_AUTO_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {120, 5600, + {{36, 5180, 667}, {40, 5200, 667}, + {44, 5220, 645}, {48, 5240, 645}, + {52, 5260, 633}, {56, 5280, 633}, + {60, 5300, 619}, {64, 5320, 619}, + {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, + {108, 5540, 291}, {112, 5560, 291}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, + {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {124, - {{36, 676}, {40, 676}, - {44, 668}, {48, 668}, - {52, 595}, {56, 595}, - {60, 622}, {64, 622}, - {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN}, - {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, - {116, 225}, {120, 225}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_AUTO_MIN}, {136, DFS_TX_LEAKAGE_AUTO_MIN}, - {140, DFS_TX_LEAKAGE_AUTO_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {124, 5620, + {{36, 5180, 676}, {40, 5200, 676}, + {44, 5220, 668}, {48, 5240, 668}, + {52, 5260, 595}, {56, 5280, 595}, + {60, 5300, 622}, {64, 5320, 622}, + {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, + {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, + {116, 5580, 225}, {120, 5600, 225}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_AUTO_MIN}, {136, 5680, DFS_TX_LEAKAGE_AUTO_MIN}, + {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {128, - {{36, 678}, {40, 678}, - {44, 664}, {48, 664}, - {52, 651}, {56, 651}, - {60, 643}, {64, 643}, - {100, DFS_TX_LEAKAGE_AUTO_MIN}, {104, DFS_TX_LEAKAGE_AUTO_MIN}, - {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, - {116, 293}, {120, 293}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_AUTO_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {128, 5640, + {{36, 5180, 678}, {40, 5200, 678}, + {44, 5220, 664}, {48, 5240, 664}, + {52, 5260, 651}, {56, 5280, 651}, + {60, 5300, 643}, {64, 5320, 643}, + {100, 5500, DFS_TX_LEAKAGE_AUTO_MIN}, {104, 5520, DFS_TX_LEAKAGE_AUTO_MIN}, + {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, + {116, 5580, 293}, {120, 5600, 293}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_AUTO_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {132, - {{36, 689}, {40, 689}, - {44, 669}, {48, 669}, - {52, 662}, {56, 662}, - {60, 609}, {64, 609}, - {100, 538}, {104, 538}, - {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, - {124, 247}, {128, 247}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {132, 5660, + {{36, 5180, 689}, {40, 5200, 689}, + {44, 5220, 669}, {48, 5240, 669}, + {52, 5260, 662}, {56, 5280, 662}, + {60, 5300, 609}, {64, 5320, 609}, + {100, 5500, 538}, {104, 5520, 538}, + {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, + {124, 5620, 247}, {128, 5640, 247}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {136, - {{36, 703}, {40, 703}, - {44, 688}, {48, DFS_TX_LEAKAGE_MIN}, - {52, 671}, {56, 671}, - {60, 658}, {64, 658}, - {100, 504}, {104, 504}, - {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, - {124, 289}, {128, 289}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {136, 5680, + {{36, 5180, 703}, {40, 5200, 703}, + {44, 5220, 688}, {48, 5240, DFS_TX_LEAKAGE_MIN}, + {52, 5260, 671}, {56, 5280, 671}, + {60, 5300, 658}, {64, 5320, 658}, + {100, 5500, 504}, {104, 5520, 504}, + {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, + {124, 5620, 289}, {128, 5640, 289}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {140, - {{36, 695}, {40, 695}, - {44, 684}, {48, 684}, - {52, 664}, {56, 664}, - {60, 658}, {64, 658}, - {100, 601}, {104, 601}, - {108, 545}, {112, 545}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, - {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, - {132, 262}, {136, 262}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {140, 5700, + {{36, 5180, 695}, {40, 5200, 695}, + {44, 5220, 684}, {48, 5240, 684}, + {52, 5260, 664}, {56, 5280, 664}, + {60, 5300, 658}, {64, 5320, 658}, + {100, 5500, 601}, {104, 5520, 601}, + {108, 5540, 545}, {112, 5560, 545}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, + {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, + {132, 5660, 262}, {136, 5680, 262}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {144, - {{36, 695}, {40, 695}, - {44, 684}, {48, 684}, - {52, 664}, {56, 664}, - {60, 658}, {64, 658}, - {100, 601}, {104, 601}, - {108, 545}, {112, 545}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, DFS_TX_LEAKAGE_AUTO_MIN}, - {124, DFS_TX_LEAKAGE_AUTO_MIN}, {128, DFS_TX_LEAKAGE_AUTO_MIN}, - {132, 262}, {136, 262}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {144, 5720, + {{36, 5180, 695}, {40, 5200, 695}, + {44, 5220, 684}, {48, 5240, 684}, + {52, 5260, 664}, {56, 5280, 664}, + {60, 5300, 658}, {64, 5320, 658}, + {100, 5500, 601}, {104, 5520, 601}, + {108, 5540, 545}, {112, 5560, 545}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, DFS_TX_LEAKAGE_AUTO_MIN}, + {124, 5620, DFS_TX_LEAKAGE_AUTO_MIN}, {128, 5640, DFS_TX_LEAKAGE_AUTO_MIN}, + {132, 5660, 262}, {136, 5680, 262}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, }; /* channel tx leakage table - ht20 */ struct dfs_matrix_tx_leak_info ht20_chan[] = { - {52, - {{36, DFS_TX_LEAKAGE_AUTO_MIN}, {40, 286}, - {44, 225}, {48, 121}, - {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, - {60, 300}, {64, DFS_TX_LEAKAGE_AUTO_MIN}, - {100, 637}, {104, DFS_TX_LEAKAGE_MAX}, - {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {52, 5260, + {{36, 5180,DFS_TX_LEAKAGE_AUTO_MIN}, {40, 5200, 286}, + {44, 5220, 225}, {48,5240, 121}, + {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, + {60, 5300, 300}, {64, 5320, DFS_TX_LEAKAGE_AUTO_MIN}, + {100, 5500, 637}, {104, 5520, DFS_TX_LEAKAGE_MAX}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {56, - {{36, 468}, {40, DFS_TX_LEAKAGE_AUTO_MIN}, - {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 206}, - {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, - {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {56, 5280, + {{36, 5180, 468}, {40, 5200, DFS_TX_LEAKAGE_AUTO_MIN}, + {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 5240, 206}, + {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {60, - {{36, 507}, {40, 440}, - {44, DFS_TX_LEAKAGE_AUTO_MIN}, {48, 313}, - {52, DFS_TX_LEAKAGE_MIN}, {56, DFS_TX_LEAKAGE_MIN}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, - {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {60, 5300, + {{36, 5180, 507}, {40, 5200, 440}, + {44, 5220, DFS_TX_LEAKAGE_AUTO_MIN}, {48,5240, 313}, + {52, 5260, DFS_TX_LEAKAGE_MIN}, {56, 5280, DFS_TX_LEAKAGE_MIN}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {64, - {{36, 516}, {40, 520}, - {44, 506}, {48, DFS_TX_LEAKAGE_AUTO_MIN}, - {52, 301}, {56, 258}, - {60, DFS_TX_LEAKAGE_MIN}, {64, DFS_TX_LEAKAGE_MIN}, - {100, 620}, {104, 617}, - {108, DFS_TX_LEAKAGE_MAX}, {112, DFS_TX_LEAKAGE_MAX}, - {116, DFS_TX_LEAKAGE_MAX}, {120, DFS_TX_LEAKAGE_MAX}, - {124, DFS_TX_LEAKAGE_MAX}, {128, DFS_TX_LEAKAGE_MAX}, - {132, DFS_TX_LEAKAGE_MAX}, {136, DFS_TX_LEAKAGE_MAX}, - {140, DFS_TX_LEAKAGE_MAX}, - {144, DFS_TX_LEAKAGE_MIN} + {64, 5320 , + {{36, 5180, 516}, {40, 5200, 520}, + {44, 5220, 506}, {48, 5240,DFS_TX_LEAKAGE_AUTO_MIN}, + {52, 5260, 301}, {56, 5280, 258}, + {60, 5300, DFS_TX_LEAKAGE_MIN}, {64, 5320, DFS_TX_LEAKAGE_MIN}, + {100, 5500, 620}, {104, 5520, 617}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, DFS_TX_LEAKAGE_MAX}, + {116, 5580, DFS_TX_LEAKAGE_MAX}, {120, 5600, DFS_TX_LEAKAGE_MAX}, + {124, 5620, DFS_TX_LEAKAGE_MAX}, {128, 5640, DFS_TX_LEAKAGE_MAX}, + {132, 5660, DFS_TX_LEAKAGE_MAX}, {136, 5680, DFS_TX_LEAKAGE_MAX}, + {140, 5700, DFS_TX_LEAKAGE_MAX}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {100, - {{36, 616}, {40, 601}, - {44, 604}, {48, 589}, - {52, 612}, {56, 592}, - {60, 590}, {64, 582}, - {100, DFS_TX_LEAKAGE_MIN}, {104, 131}, - {108, DFS_TX_LEAKAGE_AUTO_MIN}, {112, DFS_TX_LEAKAGE_AUTO_MIN}, - {116, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 522}, - {124, 571}, {128, 589}, - {132, 593}, {136, 598}, - {140, 594}, - {144, DFS_TX_LEAKAGE_MIN}, + {100, 5500, + {{36, 5180, 616}, {40, 5200, 601}, + {44, 5220, 604}, {48, 5240, 589}, + {52, 5260, 612}, {56, 5280, 592}, + {60, 5300, 590}, {64, 5320, 582}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, 131}, + {108, 5540, DFS_TX_LEAKAGE_AUTO_MIN}, {112, 5560, DFS_TX_LEAKAGE_AUTO_MIN}, + {116, 5580, DFS_TX_LEAKAGE_AUTO_MIN}, {120, 5600, 522}, + {124, 5620, 571}, {128, 5640, 589}, + {132, 5660, 593}, {136, 5680, 598}, + {140, 5700, 594}, + {144, 5720, DFS_TX_LEAKAGE_MIN}, } }, - {104, - {{36, 622}, {40, 624}, - {44, 618}, {48, 610}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, DFS_TX_LEAKAGE_MIN}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, 463}, - {116, 483}, {120, 503}, - {124, 523}, {128, 565}, - {132, 570}, {136, 588}, - {140, 585}, - {144, DFS_TX_LEAKAGE_MIN}, + {104, 5520, + {{36, 5180, 622}, {40, 5200, 624}, + {44, 5220, 618}, {48, 5240, 610}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, DFS_TX_LEAKAGE_MIN}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, 463}, + {116, 5580, 483}, {120, 5600, 503}, + {124, 5620, 523}, {128, 5640, 565}, + {132, 5660, 570}, {136, 5680, 588}, + {140, 5700, 585}, + {144, 5720, DFS_TX_LEAKAGE_MIN}, } }, - {108, - {{36, 620}, {40, 638}, - {44, 611}, {48, 614}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 477}, {104, DFS_TX_LEAKAGE_MIN}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, 477}, {120, 497}, - {124, 517}, {128, 537}, - {132, 557}, {136, 577}, - {140, 603}, - {144, DFS_TX_LEAKAGE_MIN}, + {108, 5540, + {{36, 5180, 620}, {40, 5200, 638}, + {44, 5220, 611}, {48, 5240, 614}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 477}, {104, 5520, DFS_TX_LEAKAGE_MIN}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, 477}, {120, 5600, 497}, + {124, 5620, 517}, {128, 5640, 537}, + {132, 5660, 557}, {136, 5680, 577}, + {140, 5700, 603}, + {144, 5720, DFS_TX_LEAKAGE_MIN}, } }, - {112, - {{36, 636}, {40, 623}, - {44, 638}, {48, 628}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MAX}, {64, 606}, - {100, 501}, {104, 481}, - {108, DFS_TX_LEAKAGE_MIN}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, 481}, - {124, 501}, {128, 421}, - {132, 541}, {136, 561}, - {140, 583}, - {144, DFS_TX_LEAKAGE_MIN}, + {112, 5560, + {{36, 5180, 636}, {40, 5200, 623}, + {44, 5220, 638}, {48, 5240, 628}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, 606}, + {100, 5500, 501}, {104, 5520, 481}, + {108, 5540, DFS_TX_LEAKAGE_MIN}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, 481}, + {124, 5620, 501}, {128, 5640, 421}, + {132, 5660, 541}, {136, 5680, 561}, + {140, 5700, 583}, + {144, 5720, DFS_TX_LEAKAGE_MIN}, } }, - {116, - {{36, 646}, {40, 648}, - {44, 633}, {48, 634}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, 615}, {64, 594}, - {100, 575}, {104, 554}, - {108, 534}, {112, DFS_TX_LEAKAGE_MIN}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, 534}, {136, 554}, - {140, 574}, - {144, DFS_TX_LEAKAGE_MIN}, + {116, 5580, + {{36, 5180, 646}, {40, 5200, 648}, + {44, 5220, 633}, {48, 5240, 634}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, 615}, {64, 5320, 594}, + {100, 5500, 575}, {104, 5520, 554}, + {108, 5540, 534}, {112, 5560, DFS_TX_LEAKAGE_MIN}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, 534}, {136, 5680, 554}, + {140, 5700, 574}, + {144, 5720, DFS_TX_LEAKAGE_MIN}, } }, - {120, - {{36, 643}, {40, 649}, - {44, 654}, {48, 629}, - {52, DFS_TX_LEAKAGE_MAX}, {56, 621}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 565}, {104, 545}, - {108, 525}, {112, 505}, - {116, DFS_TX_LEAKAGE_MIN}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, 505}, - {132, 525}, {136, 545}, - {140, 565}, - {144, DFS_TX_LEAKAGE_MIN}, + {120, 5600, + {{36, 5180, 643}, {40, 5200, 649}, + {44, 5220, 654}, {48, 5240, 629}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, 621}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 565}, {104, 5520, 545}, + {108, 5540, 525}, {112, 5560, 505}, + {116, 5580, DFS_TX_LEAKAGE_MIN}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, 505}, + {132, 5660, 525}, {136, 5680, 545}, + {140, 5700, 565}, + {144, 5720, DFS_TX_LEAKAGE_MIN}, } }, - {124, - {{36, 638}, {40, 657}, - {44, 663}, {48, 649}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 581}, {104, 561}, - {108, 541}, {112, 521}, - {116, 499}, {120, DFS_TX_LEAKAGE_MIN}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, 499}, {136, 519}, - {140, 539}, - {144, DFS_TX_LEAKAGE_MIN} + {124, 5620, + {{36, 5180, 638}, {40, 5200, 657}, + {44, 5220, 663}, {48, 5240, 649}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 581}, {104, 5520, 561}, + {108, 5540, 541}, {112, 5560, 521}, + {116, 5580, 499}, {120, 5600, DFS_TX_LEAKAGE_MIN}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, 499}, {136, 5680, 519}, + {140, 5700, 539}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {128, - {{36, 651}, {40, 651}, - {44, 674}, {48, 640}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, 603}, {104, 560}, - {108, 540}, {112, 520}, - {116, 499}, {120, 479}, - {124, DFS_TX_LEAKAGE_MIN}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, 479}, - {140, 499}, - {144, DFS_TX_LEAKAGE_MIN} + {128, 5640, + {{36, 5180, 651}, {40, 5200, 651}, + {44, 5220, 674}, {48, 5240, 640}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, 603}, {104, 5520, 560}, + {108, 5540, 540}, {112, 5560, 520}, + {116, 5580, 499}, {120, 5600, 479}, + {124, 5620, DFS_TX_LEAKAGE_MIN}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, 479}, + {140, 5700, 499}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {132, - {{36, 643}, {40, 668}, - {44, 651}, {48, 657}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, DFS_TX_LEAKAGE_MAX}, {104, 602}, - {108, 578}, {112, 570}, - {116, 550}, {120, 530}, - {124, 510}, {128, DFS_TX_LEAKAGE_MIN}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, 490}, - {144, DFS_TX_LEAKAGE_MIN} + {132, 5660, + {{36, 5180, 643}, {40, 5200, 668}, + {44, 5220, 651}, {48, 5240, 657}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, 602}, + {108, 5540, 578}, {112,5560, 570}, + {116, 5580, 550}, {120, 5600, 530}, + {124, 5620, 510}, {128, 5640, DFS_TX_LEAKAGE_MIN}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, 490}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {136, - {{36, 654}, {40, 667}, - {44, 666}, {48, 642}, - {52, DFS_TX_LEAKAGE_MAX}, {56, DFS_TX_LEAKAGE_MAX}, - {60, DFS_TX_LEAKAGE_MAX}, {64, DFS_TX_LEAKAGE_MAX}, - {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, - {108, DFS_TX_LEAKAGE_MAX}, {112, 596}, - {116, 555}, {120, 535}, - {124, 515}, {128, 495}, - {132, DFS_TX_LEAKAGE_MIN}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {136,5680, + {{36, 5180, 654}, {40, 5200, 667}, + {44, 5220, 666}, {48, 5240, 642}, + {52, 5260, DFS_TX_LEAKAGE_MAX}, {56, 5280, DFS_TX_LEAKAGE_MAX}, + {60, 5300, DFS_TX_LEAKAGE_MAX}, {64, 5320, DFS_TX_LEAKAGE_MAX}, + {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 596}, + {116, 5580, 555}, {120, 5600, 535}, + {124, 5620, 515}, {128, 5640, 495}, + {132, 5660, DFS_TX_LEAKAGE_MIN}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {140, - {{36, 679}, {40, 673}, - {44, 667}, {48, 656}, - {52, 634}, {56, 663}, - {60, 662}, {64, 660}, - {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, - {108, DFS_TX_LEAKAGE_MAX}, {112, 590}, - {116, 573}, {120, 553}, - {124, 533}, {128, 513}, - {132, 490}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {140,5700, + {{36, 5180, 679}, {40, 5200, 673}, + {44, 5220, 667}, {48, 5240, 656}, + {52, 5260, 634}, {56, 5280, 663}, + {60, 5300, 662}, {64, 5320, 660}, + {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 590}, + {116, 5580, 573}, {120, 5600, 553}, + {124, 5620, 533}, {128, 5640, 513}, + {132, 5660, 490}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, - {144, - {{36, 679}, {40, 673}, - {44, 667}, {48, 656}, - {52, 634}, {56, 663}, - {60, 662}, {64, 660}, - {100, DFS_TX_LEAKAGE_MAX}, {104, DFS_TX_LEAKAGE_MAX}, - {108, DFS_TX_LEAKAGE_MAX}, {112, 590}, - {116, 573}, {120, 553}, - {124, 533}, {128, 513}, - {132, 490}, {136, DFS_TX_LEAKAGE_MIN}, - {140, DFS_TX_LEAKAGE_MIN}, - {144, DFS_TX_LEAKAGE_MIN} + {144,5720, + {{36, 5180, 679}, {40, 5200, 673}, + {44, 5220, 667}, {48, 5240, 656}, + {52, 5260, 634}, {56, 5280, 663}, + {60, 5300, 662}, {64, 5320, 660}, + {100, 5500, DFS_TX_LEAKAGE_MAX}, {104, 5520, DFS_TX_LEAKAGE_MAX}, + {108, 5540, DFS_TX_LEAKAGE_MAX}, {112, 5560, 590}, + {116, 5580, 573}, {120, 5600, 553}, + {124, 5620, 533}, {128, 5640, 513}, + {132, 5660, 490}, {136, 5680, DFS_TX_LEAKAGE_MIN}, + {140, 5700, DFS_TX_LEAKAGE_MIN}, + {144, 5720, DFS_TX_LEAKAGE_MIN} } }, }; @@ -723,6 +723,7 @@ struct dfs_matrix_tx_leak_info ht20_chan[] = { * * Return: TRUE or FALSE */ +#ifdef CONFIG_CHAN_NUM_API static bool dfs_find_target_channel_in_channel_matrix(enum phy_ch_width ch_width, uint8_t NOL_channel, @@ -771,7 +772,72 @@ dfs_find_target_channel_in_channel_matrix(enum phy_ch_width ch_width, return true; } } +#endif +/* + * dfs_find_target_channel_in_channel_matrix_for_freq() - finds the leakage + * matrix. + * @chan_width: target channel width + * @nol_channel: the NOL channel frequency whose leakage matrix is required + * @pTarget_chnl_mtrx: pointer to target channel matrix returned. + * + * This function gives the leakage matrix for given NOL channel and ch_width + * + * Return: TRUE or FALSE + */ +#ifdef CONFIG_CHAN_FREQ_API +static bool +dfs_find_target_channel_in_channel_matrix_for_freq(enum phy_ch_width chan_width, + uint16_t nol_freq, + struct dfs_tx_leak_info + **pTarget_chnl_mtrx) +{ + struct dfs_tx_leak_info *target_chan_matrix = NULL; + struct dfs_matrix_tx_leak_info *pchan_matrix = NULL; + uint32_t nchan_matrix; + int i = 0; + + switch (chan_width) { + case CH_WIDTH_20MHZ: + /* HT20 */ + pchan_matrix = ht20_chan; + nchan_matrix = QDF_ARRAY_SIZE(ht20_chan); + break; + case CH_WIDTH_40MHZ: + /* HT40 */ + pchan_matrix = ht40_chan; + nchan_matrix = QDF_ARRAY_SIZE(ht40_chan); + break; + case CH_WIDTH_80MHZ: + /* HT80 */ + pchan_matrix = ht80_chan; + nchan_matrix = QDF_ARRAY_SIZE(ht80_chan); + break; + default: + /* handle exception and fall back to HT20 table */ + pchan_matrix = ht20_chan; + nchan_matrix = QDF_ARRAY_SIZE(ht20_chan); + break; + } + + for (i = 0; i < nchan_matrix; i++) { + /* find the SAP channel to map the leakage matrix */ + if (nol_freq == pchan_matrix[i].channel_freq) { + target_chan_matrix = pchan_matrix[i].chan_matrix; + break; + } + } + + if (!target_chan_matrix) { + return false; + } else { + *pTarget_chnl_mtrx = target_chan_matrix; + return true; + } +} +#endif + +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS dfs_mark_leaking_ch(struct wlan_dfs *dfs, enum phy_ch_width ch_width, @@ -838,7 +904,79 @@ dfs_mark_leaking_ch(struct wlan_dfs *dfs, return QDF_STATUS_SUCCESS; } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +#define END_CHAN_INDEX CHAN_ENUM_5720 +#define START_CHAN_INDEX CHAN_ENUM_5180 +QDF_STATUS +dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs, + enum phy_ch_width ch_width, + uint8_t temp_chan_lst_sz, + uint16_t *temp_freq_lst) +{ + struct dfs_tx_leak_info *target_chan_matrix = NULL; + uint32_t num_channel = (END_CHAN_INDEX - START_CHAN_INDEX) + 1; + uint32_t j = 0; + uint32_t k = 0; + struct dfs_nolelem *nol; + + nol = dfs->dfs_nol; + while (nol) { + if (false == dfs_find_target_channel_in_channel_matrix_for_freq( + ch_width, nol->nol_freq, + &target_chan_matrix)) { + /* + * should never happen, we should always find a table + * here, if we don't, need a fix here! + */ + dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "Couldn't find target channel matrix!"); + QDF_ASSERT(0); + return QDF_STATUS_E_FAILURE; + } + /* + * following is based on assumption that both temp_freq_lst + * and target channel matrix are in increasing order of + * ch_id + */ + for (j = 0, k = 0; j < temp_chan_lst_sz && k < num_channel;) { + if (temp_freq_lst[j] == 0) { + j++; + continue; + } + if (target_chan_matrix[k].leak_chan_freq != + temp_freq_lst[j]) { + k++; + continue; + } + /* + * check leakage from candidate channel + * to NOL channel + */ + if (target_chan_matrix[k].leak_lvl <= + dfs->tx_leakage_threshold) { + /* + * candidate channel will have + * bad leakage in NOL channel, + * remove from temp list + */ + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "dfs: channel: %d will have bad leakage due to channel: %d\n", + dfs_nol_channel, temp_freq_lst[j]); + temp_freq_lst[j] = 0; + } + j++; + k++; + } + nol = nol->nol_next; + } /* end of loop that selects each NOL */ + + return QDF_STATUS_SUCCESS; +} +#endif #else +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS dfs_mark_leaking_ch(struct wlan_dfs *dfs, enum phy_ch_width ch_width, @@ -848,18 +986,30 @@ dfs_mark_leaking_ch(struct wlan_dfs *dfs, return QDF_STATUS_SUCCESS; } #endif +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS +dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs, + enum phy_ch_width ch_width, + uint8_t temp_chan_lst_sz, + uint16_t *temp_freq_lst) +{ + return QDF_STATUS_SUCCESS; +} +#endif +#endif /** * dfs_populate_80mhz_available_channels()- Populate channels for 80MHz using * bitmap * @dfs: Pointer to DFS structure. * @bitmap: bitmap - * @avail_chnl: prepared channel list + * @avail_freq_list: prepared channel list * * Prepare 80MHz channels from the bitmap. * * Return: channel count */ +#ifdef CONFIG_CHAN_NUM_API static uint8_t dfs_populate_80mhz_available_channels( struct wlan_dfs *dfs, struct chan_bonding_bitmap *bitmap, @@ -889,6 +1039,46 @@ static uint8_t dfs_populate_80mhz_available_channels( return chnl_count; } +#endif + +/* + * dfs_populate_80mhz_available_channel_for_freq() - Populate 80MHZ channels + * available for selection. + * @dfs: Pointer to wlan_dfs. + * @bitmap: Pointer to bonding channel bitmap. + * @avail_freq_list: Pointer to frequency list of available channels. + */ +#ifdef CONFIG_CHAN_FREQ_API +static uint8_t dfs_populate_80mhz_available_channel_for_freq( + struct wlan_dfs *dfs, + struct chan_bonding_bitmap *bitmap, + uint16_t *avail_freq_list) +{ + uint8_t i = 0; + uint8_t chnl_count = 0; + uint16_t start_chan_freq = 0; + + for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { + start_chan_freq = bitmap->chan_bonding_set[i].start_chan_freq; + if (bitmap->chan_bonding_set[i].chan_map == + DFS_80MHZ_MASK) { + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 0); + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 1); + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 2); + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 3); + } + } + + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "channel count %d", chnl_count); + + return chnl_count; +} +#endif /** * dfs_populate_40mhz_available_channels()- Populate channels for 40MHz using @@ -901,6 +1091,7 @@ static uint8_t dfs_populate_80mhz_available_channels( * * Return: channel count */ +#ifdef CONFIG_CHAN_NUM_API static uint8_t dfs_populate_40mhz_available_channels( struct wlan_dfs *dfs, struct chan_bonding_bitmap *bitmap, @@ -933,6 +1124,42 @@ static uint8_t dfs_populate_40mhz_available_channels( return chnl_count; } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +static uint8_t +dfs_populate_40mhz_available_channel_for_freq(struct wlan_dfs *dfs, + struct chan_bonding_bitmap *bmap, + uint16_t *avail_freq_list) +{ + uint8_t i = 0; + uint8_t chnl_count = 0; + uint16_t start_chan_freq = 0; + + for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { + start_chan_freq = bmap->chan_bonding_set[i].start_chan_freq; + if ((bmap->chan_bonding_set[i].chan_map & + DFS_40MHZ_MASK_L) == DFS_40MHZ_MASK_L) { + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 0); + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 1); + } + if ((bmap->chan_bonding_set[i].chan_map & + DFS_40MHZ_MASK_H) == DFS_40MHZ_MASK_H) { + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 2); + avail_freq_list[chnl_count++] = start_chan_freq + + (DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET * 3); + } + } + + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "channel count %d", chnl_count); + + return chnl_count; +} +#endif /** * dfs_populate_available_channels()- Populate channels based on width and @@ -946,6 +1173,7 @@ static uint8_t dfs_populate_40mhz_available_channels( * * Return: channel count */ +#ifdef CONFIG_CHAN_NUM_API static uint8_t dfs_populate_available_channels( struct wlan_dfs *dfs, struct chan_bonding_bitmap *bitmap, @@ -969,6 +1197,47 @@ static uint8_t dfs_populate_available_channels( return 0; } +#endif + +/** + * dfs_populate_available_channel_for_freq()- Populate channels based on width + * and bitmap. + * @dfs: Pointer to DFS structure. + * @bitmap: bitmap + * @chan_width: channel width + * @avail_freq_list: prepared channel list + * + * Prepare channel list based on width and channel bitmap. + * + * Return: channel count + */ +#ifdef CONFIG_CHAN_FREQ_API +static uint8_t +dfs_populate_available_channel_for_freq(struct wlan_dfs *dfs, + struct chan_bonding_bitmap *bitmap, + uint8_t chan_width, + uint16_t *freq_list) +{ + switch (chan_width) { + case DFS_CH_WIDTH_160MHZ: + case DFS_CH_WIDTH_80P80MHZ: + case DFS_CH_WIDTH_80MHZ: + return dfs_populate_80mhz_available_channel_for_freq(dfs, + bitmap, + freq_list); + case DFS_CH_WIDTH_40MHZ: + return dfs_populate_40mhz_available_channel_for_freq(dfs, + bitmap, + freq_list); + default: + dfs_err(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "Invalid chan_width %d", chan_width); + break; + } + + return 0; +} +#endif /** * dfs_get_rand_from_lst()- Get random channel from a given channel list @@ -980,6 +1249,7 @@ static uint8_t dfs_populate_available_channels( * * Return: channel number */ +#ifdef CONFIG_CHAN_NUM_API static uint8_t dfs_get_rand_from_lst( struct wlan_dfs *dfs, uint8_t *ch_lst, @@ -1003,6 +1273,44 @@ static uint8_t dfs_get_rand_from_lst( return ch_lst[i]; } +#endif + +/** + * dfs_get_rand_from_lst_for_freq()- Get random channel from a given channel + * list. + * @dfs: Pointer to DFS structure. + * @freq_lst: Frequency list + * @num_chan: number of channels + * + * Get random channel from given channel list. + * + * Return: channel frequency. + */ + +#ifdef CONFIG_CHAN_FREQ_API +static uint16_t dfs_get_rand_from_lst_for_freq(struct wlan_dfs *dfs, + uint16_t *freq_lst, + uint8_t num_chan) +{ + uint8_t i; + uint32_t rand_byte = 0; + + if (!num_chan || !freq_lst) { + dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, + "invalid param freq_lst %pK, num_chan = %d", + freq_lst, num_chan); + return 0; + } + + get_random_bytes((uint8_t *)&rand_byte, 1); + i = (rand_byte + qdf_mc_timer_get_system_ticks()) % num_chan; + + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "random channel %d", freq_lst[i]); + + return freq_lst[i]; +} +#endif /** * dfs_random_channel_sel_set_bitmap()- Set channel bit in bitmap based @@ -1015,6 +1323,7 @@ static uint8_t dfs_get_rand_from_lst( * * Return: None */ +#ifdef CONFIG_CHAN_NUM_API static void dfs_random_channel_sel_set_bitmap( struct wlan_dfs *dfs, struct chan_bonding_bitmap *bitmap, @@ -1036,6 +1345,45 @@ static void dfs_random_channel_sel_set_bitmap( dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "Channel=%d is not in the bitmap", channel); } +#endif + +/** + * dfs_random_channel_sel_set_bitmap()- Set channel bit in bitmap based + * on given channel number + * @dfs: Pointer to DFS structure. + * @bitmap: bitmap + * @chan_freq: channel frequency + * + * Set channel bit in bitmap based on given channel frequency. + * + * Return: None + */ +#ifdef CONFIG_CHAN_FREQ_API +#define FREQUENCY_BAND_LIMIT 60 +static void +dfs_random_channel_sel_set_bitmap_for_freq(struct wlan_dfs *dfs, + struct chan_bonding_bitmap *bitmap, + uint16_t chan_freq) +{ + int i = 0; + int start_chan_freq = 0; + + for (i = 0; i < DFS_MAX_80MHZ_BANDS; i++) { + start_chan_freq = bitmap->chan_bonding_set[i].start_chan_freq; + if (chan_freq >= start_chan_freq && + chan_freq <= start_chan_freq + + FREQUENCY_BAND_LIMIT) { + bitmap->chan_bonding_set[i].chan_map |= + (1 << ((chan_freq - start_chan_freq) / + DFS_80_NUM_SUB_CHANNEL_FREQ)); + return; + } + } + + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "Frequency=%d is not in the bitmap", chan_freq); +} +#endif /** * dfs_find_ch_with_fallback()- find random channel @@ -1050,6 +1398,7 @@ static void dfs_random_channel_sel_set_bitmap( * * Return: channel number */ +#ifdef CONFIG_CHAN_NUM_API static uint8_t dfs_find_ch_with_fallback( struct wlan_dfs *dfs, uint8_t *ch_wd, @@ -1184,6 +1533,159 @@ static uint8_t dfs_find_ch_with_fallback( return target_channel; } +#endif + +/** + * dfs_find_ch_with_fallback_for_freq()- find random channel + * @dfs: Pointer to DFS structure. + * @chan_wd: channel width + * @center_freq_seg1: center frequency of secondary segment. + * @freq_lst: list of available frequency. + * @num_chan: number of channels in the list. + * + * Find random channel based on given channel width and channel list, + * fallback to lower width if requested channel width not available. + * + * Return: channel frequency. + */ +#ifdef CONFIG_CHAN_FREQ_API +static uint16_t dfs_find_ch_with_fallback_for_freq(struct wlan_dfs *dfs, + uint8_t *chan_wd, + uint16_t *center_freq_seg1, + uint16_t *freq_lst, + uint32_t num_chan) +{ + bool flag = false; + uint32_t rand_byte = 0; + struct chan_bonding_bitmap ch_map = { { {0} } }; + uint8_t count = 0, i, index = 0, final_cnt = 0; + uint16_t target_channel = 0; + uint16_t primary_seg_start_ch = 0, sec_seg_ch = 0, new_160_start_ch = 0; + uint16_t final_lst[DFS_MAX_NUM_CHAN] = {0}; + + /* initialize ch_map for all 80 MHz bands: we have 6 80MHz bands */ + ch_map.chan_bonding_set[0].start_chan_freq = 5180; + ch_map.chan_bonding_set[1].start_chan_freq = 5260; + ch_map.chan_bonding_set[2].start_chan_freq = 5500; + ch_map.chan_bonding_set[3].start_chan_freq = 5580; + ch_map.chan_bonding_set[4].start_chan_freq = 5660; + ch_map.chan_bonding_set[5].start_chan_freq = 5745; + + for (i = 0; i < num_chan; i++) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "channel = %d added to bitmap", freq_lst[i]); + dfs_random_channel_sel_set_bitmap_for_freq(dfs, &ch_map, + freq_lst[i]); + } + + /* populate available channel list from bitmap */ + final_cnt = dfs_populate_available_channel_for_freq(dfs, &ch_map, + *chan_wd, final_lst); + + /* If no valid ch bonding found, fallback */ + if (final_cnt == 0) { + if ((*chan_wd == DFS_CH_WIDTH_160MHZ) || + (*chan_wd == DFS_CH_WIDTH_80P80MHZ) || + (*chan_wd == DFS_CH_WIDTH_80MHZ)) { + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "from [%d] to 40Mhz", *chan_wd); + *chan_wd = DFS_CH_WIDTH_40MHZ; + } else if (*chan_wd == DFS_CH_WIDTH_40MHZ) { + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "from 40Mhz to 20MHz"); + *chan_wd = DFS_CH_WIDTH_20MHZ; + } + return 0; + } + + /* ch count should be > 8 to switch new channel in 160Mhz band */ + if (((*chan_wd == DFS_CH_WIDTH_160MHZ) || + (*chan_wd == DFS_CH_WIDTH_80P80MHZ)) && + (final_cnt < DFS_MAX_20M_SUB_CH)) { + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "from [%d] to 80Mhz", *chan_wd); + *chan_wd = DFS_CH_WIDTH_80MHZ; + return 0; + } + + if (*chan_wd == DFS_CH_WIDTH_160MHZ) { + /* + * Only 2 blocks for 160Mhz bandwidth i.e 36-64 & 100-128 + * and all the channels in these blocks are continuous + * and separated by 4Mhz. + */ + for (i = 1; ((i < final_cnt)); i++) { + if ((final_lst[i] - final_lst[i - 1]) == + DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET) + count++; + else + count = 0; + if (count == DFS_MAX_20M_SUB_CH - 1) { + flag = true; + new_160_start_ch = final_lst[i - count]; + break; + } + } + } else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) { + flag = true; + } + + if ((flag == false) && (*chan_wd > DFS_CH_WIDTH_80MHZ)) { + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "from [%d] to 80Mhz", *chan_wd); + *chan_wd = DFS_CH_WIDTH_80MHZ; + return 0; + } + + if (*chan_wd == DFS_CH_WIDTH_160MHZ) { + get_random_bytes((uint8_t *)&rand_byte, 1); + rand_byte = (rand_byte + qdf_mc_timer_get_system_ticks()) + % DFS_MAX_20M_SUB_CH; + target_channel = new_160_start_ch + (rand_byte * + DFS_80_NUM_SUB_CHANNEL_FREQ); + } else if (*chan_wd == DFS_CH_WIDTH_80P80MHZ) { + get_random_bytes((uint8_t *)&rand_byte, 1); + index = (rand_byte + qdf_mc_timer_get_system_ticks()) % + final_cnt; + target_channel = final_lst[index]; + index -= (index % DFS_80_NUM_SUB_CHANNEL_FREQ); + primary_seg_start_ch = final_lst[index]; + + /* reset channels associate with primary 80Mhz */ + for (i = 0; i < DFS_80_NUM_SUB_CHANNEL; i++) + final_lst[i + index] = 0; + /* select and calculate center freq for secondary segment */ + for (i = 0; i < final_cnt / DFS_80_NUM_SUB_CHANNEL; i++) { + if (final_lst[i * DFS_80_NUM_SUB_CHANNEL_FREQ] && + (abs(primary_seg_start_ch - + final_lst[i * DFS_80_NUM_SUB_CHANNEL_FREQ]) > + (DFS_MAX_20M_SUB_CH * 2))) { + sec_seg_ch = final_lst[i * + DFS_80_NUM_SUB_CHANNEL_FREQ] + + DFS_80MHZ_START_CENTER_CH_FREQ_DIFF; + break; + } + } + + if (!sec_seg_ch && (final_cnt == DFS_MAX_20M_SUB_CH)) + *chan_wd = DFS_CH_WIDTH_160MHZ; + else if (!sec_seg_ch) + *chan_wd = DFS_CH_WIDTH_80MHZ; + + *center_freq_seg1 = sec_seg_ch; + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "Center frequency seg1 = %d", sec_seg_ch); + } else { + target_channel = dfs_get_rand_from_lst_for_freq(dfs, + final_lst, + final_cnt); + } + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "target channel = %d", target_channel); + + return target_channel; +} +#endif /** * dfs_remove_cur_ch_from_list()- remove current operating channels @@ -1241,8 +1743,9 @@ bool dfs_is_freq_in_nol(struct wlan_dfs *dfs, uint32_t freq) * * prepare channel list based on flags * - * Return: None + * return: none */ +#ifdef CONFIG_CHAN_NUM_API static void dfs_apply_rules(struct wlan_dfs *dfs, uint32_t flags, uint8_t *random_chan_list, @@ -1379,7 +1882,163 @@ static void dfs_apply_rules(struct wlan_dfs *dfs, *random_chan_cnt += 1; } } +#endif +/** + * dfs_apply_rules_for_freq()- prepare channel list based on flags + * @dfs: dfs handler + * @flags: channel flags + * @random_chan_freq_list: output channel list + * @random_chan_cnt: output channel count + * @chan_list: input channel list + * @chan_cnt: input channel count + * @dfs_region: dfs region + * @acs_info: acs channel range information + * + * prepare channel list based on flags + * + * return: none + */ +#ifdef CONFIG_CHAN_FREQ_API +static void dfs_apply_rules_for_freq(struct wlan_dfs *dfs, + uint32_t flags, + uint16_t *random_chan_freq_list, + uint32_t *random_chan_cnt, + struct dfs_channel *chan_list, + uint32_t chan_cnt, + uint8_t dfs_region, + struct dfs_acs_info *acs_info) +{ + struct dfs_channel *chan; + bool flag_no_weather = 0; + bool flag_no_lower_5g = 0; + bool flag_no_upper_5g = 0; + bool flag_no_dfs_chan = 0; + bool flag_no_2g_chan = 0; + bool flag_no_5g_chan = 0; + bool flag_no_japan_w53 = 0; + int i; + bool found = false; + uint16_t j; + + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "flags %d", flags); + flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ? + flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; + + if (dfs_region == DFS_MKK_REGION_VAL) { + flag_no_lower_5g = flags & DFS_RANDOM_CH_FLAG_NO_LOWER_5G_CH; + flag_no_upper_5g = flags & DFS_RANDOM_CH_FLAG_NO_UPEER_5G_CH; + flag_no_japan_w53 = flags & DFS_RANDOM_CH_FLAG_NO_JAPAN_W53_CH; + } + + flag_no_dfs_chan = flags & DFS_RANDOM_CH_FLAG_NO_DFS_CH; + flag_no_2g_chan = flags & DFS_RANDOM_CH_FLAG_NO_2GHZ_CH; + flag_no_5g_chan = flags & DFS_RANDOM_CH_FLAG_NO_5GHZ_CH; + + for (i = 0; i < chan_cnt; i++) { + chan = &chan_list[i]; + + if ((chan->dfs_ch_ieee == 0) || + (chan->dfs_ch_ieee > MAX_CHANNEL_NUM)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "invalid channel %d", chan->dfs_ch_ieee); + continue; + } + + if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) { + /* TODO : Skip all HT20 channels in the given mode */ + if (chan->dfs_ch_freq == + dfs->dfs_curchan->dfs_ch_freq) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip %d current operating channel", + chan->dfs_ch_ieee); + continue; + } + } + if (acs_info && acs_info->acs_mode) { + for (j = 0; j < acs_info->num_of_channel; j++) { + if (acs_info->channel_list[j] == + chan->dfs_ch_ieee) { + found = true; + break; + } + } + + if (!found) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip ch %d not in acs range", + chan->dfs_ch_ieee); + continue; + } + found = false; + } + + if (flag_no_2g_chan && + chan->dfs_ch_freq <= DFS_MAX_24GHZ_CHANNEL_FREQ) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip 2.4 GHz channel=%d", chan->dfs_ch_ieee); + continue; + } + + if (flag_no_5g_chan && chan->dfs_ch_freq > + DFS_MAX_24GHZ_CHANNEL_FREQ) + { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip 5 GHz channel=%d", chan->dfs_ch_ieee); + continue; + } + + if (flag_no_weather) { + if (DFS_IS_CHANNEL_WEATHER_RADAR(chan->dfs_ch_freq)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip weather channel=%d", + chan->dfs_ch_ieee); + continue; + } + } + + if (flag_no_lower_5g && + DFS_IS_CHAN_JAPAN_INDOOR_FREQ(chan->dfs_ch_freq)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip indoor channel=%d", chan->dfs_ch_ieee); + continue; + } + + if (flag_no_upper_5g && + DFS_IS_CHAN_JAPAN_OUTDOOR_FREQ(chan->dfs_ch_freq)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip outdoor channel=%d", chan->dfs_ch_ieee); + continue; + } + + if (flag_no_dfs_chan && + (chan->dfs_ch_flagext & WLAN_CHAN_DFS)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip dfs channel=%d", chan->dfs_ch_ieee); + continue; + } + + if (flag_no_japan_w53 && + DFS_IS_CHAN_JAPAN_W53_FREQ(chan->dfs_ch_freq)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip japan W53 channel=%d", + chan->dfs_ch_ieee); + continue; + } + + if (dfs_is_freq_in_nol(dfs, chan->dfs_ch_freq)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip nol channel=%d", chan->dfs_ch_ieee); + continue; + } + + random_chan_freq_list[*random_chan_cnt] = chan->dfs_ch_freq; + *random_chan_cnt += 1; + } +} +#endif + +#ifdef CONFIG_CHAN_NUM_API uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs, struct dfs_channel *ch_list, uint32_t ch_cnt, @@ -1491,3 +2150,127 @@ uint8_t dfs_prepare_random_channel(struct wlan_dfs *dfs, return target_ch; } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs, + struct dfs_channel *chan_list, + uint32_t chan_cnt, + uint32_t flags, + uint8_t *chan_wd, + struct dfs_channel *cur_chan, + uint8_t dfs_region, + struct dfs_acs_info *acs_info) +{ + int i = 0; + uint8_t final_cnt = 0; + uint16_t target_freq = 0; + uint16_t *random_chan_freq_list = NULL; + uint32_t random_chan_cnt = 0; + uint16_t flag_no_weather = 0; + uint16_t *leakage_adjusted_lst; + uint16_t final_lst[NUM_CHANNELS] = {0}; + uint16_t *dfs_cfreq_seg2 = NULL; + + if (!chan_list || !chan_cnt) { + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "Invalid params %pK, chan_cnt=%d", + chan_list, chan_cnt); + return 0; + } + + if (*chan_wd < DFS_CH_WIDTH_20MHZ || *chan_wd > DFS_CH_WIDTH_80P80MHZ) { + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "Invalid chan_wd %d", *chan_wd); + return 0; + } + + random_chan_freq_list = + qdf_mem_malloc(chan_cnt * sizeof(*random_chan_freq_list)); + if (!random_chan_freq_list) + return 0; + + if (flags & DFS_RANDOM_CH_FLAG_NO_CURR_OPE_CH) + dfs_remove_cur_ch_from_list(chan_list, &chan_cnt, chan_wd, cur_chan); + + dfs_apply_rules_for_freq(dfs, flags, random_chan_freq_list, + &random_chan_cnt, chan_list, chan_cnt, + dfs_region, acs_info); + + flag_no_weather = (dfs_region == DFS_ETSI_REGION_VAL) ? + flags & DFS_RANDOM_CH_FLAG_NO_WEATHER_CH : 0; + + /* list adjusted after leakage has been marked */ + leakage_adjusted_lst = qdf_mem_malloc(random_chan_cnt); + if (!leakage_adjusted_lst) { + qdf_mem_free(random_chan_freq_list); + return 0; + } + + do { + int ret; + + qdf_mem_copy(leakage_adjusted_lst, random_chan_freq_list, + random_chan_cnt); + ret = dfs_mark_leaking_chan_for_freq(dfs, *chan_wd, + random_chan_cnt, + leakage_adjusted_lst); + if (QDF_IS_STATUS_ERROR(ret)) { + qdf_mem_free(random_chan_freq_list); + qdf_mem_free(leakage_adjusted_lst); + return 0; + } + + if (*chan_wd == DFS_CH_WIDTH_20MHZ) { + /* + * PASS: 3 - from leakage_adjusted_lst, prepare valid + * ch list and use random number from that + */ + for (i = 0; i < random_chan_cnt; i++) { + if (leakage_adjusted_lst[i] == 0) + continue; + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "Channel=%d added to available list", + leakage_adjusted_lst[i]); + final_lst[final_cnt] = leakage_adjusted_lst[i]; + final_cnt++; + } + target_freq = dfs_get_rand_from_lst_for_freq(dfs, + final_lst, + final_cnt); + break; + } + dfs_cfreq_seg2 = &cur_chan->dfs_ch_mhz_freq_seg2; + target_freq = + dfs_find_ch_with_fallback_for_freq(dfs, chan_wd, + dfs_cfreq_seg2, + leakage_adjusted_lst, + 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_freq == + DFS_ADJACENT_WEATHER_RADAR_CHANNEL_FREQ) && + (*chan_wd == DFS_CH_WIDTH_40MHZ)) { + dfs_debug(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "skip weather adjacent ch=%d\n", + target_freq); + continue; + } + + if (target_freq) + break; + } while (true); + + qdf_mem_free(random_chan_freq_list); + qdf_mem_free(leakage_adjusted_lst); + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, "target_freq = %d", + target_freq); + + return target_freq; +} +#endif diff --git a/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c b/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c index 880f4b205f57..e4f66c891b5c 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c @@ -71,6 +71,7 @@ bool tgt_dfs_is_pdev_5ghz(struct wlan_objmgr_pdev *pdev) return is_5ghz; } +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS tgt_dfs_set_current_channel(struct wlan_objmgr_pdev *pdev, uint16_t dfs_ch_freq, uint64_t dfs_ch_flags, @@ -101,6 +102,46 @@ QDF_STATUS tgt_dfs_set_current_channel(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } qdf_export_symbol(tgt_dfs_set_current_channel); +#endif + +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS +tgt_dfs_set_current_channel_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t dfs_chan_freq, + uint64_t dfs_chan_flags, + uint16_t dfs_chan_flagext, + uint8_t dfs_chan_ieee, + uint8_t dfs_chan_vhtop_freq_seg1, + uint8_t dfs_chan_vhtop_freq_seg2, + uint16_t dfs_chan_mhz_freq_seg1, + uint16_t dfs_chan_mhz_freq_seg2) +{ + struct wlan_dfs *dfs; + + if (!tgt_dfs_is_pdev_5ghz(pdev)) + return QDF_STATUS_SUCCESS; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return QDF_STATUS_E_FAILURE; + } + + dfs_set_current_channel_for_freq(dfs, + dfs_chan_freq, + dfs_chan_flags, + dfs_chan_flagext, + dfs_chan_ieee, + dfs_chan_vhtop_freq_seg1, + dfs_chan_vhtop_freq_seg2, + dfs_chan_mhz_freq_seg1, + dfs_chan_mhz_freq_seg2); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(tgt_dfs_set_current_channel_for_freq); +#endif QDF_STATUS tgt_dfs_radar_enable(struct wlan_objmgr_pdev *pdev, int no_cac, uint32_t opmode) @@ -379,6 +420,33 @@ QDF_STATUS tgt_dfs_agile_precac_start(struct wlan_objmgr_pdev *pdev) qdf_export_symbol(tgt_dfs_agile_precac_start); #ifdef QCA_SUPPORT_AGILE_DFS +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS tgt_dfs_set_agile_precac_state(struct wlan_objmgr_pdev *pdev, + int agile_precac_state) +{ + struct wlan_dfs *dfs; + int i; + + if (!tgt_dfs_is_pdev_5ghz(pdev)) + return QDF_STATUS_SUCCESS; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return QDF_STATUS_E_FAILURE; + } + + dfs->dfs_soc_obj->precac_state_started = agile_precac_state; + if (!dfs->dfs_soc_obj->precac_state_started) { + for (i = 0; i < dfs->dfs_soc_obj->num_dfs_privs; i++) + dfs->dfs_soc_obj->dfs_priv[i].agile_precac_active = 0; + dfs->dfs_agile_precac_freq_mhz = 0; + } + + return QDF_STATUS_SUCCESS; +} +#else +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS tgt_dfs_set_agile_precac_state(struct wlan_objmgr_pdev *pdev, int agile_precac_state) { @@ -403,6 +471,9 @@ QDF_STATUS tgt_dfs_set_agile_precac_state(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } +#endif +#endif + #else QDF_STATUS tgt_dfs_set_agile_precac_state(struct wlan_objmgr_pdev *pdev, int agile_precac_state) @@ -444,6 +515,7 @@ QDF_STATUS tgt_dfs_ocac_complete(struct wlan_objmgr_pdev *pdev, #endif qdf_export_symbol(tgt_dfs_ocac_complete); +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS tgt_dfs_find_vht80_chan_for_precac(struct wlan_objmgr_pdev *pdev, uint32_t chan_mode, uint8_t ch_freq_seg1, @@ -473,6 +545,41 @@ QDF_STATUS tgt_dfs_find_vht80_chan_for_precac(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } qdf_export_symbol(tgt_dfs_find_vht80_chan_for_precac); +#endif + +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS +tgt_dfs_find_vht80_precac_chan_freq(struct wlan_objmgr_pdev *pdev, + uint32_t chan_mode, + uint16_t chan_freq_seg1_mhz, + uint32_t *cfreq1, + uint32_t *cfreq2, + uint32_t *phy_mode, + bool *dfs_set_cfreq2, + bool *set_agile) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return QDF_STATUS_E_FAILURE; + } + + dfs_find_vht80_chan_for_precac_for_freq(dfs, + chan_mode, + chan_freq_seg1_mhz, + cfreq1, + cfreq2, + phy_mode, + dfs_set_cfreq2, + set_agile); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(tgt_dfs_find_vht80_precac_chan_freq); +#endif QDF_STATUS tgt_dfs_process_radar_ind(struct wlan_objmgr_pdev *pdev, struct radar_found_info *radar_found) diff --git a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c index 29efa363f4b6..19a71db48494 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c @@ -68,6 +68,7 @@ bool utils_dfs_is_freq_in_nol(struct wlan_objmgr_pdev *pdev, uint32_t freq) return dfs_is_freq_in_nol(dfs, freq); } +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS utils_dfs_cac_valid_reset(struct wlan_objmgr_pdev *pdev, uint8_t prevchan_ieee, uint32_t prevchan_flags) @@ -83,6 +84,26 @@ QDF_STATUS utils_dfs_cac_valid_reset(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; } qdf_export_symbol(utils_dfs_cac_valid_reset); +#endif + +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_cac_valid_reset_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t prevchan_freq, + uint32_t prevchan_flags) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) + return QDF_STATUS_E_FAILURE; + + dfs_cac_valid_reset_for_freq(dfs, prevchan_freq, prevchan_flags); + + return QDF_STATUS_SUCCESS; +} + +qdf_export_symbol(utils_dfs_cac_valid_reset_for_freq); +#endif QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev) { @@ -98,6 +119,7 @@ QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev) } qdf_export_symbol(utils_dfs_reset_precaclists); +#ifdef CONFIG_CHAN_NUM_API void utils_dfs_unmark_precac_nol(struct wlan_objmgr_pdev *pdev, uint8_t chan) { struct wlan_dfs *dfs; @@ -110,6 +132,23 @@ void utils_dfs_unmark_precac_nol(struct wlan_objmgr_pdev *pdev, uint8_t chan) } qdf_export_symbol(utils_dfs_unmark_precac_nol); +#endif + +#ifdef CONFIG_CHAN_FREQ_API +void utils_dfs_unmark_precac_nol_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t chan_freq) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) + return; + + dfs_unmark_precac_nol_for_freq(dfs, chan_freq); +} + +qdf_export_symbol(utils_dfs_unmark_precac_nol_for_freq); +#endif QDF_STATUS utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev *pdev) { @@ -125,6 +164,26 @@ QDF_STATUS utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev *pdev) } qdf_export_symbol(utils_dfs_cancel_precac_timer); +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_start_precac_timer(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs"); + return QDF_STATUS_E_FAILURE; + } + + if (!dfs->dfs_precac_secondary_freq_mhz) + return QDF_STATUS_E_FAILURE; + + dfs_start_precac_timer_for_freq(dfs, + dfs->dfs_precac_secondary_freq_mhz); + return QDF_STATUS_SUCCESS; +} +#else +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS utils_dfs_start_precac_timer(struct wlan_objmgr_pdev *pdev) { struct wlan_dfs *dfs; @@ -141,8 +200,11 @@ QDF_STATUS utils_dfs_start_precac_timer(struct wlan_objmgr_pdev *pdev) dfs->dfs_precac_secondary_freq); return QDF_STATUS_SUCCESS; } +#endif +#endif #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT +#ifdef CONFIG_CHAN_NUM_API bool utils_dfs_precac_decide_pref_chan(struct wlan_objmgr_pdev *pdev, uint8_t *ch_ieee, @@ -159,6 +221,23 @@ utils_dfs_precac_decide_pref_chan(struct wlan_objmgr_pdev *pdev, } #endif +#ifdef CONFIG_CHAN_FREQ_API +bool +utils_dfs_precac_decide_pref_chan_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *chan_freq, + enum wlan_phymode mode) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs"); + return false; + } + return dfs_decide_precac_preferred_chan_for_freq(dfs, chan_freq, mode); +} +#endif +#endif QDF_STATUS utils_dfs_cancel_cac_timer(struct wlan_objmgr_pdev *pdev) { struct wlan_dfs *dfs; @@ -207,6 +286,21 @@ qdf_export_symbol(utils_dfs_cac_stop); * * Return: void */ +#ifdef CONFIG_CHAN_FREQ_API +static void dfs_fill_chan_info(struct dfs_channel *chan, + struct wlan_channel *wlan_chan) +{ + chan->dfs_ch_freq = wlan_chan->ch_freq; + chan->dfs_ch_flags = wlan_chan->ch_flags; + chan->dfs_ch_flagext = wlan_chan->ch_flagext; + chan->dfs_ch_ieee = wlan_chan->ch_ieee; + chan->dfs_ch_vhtop_ch_freq_seg1 = wlan_chan->ch_freq_seg1; + chan->dfs_ch_vhtop_ch_freq_seg2 = wlan_chan->ch_freq_seg2; + chan->dfs_ch_mhz_freq_seg1 = wlan_chan->ch_cfreq1; + chan->dfs_ch_mhz_freq_seg2 = wlan_chan->ch_cfreq2; +} +#else +#ifdef CONFIG_CHAN_NUM_API static void dfs_fill_chan_info(struct dfs_channel *chan, struct wlan_channel *wlan_chan) { @@ -217,6 +311,8 @@ static void dfs_fill_chan_info(struct dfs_channel *chan, chan->dfs_ch_vhtop_ch_freq_seg1 = wlan_chan->ch_freq_seg1; chan->dfs_ch_vhtop_ch_freq_seg2 = wlan_chan->ch_freq_seg2; } +#endif +#endif bool utils_dfs_is_precac_done(struct wlan_objmgr_pdev *pdev, struct wlan_channel *wlan_chan) @@ -667,6 +763,72 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, * so that the random channel function does not select either 2.4GHz or 4.9GHz * channel. */ +#ifdef CONFIG_CHAN_FREQ_API +static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_vdev *vdev, + struct dfs_channel *chan_list, + uint32_t *num_chan) +{ + struct dfs_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 = wlan_pdev_get_dfs_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) + return; + + utils_dfs_get_chan_list(pdev, (void *)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_FREQ(center_freq); + is_curchan_24g = WLAN_REG_IS_24GHZ_CH_FREQ(center_freq); + 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; + /* No change in prototype needed. Hence retaining same func */ + if (!dfs_mlme_check_allowed_prim_chanlist(pdev, center_freq)) + continue; + + if ((is_curchan_5g) && WLAN_REG_IS_5GHZ_CH_FREQ(center_freq)) { + 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_FREQ(center_freq)) { + 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 /* NUM_API */ +#ifdef CONFIG_CHAN_NUM_API static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev, struct dfs_channel *chan_list, @@ -730,8 +892,11 @@ static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, qdf_mem_free(tmp_chan_list); } +#endif +#endif #else + void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev, void *clist, uint32_t *num_chan) { @@ -802,6 +967,7 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, } #endif +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS utils_dfs_get_vdev_random_channel( struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev, uint16_t flags, struct ch_params *ch_params, uint32_t *hw_mode, @@ -874,7 +1040,89 @@ random_chan_error: } qdf_export_symbol(utils_dfs_get_vdev_random_channel); +#endif +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_get_vdev_random_channel_for_freq( + struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev, + uint16_t flags, struct ch_params *chan_params, uint32_t *hw_mode, + uint16_t *target_chan_freq, struct dfs_acs_info *acs_info) +{ + uint32_t dfs_reg; + uint32_t num_chan = NUM_CHANNELS; + struct wlan_dfs *dfs = NULL; + struct wlan_objmgr_psoc *psoc; + struct dfs_channel *chan_list = NULL; + struct dfs_channel cur_chan; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + *target_chan_freq = 0; + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); + goto random_chan_error; + } + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); + goto random_chan_error; + } + + wlan_reg_get_dfs_region(pdev, &dfs_reg); + chan_list = qdf_mem_malloc(num_chan * sizeof(*chan_list)); + if (!chan_list) + goto random_chan_error; + + utils_dfs_get_channel_list(pdev, vdev, chan_list, &num_chan); + if (!num_chan) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "zero channels"); + goto random_chan_error; + } + + cur_chan.dfs_ch_vhtop_ch_freq_seg1 = chan_params->center_freq_seg0; + cur_chan.dfs_ch_vhtop_ch_freq_seg2 = chan_params->center_freq_seg1; + cur_chan.dfs_ch_mhz_freq_seg1 = chan_params->mhz_freq_seg0; + cur_chan.dfs_ch_mhz_freq_seg2 = chan_params->mhz_freq_seg1; + + if (!chan_params->ch_width) + utils_dfs_get_max_sup_width(pdev, + (uint8_t *)&chan_params->ch_width); + + *target_chan_freq = dfs_prepare_random_channel_for_freq(dfs, chan_list, + num_chan, flags, (uint8_t *)&chan_params->ch_width, + &cur_chan, (uint8_t)dfs_reg, acs_info); + + chan_params->center_freq_seg0 = cur_chan.dfs_ch_vhtop_ch_freq_seg1; + chan_params->center_freq_seg1 = cur_chan.dfs_ch_vhtop_ch_freq_seg2; + chan_params->mhz_freq_seg0 = cur_chan.dfs_ch_mhz_freq_seg1; + chan_params->mhz_freq_seg1 = cur_chan.dfs_ch_mhz_freq_seg2; + + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "input width=%d", chan_params->ch_width); + + if (*target_chan_freq) { + wlan_reg_set_channel_params_for_freq(pdev, *target_chan_freq, 0, + chan_params); + utils_dfs_get_max_phy_mode(pdev, hw_mode); + status = QDF_STATUS_SUCCESS; + } + + dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN, + "ch=%d, seg0=%d, seg1=%d, width=%d", + *target_chan_freq, chan_params->center_freq_seg0, + chan_params->center_freq_seg1, chan_params->ch_width); + +random_chan_error: + qdf_mem_free(chan_list); + + return status; +} + +qdf_export_symbol(utils_dfs_get_vdev_random_channel_for_freq); +#endif + +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS utils_dfs_get_random_channel( struct wlan_objmgr_pdev *pdev, uint16_t flags, @@ -888,7 +1136,27 @@ QDF_STATUS utils_dfs_get_random_channel( acs_info); } qdf_export_symbol(utils_dfs_get_random_channel); +#endif +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_get_random_channel_for_freq( + struct wlan_objmgr_pdev *pdev, + uint16_t flags, + struct ch_params *ch_params, + uint32_t *hw_mode, + uint16_t *target_chan_freq, + struct dfs_acs_info *acs_info) +{ + return utils_dfs_get_vdev_random_channel_for_freq(pdev, NULL, flags, + ch_params, hw_mode, + target_chan_freq, + acs_info); +} + +qdf_export_symbol(utils_dfs_get_random_channel_for_freq); +#endif + +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS utils_dfs_bw_reduced_channel( struct wlan_objmgr_pdev *pdev, struct ch_params *ch_params, @@ -936,6 +1204,60 @@ QDF_STATUS utils_dfs_bw_reduced_channel( } qdf_export_symbol(utils_dfs_bw_reduced_channel); +#endif + +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_bw_reduced_channel_for_freq( + struct wlan_objmgr_pdev *pdev, + struct ch_params *chan_params, + uint32_t *hw_mode, + uint16_t *target_chan_freq) +{ + struct wlan_dfs *dfs = NULL; + struct wlan_objmgr_psoc *psoc; + enum channel_state ch_state; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct dfs_channel *dfs_curchan; + + *target_chan_freq = 0; + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc"); + return status; + } + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); + return status; + } + dfs_curchan = dfs->dfs_curchan; + ch_state = + wlan_reg_get_channel_state_for_freq(pdev, + dfs_curchan->dfs_ch_freq); + + if (ch_state == CHANNEL_STATE_DFS || + ch_state == CHANNEL_STATE_ENABLE) { + chan_params->mhz_freq_seg0 = + dfs_curchan->dfs_ch_mhz_freq_seg1; + chan_params->mhz_freq_seg1 = + dfs_curchan->dfs_ch_mhz_freq_seg2; + wlan_reg_set_channel_params_for_freq(pdev, + dfs_curchan->dfs_ch_freq, + 0, chan_params); + + *target_chan_freq = dfs_curchan->dfs_ch_freq; + utils_dfs_get_max_phy_mode(pdev, hw_mode); + + return QDF_STATUS_SUCCESS; + } + + return status; +} + +qdf_export_symbol(utils_dfs_bw_reduced_channel_for_freq); +#endif + #ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT void utils_dfs_init_nol(struct wlan_objmgr_pdev *pdev) @@ -1070,6 +1392,7 @@ void utils_dfs_clear_nol_channels(struct wlan_objmgr_pdev *pdev) } qdf_export_symbol(utils_dfs_clear_nol_channels); +#ifdef CONFIG_CHAN_NUM_API void utils_dfs_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, uint8_t *ch_list, uint8_t num_ch, @@ -1079,7 +1402,21 @@ void utils_dfs_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, wlan_reg_update_nol_ch(pdev, ch_list, num_ch, nol_ch); } qdf_export_symbol(utils_dfs_reg_update_nol_ch); +#endif +#ifdef CONFIG_CHAN_FREQ_API +void utils_dfs_reg_update_nol_chan_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *freq_list, + uint8_t num_chan, + bool nol_chan) +{ + wlan_reg_update_nol_ch_for_freq(pdev, freq_list, num_chan, nol_chan); +} + +qdf_export_symbol(utils_dfs_reg_update_nol_chan_for_freq); +#endif + +#ifdef CONFIG_CHAN_NUM_API void utils_dfs_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev, uint8_t *ch_list, uint8_t num_ch, @@ -1087,6 +1424,19 @@ void utils_dfs_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev, { wlan_reg_update_nol_history_ch(pdev, ch_list, num_ch, nol_history_ch); } +#endif + +#ifdef CONFIG_CHAN_FREQ_API +void +utils_dfs_reg_update_nol_history_chan_for_freq(struct wlan_objmgr_pdev *pdev, + uint16_t *freq_list, + uint8_t num_chan, + bool nol_history_chan) +{ + wlan_reg_update_nol_history_ch_for_freq(pdev, freq_list, num_chan, + nol_history_chan); +} +#endif uint8_t utils_dfs_freq_to_chan(uint32_t freq) { @@ -1129,6 +1479,7 @@ uint32_t utils_dfs_chan_to_freq(uint8_t chan) qdf_export_symbol(utils_dfs_chan_to_freq); #ifdef QCA_MCL_DFS_SUPPORT +#ifdef CONFIG_CHAN_NUM_API QDF_STATUS utils_dfs_mark_leaking_ch(struct wlan_objmgr_pdev *pdev, enum phy_ch_width ch_width, uint8_t temp_ch_lst_sz, @@ -1147,6 +1498,27 @@ QDF_STATUS utils_dfs_mark_leaking_ch(struct wlan_objmgr_pdev *pdev, qdf_export_symbol(utils_dfs_mark_leaking_ch); #endif +#ifdef CONFIG_CHAN_FREQ_API +QDF_STATUS utils_dfs_mark_leaking_chan_for_freq(struct wlan_objmgr_pdev *pdev, + enum phy_ch_width ch_width, + uint8_t temp_chan_lst_sz, + uint16_t *temp_freq_lst) +{ + struct wlan_dfs *dfs = NULL; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs"); + return QDF_STATUS_E_FAILURE; + } + + return dfs_mark_leaking_chan_for_freq(dfs, ch_width, temp_chan_lst_sz, + temp_freq_lst); +} +qdf_export_symbol(utils_dfs_mark_leaking_chan_for_freq); +#endif +#endif + int utils_get_dfsdomain(struct wlan_objmgr_pdev *pdev) { enum dfs_reg dfsdomain;