Devicetree
 help / color / mirror / Atom feed
From: Jens Emil Schulz Ostergaard <jensemil.schulzostergaard@microchip.com>
To: <UNGLinuxDriver@microchip.com>, Andrew Lunn <andrew@lunn.ch>,
	"Vladimir Oltean" <olteanv@gmail.com>,
	"David S. Miller" <davem@davemloft.net>,
	"Eric Dumazet" <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>,
	"Paolo Abeni" <pabeni@redhat.com>,
	Simon Horman <horms@kernel.org>, Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Woojung Huh <woojung.huh@microchip.com>,
	"Russell King" <linux@armlinux.org.uk>,
	Steen Hegelund <Steen.Hegelund@microchip.com>,
	Daniel Machon <daniel.machon@microchip.com>
Cc: <linux-kernel@vger.kernel.org>, <netdev@vger.kernel.org>,
	<devicetree@vger.kernel.org>
Subject: Re: [PATCH net-next v11 9/9] net: dsa: lan9645x: add port statistics
Date: Wed, 19 Aug 2026 15:25:57 +0200	[thread overview]
Message-ID: <3e4122bb1493a92f6db61d313fc0627a639cbbd4.camel@microchip.com> (raw)
In-Reply-To: <20260805-dsa_lan9645x_switch_driver_base-v11-9-007ebc983a0a@microchip.com>

This is a reply to:
https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260805-dsa_lan9645x_switch_driver_base-v11-0-007ebc983a0a%40microchip.com?part=9

