qcacmn: Add wait for cancel scan on pdev and vdev

Add cancel scan sync api which will wait for scan to be aborted on
pdev or vdev.

Change-Id: Ie02eb981154856cda38ef70f42fdfcf82bb88961
CRs-Fixed: 2038092
This commit is contained in:
Abhishek Singh 2017-04-25 12:12:01 +05:30 • committed by snandini
commit f95b9e4248
5 changed files with 100 additions and 7 deletions

View file

@ -216,6 +216,7 @@ int wlan_cfg80211_abort_scan(struct wlan_objmgr_pdev *pdev);
* @pdev_id: pdev id
* @vdev_id: vdev id
* @scan_id: scan id
* @sync: if wait for scan complete is required
*
* Generic API to abort scans
*
@ -224,7 +225,8 @@ int wlan_cfg80211_abort_scan(struct wlan_objmgr_pdev *pdev);
QDF_STATUS wlan_abort_scan(struct wlan_objmgr_pdev *pdev,
uint32_t pdev_id,
uint32_t vdev_id,
wlan_scan_id scan_id);
wlan_scan_id scan_id,
bool sync);
/**
* wlan_cfg80211_cleanup_scan_queue() - remove entries in scan queue

View file

@ -216,7 +216,7 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_pdev *pdev,
SCAN_NOT_IN_PROGRESS) {
status = wlan_abort_scan(pdev,
wlan_objmgr_pdev_get_pdev_id(pdev),
INVAL_VDEV_ID, INVAL_SCAN_ID);
INVAL_VDEV_ID, INVAL_SCAN_ID, true);
if (QDF_IS_STATUS_ERROR(status)) {
cfg80211_err("aborting the existing scan is unsuccessful");
wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
@ -1118,7 +1118,7 @@ static int wlan_get_scanid(struct wlan_objmgr_pdev *pdev,
QDF_STATUS wlan_abort_scan(struct wlan_objmgr_pdev *pdev,
uint32_t pdev_id, uint32_t vdev_id,
wlan_scan_id scan_id)
wlan_scan_id scan_id, bool sync)
{
struct scan_cancel_request *req;
struct pdev_osif_priv *osif_ctx;
@ -1163,7 +1163,11 @@ QDF_STATUS wlan_abort_scan(struct wlan_objmgr_pdev *pdev,
req->cancel_req.req_type = WLAN_SCAN_CANCEL_PDEV_ALL;
else
req->cancel_req.req_type = WLAN_SCAN_CANCEL_VDEV_ALL;
status = ucfg_scan_cancel(req);
if (sync)
status = ucfg_scan_cancel_sync(req);
else
status = ucfg_scan_cancel(req);
if (QDF_IS_STATUS_ERROR(status))
cfg80211_err("Cancel scan request failed");
@ -1181,7 +1185,7 @@ int wlan_cfg80211_abort_scan(struct wlan_objmgr_pdev *pdev)
if (ucfg_scan_get_pdev_status(pdev) !=
SCAN_NOT_IN_PROGRESS)
wlan_abort_scan(pdev, pdev_id,
INVAL_VDEV_ID, INVAL_SCAN_ID);
INVAL_VDEV_ID, INVAL_SCAN_ID, true);
return 0;
}
@ -1211,7 +1215,7 @@ int wlan_vendor_abort_scan(struct wlan_objmgr_pdev *pdev,
if (ucfg_scan_get_pdev_status(pdev) !=
SCAN_NOT_IN_PROGRESS)
wlan_abort_scan(pdev, pdev_id,
INVAL_VDEV_ID, scan_id);
INVAL_VDEV_ID, scan_id, true);
}
return 0;
}

View file

@ -46,6 +46,9 @@ typedef uint32_t wlan_scan_id;
#define SCM_BSS_CAP_VALUE_UAPSD 1
#define SCM_BSS_CAP_VALUE_5GHZ 2
#define SCM_CANCEL_SCAN_WAIT_TIME 50
#define SCM_CANCEL_SCAN_WAIT_ITERATION 100
#define BURST_SCAN_MAX_NUM_OFFCHANNELS 3
#define P2P_SCAN_MAX_BURST_DURATION 180
/* Increase dwell time for P2P search in ms */

