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
This commit is contained in:
Yu Wang
2018-03-09 16:04:15 +08:00
committed by nshrivas
parent 5259c23657
commit c0b46f810d
2 changed files with 128 additions and 1 deletions

View File

@@ -84,6 +84,8 @@
#include "sme_api.h" #include "sme_api.h"
#include "wlan_hdd_regulatory.h" #include "wlan_hdd_regulatory.h"
#include <wlan_ipa_ucfg_api.h> #include <wlan_ipa_ucfg_api.h>
#include <wlan_cfg80211_mc_cp_stats.h>
#include <wlan_cp_stats_mc_ucfg_api.h>
#define IS_UP(_dev) \ #define IS_UP(_dev) \
(((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP)) (((_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 * 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 static int
__iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info, __iw_get_peer_rssi(struct net_device *dev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra) 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; length += buf;
} }
wrqu->data.length = length + 1; wrqu->data.length = length + 1;
hdd_exit(); hdd_exit();
return 0; return 0;
} }
#endif
/** /**
* iw_get_peer_rssi() - get station's rssi * iw_get_peer_rssi() - get station's rssi

View File

@@ -35,6 +35,7 @@
#include "wlan_hdd_request_manager.h" #include "wlan_hdd_request_manager.h"
#include "wlan_hdd_debugfs_llstat.h" #include "wlan_hdd_debugfs_llstat.h"
#include "wlan_reg_services_api.h" #include "wlan_reg_services_api.h"
#include <wlan_cfg80211_mc_cp_stats.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS) #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
#define HDD_INFO_SIGNAL STATION_INFO_SIGNAL #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; 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 { struct rssi_priv {
int8_t rssi; 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; return QDF_STATUS_SUCCESS;
} }
#endif /* QCA_SUPPORT_CP_STATS */
struct snr_priv { struct snr_priv {
int8_t snr; int8_t snr;