Parcourir la source

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
Yu Wang il y a 7 ans
Parent
commit
c0b46f810d
2 fichiers modifiés avec 128 ajouts et 1 suppressions
  1. 67 1
      core/hdd/src/wlan_hdd_hostapd.c
  2. 61 0
      core/hdd/src/wlan_hdd_stats.c

+ 67 - 1
core/hdd/src/wlan_hdd_hostapd.c

@@ -84,6 +84,8 @@
 #include "sme_api.h"
 #include "wlan_hdd_regulatory.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) \
 	(((_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

+ 61 - 0
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 <wlan_cfg80211_mc_cp_stats.h>
 
 #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;