View file

@ -183,6 +183,19 @@ ucfg_scan_start(struct scan_start_request *req);
QDF_STATUS
ucfg_scan_cancel(struct scan_cancel_request *req);
/**
* ucfg_scan_cancel_sync() - Public API to stop a scan and wait
* till all scan are completed
* @req: stop scan request params
*
* The Public API to stop a scan and wait
* till all scan are completed
*
* Return: 0 for success or error code.
*/
QDF_STATUS
ucfg_scan_cancel_sync(struct scan_cancel_request *req);
/**
* ucfg_scan_get_result() - The Public API to get scan results
* @pdev: pdev info

View file

@ -401,6 +401,77 @@ ucfg_scan_cancel(struct scan_cancel_request *req)
return status;
}
QDF_STATUS
ucfg_scan_cancel_sync(struct scan_cancel_request *req)
{
QDF_STATUS status;
bool cancel_vdev = false, cancel_pdev = false;
struct wlan_objmgr_vdev *vdev;
struct wlan_objmgr_pdev *pdev;
uint32_t max_wait_iterations = SCM_CANCEL_SCAN_WAIT_ITERATION;
qdf_event_t cancel_scan_event;
if (!req || !req->vdev) {
scm_err("vdev: %p, req: %p", req->vdev, req);
if (req)
qdf_mem_free(req);
return QDF_STATUS_E_NULL_VALUE;
}
if (req->cancel_req.req_type ==
WLAN_SCAN_CANCEL_PDEV_ALL)
cancel_pdev = true;
else if (req->cancel_req.req_type ==
WLAN_SCAN_CANCEL_VDEV_ALL)
cancel_vdev = true;
vdev = req->vdev;
status = ucfg_scan_cancel(req);
if (QDF_IS_STATUS_ERROR(status)) {
scm_err("failed to post to QDF_MODULE_ID_OS_IF");
return status;
}
/*
* If cancel req is to cancel all scan of pdev or vdev
* wait untill all scan of pdev or vdev get cancelled
*/
qdf_event_create(&cancel_scan_event);
qdf_event_reset(&cancel_scan_event);
if (cancel_pdev) {
wlan_vdev_obj_lock(vdev);
pdev = wlan_vdev_get_pdev(vdev);
wlan_vdev_obj_unlock(vdev);
while ((ucfg_scan_get_pdev_status(pdev) !=
SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
scm_debug("wait for all pdev scan to get complete");
qdf_wait_single_event(&cancel_scan_event,
qdf_system_msecs_to_ticks(
SCM_CANCEL_SCAN_WAIT_TIME));
max_wait_iterations--;
}
} else if (cancel_vdev) {
while ((ucfg_scan_get_vdev_status(vdev) !=
SCAN_NOT_IN_PROGRESS) && max_wait_iterations) {
scm_debug("wait for all vdev scan to get complete");
qdf_wait_single_event(&cancel_scan_event,
qdf_system_msecs_to_ticks(
SCM_CANCEL_SCAN_WAIT_TIME));
max_wait_iterations--;
}
}
qdf_event_destroy(&cancel_scan_event);
if (!max_wait_iterations) {
scm_err("Failed to wait for scans to get complete");
return QDF_STATUS_E_TIMEOUT;
}
return status;
}
wlan_scan_requester
ucfg_scan_register_requester(struct wlan_objmgr_psoc *psoc,
uint8_t *name, scan_event_handler event_cb, void *arg)
@ -896,7 +967,7 @@ ucfg_scan_get_pdev_status(struct wlan_objmgr_pdev *pdev)
if (!pdev) {
scm_err("null pdev");
return QDF_STATUS_E_NULL_VALUE;
return SCAN_NOT_IN_PROGRESS;
}
status = wlan_serialization_pdev_scan_status(pdev);