> --- Patch [9]: [PATCH net-next v11 9/9] net: dsa: lan9645x: add port statistics ---
> commit 237edd60065db45a5dc8339c001c3205645d61b0
> Author: Jens Emil Schulz Østergaard <jensemil.schulzostergaard@microchip.com>
>
> net: dsa: lan9645x: add port statistics
>
> This adds a new lan9645x_stats unit which exposes the per-port hardware
> counters through the DSA ethtool hooks and ndo_get_stats64.  Since the chip
> counters are 32 bit, a 64-bit software shadow is kept and refreshed by a
> delayed work every three seconds.  No Link: tags are present in the commit
> header.
>
> A few questions below.
>
> > diff --git a/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c
b/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c
> > index fc604edb309b9..6a14ba3661625 100644
> > --- a/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c
> > +++ b/drivers/net/dsa/microchip/lan9645x/lan9645x_main.c
>
> [ ... ]
>
> > @@ -800,6 +866,18 @@ static const struct dsa_switch_ops lan9645x_switch_ops = {
> >  	/* Multicast database */
> >  	.port_mdb_add			= lan9645x_mdb_add,
> >  	.port_mdb_del			= lan9645x_mdb_del,
> > +
> > +	/* Port statistics counters. */
> > +	.get_strings			= lan9645x_get_strings,
> > +	.get_ethtool_stats		= lan9645x_get_ethtool_stats,
> > +	.get_sset_count			= lan9645x_get_sset_count,
> > +	.get_eth_mac_stats		= lan9645x_get_eth_mac_stats,
> > +	.get_rmon_stats			= lan9645x_get_rmon_stats,
> > +	.get_stats64			= lan9645x_get_stats64,
> > +	.get_pause_stats		= lan9645x_get_pause_stats,
> > +	.get_mm_stats			= lan9645x_get_mm_stats,
>
> Discovered by: opus-5 · Missed by: sashiko-gemini
>
> Is .get_mm_stats reachable without a .get_mm implementation?  A grep over
> drivers/net/dsa/microchip/lan9645x/ finds only get_mm_stats, neither
> .get_mm nor .set_mm is provided.
>
> dsa_user_get_mm() refuses the request in that case:
>
> net/dsa/user.c:dsa_user_get_mm() {
> 	if (!ds->ops->get_mm)
> 		return -EOPNOTSUPP;
> 	...
> }
>
> and mm_prepare_data() leaves before ->get_mm_stats() is invoked:
>
> net/ethtool/mm.c:mm_prepare_data() {
> 	ret = ops->get_mm(dev, &data->state);
> 	if (ret)
> 		goto out_complete;
>
> 	if (ops->get_mm_stats && (req_base->flags & ETHTOOL_FLAG_STATS))
> 		ops->get_mm_stats(dev, &data->stats);
> 	...
> }
>
> So does lan9645x_stats_get_mm_stats() ever run, and does
> ethtool --show-mm --include-statistics just return -EOPNOTSUPP?
>
> The same missing .get_mm makes __ethtool_dev_mm_supported() always return
> false, and both stats_prepare_data() (net/ethtool/stats.c) and
> pause_prepare_data() (net/ethtool/pause.c) reject requests carrying
> src == EMAC or src == PMAC on that basis.  Does that leave the
> ETHTOOL_MAC_STATS_SRC_EMAC and ETHTOOL_MAC_STATS_SRC_PMAC branches of
> lan9645x_stats_get_eth_mac_stats(), lan9645x_stats_get_rmon_stats(),
> lan9645x_stats_get_pause_stats(), lan9645x_stats_get_eth_phy_stats() and
> lan9645x_stats_get_eth_ctrl_stats() unreachable as well, with only the
> default aggregate branch ever executing?
>

Yes, this is also correct. I will remove the mac merge related code until mac
merge itself lands in the driver.

> > +	.get_eth_phy_stats		= lan9645x_get_eth_phy_stats,
> > +	.get_eth_ctrl_stats		= lan9645x_get_eth_ctrl_stats,
> >  };
>
> [ ... ]
>
> > diff --git a/drivers/net/dsa/microchip/lan9645x/lan9645x_stats.c
b/drivers/net/dsa/microchip/lan9645x/lan9645x_stats.c
> > new file mode 100644
> > index 0000000000000..f9c4bcb308991
> > --- /dev/null
> > +++ b/drivers/net/dsa/microchip/lan9645x/lan9645x_stats.c
> > @@ -0,0 +1,935 @@
>
> [ ... ]
>
> > +void lan9645x_stats_get_stats64(struct lan9645x *lan9645x, int port,
> > +				struct rtnl_link_stats64 *stats)
> > +{
>
> [ ... ]
>
> > +	stats->rx_packets = c[SCNT_RX_SHORT] +
> > +			    c[SCNT_RX_FRAG] +
> > +			    c[SCNT_RX_JABBER] +
> > +			    c[SCNT_RX_SZ_64] +
> > +			    c[SCNT_RX_SZ_65_127] +
> > +			    c[SCNT_RX_SZ_128_255] +
> > +			    c[SCNT_RX_SZ_256_511] +
> > +			    c[SCNT_RX_SZ_512_1023] +
> > +			    c[SCNT_RX_SZ_1024_1526] +
> > +			    c[SCNT_RX_SZ_JUMBO] +
> > +			    c[SCNT_RX_LONG] +
> > +			    c[SCNT_RX_PMAC_SHORT] +
> > +			    c[SCNT_RX_PMAC_FRAG] +
> > +			    c[SCNT_RX_PMAC_JABBER] +
> > +			    c[SCNT_RX_PMAC_SZ_64] +
> > +			    c[SCNT_RX_PMAC_SZ_65_127] +
> > +			    c[SCNT_RX_PMAC_SZ_128_255] +
> > +			    c[SCNT_RX_PMAC_SZ_256_511] +
> > +			    c[SCNT_RX_PMAC_SZ_512_1023] +
> > +			    c[SCNT_RX_PMAC_SZ_1024_1526] +
> > +			    c[SCNT_RX_PMAC_SZ_JUMBO];
>
> Discovered by: opus-5 · Missed by: sashiko-gemini
>
> Is the missing c[SCNT_RX_PMAC_LONG] here intentional?  The eMAC oversize
> counter c[SCNT_RX_LONG] is summed into rx_packets, but the pMAC term list
> stops at SCNT_RX_PMAC_SZ_JUMBO.  The same asymmetry appears in
> stats->rx_dropped below, which also starts from c[SCNT_RX_LONG] alone.
>

Yes, this is a mistake, I will add it.

> Every other term in this function is paired, and rx_errors does include
> the pMAC counterpart:
>
> 	stats->rx_errors = c[SCNT_RX_SHORT] +
> 			   ...
> 			   c[SCNT_RX_PMAC_LONG];
>
> SCNT_RX_PMAC_LONG (offset 0x42) is present in
> lan9645x_port_stats_layout[] and is accumulated by
> __lan9645x_stats_view_idx_transfer(), so on a port running frame
> preemption, would oversize frames on the preemptible MAC show up in
> rx_errors while being absent from rx_packets and rx_dropped?
>
> > +
> > +	stats->multicast = c[SCNT_RX_MC] + c[SCNT_RX_PMAC_MC];
> > +
> > +	stats->rx_errors = c[SCNT_RX_SHORT] +
> > +			   c[SCNT_RX_FRAG] +
> > +			   c[SCNT_RX_JABBER] +
> > +			   c[SCNT_RX_CRC] +
> > +			   c[SCNT_RX_SYMBOL_ERR] +
> > +			   c[SCNT_RX_LONG] +
> > +			   c[SCNT_RX_PMAC_SHORT] +
> > +			   c[SCNT_RX_PMAC_FRAG] +
> > +			   c[SCNT_RX_PMAC_JABBER] +
> > +			   c[SCNT_RX_PMAC_CRC] +
> > +			   c[SCNT_RX_PMAC_SYMBOL_ERR] +
> > +			   c[SCNT_RX_PMAC_LONG];
> > +
> > +	stats->rx_dropped = c[SCNT_RX_LONG] +
> > +			    c[SCNT_DR_LOCAL] +
> > +			    c[SCNT_DR_TAIL] +
> > +			    c[SCNT_RX_CAT_DROP] +
>
> Discovered by: opus-5 · Missed by: sashiko-gemini
>
> Should one oversize frame be reported three times?  c[SCNT_RX_LONG] is
> added to rx_packets, to rx_errors and to rx_dropped, so a single frame
> appears in all three fields of ip -s link and /proc/net/dev.  The same
> applies, twice over, to c[SCNT_RX_SHORT], c[SCNT_RX_FRAG],
> c[SCNT_RX_JABBER] and their pMAC twins, which land in both rx_packets and
> rx_errors.
>
> The uAPI kernel-doc in include/uapi/linux/if_link.h describes these as
> distinct categories:
>
>  * @rx_packets: Number of good packets received by the interface.
>  * @rx_errors: Total number of bad packets received on this network device.
>  * @rx_dropped: Number of packets received but not processed, e.g. due to
>  *	lack of resources or unsupported protocol.
>
> and points length violations at @rx_length_errors, which this driver
> leaves at zero.
>
> For comparison, ocelot_port_get_stats64()
> (drivers/net/ethernet/mscc/ocelot_stats.c) does fold SHORTS, FRAGMENTS,
> JABBERS and LONGS into rx_packets, but it does not populate rx_errors at
> all and does not add RX_LONGS to rx_dropped.  Was RX_LONG in rx_dropped
> meant to be rx_length_errors instead?

I will add rx_length_errors, and move RX_LONG from rx_dropped to there.
>
> > +			    c[SCNT_RX_RED_PRIO_0] +
>
> [ ... ]
>
> > +			    c[SCNT_RX_RED_PRIO_7];
>
> [ ... ]
>
> > +void lan9645x_stats_init(struct lan9645x *lan9645x)
> > +{
> > +	struct lan9645x_stats *stats = lan9645x->stats;
> > +
> > +	queue_delayed_work(stats->queue, &stats->work,
> > +			   LAN9645X_STATS_CHECK_DELAY);
> > +}
>
> Discovered by: opus-5 · Missed by: sashiko-gemini
>
> Where does the software shadow and the hardware counter get a common
> baseline?
>
> lan9645x_stats_add_cnt() keeps the previous hardware value in the low half
> of the shadow and infers a wrap from it:
>
> 	if (val < (*cnt & U32_MAX))
> 		*cnt += (u64)1 << 32; /* value has wrapped */
>
> 	*cnt = (*cnt & ~(u64)U32_MAX) + val;
>
> vstat->cnts is devm_kcalloc()'d once in lan9645x_stats_alloc() during
> probe and never re-zeroed, and SYS_STAT_CFG.STAT_CLEAR_SHOT is defined in
> lan9645x_regs.h but never written.  lan9645x_stats_init() runs from
> lan9645x_setup() after lan9645x_reset_switch() has driven
> SYS_RESET_CFG.CORE_ENA=0 and run SYS_RAM_INIT, and it only re-arms the
> poll work.
>
> If the core reset does clear the counter RAM, then on a second .setup()
> of an already-probed instance (DSA tree teardown and re-setup, which the
> .setup/.teardown stats hooks appear written for) hardware restarts at 0
> while the shadow still holds the old values, so the first poll sees
> val = 0 < (*cnt & U32_MAX) for every non-zero counter and adds
> 4294967296 to each, permanently.
>
> If the reset does not clear them, an unbind/rebind starts with a zeroed
> shadow against non-zero hardware, so the fresh interface reports traffic
> it never saw.
>
> ocelot_init() clears the counters explicitly for the same block:
>
> drivers/net/ethernet/mscc/ocelot.c:ocelot_init() {
> 		/* Clear all counters (5 groups) */
> 		ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port) |
> 				     SYS_STAT_CFG_STAT_CLEAR_SHOT(0x7f),
> 			     SYS_STAT_CFG);
> }
>
> Would it make sense to clear the hardware counters and/or memset the
> shadow in lan9645x_stats_init() so the two always start together?
>

Yes I think this makes sense, I will add this.

> [ ... ]
>
> > diff --git a/drivers/net/dsa/microchip/lan9645x/lan9645x_stats.h
b/drivers/net/dsa/microchip/lan9645x/lan9645x_stats.h
> > new file mode 100644
> > index 0000000000000..cd5db16258a09
> > --- /dev/null
> > +++ b/drivers/net/dsa/microchip/lan9645x/lan9645x_stats.h
> > @@ -0,0 +1,279 @@
>
> [ ... ]
>
> > +/* Counter indices into stat layout structs */
> > +#define SCNT_FRER_SID_IN_PKT             0
> > +#define SCNT_ISDX_GREEN_OCT              1
>
> [ ... ]
>
> > +#define SCNT_SF_MATCHING_FRAMES_COUNT    0
>
> [ ... ]
>
> > +#define SCNT_ESDX_GREEN_OCT              0
>
> [ ... ]
>
> > +enum lan9645x_view_stat_type {
> > +	LAN9645X_STAT_PORTS = 0,
> > +	LAN9645X_STAT_ISDX,
> > +	LAN9645X_STAT_ESDX,
> > +	LAN9645X_STAT_SFID,
> > +
> > +	LAN9645X_STAT_NUM,
> > +};
>
> Discovered by: opus-5 · Missed by: sashiko-gemini
>
> This isn't a bug, but the ISDX, ESDX, SFID and FRER parts of this
> framework have no user in the patch.  A grep over
> drivers/net/dsa/microchip/lan9645x/ shows SCNT_ISDX_*, SCNT_SF_*,
> SCNT_ESDX_* and SCNT_FRER_SID_IN_PKT matching only in this header, and
> lan9645x_view_stat_cfgs[] populates just [LAN9645X_STAT_PORTS].
>
> lan9645x_stats_view_update() has PORTS as its only non-default case, so
> the loop in lan9645x_stats_update():
>
> 	for (int vtype = 0; vtype < LAN9645X_STAT_NUM; vtype++)
> 		lan9645x_stats_view_update(lan9645x, vtype);
>
> does three no-op iterations over zeroed view[] entries on every poll.
>
> Also, struct lan9645x_view_stats.name is only ever written
> (.name = "ports") and never read, and the back-pointer assignment
> vstat->stats = lan9645x->stats in lan9645x_view_stat_init() has no
> reader.  Since the commit message only describes adding "statistics
> support for the port counters", could the unused infrastructure be
> dropped until the view that needs it lands?
>

Yes I will remove the unused views and fields.

> [ ... ]


  reply	other threads:[~2026-08-19 13:26 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-05 14:34 [PATCH net-next v11 0/9] net: dsa: add DSA support for the LAN9645x switch chip family Jens Emil Schulz Østergaard
2026-08-05 14:34 ` [PATCH net-next v11 1/9] net: dsa: add tag driver for LAN9645X Jens Emil Schulz Østergaard
2026-08-06 14:38   ` sashiko-bot
2026-08-07 14:41     ` JensEmil.SchulzOstergaard
2026-08-11 10:55       ` Paolo Abeni
2026-08-11 11:50         ` JensEmil.SchulzOstergaard
2026-08-17 14:18   ` Jens Emil Schulz Ostergaard
2026-08-05 14:34 ` [PATCH net-next v11 2/9] dt-bindings: net: lan9645x: add LAN9645X switch bindings Jens Emil Schulz Østergaard
2026-08-06 14:38   ` sashiko-bot
2026-08-07 14:15     ` JensEmil.SchulzOstergaard
2026-08-17 14:21   ` Jens Emil Schulz Ostergaard
2026-08-05 14:34 ` [PATCH net-next v11 3/9] net: dsa: lan9645x: add autogenerated register macros Jens Emil Schulz Østergaard
2026-08-05 14:34 ` [PATCH net-next v11 4/9] net: dsa: lan9645x: add basic dsa driver for LAN9645X Jens Emil Schulz Østergaard
2026-08-06 14:38   ` sashiko-bot
2026-08-07 14:07     ` JensEmil.SchulzOstergaard
2026-08-17 14:25   ` Jens Emil Schulz Ostergaard
2026-08-05 14:34 ` [PATCH net-next v11 5/9] net: dsa: lan9645x: add bridge support Jens Emil Schulz Østergaard
2026-08-06 14:38   ` sashiko-bot
2026-08-07 13:44     ` JensEmil.SchulzOstergaard
2026-08-17 14:31   ` Jens Emil Schulz Ostergaard
2026-08-05 14:34 ` [PATCH net-next v11 6/9] net: dsa: lan9645x: add vlan support Jens Emil Schulz Østergaard
2026-08-06 14:38   ` sashiko-bot
2026-08-07 13:40     ` JensEmil.SchulzOstergaard
2026-08-11 10:32   ` Paolo Abeni
2026-08-11 12:12     ` Jens Emil Schulz Ostergaard
2026-08-05 14:34 ` [PATCH net-next v11 7/9] net: dsa: lan9645x: add mac table integration Jens Emil Schulz Østergaard
2026-08-19 13:16   ` Jens Emil Schulz Ostergaard
2026-08-05 14:34 ` [PATCH net-next v11 8/9] net: dsa: lan9645x: add mdb management Jens Emil Schulz Østergaard
2026-08-06 14:38   ` sashiko-bot
2026-08-07 13:22     ` JensEmil.SchulzOstergaard
2026-08-19 13:22   ` Jens Emil Schulz Ostergaard
2026-08-05 14:34 ` [PATCH net-next v11 9/9] net: dsa: lan9645x: add port statistics Jens Emil Schulz Østergaard
2026-08-19 13:25   ` Jens Emil Schulz Ostergaard [this message]
2026-08-11 10:35 ` [PATCH net-next v11 0/9] net: dsa: add DSA support for the LAN9645x switch chip family Paolo Abeni
2026-08-11 10:36   ` Paolo Abeni
2026-08-11 12:18   ` Jens Emil Schulz Ostergaard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3e4122bb1493a92f6db61d313fc0627a639cbbd4.camel@microchip.com \
    --to=jensemil.schulzostergaard@microchip.com \
    --cc=Steen.Hegelund@microchip.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=andrew@lunn.ch \
    --cc=conor+dt@kernel.org \
    --cc=daniel.machon@microchip.com \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=pabeni@redhat.com \
    --cc=robh@kernel.org \
    --cc=woojung.huh@microchip.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox