Browse Source

qcacld-3.0: Process tx and rx rate count from peer stats

Based on the new requirement process tx and rx rate counts
from peer stats response and send these stats to user space
as part of big data stats.

Change-Id: Ie442c0e37fcae8af92796032ff6a042d983c8742
CRs-Fixed: 3289741
Ashish Kumar Dhanotiya 2 years ago
parent
commit
f39a68fc05

+ 8 - 0
core/hdd/src/wlan_hdd_sta_info.h

@@ -240,6 +240,10 @@ char *sta_info_string_from_dbgid(wlan_sta_info_dbgid id);
  * @pending_eap_frm_type: EAP frame type in tx queue without tx completion
  * @is_attached: Flag to check if the stainfo is attached/detached
  * @peer_rssi_per_chain: Average value of RSSI (dbm) per chain
+ * @num_tx_rate_counts: Num tx rate count for current peer
+ * @num_rx_rate_counts: Num rx rate count for current peer
+ * @tx_pkt_per_mcs: Number of tx rate counts for each MCS
+ * @rx_pkt_per_mcs: Number of rx rate counts for each MCS
  */
 struct hdd_station_info {
 	qdf_list_node_t sta_node;
@@ -305,6 +309,10 @@ struct hdd_station_info {
 	unsigned long pending_eap_frm_type;
 	bool is_attached;
 	int32_t peer_rssi_per_chain[WMI_MAX_CHAINS];
+	uint32_t num_tx_rate_count;
+	uint32_t num_rx_rate_count;
+	uint32_t *tx_pkt_per_mcs;
+	uint32_t *rx_pkt_per_mcs;
 };
 
 /**

+ 94 - 1
core/hdd/src/wlan_hdd_station_info.c

@@ -1660,6 +1660,33 @@ static int hdd_get_peer_stats(struct hdd_adapter *adapter,
 	stainfo->tx_retry_fw = stats->peer_stats_info_ext->tx_retries;
 	stainfo->tx_retry_exhaust_fw = stats->peer_stats_info_ext->tx_failed;
 
+	if (stats->peer_stats_info_ext->num_tx_rate_counts) {
+		stainfo->tx_pkt_per_mcs = qdf_mem_malloc(
+				stats->peer_stats_info_ext->num_tx_rate_counts *
+				sizeof(uint32_t));
+		if (stainfo->tx_pkt_per_mcs) {
+			stainfo->num_tx_rate_count =
+				stats->peer_stats_info_ext->num_tx_rate_counts;
+			qdf_mem_copy(
+				stainfo->tx_pkt_per_mcs,
+				stats->peer_stats_info_ext->tx_pkt_per_mcs,
+				stainfo->num_tx_rate_count * sizeof(uint32_t));
+		}
+	}
+	if (stats->peer_stats_info_ext->num_rx_rate_counts) {
+		stainfo->rx_pkt_per_mcs = qdf_mem_malloc(
+				stats->peer_stats_info_ext->num_rx_rate_counts *
+				sizeof(uint32_t));
+		if (stainfo->rx_pkt_per_mcs) {
+			stainfo->num_rx_rate_count =
+				stats->peer_stats_info_ext->num_rx_rate_counts;
+			qdf_mem_copy(
+				stainfo->rx_pkt_per_mcs,
+				stats->peer_stats_info_ext->rx_pkt_per_mcs,
+				stainfo->num_rx_rate_count * sizeof(uint32_t));
+		}
+	}
+
 	/* Optional, just print logs here */
 	if (!stats->num_peer_adv_stats) {
 		hdd_debug("Failed to get peer adv stats info");
@@ -1681,6 +1708,25 @@ static int hdd_get_peer_stats(struct hdd_adapter *adapter,
 	return ret;
 }
 
+/**
+ * hdd_free_tx_rx_pkts_per_mcs - Free memory for tx packets per MCS and
+ * rx packets per MCS
+ * @stainfo: station information
+ *
+ * Return: None
+ */
+static void hdd_free_tx_rx_pkts_per_mcs(struct hdd_station_info *stainfo)
+{
+	if (stainfo->tx_pkt_per_mcs) {
+		qdf_mem_free(stainfo->tx_pkt_per_mcs);
+		stainfo->tx_pkt_per_mcs = NULL;
+	}
+	if (stainfo->rx_pkt_per_mcs) {
+		qdf_mem_free(stainfo->rx_pkt_per_mcs);
+		stainfo->rx_pkt_per_mcs = NULL;
+	}
+}
+
 /**
  * hdd_add_peer_stats_get_len - get data length used in
  * hdd_add_peer_stats()
@@ -1694,6 +1740,15 @@ static int hdd_get_peer_stats(struct hdd_adapter *adapter,
 static uint32_t
 hdd_add_peer_stats_get_len(struct hdd_station_info *stainfo)
 {
+	uint32_t tx_count_size = 0;
+	uint32_t rx_count_size = 0;
+	uint16_t i;
+
+	for (i = 0; i < stainfo->num_tx_rate_count; i++)
+		tx_count_size += nla_attr_size(sizeof(uint32_t));
+	for (i = 0; i < stainfo->num_rx_rate_count; i++)
+		rx_count_size += nla_attr_size(sizeof(uint32_t));
+
 	return (nla_attr_size(sizeof(stainfo->rx_retry_cnt)) +
 		nla_attr_size(sizeof(stainfo->rx_mc_bc_cnt)) +
 		nla_attr_size(sizeof(stainfo->tx_retry_succeed)) +
@@ -1701,7 +1756,8 @@ hdd_add_peer_stats_get_len(struct hdd_station_info *stainfo)
 		nla_attr_size(sizeof(stainfo->tx_total_fw)) +
 		nla_attr_size(sizeof(stainfo->tx_retry_fw)) +
 		nla_attr_size(sizeof(stainfo->tx_retry_exhaust_fw)) +
-		nla_attr_size(sizeof(stainfo->rx_fcs_count)));
+		nla_attr_size(sizeof(stainfo->rx_fcs_count)) +
+		tx_count_size + rx_count_size);
 }
 
 /**
@@ -1969,6 +2025,9 @@ static int hdd_add_connect_fail_reason_code(struct sk_buff *skb,
 static int hdd_add_peer_stats(struct sk_buff *skb,
 			      struct hdd_station_info *stainfo)
 {
+	struct nlattr *nla_attr;
+	uint8_t i;
+
 	if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_RETRY_COUNT,
 			stainfo->rx_retry_cnt)) {
 		hdd_err("Failed to put rx_retry_cnt");
@@ -2020,8 +2079,42 @@ static int hdd_add_peer_stats(struct sk_buff *skb,
 		goto fail;
 	}
 
+	nla_attr = nla_nest_start(skb,
+			QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PER_MCS_TX_PACKETS);
+	if (!nla_attr) {
+		hdd_err("nla nest start for tx packets fail");
+		goto fail;
+	}
+
+	for (i = 0; i < stainfo->num_tx_rate_count; i++)
+		if (nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PER_MCS_TX_PACKETS,
+			stainfo->tx_pkt_per_mcs[i])) {
+			hdd_err("Failed to put tx_rate_count for MCS[%d]", i);
+			goto fail;
+		}
+	nla_nest_end(skb, nla_attr);
+
+	nla_attr = nla_nest_start(skb,
+			QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PER_MCS_RX_PACKETS);
+	if (!nla_attr) {
+		hdd_err("nla nest start for rx packets fail");
+		goto fail;
+	}
+
+	for (i = 0; i < stainfo->num_rx_rate_count; i++)
+		if (nla_put_u32(skb,
+			QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PER_MCS_TX_PACKETS,
+			stainfo->rx_pkt_per_mcs[i])) {
+			hdd_err("Failed to put rx_rate_count for MCS[%d]", i);
+			goto fail;
+		}
+	nla_nest_end(skb, nla_attr);
+
+	hdd_free_tx_rx_pkts_per_mcs(stainfo);
 	return 0;
 fail:
+	hdd_free_tx_rx_pkts_per_mcs(stainfo);
 	return -EINVAL;
 }
 

+ 77 - 2
os_if/cp_stats/src/wlan_cfg80211_mc_cp_stats.c

@@ -1331,6 +1331,81 @@ get_mib_stats_fail:
 }
 #endif
 
+/**
+ * copy_peer_stats_info_ext - Copy peer ext stats info from stats event to
+ * destination peer stats info
+ * @dst_peer_stats_info: Destination peer ext stats pointer where peer ext info
+ * needs to be copied.
+ * @ev: Stats event pointer from where peers stats info needs to be copied
+ *
+ * Return: Void
+ */
+static void
+copy_peer_stats_info_ext(struct peer_stats_info_ext_event *dst_peer_stats_info,
+			 struct stats_event *ev)
+{
+	uint32_t i, j;
+	struct peer_stats_info_ext_event *src_peer_stats_info =
+							ev->peer_stats_info_ext;
+	struct peer_stats_info_ext_event *peer_stats_info = dst_peer_stats_info;
+
+	for (i = 0; i < ev->num_peer_stats_info_ext; i++) {
+		qdf_mem_copy(&peer_stats_info->peer_macaddr,
+			     &src_peer_stats_info->peer_macaddr,
+			     sizeof(peer_stats_info->peer_macaddr));
+		peer_stats_info->tx_packets = src_peer_stats_info->tx_packets;
+		peer_stats_info->tx_bytes = src_peer_stats_info->tx_bytes;
+		peer_stats_info->rx_packets = src_peer_stats_info->rx_packets;
+		peer_stats_info->rx_bytes = src_peer_stats_info->rx_bytes;
+		peer_stats_info->tx_retries = src_peer_stats_info->tx_retries;
+		peer_stats_info->tx_failed = src_peer_stats_info->tx_failed;
+		peer_stats_info->tx_succeed = src_peer_stats_info->tx_succeed;
+		peer_stats_info->rssi = src_peer_stats_info->rssi;
+		peer_stats_info->tx_rate = src_peer_stats_info->tx_rate;
+		peer_stats_info->tx_rate_code =
+					src_peer_stats_info->tx_rate_code;
+		peer_stats_info->rx_rate = src_peer_stats_info->rx_rate;
+		peer_stats_info->rx_rate_code =
+					src_peer_stats_info->rx_rate_code;
+		for (j = 0; j < WMI_MAX_CHAINS; j++)
+			peer_stats_info->peer_rssi_per_chain[j] =
+				src_peer_stats_info->peer_rssi_per_chain[j];
+
+		if (src_peer_stats_info->num_tx_rate_counts) {
+			peer_stats_info->tx_pkt_per_mcs =
+				qdf_mem_malloc(
+				src_peer_stats_info->num_tx_rate_counts *
+				sizeof(uint32_t));
+			if (!peer_stats_info->tx_pkt_per_mcs)
+				return;
+
+			peer_stats_info->num_tx_rate_counts =
+					src_peer_stats_info->num_tx_rate_counts;
+			qdf_mem_copy(peer_stats_info->tx_pkt_per_mcs,
+				     src_peer_stats_info->tx_pkt_per_mcs,
+				     peer_stats_info->num_tx_rate_counts *
+				     sizeof(uint32_t));
+		}
+		if (src_peer_stats_info->num_rx_rate_counts) {
+			peer_stats_info->rx_pkt_per_mcs =
+				qdf_mem_malloc(
+				src_peer_stats_info->num_rx_rate_counts *
+				sizeof(uint32_t));
+			if (!peer_stats_info->rx_pkt_per_mcs)
+				return;
+
+			peer_stats_info->num_rx_rate_counts =
+					src_peer_stats_info->num_rx_rate_counts;
+			qdf_mem_copy(peer_stats_info->rx_pkt_per_mcs,
+				     src_peer_stats_info->rx_pkt_per_mcs,
+				     peer_stats_info->num_rx_rate_counts *
+				     sizeof(uint32_t));
+		}
+		src_peer_stats_info++;
+		peer_stats_info++;
+	}
+}
+
 /**
  * get_peer_stats_cb() - get_peer_stats_cb callback function
  * @ev: peer stats buffer
@@ -1364,8 +1439,8 @@ static void get_peer_stats_cb(struct stats_event *ev, void *cookie)
 	if (!priv->peer_stats_info_ext)
 		goto peer_stats_cb_fail;
 
-	qdf_mem_copy(priv->peer_stats_info_ext, ev->peer_stats_info_ext,
-		     peer_stats_info_size);
+	copy_peer_stats_info_ext(priv->peer_stats_info_ext, ev);
+
 	priv->num_peer_stats_info_ext = ev->num_peer_stats_info_ext;
 
 peer_stats_cb_fail: