From 36462d50b86a0df8570a78c43be11843bb18c9ef Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Wed, 1 Aug 2018 05:01:14 -0400 Subject: [PATCH] qcacmn: add 11d periodic scan in host Add periodic 11d scan in host for non-11d scan offload hw. Periodic interval is controlled by INI scan_11d_interval, default 1 hr. Change-Id: I66d1e76a1c147fc52f0e18b6601d3be4b4973210 CRs-Fixed: 2314830 --- umac/regulatory/core/src/reg_host_11d.c | 172 ++++++++++++++++++ umac/regulatory/core/src/reg_host_11d.h | 76 ++++++++ umac/regulatory/core/src/reg_priv.h | 9 + umac/regulatory/core/src/reg_services.c | 67 ++++--- umac/regulatory/core/src/reg_services.h | 4 +- .../dispatcher/inc/wlan_reg_services_api.h | 4 +- .../dispatcher/src/wlan_reg_services_api.c | 4 +- umac/scan/dispatcher/src/wlan_scan_ucfg_api.c | 4 +- 8 files changed, 310 insertions(+), 30 deletions(-) create mode 100644 umac/regulatory/core/src/reg_host_11d.c create mode 100644 umac/regulatory/core/src/reg_host_11d.h diff --git a/umac/regulatory/core/src/reg_host_11d.c b/umac/regulatory/core/src/reg_host_11d.c new file mode 100644 index 000000000000..8fa49dd3547a --- /dev/null +++ b/umac/regulatory/core/src/reg_host_11d.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: Add host 11d scan utility functions + */ + +#include +#include +#include "reg_services.h" +#include "reg_priv.h" +#include "reg_host_11d.h" + +static QDF_STATUS reg_11d_scan_trigger_handler( + struct wlan_regulatory_psoc_priv_obj *soc_reg) +{ + struct scan_start_request *req; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status; + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) + return QDF_STATUS_E_NOMEM; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc( + soc_reg->psoc_ptr, + soc_reg->vdev_id_for_11d_scan, + WLAN_REGULATORY_SB_ID); + if (!vdev) { + reg_err("vdev object is NULL id %d", + soc_reg->vdev_id_for_11d_scan); + qdf_mem_free(req); + return QDF_STATUS_E_FAILURE; + } + + ucfg_scan_init_default_params(vdev, req); + + req->scan_req.scan_id = ucfg_scan_get_scan_id(soc_reg->psoc_ptr); + if (!req->scan_req.scan_id) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_REGULATORY_SB_ID); + qdf_mem_free(req); + reg_err("Invalid scan ID"); + return QDF_STATUS_E_FAILURE; + } + soc_reg->scan_id = req->scan_req.scan_id; + req->scan_req.vdev_id = soc_reg->vdev_id_for_11d_scan; + req->scan_req.scan_req_id = soc_reg->scan_req_id; + req->scan_req.scan_priority = SCAN_PRIORITY_LOW; + req->scan_req.scan_f_passive = false; + + status = ucfg_scan_start(req); + reg_debug("11d scan trigger vdev %d scan_id %d req_id %d status %d", + soc_reg->vdev_id_for_11d_scan, soc_reg->scan_id, + soc_reg->scan_req_id, status); + + if (status != QDF_STATUS_SUCCESS) + /* Don't free req here, ucfg_scan_start will do free */ + reg_err("11d scan req failed vdev %d", + soc_reg->vdev_id_for_11d_scan); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_REGULATORY_SB_ID); + + return status; +} + +static void reg_11d_scan_event_cb( + struct wlan_objmgr_vdev *vdev, + struct scan_event *event, void *arg) +{ +}; + +QDF_STATUS reg_11d_host_scan( + struct wlan_regulatory_psoc_priv_obj *soc_reg) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + reg_debug("host 11d enabled %d, inited: %d", soc_reg->enable_11d_supp, + soc_reg->is_host_11d_inited); + if (!soc_reg->is_host_11d_inited) + return QDF_STATUS_E_FAILURE; + + if (soc_reg->enable_11d_supp) { + qdf_mc_timer_stop(&soc_reg->timer); + status = reg_11d_scan_trigger_handler(soc_reg); + if (status != QDF_STATUS_SUCCESS) { + reg_err("11d scan trigger failed!"); + return status; + } + + qdf_mc_timer_start(&soc_reg->timer, soc_reg->scan_11d_interval); + } else { + qdf_mc_timer_stop(&soc_reg->timer); + } + return status; +} + +static void reg_11d_scan_timer(void *context) +{ + struct wlan_regulatory_psoc_priv_obj *soc_reg = context; + + reg_debug("11d scan timeout"); + + if (!soc_reg) + return; + + reg_11d_host_scan(soc_reg); +} + +QDF_STATUS reg_11d_host_scan_init(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_regulatory_psoc_priv_obj *soc_reg; + + soc_reg = reg_get_psoc_obj(psoc); + if (!soc_reg) { + reg_err("reg psoc private obj is NULL"); + return QDF_STATUS_E_FAULT; + } + + if (soc_reg->is_host_11d_inited) { + reg_debug("host 11d scan are already inited"); + return QDF_STATUS_SUCCESS; + } + soc_reg->scan_req_id = + ucfg_scan_register_requester(psoc, "11d", + reg_11d_scan_event_cb, + soc_reg); + qdf_mc_timer_init(&soc_reg->timer, QDF_TIMER_TYPE_SW, + reg_11d_scan_timer, soc_reg); + + soc_reg->is_host_11d_inited = true; + reg_debug("reg 11d scan inited"); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS reg_11d_host_scan_deinit(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_regulatory_psoc_priv_obj *soc_reg; + + soc_reg = reg_get_psoc_obj(psoc); + if (!soc_reg) { + reg_err("reg psoc private obj is NULL"); + return QDF_STATUS_E_FAULT; + } + + if (!soc_reg->is_host_11d_inited) { + reg_debug("host 11d scan are not inited"); + return QDF_STATUS_SUCCESS; + } + qdf_mc_timer_stop(&soc_reg->timer); + qdf_mc_timer_destroy(&soc_reg->timer); + ucfg_scan_unregister_requester(psoc, soc_reg->scan_req_id); + soc_reg->is_host_11d_inited = false; + reg_debug("reg 11d scan deinit"); + + return QDF_STATUS_SUCCESS; +} diff --git a/umac/regulatory/core/src/reg_host_11d.h b/umac/regulatory/core/src/reg_host_11d.h new file mode 100644 index 000000000000..7f0e620609b1 --- /dev/null +++ b/umac/regulatory/core/src/reg_host_11d.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: Defines host 11d scan utility functions + */ +#ifndef _REG_HOST_11D_H_ +#define _REG_HOST_11D_H_ + +#ifdef HOST_11D_SCAN +/** + * reg_11d_host_scan() - Start/stop 11d scan + * @soc_reg: soc regulatory context + * + * This function gets called upon 11d scan enable/disable changed. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS reg_11d_host_scan( + struct wlan_regulatory_psoc_priv_obj *soc_reg); + +/** + * reg_11d_host_scan_init() - Inid 11d host scan resource + * @psoc: soc context + * + * This function gets called during pdev create notification callback to + * init the 11d scan related resouce. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS reg_11d_host_scan_init(struct wlan_objmgr_psoc *psoc); + +/** + * reg_11d_host_scan_deinit() - Deinit 11d host scan resource + * @psoc: soc context + * + * This function gets called during pdev destroy notification callback to + * deinit the 11d scan related resouce. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS reg_11d_host_scan_deinit(struct wlan_objmgr_psoc *psoc); +#else +static inline QDF_STATUS reg_11d_host_scan( + struct wlan_regulatory_psoc_priv_obj *soc_reg) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS reg_11d_host_scan_init(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS reg_11d_host_scan_deinit( + struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} +#endif +#endif diff --git a/umac/regulatory/core/src/reg_priv.h b/umac/regulatory/core/src/reg_priv.h index 0367a3dff264..f5c5faf8d322 100644 --- a/umac/regulatory/core/src/reg_priv.h +++ b/umac/regulatory/core/src/reg_priv.h @@ -27,6 +27,9 @@ #include "reg_db.h" #include "reg_services.h" +#ifdef HOST_11D_SCAN +#include +#endif #define reg_alert(params...) \ QDF_TRACE_FATAL(QDF_MODULE_ID_REGULATORY, params) @@ -77,6 +80,12 @@ struct wlan_regulatory_psoc_priv_obj { uint8_t master_vdev_cnt; uint8_t vdev_cnt_11d; uint32_t scan_11d_interval; +#ifdef HOST_11D_SCAN + bool is_host_11d_inited; + wlan_scan_requester scan_req_id; + uint32_t scan_id; + qdf_mc_timer_t timer; +#endif uint8_t vdev_ids_11d[MAX_STA_VDEV_CNT]; bool user_ctry_priority; bool user_ctry_set; diff --git a/umac/regulatory/core/src/reg_services.c b/umac/regulatory/core/src/reg_services.c index 2a6e6bd4a15e..a4607a50e074 100644 --- a/umac/regulatory/core/src/reg_services.c +++ b/umac/regulatory/core/src/reg_services.c @@ -24,6 +24,7 @@ #include "reg_services.h" #include "reg_priv.h" #include "reg_db_parser.h" +#include "reg_host_11d.h" #include #define CHAN_12_CENT_FREQ 2467 @@ -2989,10 +2990,20 @@ static void reg_run_11d_state_machine(struct wlan_objmgr_psoc *psoc) psoc_priv_obj->enable_11d_supp = psoc_priv_obj->enable_11d_supp_original; - reg_debug("inside 11d state machine"); - if ((temp_11d_support != psoc_priv_obj->enable_11d_supp) && - (psoc_priv_obj->is_11d_offloaded)) { - reg_sched_11d_msg(psoc); + reg_debug("inside 11d state machine:tmp %d 11d_supp %d org %d set %d pri %d cnt %d vdev %d", + temp_11d_support, + psoc_priv_obj->enable_11d_supp, + psoc_priv_obj->enable_11d_supp_original, + psoc_priv_obj->user_ctry_set, + psoc_priv_obj->user_ctry_priority, + psoc_priv_obj->master_vdev_cnt, + psoc_priv_obj->vdev_id_for_11d_scan); + + if (temp_11d_support != psoc_priv_obj->enable_11d_supp) { + if (psoc_priv_obj->is_11d_offloaded) + reg_sched_11d_msg(psoc); + else + reg_11d_host_scan(psoc_priv_obj); } } @@ -3664,6 +3675,9 @@ QDF_STATUS wlan_regulatory_pdev_obj_created_notification( WLAN_UMAC_COMP_REGULATORY, pdev_priv_obj, QDF_STATUS_SUCCESS); + if (QDF_IS_STATUS_SUCCESS(status) && + !psoc_priv_obj->is_11d_offloaded) + reg_11d_host_scan_init(parent_psoc); reg_debug("reg pdev obj created with status %d", status); @@ -3675,6 +3689,7 @@ QDF_STATUS wlan_regulatory_pdev_obj_destroyed_notification( { QDF_STATUS status; struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; + struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; pdev_priv_obj = reg_get_pdev_obj(pdev); @@ -3683,6 +3698,15 @@ QDF_STATUS wlan_regulatory_pdev_obj_destroyed_notification( return QDF_STATUS_E_FAILURE; } + psoc_priv_obj = reg_get_psoc_obj(wlan_pdev_get_psoc(pdev)); + if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { + reg_err("reg psoc private obj is NULL"); + return QDF_STATUS_E_FAILURE; + } + + if (!psoc_priv_obj->is_11d_offloaded) + reg_11d_host_scan_deinit(wlan_pdev_get_psoc(pdev)); + pdev_priv_obj->pdev_ptr = NULL; status = wlan_objmgr_pdev_component_obj_detach(pdev, @@ -4586,23 +4610,6 @@ QDF_STATUS reg_save_new_11d_country(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -bool reg_11d_original_enabled_on_host(struct wlan_objmgr_psoc *psoc) -{ - struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; - - psoc_priv_obj = - wlan_objmgr_psoc_get_comp_private_obj(psoc, - WLAN_UMAC_COMP_REGULATORY); - - if (NULL == psoc_priv_obj) { - reg_err("reg psoc private obj is NULL"); - return QDF_STATUS_E_FAILURE; - } - - return (psoc_priv_obj->enable_11d_supp_original && - !psoc_priv_obj->is_11d_offloaded); -} - bool reg_11d_enabled_on_host(struct wlan_objmgr_psoc *psoc) { struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; @@ -4649,10 +4656,26 @@ QDF_STATUS reg_set_11d_offloaded(struct wlan_objmgr_psoc *psoc, } soc_reg->is_11d_offloaded = val; - + reg_debug("set is_11d_offloaded %d", val); return QDF_STATUS_SUCCESS; } +bool reg_is_11d_offloaded(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; + + psoc_priv_obj = + wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_REGULATORY); + + if (!psoc_priv_obj) { + reg_err("reg psoc private obj is NULL"); + return false; + } + + return psoc_priv_obj->is_11d_offloaded; +} + QDF_STATUS reg_get_curr_regdomain(struct wlan_objmgr_pdev *pdev, struct cur_regdmn_info *cur_regdmn) { diff --git a/umac/regulatory/core/src/reg_services.h b/umac/regulatory/core/src/reg_services.h index c78c65c8af3f..365af36d3d51 100644 --- a/umac/regulatory/core/src/reg_services.h +++ b/umac/regulatory/core/src/reg_services.h @@ -502,12 +502,12 @@ QDF_STATUS reg_save_new_11d_country(struct wlan_objmgr_psoc *psoc, uint8_t *country); /** - * reg_11d_original_enabled_on_host() - whether 11d original enabled on host + * reg_is_11d_offloaded() - whether 11d offloaded supported or not * @psoc: psoc ptr * * Return: bool */ -bool reg_11d_original_enabled_on_host(struct wlan_objmgr_psoc *psoc); +bool reg_is_11d_offloaded(struct wlan_objmgr_psoc *psoc); /** * reg_11d_enabled_on_host() - know whether 11d enabled on host diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h index a11c4efa16f8..6238653560fc 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h @@ -479,12 +479,12 @@ void wlan_reg_unregister_chan_change_callback(struct wlan_objmgr_psoc *psoc, reg_chan_change_callback cbk); /** - * wlan_reg_11d_original_enabled_on_host() - 11d original enabled don host + * wlan_reg_is_11d_offloaded() - 11d offloaded supported * @psoc: psoc ptr * * Return: bool */ -bool wlan_reg_11d_original_enabled_on_host(struct wlan_objmgr_psoc *psoc); +bool wlan_reg_is_11d_offloaded(struct wlan_objmgr_psoc *psoc); /** * wlan_reg_11d_enabled_on_host() - 11d enabled don host diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index 3345061bc145..1d957ef7a50f 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c @@ -498,9 +498,9 @@ void wlan_reg_unregister_chan_change_callback(struct wlan_objmgr_psoc *psoc, reg_unregister_chan_change_callback(psoc, cbk); } -bool wlan_reg_11d_original_enabled_on_host(struct wlan_objmgr_psoc *psoc) +bool wlan_reg_is_11d_offloaded(struct wlan_objmgr_psoc *psoc) { - return reg_11d_original_enabled_on_host(psoc); + return reg_is_11d_offloaded(psoc); } bool wlan_reg_11d_enabled_on_host(struct wlan_objmgr_psoc *psoc) diff --git a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c index 4401dd31e77b..33a612bdf6ea 100644 --- a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c @@ -2181,7 +2181,7 @@ ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc) /* Subscribe for scan events from lmac layesr */ status = tgt_scan_register_ev_handler(psoc); QDF_ASSERT(status == QDF_STATUS_SUCCESS); - if (wlan_reg_11d_original_enabled_on_host(psoc)) + if (!wlan_reg_is_11d_offloaded(psoc)) scm_11d_cc_db_init(psoc); ucfg_scan_register_unregister_bcn_cb(psoc, true); status = wlan_serialization_register_apply_rules_cb(psoc, @@ -2205,7 +2205,7 @@ ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc) status = tgt_scan_unregister_ev_handler(psoc); QDF_ASSERT(status == QDF_STATUS_SUCCESS); ucfg_scan_register_unregister_bcn_cb(psoc, false); - if (wlan_reg_11d_original_enabled_on_host(psoc)) + if (!wlan_reg_is_11d_offloaded(psoc)) scm_11d_cc_db_deinit(psoc); return status;