From 1148cb0bb262959e236ef89f4625ea26561356c2 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Fri, 13 Jul 2018 23:14:32 -0700 Subject: [PATCH] qcacld-3.0: Refine the extscan start BSSID hotlist logic Make the following updates to the extscan start BSSID hotlist logic: 1) Exclusively use the Unified WMI data structures. 2) Use the new wmi_unified_extscan_start_hotlist_monitor_cmd() API. 3) Update the HDD<=>SME interface to enforce the contract that SME must not make any assumptions about the buffers provided by HDD. Change-Id: I4d9f982177bc61a751ba0e7437fe55482dfd2723 CRs-Fixed: 2291946 --- core/hdd/src/wlan_hdd_ext_scan.c | 194 +++++++++++++++++-------------- core/mac/inc/sir_api.h | 18 --- core/sme/inc/sme_api.h | 17 ++- core/sme/src/common/sme_api.c | 47 ++++---- core/wma/inc/wma_internal.h | 16 ++- core/wma/src/wma_main.c | 3 +- core/wma/src/wma_scan_roam.c | 50 ++------ 7 files changed, 163 insertions(+), 182 deletions(-) diff --git a/core/hdd/src/wlan_hdd_ext_scan.c b/core/hdd/src/wlan_hdd_ext_scan.c index cb7b17065b25..066a35d4fe06 100644 --- a/core/hdd/src/wlan_hdd_ext_scan.c +++ b/core/hdd/src/wlan_hdd_ext_scan.c @@ -31,6 +31,8 @@ #include "cds_sched.h" #include +#define EXTSCAN_PARAM_MAX QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + /* amount of time to wait for a synchronous request/response operation */ #define WLAN_WAIT_TIME_EXTSCAN 1000 @@ -1887,6 +1889,60 @@ int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy, return ret; } +/** + * hdd_parse_ap_rssi_threshold() - parse AP RSSI threshold parameters + * @attr: netlink attribute containing the AP RSSI threshold parameters + * @ap: destination buffer for the parsed parameters + * + * This function parses the BSSID, low RSSI and high RSSI values from + * the @attr netlink attribute, storing the parsed values in @ap. + * + * Return: 0 if @attr is parsed and all required attributes are + * present, otherwise a negative errno. + */ +static int hdd_parse_ap_rssi_threshold(struct nlattr *attr, + struct ap_threshold_params *ap) +{ + struct nlattr *tb[EXTSCAN_PARAM_MAX + 1]; + int id; + + if (wlan_cfg80211_nla_parse(tb, EXTSCAN_PARAM_MAX, + nla_data(attr), nla_len(attr), + wlan_hdd_extscan_config_policy)) { + hdd_err("nla_parse failed"); + return -EINVAL; + } + + /* Parse and fetch MAC address */ + id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID; + if (!tb[id]) { + hdd_err("attr mac address failed"); + return -EINVAL; + } + nla_memcpy(ap->bssid.bytes, tb[id], QDF_MAC_ADDR_SIZE); + hdd_debug("BSSID: " MAC_ADDRESS_STR, MAC_ADDR_ARRAY(ap->bssid.bytes)); + + /* Parse and fetch low RSSI */ + id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW; + if (!tb[id]) { + hdd_err("attr low RSSI failed"); + return -EINVAL; + } + ap->low = nla_get_s32(tb[id]); + hdd_debug("RSSI low %d", ap->low); + + /* Parse and fetch high RSSI */ + id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH; + if (!tb[id]) { + hdd_err("attr high RSSI failed"); + return -EINVAL; + } + ap->high = nla_get_s32(tb[id]); + hdd_debug("RSSI High %d", ap->high); + + return 0; +} + /** * __wlan_hdd_cfg80211_extscan_set_bssid_hotlist() - set bssid hot list * @wiphy: Pointer to wireless phy @@ -1898,24 +1954,20 @@ int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy, */ static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy, - struct wireless_dev - *wdev, const void *data, - int data_len) + struct wireless_dev *wdev, + const void *data, + int data_len) { - tpSirExtScanSetBssidHotListReqParams pReqMsg = NULL; + struct extscan_bssid_hotlist_set_params *params; struct net_device *dev = wdev->netdev; struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); struct hdd_context *hdd_ctx = wiphy_priv(wiphy); - struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + - 1]; - struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX - + 1]; - struct nlattr *apTh; + struct nlattr *tb[EXTSCAN_PARAM_MAX + 1]; + struct nlattr *apth; struct hdd_ext_scan_context *context; - uint32_t request_id; QDF_STATUS status; uint8_t i; - int rem, retval; + int id, rem, retval; unsigned long rc; hdd_enter_dev(dev); @@ -1933,131 +1985,98 @@ __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy, hdd_err("extscan not supported"); return -ENOTSUPP; } - if (wlan_cfg80211_nla_parse(tb, - QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, - data, data_len, wlan_hdd_extscan_config_policy)) { + + if (wlan_cfg80211_nla_parse(tb, EXTSCAN_PARAM_MAX, + data, data_len, + wlan_hdd_extscan_config_policy)) { hdd_err("Invalid ATTR"); return -EINVAL; } - pReqMsg = qdf_mem_malloc(sizeof(*pReqMsg)); - if (!pReqMsg) { + params = qdf_mem_malloc(sizeof(*params)); + if (!params) { hdd_err("qdf_mem_malloc failed"); return -ENOMEM; } + /* assume the worst until proven otherwise */ + retval = -EINVAL; + /* Parse and fetch request Id */ - if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID; + if (!tb[id]) { hdd_err("attr request id failed"); goto fail; } - pReqMsg->requestId = - nla_get_u32(tb - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); - hdd_debug("Req Id %d", pReqMsg->requestId); + params->request_id = nla_get_u32(tb[id]); + hdd_debug("Req Id %d", params->request_id); /* Parse and fetch number of APs */ - if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) { + id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP; + if (!tb[id]) { hdd_err("attr number of AP failed"); goto fail; } - pReqMsg->numAp = - nla_get_u32(tb - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]); - if (pReqMsg->numAp > WLAN_EXTSCAN_MAX_HOTLIST_APS) { + + params->num_ap = nla_get_u32(tb[id]); + if (params->num_ap > WMI_WLAN_EXTSCAN_MAX_HOTLIST_APS) { hdd_err("Number of AP: %u exceeds max: %u", - pReqMsg->numAp, WLAN_EXTSCAN_MAX_HOTLIST_APS); + params->num_ap, WMI_WLAN_EXTSCAN_MAX_HOTLIST_APS); goto fail; } - pReqMsg->sessionId = adapter->session_id; - hdd_debug("Number of AP %d Session Id %d", - pReqMsg->numAp, pReqMsg->sessionId); + params->vdev_id = adapter->session_id; + hdd_debug("Number of AP %d vdev Id %d", + params->num_ap, params->vdev_id); /* Parse and fetch lost ap sample size */ - if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) { + id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE; + if (!tb[id]) { hdd_err("attr lost ap sample size failed"); goto fail; } - pReqMsg->lost_ap_sample_size = nla_get_u32( - tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]); + params->lost_ap_sample_size = nla_get_u32(tb[id]); hdd_debug("Lost ap sample size %d", - pReqMsg->lost_ap_sample_size); + params->lost_ap_sample_size); - if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM]) { + /* Parse the AP Threshold array */ + id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM; + if (!tb[id]) { hdd_err("attr ap threshold failed"); goto fail; } + i = 0; - nla_for_each_nested(apTh, - tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], - rem) { - if (i == pReqMsg->numAp) { + nla_for_each_nested(apth, tb[id], rem) { + if (i == params->num_ap) { hdd_warn("Ignoring excess AP"); break; } - if (wlan_cfg80211_nla_parse(tb2, - QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, - nla_data(apTh), nla_len(apTh), - wlan_hdd_extscan_config_policy)) { - hdd_err("nla_parse failed"); + retval = hdd_parse_ap_rssi_threshold(apth, ¶ms->ap[i]); + if (retval) goto fail; - } - - /* Parse and fetch MAC address */ - if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) { - hdd_err("attr mac address failed"); - goto fail; - } - nla_memcpy(pReqMsg->ap[i].bssid.bytes, - tb2 - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID], - QDF_MAC_ADDR_SIZE); - hdd_debug(MAC_ADDRESS_STR, - MAC_ADDR_ARRAY(pReqMsg->ap[i].bssid.bytes)); - - /* Parse and fetch low RSSI */ - if (!tb2 - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) { - hdd_err("attr low RSSI failed"); - goto fail; - } - pReqMsg->ap[i].low = - nla_get_s32(tb2 - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]); - hdd_debug("RSSI low %d", pReqMsg->ap[i].low); - - /* Parse and fetch high RSSI */ - if (!tb2 - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) { - hdd_err("attr high RSSI failed"); - goto fail; - } - pReqMsg->ap[i].high = - nla_get_s32(tb2 - [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]); - hdd_debug("RSSI High %d", pReqMsg->ap[i].high); i++; } - if (i < pReqMsg->numAp) { + if (i < params->num_ap) { hdd_warn("Number of AP %u less than expected %u", - i, pReqMsg->numAp); - pReqMsg->numAp = i; + i, params->num_ap); + params->num_ap = i; } context = &ext_scan_context; spin_lock(&context->context_lock); INIT_COMPLETION(context->response_event); - context->request_id = request_id = pReqMsg->requestId; + context->request_id = params->request_id; spin_unlock(&context->context_lock); - status = sme_set_bss_hotlist(hdd_ctx->mac_handle, pReqMsg); + status = sme_set_bss_hotlist(hdd_ctx->mac_handle, params); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("sme_set_bss_hotlist failed(err=%d)", status); + retval = qdf_status_to_os_return(status); goto fail; } @@ -2071,18 +2090,17 @@ __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy, retval = -ETIMEDOUT; } else { spin_lock(&context->context_lock); - if (context->request_id == request_id) + if (context->request_id == params->request_id) retval = context->response_status; else retval = -EINVAL; spin_unlock(&context->context_lock); } hdd_exit(); - return retval; fail: - qdf_mem_free(pReqMsg); - return -EINVAL; + qdf_mem_free(params); + return retval; } /** diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index a13b17b52c0f..9a83acfb6e72 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -3905,7 +3905,6 @@ struct sir_wisa_params { #define WLAN_EXTSCAN_MAX_CHANNELS 36 #define WLAN_EXTSCAN_MAX_BUCKETS 16 -#define WLAN_EXTSCAN_MAX_HOTLIST_APS 128 #define WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS 64 typedef enum { @@ -4321,23 +4320,6 @@ typedef struct { uint8_t sessionId; } tSirExtScanStopReqParams, *tpSirExtScanStopReqParams; -/** - * struct tSirExtScanSetBssidHotListReqParams - set hotlist request - * @requestId: request identifier - * @sessionId: session identifier - * @lost_ap_sample_size: number of samples to confirm AP loss - * @numAp: Number of hotlist APs - * @ap: hotlist APs - */ -typedef struct { - uint32_t requestId; - uint8_t sessionId; - - uint32_t lost_ap_sample_size; - uint32_t numAp; - tSirAPThresholdParam ap[WLAN_EXTSCAN_MAX_HOTLIST_APS]; -} tSirExtScanSetBssidHotListReqParams, *tpSirExtScanSetBssidHotListReqParams; - typedef struct { uint32_t requestId; uint8_t sessionId; diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 041c8e57fb51..d72b73bb156e 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -983,9 +983,20 @@ QDF_STATUS sme_ext_scan_start(tHalHandle hHal, tSirWifiScanCmdReqParams *pStartCmd); QDF_STATUS sme_ext_scan_stop(tHalHandle hHal, tSirExtScanStopReqParams *pStopReq); -QDF_STATUS sme_set_bss_hotlist(tHalHandle hHal, - tSirExtScanSetBssidHotListReqParams * - pSetHotListReq); + +/** + * sme_set_bss_hotlist() - SME API to set BSSID hotlist + * @mac_handle: Opaque handle to the MAC context + * @params: extscan set hotlist structure + * + * Handles the request to set the BSSID hotlist in firmware. + * + * Return: QDF_STATUS + */ +QDF_STATUS +sme_set_bss_hotlist(mac_handle_t mac_handle, + struct extscan_bssid_hotlist_set_params *params); + QDF_STATUS sme_reset_bss_hotlist(tHalHandle hHal, tSirExtScanResetBssidHotlistReqParams * pResetReq); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 61efac0f4274..7facf77fc483 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -11178,36 +11178,37 @@ QDF_STATUS sme_ext_scan_stop(tHalHandle hHal, tSirExtScanStopReqParams return status; } -/* - * sme_set_bss_hotlist() - - * SME API to set BSSID hotlist - * - * hHal - * pSetHotListReq: extscan set hotlist structure - * Return QDF_STATUS - */ -QDF_STATUS sme_set_bss_hotlist(tHalHandle hHal, - tSirExtScanSetBssidHotListReqParams * - pSetHotListReq) +QDF_STATUS +sme_set_bss_hotlist(mac_handle_t mac_handle, + struct extscan_bssid_hotlist_set_params *params) { - QDF_STATUS status = QDF_STATUS_SUCCESS; - QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; - tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + QDF_STATUS status; + tpAniSirGlobal mac = MAC_CONTEXT(mac_handle); struct scheduler_msg message = {0}; + struct extscan_bssid_hotlist_set_params *bodyptr; - status = sme_acquire_global_lock(&pMac->sme); + /* per contract must make a copy of the params when messaging */ + bodyptr = qdf_mem_malloc(sizeof(*bodyptr)); + if (!bodyptr) { + sme_err("buffer allocation failure"); + return QDF_STATUS_E_NOMEM; + } + *bodyptr = *params; + + status = sme_acquire_global_lock(&mac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { /* Serialize the req through MC thread */ - message.bodyptr = pSetHotListReq; + message.bodyptr = bodyptr; message.type = WMA_EXTSCAN_SET_BSSID_HOTLIST_REQ; - MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, - NO_SESSION, message.type)); - qdf_status = scheduler_post_msg(QDF_MODULE_ID_WMA, - &message); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) - status = QDF_STATUS_E_FAILURE; + qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG, + NO_SESSION, message.type); + status = scheduler_post_msg(QDF_MODULE_ID_WMA, &message); + sme_release_global_lock(&mac->sme); + } - sme_release_global_lock(&pMac->sme); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("failure: %d", status); + qdf_mem_free(bodyptr); } return status; } diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 2b5eaf464b28..59124c257a1c 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -362,13 +362,17 @@ QDF_STATUS wma_start_extscan(tp_wma_handle wma, QDF_STATUS wma_stop_extscan(tp_wma_handle wma, tSirExtScanStopReqParams *pstopcmd); -QDF_STATUS wma_get_buf_extscan_hotlist_cmd(tp_wma_handle wma_handle, - tSirExtScanSetBssidHotListReqParams * - photlist, int *buf_len); - +/** + * wma_extscan_start_hotlist_monitor() - start hotlist monitor + * @wma: wma handle + * @params: hotlist request params + * + * This function configures hotlist monitor in fw. + * + * Return: QDF status + */ QDF_STATUS wma_extscan_start_hotlist_monitor(tp_wma_handle wma, - tSirExtScanSetBssidHotListReqParams - *photlist); + struct extscan_bssid_hotlist_set_params *params); QDF_STATUS wma_extscan_stop_hotlist_monitor(tp_wma_handle wma, tSirExtScanResetBssidHotlistReqParams *photlist_reset); diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 21decf74dec6..0c1b4f7a2ba3 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -8149,8 +8149,7 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) qdf_mem_free(msg->bodyptr); break; case WMA_EXTSCAN_SET_BSSID_HOTLIST_REQ: - wma_extscan_start_hotlist_monitor(wma_handle, - (tSirExtScanSetBssidHotListReqParams *) msg->bodyptr); + wma_extscan_start_hotlist_monitor(wma_handle, msg->bodyptr); qdf_mem_free(msg->bodyptr); break; case WMA_EXTSCAN_RESET_BSSID_HOTLIST_REQ: diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 99dab76a3325..f988230c0d48 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -4628,56 +4628,22 @@ static inline int wma_get_hotlist_entries_per_page(wmi_unified_t wmi_handle, return num_entries; } -/** - * wma_get_buf_extscan_hotlist_cmd() - prepare hotlist command - * @handle: wma handle - * @photlist: hotlist command params - * @buf_len: buffer length - * - * This function fills individual elements for hotlist request and - * TLV for bssid entries - * - * Return: QDF Status. - */ -QDF_STATUS wma_get_buf_extscan_hotlist_cmd(tp_wma_handle wma_handle, - tSirExtScanSetBssidHotListReqParams *photlist, - int *buf_len) -{ - return wmi_unified_get_buf_extscan_hotlist_cmd(wma_handle->wmi_handle, - (struct ext_scan_setbssid_hotlist_params *)photlist, - buf_len); -} - -/** - * wma_extscan_start_hotlist_monitor() - start hotlist monitor - * @wma: wma handle - * @photlist: hotlist request params - * - * This function configures hotlist monitor in fw. - * - * Return: QDF status - */ QDF_STATUS wma_extscan_start_hotlist_monitor(tp_wma_handle wma, - tSirExtScanSetBssidHotListReqParams *photlist) + struct extscan_bssid_hotlist_set_params *params) { - QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; - int len; - if (!wma || !wma->wmi_handle) { WMA_LOGE("%s: WMA is closed, can not issue hotlist cmd", __func__); return QDF_STATUS_E_INVAL; } - /* Fill individual elements for hotlist request and - * TLV for bssid entries - */ - qdf_status = wma_get_buf_extscan_hotlist_cmd(wma, photlist, &len); - if (qdf_status != QDF_STATUS_SUCCESS) { - WMA_LOGE("%s: Failed to get buffer for hotlist scan cmd", - __func__); - return QDF_STATUS_E_FAILURE; + + if (!params) { + WMA_LOGE("%s: Invalid params", __func__); + return QDF_STATUS_E_INVAL; } - return QDF_STATUS_SUCCESS; + + return wmi_unified_extscan_start_hotlist_monitor_cmd(wma->wmi_handle, + params); } /**