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
This commit is contained in:
Priyadarshnee S 2019-10-09 14:33:18 +05:30 • committed by nshrivas
commit 38da66f0dc
15 changed files with 3422 additions and 736 deletions

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -34,7 +34,10 @@
#include "dfs.h"
#include <wlan_dfs_tgt_api.h>
#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_ */

View file

@ -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

View file

@ -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

View file

@ -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");

View file

@ -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)

View file

@ -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,

View file

@ -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,

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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)

View file

@ -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;