diff options
| author | yeshwanth sriram guntuka <ysriramg@codeaurora.org> | 2016-11-15 23:25:26 +0530 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2017-01-13 05:15:15 -0800 |
| commit | c51c5c9cde91efec5615cb48e8eabcd909787909 (patch) | |
| tree | 3a2e32d67501564a9c8b452573a800edb063a449 | |
| parent | f7184c54a439428b8b55385c719f83e94c49eb57 (diff) | |
qcacld-3.0: Add support for vendor abort scan
Add vendor abort scan which takes adapter and scan
id as input. Supplicant may abort a scan if a
preferred AP or P2P peer device is found.
Change-Id: Ia9cbf4bb38d2111b1fcf42a1e1f51d1049f5a9ab
CRs-Fixed: 1090800
| -rw-r--r-- | core/cds/inc/cds_utils.h | 4 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 2 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_cfg80211.c | 11 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_cfg80211.h | 4 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_hostapd.c | 2 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_main.c | 4 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_p2p.c | 4 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_power.c | 2 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_scan.c | 141 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_scan.h | 18 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_wext.c | 2 | ||||
| -rw-r--r-- | core/sme/inc/sme_api.h | 14 | ||||
| -rw-r--r-- | core/sme/src/common/sme_api.c | 15 | ||||
| -rw-r--r-- | core/sme/src/csr/csr_api_roam.c | 8 | ||||
| -rw-r--r-- | core/sme/src/csr/csr_api_scan.c | 148 | ||||
| -rw-r--r-- | core/sme/src/csr/csr_inside_api.h | 26 |
16 files changed, 293 insertions, 112 deletions
diff --git a/core/cds/inc/cds_utils.h b/core/cds/inc/cds_utils.h index 839ef3dcc6af..63699f0dddcc 100644 --- a/core/cds/inc/cds_utils.h +++ b/core/cds/inc/cds_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -66,6 +66,8 @@ #define CDS_CHAN_15_FREQ (2512) #define CDS_CHAN_170_FREQ (5852) +#define INVALID_SCAN_ID 0xFFFFFFFF + #define cds_log(level, args...) QDF_TRACE(QDF_MODULE_ID_QDF, level, ## args) #define cds_logfl(level, format, args...) cds_log(level, FL(format), ## args) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 3a2756da823d..371cf5155b64 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1665,7 +1665,7 @@ void hdd_set_conparam(uint32_t con_param); enum tQDF_GLOBAL_CON_MODE hdd_get_conparam(void); void hdd_abort_mac_scan(hdd_context_t *pHddCtx, uint8_t sessionId, - eCsrAbortReason reason); + uint32_t scan_id, eCsrAbortReason reason); void hdd_cleanup_actionframe(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter); void crda_regulatory_entry_default(uint8_t *countryCode, int domain_id); diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 1ffff42cbd29..07f8caf76476 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -8768,6 +8768,16 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { .doit = wlan_hdd_cfg80211_vendor_scan }, + /* Vendor abort scan */ + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ABORT_SCAN, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_vendor_abort_scan + }, + /* OCB commands */ { .info.vendor_id = QCA_NL80211_VENDOR_ID, @@ -13243,6 +13253,7 @@ static int __wlan_hdd_cfg80211_disconnect(struct wiphy *wiphy, if (pScanInfo->mScanPending) { hdd_notice("Disconnect is in progress, Aborting Scan"); hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, + INVALID_SCAN_ID, eCSR_SCAN_ABORT_DEFAULT); } wlan_hdd_cleanup_remain_on_channel_ctx(pAdapter); diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index 8d936c8a1ef5..72487bad5045 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -268,6 +268,7 @@ typedef enum { * @QCA_NL80211_VENDOR_SUBCMD_SETBAND: vendor setband command * @QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN: venodr scan command * @QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE: vendor scan complete + * @QCA_NL80211_VENDOR_SUBCMD_ABORT_SCAN: vendor abort scan * @QCA_NL80211_VENDOR_SUBCMD_OTA_TEST: enable OTA test * @QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE: set tx power by percentage * @QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE_DECR_DB: reduce tx power by DB @@ -449,6 +450,9 @@ enum qca_nl80211_vendor_subcmds { /* Configure the TDLS mode from user space */ QCA_NL80211_VENDOR_SUBCMD_CONFIGURE_TDLS = 143, + /* Vendor abort scan command */ + QCA_NL80211_VENDOR_SUBCMD_ABORT_SCAN = 145, + /* Set Specific Absorption Rate(SAR) Power Limits */ QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS = 146, }; diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 2506b778dbdb..52b7d35035e7 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -1661,6 +1661,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, /* Lets do abort scan to ensure smooth authentication for client */ if ((pScanInfo != NULL) && pScanInfo->mScanPending) { hdd_abort_mac_scan(pHddCtx, pHostapdAdapter->sessionId, + INVALID_SCAN_ID, eCSR_SCAN_ABORT_DEFAULT); } if (pHostapdAdapter->device_mode == QDF_P2P_GO_MODE) { @@ -7840,6 +7841,7 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, INIT_COMPLETION(pScanInfo->abortscan_event_var); hdd_abort_mac_scan(staAdapter->pHddCtx, staAdapter->sessionId, + INVALID_SCAN_ID, eCSR_SCAN_ABORT_DEFAULT); rc = wait_for_completion_timeout( &pScanInfo->abortscan_event_var, diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 8febd2bfc3ed..c1fcd9482add 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -106,6 +106,8 @@ #include <wlan_hdd_napi.h> #include "wlan_hdd_disa.h" #include "ol_txrx.h" +#include "cds_utils.h" + #ifdef MODULE #define WLAN_MODULE_NAME module_name(THIS_MODULE) #else @@ -413,6 +415,7 @@ static int __hdd_netdev_notifier_call(struct notifier_block *nb, abortscan_event_var); hdd_abort_mac_scan(adapter->pHddCtx, adapter->sessionId, + INVALID_SCAN_ID, eCSR_SCAN_ABORT_DEFAULT); rc = wait_for_completion_timeout( &adapter->scan_info.abortscan_event_var, @@ -4380,6 +4383,7 @@ QDF_STATUS hdd_abort_mac_scan_all_adapters(hdd_context_t *hdd_ctx) (adapter->device_mode == QDF_SAP_MODE) || (adapter->device_mode == QDF_P2P_GO_MODE)) { hdd_abort_mac_scan(hdd_ctx, adapter->sessionId, + INVALID_SCAN_ID, eCSR_SCAN_ABORT_DEFAULT); } status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext); diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c index ec210d725b12..8d63b3cc49e9 100644 --- a/core/hdd/src/wlan_hdd_p2p.c +++ b/core/hdd/src/wlan_hdd_p2p.c @@ -52,6 +52,7 @@ #include "qdf_trace.h" #include "cds_sched.h" #include "cds_concurrency.h" +#include "cds_utils.h" /* Ms to Time Unit Micro Sec */ #define MS_TO_TU_MUS(x) ((x) * 1024) @@ -2058,7 +2059,8 @@ struct wireless_dev *__wlan_hdd_add_virtual_intf(struct wiphy *wiphy, scan_info = &pAdapter->scan_info; if (scan_info->mScanPending) { hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, - eCSR_SCAN_ABORT_DEFAULT); + INVALID_SCAN_ID, + eCSR_SCAN_ABORT_DEFAULT); hdd_notice("Abort Scan while adding virtual interface"); } } diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 764ff163efeb..353bc56ceac1 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -77,6 +77,7 @@ #include "pld_common.h" #include "wlan_hdd_driver_ops.h" #include <wlan_logging_sock_svc.h> +#include "cds_utils.h" /* Preprocessor definitions and constants */ #define HDD_SSR_BRING_UP_TIME 30000 @@ -1969,6 +1970,7 @@ next_adapter: if (pScanInfo->mScanPending) { INIT_COMPLETION(pScanInfo->abortscan_event_var); hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, + INVALID_SCAN_ID, eCSR_SCAN_ABORT_DEFAULT); status = diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index 63b0e0d57fe4..358c4bdd7877 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/core/hdd/src/wlan_hdd_scan.c @@ -1003,6 +1003,7 @@ int iw_get_scan(struct net_device *dev, * hdd_abort_mac_scan() - aborts ongoing mac scan * @pHddCtx: Pointer to hdd context * @sessionId: session id + * @scan_id: scan id * @reason: abort reason * * Abort any MAC scan if in progress @@ -1010,9 +1011,9 @@ int iw_get_scan(struct net_device *dev, * Return: none */ void hdd_abort_mac_scan(hdd_context_t *pHddCtx, uint8_t sessionId, - eCsrAbortReason reason) + uint32_t scan_id, eCsrAbortReason reason) { - sme_abort_mac_scan(pHddCtx->hHal, sessionId, reason); + sme_abort_mac_scan(pHddCtx->hHal, sessionId, scan_id, reason); } /** @@ -2274,6 +2275,140 @@ int wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy, return ret; } +/** + * wlan_hdd_get_scanid() - API to get the scan id + * from the scan cookie attribute. + * @hdd_ctx: Pointer to HDD context + * @scan_id: Pointer to scan id + * @cookie : Scan cookie attribute + * + * API to get the scan id from the scan cookie attribute + * sent from supplicant by matching scan request. + * + * Return: 0 for success, non zero for failure + */ +static int wlan_hdd_get_scanid(hdd_context_t *hdd_ctx, + uint32_t *scan_id, uint64_t cookie) +{ + struct hdd_scan_req *scan_req; + qdf_list_node_t *node = NULL; + qdf_list_node_t *ptr_node = NULL; + int ret = -EINVAL; + + qdf_spin_lock(&hdd_ctx->hdd_scan_req_q_lock); + if (qdf_list_empty(&hdd_ctx->hdd_scan_req_q)) { + qdf_spin_unlock(&hdd_ctx->hdd_scan_req_q_lock); + return ret; + } + + if (QDF_STATUS_SUCCESS != + qdf_list_peek_front(&hdd_ctx->hdd_scan_req_q, + &ptr_node)) { + qdf_spin_unlock(&hdd_ctx->hdd_scan_req_q_lock); + return ret; + } + + do { + node = ptr_node; + scan_req = container_of(node, struct hdd_scan_req, node); + + if (cookie == + (uintptr_t)(scan_req->scan_request)) { + *scan_id = scan_req->scan_id; + ret = 0; + break; + } + } while (QDF_STATUS_SUCCESS == + qdf_list_peek_next(&hdd_ctx->hdd_scan_req_q, + node, &ptr_node)); + + qdf_spin_unlock(&hdd_ctx->hdd_scan_req_q_lock); + + return ret; + +} +/** + * __wlan_hdd_vendor_abort_scan() - API to process vendor command for + * abort scan + * @wiphy: Pointer to wiphy + * @wdev: Pointer to net device + * @data : Pointer to the data + * @data_len : length of the data + * + * API to process vendor abort scan + * + * Return: zero for success and non zero for failure + */ +static int __wlan_hdd_vendor_abort_scan( + struct wiphy *wiphy, const void *data, + int data_len) +{ + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1]; + uint32_t scan_id; + uint64_t cookie; + int ret; + + if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { + hdd_err("Command not allowed in FTM mode"); + return -EINVAL; + } + + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) + return ret; + + ret = -EINVAL; + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX, data, + data_len, NULL)) { + hdd_err("Invalid ATTR"); + return ret; + } + + if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]) { + cookie = nla_get_u64( + tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]); + ret = wlan_hdd_get_scanid(hdd_ctx, + &scan_id, + cookie); + if (ret != 0) + return ret; + hdd_abort_mac_scan(hdd_ctx, + HDD_SESSION_ID_INVALID, + scan_id, + eCSR_SCAN_ABORT_DEFAULT); + } + + return ret; +} + + +/** + * wlan_hdd_vendor_abort_scan() - API to process vendor command for + * abort scan + * @wiphy: Pointer to wiphy + * @wdev: Pointer to net device + * @data : Pointer to the data + * @data_len : length of the data + * + * This is called from supplicant to abort scan + * + * Return: zero for success and non zero for failure + */ +int wlan_hdd_vendor_abort_scan( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret; + + cds_ssr_protect(__func__); + ret = __wlan_hdd_vendor_abort_scan(wiphy, + data, + data_len); + cds_ssr_unprotect(__func__); + + return ret; +} /** * wlan_hdd_scan_abort() - abort ongoing scan @@ -2292,7 +2427,7 @@ int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter) if (pScanInfo->mScanPending) { INIT_COMPLETION(pScanInfo->abortscan_event_var); hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, - eCSR_SCAN_ABORT_DEFAULT); + INVALID_SCAN_ID, eCSR_SCAN_ABORT_DEFAULT); rc = wait_for_completion_timeout( &pScanInfo->abortscan_event_var, diff --git a/core/hdd/src/wlan_hdd_scan.h b/core/hdd/src/wlan_hdd_scan.h index 249449594272..2094ffd9e0c6 100644 --- a/core/hdd/src/wlan_hdd_scan.h +++ b/core/hdd/src/wlan_hdd_scan.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -93,6 +93,22 @@ int wlan_hdd_cfg80211_vendor_scan(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); +/** + * wlan_hdd_vendor_abort_scan() - API to process vendor command for + * abort scan + * @wiphy: Pointer to wiphy + * @wdev: Pointer to net device + * @data : Pointer to the data + * @data_len : length of the data + * + * This is called from supplicant to abort scan + * + * Return: zero for success and non zero for failure. + */ +int wlan_hdd_vendor_abort_scan( + struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len); + void hdd_cleanup_scan_queue(hdd_context_t *hdd_ctx); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) || \ diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index 1ea6f510e4af..4b2e144c8518 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -92,6 +92,7 @@ #include "pld_common.h" #endif #include "wlan_hdd_lro.h" +#include "cds_utils.h" #define HDD_FINISH_ULA_TIME_OUT 800 #define HDD_SET_MCBC_FILTERS_TO_FW 1 @@ -10572,6 +10573,7 @@ int hdd_set_band(struct net_device *dev, u8 ui_band) pAdapter = pAdapterNode->pAdapter; hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, + INVALID_SCAN_ID, eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE); connectedBand = hdd_conn_get_connected_band diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 48b0653e06d6..6d0869eaef06 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -508,8 +508,20 @@ uint16_t sme_check_concurrent_channel_overlap(tHalHandle hHal, uint16_t sap_ch, eCsrPhyMode sapPhyMode, uint8_t cc_switch_mode); #endif +/** + * sme_abort_mac_scan() - API to cancel MAC scan + * @hHal: The handle returned by mac_open + * @sessionId: sessionId on which we need to abort scan + * @scan_id: scan id on which we need to abort scan + * @reason: Reason to abort the scan + * + * This function aborts MAC scan. + * + * Return: QDF_STATUS_E_FAILURE for failure, QDF_STATUS_SUCCESS for + * success + */ QDF_STATUS sme_abort_mac_scan(tHalHandle hHal, uint8_t sessionId, - eCsrAbortReason reason); + uint32_t scan_id, eCsrAbortReason reason); QDF_STATUS sme_get_cfg_valid_channels(tHalHandle hHal, uint8_t *aValidChannels, uint32_t *len); #ifdef FEATURE_WLAN_SCAN_PNO diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 2efcdc3af0d4..27c06338ad05 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -6560,18 +6560,8 @@ QDF_STATUS sme_set_preferred_network_list(tHalHandle hHal, #endif /* FEATURE_WLAN_SCAN_PNO */ -/* --------------------------------------------------------------------------- - \fn sme_abort_mac_scan - \brief API to cancel MAC scan. - \param hHal - The handle returned by mac_open. - \param sessionId - sessionId on which we need to abort scan. - \param reason - Reason to abort the scan. - \return QDF_STATUS - QDF_STATUS_E_FAILURE - failure - QDF_STATUS_SUCCESS success - ---------------------------------------------------------------------------*/ QDF_STATUS sme_abort_mac_scan(tHalHandle hHal, uint8_t sessionId, - eCsrAbortReason reason) + uint32_t scan_id, eCsrAbortReason reason) { QDF_STATUS status; tpAniSirGlobal pMac = PMAC_STRUCT(hHal); @@ -6580,7 +6570,8 @@ QDF_STATUS sme_abort_mac_scan(tHalHandle hHal, uint8_t sessionId, TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN, NO_SESSION, 0)); status = sme_acquire_global_lock(&pMac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { - status = csr_scan_abort_mac_scan(pMac, sessionId, reason); + status = csr_scan_abort_mac_scan(pMac, sessionId, + scan_id, reason); sme_release_global_lock(&pMac->sme); } diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index f65cf158ec20..1cbafe40ddaf 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -9514,12 +9514,14 @@ void csr_roaming_state_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf) case eWNI_SME_DEAUTH_RSP: /* or the Deauthentication response message... */ if (CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(pMac, pSmeRsp->sessionId)) { - csr_remove_cmd_with_session_id_from_pending_list(pMac, + csr_remove_cmd_from_pending_list(pMac, pSmeRsp->sessionId, + INVALID_SCAN_ID, &pMac->sme.smeCmdPendingList, eSmeCommandWmStatusChange); - csr_remove_cmd_with_session_id_from_pending_list(pMac, + csr_remove_cmd_from_pending_list(pMac, pSmeRsp->sessionId, + INVALID_SCAN_ID, &pMac->roam.roamCmdPendingList, eSmeCommandWmStatusChange); csr_roam_roaming_state_deauth_rsp_processor(pMac, @@ -11564,7 +11566,7 @@ void csr_roam_cancel_roaming(tpAniSirGlobal pMac, uint32_t sessionId) roamResult); /* Since CSR may be in lostlink roaming situation, abort all roaming related activities */ csr_scan_abort_mac_scan(pMac, sessionId, - eCSR_SCAN_ABORT_DEFAULT); + INVALID_SCAN_ID, eCSR_SCAN_ABORT_DEFAULT); csr_roam_stop_roaming_timer(pMac, sessionId); } } diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index 0c20ebe27b4d..b9e2c52d5ba8 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -6730,13 +6730,15 @@ QDF_STATUS csr_scan_abort_all_scans(tpAniSirGlobal mac_ctx, mac_ctx->scan.fDropScanCmd = true; for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) { if (CSR_IS_SESSION_VALID(mac_ctx, session_id)) { - csr_remove_cmd_with_session_id_from_pending_list( + csr_remove_cmd_from_pending_list( mac_ctx, - session_id, &mac_ctx->sme.smeScanCmdPendingList, + session_id, INVALID_SCAN_ID, + &mac_ctx->sme.smeScanCmdPendingList, eSmeCommandScan); csr_abort_scan_from_active_list(mac_ctx, &mac_ctx->sme.smeScanCmdActiveList, - session_id, eSmeCommandScan, reason); + session_id, INVALID_SCAN_ID, eSmeCommandScan, + reason); } } mac_ctx->scan.fDropScanCmd = false; @@ -6745,24 +6747,34 @@ QDF_STATUS csr_scan_abort_all_scans(tpAniSirGlobal mac_ctx, } QDF_STATUS csr_scan_abort_mac_scan(tpAniSirGlobal pMac, uint8_t sessionId, - eCsrAbortReason reason) + uint32_t scan_id, eCsrAbortReason reason) { QDF_STATUS status = QDF_STATUS_SUCCESS; + QDF_STATUS ret; pMac->scan.fDropScanCmd = true; - csr_remove_cmd_with_session_id_from_pending_list(pMac, - sessionId, &pMac->sme.smeScanCmdPendingList, + ret = csr_remove_cmd_from_pending_list(pMac, + sessionId, scan_id, &pMac->sme.smeScanCmdPendingList, eSmeCommandScan); pMac->scan.fDropScanCmd = false; - csr_abort_scan_from_active_list(pMac, - &pMac->sme.smeScanCmdActiveList, sessionId, - eSmeCommandScan, reason); + /* + * If we are not able to find command for scan id in + * pending list, check active list. Also if the session + * id is valid then we have to check below active list. + */ + if (ret != QDF_STATUS_SUCCESS || + sessionId != CSR_SESSION_ID_INVALID) { + status = csr_abort_scan_from_active_list(pMac, + &pMac->sme.smeScanCmdActiveList, sessionId, scan_id, + eSmeCommandScan, reason); + } return status; } -void csr_remove_cmd_with_session_id_from_pending_list(tpAniSirGlobal pMac, +QDF_STATUS csr_remove_cmd_from_pending_list(tpAniSirGlobal pMac, uint8_t sessionId, + uint32_t scan_id, tDblLinkList *pList, eSmeCommandType commandType) { @@ -6770,33 +6782,36 @@ void csr_remove_cmd_with_session_id_from_pending_list(tpAniSirGlobal pMac, tListElem *pEntry; tSmeCmd *pCommand; tListElem *pEntryToRemove; + QDF_STATUS status = QDF_STATUS_E_FAILURE; qdf_mem_zero(&localList, sizeof(tDblLinkList)); if (!QDF_IS_STATUS_SUCCESS(csr_ll_open(pMac->hHdd, &localList))) { sms_log(pMac, LOGE, FL("failed to open list")); - return; + return status; } csr_ll_lock(pList); pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK); - if (pEntry) { - /* - * Have to make sure we don't loop back to the head of the list, - * which will happen if the entry is NOT on the list - */ - while (pEntry) { - pEntryToRemove = pEntry; - pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK); - pCommand = GET_BASE_ADDR(pEntryToRemove, tSmeCmd, Link); - if (!((pCommand->command == commandType) && - (pCommand->sessionId == sessionId))) - continue; + /* + * Have to make sure we don't loop back to the head of the list, + * which will happen if the entry is NOT on the list + */ + while (pEntry) { + pEntryToRemove = pEntry; + pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR(pEntryToRemove, tSmeCmd, Link); + + if ((pCommand->command == commandType) && + (((commandType == eSmeCommandScan) && + (pCommand->u.scanCmd.scanID == scan_id)) || + (pCommand->sessionId == sessionId))) { /* Remove that entry only */ if (csr_ll_remove_entry(pList, pEntryToRemove, - LL_ACCESS_NOLOCK)) { + LL_ACCESS_NOLOCK)) { csr_ll_insert_tail(&localList, pEntryToRemove, LL_ACCESS_NOLOCK); + status = QDF_STATUS_SUCCESS; } } } @@ -6804,57 +6819,14 @@ void csr_remove_cmd_with_session_id_from_pending_list(tpAniSirGlobal pMac, while ((pEntry = csr_ll_remove_head(&localList, LL_ACCESS_NOLOCK))) { pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); - sms_log(pMac, LOG1, FL("Sending abort for scan command ID %d"), - pCommand->u.scanCmd.scanID); + sms_log(pMac, LOG1, FL("Sending abort for command ID %d"), + (commandType == eSmeCommandScan) ? pCommand->u. + scanCmd.scanID : sessionId); csr_abort_command(pMac, pCommand, false); } csr_ll_close(&localList); -} - -void csr_remove_cmd_from_pending_list(tpAniSirGlobal pMac, - tDblLinkList *pList, - eSmeCommandType commandType) -{ - tDblLinkList localList; - tListElem *pEntry; - tSmeCmd *pCommand; - tListElem *pEntryToRemove; - - qdf_mem_zero(&localList, sizeof(tDblLinkList)); - if (!QDF_IS_STATUS_SUCCESS(csr_ll_open(pMac->hHdd, &localList))) { - sms_log(pMac, LOGE, FL(" failed to open list")); - return; - } - - csr_ll_lock(pList); - if (!csr_ll_is_list_empty(pList, LL_ACCESS_NOLOCK)) { - pEntry = csr_ll_peek_head(pList, LL_ACCESS_NOLOCK); - /* - * Have to make sure we don't loop back to the head of the list, - * which will happen if the entry is NOT on the list... - */ - while (pEntry) { - pEntryToRemove = pEntry; - pEntry = csr_ll_next(pList, pEntry, LL_ACCESS_NOLOCK); - pCommand = GET_BASE_ADDR(pEntryToRemove, tSmeCmd, Link); - /* Remove that entry only that matches cmd type */ - if (pCommand->command == commandType && - csr_ll_remove_entry(pList, pEntryToRemove, - LL_ACCESS_NOLOCK)) { - csr_ll_insert_tail(&localList, pEntryToRemove, - LL_ACCESS_NOLOCK); - } - } - } - csr_ll_unlock(pList); - - while ((pEntry = csr_ll_remove_head(&localList, LL_ACCESS_NOLOCK))) { - pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); - csr_abort_command(pMac, pCommand, false); - } - csr_ll_close(&localList); - + return status; } QDF_STATUS csr_scan_abort_scan_for_ssid(tpAniSirGlobal pMac, uint32_t sessionId) @@ -6866,7 +6838,8 @@ QDF_STATUS csr_scan_abort_scan_for_ssid(tpAniSirGlobal pMac, uint32_t sessionId) &pMac->sme.smeScanCmdPendingList, sessionId); pMac->scan.fDropScanCmd = false; csr_abort_scan_from_active_list(pMac, &pMac->sme.smeScanCmdActiveList, - sessionId, eSmeCommandScan, eCSR_SCAN_ABORT_SSID_ONLY); + sessionId, INVALID_SCAN_ID, eSmeCommandScan, + eCSR_SCAN_ABORT_SSID_ONLY); return status; } @@ -6963,15 +6936,17 @@ static void csr_send_scan_abort(tpAniSirGlobal mac_ctx, * @mac_ctx: Pointer to Global Mac structure * @list: pointer to scan active list * @session_id: CSR session identification + * @scan_id: scan id * @scan_cmd_type: scan command type * @abort_reason: abort reason * - * .Remove Scan command from active scan list + * Remove Scan command from active scan list by matching either the scan id + * or session id. * * Return: Success - QDF_STATUS_SUCCESS, Failure - error number */ QDF_STATUS csr_abort_scan_from_active_list(tpAniSirGlobal mac_ctx, - tDblLinkList *list, uint32_t session_id, + tDblLinkList *list, uint32_t session_id, uint32_t scan_id, eSmeCommandType scan_cmd_type, eCsrAbortReason abort_reason) { tListElem *entry; @@ -6987,19 +6962,26 @@ QDF_STATUS csr_abort_scan_from_active_list(tpAniSirGlobal mac_ctx, entry = csr_ll_next(list, entry, LL_ACCESS_NOLOCK); cmd = GET_BASE_ADDR(entry_remove, tSmeCmd, Link); - /* Skip if command and session id not matched */ - if (!((scan_cmd_type == cmd->command) && - (session_id == cmd->sessionId))) - continue; /*skip if abort reason is for SSID*/ if ((abort_reason == eCSR_SCAN_ABORT_SSID_ONLY) && (eCsrScanForSsid != cmd->u.scanCmd.reason)) continue; - if (abort_reason == eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE) - cmd->u.scanCmd.abort_scan_indication = + /* + * Do not skip if command and either session id + * or scan id is matched + */ + if ((cmd->command == scan_cmd_type) && + ((cmd->u.scanCmd.scanID == scan_id) || + (cmd->sessionId == session_id))) { + if (abort_reason == + eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE) + cmd->u.scanCmd.abort_scan_indication = eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE; - csr_send_scan_abort(mac_ctx, cmd->sessionId, - cmd->u.scanCmd.scanID); + + csr_send_scan_abort(mac_ctx, cmd->sessionId, + cmd->u.scanCmd.scanID); + + } } } csr_ll_unlock(list); @@ -7018,7 +7000,7 @@ QDF_STATUS csr_scan_abort_mac_scan_not_for_connect(tpAniSirGlobal pMac, * purpose */ status = csr_scan_abort_mac_scan(pMac, sessionId, - eCSR_SCAN_ABORT_DEFAULT); + INVALID_SCAN_ID, eCSR_SCAN_ABORT_DEFAULT); } return status; } diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index ea634b09112b..0e7624b71891 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -279,13 +279,27 @@ QDF_STATUS csr_scan_for_ssid(tpAniSirGlobal pMac, uint32_t sessionId, /* To remove fresh scan commands from the pending queue */ bool csr_scan_remove_fresh_scan_command(tpAniSirGlobal pMac, uint8_t sessionId); QDF_STATUS csr_scan_abort_mac_scan(tpAniSirGlobal pMac, uint8_t sessionId, - eCsrAbortReason reason); + uint32_t scan_id, eCsrAbortReason reason); QDF_STATUS csr_scan_abort_all_scans(tpAniSirGlobal mac_ctx, eCsrAbortReason reason); -void csr_remove_cmd_from_pending_list(tpAniSirGlobal pMac, tDblLinkList *pList, - eSmeCommandType commandType); -void csr_remove_cmd_with_session_id_from_pending_list(tpAniSirGlobal pMac, +/** + * csr_remove_cmd_from_pending_list() - Remove command from + * pending list + * @pMac: Pointer to Global MAC structure + * @sessionId: session id + * @scan_id: scan id + * @pList: pointer to pending command list + * @commandType: sme command type + * + * Remove command from pending list by matching either + * scan id or session id. + * + * Return: QDF_STATUS_SUCCESS for success, QDF_STATUS_E_FAILURE + * for failure + */ +QDF_STATUS csr_remove_cmd_from_pending_list(tpAniSirGlobal pMac, uint8_t sessionId, + uint32_t scan_id, tDblLinkList *pList, eSmeCommandType commandType); QDF_STATUS csr_scan_abort_mac_scan_not_for_connect(tpAniSirGlobal pMac, @@ -296,7 +310,7 @@ void csr_remove_scan_for_ssid_from_pending_list(tpAniSirGlobal pMac, uint32_t sessionId); QDF_STATUS csr_abort_scan_from_active_list(tpAniSirGlobal pMac, - tDblLinkList *pList, uint32_t sessionId, + tDblLinkList *pList, uint32_t sessionId, uint32_t scan_id, eSmeCommandType scan_cmd_type, eCsrAbortReason abort_reason); /* To age out scan results base. tSmeGetScanChnRsp is a pointer returned by LIM that */ |
