From 4b47f374dcd5f228cdae5366492f78db408f1153 Mon Sep 17 00:00:00 2001 From: Ashish Kumar Dhanotiya Date: Fri, 13 Apr 2018 16:34:10 +0530 Subject: [PATCH] qcacmn: Add support to disable channel list Propagation from prima to qcacmn Add support to disable channel list received with command "SET_DISABLE_CHANNEL_LIST". As part of this command, number of channels and list of that many channels should be given. When SAP comes up, disable the channels received in the command. If any of the interface is up on any of the channel from the list, first disconnect the interface and start the interface on the new channel. Change-Id: I3c7810bfde78878a3e60570a13bf2741e1da599b CRs-Fixed: 2225865 --- umac/regulatory/core/src/reg_priv.h | 5 + umac/regulatory/core/src/reg_services.c | 133 ++++++++++++++++++ umac/regulatory/core/src/reg_services.h | 35 +++++ .../dispatcher/inc/wlan_reg_ucfg_api.h | 36 +++++ .../dispatcher/src/wlan_reg_ucfg_api.c | 24 ++++ 5 files changed, 233 insertions(+) diff --git a/umac/regulatory/core/src/reg_priv.h b/umac/regulatory/core/src/reg_priv.h index b8e5d37eded0..a6de5efc8f33 100644 --- a/umac/regulatory/core/src/reg_priv.h +++ b/umac/regulatory/core/src/reg_priv.h @@ -83,6 +83,11 @@ struct wlan_regulatory_psoc_priv_obj { struct wlan_regulatory_pdev_priv_obj { struct regulatory_channel cur_chan_list[NUM_CHANNELS]; struct regulatory_channel mas_chan_list[NUM_CHANNELS]; +#ifdef DISABLE_CHANNEL_LIST + struct regulatory_channel cache_disable_chan_list[NUM_CHANNELS]; + uint32_t num_cache_channels; + bool disable_cached_channels; +#endif char default_country[REG_ALPHA2_LEN + 1]; uint16_t def_region_domain; uint16_t def_country_code; diff --git a/umac/regulatory/core/src/reg_services.c b/umac/regulatory/core/src/reg_services.c index de030ec37ea8..145338b84083 100644 --- a/umac/regulatory/core/src/reg_services.c +++ b/umac/regulatory/core/src/reg_services.c @@ -2181,6 +2181,37 @@ static void reg_modify_chan_list_for_indoor_channels( } } +#ifdef DISABLE_CHANNEL_LIST +static void reg_modify_chan_list_for_cached_channels( + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) +{ + uint32_t i, j, num_cache_channels = pdev_priv_obj->num_cache_channels; + struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list; + struct regulatory_channel *cache_chan_list = + pdev_priv_obj->cache_disable_chan_list; + + if (!num_cache_channels) + return; + + if (pdev_priv_obj->disable_cached_channels) { + for (i = 0; i < num_cache_channels; i++) + for (j = 0; j < NUM_CHANNELS; j++) + if (cache_chan_list[i].chan_num == + chan_list[j].chan_num) { + chan_list[j].state = + CHANNEL_STATE_DISABLE; + chan_list[j].chan_flags |= + REGULATORY_CHAN_DISABLED; + } + } +} +#else +static void reg_modify_chan_list_for_cached_channels( + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) +{ +} +#endif + static void reg_modify_chan_list_for_band(struct regulatory_channel *chan_list, enum band_info band_val) { @@ -2522,6 +2553,8 @@ static void reg_compute_pdev_current_chan_list( reg_modify_chan_list_for_chan_144(pdev_priv_obj->cur_chan_list, pdev_priv_obj->en_chan_144); + + reg_modify_chan_list_for_cached_channels(pdev_priv_obj); } static void reg_call_chan_change_cbks(struct wlan_objmgr_psoc *psoc, @@ -3287,6 +3320,105 @@ QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, return status; } +#ifdef DISABLE_CHANNEL_LIST +QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct wlan_objmgr_psoc *psoc; + QDF_STATUS status; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("pdev reg component is NULL"); + return QDF_STATUS_E_INVAL; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + reg_err("psoc is NULL"); + return QDF_STATUS_E_INVAL; + } + + psoc_priv_obj = reg_get_psoc_obj(psoc); + if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { + reg_err("psoc reg component is NULL"); + return QDF_STATUS_E_INVAL; + } + + pdev_priv_obj->disable_cached_channels = false; + reg_compute_pdev_current_chan_list(pdev_priv_obj); + status = reg_send_scheduler_msg_sb(psoc, pdev); + return status; +} + +QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, + uint32_t *channel_list, + uint32_t num_channels) +{ + struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct wlan_objmgr_psoc *psoc; + uint8_t i, j; + + pdev_priv_obj = reg_get_pdev_obj(pdev); + + if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { + reg_err("pdev reg component is NULL"); + return QDF_STATUS_E_INVAL; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + reg_err("psoc is NULL"); + return QDF_STATUS_E_INVAL; + } + + psoc_priv_obj = reg_get_psoc_obj(psoc); + if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { + reg_err("psoc reg component is NULL"); + return QDF_STATUS_E_INVAL; + } + if (pdev_priv_obj->num_cache_channels > 0) { + pdev_priv_obj->num_cache_channels = 0; + qdf_mem_set(&pdev_priv_obj->cache_disable_chan_list, + sizeof(pdev_priv_obj->cache_disable_chan_list), 0); + } + + for (i = 0; i < num_channels; i++) { + for (j = 0; j < NUM_CHANNELS; j++) { + if (channel_list[i] == pdev_priv_obj-> + cur_chan_list[j].chan_num) { + pdev_priv_obj-> + cache_disable_chan_list[i].chan_num = + channel_list[i]; + pdev_priv_obj-> + cache_disable_chan_list[i].state = + pdev_priv_obj->cur_chan_list[j].state; + pdev_priv_obj-> + cache_disable_chan_list[i].chan_flags = + pdev_priv_obj-> + cur_chan_list[j].chan_flags; + } + } + } + pdev_priv_obj->num_cache_channels = num_channels; + + return QDF_STATUS_SUCCESS; +} + +static void set_disable_channel_state( + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) +{ + pdev_priv_obj->disable_cached_channels = pdev_priv_obj->sap_state; +} +#else +static void set_disable_channel_state( + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) +{ +} +#endif + QDF_STATUS reg_notify_sap_event(struct wlan_objmgr_pdev *pdev, bool sap_state) { @@ -3320,6 +3452,7 @@ QDF_STATUS reg_notify_sap_event(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_SUCCESS; pdev_priv_obj->sap_state = sap_state; + set_disable_channel_state(pdev_priv_obj); reg_compute_pdev_current_chan_list(pdev_priv_obj); status = reg_send_scheduler_msg_sb(psoc, pdev); diff --git a/umac/regulatory/core/src/reg_services.h b/umac/regulatory/core/src/reg_services.h index f843eb61c920..c78c65c8af3f 100644 --- a/umac/regulatory/core/src/reg_services.h +++ b/umac/regulatory/core/src/reg_services.h @@ -130,6 +130,41 @@ void reg_set_channel_params(struct wlan_objmgr_pdev *pdev, */ QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, enum band_info band); +/** + * reg_restore_cached_channels() - Cache the current state of the channles + * @pdev: The physical dev to cache the channels for + */ +#ifdef DISABLE_CHANNEL_LIST +QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev); +#else +static inline +QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +/** + * reg_cache_channel_state() - Cache the current state of the channles + * @pdev: The physical dev to cache the channels for + * @channel_list: List of the channels for which states needs to be cached + * @num_channels: Number of channels in the list + * + */ +#ifdef DISABLE_CHANNEL_LIST +QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, + uint32_t *channel_list, + uint32_t num_channels); +#else +static inline +QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, + uint32_t *channel_list, + uint32_t num_channels) +{ + return QDF_STATUS_SUCCESS; +} +#endif + /** * reg_notify_sap_event() - Notify regulatory domain for sap event * @pdev: The physical dev to set the band for diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h index 0fb420b7a6d0..286ee9837f06 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h +++ b/umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h @@ -53,6 +53,42 @@ QDF_STATUS ucfg_reg_set_band(struct wlan_objmgr_pdev *pdev, QDF_STATUS ucfg_reg_notify_sap_event(struct wlan_objmgr_pdev *pdev, bool sap_state); +/** + * ucfg_reg_cache_channel_state() - Cache the current state of the channles + * @pdev: The physical dev to cache the channels for + * @channel_list: List of the channels for which states needs to be cached + * @num_channels: Number of channels in the list + * + * Return: QDF_STATUS + */ +#ifdef DISABLE_CHANNEL_LIST +void ucfg_reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, + uint32_t *channel_list, + uint32_t num_channels); +#else +static inline +void ucfg_reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, + uint32_t *channel_list, + uint32_t num_channels) +{ +} +#endif + +/** + * ucfg_reg_restore_cached_channels() - Cache the current state of the channles + * @pdev: The physical dev to cache the channels for + * + * Return: QDF_STATUS + */ +#ifdef DISABLE_CHANNEL_LIST +void ucfg_reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev); +#else +static inline +void ucfg_reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) +{ +} +#endif + /** * ucfg_reg_set_fcc_constraint() - apply fcc constraints on channels 12/13 * @pdev: The physical pdev to reduce tx power for diff --git a/umac/regulatory/dispatcher/src/wlan_reg_ucfg_api.c b/umac/regulatory/dispatcher/src/wlan_reg_ucfg_api.c index 4ae7b03331ee..61252f6e786d 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_ucfg_api.c +++ b/umac/regulatory/dispatcher/src/wlan_reg_ucfg_api.c @@ -131,6 +131,30 @@ QDF_STATUS ucfg_reg_notify_sap_event(struct wlan_objmgr_pdev *pdev, return reg_notify_sap_event(pdev, sap_state); } +#ifdef DISABLE_CHANNEL_LIST +/** + * ucfg_reg_cache_channel_state() - Cache the current state of the channles + * @pdev: The physical dev to cache the channels for + * @channel_list: List of the channels for which states needs to be cached + * @num_channels: Number of channels in the list + * + */ +void ucfg_reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, + uint32_t *channel_list, uint32_t num_channels) +{ + reg_cache_channel_state(pdev, channel_list, num_channels); +} + +/** + * ucfg_reg_restore_cached_channels() - Cache the current state of the channles + * @pdev: The physical dev to cache the channels for + */ +void ucfg_reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) +{ + reg_restore_cached_channels(pdev); +} +#endif + /** * ucfg_reg_set_fcc_constraint() - apply fcc constraints on channels 12/13 * @pdev: The physical pdev to reduce tx power for