From 2d6243e27e3d83b736f16da1e4ae2d9dd8502670 Mon Sep 17 00:00:00 2001 From: Ashish Kumar Dhanotiya Date: Tue, 28 Jul 2020 15:17:17 +0530 Subject: [PATCH] qcacmn: Do not update the NOL state of the channels Currently driver sets the NOL state of the channels to false on every regulatory updated, which indicates the channel is not in NOL. Which may lead to some issues where the channel is actually in NOL but host treats it as non-NOL channel. Ideally NOL list should be maintained throughout the driver lifetime and across the regulatory changes. To address this issue add a logic to not update the NOL state of the channels whenever the regulatory update is received. Change-Id: I7487a24a349f5f6e06a058b4d07799c8e5ac2d40 CRs-Fixed: 2735137 --- .../regulatory/core/src/reg_build_chan_list.c | 3 +- umac/regulatory/core/src/reg_priv_objs.c | 1 + umac/regulatory/core/src/reg_priv_objs.h | 3 ++ .../regulatory/core/src/reg_services_common.c | 47 ++++++++++++++++++- umac/regulatory/core/src/reg_utils.c | 2 + .../inc/reg_services_public_struct.h | 2 + 6 files changed, 56 insertions(+), 2 deletions(-) diff --git a/umac/regulatory/core/src/reg_build_chan_list.c b/umac/regulatory/core/src/reg_build_chan_list.c index fbc8532109..ee9d054660 100644 --- a/umac/regulatory/core/src/reg_build_chan_list.c +++ b/umac/regulatory/core/src/reg_build_chan_list.c @@ -1141,7 +1141,8 @@ QDF_STATUS reg_process_master_chan_list( REGULATORY_CHAN_DISABLED; mas_chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; - mas_chan_list[chan_enum].nol_chan = false; + if (!soc_reg->retain_nol_across_regdmn_update) + mas_chan_list[chan_enum].nol_chan = false; } soc_reg->num_phy = regulat_info->num_phy; diff --git a/umac/regulatory/core/src/reg_priv_objs.c b/umac/regulatory/core/src/reg_priv_objs.c index 1a67ae8bed..6362e09ffd 100644 --- a/umac/regulatory/core/src/reg_priv_objs.c +++ b/umac/regulatory/core/src/reg_priv_objs.c @@ -95,6 +95,7 @@ QDF_STATUS wlan_regulatory_psoc_obj_created_notification( soc_reg_obj->enable_11d_in_world_mode = false; soc_reg_obj->five_dot_nine_ghz_supported = false; soc_reg_obj->enable_5dot9_ghz_chan_in_master_mode = false; + soc_reg_obj->retain_nol_across_regdmn_update = false; for (i = 0; i < MAX_STA_VDEV_CNT; i++) soc_reg_obj->vdev_ids_11d[i] = INVALID_VDEV_ID; diff --git a/umac/regulatory/core/src/reg_priv_objs.h b/umac/regulatory/core/src/reg_priv_objs.h index 6d16939fb5..057420928d 100644 --- a/umac/regulatory/core/src/reg_priv_objs.h +++ b/umac/regulatory/core/src/reg_priv_objs.h @@ -99,6 +99,8 @@ struct chan_change_cbk_entry { * (service bit WMI_SERVICE_5_DOT_9GHZ_SUPPORT) * @enable_5dot9_ghz_chan_in_master_mode: 5.9 GHz channel support in * master mode (ini fcc_5dot9_ghz_chan_in_master_mode) + * @retain_nol_across_regdmn_update: Retain the NOL list across the regdomain + * changes. */ struct wlan_regulatory_psoc_priv_obj { struct mas_chan_params mas_chan_params[PSOC_MAX_PHY_REG_CAP]; @@ -150,6 +152,7 @@ struct wlan_regulatory_psoc_priv_obj { bool enable_11d_in_world_mode; bool enable_5dot9_ghz_chan_in_master_mode; qdf_spinlock_t cbk_list_lock; + bool retain_nol_across_regdmn_update; }; /** diff --git a/umac/regulatory/core/src/reg_services_common.c b/umac/regulatory/core/src/reg_services_common.c index 072906a18a..5ffdb95ff1 100644 --- a/umac/regulatory/core/src/reg_services_common.c +++ b/umac/regulatory/core/src/reg_services_common.c @@ -3657,13 +3657,54 @@ bool reg_is_dfs_for_freq(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq) return chan_flags & REGULATORY_CHAN_RADAR; } +#ifdef CONFIG_REG_CLIENT +/** + * reg_get_psoc_mas_chan_list () - Get psoc master channel list + * @pdev: pointer to pdev object + * @psoc: pointer to psoc object + * + * Return: psoc master chanel list + */ +static struct regulatory_channel *reg_get_psoc_mas_chan_list( + struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_psoc *psoc) +{ + struct wlan_regulatory_psoc_priv_obj *soc_reg; + uint8_t pdev_id; + uint8_t phy_id; + struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; + + soc_reg = reg_get_psoc_obj(psoc); + if (!soc_reg) { + reg_err("reg psoc private obj is NULL"); + return NULL; + } + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + + reg_tx_ops = reg_get_psoc_tx_ops(psoc); + if (reg_tx_ops->get_phy_id_from_pdev_id) + reg_tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id); + else + phy_id = pdev_id; + + return soc_reg->mas_chan_params[phy_id].mas_chan_list; +} +#else +static inline struct regulatory_channel *reg_get_psoc_mas_chan_list( + struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_psoc *psoc) +{ + return NULL; +} +#endif + void reg_update_nol_ch_for_freq(struct wlan_objmgr_pdev *pdev, uint16_t *chan_freq_list, uint8_t num_chan, bool nol_chan) { enum channel_enum chan_enum; - struct regulatory_channel *mas_chan_list; + struct regulatory_channel *mas_chan_list, *psoc_mas_chan_list; struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; struct wlan_objmgr_psoc *psoc; uint16_t i; @@ -3681,6 +3722,8 @@ void reg_update_nol_ch_for_freq(struct wlan_objmgr_pdev *pdev, return; } + psoc_mas_chan_list = reg_get_psoc_mas_chan_list(pdev, psoc); + mas_chan_list = pdev_priv_obj->mas_chan_list; for (i = 0; i < num_chan; i++) { chan_enum = reg_get_chan_enum_for_freq(chan_freq_list[i]); @@ -3690,6 +3733,8 @@ void reg_update_nol_ch_for_freq(struct wlan_objmgr_pdev *pdev, continue; } mas_chan_list[chan_enum].nol_chan = nol_chan; + if (psoc_mas_chan_list) + psoc_mas_chan_list[chan_enum].nol_chan = nol_chan; } reg_compute_pdev_current_chan_list(pdev_priv_obj); diff --git a/umac/regulatory/core/src/reg_utils.c b/umac/regulatory/core/src/reg_utils.c index b7bbf18d05..9eb9bb5e5f 100644 --- a/umac/regulatory/core/src/reg_utils.c +++ b/umac/regulatory/core/src/reg_utils.c @@ -796,6 +796,8 @@ QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc, config_vars.enable_11d_in_world_mode; psoc_priv_obj->enable_5dot9_ghz_chan_in_master_mode = config_vars.enable_5dot9_ghz_chan_in_master_mode; + psoc_priv_obj->retain_nol_across_regdmn_update = + config_vars.retain_nol_across_regdmn_update; status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); if (QDF_IS_STATUS_ERROR(status)) { diff --git a/umac/regulatory/dispatcher/inc/reg_services_public_struct.h b/umac/regulatory/dispatcher/inc/reg_services_public_struct.h index 4a20cb2f3e..285fd195d0 100644 --- a/umac/regulatory/dispatcher/inc/reg_services_public_struct.h +++ b/umac/regulatory/dispatcher/inc/reg_services_public_struct.h @@ -980,6 +980,7 @@ enum restart_beaconing_on_ch_avoid_rule { * @enable_11d_in_world_mode: enable 11d in world mode * @enable_5dot9_ghz_chan_in_master_mode: 5.9 GHz channel support in * master mode + * @retain_nol_across_regdmn_update: Retain the NOL list across the regdomain. */ struct reg_config_vars { uint32_t enable_11d_support; @@ -993,6 +994,7 @@ struct reg_config_vars { bool enable_srd_chan_in_master_mode; bool enable_11d_in_world_mode; bool enable_5dot9_ghz_chan_in_master_mode; + bool retain_nol_across_regdmn_update; }; /**