From c0b46f810de420a550a8f31141cf71d9f78fb828 Mon Sep 17 00:00:00 2001 From: Yu Wang Date: Fri, 9 Mar 2018 16:04:15 +0800 Subject: [PATCH] qcacld-3.0: add implementation of getting peer rssi Add changes to support get peer rssi from within cp_stats component. Change-Id: I4c3d5168eeb6fa097d91eb2568e059817cab7d91 CRs-Fixed: 2222778 --- core/hdd/src/wlan_hdd_hostapd.c | 68 ++++++++++++++++++++++++++++++++- core/hdd/src/wlan_hdd_stats.c | 61 +++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 1 deletion(-) diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index aaa514efdcc8..c288d8ce6a35 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -84,6 +84,8 @@ #include "sme_api.h" #include "wlan_hdd_regulatory.h" #include +#include +#include #define IS_UP(_dev) \ (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP)) @@ -5282,6 +5284,70 @@ iw_get_softap_linkspeed(struct net_device *dev, * * Return: 0 on success, otherwise error value */ +#ifdef QCA_SUPPORT_CP_STATS +static int +__iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret, i; + struct hdd_context *hddctx; + struct stats_event rssi_info; + char macaddrarray[MAC_ADDRESS_STR_LEN]; + struct hdd_adapter *adapter = netdev_priv(dev); + struct qdf_mac_addr macaddress = QDF_MAC_ADDR_BCAST_INIT; + + hdd_enter(); + + hddctx = WLAN_HDD_GET_CTX(adapter); + ret = wlan_hdd_validate_context(hddctx); + if (ret != 0) + return ret; + + ret = hdd_check_private_wext_control(hddctx, info); + if (0 != ret) + return ret; + + hdd_debug("wrqu->data.length= %d", wrqu->data.length); + + if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) { + if (copy_from_user(macaddrarray, + wrqu->data.pointer, + MAC_ADDRESS_STR_LEN - 1)) { + hdd_info("failed to copy data from user buffer"); + return -EFAULT; + } + + macaddrarray[MAC_ADDRESS_STR_LEN - 1] = '\0'; + hdd_debug("%s", macaddrarray); + + if (!mac_pton(macaddrarray, macaddress.bytes)) + hdd_err("String to Hex conversion Failed"); + } + + ret = wlan_cfg80211_mc_cp_stats_get_peer_rssi(adapter->hdd_vdev, + macaddress.bytes, + &rssi_info); + if (ret) { + hdd_err("Unable to retrieve peer rssi: %d", ret); + wlan_cfg80211_mc_cp_stats_put_peer_rssi(&rssi_info); + return ret; + } + + wrqu->data.length = scnprintf(extra, IW_PRIV_SIZE_MASK, "\n"); + for (i = 0; i < rssi_info.num_peer_stats; i++) { + wrqu->data.length += scnprintf(extra + wrqu->data.length, + IW_PRIV_SIZE_MASK - wrqu->data.length, + "[%pM] [%d]\n", + rssi_info.peer_stats[i].peer_macaddr, + rssi_info.peer_stats[i].peer_rssi); + } + wrqu->data.length++; + wlan_cfg80211_mc_cp_stats_put_peer_rssi(&rssi_info); + + hdd_exit(); + return 0; +} +#else static int __iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -5354,11 +5420,11 @@ __iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info, length += buf; } wrqu->data.length = length + 1; - hdd_exit(); return 0; } +#endif /** * iw_get_peer_rssi() - get station's rssi diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c index 6e67927d1cf3..bda6c33282e8 100644 --- a/core/hdd/src/wlan_hdd_stats.c +++ b/core/hdd/src/wlan_hdd_stats.c @@ -35,6 +35,7 @@ #include "wlan_hdd_request_manager.h" #include "wlan_hdd_debugfs_llstat.h" #include "wlan_reg_services_api.h" +#include #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS) #define HDD_INFO_SIGNAL STATION_INFO_SIGNAL @@ -4960,6 +4961,65 @@ int wlan_hdd_get_rcpi(struct hdd_adapter *adapter, uint8_t *mac, return ret; } +#ifdef QCA_SUPPORT_CP_STATS +QDF_STATUS wlan_hdd_get_rssi(struct hdd_adapter *adapter, int8_t *rssi_value) +{ + int ret, i; + struct hdd_station_ctx *sta_ctx; + struct stats_event rssi_info; + + if (NULL == adapter) { + hdd_err("Invalid context, adapter"); + return QDF_STATUS_E_FAULT; + } + if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) { + hdd_err("Recovery in Progress. State: 0x%x Ignore!!!", + cds_get_driver_state()); + /* return a cached value */ + *rssi_value = adapter->rssi; + return QDF_STATUS_SUCCESS; + } + + sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + + if (eConnectionState_Associated != sta_ctx->conn_info.connState) { + hdd_debug("Not associated!, rssi on disconnect %d", + adapter->rssi_on_disconnect); + *rssi_value = adapter->rssi_on_disconnect; + return QDF_STATUS_SUCCESS; + } + + if (sta_ctx->hdd_reassoc_scenario) { + hdd_debug("Roaming in progress, return cached RSSI"); + *rssi_value = adapter->rssi; + return QDF_STATUS_SUCCESS; + } + + ret = wlan_cfg80211_mc_cp_stats_get_peer_rssi(adapter->hdd_vdev, + sta_ctx->conn_info.bssId.bytes, + &rssi_info); + if (ret) { + hdd_err("Unable to retrieve peer rssi: %d", ret); + wlan_cfg80211_mc_cp_stats_put_peer_rssi(&rssi_info); + return ret; + } + + for (i = 0; i < rssi_info.num_peer_stats; i++) { + if (!qdf_mem_cmp(rssi_info.peer_stats[i].peer_macaddr, + sta_ctx->conn_info.bssId.bytes, + WLAN_MACADDR_LEN)) { + *rssi_value = rssi_info.peer_stats[i].peer_rssi; + hdd_debug("RSSI = %d", *rssi_value); + wlan_cfg80211_mc_cp_stats_put_peer_rssi(&rssi_info); + return QDF_STATUS_SUCCESS; + } + } + + wlan_cfg80211_mc_cp_stats_put_peer_rssi(&rssi_info); + hdd_err("bss peer not present in returned result"); + return QDF_STATUS_E_FAULT; +} +#else /* QCA_SUPPORT_CP_STATS */ struct rssi_priv { int8_t rssi; }; @@ -5083,6 +5143,7 @@ QDF_STATUS wlan_hdd_get_rssi(struct hdd_adapter *adapter, int8_t *rssi_value) return QDF_STATUS_SUCCESS; } +#endif /* QCA_SUPPORT_CP_STATS */ struct snr_priv { int8_t snr;