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
This commit is contained in:
Liangwei Dong 2018-08-01 05:01:14 -04:00 • committed by nshrivas
commit 36462d50b8
8 changed files with 310 additions and 30 deletions

View file

@ -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 <wlan_scan_public_structs.h>
#include <wlan_scan_ucfg_api.h>
#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;
}

View file

@ -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

View file

@ -27,6 +27,9 @@
#include "reg_db.h"
#include "reg_services.h"
#ifdef HOST_11D_SCAN
#include <qdf_mc_timer.h>
#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;

View file

@ -24,6 +24,7 @@
#include "reg_services.h"
#include "reg_priv.h"
#include "reg_db_parser.h"
#include "reg_host_11d.h"
#include <scheduler_api.h>
#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)
{

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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;