Переглянути джерело

rmnet_core: ethtool QMAP stats

Add QMAP(rmnet_ctl) RX/TX stats to the ethtool.

Change-Id: I730c6e06aaadba20d56485891408abfa1be8c27a
Signed-off-by: Weiyi Chen <[email protected]>
Weiyi Chen 3 роки тому
батько
коміт
d26ada23f9
3 змінених файлів з 41 додано та 2 видалено
  1. 4 1
      core/rmnet_ctl.h
  2. 16 0
      core/rmnet_ctl_client.c
  3. 21 1
      core/rmnet_vnd.c

+ 4 - 1
core/rmnet_ctl.h

@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * RMNET_CTL header
  *
@@ -31,8 +32,10 @@ struct rmnet_ctl_client_if {
 
 #ifdef RMNET_LA_PLATFORM
 struct rmnet_ctl_client_if *rmnet_ctl_if(void);
+int rmnet_ctl_get_stats(u64 *s, int n);
 #else
-inline struct rmnet_ctl_client_if *rmnet_ctl_if(void) {return NULL;};
+static inline struct rmnet_ctl_client_if *rmnet_ctl_if(void) {return NULL;};
+static inline int rmnet_ctl_get_stats(u64 *s, int n) {return 0;};
 #endif /* RMNET_LA_PLATFORM */
 
 #endif /* _RMNET_CTL_H_ */

+ 16 - 0
core/rmnet_ctl_client.c

@@ -231,3 +231,19 @@ struct rmnet_ctl_client_if *rmnet_ctl_if(void)
 	return &client_if;
 }
 EXPORT_SYMBOL(rmnet_ctl_if);
+
+int rmnet_ctl_get_stats(u64 *s, int n)
+{
+	struct rmnet_ctl_dev *dev;
+
+	rcu_read_lock();
+	dev = rcu_dereference(ctl_ep.dev);
+	if (dev && n > 0) {
+		n = min(n, (int)(sizeof(dev->stats) / sizeof(u64)));
+		memcpy(s, &dev->stats, n * sizeof(u64));
+	}
+	rcu_read_unlock();
+
+	return n;
+}
+EXPORT_SYMBOL(rmnet_ctl_get_stats);

+ 21 - 1
core/rmnet_vnd.c

@@ -33,6 +33,7 @@
 #include "rmnet_vnd.h"
 #include "rmnet_genl.h"
 #include "rmnet_ll.h"
+#include "rmnet_ctl.h"
 
 #include "qmi_rmnet.h"
 #include "rmnet_qmi.h"
@@ -565,6 +566,14 @@ static const char rmnet_ll_gstrings_stats[][ETH_GSTRING_LEN] = {
 	"LL TX FC err",
 };
 
+static const char rmnet_qmap_gstrings_stats[][ETH_GSTRING_LEN] = {
+	"QMAP RX success",
+	"QMAP RX errors",
+	"QMAP TX queued",
+	"QMAP TX errors",
+	"QMAP TX complete (MHI)",
+};
+
 static void rmnet_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
 {
 	size_t off = 0;
@@ -580,6 +589,9 @@ static void rmnet_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
 		off += sizeof(rmnet_port_gstrings_stats);
 		memcpy(buf + off, &rmnet_ll_gstrings_stats,
 		       sizeof(rmnet_ll_gstrings_stats));
+		off += sizeof(rmnet_ll_gstrings_stats);
+		memcpy(buf + off, &rmnet_qmap_gstrings_stats,
+		       sizeof(rmnet_qmap_gstrings_stats));
 		break;
 	}
 }
@@ -590,7 +602,8 @@ static int rmnet_get_sset_count(struct net_device *dev, int sset)
 	case ETH_SS_STATS:
 		return ARRAY_SIZE(rmnet_gstrings_stats) +
 		       ARRAY_SIZE(rmnet_port_gstrings_stats) +
-		       ARRAY_SIZE(rmnet_ll_gstrings_stats);
+		       ARRAY_SIZE(rmnet_ll_gstrings_stats) +
+		       ARRAY_SIZE(rmnet_qmap_gstrings_stats);
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -605,6 +618,7 @@ static void rmnet_get_ethtool_stats(struct net_device *dev,
 	struct rmnet_ll_stats *llp;
 	struct rmnet_port *port;
 	size_t off = 0;
+	u64 qmap_s[ARRAY_SIZE(rmnet_qmap_gstrings_stats)];
 
 	port = rmnet_get_port(priv->real_dev);
 
@@ -621,6 +635,12 @@ static void rmnet_get_ethtool_stats(struct net_device *dev,
 	off += ARRAY_SIZE(rmnet_port_gstrings_stats);
 	memcpy(data + off, llp,
 	       ARRAY_SIZE(rmnet_ll_gstrings_stats) * sizeof(u64));
+
+	off += ARRAY_SIZE(rmnet_ll_gstrings_stats);
+	memset(qmap_s, 0, sizeof(qmap_s));
+	rmnet_ctl_get_stats(qmap_s, ARRAY_SIZE(rmnet_qmap_gstrings_stats));
+	memcpy(data + off, qmap_s,
+	       ARRAY_SIZE(rmnet_qmap_gstrings_stats) * sizeof(u64));
 }
 
 static int rmnet_stats_reset(struct net_device *dev)