From 62ce2260e9cb42891668845056ea4639a23160cf Mon Sep 17 00:00:00 2001 From: Shashikala Prabhu Date: Wed, 24 Oct 2018 08:45:34 +0530 Subject: [PATCH] qcacmn: Use regdb component to set/get NOL-History channel list In case of STADFS feature, when STA vap detects the RADAR, it marks the channel as RADAR and adds the RADAR found channel to both NOL and NOL-HISTORY list. After nol expiry, STA vap does the CAC before connecting to the RootAP if the RootAP channel is present in the STA NOL-HISTORY. Set nol_history_flag in regulatory component current channel list when STA vap detects the RADAR. Change-Id: I8d01f5830e6b4dd634b71c551ac347bc7d3d5c4c CRs-Fixed: 2337921 --- umac/dfs/core/src/dfs.h | 2 + umac/dfs/core/src/misc/dfs_nol.c | 83 +++++++++++-------- .../src/misc/dfs_process_radar_found_ind.c | 7 ++ umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h | 8 ++ umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h | 15 ++++ umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h | 2 + umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h | 31 +++++++ .../dispatcher/src/wlan_dfs_init_deinit_api.c | 2 + umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c | 8 ++ umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c | 26 ++++++ umac/dfs/dispatcher/src/wlan_dfs_utils_api.c | 74 ++++++++++++++--- 11 files changed, 211 insertions(+), 47 deletions(-) diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index de4ce095db4a..21bd980f49f3 100644 --- a/umac/dfs/core/src/dfs.h +++ b/umac/dfs/core/src/dfs.h @@ -1003,6 +1003,7 @@ struct dfs_event_log { * @dfs_spoof_test_done: Indicates if the sppof test is done. * @dfs_status_timeout_override: Used to change the timeout value of * dfs_host_wait_timer. + * @dfs_is_stadfs_enabled: Is STADFS enabled. * @dfs_min_sidx: Minimum sidx of the received radar pulses. * @dfs_max_sidx: Maximum sidx of the received radar pulses. * @dfs_seg_id: Segment ID of the radar hit channel. @@ -1140,6 +1141,7 @@ struct wlan_dfs { struct dfs_channel dfs_radar_found_chan; int dfs_status_timeout_override; #endif + bool dfs_is_stadfs_enabled; uint32_t dfs_min_sidx; uint32_t dfs_max_sidx; uint8_t dfs_seg_id; diff --git a/umac/dfs/core/src/misc/dfs_nol.c b/umac/dfs/core/src/misc/dfs_nol.c index b8502a40d8fd..4f24f3f808cc 100644 --- a/umac/dfs/core/src/misc/dfs_nol.c +++ b/umac/dfs/core/src/misc/dfs_nol.c @@ -292,34 +292,35 @@ void dfs_print_nol(struct wlan_dfs *dfs) void dfs_print_nolhistory(struct wlan_dfs *dfs) { - struct dfs_channel *c, lc; - int i, j = 0; - int nchans = 0; + struct dfs_channel *chan_list; + int i, j; + int nchans; if (!dfs) { dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); return; } - c = &lc; + nchans = dfs_get_num_chans(); - dfs_mlme_get_dfs_ch_nchans(dfs->dfs_pdev_obj, &nchans); - for (i = 0; i < nchans; i++) { - dfs_mlme_get_dfs_ch_channels(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), - i); - if (WLAN_IS_CHAN_HISTORY_RADAR(c)) { - dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, - "nolhistory:%d channel=%d MHz Flags=%llx", - j, c->dfs_ch_freq, c->dfs_ch_flags); - j++; - } + 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; } + + for (i = 0, j = 0; i < nchans; i++, j++) + dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, + "nolhistory = %d channel = %d MHz", + j, chan_list[i].dfs_ch_freq); + + qdf_mem_free(chan_list); } void dfs_get_nol(struct wlan_dfs *dfs, @@ -592,24 +593,36 @@ void dfs_getnol(struct wlan_dfs *dfs, void *dfs_nolinfo) void dfs_clear_nolhistory(struct wlan_dfs *dfs) { - /* We should have a dfs_clear_nolhistory API from Regdomain. */ - struct dfs_channel *c, lc; - int i; + struct dfs_channel *chan_list; int nchans = 0; + bool sta_opmode; - c = &lc; - dfs_mlme_get_dfs_ch_nchans(dfs->dfs_pdev_obj, &nchans); - for (i = 0; i < nchans; i++) { - dfs_mlme_get_dfs_ch_channels(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), - i); - WLAN_CHAN_CLR_HISTORY_RADAR(c); + 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_ch(dfs->dfs_pdev_obj, + (void *)chan_list, nchans, + DFS_NOL_HISTORY_RESET); + + qdf_mem_free(chan_list); } #if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) 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 5933b198e95a..3b1c4980cc8a 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 @@ -170,6 +170,13 @@ static QDF_STATUS dfs_radar_add_channel_list_to_nol(struct wlan_dfs *dfs, utils_dfs_reg_update_nol_ch(dfs->dfs_pdev_obj, nollist, 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); + dfs_nol_update(dfs); utils_dfs_save_nol(dfs->dfs_pdev_obj); diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h index 73b5f9baad13..dab1edda5d17 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_mlme_api.h @@ -281,4 +281,12 @@ void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev) { } #endif + +/** + * dfs_mlme_is_opmode_sta() - Check if pdev opmode is STA. + * @pdev: Pointer to DFS pdev object. + * + * Return: true if pdev opmode is STA, else false. + */ +bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev); #endif /* _WLAN_DFS_MLME_API_H_ */ diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h index aac43dd84fa8..4931e4961b9d 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_tgt_api.h @@ -395,6 +395,21 @@ QDF_STATUS tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev *pdev) } #endif +/** + * tgt_dfs_enable_stadfs() - Enable/Disable STADFS capability. + * @pdev: Pointer to DFS pdev object. + * @val: input value. + */ +void tgt_dfs_enable_stadfs(struct wlan_objmgr_pdev *pdev, bool val); + +/** + * tgt_dfs_is_stadfs_enabled() - Get STADFS capability + * @pdev: Pointer to DFS pdev object. + * + * Return: true if STADFS is enabled, else false. + */ +bool tgt_dfs_is_stadfs_enabled(struct wlan_objmgr_pdev *pdev); + /** * tgt_dfs_is_pdev_5ghz() - Check if the input pdev is 5GHZ. * @pdev: Pointer to DFS pdev object. diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h index 69e8a19ebf30..2314fcd2efaa 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_ucfg_api.h @@ -52,6 +52,7 @@ * Channel Switch Announcement. * @mlme_nol_timeout_notification: NOL timeout notification. * @mlme_clist_update: Updates the channel list. + * @mlme_is_opmode_sta: Check if pdev opmode is STA. * @mlme_get_cac_timeout: Gets the CAC timeout. * @mlme_rebuild_chan_list_with_non_dfs_channel: Rebuild channels with non-dfs * channels. @@ -132,6 +133,7 @@ struct dfs_to_mlme { QDF_STATUS (*mlme_clist_update)(struct wlan_objmgr_pdev *pdev, void *nollist, int nentries); + bool (*mlme_is_opmode_sta)(struct wlan_objmgr_pdev *pdev); QDF_STATUS (*mlme_get_cac_timeout)(struct wlan_objmgr_pdev *pdev, uint16_t dfs_ch_freq, uint8_t c_vhtop_ch_freq_seg2, diff --git a/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h b/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h index fe53d9d0b033..b24eb07426ce 100644 --- a/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h +++ b/umac/dfs/dispatcher/inc/wlan_dfs_utils_api.h @@ -34,6 +34,12 @@ /* Remove channel from nol */ #define DFS_NOL_RESET 0 +/* Mark nol-history flag for the channel */ +#define DFS_NOL_HISTORY_SET 1 + +/* Clear nol-history flag from the channel */ +#define DFS_NOL_HISTORY_RESET 0 + /* Max nol channels */ #define DFS_MAX_NOL_CHANNEL 80 @@ -560,6 +566,31 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, void *clist, uint32_t *num_chan); +/** + * utils_dfs_get_nol_history_chan_list() - Get nol_history channels from regdb + * component. + * @pdev: Pointer to pdev structure. + * @clist: Pointer to channel list. + * @num_chan: number of channels. + */ +void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev, + void *clist, uint32_t *num_chan); + +/** + * utils_dfs_reg_update_nol_history_ch() - set nol history channel + * + * @pdev: pdev ptr + * @ch_list: channel list to be returned + * @num_ch: number of channels + * @nol_history_ch: nol history flag + * + * Return: void + */ +void utils_dfs_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev, + uint8_t *ch_list, + uint8_t num_ch, + bool nol_history_ch); + /** * utils_dfs_check_for_cac_start() - Check for DFS CAC start conditions. * @pdev: pdev ptr diff --git a/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c b/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c index ded8ad941122..f5594ad14571 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c @@ -102,6 +102,8 @@ void register_dfs_callbacks(void) mlme_dfs_rebuild_chan_list_with_non_dfs_channels; tmp_dfs_to_mlme->mlme_restart_vaps_with_non_dfs_chan = mlme_dfs_restart_vaps_with_non_dfs_chan; + tmp_dfs_to_mlme->mlme_is_opmode_sta = + mlme_dfs_is_opmode_sta; tmp_dfs_to_mlme->mlme_check_allowed_prim_chanlist = mlme_dfs_check_allowed_prim_chanlist; tmp_dfs_to_mlme->mlme_update_scan_channel_list = diff --git a/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c b/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c index 801d12f6dd82..94b5b96d073c 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_mlme_api.c @@ -338,3 +338,11 @@ void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev) global_dfs_to_mlme.mlme_update_scan_channel_list(pdev); } #endif + +bool dfs_mlme_is_opmode_sta(struct wlan_objmgr_pdev *pdev) +{ + if (!global_dfs_to_mlme.mlme_is_opmode_sta) + return false; + + return global_dfs_to_mlme.mlme_is_opmode_sta(pdev); +} diff --git a/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c b/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c index a4cc0ea264b6..ecee93d23b91 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_tgt_api.c @@ -610,3 +610,29 @@ QDF_STATUS tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev, qdf_export_symbol(tgt_dfs_send_usenol_pdev_param); #endif + +void tgt_dfs_enable_stadfs(struct wlan_objmgr_pdev *pdev, bool val) +{ + struct wlan_dfs *dfs; + + dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return; + } + + dfs->dfs_is_stadfs_enabled = val; +} + +bool tgt_dfs_is_stadfs_enabled(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_dfs *dfs; + + dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); + if (!dfs) { + dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is NULL"); + return false; + } + + return dfs->dfs_is_stadfs_enabled; +} diff --git a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c index f7ae9b97b245..1328ac36ec7c 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_utils_api.c @@ -429,6 +429,43 @@ static void utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev *pdev, } #ifndef QCA_DFS_USE_POLICY_MANAGER +void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev, + void *clist, uint32_t *num_chan) +{ + int i, j = 0; + struct regulatory_channel *cur_chan_list; + struct wlan_dfs *dfs; + struct dfs_channel *chan_list = (struct dfs_channel *)clist; + + *num_chan = 0; + + dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev); + if (!dfs) + return; + + cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(*cur_chan_list)); + if (!cur_chan_list) + return; + + if (wlan_reg_get_current_chan_list( + pdev, cur_chan_list) != QDF_STATUS_SUCCESS) { + dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS, + "failed to get cur_chan list"); + qdf_mem_free(cur_chan_list); + return; + } + + for (i = 0; i < NUM_CHANNELS; i++) { + if (cur_chan_list[i].nol_history) { + chan_list[j].dfs_ch_freq = cur_chan_list[i].center_freq; + j++; + } + } + + *num_chan = j; + qdf_mem_free(cur_chan_list); +} + void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, void *clist, uint32_t *num_chan) { @@ -467,6 +504,10 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, if (state == CHANNEL_STATE_DFS) chan_list[j].dfs_ch_flagext = WLAN_CHAN_DFS; + + if (cur_chan_list[i].nol_history) + chan_list[j].dfs_ch_flagext |= + WLAN_CHAN_HISTORY_RADAR; j++; } } @@ -477,19 +518,20 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, } /** - * utils_dfs_get_channel_list() - Get channel list from regdb component based + * utils_dfs_get_channel_list() - Get channel list from regdb component, based * on current channel list. * @pdev: Pointer to pdev structure. - * @chan_list: Pointer to regdb channel list. + * @chan: Pointer to channel list. * @num_chan: number of channels. * * Get regdb channel list based on dfs current channel. - * ex: When AP is operating in 5GHz channel, filter 2.4GHz and 4.9GHZ channels + * Ex: When AP is operating in 5GHz channel, filter 2.4GHz and 4.9GHZ channels * so that the random channel function does not select either 2.4GHz or 4.9GHz * channel. */ static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, - struct dfs_channel *chan_list, uint32_t *num_chan) + struct dfs_channel *chan_list, + uint32_t *num_chan) { struct dfs_channel *tmp_chan_list = NULL; struct wlan_dfs *dfs; @@ -554,6 +596,12 @@ static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, #else +void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev, + void *clist, uint32_t *num_chan) +{ + utils_dfs_get_chan_list(pdev, clist, num_chan); +} + void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, void *clist, uint32_t *num_chan) { @@ -601,15 +649,9 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev, dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "num channels %d", i); } -/** - * utils_dfs_get_channel_list() - Wrapper function to get channel list from - * regdb component. - * @pdev: Pointer to pdev structure. - * @chan_list: Pointer to regdb channel list. - * @num_chan: number of channels. - */ static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev, - struct dfs_channel *chan_list, uint32_t *num_chan) + struct dfs_channel *chan_list, + uint32_t *num_chan) { utils_dfs_get_chan_list(pdev, (void *)chan_list, num_chan); } @@ -886,6 +928,14 @@ void utils_dfs_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, } qdf_export_symbol(utils_dfs_reg_update_nol_ch); +void utils_dfs_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev, + uint8_t *ch_list, + uint8_t num_ch, + bool nol_history_ch) +{ + wlan_reg_update_nol_history_ch(pdev, ch_list, num_ch, nol_history_ch); +} + uint8_t utils_dfs_freq_to_chan(uint32_t freq) { uint8_t chan;