lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1686781820-832-9-git-send-email-justin.chen@broadcom.com>
Date: Wed, 14 Jun 2023 15:30:17 -0700
From: Justin Chen <justin.chen@...adcom.com>
To: netdev@...r.kernel.org,
	devicetree@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	dri-devel@...ts.freedesktop.org,
	bcm-kernel-feedback-list@...adcom.com
Cc: florian.fainelli@...adcom.com,
	davem@...emloft.net,
	edumazet@...gle.com,
	kuba@...nel.org,
	pabeni@...hat.com,
	robh+dt@...nel.org,
	krzysztof.kozlowski+dt@...aro.org,
	conor+dt@...nel.org,
	opendmb@...il.com,
	andrew@...n.ch,
	hkallweit1@...il.com,
	linux@...linux.org.uk,
	richardcochran@...il.com,
	sumit.semwal@...aro.org,
	christian.koenig@....com,
	simon.horman@...igine.com,
	Justin Chen <justin.chen@...adcom.com>
Subject: [PATCH net-next v7 08/11] net: bcmasp: Add support for ethtool driver stats

Add support for ethernet driver specific stats.

Signed-off-by: Justin Chen <justin.chen@...adcom.com>
---
 drivers/net/ethernet/broadcom/asp2/bcmasp.c        |   1 +
 drivers/net/ethernet/broadcom/asp2/bcmasp.h        |  21 +++
 .../net/ethernet/broadcom/asp2/bcmasp_ethtool.c    | 158 +++++++++++++++++++++
 drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c   |   8 ++
 4 files changed, 188 insertions(+)

diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp.c b/drivers/net/ethernet/broadcom/asp2/bcmasp.c
index ba9842c760d5..a8905fef4f8a 100644
--- a/drivers/net/ethernet/broadcom/asp2/bcmasp.c
+++ b/drivers/net/ethernet/broadcom/asp2/bcmasp.c
@@ -891,6 +891,7 @@ int bcmasp_set_en_mda_filter(struct bcmasp_intf *intf, unsigned char *addr,
 		/* Attempt to combine filters */
 		ret = bcmasp_combine_set_filter(intf, addr, mask, i);
 		if (!ret) {
+			intf->mib.filters_combine_cnt++;
 			return 0;
 		}
 	}
diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp.h b/drivers/net/ethernet/broadcom/asp2/bcmasp.h
index 7dc597658ed7..1485c2c3712d 100644
--- a/drivers/net/ethernet/broadcom/asp2/bcmasp.h
+++ b/drivers/net/ethernet/broadcom/asp2/bcmasp.h
@@ -245,6 +245,26 @@ struct bcmasp_intf_stats64{
 	struct u64_stats_sync		syncp;
 };
 
+struct bcmasp_mib_counters {
+	u32	edpkt_ts;
+	u32	edpkt_rx_pkt_cnt;
+	u32	edpkt_hdr_ext_cnt;
+	u32	edpkt_hdr_out_cnt;
+	u32	umac_frm_cnt;
+	u32	fb_frm_cnt;
+	u32	fb_rx_fifo_depth;
+	u32	fb_out_frm_cnt;
+	u32	fb_filt_out_frm_cnt;
+	u32	alloc_rx_skb_failed;
+	u32	tx_dma_failed;
+	u32	mc_filters_full_cnt;
+	u32	uc_filters_full_cnt;
+	u32	filters_combine_cnt;
+	u32	promisc_filters_cnt;
+	u32	tx_realloc_offload_failed;
+	u32	tx_realloc_offload;
+};
+
 struct bcmasp_intf_ops {
 	unsigned long (*rx_desc_read)(struct bcmasp_intf *intf);
 	void (*rx_buffer_write)(struct bcmasp_intf *intf, dma_addr_t addr);
@@ -307,6 +327,7 @@ struct bcmasp_intf {
 
 	/* Statistics */
 	struct bcmasp_intf_stats64	stats64;
+	struct bcmasp_mib_counters	mib;
 
 	u32			wolopts;
 	u8			sopass[SOPASS_MAX];
diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c b/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c
index 59d853c2293c..fc47e27b148d 100644
--- a/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c
+++ b/drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #define pr_fmt(fmt)				"bcmasp_ethtool: " fmt
 
+#include <asm-generic/unaligned.h>
 #include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/platform_device.h>
@@ -8,6 +9,160 @@
 #include "bcmasp.h"
 #include "bcmasp_intf_defs.h"
 
+enum bcmasp_stat_type {
+	BCMASP_STAT_RX_EDPKT,
+	BCMASP_STAT_RX_CTRL,
+	BCMASP_STAT_RX_CTRL_PER_INTF,
+	BCMASP_STAT_SOFT,
+};
+
+struct bcmasp_stats {
+	char stat_string[ETH_GSTRING_LEN];
+	enum bcmasp_stat_type type;
+	u32 reg_offset;
+};
+
+#define STAT_BCMASP_SOFT_MIB(str) { \
+	.stat_string = str, \
+	.type = BCMASP_STAT_SOFT, \
+}
+
+#define STAT_BCMASP_OFFSET(str, _type, offset) { \
+	.stat_string = str, \
+	.type = _type, \
+	.reg_offset = offset, \
+}
+
+#define STAT_BCMASP_RX_EDPKT(str, offset) \
+	STAT_BCMASP_OFFSET(str, BCMASP_STAT_RX_EDPKT, offset)
+#define STAT_BCMASP_RX_CTRL(str, offset) \
+	STAT_BCMASP_OFFSET(str, BCMASP_STAT_RX_CTRL, offset)
+#define STAT_BCMASP_RX_CTRL_PER_INTF(str, offset) \
+	STAT_BCMASP_OFFSET(str, BCMASP_STAT_RX_CTRL_PER_INTF, offset)
+
+/* Must match the order of struct bcmasp_mib_counters */
+static const struct bcmasp_stats bcmasp_gstrings_stats[] = {
+	/* EDPKT counters */
+	STAT_BCMASP_RX_EDPKT("RX Time Stamp", ASP_EDPKT_RX_TS_COUNTER),
+	STAT_BCMASP_RX_EDPKT("RX PKT Count", ASP_EDPKT_RX_PKT_CNT),
+	STAT_BCMASP_RX_EDPKT("RX PKT Buffered", ASP_EDPKT_HDR_EXTR_CNT),
+	STAT_BCMASP_RX_EDPKT("RX PKT Pushed to DRAM", ASP_EDPKT_HDR_OUT_CNT),
+	/* ASP RX control */
+	STAT_BCMASP_RX_CTRL_PER_INTF("Frames From Unimac",
+				     ASP_RX_CTRL_UMAC_0_FRAME_COUNT),
+	STAT_BCMASP_RX_CTRL_PER_INTF("Frames From Port",
+				     ASP_RX_CTRL_FB_0_FRAME_COUNT),
+	STAT_BCMASP_RX_CTRL_PER_INTF("RX Buffer FIFO Depth",
+				     ASP_RX_CTRL_FB_RX_FIFO_DEPTH),
+	STAT_BCMASP_RX_CTRL("Frames Out(Buffer)",
+			    ASP_RX_CTRL_FB_OUT_FRAME_COUNT),
+	STAT_BCMASP_RX_CTRL("Frames Out(Filters)",
+			    ASP_RX_CTRL_FB_FILT_OUT_FRAME_COUNT),
+	/* Software maintained statistics */
+	STAT_BCMASP_SOFT_MIB("RX SKB Alloc Failed"),
+	STAT_BCMASP_SOFT_MIB("TX DMA Failed"),
+	STAT_BCMASP_SOFT_MIB("Multicast Filters Full"),
+	STAT_BCMASP_SOFT_MIB("Unicast Filters Full"),
+	STAT_BCMASP_SOFT_MIB("MDA Filters Combined"),
+	STAT_BCMASP_SOFT_MIB("Promisc Filter Set"),
+	STAT_BCMASP_SOFT_MIB("TX Realloc For Offload Failed"),
+	STAT_BCMASP_SOFT_MIB("Tx Realloc For Offload"),
+};
+
+#define BCMASP_STATS_LEN	ARRAY_SIZE(bcmasp_gstrings_stats)
+
+static u16 bcmasp_stat_fixup_offset(struct bcmasp_intf *intf,
+				    const struct bcmasp_stats *s)
+{
+	struct bcmasp_priv *priv = intf->parent;
+
+	if (!strcmp("Frames Out(Buffer)", s->stat_string))
+		return priv->hw_info->rx_ctrl_fb_out_frame_count;
+
+	if (!strcmp("Frames Out(Filters)", s->stat_string))
+		return priv->hw_info->rx_ctrl_fb_filt_out_frame_count;
+
+	if (!strcmp("RX Buffer FIFO Depth", s->stat_string))
+		return priv->hw_info->rx_ctrl_fb_rx_fifo_depth;
+
+	return s->reg_offset;
+}
+
+static int bcmasp_get_sset_count(struct net_device *dev, int string_set)
+{
+	switch (string_set) {
+	case ETH_SS_STATS:
+		return BCMASP_STATS_LEN;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static void bcmasp_get_strings(struct net_device *dev, u32 stringset,
+			       u8 *data)
+{
+	int i;
+
+	switch (stringset) {
+	case ETH_SS_STATS:
+		for (i = 0; i < BCMASP_STATS_LEN; i++) {
+			memcpy(data + i * ETH_GSTRING_LEN,
+			       bcmasp_gstrings_stats[i].stat_string,
+			       ETH_GSTRING_LEN);
+		}
+		break;
+	default:
+		return;
+	}
+}
+
+static void bcmasp_update_mib_counters(struct bcmasp_intf *intf)
+{
+	int i;
+
+	for (i = 0; i < BCMASP_STATS_LEN; i++) {
+		const struct bcmasp_stats *s;
+		u32 offset, val;
+		char *p;
+
+		s = &bcmasp_gstrings_stats[i];
+		offset = bcmasp_stat_fixup_offset(intf, s);
+		switch (s->type) {
+		case BCMASP_STAT_SOFT:
+			continue;
+		case BCMASP_STAT_RX_EDPKT:
+			val = rx_edpkt_core_rl(intf->parent, offset);
+			break;
+		case BCMASP_STAT_RX_CTRL:
+			val = rx_ctrl_core_rl(intf->parent, offset);
+			break;
+		case BCMASP_STAT_RX_CTRL_PER_INTF:
+			offset += sizeof(u32) * intf->port;
+			val = rx_ctrl_core_rl(intf->parent, offset);
+			break;
+		}
+		p = (char *)(&intf->mib) + (i * sizeof(u32));
+		put_unaligned(val, (u32 *)p);
+	}
+}
+
+static void bcmasp_get_ethtool_stats(struct net_device *dev,
+				     struct ethtool_stats *stats,
+				     u64 *data)
+{
+	struct bcmasp_intf *intf = netdev_priv(dev);
+	char *p;
+	int i;
+
+	if (netif_running(dev))
+		bcmasp_update_mib_counters(intf);
+
+	for (i = 0; i < BCMASP_STATS_LEN; i++) {
+		p = (char *)(&intf->mib) + (i * sizeof(u32));
+		data[i] = *(u32 *)p;
+	}
+}
+
 static void bcmasp_get_drvinfo(struct net_device *dev,
 			       struct ethtool_drvinfo *info)
 {
@@ -340,4 +495,7 @@ const struct ethtool_ops bcmasp_ethtool_ops = {
 	.get_eth_mac_stats	= bcmasp_get_eth_mac_stats,
 	.get_rmon_stats		= bcmasp_get_rmon_stats,
 	.get_eth_ctrl_stats	= bcmasp_get_eth_ctrl_stats,
+	.get_strings		= bcmasp_get_strings,
+	.get_ethtool_stats	= bcmasp_get_ethtool_stats,
+	.get_sset_count		= bcmasp_get_sset_count,
 };
diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
index 899cb06a3fde..e67e725633b4 100644
--- a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
+++ b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
@@ -105,6 +105,7 @@ static void bcmasp_set_rx_mode(struct net_device *dev)
 		netdev_for_each_mc_addr(ha, dev) {
 			ret = bcmasp_set_en_mda_filter(intf, ha->addr, mask);
 			if (ret) {
+				intf->mib.mc_filters_full_cnt++;
 				goto set_promisc;
 			}
 		}
@@ -113,6 +114,7 @@ static void bcmasp_set_rx_mode(struct net_device *dev)
 	netdev_for_each_uc_addr(ha, dev) {
 		ret = bcmasp_set_en_mda_filter(intf, ha->addr, mask);
 		if (ret) {
+			intf->mib.uc_filters_full_cnt++;
 			goto set_promisc;
 		}
 	}
@@ -122,6 +124,7 @@ static void bcmasp_set_rx_mode(struct net_device *dev)
 
 set_promisc:
 	bcmasp_set_promisc(intf, 1);
+	intf->mib.promisc_filters_cnt++;
 
 	/* disable all filters used by this port */
 	bcmasp_disable_all_filters(intf);
@@ -157,6 +160,7 @@ static struct sk_buff *bcmasp_csum_offload(struct net_device *dev,
 					   struct sk_buff *skb,
 					   bool *csum_hw)
 {
+	struct bcmasp_intf *intf = netdev_priv(dev);
 	u32 header = 0, header2 = 0, epkt = 0;
 	struct bcmasp_pkt_offload *offload;
 	unsigned int header_cnt = 0;
@@ -169,11 +173,13 @@ static struct sk_buff *bcmasp_csum_offload(struct net_device *dev,
 	if (unlikely(skb_headroom(skb) < sizeof(*offload))) {
 		new_skb = skb_realloc_headroom(skb, sizeof(*offload));
 		if (!new_skb) {
+			intf->mib.tx_realloc_offload_failed++;
 			goto help;
 		}
 
 		dev_consume_skb_any(skb);
 		skb = new_skb;
+		intf->mib.tx_realloc_offload++;
 	}
 
 	switch (skb->protocol) {
@@ -312,6 +318,7 @@ static netdev_tx_t bcmasp_xmit(struct sk_buff *skb, struct net_device *dev)
 		}
 
 		if (dma_mapping_error(kdev, mapping)) {
+			intf->mib.tx_dma_failed++;
 			spb_index = intf->tx_spb_index;
 			for (j = 0; j < i; j++) {
 				bcmasp_clean_txcb(intf, spb_index);
@@ -549,6 +556,7 @@ static int bcmasp_rx_poll(struct napi_struct *napi, int budget)
 			u64_stats_inc(&stats->rx_errors);
 			u64_stats_update_end(&stats->syncp);
 
+			intf->mib.alloc_rx_skb_failed++;
 			netif_warn(intf, rx_err, intf->ndev,
 				   "SKB alloc failed\n");
 			goto next;
-- 
2.7.4


Download attachment "smime.p7s" of type "application/pkcs7-signature" (4206 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