diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index fd381fb74b1d..27927dc6331f 100644 --- a/umac/dfs/core/src/dfs.h +++ b/umac/dfs/core/src/dfs.h @@ -29,6 +29,7 @@ #include /* qdf_spinlock */ #include #include +#include /* qdf_str_lcopy */ #include #include "dfs_structs.h" @@ -39,6 +40,7 @@ #include #include #include +#include /* File Line and Submodule String */ #define FLSM(x, str) #str " : " FL(x) @@ -979,9 +981,8 @@ struct dfs_event_log { * not be re-done. * @dfs_precac_timeout_override: Overridden precac timeout. * @dfs_num_precac_freqs: Number of PreCAC VHT80 frequencies. - * @dfs_precac_required_list: PreCAC required list. - * @dfs_precac_done_list: PreCAC done list. - * @dfs_precac_nol_list: PreCAC NOL List. + * @dfs_precac_list: PreCAC list (contains individual trees). + * @dfs_precac_chwidth: PreCAC channel width enum. * @dfs_curchan: DFS current channel. * @dfs_cac_started_chan: CAC started channel. * @dfs_pdev_obj: DFS pdev object. @@ -1126,10 +1127,8 @@ struct wlan_dfs { #if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD) uint8_t dfs_disable_radar_marking; #endif - TAILQ_HEAD(, dfs_precac_entry) dfs_precac_required_list; - TAILQ_HEAD(, dfs_precac_entry) dfs_precac_done_list; - TAILQ_HEAD(, dfs_precac_entry) dfs_precac_nol_list; - + TAILQ_HEAD(, dfs_precac_entry) dfs_precac_list; + enum phy_ch_width dfs_precac_chwidth; #ifdef QCA_SUPPORT_ETSI_PRECAC_DFS TAILQ_HEAD(, dfs_etsi_precac_entry) dfs_etsiprecac_required_list; TAILQ_HEAD(, dfs_etsi_precac_entry) dfs_etsiprecac_done_list; diff --git a/umac/dfs/core/src/dfs_zero_cac.h b/umac/dfs/core/src/dfs_zero_cac.h index cfeddc3a323b..b13294d02b6e 100644 --- a/umac/dfs/core/src/dfs_zero_cac.h +++ b/umac/dfs/core/src/dfs_zero_cac.h @@ -39,18 +39,41 @@ #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 /** - * struct dfs_precac_entry - PreCAC entry. - * @pe_list: PreCAC entry. - * @vht80_freq: VHT80 freq. - * @precac_nol_timer: Per element precac NOL timer. - * @dfs: Pointer to wlan_dfs structure. + * 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 (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 dfs_precac_entry { - TAILQ_ENTRY(dfs_precac_entry) pe_list; - uint8_t vht80_freq; - qdf_timer_t precac_nol_timer; - struct wlan_dfs *dfs; +struct precac_tree_node { + struct precac_tree_node *left_child; + struct precac_tree_node *right_child; + uint8_t ch_ieee; + uint8_t n_caced_subchs; + uint8_t n_nol_subchs; + uint8_t n_valid_subchs; + uint8_t bandwidth; }; /** @@ -69,6 +92,20 @@ enum precac_chan_state { PRECAC_NOL, }; +/** + * struct dfs_precac_entry - PreCAC entry. + * @pe_list: PreCAC entry. + * @vht80_ch_ieee: VHT80 centre channel IEEE 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; + 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. @@ -106,9 +143,7 @@ static inline void dfs_reset_precac_lists(struct wlan_dfs *dfs) #endif /** - * dfs_reset_precaclists() - Clears and initiakizes precac_required_list, - * precac_done_list and precac_nol_list. - * + * 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) @@ -252,14 +287,17 @@ static inline void dfs_decide_precac_preferred_chan(struct wlan_dfs *dfs, #endif /** - * dfs_get_freq_from_precac_required_list() - Get VHT80 freq from - * precac_required_list. - * @dfs: Pointer to wlan_dfs structure. - * @exclude_ieee_freq: Find a VHT80 freqency that is not equal to - * exclude_ieee_freq. + * 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. */ -uint8_t dfs_get_freq_from_precac_required_list(struct wlan_dfs *dfs, - uint8_t exclude_ieee_freq); +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); /** * dfs_override_precac_timeout() - Override the default precac timeout. @@ -376,16 +414,19 @@ void dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev, uint32_t center_freq); /** - * dfs_find_vht80_chan_for_agile_precac() - . - * @pdev :Pointer to wlan_objmgr_pdev structure. - * @*ch_freq: Pointer to channel number for agile set request. - * @ch_freq_seg1 : Current primary beaconing channel number. - * @ch_freq_seg2 : Current secondary segment channel number. + * 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). */ -void dfs_find_vht80_chan_for_agile_precac(struct wlan_dfs *dfs, - uint8_t *ch_freq, - uint8_t ch_freq_seg1, - uint8_t ch_freq_seg2); +void dfs_get_ieeechan_for_agilecac(struct wlan_dfs *dfs, + uint8_t *ch_ieee, + uint8_t pri_ch_ieee, + uint8_t sec_ch_ieee); /** * dfs_agile_precac_start() - Start agile precac. * @dfs: Pointer to wlan_dfs structure. @@ -418,10 +459,10 @@ dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev, { } -static inline void dfs_find_vht80_chan_for_agile_precac(struct wlan_dfs *dfs, - uint8_t *ch_freq, - uint8_t ch_freq_seg1, - uint8_t ch_freq_seg2) +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) { } @@ -526,8 +567,8 @@ static inline uint32_t dfs_get_intermediate_chan(struct wlan_dfs *dfs) * Return: * * PRECAC_REQUIRED: Precac has not done on precac_chan. * * PRECAC_NOW : Precac is running on precac_chan. - * * PRECAC_DONE : precac_chan is in precac done list. - * * PRECAC_NOL : precac_chan is in precac NOL list. + * * 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 @@ -548,46 +589,105 @@ dfs_get_precac_chan_state(struct wlan_dfs *dfs, void dfs_zero_cac_reset(struct wlan_dfs *dfs); /** - * dfs_is_ht20_40_80_chan_in_precac_done_list() - Is precac done on a - * VHT20/40/80 channel. + * 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: Pointer to dfs_channel for which preCAC done is checked. + *@chan: Channel IEEE value. * * Return: - * * True: If channel is present in precac-done list. - * * False: If channel is not present in precac-done list. + * * True: If CAC is done on channel. + * * False: If CAC is not done on channel. */ -bool dfs_is_ht20_40_80_chan_in_precac_done_list(struct wlan_dfs *dfs, - struct dfs_channel *chan); +bool dfs_is_precac_done_on_ht20_40_80_chan(struct wlan_dfs *dfs, + uint8_t chan); /** - * dfs_is_ht8080_ht160_chan_in_precac_done_list() - Is precac done on - * VHT80+80 or VHT160 - * channel. + * 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 channel is present in precac-done list. - * * False: If channel is not present in precac-done list. + * * True: If CAC is done on channel. + * * False: If CAC is not done on channel. */ -bool dfs_is_ht8080_ht160_chan_in_precac_done_list(struct wlan_dfs *dfs, - struct dfs_channel *chan); +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). + */ +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); /** - * dfs_mark_precac_dfs() - 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. + * 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. */ -#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && !defined(QCA_MCL_DFS_SUPPORT) -void dfs_mark_precac_dfs(struct wlan_dfs *dfs, - uint8_t is_radar_found_on_secondary_seg, - uint8_t detector_id); +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); + +/** + * 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. + */ +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); + +/** + * dfs_unmark_precac_nol() - Unmark the precac channel as radar. + * @dfs: Pointer to wlan_dfs structure. + * @channel: channel marked as radar. + */ +void dfs_unmark_precac_nol(struct wlan_dfs *dfs, uint8_t channel); + #else -static inline void dfs_mark_precac_dfs(struct wlan_dfs *dfs, - uint8_t is_radar_found_on_secondary_seg, - uint8_t detector_id) +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) +{ +} + +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) +{ +} + +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) +{ +} + +static inline void dfs_unmark_precac_nol(struct wlan_dfs *dfs, uint8_t channel) { } #endif diff --git a/umac/dfs/core/src/misc/dfs.c b/umac/dfs/core/src/misc/dfs.c index d69592f7beda..9420f39d52e3 100644 --- a/umac/dfs/core/src/misc/dfs.c +++ b/umac/dfs/core/src/misc/dfs.c @@ -700,7 +700,6 @@ int dfs_control(struct wlan_dfs *dfs, break; case DFS_SHOW_PRECAC_LISTS: dfs_print_precaclists(dfs); - dfs_print_etsi_precaclists(dfs); break; case DFS_RESET_PRECAC_LISTS: dfs_reset_precac_lists(dfs); diff --git a/umac/dfs/core/src/misc/dfs_cac.c b/umac/dfs/core/src/misc/dfs_cac.c index f5dc99db66f6..ed540429cb15 100644 --- a/umac/dfs/core/src/misc/dfs_cac.c +++ b/umac/dfs/core/src/misc/dfs_cac.c @@ -102,6 +102,8 @@ static os_timer_func(dfs_cac_valid_timeout) static os_timer_func(dfs_cac_timeout) { struct wlan_dfs *dfs = NULL; + enum phy_ch_width ch_width = CH_WIDTH_INVALID; + uint8_t primary_chan_ieee = 0, secondary_chan_ieee = 0; OS_GET_TIMER_ARG(dfs, struct wlan_dfs *); dfs->dfs_cac_timer_running = 0; @@ -144,6 +146,14 @@ static os_timer_func(dfs_cac_timeout) qdf_timer_mod(&dfs->dfs_cac_valid_timer, dfs->dfs_cac_valid_time * 1000); } + + dfs_find_chwidth_and_center_chan(dfs, + &ch_width, + &primary_chan_ieee, + &secondary_chan_ieee); + /* Mark the current channel as preCAC done */ + dfs_mark_precac_done(dfs, primary_chan_ieee, + secondary_chan_ieee, ch_width); } /* Iterate over the nodes, processing the CAC completion event. */ diff --git a/umac/dfs/core/src/misc/dfs_nol.c b/umac/dfs/core/src/misc/dfs_nol.c index 85ec6fab541a..5ebe1a9b961a 100644 --- a/umac/dfs/core/src/misc/dfs_nol.c +++ b/umac/dfs/core/src/misc/dfs_nol.c @@ -253,6 +253,7 @@ static os_timer_func(dfs_remove_from_nol) WLAN_EV_NOL_FINISHED); dfs_debug(dfs, WLAN_DEBUG_DFS_NOL, "remove channel %d from nol", chan); + utils_dfs_unmark_precac_nol(dfs->dfs_pdev_obj, chan); utils_dfs_add_to_etsi_precac_required_list(dfs->dfs_pdev_obj, &chan); utils_dfs_reg_update_nol_ch(dfs->dfs_pdev_obj, diff --git a/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c b/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c index 2ef7188e0675..b2c503477737 100644 --- a/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c +++ b/umac/dfs/core/src/misc/dfs_process_radar_found_ind.c @@ -789,8 +789,9 @@ QDF_STATUS dfs_process_radar_ind(struct wlan_dfs *dfs, dfs_debug(dfs, WLAN_DEBUG_DFS, "%s: %d Radar found on agile detector:%d , STAY in Same operating Channel", __func__, __LINE__, radar_found->detector_id); - dfs_mark_precac_dfs(dfs, dfs->is_radar_found_on_secondary_seg, - radar_found->detector_id); + dfs_mark_precac_nol(dfs, dfs->is_radar_found_on_secondary_seg, + radar_found->detector_id, channels, + num_channels); return QDF_STATUS_SUCCESS; } @@ -831,9 +832,10 @@ 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_dfs(dfs, + dfs_mark_precac_nol(dfs, dfs->is_radar_found_on_secondary_seg, - radar_found->detector_id); + radar_found->detector_id, channels, + num_channels); } if (utils_get_dfsdomain(dfs->dfs_pdev_obj) == DFS_ETSI_DOMAIN) { diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h index feb1d1d3f43d..ca0b4e902357 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h @@ -116,8 +116,7 @@ QDF_STATUS utils_dfs_reset(struct wlan_objmgr_pdev *pdev); bool utils_dfs_is_freq_in_nol(struct wlan_objmgr_pdev *pdev, uint32_t freq); /** - * utils_dfs_reset_precaclists() - Clears and initiakizes precac_required_list, - * precac_done_list and precac_nol_list. + * utils_dfs_reset_precaclists() - Clears and initializes precac_list. * @pdev: Pointer to DFS pdev object. * * Wrapper function for dfs_reset_precaclists(). This function called from @@ -125,6 +124,15 @@ bool utils_dfs_is_freq_in_nol(struct wlan_objmgr_pdev *pdev, uint32_t freq); */ QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev); +/** + * utils_dfs_unmark_precac_nol() - Clears precac channel marked as NOL. + * @pdev: Pointer to DFS pdev object. + * @chan: channel to be unmarked as NOL. + * + * Return void. + */ +void utils_dfs_unmark_precac_nol(struct wlan_objmgr_pdev *pdev, uint8_t chan); + /** * utils_dfs_reset_etsi_precaclists() - Clears and initializes etsi * precac_required_list, diff --git a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c index baf6b876e6a6..834676ec46e5 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c @@ -100,6 +100,19 @@ QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev) } qdf_export_symbol(utils_dfs_reset_precaclists); +void utils_dfs_unmark_precac_nol(struct wlan_objmgr_pdev *pdev, uint8_t chan) +{ + struct wlan_dfs *dfs; + + dfs = wlan_pdev_get_dfs_obj(pdev); + if (!dfs) + return; + + dfs_unmark_precac_nol(dfs, chan); +} + +qdf_export_symbol(utils_dfs_unmark_precac_nol); + #ifdef QCA_SUPPORT_ETSI_PRECAC_DFS QDF_STATUS utils_dfs_reset_etsi_precaclists(struct wlan_objmgr_pdev *pdev) {