| /* |
| * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. |
| * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| /** |
| * DOC: This file has Zero CAC DFS APIs. |
| */ |
| |
| #ifndef _DFS_ZERO_CAC_H_ |
| #define _DFS_ZERO_CAC_H_ |
| |
| #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 |
| |
| #define TREE_DEPTH 3 |
| #define N_SUBCHANS_FOR_80BW 4 |
| |
| #define INITIAL_20_CHAN_OFFSET -6 |
| #define INITIAL_40_CHAN_OFFSET -4 |
| #define INITIAL_80_CHAN_OFFSET 0 |
| |
| #define NEXT_20_CHAN_OFFSET 4 |
| #define NEXT_40_CHAN_OFFSET 8 |
| #define NEXT_80_CHAN_OFFSET 16 |
| |
| #define DFS_CHWIDTH_20_VAL 20 |
| #define DFS_CHWIDTH_40_VAL 40 |
| #define DFS_CHWIDTH_80_VAL 80 |
| #define DFS_CHWIDTH_160_VAL 160 |
| |
| #define WEATHER_CHAN_START 120 |
| #define WEATHER_CHAN_END 128 |
| |
| /* PreCAC timeout durations in ms. */ |
| #define MIN_PRECAC_DURATION (6 * 60 * 1000) /* 6 mins */ |
| #define MIN_WEATHER_PRECAC_DURATION (60 * 60 * 1000) /* 1 hour */ |
| #define MAX_PRECAC_DURATION (4 * 60 * 60 * 1000) /* 4 hours */ |
| #define MAX_WEATHER_PRECAC_DURATION (24 * 60 * 60 * 1000) /* 24 hours */ |
| |
| #define PCAC_DFS_INDEX_ZERO 0 |
| #define PCAC_TIMER_NOT_RUNNING 0 |
| #define PRECAC_NOT_STARTED 0 |
| /** |
| * struct precac_tree_node - Individual tree node structure for every node in |
| * 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. |
| * @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 |
| * the country's channel list). |
| * @bandwidth: Bandwidth of the ch_ieee (in the current node). |
| */ |
| 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; |
| uint8_t bandwidth; |
| }; |
| |
| /** |
| * enum precac_chan_state - Enum for PreCAC state of a channel. |
| * @PRECAC_ERR: Invalid preCAC state. |
| * @PRECAC_REQUIRED: preCAC need to be done on the channel. |
| * @PRECAC_NOW: preCAC is running on the channel. |
| * @PRECAC_DONE: preCAC is done and channel is clear. |
| * @PRECAC_NOL: preCAC is done and radar is detected. |
| */ |
| enum precac_chan_state { |
| PRECAC_ERR = -1, |
| PRECAC_REQUIRED, |
| PRECAC_NOW, |
| PRECAC_DONE, |
| PRECAC_NOL, |
| }; |
| |
| /** |
| * 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; |
| }; |
| |
| /** |
| * dfs_zero_cac_timer_init() - Initialize zero-cac timers |
| * @dfs_soc_obj: Pointer to DFS SOC object structure. |
| */ |
| #if !defined(QCA_MCL_DFS_SUPPORT) |
| void dfs_zero_cac_timer_init(struct dfs_soc_priv_obj *dfs_soc_obj); |
| #else |
| static inline void |
| dfs_zero_cac_timer_init(struct dfs_soc_priv_obj *dfs_soc_obj) |
| { |
| } |
| #endif |
| /** |
| * dfs_print_precaclists() - Print precac list. |
| * @dfs: Pointer to wlan_dfs structure. |
| */ |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| void dfs_print_precaclists(struct wlan_dfs *dfs); |
| #else |
| static inline void dfs_print_precaclists(struct wlan_dfs *dfs) |
| { |
| } |
| #endif |
| |
| /** |
| * dfs_reset_precac_lists() - Resets the precac lists. |
| * @dfs: Pointer to wlan_dfs structure. |
| */ |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| void dfs_reset_precac_lists(struct wlan_dfs *dfs); |
| #else |
| static inline void dfs_reset_precac_lists(struct wlan_dfs *dfs) |
| { |
| } |
| #endif |
| |
| /** |
| * dfs_reset_precaclists() - Clears and initializes precac_list. |
| * @dfs: Pointer to wlan_dfs structure. |
| */ |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| void dfs_reset_precaclists(struct wlan_dfs *dfs); |
| #else |
| static inline void dfs_reset_precaclists(struct wlan_dfs *dfs) |
| { |
| } |
| #endif |
| |
| /** |
| * dfs_deinit_precac_list() - Clears the precac list. |
| * @dfs: Pointer to wlan_dfs dtructure. |
| */ |
| void dfs_deinit_precac_list(struct wlan_dfs *dfs); |
| |
| /** |
| * dfs_zero_cac_detach() - Free zero_cac memory. |
| * @dfs: Pointer to wlan_dfs dtructure. |
| */ |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| void dfs_zero_cac_detach(struct wlan_dfs *dfs); |
| #else |
| static inline void dfs_zero_cac_detach(struct wlan_dfs *dfs) |
| { |
| } |
| #endif |
| |
| /** |
| * dfs_init_precac_list() - Init precac list. |
| * @dfs: Pointer to wlan_dfs dtructure. |
| */ |
| void dfs_init_precac_list(struct wlan_dfs *dfs); |
| |
| /** |
| * dfs_start_precac_timer() - Start precac timer. |
| * @dfs: Pointer to wlan_dfs structure. |
| * @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. |
| * @dfs: Pointer to wlan_dfs structure. |
| */ |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| void dfs_cancel_precac_timer(struct wlan_dfs *dfs); |
| #else |
| static inline void dfs_cancel_precac_timer(struct wlan_dfs *dfs) |
| { |
| } |
| #endif |
| |
| /** |
| * dfs_zero_cac_attach() - Initialize dfs zerocac variables. |
| * @dfs: Pointer to DFS structure. |
| */ |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| void dfs_zero_cac_attach(struct wlan_dfs *dfs); |
| #else |
| static inline void dfs_zero_cac_attach(struct wlan_dfs *dfs) |
| { |
| } |
| #endif |
| |
| /** |
| * dfs_zero_cac_reset() - Reset Zero cac DFS variables. |
| * @dfs: Pointer to wlan_dfs structure. |
| */ |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| void dfs_zero_cac_reset(struct wlan_dfs *dfs); |
| #else |
| static inline void dfs_zero_cac_reset(struct wlan_dfs *dfs) |
| { |
| } |
| #endif |
| |
| /** |
| * dfs_zero_cac_timer_detach() - Free Zero cac DFS variables. |
| * @dfs_soc_obj: Pointer to dfs_soc_priv_obj structure. |
| */ |
| #if !defined(QCA_MCL_DFS_SUPPORT) |
| void dfs_zero_cac_timer_detach(struct dfs_soc_priv_obj *dfs_soc_obj); |
| #else |
| static inline void |
| dfs_zero_cac_timer_detach(struct dfs_soc_priv_obj *dfs_soc_obj) |
| { |
| } |
| #endif |
| |
| /** |
| * dfs_is_precac_done() - Is precac done. |
| * @dfs: Pointer to wlan_dfs structure. |
| * @chan: Pointer to dfs_channel for which preCAC done is checked. |
| * |
| * Return: |
| * * True: If precac is done on channel. |
| * * False: If precac is not done on channel. |
| */ |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| bool dfs_is_precac_done(struct wlan_dfs *dfs, struct dfs_channel *chan); |
| #else |
| static inline bool dfs_is_precac_done(struct wlan_dfs *dfs, |
| struct dfs_channel *chan) |
| { |
| return false; |
| } |
| #endif |
| |
| #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT |
| /** |
| * dfs_decide_precac_preferred_chan() - 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. |
| * @mode: Configured PHY mode. |
| * |
| * 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 |
| * precac_list. |
| * @dfs: Pointer to wlan_dfs structure. |
| * @exclude_pri_ch_ieee: Primary channel IEEE to be excluded for preCAC. |
| * @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. |
| * @dfs: Pointer to wlan_dfs structure. |
| * @precac_timeout: Precac timeout value. |
| */ |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| int dfs_override_precac_timeout(struct wlan_dfs *dfs, |
| int precac_timeout); |
| #else |
| static inline int dfs_override_precac_timeout(struct wlan_dfs *dfs, |
| int precac_timeout) |
| { |
| return 0; |
| } |
| #endif |
| |
| /** |
| * dfs_get_override_precac_timeout() - Get precac timeout. |
| * @dfs: Pointer wlan_dfs structure. |
| * @precac_timeout: Get precac timeout value in this variable. |
| */ |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| int dfs_get_override_precac_timeout(struct wlan_dfs *dfs, |
| int *precac_timeout); |
| #else |
| static inline int dfs_get_override_precac_timeout(struct wlan_dfs *dfs, |
| int *precac_timeout) |
| { |
| return 0; |
| } |
| #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. |
| * @cfreq1: cfreq1. |
| * @cfreq2: cfreq2. |
| * @phy_mode: Precac phymode. |
| * @dfs_set_cfreq2: Precac cfreq2 |
| * @set_agile: Agile mode flag. |
| * |
| * Zero-CAC-DFS algorithm:- |
| * Zero-CAC-DFS algorithm works in stealth mode. |
| * 1) When any channel change happens in VHT80 mode the algorithm |
| * changes the HW channel mode to VHT80_80/VHT160 mode and adds a |
| * new channel in the secondary VHT80 to perform precac and a |
| * precac timer is started. However the upper layer/UMAC is unaware |
| * of this change. |
| * 2) When the precac timer expires without being interrupted by |
| * any channel change the secondary VHT80 channel is moved from |
| * precac-required-list to precac-done-list. |
| * 3) If there is a radar detect at any time in any segment |
| * (segment-1 is preimary VHT80 and segment-2 is VHT80)then the |
| * channel is searched in both precac-reuired-list and precac-done-list |
| * and moved to precac-nol-list. |
| * 4) Whenever channel change happens if the new channel is a DFS |
| * channel then precac-done-list is searched and if the channel is |
| * found in the precac-done-list then the CAC is skipped. |
| * 5) The precac expiry timer makes a vedv_restart(channel change |
| * with current-upper-layer-channel-mode which is VHT80). In channel |
| * change the algorithm tries to pick a new channel from the |
| * precac-required list. If none found then channel mode remains same. |
| * Which means when all the channels in precac-required-list are |
| * 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, |
| uint32_t *cfreq1, |
| uint32_t *cfreq2, |
| 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, |
| uint32_t *cfreq1, |
| uint32_t *cfreq2, |
| uint32_t *phy_mode, |
| bool *dfs_set_cfreq2, |
| bool *set_agile) |
| { |
| } |
| #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. |
| * @pdev: Pointer to wlan_objmgr_pdev structure. |
| * @cur_precac_dfs_index: current precac index |
| */ |
| void dfs_find_pdev_for_agile_precac(struct wlan_objmgr_pdev *pdev, |
| uint8_t *cur_precac_dfs_index); |
| |
| /** |
| * dfs_prepare_agile_precac_chan() - Send Agile set request for given pdev. |
| * @dfs: Pointer to wlan_dfs structure. |
| */ |
| void dfs_prepare_agile_precac_chan(struct wlan_dfs *dfs); |
| |
| /** |
| * dfs_process_ocac_complete() - Process Off-Channel CAC complete indication. |
| * @pdev :Pointer to wlan_objmgr_pdev structure. |
| * @ocac_status: Off channel CAC complete status |
| * @center_freq : Center Frequency of O-CAC done indication. |
| */ |
| void dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev, |
| uint32_t ocac_status, |
| uint32_t center_freq); |
| |
| /** |
| * dfs_get_ieeechan_for_agilecac() - Find an IEEE channel for agile CAC. |
| * @dfs: Pointer to wlan_dfs structure. |
| * @ch_ieee: Pointer to channel number for agile set request. |
| * @pri_ch_ieee: Current primary IEEE channel. |
| * @sec_ch_ieee: Current secondary IEEE channel (in HT80_80 mode). |
| * |
| * 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. |
| */ |
| void dfs_agile_precac_start(struct wlan_dfs *dfs); |
| |
| /** |
| * dfs_start_agile_precac_timer() - Start precac timer for the given channel. |
| * @dfs: Pointer to wlan_dfs structure. |
| * @ocac_status: Status of the off channel CAC. |
| * @adfs_param: Agile DFS CAC parameters. |
| * |
| * Start the precac timer with proper timeout values based on the channel to |
| * be preCACed. The preCAC channel number and chwidth information is present |
| * in the adfs_param argument. Once the timer is started, update the timeout |
| * fields in adfs_param. |
| */ |
| void dfs_start_agile_precac_timer(struct wlan_dfs *dfs, |
| uint8_t ocac_status, |
| struct dfs_agile_cac_params *adfs_param); |
| |
| /** |
| * dfs_set_fw_adfs_support() - Set FW aDFS support in dfs object. |
| * @dfs: Pointer to wlan_dfs structure. |
| * @fw_adfs_support_160: aDFS enabled when pdev is on 160/80P80MHz. |
| * @fw_adfs_support_non_160: aDFS enabled when pdev is on 20/40/80MHz. |
| * |
| * Return: void. |
| */ |
| void dfs_set_fw_adfs_support(struct wlan_dfs *dfs, |
| bool fw_adfs_support_160, |
| bool fw_adfs_support_non_160); |
| #else |
| static inline void dfs_find_pdev_for_agile_precac(struct wlan_objmgr_pdev *pdev, |
| uint8_t *cur_precac_dfs_index) |
| { |
| } |
| |
| static inline void dfs_prepare_agile_precac_chan(struct wlan_dfs *dfs) |
| { |
| } |
| |
| static inline void |
| dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev, |
| uint32_t ocac_status, |
| uint32_t center_freq) |
| { |
| } |
| |
| #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) |
| { |
| } |
| |
| static inline void |
| dfs_start_agile_precac_timer(struct wlan_dfs *dfs, |
| uint8_t ocac_status, |
| struct dfs_agile_cac_params *adfs_param) |
| { |
| } |
| |
| static inline void |
| dfs_set_fw_adfs_support(struct wlan_dfs *dfs, |
| bool fw_adfs_support_160, |
| bool fw_adfs_support_non_160) |
| { |
| } |
| #endif |
| |
| #if defined(QCA_SUPPORT_AGILE_DFS) || defined(ATH_SUPPORT_ZERO_CAC_DFS) |
| /** |
| * dfs_agile_soc_obj_init() - Initialize soc obj for agile precac. |
| * @dfs: Pointer to wlan_dfs structure. |
| * @precac_chan: Start thr precac timer in this channel. |
| * @ocac_status: Status of the off channel CAC. |
| */ |
| void dfs_agile_soc_obj_init(struct wlan_dfs *dfs, |
| struct wlan_objmgr_psoc *psoc); |
| #else |
| static inline void dfs_agile_soc_obj_init(struct wlan_dfs *dfs, |
| struct wlan_objmgr_psoc *psoc) |
| { |
| } |
| #endif |
| |
| /** |
| * dfs_set_precac_enable() - Set precac enable flag. |
| * @dfs: Pointer to wlan_dfs structure. |
| * @value: input value for dfs_legacy_precac_ucfg flag. |
| */ |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| void dfs_set_precac_enable(struct wlan_dfs *dfs, |
| uint32_t value); |
| #else |
| static inline void dfs_set_precac_enable(struct wlan_dfs *dfs, |
| uint32_t value) |
| { |
| } |
| #endif |
| |
| /** |
| * dfs_is_legacy_precac_enabled() - Check if legacy preCAC is enabled for the |
| * DFS onject. |
| * @dfs: Pointer to the wlan_dfs object. |
| * |
| * Return: True if legacy preCAC is enabled, else false. |
| */ |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| bool dfs_is_legacy_precac_enabled(struct wlan_dfs *dfs); |
| #else |
| static inline bool dfs_is_legacy_precac_enabled(struct wlan_dfs *dfs) |
| { |
| return 0; |
| } |
| #endif |
| |
| /** |
| * dfs_is_agile_precac_enabled() - Check if agile preCAC is enabled for the DFS. |
| * @dfs: Pointer to the wlan_dfs object. |
| * |
| * Return: True if agile DFS is enabled, else false. |
| * |
| * For agile preCAC to be enabled, |
| * 1. User configuration should be set. |
| * 2. Target should support aDFS. |
| */ |
| #ifdef QCA_SUPPORT_AGILE_DFS |
| bool dfs_is_agile_precac_enabled(struct wlan_dfs *dfs); |
| #else |
| static inline bool dfs_is_agile_precac_enabled(struct wlan_dfs *dfs) |
| { |
| return false; |
| } |
| #endif |
| |
| #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT |
| /** |
| * dfs_set_precac_intermediate_chan() - Set intermediate chan to be used while |
| * doing precac. |
| * @dfs: Pointer to wlan_dfs structure. |
| * @value: input value for dfs_legacy_precac_ucfg flag. |
| * |
| * Return: |
| * * 0 - Successfully set intermediate channel. |
| * * -EINVAL - Invalid channel. |
| */ |
| int32_t dfs_set_precac_intermediate_chan(struct wlan_dfs *dfs, |
| uint32_t value); |
| #else |
| static inline int32_t dfs_set_precac_intermediate_chan(struct wlan_dfs *dfs, |
| uint32_t value) |
| { |
| return 0; |
| } |
| #endif |
| |
| #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT |
| /** |
| * dfs_get_precac_intermediate_chan() - Get configured precac |
| * intermediate channel. |
| * @dfs: Pointer to wlan_dfs structure. |
| * |
| * Return: Configured intermediate channel number. |
| */ |
| uint32_t dfs_get_precac_intermediate_chan(struct wlan_dfs *dfs); |
| #else |
| static inline uint32_t dfs_get_intermediate_chan(struct wlan_dfs *dfs) |
| { |
| return 0; |
| } |
| #endif |
| |
| #ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT |
| /** |
| * dfs_get_precac_chan_state() - Get precac status of a given channel. |
| * @dfs: Pointer to wlan_dfs structure. |
| * @precac_chan: Channel number for which precac state need to be checked. |
| * |
| * Return: |
| * * PRECAC_REQUIRED: Precac has not done on precac_chan. |
| * * PRECAC_NOW : Precac is running on precac_chan. |
| * * PRECAC_DONE : precac_chan is in CAC done state in precac list. |
| * * PRECAC_NOL : precac_chan is in NOL state in precac list. |
| * * PRECAC_ERR : Invalid precac state. |
| */ |
| 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) |
| { |
| return PRECAC_REQUIRED; |
| } |
| #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. |
| */ |
| void dfs_zero_cac_reset(struct wlan_dfs *dfs); |
| |
| /** |
| * dfs_reinit_precac_lists() - Reinit DFS preCAC lists. |
| * @src_dfs: Source DFS from which the preCAC list is copied. |
| * @dest_dfs: Destination DFS to which the preCAC list is copied. |
| * @low_5g_freq: Low 5G frequency value of the destination DFS. |
| * @high_5g_freq: High 5G frequency value of the destination DFS. |
| * |
| * Copy all the preCAC list entries from the source DFS to the destination DFS |
| * which fall within the frequency range of low_5g_freq and high_5g_freq. |
| * |
| * Return: None (void). |
| */ |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| void dfs_reinit_precac_lists(struct wlan_dfs *src_dfs, |
| struct wlan_dfs *dest_dfs, |
| uint16_t low_5g_freq, |
| uint16_t high_5g_freq); |
| #else |
| static inline void dfs_reinit_precac_lists(struct wlan_dfs *src_dfs, |
| struct wlan_dfs *dest_dfs, |
| uint16_t low_5g_freq, |
| uint16_t high_5g_freq) |
| { |
| } |
| #endif |
| |
| /** |
| * dfs_is_precac_done_on_ht20_40_80_chan() - Is precac done on a |
| * VHT20/40/80 channel. |
| *@dfs: Pointer to wlan_dfs structure. |
| *@chan: Channel IEEE value. |
| * |
| * Return: |
| * * 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 |
| * VHT80+80 or VHT160 |
| * channel. |
| * @dfs: Pointer to wlan_dfs structure. |
| * @chan: Pointer to dfs_channel for which preCAC done is checked. |
| * |
| * Return: |
| * * True: If CAC is done on channel. |
| * * False: If CAC is not done on channel. |
| */ |
| bool dfs_is_precac_done_on_ht8080_ht160_chan(struct wlan_dfs *dfs, |
| struct dfs_channel *chan); |
| |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| /** |
| * dfs_find_chwidth_and_center_chan() - 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_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. |
| * @pri_ch_ieee: Primary channel IEEE. |
| * @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. |
| * @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. |
| * @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, |
| uint8_t *primary_chan_ieee, |
| 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, |
| uint8_t *channels, |
| 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. |
| */ |
| #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) |
| bool dfs_is_precac_timer_running(struct wlan_dfs *dfs); |
| #else |
| 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_ */ |