From 502095b23633b37317043571ab90e540c0aa2eef Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Wed, 21 Nov 2018 14:34:49 +0530 Subject: [PATCH] qcacmn: Add support to enable/disable scan with reason code Adds support to enable/disable scan for psoc/vdev with reason, so that multiple clients can enable/disable the scan at same time. Scan will remain disabled till all clients enable it back. Change-Id: I8d840b24210095accb56ac9a2697ec26e8a5eb17 CRs-Fixed: 2362093 --- umac/scan/core/src/wlan_scan_main.h | 8 +- umac/scan/core/src/wlan_scan_manager.c | 60 +++++++--- umac/scan/core/src/wlan_scan_manager.h | 10 +- .../dispatcher/inc/wlan_scan_public_structs.h | 13 +++ umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h | 54 +++++---- umac/scan/dispatcher/src/wlan_scan_ucfg_api.c | 108 ++++++++++-------- 6 files changed, 161 insertions(+), 92 deletions(-) diff --git a/umac/scan/core/src/wlan_scan_main.h b/umac/scan/core/src/wlan_scan_main.h index 7b8b7cde7dc9..e0e4d281884b 100644 --- a/umac/scan/core/src/wlan_scan_main.h +++ b/umac/scan/core/src/wlan_scan_main.h @@ -238,12 +238,12 @@ struct pdev_scan_info { * struct scan_vdev_obj - scan vdev obj * @pno_match_evt_received: pno match received * @pno_in_progress: pno in progress - * @is_vdev_delete_in_progress: flag to indicate if vdev del is in progress + * @scan_disabled: if scan is disabled for this vdev */ struct scan_vdev_obj { bool pno_match_evt_received; bool pno_in_progress; - bool is_vdev_delete_in_progress; + uint32_t scan_disabled; }; /** @@ -461,7 +461,7 @@ struct scan_cb { /** * struct wlan_scan_obj - scan object definition - * @enable_scan: if scan is enabled + * @scan_disabled: if scan is disabled * @scan_db: scan cache data base * @cc_db: pointer of country code data base * @lock: spin lock @@ -482,7 +482,7 @@ struct scan_cb { * scan config to event handlers */ struct wlan_scan_obj { - bool enable_scan; + uint32_t scan_disabled; qdf_spinlock_t lock; qdf_atomic_t scan_ids; struct scan_dbs scan_db[WLAN_UMAC_MAX_PDEVS]; diff --git a/umac/scan/core/src/wlan_scan_manager.c b/umac/scan/core/src/wlan_scan_manager.c index 94913e44e692..aa92842b1a20 100644 --- a/umac/scan/core/src/wlan_scan_manager.c +++ b/umac/scan/core/src/wlan_scan_manager.c @@ -367,6 +367,44 @@ scm_scan_serialize_callback(struct wlan_serialization_command *cmd, return status; } +bool scm_is_scan_allowed(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_scan_obj *scan_psoc_obj; + struct scan_vdev_obj *scan_vdev_obj; + + if (!vdev) { + scm_err("vdev is NULL"); + return false; + } + + scan_psoc_obj = wlan_vdev_get_scan_obj(vdev); + if (!scan_psoc_obj) { + scm_err("Couldn't find scan psoc object"); + return false; + } + + if (scan_psoc_obj->scan_disabled) { + scm_err_rl("scan disabled %x, for psoc", + scan_psoc_obj->scan_disabled); + return false; + } + + scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); + if (!scan_vdev_obj) { + scm_err("Couldn't find scan vdev object"); + return false; + } + + if (scan_vdev_obj->scan_disabled) { + scm_err_rl("scan disabled %x on vdev_id:%d", + scan_vdev_obj->scan_disabled, + wlan_vdev_get_id(vdev)); + return false; + } + + return true; +} + QDF_STATUS scm_scan_start_req(struct scheduler_msg *msg) { @@ -374,7 +412,6 @@ scm_scan_start_req(struct scheduler_msg *msg) enum wlan_serialization_status ser_cmd_status; struct scan_start_request *req = NULL; struct wlan_scan_obj *scan_obj; - struct scan_vdev_obj *scan_vdev_priv_obj; QDF_STATUS status = QDF_STATUS_SUCCESS; if (!msg) { @@ -389,29 +426,16 @@ scm_scan_start_req(struct scheduler_msg *msg) } req = msg->bodyptr; - scan_obj = wlan_vdev_get_scan_obj(req->vdev); - if (!scan_obj) { - scm_debug("Couldn't find scan object"); - status = QDF_STATUS_E_NULL_VALUE; - goto err; - } - if (!scan_obj->enable_scan) { + if (!scm_is_scan_allowed(req->vdev)) { scm_err("scan disabled, rejecting the scan req"); status = QDF_STATUS_E_NULL_VALUE; goto err; } - scan_vdev_priv_obj = wlan_get_vdev_scan_obj(req->vdev); - if (!scan_vdev_priv_obj) { - scm_debug("Couldn't find scan priv object"); - status = QDF_STATUS_E_NULL_VALUE; - goto err; - } - - if (scan_vdev_priv_obj->is_vdev_delete_in_progress) { - scm_err("Can't allow scan on vdev_id:%d", - wlan_vdev_get_id(req->vdev)); + scan_obj = wlan_vdev_get_scan_obj(req->vdev); + if (!scan_obj) { + scm_debug("Couldn't find scan object"); status = QDF_STATUS_E_NULL_VALUE; goto err; } diff --git a/umac/scan/core/src/wlan_scan_manager.h b/umac/scan/core/src/wlan_scan_manager.h index e879c4d6e0ff..a7600d1b9be8 100644 --- a/umac/scan/core/src/wlan_scan_manager.h +++ b/umac/scan/core/src/wlan_scan_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-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 @@ -44,6 +44,14 @@ struct scan_event_listeners { struct cb_handler cb[MAX_SCAN_EVENT_LISTENERS]; }; +/** + * scm_is_scan_allowed() - check if scan is allowed + * @vdev: vdev for which scan allowed is check + * + * Return: true if scan is allowed else false + */ +bool scm_is_scan_allowed(struct wlan_objmgr_vdev *vdev); + /** * scm_scan_start_req() - scan start req core api * @msg: scheduler message object containing start scan req params diff --git a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h index 6e6312cd4fea..514d8bf801dc 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h +++ b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h @@ -577,6 +577,19 @@ struct scan_filter { struct qdf_mac_addr bssid_hint; }; +/** + * enum scan_disable_reason - scan enable/disable reason + * @REASON_SUSPEND: reason is suspend + * @REASON_SYSTEM_DOWN: reason is system going down + * @REASON_USER_SPACE: reason is user space initiated + * @REASON_VDEV_DOWN: reason is vdev going down + */ +enum scan_disable_reason { + REASON_SUSPEND = 0x1, + REASON_SYSTEM_DOWN = 0x2, + REASON_USER_SPACE = 0x4, + REASON_VDEV_DOWN = 0x8, +}; /** * enum scan_priority - scan priority definitions diff --git a/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h b/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h index f4fad6d83e06..af3282bc2781 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h +++ b/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h @@ -174,21 +174,46 @@ QDF_STATUS ucfg_scan_start(struct scan_start_request *req); /** - * ucfg_scan_set_enable() - Public API to disable/enable scans + * ucfg_scan_set_psoc_enable() - Public API to enable scans for psoc * @psoc: psoc on which scans need to be disabled - * @enable: enable scan if true disable is false + * @reason: reason for enable/disabled * * Return: QDF_STATUS. */ -QDF_STATUS ucfg_scan_set_enable(struct wlan_objmgr_psoc *psoc, bool enable); +QDF_STATUS ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc *psoc, + enum scan_disable_reason reason); /** - * ucfg_scan_get_enable() - Public API to get if scan is enabled or disabled - * @psoc: psoc on which scans status need to be checked + * ucfg_scan_psoc_set_disable() - Public API to disable scans for psoc + * @psoc: psoc on which scans need to be disabled + * @reason: reason for enable/disabled * - * Return: true if enabled else false. + * Return: QDF_STATUS. */ -bool ucfg_scan_get_enable(struct wlan_objmgr_psoc *psoc); +QDF_STATUS ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc *psoc, + enum scan_disable_reason reason); + +/** + * ucfg_scan_vdev_set_enable() - Public API to enable scans for vdev + * @psoc: psoc on which scans need to be disabled + * @reason: reason for enable/disabled + * + * Return: QDF_STATUS. + */ +QDF_STATUS ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev *vdev, + enum scan_disable_reason reason); + +/** + * ucfg_scan_vdev_set_disable() - Public API to disable scans for vdev + * @psoc: psoc on which scans need to be disabled + * @reason: reason for enable/disabled + * + * Return: QDF_STATUS. + */ +QDF_STATUS ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev *vdev, + enum scan_disable_reason reason); + + /** * ucfg_scan_set_miracast() - Public API to disable/enable miracast flag @@ -614,21 +639,6 @@ void ucfg_scan_set_bt_activity(struct wlan_objmgr_psoc *psoc, */ bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc); -/** - * ucfg_scan_set_vdev_del_in_progress() - API to mark vdev delete in progress - * @vdev: pointer to vdev object - * - * Return: none - */ -void ucfg_scan_set_vdev_del_in_progress(struct wlan_objmgr_vdev *vdev); -/** - * ucfg_scan_clear_vdev_del_in_progress() - API to reset vdev delete in progress - * @vdev: pointer to vdev object - * - * Return: none - */ -void ucfg_scan_clear_vdev_del_in_progress(struct wlan_objmgr_vdev *vdev); - /** * ucfg_scan_cfg_set_active_dwelltime() - API to set scan active dwelltime * @psoc: pointer to psoc object diff --git a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c index 6d6bd72b39cf..2ae43db80541 100644 --- a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c @@ -879,6 +879,12 @@ ucfg_scan_start(struct scan_start_request *req) return QDF_STATUS_E_NULL_VALUE; } + if (!scm_is_scan_allowed(req->vdev)) { + scm_err("scan disabled, rejecting the scan req"); + scm_scan_free_scan_request_mem(req); + return QDF_STATUS_E_AGAIN; + } + scan_obj = wlan_pdev_get_scan_obj(pdev); if (!scan_obj) { scm_err("Failed to get scan object"); @@ -886,12 +892,6 @@ ucfg_scan_start(struct scan_start_request *req) return QDF_STATUS_E_NULL_VALUE; } - if (!scan_obj->enable_scan) { - scm_err("scan disabled, rejecting the scan req"); - scm_scan_free_scan_request_mem(req); - return QDF_STATUS_E_AGAIN; - } - scm_debug("reqid: %d, scanid: %d, vdevid: %d", req->scan_req.scan_req_id, req->scan_req.scan_id, req->scan_req.vdev_id); @@ -932,7 +932,8 @@ ucfg_scan_start(struct scan_start_request *req) return status; } -QDF_STATUS ucfg_scan_set_enable(struct wlan_objmgr_psoc *psoc, bool enable) +QDF_STATUS ucfg_scan_psoc_set_enable(struct wlan_objmgr_psoc *psoc, + enum scan_disable_reason reason) { struct wlan_scan_obj *scan_obj; @@ -941,24 +942,69 @@ QDF_STATUS ucfg_scan_set_enable(struct wlan_objmgr_psoc *psoc, bool enable) scm_err("Failed to get scan object"); return QDF_STATUS_E_NULL_VALUE; } - scan_obj->enable_scan = enable; - scm_debug("set enable_scan to %d", scan_obj->enable_scan); + + scan_obj->scan_disabled &= ~reason; + scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled); return QDF_STATUS_SUCCESS; } -bool ucfg_scan_get_enable(struct wlan_objmgr_psoc *psoc) +QDF_STATUS ucfg_scan_psoc_set_disable(struct wlan_objmgr_psoc *psoc, + enum scan_disable_reason reason) { struct wlan_scan_obj *scan_obj; scan_obj = wlan_psoc_get_scan_obj(psoc); if (!scan_obj) { scm_err("Failed to get scan object"); - return false; + return QDF_STATUS_E_NULL_VALUE; } - return scan_obj->enable_scan; + + scan_obj->scan_disabled |= reason; + + scm_debug("Psoc scan_disabled %x", scan_obj->scan_disabled); + + return QDF_STATUS_SUCCESS; } + +QDF_STATUS ucfg_scan_vdev_set_enable(struct wlan_objmgr_vdev *vdev, + enum scan_disable_reason reason) +{ + struct scan_vdev_obj *scan_vdev_obj; + + scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); + if (!scan_vdev_obj) { + scm_err("null scan_vdev_obj"); + return QDF_STATUS_E_NULL_VALUE; + } + + scan_vdev_obj->scan_disabled &= ~reason; + + scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_scan_vdev_set_disable(struct wlan_objmgr_vdev *vdev, + enum scan_disable_reason reason) +{ + struct scan_vdev_obj *scan_vdev_obj; + + scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); + if (!scan_vdev_obj) { + scm_err("null scan_vdev_obj"); + return QDF_STATUS_E_NULL_VALUE; + } + + scan_vdev_obj->scan_disabled |= reason; + + scm_debug("Vdev scan_disabled %x", scan_vdev_obj->scan_disabled); + + return QDF_STATUS_SUCCESS; +} + + QDF_STATUS ucfg_scan_set_miracast( struct wlan_objmgr_psoc *psoc, bool enable) { @@ -1359,7 +1405,7 @@ static QDF_STATUS wlan_scan_global_init(struct wlan_objmgr_psoc *psoc, struct wlan_scan_obj *scan_obj) { - scan_obj->enable_scan = true; + scan_obj->scan_disabled = 0; scan_obj->drop_bcn_on_chan_mismatch = true; scan_obj->disable_timeout = false; scan_obj->scan_def.active_dwell = @@ -1980,7 +2026,7 @@ ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg) QDF_STATUS status = QDF_STATUS_SUCCESS; int i; - ucfg_scan_set_enable(psoc, false); + ucfg_scan_psoc_set_disable(psoc, REASON_SUSPEND); /* Check all pdev */ for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) { pdev = wlan_objmgr_get_pdev_by_id(psoc, i, WLAN_SCAN_ID); @@ -2002,7 +2048,7 @@ ucfg_scan_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg) static QDF_STATUS ucfg_scan_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg) { - ucfg_scan_set_enable(psoc, true); + ucfg_scan_psoc_set_enable(psoc, REASON_SUSPEND); return QDF_STATUS_SUCCESS; } @@ -2229,38 +2275,6 @@ bool ucfg_scan_get_bt_activity(struct wlan_objmgr_psoc *psoc) return scan_obj->bt_a2dp_enabled; } -void ucfg_scan_set_vdev_del_in_progress(struct wlan_objmgr_vdev *vdev) -{ - struct scan_vdev_obj *scan_vdev_obj; - - if (!vdev) { - scm_err("invalid vdev"); - return; - } - scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); - if (!scan_vdev_obj) { - scm_err("null scan_vdev_obj"); - return; - } - scan_vdev_obj->is_vdev_delete_in_progress = true; -} - -void ucfg_scan_clear_vdev_del_in_progress(struct wlan_objmgr_vdev *vdev) -{ - struct scan_vdev_obj *scan_vdev_obj; - - if (!vdev) { - scm_err("invalid vdev"); - return; - } - scan_vdev_obj = wlan_get_vdev_scan_obj(vdev); - if (!scan_vdev_obj) { - scm_err("null scan_vdev_obj"); - return; - } - scan_vdev_obj->is_vdev_delete_in_progress = false; -} - QDF_STATUS ucfg_scan_set_global_config(struct wlan_objmgr_psoc *psoc, enum scan_config config, uint32_t val)