diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index 5d78b7800b..6140e5a0e6 100644 --- a/umac/dfs/core/src/dfs.h +++ b/umac/dfs/core/src/dfs.h @@ -2157,13 +2157,16 @@ void dfs_stacac_stop(struct wlan_dfs *dfs); * @continue_current_cac: If AP can start CAC then this variable indicates * whether to continue with the current CAC or restart the CAC. This variable * is valid only if this function returns true. + * @is_vap_restart: Flag to indicate if vap is restarted/started. + * True: VAP restart. False: VAP start * * Return: true if AP requires CAC or can continue current CAC, else false. */ bool dfs_is_cac_required(struct wlan_dfs *dfs, struct dfs_channel *cur_chan, struct dfs_channel *prev_chan, - bool *continue_current_cac); + bool *continue_current_cac, + bool is_vap_restart); /** * dfs_cac_stop() - Clear the AP CAC timer. @@ -2245,7 +2248,8 @@ static inline bool dfs_is_cac_required(struct wlan_dfs *dfs, struct dfs_channel *cur_chan, struct dfs_channel *prev_chan, - bool *continue_current_cac) + bool *continue_current_cac, + bool is_vap_restart) { return false; } diff --git a/umac/dfs/core/src/misc/dfs_cac.c b/umac/dfs/core/src/misc/dfs_cac.c index 3df4c4c243..72950e79a4 100644 --- a/umac/dfs/core/src/misc/dfs_cac.c +++ b/umac/dfs/core/src/misc/dfs_cac.c @@ -402,10 +402,16 @@ dfs_is_new_chan_subset_of_old_chan(struct wlan_dfs *dfs, bool dfs_is_cac_required(struct wlan_dfs *dfs, struct dfs_channel *cur_chan, struct dfs_channel *prev_chan, - bool *continue_current_cac) + bool *continue_current_cac, + bool is_vap_restart) { struct dfs_channel *cac_started_chan = &dfs->dfs_cac_started_chan; + if (!WLAN_IS_PRIMARY_OR_SECONDARY_CHAN_DFS(cur_chan)) { + dfs_debug(dfs, WLAN_DEBUG_DFS, "Skip CAC on non-DFS channel"); + return false; + } + if (dfs->dfs_ignore_dfs || dfs->dfs_cac_valid || dfs->dfs_ignore_cac) { dfs_debug(dfs, WLAN_DEBUG_DFS, "Skip CAC, ignore_dfs = %d cac_valid = %d ignore_cac = %d", @@ -453,6 +459,19 @@ bool dfs_is_cac_required(struct wlan_dfs *dfs, dfs_cancel_cac_timer(dfs); } } else { /* CAC timer is not running. */ + /* If channel change happens via VAP DOWN/UP on subset channels, + * (eg: from 52 HT80 to 64 HT80) CAC done information + * (of 52 HT80) based on subset logic + * (as 52 and 64 HT80 are subsets of each other) + * is not expected to be preserved as VAP has come up + * from DOWN state. Hence do not skip CAC on 64 HT80. + * is_vap_restart flag is used as an identifer to indicate if + * vap has come up from a DOWN state or UP state (vap restart). + */ + if (!is_vap_restart) { + dfs_debug(dfs, WLAN_DEBUG_DFS, "CAC is needed"); + return true; + } if (dfs_is_new_chan_subset_of_old_chan(dfs, cur_chan, prev_chan)) { diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h index 9c9f7fbf5d..3db544f438 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h @@ -857,6 +857,8 @@ bool utils_dfs_is_cac_required(struct wlan_objmgr_pdev *pdev, * @continue_current_cac: If AP can start CAC then this variable indicates * whether to continue with the current CAC or restart the CAC. This variable * is valid only if this function returns true. + * @is_vap_restart: Flag to indicate if vap is restarted/started. + * True: VAP restart. False: VAP start * * This API checks if the dfs_curchan is a subset of the dfs_prevchan. * dfs_curchan and dfs_prevchan are updated after start response by @@ -866,7 +868,8 @@ bool utils_dfs_is_cac_required(struct wlan_objmgr_pdev *pdev, */ bool utils_dfs_is_cac_required_on_dfs_curchan(struct wlan_objmgr_pdev *pdev, - bool *continue_current_cac); + bool *continue_current_cac, + bool is_vap_restart); /** utils_dfs_is_precac_done() - Check if precac has been done in chosen channel * @pdev: Pointer to DFS pdev object. diff --git a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c index 8eb0efb24a..283fb43624 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c @@ -305,12 +305,13 @@ bool utils_dfs_is_cac_required(struct wlan_objmgr_pdev *pdev, return dfs_is_cac_required(dfs, &cur_channel, &prev_channel, - continue_current_cac); + continue_current_cac, true); } bool utils_dfs_is_cac_required_on_dfs_curchan(struct wlan_objmgr_pdev *pdev, - bool *continue_current_cac) + bool *continue_current_cac, + bool is_vap_restart) { struct wlan_dfs *dfs; @@ -321,7 +322,8 @@ utils_dfs_is_cac_required_on_dfs_curchan(struct wlan_objmgr_pdev *pdev, return dfs_is_cac_required(dfs, dfs->dfs_curchan, dfs->dfs_prevchan, - continue_current_cac); + continue_current_cac, + is_vap_restart); } QDF_STATUS utils_dfs_stacac_stop(struct wlan_objmgr_pdev *pdev)