Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH iproute2]rdma: modify the command output message of rdma statistic help based on man manual
From: Leon Romanovsky @ 2022-08-16 13:49 UTC (permalink / raw)
  To: jiangheng; +Cc: netdev
In-Reply-To: <25ce8a4f.6db0.182910b625a.Coremail.15720603159@163.com>

On Fri, Aug 12, 2022 at 03:53:38PM +0800, jiangheng wrote:
> 
> From 4ce8d60f34c5cdcff8b25e3c3891fc053736225b Mon Sep 17 00:00:00 2001
> From: jinag <jinag12138@gmail.com>
> Date: Fri, 12 Aug 2022 15:48:07 +0800
> Subject: [PATCH] rdma: modify the command output message of rdma statistic help
>  based on man manual
> 
> 
> ---
>  rdma/stat.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

iproute2 follows kernel coding style, both in the code
and in the patches. Please follow it.

Thanks

> 
> 
> diff --git a/rdma/stat.c b/rdma/stat.c
> index aad8815c..1e869c25 100644
> --- a/rdma/stat.c
> +++ b/rdma/stat.c
> @@ -24,10 +24,10 @@ static int stat_help(struct rd *rd)
>     pr_out("       %s statistic mode [ supported ] link [ DEV/PORT_INDEX ]\n", rd->filename);
>     pr_out("       %s statistic set link [ DEV/PORT_INDEX ] optional-counters [ OPTIONAL-COUNTERS ]\n", rd->filename);
>     pr_out("       %s statistic unset link [ DEV/PORT_INDEX ] optional-counters\n", rd->filename);
> -   pr_out("where  OBJECT: = { qp }\n");
> -   pr_out("       CRITERIA : = { type }\n");
> +   pr_out("where  OBJECT: = { qp | mr }\n");
> +   pr_out("       CRITERIA : = { type | pid }\n");
>     pr_out("       COUNTER_SCOPE: = { link | dev }\n");
> -   pr_out("       FILTER_NAME: = { cntn | lqpn | pid }\n");
> +   pr_out("       FILTER_NAME: = { cntn | lqpn | pid | qp_type }\n");
>     pr_out("Examples:\n");
>     pr_out("       %s statistic qp show\n", rd->filename);
>     pr_out("       %s statistic qp show link mlx5_2/1\n", rd->filename);
> --
> 2.23.0

^ permalink raw reply

* [PATCH net 0/8] Fixes for Ocelot driver statistics
From: Vladimir Oltean @ 2022-08-16 13:53 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Claudiu Manoil,
	Alexandre Belloni, UNGLinuxDriver, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Colin Foster, Maxim Kochetkov

This series contains bug fixes for the ocelot drivers (both switchdev
and DSA). Some concern the counters exposed to ethtool -S, and others to
the counters exposed to ifconfig. I'm aware that the changes are fairly
large, but I wanted to prioritize on a proper approach to addressing the
issues rather than a quick hack.

Some of the noticed problems:
- bad register offsets for some counters
- unhandled concurrency leading to corrupted counters
- unhandled 32-bit wraparound of ifconfig counters

The issues on the ocelot switchdev driver were noticed through code
inspection, I do not have the hardware to test.

This patch set necessarily converts ocelot->stats_lock from a mutex to a
spinlock. I know this affects Colin Foster's development with the SPI
controlled VSC7512. I have other changes prepared for net-next that
convert this back into a mutex (along with other changes in this area).

Vladimir Oltean (8):
  net: dsa: felix: fix ethtool 256-511 and 512-1023 TX packet counters
  net: mscc: ocelot: fix incorrect ndo_get_stats64 packet counters
  net: mscc: ocelot: fix address of SYS_COUNT_TX_AGING counter
  net: mscc: ocelot: turn stats_lock into a spinlock
  net: mscc: ocelot: fix race between ndo_get_stats64 and
    ocelot_check_stats_work
  net: mscc: ocelot: make struct ocelot_stat_layout array indexable
  net: mscc: ocelot: keep ocelot_stat_layout by reg address, not offset
  net: mscc: ocelot: report ndo_get_stats64 from the
    wraparound-resistant ocelot->stats

 drivers/net/dsa/ocelot/felix_vsc9959.c     | 558 +++++++++++++++++----
 drivers/net/dsa/ocelot/seville_vsc9953.c   | 553 ++++++++++++++++----
 drivers/net/ethernet/mscc/ocelot.c         |  62 ++-
 drivers/net/ethernet/mscc/ocelot_net.c     |  55 +-
 drivers/net/ethernet/mscc/ocelot_vsc7514.c | 468 +++++++++++++----
 drivers/net/ethernet/mscc/vsc7514_regs.c   |  84 +++-
 include/soc/mscc/ocelot.h                  | 179 ++++++-
 7 files changed, 1581 insertions(+), 378 deletions(-)

-- 
2.34.1


^ permalink raw reply

* [PATCH net 1/8] net: dsa: felix: fix ethtool 256-511 and 512-1023 TX packet counters
From: Vladimir Oltean @ 2022-08-16 13:53 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Claudiu Manoil,
	Alexandre Belloni, UNGLinuxDriver, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Colin Foster, Maxim Kochetkov
In-Reply-To: <20220816135352.1431497-1-vladimir.oltean@nxp.com>

What the driver actually reports as 256-511 is in fact 512-1023, and the
TX packets in the 256-511 bucket are not reported. Fix that.

Fixes: 56051948773e ("net: dsa: ocelot: add driver for Felix switch family")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/dsa/ocelot/felix_vsc9959.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index b4034b78c0ca..5859ef3b242c 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -602,7 +602,8 @@ static const struct ocelot_stat_layout vsc9959_stats_layout[] = {
 	{ .offset = 0x87,	.name = "tx_frames_below_65_octets", },
 	{ .offset = 0x88,	.name = "tx_frames_65_to_127_octets", },
 	{ .offset = 0x89,	.name = "tx_frames_128_255_octets", },
-	{ .offset = 0x8B,	.name = "tx_frames_256_511_octets", },
+	{ .offset = 0x8A,	.name = "tx_frames_256_511_octets", },
+	{ .offset = 0x8B,	.name = "tx_frames_512_1023_octets", },
 	{ .offset = 0x8C,	.name = "tx_frames_1024_1526_octets", },
 	{ .offset = 0x8D,	.name = "tx_frames_over_1526_octets", },
 	{ .offset = 0x8E,	.name = "tx_yellow_prio_0", },
-- 
2.34.1


^ permalink raw reply related

* [PATCH net 4/8] net: mscc: ocelot: turn stats_lock into a spinlock
From: Vladimir Oltean @ 2022-08-16 13:53 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Claudiu Manoil,
	Alexandre Belloni, UNGLinuxDriver, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Colin Foster, Maxim Kochetkov
In-Reply-To: <20220816135352.1431497-1-vladimir.oltean@nxp.com>

ocelot_get_stats64() currently runs unlocked and therefore may collide
with ocelot_port_update_stats() which indirectly accesses the same
counters. However, ocelot_get_stats64() runs in atomic context, and we
cannot simply take the sleepable ocelot->stats_lock mutex. We need to
convert it to an atomic spinlock first. Do that as a preparatory change.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/dsa/ocelot/felix_vsc9959.c |  4 ++--
 drivers/net/ethernet/mscc/ocelot.c     | 11 +++++------
 include/soc/mscc/ocelot.h              |  2 +-
 3 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index e1ebe21cad00..46fd6cd0d8f3 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -2171,7 +2171,7 @@ static void vsc9959_psfp_sgi_table_del(struct ocelot *ocelot,
 static void vsc9959_psfp_counters_get(struct ocelot *ocelot, u32 index,
 				      struct felix_stream_filter_counters *counters)
 {
-	mutex_lock(&ocelot->stats_lock);
+	spin_lock(&ocelot->stats_lock);
 
 	ocelot_rmw(ocelot, SYS_STAT_CFG_STAT_VIEW(index),
 		   SYS_STAT_CFG_STAT_VIEW_M,
@@ -2188,7 +2188,7 @@ static void vsc9959_psfp_counters_get(struct ocelot *ocelot, u32 index,
 		     SYS_STAT_CFG_STAT_CLEAR_SHOT(0x10),
 		     SYS_STAT_CFG);
 
-	mutex_unlock(&ocelot->stats_lock);
+	spin_unlock(&ocelot->stats_lock);
 }
 
 static int vsc9959_psfp_filter_add(struct ocelot *ocelot, int port,
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index d4649e4ee0e7..c67f162f8ab5 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1906,13 +1906,13 @@ static void ocelot_check_stats_work(struct work_struct *work)
 					     stats_work);
 	int i, err;
 
-	mutex_lock(&ocelot->stats_lock);
+	spin_lock(&ocelot->stats_lock);
 	for (i = 0; i < ocelot->num_phys_ports; i++) {
 		err = ocelot_port_update_stats(ocelot, i);
 		if (err)
 			break;
 	}
-	mutex_unlock(&ocelot->stats_lock);
+	spin_unlock(&ocelot->stats_lock);
 
 	if (err)
 		dev_err(ocelot->dev, "Error %d updating ethtool stats\n",  err);
@@ -1925,7 +1925,7 @@ void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data)
 {
 	int i, err;
 
-	mutex_lock(&ocelot->stats_lock);
+	spin_lock(&ocelot->stats_lock);
 
 	/* check and update now */
 	err = ocelot_port_update_stats(ocelot, port);
@@ -1934,7 +1934,7 @@ void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data)
 	for (i = 0; i < ocelot->num_stats; i++)
 		*data++ = ocelot->stats[port * ocelot->num_stats + i];
 
-	mutex_unlock(&ocelot->stats_lock);
+	spin_unlock(&ocelot->stats_lock);
 
 	if (err)
 		dev_err(ocelot->dev, "Error %d updating ethtool stats\n", err);
@@ -3363,7 +3363,7 @@ int ocelot_init(struct ocelot *ocelot)
 	if (!ocelot->stats)
 		return -ENOMEM;
 
-	mutex_init(&ocelot->stats_lock);
+	spin_lock_init(&ocelot->stats_lock);
 	mutex_init(&ocelot->ptp_lock);
 	mutex_init(&ocelot->mact_lock);
 	mutex_init(&ocelot->fwd_domain_lock);
@@ -3511,7 +3511,6 @@ void ocelot_deinit(struct ocelot *ocelot)
 	cancel_delayed_work(&ocelot->stats_work);
 	destroy_workqueue(ocelot->stats_queue);
 	destroy_workqueue(ocelot->owq);
-	mutex_destroy(&ocelot->stats_lock);
 }
 EXPORT_SYMBOL(ocelot_deinit);
 
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index e7e5b06deb2d..72b9474391da 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -752,7 +752,7 @@ struct ocelot {
 	struct ocelot_psfp_list		psfp;
 
 	/* Workqueue to check statistics for overflow with its lock */
-	struct mutex			stats_lock;
+	spinlock_t			stats_lock;
 	u64				*stats;
 	struct delayed_work		stats_work;
 	struct workqueue_struct		*stats_queue;
-- 
2.34.1


^ permalink raw reply related

* [PATCH net 2/8] net: mscc: ocelot: fix incorrect ndo_get_stats64 packet counters
From: Vladimir Oltean @ 2022-08-16 13:53 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Claudiu Manoil,
	Alexandre Belloni, UNGLinuxDriver, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Colin Foster, Maxim Kochetkov
In-Reply-To: <20220816135352.1431497-1-vladimir.oltean@nxp.com>

Reading stats using the SYS_COUNT_* register definitions is only used by
ocelot_get_stats64() from the ocelot switchdev driver, however,
currently the bucket definitions are incorrect.

Separately, on both RX and TX, we have the following problems:
- a 256-1023 bucket which actually tracks the 256-511 packets
- the 1024-1526 bucket actually tracks the 512-1023 packets
- the 1527-max bucket actually tracks the 1024-1526 packets

=> nobody tracks the packets from the real 1527-max bucket

Additionally, the RX_PAUSE, RX_CONTROL, RX_LONGS and RX_CLASSIFIED_DROPS
all track the wrong thing. However this doesn't seem to have any
consequence, since ocelot_get_stats64() doesn't use these.

Even though this problem only manifests itself for the switchdev driver,
we cannot split the fix for ocelot and for DSA, since it requires fixing
the bucket definitions from enum ocelot_reg, which makes us necessarily
adapt the structures from felix and seville as well.

Fixes: 84705fc16552 ("net: dsa: felix: introduce support for Seville VSC9953 switch")
Fixes: 56051948773e ("net: dsa: ocelot: add driver for Felix switch family")
Fixes: a556c76adc05 ("net: mscc: Add initial Ocelot switch support")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/dsa/ocelot/felix_vsc9959.c   | 20 ++++++++++++--------
 drivers/net/dsa/ocelot/seville_vsc9953.c | 16 +++++++++-------
 drivers/net/ethernet/mscc/ocelot_net.c   |  6 ++++--
 drivers/net/ethernet/mscc/vsc7514_regs.c | 24 +++++++++++++-----------
 include/soc/mscc/ocelot.h                |  6 ++++--
 5 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index 5859ef3b242c..e1ebe21cad00 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -281,19 +281,23 @@ static const u32 vsc9959_sys_regmap[] = {
 	REG(SYS_COUNT_RX_64,			0x000024),
 	REG(SYS_COUNT_RX_65_127,		0x000028),
 	REG(SYS_COUNT_RX_128_255,		0x00002c),
-	REG(SYS_COUNT_RX_256_1023,		0x000030),
-	REG(SYS_COUNT_RX_1024_1526,		0x000034),
-	REG(SYS_COUNT_RX_1527_MAX,		0x000038),
-	REG(SYS_COUNT_RX_LONGS,			0x000044),
+	REG(SYS_COUNT_RX_256_511,		0x000030),
+	REG(SYS_COUNT_RX_512_1023,		0x000034),
+	REG(SYS_COUNT_RX_1024_1526,		0x000038),
+	REG(SYS_COUNT_RX_1527_MAX,		0x00003c),
+	REG(SYS_COUNT_RX_PAUSE,			0x000040),
+	REG(SYS_COUNT_RX_CONTROL,		0x000044),
+	REG(SYS_COUNT_RX_LONGS,			0x000048),
 	REG(SYS_COUNT_TX_OCTETS,		0x000200),
 	REG(SYS_COUNT_TX_COLLISION,		0x000210),
 	REG(SYS_COUNT_TX_DROPS,			0x000214),
 	REG(SYS_COUNT_TX_64,			0x00021c),
 	REG(SYS_COUNT_TX_65_127,		0x000220),
-	REG(SYS_COUNT_TX_128_511,		0x000224),
-	REG(SYS_COUNT_TX_512_1023,		0x000228),
-	REG(SYS_COUNT_TX_1024_1526,		0x00022c),
-	REG(SYS_COUNT_TX_1527_MAX,		0x000230),
+	REG(SYS_COUNT_TX_128_255,		0x000224),
+	REG(SYS_COUNT_TX_256_511,		0x000228),
+	REG(SYS_COUNT_TX_512_1023,		0x00022c),
+	REG(SYS_COUNT_TX_1024_1526,		0x000230),
+	REG(SYS_COUNT_TX_1527_MAX,		0x000234),
 	REG(SYS_COUNT_TX_AGING,			0x000278),
 	REG(SYS_RESET_CFG,			0x000e00),
 	REG(SYS_SR_ETYPE_CFG,			0x000e04),
diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
index ea0649211356..ebe9ddbbe2b7 100644
--- a/drivers/net/dsa/ocelot/seville_vsc9953.c
+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
@@ -277,19 +277,21 @@ static const u32 vsc9953_sys_regmap[] = {
 	REG(SYS_COUNT_RX_64,			0x000024),
 	REG(SYS_COUNT_RX_65_127,		0x000028),
 	REG(SYS_COUNT_RX_128_255,		0x00002c),
-	REG(SYS_COUNT_RX_256_1023,		0x000030),
-	REG(SYS_COUNT_RX_1024_1526,		0x000034),
-	REG(SYS_COUNT_RX_1527_MAX,		0x000038),
+	REG(SYS_COUNT_RX_256_511,		0x000030),
+	REG(SYS_COUNT_RX_512_1023,		0x000034),
+	REG(SYS_COUNT_RX_1024_1526,		0x000038),
+	REG(SYS_COUNT_RX_1527_MAX,		0x00003c),
 	REG(SYS_COUNT_RX_LONGS,			0x000048),
 	REG(SYS_COUNT_TX_OCTETS,		0x000100),
 	REG(SYS_COUNT_TX_COLLISION,		0x000110),
 	REG(SYS_COUNT_TX_DROPS,			0x000114),
 	REG(SYS_COUNT_TX_64,			0x00011c),
 	REG(SYS_COUNT_TX_65_127,		0x000120),
-	REG(SYS_COUNT_TX_128_511,		0x000124),
-	REG(SYS_COUNT_TX_512_1023,		0x000128),
-	REG(SYS_COUNT_TX_1024_1526,		0x00012c),
-	REG(SYS_COUNT_TX_1527_MAX,		0x000130),
+	REG(SYS_COUNT_TX_128_255,		0x000124),
+	REG(SYS_COUNT_TX_256_511,		0x000128),
+	REG(SYS_COUNT_TX_512_1023,		0x00012c),
+	REG(SYS_COUNT_TX_1024_1526,		0x000130),
+	REG(SYS_COUNT_TX_1527_MAX,		0x000134),
 	REG(SYS_COUNT_TX_AGING,			0x000178),
 	REG(SYS_RESET_CFG,			0x000318),
 	REG_RESERVED(SYS_SR_ETYPE_CFG),
diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
index 5e6136e80282..9d8cea16245e 100644
--- a/drivers/net/ethernet/mscc/ocelot_net.c
+++ b/drivers/net/ethernet/mscc/ocelot_net.c
@@ -739,7 +739,8 @@ static void ocelot_get_stats64(struct net_device *dev,
 			    ocelot_read(ocelot, SYS_COUNT_RX_64) +
 			    ocelot_read(ocelot, SYS_COUNT_RX_65_127) +
 			    ocelot_read(ocelot, SYS_COUNT_RX_128_255) +
-			    ocelot_read(ocelot, SYS_COUNT_RX_256_1023) +
+			    ocelot_read(ocelot, SYS_COUNT_RX_256_511) +
+			    ocelot_read(ocelot, SYS_COUNT_RX_512_1023) +
 			    ocelot_read(ocelot, SYS_COUNT_RX_1024_1526) +
 			    ocelot_read(ocelot, SYS_COUNT_RX_1527_MAX);
 	stats->multicast = ocelot_read(ocelot, SYS_COUNT_RX_MULTICAST);
@@ -749,7 +750,8 @@ static void ocelot_get_stats64(struct net_device *dev,
 	stats->tx_bytes = ocelot_read(ocelot, SYS_COUNT_TX_OCTETS);
 	stats->tx_packets = ocelot_read(ocelot, SYS_COUNT_TX_64) +
 			    ocelot_read(ocelot, SYS_COUNT_TX_65_127) +
-			    ocelot_read(ocelot, SYS_COUNT_TX_128_511) +
+			    ocelot_read(ocelot, SYS_COUNT_TX_128_255) +
+			    ocelot_read(ocelot, SYS_COUNT_TX_256_511) +
 			    ocelot_read(ocelot, SYS_COUNT_TX_512_1023) +
 			    ocelot_read(ocelot, SYS_COUNT_TX_1024_1526) +
 			    ocelot_read(ocelot, SYS_COUNT_TX_1527_MAX);
diff --git a/drivers/net/ethernet/mscc/vsc7514_regs.c b/drivers/net/ethernet/mscc/vsc7514_regs.c
index c2af4eb8ca5d..38ab20b48cd4 100644
--- a/drivers/net/ethernet/mscc/vsc7514_regs.c
+++ b/drivers/net/ethernet/mscc/vsc7514_regs.c
@@ -180,13 +180,14 @@ const u32 vsc7514_sys_regmap[] = {
 	REG(SYS_COUNT_RX_64,				0x000024),
 	REG(SYS_COUNT_RX_65_127,			0x000028),
 	REG(SYS_COUNT_RX_128_255,			0x00002c),
-	REG(SYS_COUNT_RX_256_1023,			0x000030),
-	REG(SYS_COUNT_RX_1024_1526,			0x000034),
-	REG(SYS_COUNT_RX_1527_MAX,			0x000038),
-	REG(SYS_COUNT_RX_PAUSE,				0x00003c),
-	REG(SYS_COUNT_RX_CONTROL,			0x000040),
-	REG(SYS_COUNT_RX_LONGS,				0x000044),
-	REG(SYS_COUNT_RX_CLASSIFIED_DROPS,		0x000048),
+	REG(SYS_COUNT_RX_256_511,			0x000030),
+	REG(SYS_COUNT_RX_512_1023,			0x000034),
+	REG(SYS_COUNT_RX_1024_1526,			0x000038),
+	REG(SYS_COUNT_RX_1527_MAX,			0x00003c),
+	REG(SYS_COUNT_RX_PAUSE,				0x000040),
+	REG(SYS_COUNT_RX_CONTROL,			0x000044),
+	REG(SYS_COUNT_RX_LONGS,				0x000048),
+	REG(SYS_COUNT_RX_CLASSIFIED_DROPS,		0x00004c),
 	REG(SYS_COUNT_TX_OCTETS,			0x000100),
 	REG(SYS_COUNT_TX_UNICAST,			0x000104),
 	REG(SYS_COUNT_TX_MULTICAST,			0x000108),
@@ -196,10 +197,11 @@ const u32 vsc7514_sys_regmap[] = {
 	REG(SYS_COUNT_TX_PAUSE,				0x000118),
 	REG(SYS_COUNT_TX_64,				0x00011c),
 	REG(SYS_COUNT_TX_65_127,			0x000120),
-	REG(SYS_COUNT_TX_128_511,			0x000124),
-	REG(SYS_COUNT_TX_512_1023,			0x000128),
-	REG(SYS_COUNT_TX_1024_1526,			0x00012c),
-	REG(SYS_COUNT_TX_1527_MAX,			0x000130),
+	REG(SYS_COUNT_TX_128_255,			0x000124),
+	REG(SYS_COUNT_TX_256_511,			0x000128),
+	REG(SYS_COUNT_TX_512_1023,			0x00012c),
+	REG(SYS_COUNT_TX_1024_1526,			0x000130),
+	REG(SYS_COUNT_TX_1527_MAX,			0x000134),
 	REG(SYS_COUNT_TX_AGING,				0x000170),
 	REG(SYS_RESET_CFG,				0x000508),
 	REG(SYS_CMID,					0x00050c),
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index ac151ecc7f19..e7e5b06deb2d 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -335,7 +335,8 @@ enum ocelot_reg {
 	SYS_COUNT_RX_64,
 	SYS_COUNT_RX_65_127,
 	SYS_COUNT_RX_128_255,
-	SYS_COUNT_RX_256_1023,
+	SYS_COUNT_RX_256_511,
+	SYS_COUNT_RX_512_1023,
 	SYS_COUNT_RX_1024_1526,
 	SYS_COUNT_RX_1527_MAX,
 	SYS_COUNT_RX_PAUSE,
@@ -351,7 +352,8 @@ enum ocelot_reg {
 	SYS_COUNT_TX_PAUSE,
 	SYS_COUNT_TX_64,
 	SYS_COUNT_TX_65_127,
-	SYS_COUNT_TX_128_511,
+	SYS_COUNT_TX_128_255,
+	SYS_COUNT_TX_256_511,
 	SYS_COUNT_TX_512_1023,
 	SYS_COUNT_TX_1024_1526,
 	SYS_COUNT_TX_1527_MAX,
-- 
2.34.1


^ permalink raw reply related

* [PATCH net 5/8] net: mscc: ocelot: fix race between ndo_get_stats64 and ocelot_check_stats_work
From: Vladimir Oltean @ 2022-08-16 13:53 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Claudiu Manoil,
	Alexandre Belloni, UNGLinuxDriver, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Colin Foster, Maxim Kochetkov
In-Reply-To: <20220816135352.1431497-1-vladimir.oltean@nxp.com>

The 2 methods can run concurrently, and one will change the window of
counters (SYS_STAT_CFG_STAT_VIEW) that the other sees. The fix is
similar to what commit 7fbf6795d127 ("net: mscc: ocelot: fix mutex lock
error during ethtool stats read") has done for ethtool -S.

Fixes: a556c76adc05 ("net: mscc: Add initial Ocelot switch support")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/ethernet/mscc/ocelot_net.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
index 9d8cea16245e..6b9d37138844 100644
--- a/drivers/net/ethernet/mscc/ocelot_net.c
+++ b/drivers/net/ethernet/mscc/ocelot_net.c
@@ -726,6 +726,8 @@ static void ocelot_get_stats64(struct net_device *dev,
 	struct ocelot *ocelot = priv->port.ocelot;
 	int port = priv->port.index;
 
+	spin_lock(&ocelot->stats_lock);
+
 	/* Configure the port to read the stats from */
 	ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port),
 		     SYS_STAT_CFG);
@@ -758,6 +760,8 @@ static void ocelot_get_stats64(struct net_device *dev,
 	stats->tx_dropped = ocelot_read(ocelot, SYS_COUNT_TX_DROPS) +
 			    ocelot_read(ocelot, SYS_COUNT_TX_AGING);
 	stats->collisions = ocelot_read(ocelot, SYS_COUNT_TX_COLLISION);
+
+	spin_unlock(&ocelot->stats_lock);
 }
 
 static int ocelot_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
-- 
2.34.1


^ permalink raw reply related

* [PATCH net 3/8] net: mscc: ocelot: fix address of SYS_COUNT_TX_AGING counter
From: Vladimir Oltean @ 2022-08-16 13:53 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Claudiu Manoil,
	Alexandre Belloni, UNGLinuxDriver, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Colin Foster, Maxim Kochetkov
In-Reply-To: <20220816135352.1431497-1-vladimir.oltean@nxp.com>

This register, used as part of stats->tx_dropped in
ocelot_get_stats64(), has a wrong address. At the address currently
given, there is actually the c_tx_green_prio_6 counter.

Fixes: a556c76adc05 ("net: mscc: Add initial Ocelot switch support")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/ethernet/mscc/vsc7514_regs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mscc/vsc7514_regs.c b/drivers/net/ethernet/mscc/vsc7514_regs.c
index 38ab20b48cd4..8ff935f7f150 100644
--- a/drivers/net/ethernet/mscc/vsc7514_regs.c
+++ b/drivers/net/ethernet/mscc/vsc7514_regs.c
@@ -202,7 +202,7 @@ const u32 vsc7514_sys_regmap[] = {
 	REG(SYS_COUNT_TX_512_1023,			0x00012c),
 	REG(SYS_COUNT_TX_1024_1526,			0x000130),
 	REG(SYS_COUNT_TX_1527_MAX,			0x000134),
-	REG(SYS_COUNT_TX_AGING,				0x000170),
+	REG(SYS_COUNT_TX_AGING,				0x000178),
 	REG(SYS_RESET_CFG,				0x000508),
 	REG(SYS_CMID,					0x00050c),
 	REG(SYS_VLAN_ETYPE_CFG,				0x000510),
-- 
2.34.1


^ permalink raw reply related

* [PATCH net 6/8] net: mscc: ocelot: make struct ocelot_stat_layout array indexable
From: Vladimir Oltean @ 2022-08-16 13:53 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Claudiu Manoil,
	Alexandre Belloni, UNGLinuxDriver, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Colin Foster, Maxim Kochetkov
In-Reply-To: <20220816135352.1431497-1-vladimir.oltean@nxp.com>

The ocelot counters are 32-bit and require periodic reading, every 2
seconds, by ocelot_port_update_stats(), so that wraparounds are
detected.

Currently, the counters reported by ocelot_get_stats64() come from the
32-bit hardware counters directly, rather than from the 64-bit
accumulated ocelot->stats, and this is a problem for their integrity.

The strategy is to make ocelot_get_stats64() able to cherry-pick
individual stats from ocelot->stats the way in which it currently reads
them out from SYS_COUNT_* registers. But currently it can't, because
ocelot->stats is an opaque u64 array that's used only to feed data into
ethtool -S.

To solve that problem, we need to make ocelot->stats indexable, and
associate each element with an element of struct ocelot_stat_layout used
by ethtool -S.

This makes ocelot_stat_layout a fat (and possibly sparse) array, so we
need to change the way in which we access it. We no longer need
OCELOT_STAT_END as a sentinel, because we know the array's size
(OCELOT_NUM_STATS). We just need to skip the array elements that were
left unpopulated for the switch revision (ocelot, felix, seville).

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/dsa/ocelot/felix_vsc9959.c     | 468 ++++++++++++++++-----
 drivers/net/dsa/ocelot/seville_vsc9953.c   | 468 ++++++++++++++++-----
 drivers/net/ethernet/mscc/ocelot.c         |  40 +-
 drivers/net/ethernet/mscc/ocelot_vsc7514.c | 468 ++++++++++++++++-----
 include/soc/mscc/ocelot.h                  | 105 ++++-
 5 files changed, 1243 insertions(+), 306 deletions(-)

diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index 46fd6cd0d8f3..c9f270f24b1c 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -551,101 +551,379 @@ static const struct reg_field vsc9959_regfields[REGFIELD_MAX] = {
 	[SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 7, 4),
 };
 
-static const struct ocelot_stat_layout vsc9959_stats_layout[] = {
-	{ .offset = 0x00,	.name = "rx_octets", },
-	{ .offset = 0x01,	.name = "rx_unicast", },
-	{ .offset = 0x02,	.name = "rx_multicast", },
-	{ .offset = 0x03,	.name = "rx_broadcast", },
-	{ .offset = 0x04,	.name = "rx_shorts", },
-	{ .offset = 0x05,	.name = "rx_fragments", },
-	{ .offset = 0x06,	.name = "rx_jabbers", },
-	{ .offset = 0x07,	.name = "rx_crc_align_errs", },
-	{ .offset = 0x08,	.name = "rx_sym_errs", },
-	{ .offset = 0x09,	.name = "rx_frames_below_65_octets", },
-	{ .offset = 0x0A,	.name = "rx_frames_65_to_127_octets", },
-	{ .offset = 0x0B,	.name = "rx_frames_128_to_255_octets", },
-	{ .offset = 0x0C,	.name = "rx_frames_256_to_511_octets", },
-	{ .offset = 0x0D,	.name = "rx_frames_512_to_1023_octets", },
-	{ .offset = 0x0E,	.name = "rx_frames_1024_to_1526_octets", },
-	{ .offset = 0x0F,	.name = "rx_frames_over_1526_octets", },
-	{ .offset = 0x10,	.name = "rx_pause", },
-	{ .offset = 0x11,	.name = "rx_control", },
-	{ .offset = 0x12,	.name = "rx_longs", },
-	{ .offset = 0x13,	.name = "rx_classified_drops", },
-	{ .offset = 0x14,	.name = "rx_red_prio_0", },
-	{ .offset = 0x15,	.name = "rx_red_prio_1", },
-	{ .offset = 0x16,	.name = "rx_red_prio_2", },
-	{ .offset = 0x17,	.name = "rx_red_prio_3", },
-	{ .offset = 0x18,	.name = "rx_red_prio_4", },
-	{ .offset = 0x19,	.name = "rx_red_prio_5", },
-	{ .offset = 0x1A,	.name = "rx_red_prio_6", },
-	{ .offset = 0x1B,	.name = "rx_red_prio_7", },
-	{ .offset = 0x1C,	.name = "rx_yellow_prio_0", },
-	{ .offset = 0x1D,	.name = "rx_yellow_prio_1", },
-	{ .offset = 0x1E,	.name = "rx_yellow_prio_2", },
-	{ .offset = 0x1F,	.name = "rx_yellow_prio_3", },
-	{ .offset = 0x20,	.name = "rx_yellow_prio_4", },
-	{ .offset = 0x21,	.name = "rx_yellow_prio_5", },
-	{ .offset = 0x22,	.name = "rx_yellow_prio_6", },
-	{ .offset = 0x23,	.name = "rx_yellow_prio_7", },
-	{ .offset = 0x24,	.name = "rx_green_prio_0", },
-	{ .offset = 0x25,	.name = "rx_green_prio_1", },
-	{ .offset = 0x26,	.name = "rx_green_prio_2", },
-	{ .offset = 0x27,	.name = "rx_green_prio_3", },
-	{ .offset = 0x28,	.name = "rx_green_prio_4", },
-	{ .offset = 0x29,	.name = "rx_green_prio_5", },
-	{ .offset = 0x2A,	.name = "rx_green_prio_6", },
-	{ .offset = 0x2B,	.name = "rx_green_prio_7", },
-	{ .offset = 0x80,	.name = "tx_octets", },
-	{ .offset = 0x81,	.name = "tx_unicast", },
-	{ .offset = 0x82,	.name = "tx_multicast", },
-	{ .offset = 0x83,	.name = "tx_broadcast", },
-	{ .offset = 0x84,	.name = "tx_collision", },
-	{ .offset = 0x85,	.name = "tx_drops", },
-	{ .offset = 0x86,	.name = "tx_pause", },
-	{ .offset = 0x87,	.name = "tx_frames_below_65_octets", },
-	{ .offset = 0x88,	.name = "tx_frames_65_to_127_octets", },
-	{ .offset = 0x89,	.name = "tx_frames_128_255_octets", },
-	{ .offset = 0x8A,	.name = "tx_frames_256_511_octets", },
-	{ .offset = 0x8B,	.name = "tx_frames_512_1023_octets", },
-	{ .offset = 0x8C,	.name = "tx_frames_1024_1526_octets", },
-	{ .offset = 0x8D,	.name = "tx_frames_over_1526_octets", },
-	{ .offset = 0x8E,	.name = "tx_yellow_prio_0", },
-	{ .offset = 0x8F,	.name = "tx_yellow_prio_1", },
-	{ .offset = 0x90,	.name = "tx_yellow_prio_2", },
-	{ .offset = 0x91,	.name = "tx_yellow_prio_3", },
-	{ .offset = 0x92,	.name = "tx_yellow_prio_4", },
-	{ .offset = 0x93,	.name = "tx_yellow_prio_5", },
-	{ .offset = 0x94,	.name = "tx_yellow_prio_6", },
-	{ .offset = 0x95,	.name = "tx_yellow_prio_7", },
-	{ .offset = 0x96,	.name = "tx_green_prio_0", },
-	{ .offset = 0x97,	.name = "tx_green_prio_1", },
-	{ .offset = 0x98,	.name = "tx_green_prio_2", },
-	{ .offset = 0x99,	.name = "tx_green_prio_3", },
-	{ .offset = 0x9A,	.name = "tx_green_prio_4", },
-	{ .offset = 0x9B,	.name = "tx_green_prio_5", },
-	{ .offset = 0x9C,	.name = "tx_green_prio_6", },
-	{ .offset = 0x9D,	.name = "tx_green_prio_7", },
-	{ .offset = 0x9E,	.name = "tx_aged", },
-	{ .offset = 0x100,	.name = "drop_local", },
-	{ .offset = 0x101,	.name = "drop_tail", },
-	{ .offset = 0x102,	.name = "drop_yellow_prio_0", },
-	{ .offset = 0x103,	.name = "drop_yellow_prio_1", },
-	{ .offset = 0x104,	.name = "drop_yellow_prio_2", },
-	{ .offset = 0x105,	.name = "drop_yellow_prio_3", },
-	{ .offset = 0x106,	.name = "drop_yellow_prio_4", },
-	{ .offset = 0x107,	.name = "drop_yellow_prio_5", },
-	{ .offset = 0x108,	.name = "drop_yellow_prio_6", },
-	{ .offset = 0x109,	.name = "drop_yellow_prio_7", },
-	{ .offset = 0x10A,	.name = "drop_green_prio_0", },
-	{ .offset = 0x10B,	.name = "drop_green_prio_1", },
-	{ .offset = 0x10C,	.name = "drop_green_prio_2", },
-	{ .offset = 0x10D,	.name = "drop_green_prio_3", },
-	{ .offset = 0x10E,	.name = "drop_green_prio_4", },
-	{ .offset = 0x10F,	.name = "drop_green_prio_5", },
-	{ .offset = 0x110,	.name = "drop_green_prio_6", },
-	{ .offset = 0x111,	.name = "drop_green_prio_7", },
-	OCELOT_STAT_END
+static const struct ocelot_stat_layout vsc9959_stats_layout[OCELOT_NUM_STATS] = {
+	[OCELOT_STAT_RX_OCTETS] = {
+		.name = "rx_octets",
+		.offset = 0x00,
+	},
+	[OCELOT_STAT_RX_UNICAST] = {
+		.name = "rx_unicast",
+		.offset = 0x01,
+	},
+	[OCELOT_STAT_RX_MULTICAST] = {
+		.name = "rx_multicast",
+		.offset = 0x02,
+	},
+	[OCELOT_STAT_RX_BROADCAST] = {
+		.name = "rx_broadcast",
+		.offset = 0x03,
+	},
+	[OCELOT_STAT_RX_SHORTS] = {
+		.name = "rx_shorts",
+		.offset = 0x04,
+	},
+	[OCELOT_STAT_RX_FRAGMENTS] = {
+		.name = "rx_fragments",
+		.offset = 0x05,
+	},
+	[OCELOT_STAT_RX_JABBERS] = {
+		.name = "rx_jabbers",
+		.offset = 0x06,
+	},
+	[OCELOT_STAT_RX_CRC_ALIGN_ERRS] = {
+		.name = "rx_crc_align_errs",
+		.offset = 0x07,
+	},
+	[OCELOT_STAT_RX_SYM_ERRS] = {
+		.name = "rx_sym_errs",
+		.offset = 0x08,
+	},
+	[OCELOT_STAT_RX_64] = {
+		.name = "rx_frames_below_65_octets",
+		.offset = 0x09,
+	},
+	[OCELOT_STAT_RX_65_127] = {
+		.name = "rx_frames_65_to_127_octets",
+		.offset = 0x0A,
+	},
+	[OCELOT_STAT_RX_128_255] = {
+		.name = "rx_frames_128_to_255_octets",
+		.offset = 0x0B,
+	},
+	[OCELOT_STAT_RX_256_511] = {
+		.name = "rx_frames_256_to_511_octets",
+		.offset = 0x0C,
+	},
+	[OCELOT_STAT_RX_512_1023] = {
+		.name = "rx_frames_512_to_1023_octets",
+		.offset = 0x0D,
+	},
+	[OCELOT_STAT_RX_1024_1526] = {
+		.name = "rx_frames_1024_to_1526_octets",
+		.offset = 0x0E,
+	},
+	[OCELOT_STAT_RX_1527_MAX] = {
+		.name = "rx_frames_over_1526_octets",
+		.offset = 0x0F,
+	},
+	[OCELOT_STAT_RX_PAUSE] = {
+		.name = "rx_pause",
+		.offset = 0x10,
+	},
+	[OCELOT_STAT_RX_CONTROL] = {
+		.name = "rx_control",
+		.offset = 0x11,
+	},
+	[OCELOT_STAT_RX_LONGS] = {
+		.name = "rx_longs",
+		.offset = 0x12,
+	},
+	[OCELOT_STAT_RX_CLASSIFIED_DROPS] = {
+		.name = "rx_classified_drops",
+		.offset = 0x13,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_0] = {
+		.name = "rx_red_prio_0",
+		.offset = 0x14,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_1] = {
+		.name = "rx_red_prio_1",
+		.offset = 0x15,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_2] = {
+		.name = "rx_red_prio_2",
+		.offset = 0x16,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_3] = {
+		.name = "rx_red_prio_3",
+		.offset = 0x17,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_4] = {
+		.name = "rx_red_prio_4",
+		.offset = 0x18,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_5] = {
+		.name = "rx_red_prio_5",
+		.offset = 0x19,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_6] = {
+		.name = "rx_red_prio_6",
+		.offset = 0x1A,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_7] = {
+		.name = "rx_red_prio_7",
+		.offset = 0x1B,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_0] = {
+		.name = "rx_yellow_prio_0",
+		.offset = 0x1C,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_1] = {
+		.name = "rx_yellow_prio_1",
+		.offset = 0x1D,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_2] = {
+		.name = "rx_yellow_prio_2",
+		.offset = 0x1E,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_3] = {
+		.name = "rx_yellow_prio_3",
+		.offset = 0x1F,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_4] = {
+		.name = "rx_yellow_prio_4",
+		.offset = 0x20,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_5] = {
+		.name = "rx_yellow_prio_5",
+		.offset = 0x21,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_6] = {
+		.name = "rx_yellow_prio_6",
+		.offset = 0x22,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_7] = {
+		.name = "rx_yellow_prio_7",
+		.offset = 0x23,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_0] = {
+		.name = "rx_green_prio_0",
+		.offset = 0x24,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_1] = {
+		.name = "rx_green_prio_1",
+		.offset = 0x25,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_2] = {
+		.name = "rx_green_prio_2",
+		.offset = 0x26,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_3] = {
+		.name = "rx_green_prio_3",
+		.offset = 0x27,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_4] = {
+		.name = "rx_green_prio_4",
+		.offset = 0x28,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_5] = {
+		.name = "rx_green_prio_5",
+		.offset = 0x29,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_6] = {
+		.name = "rx_green_prio_6",
+		.offset = 0x2A,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_7] = {
+		.name = "rx_green_prio_7",
+		.offset = 0x2B,
+	},
+	[OCELOT_STAT_TX_OCTETS] = {
+		.name = "tx_octets",
+		.offset = 0x80,
+	},
+	[OCELOT_STAT_TX_UNICAST] = {
+		.name = "tx_unicast",
+		.offset = 0x81,
+	},
+	[OCELOT_STAT_TX_MULTICAST] = {
+		.name = "tx_multicast",
+		.offset = 0x82,
+	},
+	[OCELOT_STAT_TX_BROADCAST] = {
+		.name = "tx_broadcast",
+		.offset = 0x83,
+	},
+	[OCELOT_STAT_TX_COLLISION] = {
+		.name = "tx_collision",
+		.offset = 0x84,
+	},
+	[OCELOT_STAT_TX_DROPS] = {
+		.name = "tx_drops",
+		.offset = 0x85,
+	},
+	[OCELOT_STAT_TX_PAUSE] = {
+		.name = "tx_pause",
+		.offset = 0x86,
+	},
+	[OCELOT_STAT_TX_64] = {
+		.name = "tx_frames_below_65_octets",
+		.offset = 0x87,
+	},
+	[OCELOT_STAT_TX_65_127] = {
+		.name = "tx_frames_65_to_127_octets",
+		.offset = 0x88,
+	},
+	[OCELOT_STAT_TX_128_255] = {
+		.name = "tx_frames_128_255_octets",
+		.offset = 0x89,
+	},
+	[OCELOT_STAT_TX_256_511] = {
+		.name = "tx_frames_256_511_octets",
+		.offset = 0x8A,
+	},
+	[OCELOT_STAT_TX_512_1023] = {
+		.name = "tx_frames_512_1023_octets",
+		.offset = 0x8B,
+	},
+	[OCELOT_STAT_TX_1024_1526] = {
+		.name = "tx_frames_1024_1526_octets",
+		.offset = 0x8C,
+	},
+	[OCELOT_STAT_TX_1527_MAX] = {
+		.name = "tx_frames_over_1526_octets",
+		.offset = 0x8D,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_0] = {
+		.name = "tx_yellow_prio_0",
+		.offset = 0x8E,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_1] = {
+		.name = "tx_yellow_prio_1",
+		.offset = 0x8F,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_2] = {
+		.name = "tx_yellow_prio_2",
+		.offset = 0x90,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_3] = {
+		.name = "tx_yellow_prio_3",
+		.offset = 0x91,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_4] = {
+		.name = "tx_yellow_prio_4",
+		.offset = 0x92,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_5] = {
+		.name = "tx_yellow_prio_5",
+		.offset = 0x93,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_6] = {
+		.name = "tx_yellow_prio_6",
+		.offset = 0x94,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_7] = {
+		.name = "tx_yellow_prio_7",
+		.offset = 0x95,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_0] = {
+		.name = "tx_green_prio_0",
+		.offset = 0x96,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_1] = {
+		.name = "tx_green_prio_1",
+		.offset = 0x97,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_2] = {
+		.name = "tx_green_prio_2",
+		.offset = 0x98,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_3] = {
+		.name = "tx_green_prio_3",
+		.offset = 0x99,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_4] = {
+		.name = "tx_green_prio_4",
+		.offset = 0x9A,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_5] = {
+		.name = "tx_green_prio_5",
+		.offset = 0x9B,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_6] = {
+		.name = "tx_green_prio_6",
+		.offset = 0x9C,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_7] = {
+		.name = "tx_green_prio_7",
+		.offset = 0x9D,
+	},
+	[OCELOT_STAT_TX_AGED] = {
+		.name = "tx_aged",
+		.offset = 0x9E,
+	},
+	[OCELOT_STAT_DROP_LOCAL] = {
+		.name = "drop_local",
+		.offset = 0x100,
+	},
+	[OCELOT_STAT_DROP_TAIL] = {
+		.name = "drop_tail",
+		.offset = 0x101,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_0] = {
+		.name = "drop_yellow_prio_0",
+		.offset = 0x102,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_1] = {
+		.name = "drop_yellow_prio_1",
+		.offset = 0x103,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_2] = {
+		.name = "drop_yellow_prio_2",
+		.offset = 0x104,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_3] = {
+		.name = "drop_yellow_prio_3",
+		.offset = 0x105,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_4] = {
+		.name = "drop_yellow_prio_4",
+		.offset = 0x106,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_5] = {
+		.name = "drop_yellow_prio_5",
+		.offset = 0x107,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_6] = {
+		.name = "drop_yellow_prio_6",
+		.offset = 0x108,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_7] = {
+		.name = "drop_yellow_prio_7",
+		.offset = 0x109,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_0] = {
+		.name = "drop_green_prio_0",
+		.offset = 0x10A,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_1] = {
+		.name = "drop_green_prio_1",
+		.offset = 0x10B,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_2] = {
+		.name = "drop_green_prio_2",
+		.offset = 0x10C,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_3] = {
+		.name = "drop_green_prio_3",
+		.offset = 0x10D,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_4] = {
+		.name = "drop_green_prio_4",
+		.offset = 0x10E,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_5] = {
+		.name = "drop_green_prio_5",
+		.offset = 0x10F,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_6] = {
+		.name = "drop_green_prio_6",
+		.offset = 0x110,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_7] = {
+		.name = "drop_green_prio_7",
+		.offset = 0x111,
+	},
 };
 
 static const struct vcap_field vsc9959_vcap_es0_keys[] = {
diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
index ebe9ddbbe2b7..fe5d4642d0bc 100644
--- a/drivers/net/dsa/ocelot/seville_vsc9953.c
+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
@@ -545,101 +545,379 @@ static const struct reg_field vsc9953_regfields[REGFIELD_MAX] = {
 	[SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 11, 4),
 };
 
-static const struct ocelot_stat_layout vsc9953_stats_layout[] = {
-	{ .offset = 0x00,	.name = "rx_octets", },
-	{ .offset = 0x01,	.name = "rx_unicast", },
-	{ .offset = 0x02,	.name = "rx_multicast", },
-	{ .offset = 0x03,	.name = "rx_broadcast", },
-	{ .offset = 0x04,	.name = "rx_shorts", },
-	{ .offset = 0x05,	.name = "rx_fragments", },
-	{ .offset = 0x06,	.name = "rx_jabbers", },
-	{ .offset = 0x07,	.name = "rx_crc_align_errs", },
-	{ .offset = 0x08,	.name = "rx_sym_errs", },
-	{ .offset = 0x09,	.name = "rx_frames_below_65_octets", },
-	{ .offset = 0x0A,	.name = "rx_frames_65_to_127_octets", },
-	{ .offset = 0x0B,	.name = "rx_frames_128_to_255_octets", },
-	{ .offset = 0x0C,	.name = "rx_frames_256_to_511_octets", },
-	{ .offset = 0x0D,	.name = "rx_frames_512_to_1023_octets", },
-	{ .offset = 0x0E,	.name = "rx_frames_1024_to_1526_octets", },
-	{ .offset = 0x0F,	.name = "rx_frames_over_1526_octets", },
-	{ .offset = 0x10,	.name = "rx_pause", },
-	{ .offset = 0x11,	.name = "rx_control", },
-	{ .offset = 0x12,	.name = "rx_longs", },
-	{ .offset = 0x13,	.name = "rx_classified_drops", },
-	{ .offset = 0x14,	.name = "rx_red_prio_0", },
-	{ .offset = 0x15,	.name = "rx_red_prio_1", },
-	{ .offset = 0x16,	.name = "rx_red_prio_2", },
-	{ .offset = 0x17,	.name = "rx_red_prio_3", },
-	{ .offset = 0x18,	.name = "rx_red_prio_4", },
-	{ .offset = 0x19,	.name = "rx_red_prio_5", },
-	{ .offset = 0x1A,	.name = "rx_red_prio_6", },
-	{ .offset = 0x1B,	.name = "rx_red_prio_7", },
-	{ .offset = 0x1C,	.name = "rx_yellow_prio_0", },
-	{ .offset = 0x1D,	.name = "rx_yellow_prio_1", },
-	{ .offset = 0x1E,	.name = "rx_yellow_prio_2", },
-	{ .offset = 0x1F,	.name = "rx_yellow_prio_3", },
-	{ .offset = 0x20,	.name = "rx_yellow_prio_4", },
-	{ .offset = 0x21,	.name = "rx_yellow_prio_5", },
-	{ .offset = 0x22,	.name = "rx_yellow_prio_6", },
-	{ .offset = 0x23,	.name = "rx_yellow_prio_7", },
-	{ .offset = 0x24,	.name = "rx_green_prio_0", },
-	{ .offset = 0x25,	.name = "rx_green_prio_1", },
-	{ .offset = 0x26,	.name = "rx_green_prio_2", },
-	{ .offset = 0x27,	.name = "rx_green_prio_3", },
-	{ .offset = 0x28,	.name = "rx_green_prio_4", },
-	{ .offset = 0x29,	.name = "rx_green_prio_5", },
-	{ .offset = 0x2A,	.name = "rx_green_prio_6", },
-	{ .offset = 0x2B,	.name = "rx_green_prio_7", },
-	{ .offset = 0x40,	.name = "tx_octets", },
-	{ .offset = 0x41,	.name = "tx_unicast", },
-	{ .offset = 0x42,	.name = "tx_multicast", },
-	{ .offset = 0x43,	.name = "tx_broadcast", },
-	{ .offset = 0x44,	.name = "tx_collision", },
-	{ .offset = 0x45,	.name = "tx_drops", },
-	{ .offset = 0x46,	.name = "tx_pause", },
-	{ .offset = 0x47,	.name = "tx_frames_below_65_octets", },
-	{ .offset = 0x48,	.name = "tx_frames_65_to_127_octets", },
-	{ .offset = 0x49,	.name = "tx_frames_128_255_octets", },
-	{ .offset = 0x4A,	.name = "tx_frames_256_511_octets", },
-	{ .offset = 0x4B,	.name = "tx_frames_512_1023_octets", },
-	{ .offset = 0x4C,	.name = "tx_frames_1024_1526_octets", },
-	{ .offset = 0x4D,	.name = "tx_frames_over_1526_octets", },
-	{ .offset = 0x4E,	.name = "tx_yellow_prio_0", },
-	{ .offset = 0x4F,	.name = "tx_yellow_prio_1", },
-	{ .offset = 0x50,	.name = "tx_yellow_prio_2", },
-	{ .offset = 0x51,	.name = "tx_yellow_prio_3", },
-	{ .offset = 0x52,	.name = "tx_yellow_prio_4", },
-	{ .offset = 0x53,	.name = "tx_yellow_prio_5", },
-	{ .offset = 0x54,	.name = "tx_yellow_prio_6", },
-	{ .offset = 0x55,	.name = "tx_yellow_prio_7", },
-	{ .offset = 0x56,	.name = "tx_green_prio_0", },
-	{ .offset = 0x57,	.name = "tx_green_prio_1", },
-	{ .offset = 0x58,	.name = "tx_green_prio_2", },
-	{ .offset = 0x59,	.name = "tx_green_prio_3", },
-	{ .offset = 0x5A,	.name = "tx_green_prio_4", },
-	{ .offset = 0x5B,	.name = "tx_green_prio_5", },
-	{ .offset = 0x5C,	.name = "tx_green_prio_6", },
-	{ .offset = 0x5D,	.name = "tx_green_prio_7", },
-	{ .offset = 0x5E,	.name = "tx_aged", },
-	{ .offset = 0x80,	.name = "drop_local", },
-	{ .offset = 0x81,	.name = "drop_tail", },
-	{ .offset = 0x82,	.name = "drop_yellow_prio_0", },
-	{ .offset = 0x83,	.name = "drop_yellow_prio_1", },
-	{ .offset = 0x84,	.name = "drop_yellow_prio_2", },
-	{ .offset = 0x85,	.name = "drop_yellow_prio_3", },
-	{ .offset = 0x86,	.name = "drop_yellow_prio_4", },
-	{ .offset = 0x87,	.name = "drop_yellow_prio_5", },
-	{ .offset = 0x88,	.name = "drop_yellow_prio_6", },
-	{ .offset = 0x89,	.name = "drop_yellow_prio_7", },
-	{ .offset = 0x8A,	.name = "drop_green_prio_0", },
-	{ .offset = 0x8B,	.name = "drop_green_prio_1", },
-	{ .offset = 0x8C,	.name = "drop_green_prio_2", },
-	{ .offset = 0x8D,	.name = "drop_green_prio_3", },
-	{ .offset = 0x8E,	.name = "drop_green_prio_4", },
-	{ .offset = 0x8F,	.name = "drop_green_prio_5", },
-	{ .offset = 0x90,	.name = "drop_green_prio_6", },
-	{ .offset = 0x91,	.name = "drop_green_prio_7", },
-	OCELOT_STAT_END
+static const struct ocelot_stat_layout vsc9953_stats_layout[OCELOT_NUM_STATS] = {
+	[OCELOT_STAT_RX_OCTETS] = {
+		.name = "rx_octets",
+		.offset = 0x00,
+	},
+	[OCELOT_STAT_RX_UNICAST] = {
+		.name = "rx_unicast",
+		.offset = 0x01,
+	},
+	[OCELOT_STAT_RX_MULTICAST] = {
+		.name = "rx_multicast",
+		.offset = 0x02,
+	},
+	[OCELOT_STAT_RX_BROADCAST] = {
+		.name = "rx_broadcast",
+		.offset = 0x03,
+	},
+	[OCELOT_STAT_RX_SHORTS] = {
+		.name = "rx_shorts",
+		.offset = 0x04,
+	},
+	[OCELOT_STAT_RX_FRAGMENTS] = {
+		.name = "rx_fragments",
+		.offset = 0x05,
+	},
+	[OCELOT_STAT_RX_JABBERS] = {
+		.name = "rx_jabbers",
+		.offset = 0x06,
+	},
+	[OCELOT_STAT_RX_CRC_ALIGN_ERRS] = {
+		.name = "rx_crc_align_errs",
+		.offset = 0x07,
+	},
+	[OCELOT_STAT_RX_SYM_ERRS] = {
+		.name = "rx_sym_errs",
+		.offset = 0x08,
+	},
+	[OCELOT_STAT_RX_64] = {
+		.name = "rx_frames_below_65_octets",
+		.offset = 0x09,
+	},
+	[OCELOT_STAT_RX_65_127] = {
+		.name = "rx_frames_65_to_127_octets",
+		.offset = 0x0A,
+	},
+	[OCELOT_STAT_RX_128_255] = {
+		.name = "rx_frames_128_to_255_octets",
+		.offset = 0x0B,
+	},
+	[OCELOT_STAT_RX_256_511] = {
+		.name = "rx_frames_256_to_511_octets",
+		.offset = 0x0C,
+	},
+	[OCELOT_STAT_RX_512_1023] = {
+		.name = "rx_frames_512_to_1023_octets",
+		.offset = 0x0D,
+	},
+	[OCELOT_STAT_RX_1024_1526] = {
+		.name = "rx_frames_1024_to_1526_octets",
+		.offset = 0x0E,
+	},
+	[OCELOT_STAT_RX_1527_MAX] = {
+		.name = "rx_frames_over_1526_octets",
+		.offset = 0x0F,
+	},
+	[OCELOT_STAT_RX_PAUSE] = {
+		.name = "rx_pause",
+		.offset = 0x10,
+	},
+	[OCELOT_STAT_RX_CONTROL] = {
+		.name = "rx_control",
+		.offset = 0x11,
+	},
+	[OCELOT_STAT_RX_LONGS] = {
+		.name = "rx_longs",
+		.offset = 0x12,
+	},
+	[OCELOT_STAT_RX_CLASSIFIED_DROPS] = {
+		.name = "rx_classified_drops",
+		.offset = 0x13,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_0] = {
+		.name = "rx_red_prio_0",
+		.offset = 0x14,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_1] = {
+		.name = "rx_red_prio_1",
+		.offset = 0x15,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_2] = {
+		.name = "rx_red_prio_2",
+		.offset = 0x16,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_3] = {
+		.name = "rx_red_prio_3",
+		.offset = 0x17,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_4] = {
+		.name = "rx_red_prio_4",
+		.offset = 0x18,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_5] = {
+		.name = "rx_red_prio_5",
+		.offset = 0x19,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_6] = {
+		.name = "rx_red_prio_6",
+		.offset = 0x1A,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_7] = {
+		.name = "rx_red_prio_7",
+		.offset = 0x1B,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_0] = {
+		.name = "rx_yellow_prio_0",
+		.offset = 0x1C,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_1] = {
+		.name = "rx_yellow_prio_1",
+		.offset = 0x1D,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_2] = {
+		.name = "rx_yellow_prio_2",
+		.offset = 0x1E,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_3] = {
+		.name = "rx_yellow_prio_3",
+		.offset = 0x1F,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_4] = {
+		.name = "rx_yellow_prio_4",
+		.offset = 0x20,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_5] = {
+		.name = "rx_yellow_prio_5",
+		.offset = 0x21,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_6] = {
+		.name = "rx_yellow_prio_6",
+		.offset = 0x22,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_7] = {
+		.name = "rx_yellow_prio_7",
+		.offset = 0x23,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_0] = {
+		.name = "rx_green_prio_0",
+		.offset = 0x24,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_1] = {
+		.name = "rx_green_prio_1",
+		.offset = 0x25,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_2] = {
+		.name = "rx_green_prio_2",
+		.offset = 0x26,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_3] = {
+		.name = "rx_green_prio_3",
+		.offset = 0x27,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_4] = {
+		.name = "rx_green_prio_4",
+		.offset = 0x28,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_5] = {
+		.name = "rx_green_prio_5",
+		.offset = 0x29,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_6] = {
+		.name = "rx_green_prio_6",
+		.offset = 0x2A,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_7] = {
+		.name = "rx_green_prio_7",
+		.offset = 0x2B,
+	},
+	[OCELOT_STAT_TX_OCTETS] = {
+		.name = "tx_octets",
+		.offset = 0x40,
+	},
+	[OCELOT_STAT_TX_UNICAST] = {
+		.name = "tx_unicast",
+		.offset = 0x41,
+	},
+	[OCELOT_STAT_TX_MULTICAST] = {
+		.name = "tx_multicast",
+		.offset = 0x42,
+	},
+	[OCELOT_STAT_TX_BROADCAST] = {
+		.name = "tx_broadcast",
+		.offset = 0x43,
+	},
+	[OCELOT_STAT_TX_COLLISION] = {
+		.name = "tx_collision",
+		.offset = 0x44,
+	},
+	[OCELOT_STAT_TX_DROPS] = {
+		.name = "tx_drops",
+		.offset = 0x45,
+	},
+	[OCELOT_STAT_TX_PAUSE] = {
+		.name = "tx_pause",
+		.offset = 0x46,
+	},
+	[OCELOT_STAT_TX_64] = {
+		.name = "tx_frames_below_65_octets",
+		.offset = 0x47,
+	},
+	[OCELOT_STAT_TX_65_127] = {
+		.name = "tx_frames_65_to_127_octets",
+		.offset = 0x48,
+	},
+	[OCELOT_STAT_TX_128_255] = {
+		.name = "tx_frames_128_255_octets",
+		.offset = 0x49,
+	},
+	[OCELOT_STAT_TX_256_511] = {
+		.name = "tx_frames_256_511_octets",
+		.offset = 0x4A,
+	},
+	[OCELOT_STAT_TX_512_1023] = {
+		.name = "tx_frames_512_1023_octets",
+		.offset = 0x4B,
+	},
+	[OCELOT_STAT_TX_1024_1526] = {
+		.name = "tx_frames_1024_1526_octets",
+		.offset = 0x4C,
+	},
+	[OCELOT_STAT_TX_1527_MAX] = {
+		.name = "tx_frames_over_1526_octets",
+		.offset = 0x4D,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_0] = {
+		.name = "tx_yellow_prio_0",
+		.offset = 0x4E,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_1] = {
+		.name = "tx_yellow_prio_1",
+		.offset = 0x4F,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_2] = {
+		.name = "tx_yellow_prio_2",
+		.offset = 0x50,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_3] = {
+		.name = "tx_yellow_prio_3",
+		.offset = 0x51,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_4] = {
+		.name = "tx_yellow_prio_4",
+		.offset = 0x52,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_5] = {
+		.name = "tx_yellow_prio_5",
+		.offset = 0x53,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_6] = {
+		.name = "tx_yellow_prio_6",
+		.offset = 0x54,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_7] = {
+		.name = "tx_yellow_prio_7",
+		.offset = 0x55,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_0] = {
+		.name = "tx_green_prio_0",
+		.offset = 0x56,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_1] = {
+		.name = "tx_green_prio_1",
+		.offset = 0x57,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_2] = {
+		.name = "tx_green_prio_2",
+		.offset = 0x58,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_3] = {
+		.name = "tx_green_prio_3",
+		.offset = 0x59,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_4] = {
+		.name = "tx_green_prio_4",
+		.offset = 0x5A,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_5] = {
+		.name = "tx_green_prio_5",
+		.offset = 0x5B,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_6] = {
+		.name = "tx_green_prio_6",
+		.offset = 0x5C,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_7] = {
+		.name = "tx_green_prio_7",
+		.offset = 0x5D,
+	},
+	[OCELOT_STAT_TX_AGED] = {
+		.name = "tx_aged",
+		.offset = 0x5E,
+	},
+	[OCELOT_STAT_DROP_LOCAL] = {
+		.name = "drop_local",
+		.offset = 0x80,
+	},
+	[OCELOT_STAT_DROP_TAIL] = {
+		.name = "drop_tail",
+		.offset = 0x81,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_0] = {
+		.name = "drop_yellow_prio_0",
+		.offset = 0x82,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_1] = {
+		.name = "drop_yellow_prio_1",
+		.offset = 0x83,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_2] = {
+		.name = "drop_yellow_prio_2",
+		.offset = 0x84,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_3] = {
+		.name = "drop_yellow_prio_3",
+		.offset = 0x85,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_4] = {
+		.name = "drop_yellow_prio_4",
+		.offset = 0x86,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_5] = {
+		.name = "drop_yellow_prio_5",
+		.offset = 0x87,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_6] = {
+		.name = "drop_yellow_prio_6",
+		.offset = 0x88,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_7] = {
+		.name = "drop_yellow_prio_7",
+		.offset = 0x89,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_0] = {
+		.name = "drop_green_prio_0",
+		.offset = 0x8A,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_1] = {
+		.name = "drop_green_prio_1",
+		.offset = 0x8B,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_2] = {
+		.name = "drop_green_prio_2",
+		.offset = 0x8C,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_3] = {
+		.name = "drop_green_prio_3",
+		.offset = 0x8D,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_4] = {
+		.name = "drop_green_prio_4",
+		.offset = 0x8E,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_5] = {
+		.name = "drop_green_prio_5",
+		.offset = 0x8F,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_6] = {
+		.name = "drop_green_prio_6",
+		.offset = 0x90,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_7] = {
+		.name = "drop_green_prio_7",
+		.offset = 0x91,
+	},
 };
 
 static const struct vcap_field vsc9953_vcap_es0_keys[] = {
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index c67f162f8ab5..68991b021c56 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1860,16 +1860,20 @@ void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset, u8 *data)
 	if (sset != ETH_SS_STATS)
 		return;
 
-	for (i = 0; i < ocelot->num_stats; i++)
+	for (i = 0; i < OCELOT_NUM_STATS; i++) {
+		if (ocelot->stats_layout[i].name[0] == '\0')
+			continue;
+
 		memcpy(data + i * ETH_GSTRING_LEN, ocelot->stats_layout[i].name,
 		       ETH_GSTRING_LEN);
+	}
 }
 EXPORT_SYMBOL(ocelot_get_strings);
 
 /* Caller must hold &ocelot->stats_lock */
 static int ocelot_port_update_stats(struct ocelot *ocelot, int port)
 {
-	unsigned int idx = port * ocelot->num_stats;
+	unsigned int idx = port * OCELOT_NUM_STATS;
 	struct ocelot_stats_region *region;
 	int err, j;
 
@@ -1930,9 +1934,15 @@ void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data)
 	/* check and update now */
 	err = ocelot_port_update_stats(ocelot, port);
 
-	/* Copy all counters */
-	for (i = 0; i < ocelot->num_stats; i++)
-		*data++ = ocelot->stats[port * ocelot->num_stats + i];
+	/* Copy all supported counters */
+	for (i = 0; i < OCELOT_NUM_STATS; i++) {
+		int index = port * OCELOT_NUM_STATS + i;
+
+		if (ocelot->stats_layout[i].name[0] == '\0')
+			continue;
+
+		*data++ = ocelot->stats[index];
+	}
 
 	spin_unlock(&ocelot->stats_lock);
 
@@ -1943,10 +1953,16 @@ EXPORT_SYMBOL(ocelot_get_ethtool_stats);
 
 int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset)
 {
+	int i, num_stats = 0;
+
 	if (sset != ETH_SS_STATS)
 		return -EOPNOTSUPP;
 
-	return ocelot->num_stats;
+	for (i = 0; i < OCELOT_NUM_STATS; i++)
+		if (ocelot->stats_layout[i].name[0] != '\0')
+			num_stats++;
+
+	return num_stats;
 }
 EXPORT_SYMBOL(ocelot_get_sset_count);
 
@@ -1958,7 +1974,10 @@ static int ocelot_prepare_stats_regions(struct ocelot *ocelot)
 
 	INIT_LIST_HEAD(&ocelot->stats_regions);
 
-	for (i = 0; i < ocelot->num_stats; i++) {
+	for (i = 0; i < OCELOT_NUM_STATS; i++) {
+		if (ocelot->stats_layout[i].name[0] == '\0')
+			continue;
+
 		if (region && ocelot->stats_layout[i].offset == last + 1) {
 			region->count++;
 		} else {
@@ -3340,7 +3359,6 @@ static void ocelot_detect_features(struct ocelot *ocelot)
 
 int ocelot_init(struct ocelot *ocelot)
 {
-	const struct ocelot_stat_layout *stat;
 	char queue_name[32];
 	int i, ret;
 	u32 port;
@@ -3353,12 +3371,8 @@ int ocelot_init(struct ocelot *ocelot)
 		}
 	}
 
-	ocelot->num_stats = 0;
-	for_each_stat(ocelot, stat)
-		ocelot->num_stats++;
-
 	ocelot->stats = devm_kcalloc(ocelot->dev,
-				     ocelot->num_phys_ports * ocelot->num_stats,
+				     ocelot->num_phys_ports * OCELOT_NUM_STATS,
 				     sizeof(u64), GFP_KERNEL);
 	if (!ocelot->stats)
 		return -ENOMEM;
diff --git a/drivers/net/ethernet/mscc/ocelot_vsc7514.c b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
index 961f803aca19..9ff910560043 100644
--- a/drivers/net/ethernet/mscc/ocelot_vsc7514.c
+++ b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
@@ -96,101 +96,379 @@ static const struct reg_field ocelot_regfields[REGFIELD_MAX] = {
 	[SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 12, 4),
 };
 
-static const struct ocelot_stat_layout ocelot_stats_layout[] = {
-	{ .name = "rx_octets", .offset = 0x00, },
-	{ .name = "rx_unicast", .offset = 0x01, },
-	{ .name = "rx_multicast", .offset = 0x02, },
-	{ .name = "rx_broadcast", .offset = 0x03, },
-	{ .name = "rx_shorts", .offset = 0x04, },
-	{ .name = "rx_fragments", .offset = 0x05, },
-	{ .name = "rx_jabbers", .offset = 0x06, },
-	{ .name = "rx_crc_align_errs", .offset = 0x07, },
-	{ .name = "rx_sym_errs", .offset = 0x08, },
-	{ .name = "rx_frames_below_65_octets", .offset = 0x09, },
-	{ .name = "rx_frames_65_to_127_octets", .offset = 0x0A, },
-	{ .name = "rx_frames_128_to_255_octets", .offset = 0x0B, },
-	{ .name = "rx_frames_256_to_511_octets", .offset = 0x0C, },
-	{ .name = "rx_frames_512_to_1023_octets", .offset = 0x0D, },
-	{ .name = "rx_frames_1024_to_1526_octets", .offset = 0x0E, },
-	{ .name = "rx_frames_over_1526_octets", .offset = 0x0F, },
-	{ .name = "rx_pause", .offset = 0x10, },
-	{ .name = "rx_control", .offset = 0x11, },
-	{ .name = "rx_longs", .offset = 0x12, },
-	{ .name = "rx_classified_drops", .offset = 0x13, },
-	{ .name = "rx_red_prio_0", .offset = 0x14, },
-	{ .name = "rx_red_prio_1", .offset = 0x15, },
-	{ .name = "rx_red_prio_2", .offset = 0x16, },
-	{ .name = "rx_red_prio_3", .offset = 0x17, },
-	{ .name = "rx_red_prio_4", .offset = 0x18, },
-	{ .name = "rx_red_prio_5", .offset = 0x19, },
-	{ .name = "rx_red_prio_6", .offset = 0x1A, },
-	{ .name = "rx_red_prio_7", .offset = 0x1B, },
-	{ .name = "rx_yellow_prio_0", .offset = 0x1C, },
-	{ .name = "rx_yellow_prio_1", .offset = 0x1D, },
-	{ .name = "rx_yellow_prio_2", .offset = 0x1E, },
-	{ .name = "rx_yellow_prio_3", .offset = 0x1F, },
-	{ .name = "rx_yellow_prio_4", .offset = 0x20, },
-	{ .name = "rx_yellow_prio_5", .offset = 0x21, },
-	{ .name = "rx_yellow_prio_6", .offset = 0x22, },
-	{ .name = "rx_yellow_prio_7", .offset = 0x23, },
-	{ .name = "rx_green_prio_0", .offset = 0x24, },
-	{ .name = "rx_green_prio_1", .offset = 0x25, },
-	{ .name = "rx_green_prio_2", .offset = 0x26, },
-	{ .name = "rx_green_prio_3", .offset = 0x27, },
-	{ .name = "rx_green_prio_4", .offset = 0x28, },
-	{ .name = "rx_green_prio_5", .offset = 0x29, },
-	{ .name = "rx_green_prio_6", .offset = 0x2A, },
-	{ .name = "rx_green_prio_7", .offset = 0x2B, },
-	{ .name = "tx_octets", .offset = 0x40, },
-	{ .name = "tx_unicast", .offset = 0x41, },
-	{ .name = "tx_multicast", .offset = 0x42, },
-	{ .name = "tx_broadcast", .offset = 0x43, },
-	{ .name = "tx_collision", .offset = 0x44, },
-	{ .name = "tx_drops", .offset = 0x45, },
-	{ .name = "tx_pause", .offset = 0x46, },
-	{ .name = "tx_frames_below_65_octets", .offset = 0x47, },
-	{ .name = "tx_frames_65_to_127_octets", .offset = 0x48, },
-	{ .name = "tx_frames_128_255_octets", .offset = 0x49, },
-	{ .name = "tx_frames_256_511_octets", .offset = 0x4A, },
-	{ .name = "tx_frames_512_1023_octets", .offset = 0x4B, },
-	{ .name = "tx_frames_1024_1526_octets", .offset = 0x4C, },
-	{ .name = "tx_frames_over_1526_octets", .offset = 0x4D, },
-	{ .name = "tx_yellow_prio_0", .offset = 0x4E, },
-	{ .name = "tx_yellow_prio_1", .offset = 0x4F, },
-	{ .name = "tx_yellow_prio_2", .offset = 0x50, },
-	{ .name = "tx_yellow_prio_3", .offset = 0x51, },
-	{ .name = "tx_yellow_prio_4", .offset = 0x52, },
-	{ .name = "tx_yellow_prio_5", .offset = 0x53, },
-	{ .name = "tx_yellow_prio_6", .offset = 0x54, },
-	{ .name = "tx_yellow_prio_7", .offset = 0x55, },
-	{ .name = "tx_green_prio_0", .offset = 0x56, },
-	{ .name = "tx_green_prio_1", .offset = 0x57, },
-	{ .name = "tx_green_prio_2", .offset = 0x58, },
-	{ .name = "tx_green_prio_3", .offset = 0x59, },
-	{ .name = "tx_green_prio_4", .offset = 0x5A, },
-	{ .name = "tx_green_prio_5", .offset = 0x5B, },
-	{ .name = "tx_green_prio_6", .offset = 0x5C, },
-	{ .name = "tx_green_prio_7", .offset = 0x5D, },
-	{ .name = "tx_aged", .offset = 0x5E, },
-	{ .name = "drop_local", .offset = 0x80, },
-	{ .name = "drop_tail", .offset = 0x81, },
-	{ .name = "drop_yellow_prio_0", .offset = 0x82, },
-	{ .name = "drop_yellow_prio_1", .offset = 0x83, },
-	{ .name = "drop_yellow_prio_2", .offset = 0x84, },
-	{ .name = "drop_yellow_prio_3", .offset = 0x85, },
-	{ .name = "drop_yellow_prio_4", .offset = 0x86, },
-	{ .name = "drop_yellow_prio_5", .offset = 0x87, },
-	{ .name = "drop_yellow_prio_6", .offset = 0x88, },
-	{ .name = "drop_yellow_prio_7", .offset = 0x89, },
-	{ .name = "drop_green_prio_0", .offset = 0x8A, },
-	{ .name = "drop_green_prio_1", .offset = 0x8B, },
-	{ .name = "drop_green_prio_2", .offset = 0x8C, },
-	{ .name = "drop_green_prio_3", .offset = 0x8D, },
-	{ .name = "drop_green_prio_4", .offset = 0x8E, },
-	{ .name = "drop_green_prio_5", .offset = 0x8F, },
-	{ .name = "drop_green_prio_6", .offset = 0x90, },
-	{ .name = "drop_green_prio_7", .offset = 0x91, },
-	OCELOT_STAT_END
+static const struct ocelot_stat_layout ocelot_stats_layout[OCELOT_NUM_STATS] = {
+	[OCELOT_STAT_RX_OCTETS] = {
+		.name = "rx_octets",
+		.offset = 0x00,
+	},
+	[OCELOT_STAT_RX_UNICAST] = {
+		.name = "rx_unicast",
+		.offset = 0x01,
+	},
+	[OCELOT_STAT_RX_MULTICAST] = {
+		.name = "rx_multicast",
+		.offset = 0x02,
+	},
+	[OCELOT_STAT_RX_BROADCAST] = {
+		.name = "rx_broadcast",
+		.offset = 0x03,
+	},
+	[OCELOT_STAT_RX_SHORTS] = {
+		.name = "rx_shorts",
+		.offset = 0x04,
+	},
+	[OCELOT_STAT_RX_FRAGMENTS] = {
+		.name = "rx_fragments",
+		.offset = 0x05,
+	},
+	[OCELOT_STAT_RX_JABBERS] = {
+		.name = "rx_jabbers",
+		.offset = 0x06,
+	},
+	[OCELOT_STAT_RX_CRC_ALIGN_ERRS] = {
+		.name = "rx_crc_align_errs",
+		.offset = 0x07,
+	},
+	[OCELOT_STAT_RX_SYM_ERRS] = {
+		.name = "rx_sym_errs",
+		.offset = 0x08,
+	},
+	[OCELOT_STAT_RX_64] = {
+		.name = "rx_frames_below_65_octets",
+		.offset = 0x09,
+	},
+	[OCELOT_STAT_RX_65_127] = {
+		.name = "rx_frames_65_to_127_octets",
+		.offset = 0x0A,
+	},
+	[OCELOT_STAT_RX_128_255] = {
+		.name = "rx_frames_128_to_255_octets",
+		.offset = 0x0B,
+	},
+	[OCELOT_STAT_RX_256_511] = {
+		.name = "rx_frames_256_to_511_octets",
+		.offset = 0x0C,
+	},
+	[OCELOT_STAT_RX_512_1023] = {
+		.name = "rx_frames_512_to_1023_octets",
+		.offset = 0x0D,
+	},
+	[OCELOT_STAT_RX_1024_1526] = {
+		.name = "rx_frames_1024_to_1526_octets",
+		.offset = 0x0E,
+	},
+	[OCELOT_STAT_RX_1527_MAX] = {
+		.name = "rx_frames_over_1526_octets",
+		.offset = 0x0F,
+	},
+	[OCELOT_STAT_RX_PAUSE] = {
+		.name = "rx_pause",
+		.offset = 0x10,
+	},
+	[OCELOT_STAT_RX_CONTROL] = {
+		.name = "rx_control",
+		.offset = 0x11,
+	},
+	[OCELOT_STAT_RX_LONGS] = {
+		.name = "rx_longs",
+		.offset = 0x12,
+	},
+	[OCELOT_STAT_RX_CLASSIFIED_DROPS] = {
+		.name = "rx_classified_drops",
+		.offset = 0x13,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_0] = {
+		.name = "rx_red_prio_0",
+		.offset = 0x14,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_1] = {
+		.name = "rx_red_prio_1",
+		.offset = 0x15,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_2] = {
+		.name = "rx_red_prio_2",
+		.offset = 0x16,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_3] = {
+		.name = "rx_red_prio_3",
+		.offset = 0x17,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_4] = {
+		.name = "rx_red_prio_4",
+		.offset = 0x18,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_5] = {
+		.name = "rx_red_prio_5",
+		.offset = 0x19,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_6] = {
+		.name = "rx_red_prio_6",
+		.offset = 0x1A,
+	},
+	[OCELOT_STAT_RX_RED_PRIO_7] = {
+		.name = "rx_red_prio_7",
+		.offset = 0x1B,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_0] = {
+		.name = "rx_yellow_prio_0",
+		.offset = 0x1C,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_1] = {
+		.name = "rx_yellow_prio_1",
+		.offset = 0x1D,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_2] = {
+		.name = "rx_yellow_prio_2",
+		.offset = 0x1E,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_3] = {
+		.name = "rx_yellow_prio_3",
+		.offset = 0x1F,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_4] = {
+		.name = "rx_yellow_prio_4",
+		.offset = 0x20,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_5] = {
+		.name = "rx_yellow_prio_5",
+		.offset = 0x21,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_6] = {
+		.name = "rx_yellow_prio_6",
+		.offset = 0x22,
+	},
+	[OCELOT_STAT_RX_YELLOW_PRIO_7] = {
+		.name = "rx_yellow_prio_7",
+		.offset = 0x23,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_0] = {
+		.name = "rx_green_prio_0",
+		.offset = 0x24,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_1] = {
+		.name = "rx_green_prio_1",
+		.offset = 0x25,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_2] = {
+		.name = "rx_green_prio_2",
+		.offset = 0x26,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_3] = {
+		.name = "rx_green_prio_3",
+		.offset = 0x27,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_4] = {
+		.name = "rx_green_prio_4",
+		.offset = 0x28,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_5] = {
+		.name = "rx_green_prio_5",
+		.offset = 0x29,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_6] = {
+		.name = "rx_green_prio_6",
+		.offset = 0x2A,
+	},
+	[OCELOT_STAT_RX_GREEN_PRIO_7] = {
+		.name = "rx_green_prio_7",
+		.offset = 0x2B,
+	},
+	[OCELOT_STAT_TX_OCTETS] = {
+		.name = "tx_octets",
+		.offset = 0x40,
+	},
+	[OCELOT_STAT_TX_UNICAST] = {
+		.name = "tx_unicast",
+		.offset = 0x41,
+	},
+	[OCELOT_STAT_TX_MULTICAST] = {
+		.name = "tx_multicast",
+		.offset = 0x42,
+	},
+	[OCELOT_STAT_TX_BROADCAST] = {
+		.name = "tx_broadcast",
+		.offset = 0x43,
+	},
+	[OCELOT_STAT_TX_COLLISION] = {
+		.name = "tx_collision",
+		.offset = 0x44,
+	},
+	[OCELOT_STAT_TX_DROPS] = {
+		.name = "tx_drops",
+		.offset = 0x45,
+	},
+	[OCELOT_STAT_TX_PAUSE] = {
+		.name = "tx_pause",
+		.offset = 0x46,
+	},
+	[OCELOT_STAT_TX_64] = {
+		.name = "tx_frames_below_65_octets",
+		.offset = 0x47,
+	},
+	[OCELOT_STAT_TX_65_127] = {
+		.name = "tx_frames_65_to_127_octets",
+		.offset = 0x48,
+	},
+	[OCELOT_STAT_TX_128_255] = {
+		.name = "tx_frames_128_255_octets",
+		.offset = 0x49,
+	},
+	[OCELOT_STAT_TX_256_511] = {
+		.name = "tx_frames_256_511_octets",
+		.offset = 0x4A,
+	},
+	[OCELOT_STAT_TX_512_1023] = {
+		.name = "tx_frames_512_1023_octets",
+		.offset = 0x4B,
+	},
+	[OCELOT_STAT_TX_1024_1526] = {
+		.name = "tx_frames_1024_1526_octets",
+		.offset = 0x4C,
+	},
+	[OCELOT_STAT_TX_1527_MAX] = {
+		.name = "tx_frames_over_1526_octets",
+		.offset = 0x4D,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_0] = {
+		.name = "tx_yellow_prio_0",
+		.offset = 0x4E,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_1] = {
+		.name = "tx_yellow_prio_1",
+		.offset = 0x4F,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_2] = {
+		.name = "tx_yellow_prio_2",
+		.offset = 0x50,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_3] = {
+		.name = "tx_yellow_prio_3",
+		.offset = 0x51,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_4] = {
+		.name = "tx_yellow_prio_4",
+		.offset = 0x52,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_5] = {
+		.name = "tx_yellow_prio_5",
+		.offset = 0x53,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_6] = {
+		.name = "tx_yellow_prio_6",
+		.offset = 0x54,
+	},
+	[OCELOT_STAT_TX_YELLOW_PRIO_7] = {
+		.name = "tx_yellow_prio_7",
+		.offset = 0x55,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_0] = {
+		.name = "tx_green_prio_0",
+		.offset = 0x56,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_1] = {
+		.name = "tx_green_prio_1",
+		.offset = 0x57,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_2] = {
+		.name = "tx_green_prio_2",
+		.offset = 0x58,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_3] = {
+		.name = "tx_green_prio_3",
+		.offset = 0x59,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_4] = {
+		.name = "tx_green_prio_4",
+		.offset = 0x5A,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_5] = {
+		.name = "tx_green_prio_5",
+		.offset = 0x5B,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_6] = {
+		.name = "tx_green_prio_6",
+		.offset = 0x5C,
+	},
+	[OCELOT_STAT_TX_GREEN_PRIO_7] = {
+		.name = "tx_green_prio_7",
+		.offset = 0x5D,
+	},
+	[OCELOT_STAT_TX_AGED] = {
+		.name = "tx_aged",
+		.offset = 0x5E,
+	},
+	[OCELOT_STAT_DROP_LOCAL] = {
+		.name = "drop_local",
+		.offset = 0x80,
+	},
+	[OCELOT_STAT_DROP_TAIL] = {
+		.name = "drop_tail",
+		.offset = 0x81,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_0] = {
+		.name = "drop_yellow_prio_0",
+		.offset = 0x82,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_1] = {
+		.name = "drop_yellow_prio_1",
+		.offset = 0x83,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_2] = {
+		.name = "drop_yellow_prio_2",
+		.offset = 0x84,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_3] = {
+		.name = "drop_yellow_prio_3",
+		.offset = 0x85,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_4] = {
+		.name = "drop_yellow_prio_4",
+		.offset = 0x86,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_5] = {
+		.name = "drop_yellow_prio_5",
+		.offset = 0x87,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_6] = {
+		.name = "drop_yellow_prio_6",
+		.offset = 0x88,
+	},
+	[OCELOT_STAT_DROP_YELLOW_PRIO_7] = {
+		.name = "drop_yellow_prio_7",
+		.offset = 0x89,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_0] = {
+		.name = "drop_green_prio_0",
+		.offset = 0x8A,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_1] = {
+		.name = "drop_green_prio_1",
+		.offset = 0x8B,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_2] = {
+		.name = "drop_green_prio_2",
+		.offset = 0x8C,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_3] = {
+		.name = "drop_green_prio_3",
+		.offset = 0x8D,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_4] = {
+		.name = "drop_green_prio_4",
+		.offset = 0x8E,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_5] = {
+		.name = "drop_green_prio_5",
+		.offset = 0x8F,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_6] = {
+		.name = "drop_green_prio_6",
+		.offset = 0x90,
+	},
+	[OCELOT_STAT_DROP_GREEN_PRIO_7] = {
+		.name = "drop_green_prio_7",
+		.offset = 0x91,
+	},
 };
 
 static void ocelot_pll5_init(struct ocelot *ocelot)
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 72b9474391da..2428bc64cb1d 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -105,11 +105,6 @@
 #define REG_RESERVED_ADDR		0xffffffff
 #define REG_RESERVED(reg)		REG(reg, REG_RESERVED_ADDR)
 
-#define for_each_stat(ocelot, stat)				\
-	for ((stat) = (ocelot)->stats_layout;			\
-	     ((stat)->name[0] != '\0');				\
-	     (stat)++)
-
 enum ocelot_target {
 	ANA = 1,
 	QS,
@@ -540,13 +535,108 @@ enum ocelot_ptp_pins {
 	TOD_ACC_PIN
 };
 
+enum ocelot_stat {
+	OCELOT_STAT_RX_OCTETS,
+	OCELOT_STAT_RX_UNICAST,
+	OCELOT_STAT_RX_MULTICAST,
+	OCELOT_STAT_RX_BROADCAST,
+	OCELOT_STAT_RX_SHORTS,
+	OCELOT_STAT_RX_FRAGMENTS,
+	OCELOT_STAT_RX_JABBERS,
+	OCELOT_STAT_RX_CRC_ALIGN_ERRS,
+	OCELOT_STAT_RX_SYM_ERRS,
+	OCELOT_STAT_RX_64,
+	OCELOT_STAT_RX_65_127,
+	OCELOT_STAT_RX_128_255,
+	OCELOT_STAT_RX_256_511,
+	OCELOT_STAT_RX_512_1023,
+	OCELOT_STAT_RX_1024_1526,
+	OCELOT_STAT_RX_1527_MAX,
+	OCELOT_STAT_RX_PAUSE,
+	OCELOT_STAT_RX_CONTROL,
+	OCELOT_STAT_RX_LONGS,
+	OCELOT_STAT_RX_CLASSIFIED_DROPS,
+	OCELOT_STAT_RX_RED_PRIO_0,
+	OCELOT_STAT_RX_RED_PRIO_1,
+	OCELOT_STAT_RX_RED_PRIO_2,
+	OCELOT_STAT_RX_RED_PRIO_3,
+	OCELOT_STAT_RX_RED_PRIO_4,
+	OCELOT_STAT_RX_RED_PRIO_5,
+	OCELOT_STAT_RX_RED_PRIO_6,
+	OCELOT_STAT_RX_RED_PRIO_7,
+	OCELOT_STAT_RX_YELLOW_PRIO_0,
+	OCELOT_STAT_RX_YELLOW_PRIO_1,
+	OCELOT_STAT_RX_YELLOW_PRIO_2,
+	OCELOT_STAT_RX_YELLOW_PRIO_3,
+	OCELOT_STAT_RX_YELLOW_PRIO_4,
+	OCELOT_STAT_RX_YELLOW_PRIO_5,
+	OCELOT_STAT_RX_YELLOW_PRIO_6,
+	OCELOT_STAT_RX_YELLOW_PRIO_7,
+	OCELOT_STAT_RX_GREEN_PRIO_0,
+	OCELOT_STAT_RX_GREEN_PRIO_1,
+	OCELOT_STAT_RX_GREEN_PRIO_2,
+	OCELOT_STAT_RX_GREEN_PRIO_3,
+	OCELOT_STAT_RX_GREEN_PRIO_4,
+	OCELOT_STAT_RX_GREEN_PRIO_5,
+	OCELOT_STAT_RX_GREEN_PRIO_6,
+	OCELOT_STAT_RX_GREEN_PRIO_7,
+	OCELOT_STAT_TX_OCTETS,
+	OCELOT_STAT_TX_UNICAST,
+	OCELOT_STAT_TX_MULTICAST,
+	OCELOT_STAT_TX_BROADCAST,
+	OCELOT_STAT_TX_COLLISION,
+	OCELOT_STAT_TX_DROPS,
+	OCELOT_STAT_TX_PAUSE,
+	OCELOT_STAT_TX_64,
+	OCELOT_STAT_TX_65_127,
+	OCELOT_STAT_TX_128_255,
+	OCELOT_STAT_TX_256_511,
+	OCELOT_STAT_TX_512_1023,
+	OCELOT_STAT_TX_1024_1526,
+	OCELOT_STAT_TX_1527_MAX,
+	OCELOT_STAT_TX_YELLOW_PRIO_0,
+	OCELOT_STAT_TX_YELLOW_PRIO_1,
+	OCELOT_STAT_TX_YELLOW_PRIO_2,
+	OCELOT_STAT_TX_YELLOW_PRIO_3,
+	OCELOT_STAT_TX_YELLOW_PRIO_4,
+	OCELOT_STAT_TX_YELLOW_PRIO_5,
+	OCELOT_STAT_TX_YELLOW_PRIO_6,
+	OCELOT_STAT_TX_YELLOW_PRIO_7,
+	OCELOT_STAT_TX_GREEN_PRIO_0,
+	OCELOT_STAT_TX_GREEN_PRIO_1,
+	OCELOT_STAT_TX_GREEN_PRIO_2,
+	OCELOT_STAT_TX_GREEN_PRIO_3,
+	OCELOT_STAT_TX_GREEN_PRIO_4,
+	OCELOT_STAT_TX_GREEN_PRIO_5,
+	OCELOT_STAT_TX_GREEN_PRIO_6,
+	OCELOT_STAT_TX_GREEN_PRIO_7,
+	OCELOT_STAT_TX_AGED,
+	OCELOT_STAT_DROP_LOCAL,
+	OCELOT_STAT_DROP_TAIL,
+	OCELOT_STAT_DROP_YELLOW_PRIO_0,
+	OCELOT_STAT_DROP_YELLOW_PRIO_1,
+	OCELOT_STAT_DROP_YELLOW_PRIO_2,
+	OCELOT_STAT_DROP_YELLOW_PRIO_3,
+	OCELOT_STAT_DROP_YELLOW_PRIO_4,
+	OCELOT_STAT_DROP_YELLOW_PRIO_5,
+	OCELOT_STAT_DROP_YELLOW_PRIO_6,
+	OCELOT_STAT_DROP_YELLOW_PRIO_7,
+	OCELOT_STAT_DROP_GREEN_PRIO_0,
+	OCELOT_STAT_DROP_GREEN_PRIO_1,
+	OCELOT_STAT_DROP_GREEN_PRIO_2,
+	OCELOT_STAT_DROP_GREEN_PRIO_3,
+	OCELOT_STAT_DROP_GREEN_PRIO_4,
+	OCELOT_STAT_DROP_GREEN_PRIO_5,
+	OCELOT_STAT_DROP_GREEN_PRIO_6,
+	OCELOT_STAT_DROP_GREEN_PRIO_7,
+	OCELOT_NUM_STATS,
+};
+
 struct ocelot_stat_layout {
 	u32 offset;
 	char name[ETH_GSTRING_LEN];
 };
 
-#define OCELOT_STAT_END { .name = "" }
-
 struct ocelot_stats_region {
 	struct list_head node;
 	u32 offset;
@@ -709,7 +799,6 @@ struct ocelot {
 	const u32 *const		*map;
 	const struct ocelot_stat_layout	*stats_layout;
 	struct list_head		stats_regions;
-	unsigned int			num_stats;
 
 	u32				pool_size[OCELOT_SB_NUM][OCELOT_SB_POOL_NUM];
 	int				packet_buffer_size;
-- 
2.34.1


^ permalink raw reply related

* [PATCH net 8/8] net: mscc: ocelot: report ndo_get_stats64 from the wraparound-resistant ocelot->stats
From: Vladimir Oltean @ 2022-08-16 13:53 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Claudiu Manoil,
	Alexandre Belloni, UNGLinuxDriver, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Colin Foster, Maxim Kochetkov
In-Reply-To: <20220816135352.1431497-1-vladimir.oltean@nxp.com>

Rather than reading the stats64 counters directly from the 32-bit
hardware, it's better to rely on the output produced by the periodic
ocelot_port_update_stats().

It would be even better to call ocelot_port_update_stats() right from
ocelot_get_stats64() to make sure we report the current values rather
than the ones from 2 seconds ago. But we need to export
ocelot_port_update_stats() from the switch lib towards the switchdev
driver for that, and future work will largely undo that.

There are more ocelot-based drivers waiting to be introduced, an example
of which is the SPI-controlled VSC7512. In that driver's case, it will
be impossible to call ocelot_port_update_stats() from ndo_get_stats64
context, since the latter is atomic, and reading the stats over SPI is
sleepable. So the compromise taken here, which will also hold going
forward, is to report 64-bit counters to stats64, which are not 100% up
to date.

Fixes: a556c76adc05 ("net: mscc: Add initial Ocelot switch support")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/ethernet/mscc/ocelot_net.c | 53 +++++++++++++-------------
 1 file changed, 26 insertions(+), 27 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
index 6b9d37138844..330d30841cdc 100644
--- a/drivers/net/ethernet/mscc/ocelot_net.c
+++ b/drivers/net/ethernet/mscc/ocelot_net.c
@@ -725,41 +725,40 @@ static void ocelot_get_stats64(struct net_device *dev,
 	struct ocelot_port_private *priv = netdev_priv(dev);
 	struct ocelot *ocelot = priv->port.ocelot;
 	int port = priv->port.index;
+	u64 *s;
 
 	spin_lock(&ocelot->stats_lock);
 
-	/* Configure the port to read the stats from */
-	ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port),
-		     SYS_STAT_CFG);
+	s = &ocelot->stats[port * OCELOT_NUM_STATS];
 
 	/* Get Rx stats */
-	stats->rx_bytes = ocelot_read(ocelot, SYS_COUNT_RX_OCTETS);
-	stats->rx_packets = ocelot_read(ocelot, SYS_COUNT_RX_SHORTS) +
-			    ocelot_read(ocelot, SYS_COUNT_RX_FRAGMENTS) +
-			    ocelot_read(ocelot, SYS_COUNT_RX_JABBERS) +
-			    ocelot_read(ocelot, SYS_COUNT_RX_LONGS) +
-			    ocelot_read(ocelot, SYS_COUNT_RX_64) +
-			    ocelot_read(ocelot, SYS_COUNT_RX_65_127) +
-			    ocelot_read(ocelot, SYS_COUNT_RX_128_255) +
-			    ocelot_read(ocelot, SYS_COUNT_RX_256_511) +
-			    ocelot_read(ocelot, SYS_COUNT_RX_512_1023) +
-			    ocelot_read(ocelot, SYS_COUNT_RX_1024_1526) +
-			    ocelot_read(ocelot, SYS_COUNT_RX_1527_MAX);
-	stats->multicast = ocelot_read(ocelot, SYS_COUNT_RX_MULTICAST);
+	stats->rx_bytes = s[OCELOT_STAT_RX_OCTETS];
+	stats->rx_packets = s[OCELOT_STAT_RX_SHORTS] +
+			    s[OCELOT_STAT_RX_FRAGMENTS] +
+			    s[OCELOT_STAT_RX_JABBERS] +
+			    s[OCELOT_STAT_RX_LONGS] +
+			    s[OCELOT_STAT_RX_64] +
+			    s[OCELOT_STAT_RX_65_127] +
+			    s[OCELOT_STAT_RX_128_255] +
+			    s[OCELOT_STAT_RX_256_511] +
+			    s[OCELOT_STAT_RX_512_1023] +
+			    s[OCELOT_STAT_RX_1024_1526] +
+			    s[OCELOT_STAT_RX_1527_MAX];
+	stats->multicast = s[OCELOT_STAT_RX_MULTICAST];
 	stats->rx_dropped = dev->stats.rx_dropped;
 
 	/* Get Tx stats */
-	stats->tx_bytes = ocelot_read(ocelot, SYS_COUNT_TX_OCTETS);
-	stats->tx_packets = ocelot_read(ocelot, SYS_COUNT_TX_64) +
-			    ocelot_read(ocelot, SYS_COUNT_TX_65_127) +
-			    ocelot_read(ocelot, SYS_COUNT_TX_128_255) +
-			    ocelot_read(ocelot, SYS_COUNT_TX_256_511) +
-			    ocelot_read(ocelot, SYS_COUNT_TX_512_1023) +
-			    ocelot_read(ocelot, SYS_COUNT_TX_1024_1526) +
-			    ocelot_read(ocelot, SYS_COUNT_TX_1527_MAX);
-	stats->tx_dropped = ocelot_read(ocelot, SYS_COUNT_TX_DROPS) +
-			    ocelot_read(ocelot, SYS_COUNT_TX_AGING);
-	stats->collisions = ocelot_read(ocelot, SYS_COUNT_TX_COLLISION);
+	stats->tx_bytes = s[OCELOT_STAT_TX_OCTETS];
+	stats->tx_packets = s[OCELOT_STAT_TX_64] +
+			    s[OCELOT_STAT_TX_65_127] +
+			    s[OCELOT_STAT_TX_128_255] +
+			    s[OCELOT_STAT_TX_256_511] +
+			    s[OCELOT_STAT_TX_512_1023] +
+			    s[OCELOT_STAT_TX_1024_1526] +
+			    s[OCELOT_STAT_TX_1527_MAX];
+	stats->tx_dropped = s[OCELOT_STAT_TX_DROPS] +
+			    s[OCELOT_STAT_TX_AGED];
+	stats->collisions = s[OCELOT_STAT_TX_COLLISION];
 
 	spin_unlock(&ocelot->stats_lock);
 }
-- 
2.34.1


^ permalink raw reply related

* [PATCH net 7/8] net: mscc: ocelot: keep ocelot_stat_layout by reg address, not offset
From: Vladimir Oltean @ 2022-08-16 13:53 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Claudiu Manoil,
	Alexandre Belloni, UNGLinuxDriver, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Colin Foster, Maxim Kochetkov
In-Reply-To: <20220816135352.1431497-1-vladimir.oltean@nxp.com>

With so many counter addresses recently discovered as being wrong, it is
desirable to at least have a central database of information, rather
than two: one through the SYS_COUNT_* registers (used for
ndo_get_stats64), and the other through the offset field of struct
ocelot_stat_layout elements (used for ethtool -S).

The strategy will be to keep the SYS_COUNT_* definitions as the single
source of truth, but for that we need to expand our current definitions
to cover all registers. Then we need to convert the ocelot region
creation logic, and stats worker, to the read semantics imposed by going
through SYS_COUNT_* absolute register addresses, rather than offsets
of 32-bit words relative to SYS_COUNT_RX_OCTETS (which should have been
SYS_CNT, by the way).

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/net/dsa/ocelot/felix_vsc9959.c     | 253 ++++++++++++--------
 drivers/net/dsa/ocelot/seville_vsc9953.c   | 255 +++++++++++++--------
 drivers/net/ethernet/mscc/ocelot.c         |  11 +-
 drivers/net/ethernet/mscc/ocelot_vsc7514.c | 186 +++++++--------
 drivers/net/ethernet/mscc/vsc7514_regs.c   |  58 +++++
 include/soc/mscc/ocelot.h                  |  66 +++++-
 6 files changed, 540 insertions(+), 289 deletions(-)

diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index c9f270f24b1c..1cdce8a98d1d 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -274,10 +274,14 @@ static const u32 vsc9959_rew_regmap[] = {
 
 static const u32 vsc9959_sys_regmap[] = {
 	REG(SYS_COUNT_RX_OCTETS,		0x000000),
+	REG(SYS_COUNT_RX_UNICAST,		0x000004),
 	REG(SYS_COUNT_RX_MULTICAST,		0x000008),
+	REG(SYS_COUNT_RX_BROADCAST,		0x00000c),
 	REG(SYS_COUNT_RX_SHORTS,		0x000010),
 	REG(SYS_COUNT_RX_FRAGMENTS,		0x000014),
 	REG(SYS_COUNT_RX_JABBERS,		0x000018),
+	REG(SYS_COUNT_RX_CRC_ALIGN_ERRS,	0x00001c),
+	REG(SYS_COUNT_RX_SYM_ERRS,		0x000020),
 	REG(SYS_COUNT_RX_64,			0x000024),
 	REG(SYS_COUNT_RX_65_127,		0x000028),
 	REG(SYS_COUNT_RX_128_255,		0x00002c),
@@ -288,9 +292,38 @@ static const u32 vsc9959_sys_regmap[] = {
 	REG(SYS_COUNT_RX_PAUSE,			0x000040),
 	REG(SYS_COUNT_RX_CONTROL,		0x000044),
 	REG(SYS_COUNT_RX_LONGS,			0x000048),
+	REG(SYS_COUNT_RX_CLASSIFIED_DROPS,	0x00004c),
+	REG(SYS_COUNT_RX_RED_PRIO_0,		0x000050),
+	REG(SYS_COUNT_RX_RED_PRIO_1,		0x000054),
+	REG(SYS_COUNT_RX_RED_PRIO_2,		0x000058),
+	REG(SYS_COUNT_RX_RED_PRIO_3,		0x00005c),
+	REG(SYS_COUNT_RX_RED_PRIO_4,		0x000060),
+	REG(SYS_COUNT_RX_RED_PRIO_5,		0x000064),
+	REG(SYS_COUNT_RX_RED_PRIO_6,		0x000068),
+	REG(SYS_COUNT_RX_RED_PRIO_7,		0x00006c),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_0,		0x000070),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_1,		0x000074),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_2,		0x000078),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_3,		0x00007c),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_4,		0x000080),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_5,		0x000084),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_6,		0x000088),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_7,		0x00008c),
+	REG(SYS_COUNT_RX_GREEN_PRIO_0,		0x000090),
+	REG(SYS_COUNT_RX_GREEN_PRIO_1,		0x000094),
+	REG(SYS_COUNT_RX_GREEN_PRIO_2,		0x000098),
+	REG(SYS_COUNT_RX_GREEN_PRIO_3,		0x00009c),
+	REG(SYS_COUNT_RX_GREEN_PRIO_4,		0x0000a0),
+	REG(SYS_COUNT_RX_GREEN_PRIO_5,		0x0000a4),
+	REG(SYS_COUNT_RX_GREEN_PRIO_6,		0x0000a8),
+	REG(SYS_COUNT_RX_GREEN_PRIO_7,		0x0000ac),
 	REG(SYS_COUNT_TX_OCTETS,		0x000200),
+	REG(SYS_COUNT_TX_UNICAST,		0x000204),
+	REG(SYS_COUNT_TX_MULTICAST,		0x000208),
+	REG(SYS_COUNT_TX_BROADCAST,		0x00020c),
 	REG(SYS_COUNT_TX_COLLISION,		0x000210),
 	REG(SYS_COUNT_TX_DROPS,			0x000214),
+	REG(SYS_COUNT_TX_PAUSE,			0x000218),
 	REG(SYS_COUNT_TX_64,			0x00021c),
 	REG(SYS_COUNT_TX_65_127,		0x000220),
 	REG(SYS_COUNT_TX_128_255,		0x000224),
@@ -298,7 +331,41 @@ static const u32 vsc9959_sys_regmap[] = {
 	REG(SYS_COUNT_TX_512_1023,		0x00022c),
 	REG(SYS_COUNT_TX_1024_1526,		0x000230),
 	REG(SYS_COUNT_TX_1527_MAX,		0x000234),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_0,		0x000238),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_1,		0x00023c),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_2,		0x000240),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_3,		0x000244),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_4,		0x000248),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_5,		0x00024c),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_6,		0x000250),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_7,		0x000254),
+	REG(SYS_COUNT_TX_GREEN_PRIO_0,		0x000258),
+	REG(SYS_COUNT_TX_GREEN_PRIO_1,		0x00025c),
+	REG(SYS_COUNT_TX_GREEN_PRIO_2,		0x000260),
+	REG(SYS_COUNT_TX_GREEN_PRIO_3,		0x000264),
+	REG(SYS_COUNT_TX_GREEN_PRIO_4,		0x000268),
+	REG(SYS_COUNT_TX_GREEN_PRIO_5,		0x00026c),
+	REG(SYS_COUNT_TX_GREEN_PRIO_6,		0x000270),
+	REG(SYS_COUNT_TX_GREEN_PRIO_7,		0x000274),
 	REG(SYS_COUNT_TX_AGING,			0x000278),
+	REG(SYS_COUNT_DROP_LOCAL,		0x000400),
+	REG(SYS_COUNT_DROP_TAIL,		0x000404),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_0,	0x000408),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_1,	0x00040c),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_2,	0x000410),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_3,	0x000414),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_4,	0x000418),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_5,	0x00041c),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_6,	0x000420),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_7,	0x000424),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_0,	0x000428),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_1,	0x00042c),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_2,	0x000430),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_3,	0x000434),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_4,	0x000438),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_5,	0x00043c),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_6,	0x000440),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_7,	0x000444),
 	REG(SYS_RESET_CFG,			0x000e00),
 	REG(SYS_SR_ETYPE_CFG,			0x000e04),
 	REG(SYS_VLAN_ETYPE_CFG,			0x000e08),
@@ -554,375 +621,375 @@ static const struct reg_field vsc9959_regfields[REGFIELD_MAX] = {
 static const struct ocelot_stat_layout vsc9959_stats_layout[OCELOT_NUM_STATS] = {
 	[OCELOT_STAT_RX_OCTETS] = {
 		.name = "rx_octets",
-		.offset = 0x00,
+		.reg = SYS_COUNT_RX_OCTETS,
 	},
 	[OCELOT_STAT_RX_UNICAST] = {
 		.name = "rx_unicast",
-		.offset = 0x01,
+		.reg = SYS_COUNT_RX_UNICAST,
 	},
 	[OCELOT_STAT_RX_MULTICAST] = {
 		.name = "rx_multicast",
-		.offset = 0x02,
+		.reg = SYS_COUNT_RX_MULTICAST,
 	},
 	[OCELOT_STAT_RX_BROADCAST] = {
 		.name = "rx_broadcast",
-		.offset = 0x03,
+		.reg = SYS_COUNT_RX_BROADCAST,
 	},
 	[OCELOT_STAT_RX_SHORTS] = {
 		.name = "rx_shorts",
-		.offset = 0x04,
+		.reg = SYS_COUNT_RX_SHORTS,
 	},
 	[OCELOT_STAT_RX_FRAGMENTS] = {
 		.name = "rx_fragments",
-		.offset = 0x05,
+		.reg = SYS_COUNT_RX_FRAGMENTS,
 	},
 	[OCELOT_STAT_RX_JABBERS] = {
 		.name = "rx_jabbers",
-		.offset = 0x06,
+		.reg = SYS_COUNT_RX_JABBERS,
 	},
 	[OCELOT_STAT_RX_CRC_ALIGN_ERRS] = {
 		.name = "rx_crc_align_errs",
-		.offset = 0x07,
+		.reg = SYS_COUNT_RX_CRC_ALIGN_ERRS,
 	},
 	[OCELOT_STAT_RX_SYM_ERRS] = {
 		.name = "rx_sym_errs",
-		.offset = 0x08,
+		.reg = SYS_COUNT_RX_SYM_ERRS,
 	},
 	[OCELOT_STAT_RX_64] = {
 		.name = "rx_frames_below_65_octets",
-		.offset = 0x09,
+		.reg = SYS_COUNT_RX_64,
 	},
 	[OCELOT_STAT_RX_65_127] = {
 		.name = "rx_frames_65_to_127_octets",
-		.offset = 0x0A,
+		.reg = SYS_COUNT_RX_65_127,
 	},
 	[OCELOT_STAT_RX_128_255] = {
 		.name = "rx_frames_128_to_255_octets",
-		.offset = 0x0B,
+		.reg = SYS_COUNT_RX_128_255,
 	},
 	[OCELOT_STAT_RX_256_511] = {
 		.name = "rx_frames_256_to_511_octets",
-		.offset = 0x0C,
+		.reg = SYS_COUNT_RX_256_511,
 	},
 	[OCELOT_STAT_RX_512_1023] = {
 		.name = "rx_frames_512_to_1023_octets",
-		.offset = 0x0D,
+		.reg = SYS_COUNT_RX_512_1023,
 	},
 	[OCELOT_STAT_RX_1024_1526] = {
 		.name = "rx_frames_1024_to_1526_octets",
-		.offset = 0x0E,
+		.reg = SYS_COUNT_RX_1024_1526,
 	},
 	[OCELOT_STAT_RX_1527_MAX] = {
 		.name = "rx_frames_over_1526_octets",
-		.offset = 0x0F,
+		.reg = SYS_COUNT_RX_1527_MAX,
 	},
 	[OCELOT_STAT_RX_PAUSE] = {
 		.name = "rx_pause",
-		.offset = 0x10,
+		.reg = SYS_COUNT_RX_PAUSE,
 	},
 	[OCELOT_STAT_RX_CONTROL] = {
 		.name = "rx_control",
-		.offset = 0x11,
+		.reg = SYS_COUNT_RX_CONTROL,
 	},
 	[OCELOT_STAT_RX_LONGS] = {
 		.name = "rx_longs",
-		.offset = 0x12,
+		.reg = SYS_COUNT_RX_LONGS,
 	},
 	[OCELOT_STAT_RX_CLASSIFIED_DROPS] = {
 		.name = "rx_classified_drops",
-		.offset = 0x13,
+		.reg = SYS_COUNT_RX_CLASSIFIED_DROPS,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_0] = {
 		.name = "rx_red_prio_0",
-		.offset = 0x14,
+		.reg = SYS_COUNT_RX_RED_PRIO_0,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_1] = {
 		.name = "rx_red_prio_1",
-		.offset = 0x15,
+		.reg = SYS_COUNT_RX_RED_PRIO_1,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_2] = {
 		.name = "rx_red_prio_2",
-		.offset = 0x16,
+		.reg = SYS_COUNT_RX_RED_PRIO_2,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_3] = {
 		.name = "rx_red_prio_3",
-		.offset = 0x17,
+		.reg = SYS_COUNT_RX_RED_PRIO_3,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_4] = {
 		.name = "rx_red_prio_4",
-		.offset = 0x18,
+		.reg = SYS_COUNT_RX_RED_PRIO_4,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_5] = {
 		.name = "rx_red_prio_5",
-		.offset = 0x19,
+		.reg = SYS_COUNT_RX_RED_PRIO_5,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_6] = {
 		.name = "rx_red_prio_6",
-		.offset = 0x1A,
+		.reg = SYS_COUNT_RX_RED_PRIO_6,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_7] = {
 		.name = "rx_red_prio_7",
-		.offset = 0x1B,
+		.reg = SYS_COUNT_RX_RED_PRIO_7,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_0] = {
 		.name = "rx_yellow_prio_0",
-		.offset = 0x1C,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_0,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_1] = {
 		.name = "rx_yellow_prio_1",
-		.offset = 0x1D,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_1,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_2] = {
 		.name = "rx_yellow_prio_2",
-		.offset = 0x1E,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_2,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_3] = {
 		.name = "rx_yellow_prio_3",
-		.offset = 0x1F,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_3,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_4] = {
 		.name = "rx_yellow_prio_4",
-		.offset = 0x20,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_4,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_5] = {
 		.name = "rx_yellow_prio_5",
-		.offset = 0x21,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_5,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_6] = {
 		.name = "rx_yellow_prio_6",
-		.offset = 0x22,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_6,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_7] = {
 		.name = "rx_yellow_prio_7",
-		.offset = 0x23,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_7,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_0] = {
 		.name = "rx_green_prio_0",
-		.offset = 0x24,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_0,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_1] = {
 		.name = "rx_green_prio_1",
-		.offset = 0x25,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_1,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_2] = {
 		.name = "rx_green_prio_2",
-		.offset = 0x26,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_2,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_3] = {
 		.name = "rx_green_prio_3",
-		.offset = 0x27,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_3,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_4] = {
 		.name = "rx_green_prio_4",
-		.offset = 0x28,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_4,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_5] = {
 		.name = "rx_green_prio_5",
-		.offset = 0x29,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_5,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_6] = {
 		.name = "rx_green_prio_6",
-		.offset = 0x2A,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_6,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_7] = {
 		.name = "rx_green_prio_7",
-		.offset = 0x2B,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_7,
 	},
 	[OCELOT_STAT_TX_OCTETS] = {
 		.name = "tx_octets",
-		.offset = 0x80,
+		.reg = SYS_COUNT_TX_OCTETS,
 	},
 	[OCELOT_STAT_TX_UNICAST] = {
 		.name = "tx_unicast",
-		.offset = 0x81,
+		.reg = SYS_COUNT_TX_UNICAST,
 	},
 	[OCELOT_STAT_TX_MULTICAST] = {
 		.name = "tx_multicast",
-		.offset = 0x82,
+		.reg = SYS_COUNT_TX_MULTICAST,
 	},
 	[OCELOT_STAT_TX_BROADCAST] = {
 		.name = "tx_broadcast",
-		.offset = 0x83,
+		.reg = SYS_COUNT_TX_BROADCAST,
 	},
 	[OCELOT_STAT_TX_COLLISION] = {
 		.name = "tx_collision",
-		.offset = 0x84,
+		.reg = SYS_COUNT_TX_COLLISION,
 	},
 	[OCELOT_STAT_TX_DROPS] = {
 		.name = "tx_drops",
-		.offset = 0x85,
+		.reg = SYS_COUNT_TX_DROPS,
 	},
 	[OCELOT_STAT_TX_PAUSE] = {
 		.name = "tx_pause",
-		.offset = 0x86,
+		.reg = SYS_COUNT_TX_PAUSE,
 	},
 	[OCELOT_STAT_TX_64] = {
 		.name = "tx_frames_below_65_octets",
-		.offset = 0x87,
+		.reg = SYS_COUNT_TX_64,
 	},
 	[OCELOT_STAT_TX_65_127] = {
 		.name = "tx_frames_65_to_127_octets",
-		.offset = 0x88,
+		.reg = SYS_COUNT_TX_65_127,
 	},
 	[OCELOT_STAT_TX_128_255] = {
 		.name = "tx_frames_128_255_octets",
-		.offset = 0x89,
+		.reg = SYS_COUNT_TX_128_255,
 	},
 	[OCELOT_STAT_TX_256_511] = {
 		.name = "tx_frames_256_511_octets",
-		.offset = 0x8A,
+		.reg = SYS_COUNT_TX_256_511,
 	},
 	[OCELOT_STAT_TX_512_1023] = {
 		.name = "tx_frames_512_1023_octets",
-		.offset = 0x8B,
+		.reg = SYS_COUNT_TX_512_1023,
 	},
 	[OCELOT_STAT_TX_1024_1526] = {
 		.name = "tx_frames_1024_1526_octets",
-		.offset = 0x8C,
+		.reg = SYS_COUNT_TX_1024_1526,
 	},
 	[OCELOT_STAT_TX_1527_MAX] = {
 		.name = "tx_frames_over_1526_octets",
-		.offset = 0x8D,
+		.reg = SYS_COUNT_TX_1527_MAX,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_0] = {
 		.name = "tx_yellow_prio_0",
-		.offset = 0x8E,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_0,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_1] = {
 		.name = "tx_yellow_prio_1",
-		.offset = 0x8F,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_1,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_2] = {
 		.name = "tx_yellow_prio_2",
-		.offset = 0x90,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_2,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_3] = {
 		.name = "tx_yellow_prio_3",
-		.offset = 0x91,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_3,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_4] = {
 		.name = "tx_yellow_prio_4",
-		.offset = 0x92,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_4,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_5] = {
 		.name = "tx_yellow_prio_5",
-		.offset = 0x93,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_5,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_6] = {
 		.name = "tx_yellow_prio_6",
-		.offset = 0x94,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_6,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_7] = {
 		.name = "tx_yellow_prio_7",
-		.offset = 0x95,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_7,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_0] = {
 		.name = "tx_green_prio_0",
-		.offset = 0x96,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_0,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_1] = {
 		.name = "tx_green_prio_1",
-		.offset = 0x97,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_1,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_2] = {
 		.name = "tx_green_prio_2",
-		.offset = 0x98,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_2,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_3] = {
 		.name = "tx_green_prio_3",
-		.offset = 0x99,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_3,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_4] = {
 		.name = "tx_green_prio_4",
-		.offset = 0x9A,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_4,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_5] = {
 		.name = "tx_green_prio_5",
-		.offset = 0x9B,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_5,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_6] = {
 		.name = "tx_green_prio_6",
-		.offset = 0x9C,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_6,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_7] = {
 		.name = "tx_green_prio_7",
-		.offset = 0x9D,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_7,
 	},
 	[OCELOT_STAT_TX_AGED] = {
 		.name = "tx_aged",
-		.offset = 0x9E,
+		.reg = SYS_COUNT_TX_AGING,
 	},
 	[OCELOT_STAT_DROP_LOCAL] = {
 		.name = "drop_local",
-		.offset = 0x100,
+		.reg = SYS_COUNT_DROP_LOCAL,
 	},
 	[OCELOT_STAT_DROP_TAIL] = {
 		.name = "drop_tail",
-		.offset = 0x101,
+		.reg = SYS_COUNT_DROP_TAIL,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_0] = {
 		.name = "drop_yellow_prio_0",
-		.offset = 0x102,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_0,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_1] = {
 		.name = "drop_yellow_prio_1",
-		.offset = 0x103,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_1,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_2] = {
 		.name = "drop_yellow_prio_2",
-		.offset = 0x104,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_2,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_3] = {
 		.name = "drop_yellow_prio_3",
-		.offset = 0x105,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_3,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_4] = {
 		.name = "drop_yellow_prio_4",
-		.offset = 0x106,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_4,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_5] = {
 		.name = "drop_yellow_prio_5",
-		.offset = 0x107,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_5,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_6] = {
 		.name = "drop_yellow_prio_6",
-		.offset = 0x108,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_6,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_7] = {
 		.name = "drop_yellow_prio_7",
-		.offset = 0x109,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_7,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_0] = {
 		.name = "drop_green_prio_0",
-		.offset = 0x10A,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_0,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_1] = {
 		.name = "drop_green_prio_1",
-		.offset = 0x10B,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_1,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_2] = {
 		.name = "drop_green_prio_2",
-		.offset = 0x10C,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_2,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_3] = {
 		.name = "drop_green_prio_3",
-		.offset = 0x10D,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_3,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_4] = {
 		.name = "drop_green_prio_4",
-		.offset = 0x10E,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_4,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_5] = {
 		.name = "drop_green_prio_5",
-		.offset = 0x10F,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_5,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_6] = {
 		.name = "drop_green_prio_6",
-		.offset = 0x110,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_6,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_7] = {
 		.name = "drop_green_prio_7",
-		.offset = 0x111,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_7,
 	},
 };
 
diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
index fe5d4642d0bc..b34f4cdfe814 100644
--- a/drivers/net/dsa/ocelot/seville_vsc9953.c
+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
@@ -270,10 +270,14 @@ static const u32 vsc9953_rew_regmap[] = {
 
 static const u32 vsc9953_sys_regmap[] = {
 	REG(SYS_COUNT_RX_OCTETS,		0x000000),
+	REG(SYS_COUNT_RX_UNICAST,		0x000004),
 	REG(SYS_COUNT_RX_MULTICAST,		0x000008),
+	REG(SYS_COUNT_RX_BROADCAST,		0x00000c),
 	REG(SYS_COUNT_RX_SHORTS,		0x000010),
 	REG(SYS_COUNT_RX_FRAGMENTS,		0x000014),
 	REG(SYS_COUNT_RX_JABBERS,		0x000018),
+	REG(SYS_COUNT_RX_CRC_ALIGN_ERRS,	0x00001c),
+	REG(SYS_COUNT_RX_SYM_ERRS,		0x000020),
 	REG(SYS_COUNT_RX_64,			0x000024),
 	REG(SYS_COUNT_RX_65_127,		0x000028),
 	REG(SYS_COUNT_RX_128_255,		0x00002c),
@@ -281,10 +285,41 @@ static const u32 vsc9953_sys_regmap[] = {
 	REG(SYS_COUNT_RX_512_1023,		0x000034),
 	REG(SYS_COUNT_RX_1024_1526,		0x000038),
 	REG(SYS_COUNT_RX_1527_MAX,		0x00003c),
+	REG(SYS_COUNT_RX_PAUSE,			0x000040),
+	REG(SYS_COUNT_RX_CONTROL,		0x000044),
 	REG(SYS_COUNT_RX_LONGS,			0x000048),
+	REG(SYS_COUNT_RX_CLASSIFIED_DROPS,	0x00004c),
+	REG(SYS_COUNT_RX_RED_PRIO_0,		0x000050),
+	REG(SYS_COUNT_RX_RED_PRIO_1,		0x000054),
+	REG(SYS_COUNT_RX_RED_PRIO_2,		0x000058),
+	REG(SYS_COUNT_RX_RED_PRIO_3,		0x00005c),
+	REG(SYS_COUNT_RX_RED_PRIO_4,		0x000060),
+	REG(SYS_COUNT_RX_RED_PRIO_5,		0x000064),
+	REG(SYS_COUNT_RX_RED_PRIO_6,		0x000068),
+	REG(SYS_COUNT_RX_RED_PRIO_7,		0x00006c),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_0,		0x000070),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_1,		0x000074),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_2,		0x000078),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_3,		0x00007c),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_4,		0x000080),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_5,		0x000084),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_6,		0x000088),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_7,		0x00008c),
+	REG(SYS_COUNT_RX_GREEN_PRIO_0,		0x000090),
+	REG(SYS_COUNT_RX_GREEN_PRIO_1,		0x000094),
+	REG(SYS_COUNT_RX_GREEN_PRIO_2,		0x000098),
+	REG(SYS_COUNT_RX_GREEN_PRIO_3,		0x00009c),
+	REG(SYS_COUNT_RX_GREEN_PRIO_4,		0x0000a0),
+	REG(SYS_COUNT_RX_GREEN_PRIO_5,		0x0000a4),
+	REG(SYS_COUNT_RX_GREEN_PRIO_6,		0x0000a8),
+	REG(SYS_COUNT_RX_GREEN_PRIO_7,		0x0000ac),
 	REG(SYS_COUNT_TX_OCTETS,		0x000100),
+	REG(SYS_COUNT_TX_UNICAST,		0x000104),
+	REG(SYS_COUNT_TX_MULTICAST,		0x000108),
+	REG(SYS_COUNT_TX_BROADCAST,		0x00010c),
 	REG(SYS_COUNT_TX_COLLISION,		0x000110),
 	REG(SYS_COUNT_TX_DROPS,			0x000114),
+	REG(SYS_COUNT_TX_PAUSE,			0x000118),
 	REG(SYS_COUNT_TX_64,			0x00011c),
 	REG(SYS_COUNT_TX_65_127,		0x000120),
 	REG(SYS_COUNT_TX_128_255,		0x000124),
@@ -292,7 +327,41 @@ static const u32 vsc9953_sys_regmap[] = {
 	REG(SYS_COUNT_TX_512_1023,		0x00012c),
 	REG(SYS_COUNT_TX_1024_1526,		0x000130),
 	REG(SYS_COUNT_TX_1527_MAX,		0x000134),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_0,		0x000138),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_1,		0x00013c),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_2,		0x000140),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_3,		0x000144),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_4,		0x000148),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_5,		0x00014c),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_6,		0x000150),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_7,		0x000154),
+	REG(SYS_COUNT_TX_GREEN_PRIO_0,		0x000158),
+	REG(SYS_COUNT_TX_GREEN_PRIO_1,		0x00015c),
+	REG(SYS_COUNT_TX_GREEN_PRIO_2,		0x000160),
+	REG(SYS_COUNT_TX_GREEN_PRIO_3,		0x000164),
+	REG(SYS_COUNT_TX_GREEN_PRIO_4,		0x000168),
+	REG(SYS_COUNT_TX_GREEN_PRIO_5,		0x00016c),
+	REG(SYS_COUNT_TX_GREEN_PRIO_6,		0x000170),
+	REG(SYS_COUNT_TX_GREEN_PRIO_7,		0x000174),
 	REG(SYS_COUNT_TX_AGING,			0x000178),
+	REG(SYS_COUNT_DROP_LOCAL,		0x000200),
+	REG(SYS_COUNT_DROP_TAIL,		0x000204),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_0,	0x000208),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_1,	0x00020c),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_2,	0x000210),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_3,	0x000214),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_4,	0x000218),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_5,	0x00021c),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_6,	0x000220),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_7,	0x000224),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_0,	0x000228),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_1,	0x00022c),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_2,	0x000230),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_3,	0x000234),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_4,	0x000238),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_5,	0x00023c),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_6,	0x000240),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_7,	0x000244),
 	REG(SYS_RESET_CFG,			0x000318),
 	REG_RESERVED(SYS_SR_ETYPE_CFG),
 	REG(SYS_VLAN_ETYPE_CFG,			0x000320),
@@ -548,375 +617,375 @@ static const struct reg_field vsc9953_regfields[REGFIELD_MAX] = {
 static const struct ocelot_stat_layout vsc9953_stats_layout[OCELOT_NUM_STATS] = {
 	[OCELOT_STAT_RX_OCTETS] = {
 		.name = "rx_octets",
-		.offset = 0x00,
+		.reg = SYS_COUNT_RX_OCTETS,
 	},
 	[OCELOT_STAT_RX_UNICAST] = {
 		.name = "rx_unicast",
-		.offset = 0x01,
+		.reg = SYS_COUNT_RX_UNICAST,
 	},
 	[OCELOT_STAT_RX_MULTICAST] = {
 		.name = "rx_multicast",
-		.offset = 0x02,
+		.reg = SYS_COUNT_RX_MULTICAST,
 	},
 	[OCELOT_STAT_RX_BROADCAST] = {
 		.name = "rx_broadcast",
-		.offset = 0x03,
+		.reg = SYS_COUNT_RX_BROADCAST,
 	},
 	[OCELOT_STAT_RX_SHORTS] = {
 		.name = "rx_shorts",
-		.offset = 0x04,
+		.reg = SYS_COUNT_RX_SHORTS,
 	},
 	[OCELOT_STAT_RX_FRAGMENTS] = {
 		.name = "rx_fragments",
-		.offset = 0x05,
+		.reg = SYS_COUNT_RX_FRAGMENTS,
 	},
 	[OCELOT_STAT_RX_JABBERS] = {
 		.name = "rx_jabbers",
-		.offset = 0x06,
+		.reg = SYS_COUNT_RX_JABBERS,
 	},
 	[OCELOT_STAT_RX_CRC_ALIGN_ERRS] = {
 		.name = "rx_crc_align_errs",
-		.offset = 0x07,
+		.reg = SYS_COUNT_RX_CRC_ALIGN_ERRS,
 	},
 	[OCELOT_STAT_RX_SYM_ERRS] = {
 		.name = "rx_sym_errs",
-		.offset = 0x08,
+		.reg = SYS_COUNT_RX_SYM_ERRS,
 	},
 	[OCELOT_STAT_RX_64] = {
 		.name = "rx_frames_below_65_octets",
-		.offset = 0x09,
+		.reg = SYS_COUNT_RX_64,
 	},
 	[OCELOT_STAT_RX_65_127] = {
 		.name = "rx_frames_65_to_127_octets",
-		.offset = 0x0A,
+		.reg = SYS_COUNT_RX_65_127,
 	},
 	[OCELOT_STAT_RX_128_255] = {
 		.name = "rx_frames_128_to_255_octets",
-		.offset = 0x0B,
+		.reg = SYS_COUNT_RX_128_255,
 	},
 	[OCELOT_STAT_RX_256_511] = {
 		.name = "rx_frames_256_to_511_octets",
-		.offset = 0x0C,
+		.reg = SYS_COUNT_RX_256_511,
 	},
 	[OCELOT_STAT_RX_512_1023] = {
 		.name = "rx_frames_512_to_1023_octets",
-		.offset = 0x0D,
+		.reg = SYS_COUNT_RX_512_1023,
 	},
 	[OCELOT_STAT_RX_1024_1526] = {
 		.name = "rx_frames_1024_to_1526_octets",
-		.offset = 0x0E,
+		.reg = SYS_COUNT_RX_1024_1526,
 	},
 	[OCELOT_STAT_RX_1527_MAX] = {
 		.name = "rx_frames_over_1526_octets",
-		.offset = 0x0F,
+		.reg = SYS_COUNT_RX_1527_MAX,
 	},
 	[OCELOT_STAT_RX_PAUSE] = {
 		.name = "rx_pause",
-		.offset = 0x10,
+		.reg = SYS_COUNT_RX_PAUSE,
 	},
 	[OCELOT_STAT_RX_CONTROL] = {
 		.name = "rx_control",
-		.offset = 0x11,
+		.reg = SYS_COUNT_RX_CONTROL,
 	},
 	[OCELOT_STAT_RX_LONGS] = {
 		.name = "rx_longs",
-		.offset = 0x12,
+		.reg = SYS_COUNT_RX_LONGS,
 	},
 	[OCELOT_STAT_RX_CLASSIFIED_DROPS] = {
 		.name = "rx_classified_drops",
-		.offset = 0x13,
+		.reg = SYS_COUNT_RX_CLASSIFIED_DROPS,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_0] = {
 		.name = "rx_red_prio_0",
-		.offset = 0x14,
+		.reg = SYS_COUNT_RX_RED_PRIO_0,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_1] = {
 		.name = "rx_red_prio_1",
-		.offset = 0x15,
+		.reg = SYS_COUNT_RX_RED_PRIO_1,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_2] = {
 		.name = "rx_red_prio_2",
-		.offset = 0x16,
+		.reg = SYS_COUNT_RX_RED_PRIO_2,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_3] = {
 		.name = "rx_red_prio_3",
-		.offset = 0x17,
+		.reg = SYS_COUNT_RX_RED_PRIO_3,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_4] = {
 		.name = "rx_red_prio_4",
-		.offset = 0x18,
+		.reg = SYS_COUNT_RX_RED_PRIO_4,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_5] = {
 		.name = "rx_red_prio_5",
-		.offset = 0x19,
+		.reg = SYS_COUNT_RX_RED_PRIO_5,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_6] = {
 		.name = "rx_red_prio_6",
-		.offset = 0x1A,
+		.reg = SYS_COUNT_RX_RED_PRIO_6,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_7] = {
 		.name = "rx_red_prio_7",
-		.offset = 0x1B,
+		.reg = SYS_COUNT_RX_RED_PRIO_7,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_0] = {
 		.name = "rx_yellow_prio_0",
-		.offset = 0x1C,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_0,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_1] = {
 		.name = "rx_yellow_prio_1",
-		.offset = 0x1D,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_1,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_2] = {
 		.name = "rx_yellow_prio_2",
-		.offset = 0x1E,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_2,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_3] = {
 		.name = "rx_yellow_prio_3",
-		.offset = 0x1F,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_3,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_4] = {
 		.name = "rx_yellow_prio_4",
-		.offset = 0x20,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_4,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_5] = {
 		.name = "rx_yellow_prio_5",
-		.offset = 0x21,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_5,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_6] = {
 		.name = "rx_yellow_prio_6",
-		.offset = 0x22,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_6,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_7] = {
 		.name = "rx_yellow_prio_7",
-		.offset = 0x23,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_7,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_0] = {
 		.name = "rx_green_prio_0",
-		.offset = 0x24,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_0,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_1] = {
 		.name = "rx_green_prio_1",
-		.offset = 0x25,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_1,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_2] = {
 		.name = "rx_green_prio_2",
-		.offset = 0x26,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_2,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_3] = {
 		.name = "rx_green_prio_3",
-		.offset = 0x27,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_3,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_4] = {
 		.name = "rx_green_prio_4",
-		.offset = 0x28,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_4,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_5] = {
 		.name = "rx_green_prio_5",
-		.offset = 0x29,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_5,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_6] = {
 		.name = "rx_green_prio_6",
-		.offset = 0x2A,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_6,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_7] = {
 		.name = "rx_green_prio_7",
-		.offset = 0x2B,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_7,
 	},
 	[OCELOT_STAT_TX_OCTETS] = {
 		.name = "tx_octets",
-		.offset = 0x40,
+		.reg = SYS_COUNT_TX_OCTETS,
 	},
 	[OCELOT_STAT_TX_UNICAST] = {
 		.name = "tx_unicast",
-		.offset = 0x41,
+		.reg = SYS_COUNT_TX_UNICAST,
 	},
 	[OCELOT_STAT_TX_MULTICAST] = {
 		.name = "tx_multicast",
-		.offset = 0x42,
+		.reg = SYS_COUNT_TX_MULTICAST,
 	},
 	[OCELOT_STAT_TX_BROADCAST] = {
 		.name = "tx_broadcast",
-		.offset = 0x43,
+		.reg = SYS_COUNT_TX_BROADCAST,
 	},
 	[OCELOT_STAT_TX_COLLISION] = {
 		.name = "tx_collision",
-		.offset = 0x44,
+		.reg = SYS_COUNT_TX_COLLISION,
 	},
 	[OCELOT_STAT_TX_DROPS] = {
 		.name = "tx_drops",
-		.offset = 0x45,
+		.reg = SYS_COUNT_TX_DROPS,
 	},
 	[OCELOT_STAT_TX_PAUSE] = {
 		.name = "tx_pause",
-		.offset = 0x46,
+		.reg = SYS_COUNT_TX_PAUSE,
 	},
 	[OCELOT_STAT_TX_64] = {
 		.name = "tx_frames_below_65_octets",
-		.offset = 0x47,
+		.reg = SYS_COUNT_TX_64,
 	},
 	[OCELOT_STAT_TX_65_127] = {
 		.name = "tx_frames_65_to_127_octets",
-		.offset = 0x48,
+		.reg = SYS_COUNT_TX_65_127,
 	},
 	[OCELOT_STAT_TX_128_255] = {
 		.name = "tx_frames_128_255_octets",
-		.offset = 0x49,
+		.reg = SYS_COUNT_TX_128_255,
 	},
 	[OCELOT_STAT_TX_256_511] = {
 		.name = "tx_frames_256_511_octets",
-		.offset = 0x4A,
+		.reg = SYS_COUNT_TX_256_511,
 	},
 	[OCELOT_STAT_TX_512_1023] = {
 		.name = "tx_frames_512_1023_octets",
-		.offset = 0x4B,
+		.reg = SYS_COUNT_TX_512_1023,
 	},
 	[OCELOT_STAT_TX_1024_1526] = {
 		.name = "tx_frames_1024_1526_octets",
-		.offset = 0x4C,
+		.reg = SYS_COUNT_TX_1024_1526,
 	},
 	[OCELOT_STAT_TX_1527_MAX] = {
 		.name = "tx_frames_over_1526_octets",
-		.offset = 0x4D,
+		.reg = SYS_COUNT_TX_1527_MAX,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_0] = {
 		.name = "tx_yellow_prio_0",
-		.offset = 0x4E,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_0,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_1] = {
 		.name = "tx_yellow_prio_1",
-		.offset = 0x4F,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_1,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_2] = {
 		.name = "tx_yellow_prio_2",
-		.offset = 0x50,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_2,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_3] = {
 		.name = "tx_yellow_prio_3",
-		.offset = 0x51,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_3,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_4] = {
 		.name = "tx_yellow_prio_4",
-		.offset = 0x52,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_4,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_5] = {
 		.name = "tx_yellow_prio_5",
-		.offset = 0x53,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_5,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_6] = {
 		.name = "tx_yellow_prio_6",
-		.offset = 0x54,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_6,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_7] = {
 		.name = "tx_yellow_prio_7",
-		.offset = 0x55,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_7,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_0] = {
 		.name = "tx_green_prio_0",
-		.offset = 0x56,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_0,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_1] = {
 		.name = "tx_green_prio_1",
-		.offset = 0x57,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_1,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_2] = {
 		.name = "tx_green_prio_2",
-		.offset = 0x58,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_2,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_3] = {
 		.name = "tx_green_prio_3",
-		.offset = 0x59,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_3,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_4] = {
 		.name = "tx_green_prio_4",
-		.offset = 0x5A,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_4,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_5] = {
 		.name = "tx_green_prio_5",
-		.offset = 0x5B,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_5,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_6] = {
 		.name = "tx_green_prio_6",
-		.offset = 0x5C,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_6,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_7] = {
 		.name = "tx_green_prio_7",
-		.offset = 0x5D,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_7,
 	},
 	[OCELOT_STAT_TX_AGED] = {
 		.name = "tx_aged",
-		.offset = 0x5E,
+		.reg = SYS_COUNT_TX_AGING,
 	},
 	[OCELOT_STAT_DROP_LOCAL] = {
 		.name = "drop_local",
-		.offset = 0x80,
+		.reg = SYS_COUNT_DROP_LOCAL,
 	},
 	[OCELOT_STAT_DROP_TAIL] = {
 		.name = "drop_tail",
-		.offset = 0x81,
+		.reg = SYS_COUNT_DROP_TAIL,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_0] = {
 		.name = "drop_yellow_prio_0",
-		.offset = 0x82,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_0,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_1] = {
 		.name = "drop_yellow_prio_1",
-		.offset = 0x83,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_1,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_2] = {
 		.name = "drop_yellow_prio_2",
-		.offset = 0x84,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_2,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_3] = {
 		.name = "drop_yellow_prio_3",
-		.offset = 0x85,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_3,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_4] = {
 		.name = "drop_yellow_prio_4",
-		.offset = 0x86,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_4,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_5] = {
 		.name = "drop_yellow_prio_5",
-		.offset = 0x87,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_5,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_6] = {
 		.name = "drop_yellow_prio_6",
-		.offset = 0x88,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_6,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_7] = {
 		.name = "drop_yellow_prio_7",
-		.offset = 0x89,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_7,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_0] = {
 		.name = "drop_green_prio_0",
-		.offset = 0x8A,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_0,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_1] = {
 		.name = "drop_green_prio_1",
-		.offset = 0x8B,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_1,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_2] = {
 		.name = "drop_green_prio_2",
-		.offset = 0x8C,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_2,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_3] = {
 		.name = "drop_green_prio_3",
-		.offset = 0x8D,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_3,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_4] = {
 		.name = "drop_green_prio_4",
-		.offset = 0x8E,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_4,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_5] = {
 		.name = "drop_green_prio_5",
-		.offset = 0x8F,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_5,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_6] = {
 		.name = "drop_green_prio_6",
-		.offset = 0x90,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_6,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_7] = {
 		.name = "drop_green_prio_7",
-		.offset = 0x91,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_7,
 	},
 };
 
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 68991b021c56..306026e6aa11 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1881,9 +1881,8 @@ static int ocelot_port_update_stats(struct ocelot *ocelot, int port)
 	ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port), SYS_STAT_CFG);
 
 	list_for_each_entry(region, &ocelot->stats_regions, node) {
-		err = ocelot_bulk_read_rix(ocelot, SYS_COUNT_RX_OCTETS,
-					   region->offset, region->buf,
-					   region->count);
+		err = ocelot_bulk_read(ocelot, region->base, region->buf,
+				       region->count);
 		if (err)
 			return err;
 
@@ -1978,7 +1977,7 @@ static int ocelot_prepare_stats_regions(struct ocelot *ocelot)
 		if (ocelot->stats_layout[i].name[0] == '\0')
 			continue;
 
-		if (region && ocelot->stats_layout[i].offset == last + 1) {
+		if (region && ocelot->stats_layout[i].reg == last + 4) {
 			region->count++;
 		} else {
 			region = devm_kzalloc(ocelot->dev, sizeof(*region),
@@ -1986,12 +1985,12 @@ static int ocelot_prepare_stats_regions(struct ocelot *ocelot)
 			if (!region)
 				return -ENOMEM;
 
-			region->offset = ocelot->stats_layout[i].offset;
+			region->base = ocelot->stats_layout[i].reg;
 			region->count = 1;
 			list_add_tail(&region->node, &ocelot->stats_regions);
 		}
 
-		last = ocelot->stats_layout[i].offset;
+		last = ocelot->stats_layout[i].reg;
 	}
 
 	list_for_each_entry(region, &ocelot->stats_regions, node) {
diff --git a/drivers/net/ethernet/mscc/ocelot_vsc7514.c b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
index 9ff910560043..9c488953f541 100644
--- a/drivers/net/ethernet/mscc/ocelot_vsc7514.c
+++ b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
@@ -99,375 +99,375 @@ static const struct reg_field ocelot_regfields[REGFIELD_MAX] = {
 static const struct ocelot_stat_layout ocelot_stats_layout[OCELOT_NUM_STATS] = {
 	[OCELOT_STAT_RX_OCTETS] = {
 		.name = "rx_octets",
-		.offset = 0x00,
+		.reg = SYS_COUNT_RX_OCTETS,
 	},
 	[OCELOT_STAT_RX_UNICAST] = {
 		.name = "rx_unicast",
-		.offset = 0x01,
+		.reg = SYS_COUNT_RX_UNICAST,
 	},
 	[OCELOT_STAT_RX_MULTICAST] = {
 		.name = "rx_multicast",
-		.offset = 0x02,
+		.reg = SYS_COUNT_RX_MULTICAST,
 	},
 	[OCELOT_STAT_RX_BROADCAST] = {
 		.name = "rx_broadcast",
-		.offset = 0x03,
+		.reg = SYS_COUNT_RX_BROADCAST,
 	},
 	[OCELOT_STAT_RX_SHORTS] = {
 		.name = "rx_shorts",
-		.offset = 0x04,
+		.reg = SYS_COUNT_RX_SHORTS,
 	},
 	[OCELOT_STAT_RX_FRAGMENTS] = {
 		.name = "rx_fragments",
-		.offset = 0x05,
+		.reg = SYS_COUNT_RX_FRAGMENTS,
 	},
 	[OCELOT_STAT_RX_JABBERS] = {
 		.name = "rx_jabbers",
-		.offset = 0x06,
+		.reg = SYS_COUNT_RX_JABBERS,
 	},
 	[OCELOT_STAT_RX_CRC_ALIGN_ERRS] = {
 		.name = "rx_crc_align_errs",
-		.offset = 0x07,
+		.reg = SYS_COUNT_RX_CRC_ALIGN_ERRS,
 	},
 	[OCELOT_STAT_RX_SYM_ERRS] = {
 		.name = "rx_sym_errs",
-		.offset = 0x08,
+		.reg = SYS_COUNT_RX_SYM_ERRS,
 	},
 	[OCELOT_STAT_RX_64] = {
 		.name = "rx_frames_below_65_octets",
-		.offset = 0x09,
+		.reg = SYS_COUNT_RX_64,
 	},
 	[OCELOT_STAT_RX_65_127] = {
 		.name = "rx_frames_65_to_127_octets",
-		.offset = 0x0A,
+		.reg = SYS_COUNT_RX_65_127,
 	},
 	[OCELOT_STAT_RX_128_255] = {
 		.name = "rx_frames_128_to_255_octets",
-		.offset = 0x0B,
+		.reg = SYS_COUNT_RX_128_255,
 	},
 	[OCELOT_STAT_RX_256_511] = {
 		.name = "rx_frames_256_to_511_octets",
-		.offset = 0x0C,
+		.reg = SYS_COUNT_RX_256_511,
 	},
 	[OCELOT_STAT_RX_512_1023] = {
 		.name = "rx_frames_512_to_1023_octets",
-		.offset = 0x0D,
+		.reg = SYS_COUNT_RX_512_1023,
 	},
 	[OCELOT_STAT_RX_1024_1526] = {
 		.name = "rx_frames_1024_to_1526_octets",
-		.offset = 0x0E,
+		.reg = SYS_COUNT_RX_1024_1526,
 	},
 	[OCELOT_STAT_RX_1527_MAX] = {
 		.name = "rx_frames_over_1526_octets",
-		.offset = 0x0F,
+		.reg = SYS_COUNT_RX_1527_MAX,
 	},
 	[OCELOT_STAT_RX_PAUSE] = {
 		.name = "rx_pause",
-		.offset = 0x10,
+		.reg = SYS_COUNT_RX_PAUSE,
 	},
 	[OCELOT_STAT_RX_CONTROL] = {
 		.name = "rx_control",
-		.offset = 0x11,
+		.reg = SYS_COUNT_RX_CONTROL,
 	},
 	[OCELOT_STAT_RX_LONGS] = {
 		.name = "rx_longs",
-		.offset = 0x12,
+		.reg = SYS_COUNT_RX_LONGS,
 	},
 	[OCELOT_STAT_RX_CLASSIFIED_DROPS] = {
 		.name = "rx_classified_drops",
-		.offset = 0x13,
+		.reg = SYS_COUNT_RX_CLASSIFIED_DROPS,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_0] = {
 		.name = "rx_red_prio_0",
-		.offset = 0x14,
+		.reg = SYS_COUNT_RX_RED_PRIO_0,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_1] = {
 		.name = "rx_red_prio_1",
-		.offset = 0x15,
+		.reg = SYS_COUNT_RX_RED_PRIO_1,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_2] = {
 		.name = "rx_red_prio_2",
-		.offset = 0x16,
+		.reg = SYS_COUNT_RX_RED_PRIO_2,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_3] = {
 		.name = "rx_red_prio_3",
-		.offset = 0x17,
+		.reg = SYS_COUNT_RX_RED_PRIO_3,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_4] = {
 		.name = "rx_red_prio_4",
-		.offset = 0x18,
+		.reg = SYS_COUNT_RX_RED_PRIO_4,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_5] = {
 		.name = "rx_red_prio_5",
-		.offset = 0x19,
+		.reg = SYS_COUNT_RX_RED_PRIO_5,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_6] = {
 		.name = "rx_red_prio_6",
-		.offset = 0x1A,
+		.reg = SYS_COUNT_RX_RED_PRIO_6,
 	},
 	[OCELOT_STAT_RX_RED_PRIO_7] = {
 		.name = "rx_red_prio_7",
-		.offset = 0x1B,
+		.reg = SYS_COUNT_RX_RED_PRIO_7,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_0] = {
 		.name = "rx_yellow_prio_0",
-		.offset = 0x1C,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_0,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_1] = {
 		.name = "rx_yellow_prio_1",
-		.offset = 0x1D,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_1,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_2] = {
 		.name = "rx_yellow_prio_2",
-		.offset = 0x1E,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_2,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_3] = {
 		.name = "rx_yellow_prio_3",
-		.offset = 0x1F,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_3,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_4] = {
 		.name = "rx_yellow_prio_4",
-		.offset = 0x20,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_4,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_5] = {
 		.name = "rx_yellow_prio_5",
-		.offset = 0x21,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_5,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_6] = {
 		.name = "rx_yellow_prio_6",
-		.offset = 0x22,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_6,
 	},
 	[OCELOT_STAT_RX_YELLOW_PRIO_7] = {
 		.name = "rx_yellow_prio_7",
-		.offset = 0x23,
+		.reg = SYS_COUNT_RX_YELLOW_PRIO_7,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_0] = {
 		.name = "rx_green_prio_0",
-		.offset = 0x24,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_0,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_1] = {
 		.name = "rx_green_prio_1",
-		.offset = 0x25,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_1,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_2] = {
 		.name = "rx_green_prio_2",
-		.offset = 0x26,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_2,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_3] = {
 		.name = "rx_green_prio_3",
-		.offset = 0x27,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_3,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_4] = {
 		.name = "rx_green_prio_4",
-		.offset = 0x28,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_4,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_5] = {
 		.name = "rx_green_prio_5",
-		.offset = 0x29,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_5,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_6] = {
 		.name = "rx_green_prio_6",
-		.offset = 0x2A,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_6,
 	},
 	[OCELOT_STAT_RX_GREEN_PRIO_7] = {
 		.name = "rx_green_prio_7",
-		.offset = 0x2B,
+		.reg = SYS_COUNT_RX_GREEN_PRIO_7,
 	},
 	[OCELOT_STAT_TX_OCTETS] = {
 		.name = "tx_octets",
-		.offset = 0x40,
+		.reg = SYS_COUNT_TX_OCTETS,
 	},
 	[OCELOT_STAT_TX_UNICAST] = {
 		.name = "tx_unicast",
-		.offset = 0x41,
+		.reg = SYS_COUNT_TX_UNICAST,
 	},
 	[OCELOT_STAT_TX_MULTICAST] = {
 		.name = "tx_multicast",
-		.offset = 0x42,
+		.reg = SYS_COUNT_TX_MULTICAST,
 	},
 	[OCELOT_STAT_TX_BROADCAST] = {
 		.name = "tx_broadcast",
-		.offset = 0x43,
+		.reg = SYS_COUNT_TX_BROADCAST,
 	},
 	[OCELOT_STAT_TX_COLLISION] = {
 		.name = "tx_collision",
-		.offset = 0x44,
+		.reg = SYS_COUNT_TX_COLLISION,
 	},
 	[OCELOT_STAT_TX_DROPS] = {
 		.name = "tx_drops",
-		.offset = 0x45,
+		.reg = SYS_COUNT_TX_DROPS,
 	},
 	[OCELOT_STAT_TX_PAUSE] = {
 		.name = "tx_pause",
-		.offset = 0x46,
+		.reg = SYS_COUNT_TX_PAUSE,
 	},
 	[OCELOT_STAT_TX_64] = {
 		.name = "tx_frames_below_65_octets",
-		.offset = 0x47,
+		.reg = SYS_COUNT_TX_64,
 	},
 	[OCELOT_STAT_TX_65_127] = {
 		.name = "tx_frames_65_to_127_octets",
-		.offset = 0x48,
+		.reg = SYS_COUNT_TX_65_127,
 	},
 	[OCELOT_STAT_TX_128_255] = {
 		.name = "tx_frames_128_255_octets",
-		.offset = 0x49,
+		.reg = SYS_COUNT_TX_128_255,
 	},
 	[OCELOT_STAT_TX_256_511] = {
 		.name = "tx_frames_256_511_octets",
-		.offset = 0x4A,
+		.reg = SYS_COUNT_TX_256_511,
 	},
 	[OCELOT_STAT_TX_512_1023] = {
 		.name = "tx_frames_512_1023_octets",
-		.offset = 0x4B,
+		.reg = SYS_COUNT_TX_512_1023,
 	},
 	[OCELOT_STAT_TX_1024_1526] = {
 		.name = "tx_frames_1024_1526_octets",
-		.offset = 0x4C,
+		.reg = SYS_COUNT_TX_1024_1526,
 	},
 	[OCELOT_STAT_TX_1527_MAX] = {
 		.name = "tx_frames_over_1526_octets",
-		.offset = 0x4D,
+		.reg = SYS_COUNT_TX_1527_MAX,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_0] = {
 		.name = "tx_yellow_prio_0",
-		.offset = 0x4E,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_0,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_1] = {
 		.name = "tx_yellow_prio_1",
-		.offset = 0x4F,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_1,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_2] = {
 		.name = "tx_yellow_prio_2",
-		.offset = 0x50,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_2,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_3] = {
 		.name = "tx_yellow_prio_3",
-		.offset = 0x51,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_3,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_4] = {
 		.name = "tx_yellow_prio_4",
-		.offset = 0x52,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_4,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_5] = {
 		.name = "tx_yellow_prio_5",
-		.offset = 0x53,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_5,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_6] = {
 		.name = "tx_yellow_prio_6",
-		.offset = 0x54,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_6,
 	},
 	[OCELOT_STAT_TX_YELLOW_PRIO_7] = {
 		.name = "tx_yellow_prio_7",
-		.offset = 0x55,
+		.reg = SYS_COUNT_TX_YELLOW_PRIO_7,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_0] = {
 		.name = "tx_green_prio_0",
-		.offset = 0x56,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_0,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_1] = {
 		.name = "tx_green_prio_1",
-		.offset = 0x57,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_1,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_2] = {
 		.name = "tx_green_prio_2",
-		.offset = 0x58,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_2,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_3] = {
 		.name = "tx_green_prio_3",
-		.offset = 0x59,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_3,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_4] = {
 		.name = "tx_green_prio_4",
-		.offset = 0x5A,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_4,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_5] = {
 		.name = "tx_green_prio_5",
-		.offset = 0x5B,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_5,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_6] = {
 		.name = "tx_green_prio_6",
-		.offset = 0x5C,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_6,
 	},
 	[OCELOT_STAT_TX_GREEN_PRIO_7] = {
 		.name = "tx_green_prio_7",
-		.offset = 0x5D,
+		.reg = SYS_COUNT_TX_GREEN_PRIO_7,
 	},
 	[OCELOT_STAT_TX_AGED] = {
 		.name = "tx_aged",
-		.offset = 0x5E,
+		.reg = SYS_COUNT_TX_AGING,
 	},
 	[OCELOT_STAT_DROP_LOCAL] = {
 		.name = "drop_local",
-		.offset = 0x80,
+		.reg = SYS_COUNT_DROP_LOCAL,
 	},
 	[OCELOT_STAT_DROP_TAIL] = {
 		.name = "drop_tail",
-		.offset = 0x81,
+		.reg = SYS_COUNT_DROP_TAIL,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_0] = {
 		.name = "drop_yellow_prio_0",
-		.offset = 0x82,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_0,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_1] = {
 		.name = "drop_yellow_prio_1",
-		.offset = 0x83,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_1,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_2] = {
 		.name = "drop_yellow_prio_2",
-		.offset = 0x84,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_2,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_3] = {
 		.name = "drop_yellow_prio_3",
-		.offset = 0x85,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_3,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_4] = {
 		.name = "drop_yellow_prio_4",
-		.offset = 0x86,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_4,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_5] = {
 		.name = "drop_yellow_prio_5",
-		.offset = 0x87,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_5,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_6] = {
 		.name = "drop_yellow_prio_6",
-		.offset = 0x88,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_6,
 	},
 	[OCELOT_STAT_DROP_YELLOW_PRIO_7] = {
 		.name = "drop_yellow_prio_7",
-		.offset = 0x89,
+		.reg = SYS_COUNT_DROP_YELLOW_PRIO_7,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_0] = {
 		.name = "drop_green_prio_0",
-		.offset = 0x8A,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_0,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_1] = {
 		.name = "drop_green_prio_1",
-		.offset = 0x8B,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_1,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_2] = {
 		.name = "drop_green_prio_2",
-		.offset = 0x8C,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_2,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_3] = {
 		.name = "drop_green_prio_3",
-		.offset = 0x8D,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_3,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_4] = {
 		.name = "drop_green_prio_4",
-		.offset = 0x8E,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_4,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_5] = {
 		.name = "drop_green_prio_5",
-		.offset = 0x8F,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_5,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_6] = {
 		.name = "drop_green_prio_6",
-		.offset = 0x90,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_6,
 	},
 	[OCELOT_STAT_DROP_GREEN_PRIO_7] = {
 		.name = "drop_green_prio_7",
-		.offset = 0x91,
+		.reg = SYS_COUNT_DROP_GREEN_PRIO_7,
 	},
 };
 
diff --git a/drivers/net/ethernet/mscc/vsc7514_regs.c b/drivers/net/ethernet/mscc/vsc7514_regs.c
index 8ff935f7f150..9cf82ecf191c 100644
--- a/drivers/net/ethernet/mscc/vsc7514_regs.c
+++ b/drivers/net/ethernet/mscc/vsc7514_regs.c
@@ -188,6 +188,30 @@ const u32 vsc7514_sys_regmap[] = {
 	REG(SYS_COUNT_RX_CONTROL,			0x000044),
 	REG(SYS_COUNT_RX_LONGS,				0x000048),
 	REG(SYS_COUNT_RX_CLASSIFIED_DROPS,		0x00004c),
+	REG(SYS_COUNT_RX_RED_PRIO_0,			0x000050),
+	REG(SYS_COUNT_RX_RED_PRIO_1,			0x000054),
+	REG(SYS_COUNT_RX_RED_PRIO_2,			0x000058),
+	REG(SYS_COUNT_RX_RED_PRIO_3,			0x00005c),
+	REG(SYS_COUNT_RX_RED_PRIO_4,			0x000060),
+	REG(SYS_COUNT_RX_RED_PRIO_5,			0x000064),
+	REG(SYS_COUNT_RX_RED_PRIO_6,			0x000068),
+	REG(SYS_COUNT_RX_RED_PRIO_7,			0x00006c),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_0,			0x000070),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_1,			0x000074),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_2,			0x000078),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_3,			0x00007c),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_4,			0x000080),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_5,			0x000084),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_6,			0x000088),
+	REG(SYS_COUNT_RX_YELLOW_PRIO_7,			0x00008c),
+	REG(SYS_COUNT_RX_GREEN_PRIO_0,			0x000090),
+	REG(SYS_COUNT_RX_GREEN_PRIO_1,			0x000094),
+	REG(SYS_COUNT_RX_GREEN_PRIO_2,			0x000098),
+	REG(SYS_COUNT_RX_GREEN_PRIO_3,			0x00009c),
+	REG(SYS_COUNT_RX_GREEN_PRIO_4,			0x0000a0),
+	REG(SYS_COUNT_RX_GREEN_PRIO_5,			0x0000a4),
+	REG(SYS_COUNT_RX_GREEN_PRIO_6,			0x0000a8),
+	REG(SYS_COUNT_RX_GREEN_PRIO_7,			0x0000ac),
 	REG(SYS_COUNT_TX_OCTETS,			0x000100),
 	REG(SYS_COUNT_TX_UNICAST,			0x000104),
 	REG(SYS_COUNT_TX_MULTICAST,			0x000108),
@@ -202,7 +226,41 @@ const u32 vsc7514_sys_regmap[] = {
 	REG(SYS_COUNT_TX_512_1023,			0x00012c),
 	REG(SYS_COUNT_TX_1024_1526,			0x000130),
 	REG(SYS_COUNT_TX_1527_MAX,			0x000134),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_0,			0x000138),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_1,			0x00013c),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_2,			0x000140),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_3,			0x000144),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_4,			0x000148),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_5,			0x00014c),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_6,			0x000150),
+	REG(SYS_COUNT_TX_YELLOW_PRIO_7,			0x000154),
+	REG(SYS_COUNT_TX_GREEN_PRIO_0,			0x000158),
+	REG(SYS_COUNT_TX_GREEN_PRIO_1,			0x00015c),
+	REG(SYS_COUNT_TX_GREEN_PRIO_2,			0x000160),
+	REG(SYS_COUNT_TX_GREEN_PRIO_3,			0x000164),
+	REG(SYS_COUNT_TX_GREEN_PRIO_4,			0x000168),
+	REG(SYS_COUNT_TX_GREEN_PRIO_5,			0x00016c),
+	REG(SYS_COUNT_TX_GREEN_PRIO_6,			0x000170),
+	REG(SYS_COUNT_TX_GREEN_PRIO_7,			0x000174),
 	REG(SYS_COUNT_TX_AGING,				0x000178),
+	REG(SYS_COUNT_DROP_LOCAL,			0x000200),
+	REG(SYS_COUNT_DROP_TAIL,			0x000204),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_0,		0x000208),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_1,		0x00020c),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_2,		0x000210),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_3,		0x000214),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_4,		0x000218),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_5,		0x00021c),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_6,		0x000220),
+	REG(SYS_COUNT_DROP_YELLOW_PRIO_7,		0x000214),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_0,		0x000218),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_1,		0x00021c),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_2,		0x000220),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_3,		0x000224),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_4,		0x000228),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_5,		0x00022c),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_6,		0x000230),
+	REG(SYS_COUNT_DROP_GREEN_PRIO_7,		0x000234),
 	REG(SYS_RESET_CFG,				0x000508),
 	REG(SYS_CMID,					0x00050c),
 	REG(SYS_VLAN_ETYPE_CFG,				0x000510),
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 2428bc64cb1d..2edea901bbd5 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -338,6 +338,30 @@ enum ocelot_reg {
 	SYS_COUNT_RX_CONTROL,
 	SYS_COUNT_RX_LONGS,
 	SYS_COUNT_RX_CLASSIFIED_DROPS,
+	SYS_COUNT_RX_RED_PRIO_0,
+	SYS_COUNT_RX_RED_PRIO_1,
+	SYS_COUNT_RX_RED_PRIO_2,
+	SYS_COUNT_RX_RED_PRIO_3,
+	SYS_COUNT_RX_RED_PRIO_4,
+	SYS_COUNT_RX_RED_PRIO_5,
+	SYS_COUNT_RX_RED_PRIO_6,
+	SYS_COUNT_RX_RED_PRIO_7,
+	SYS_COUNT_RX_YELLOW_PRIO_0,
+	SYS_COUNT_RX_YELLOW_PRIO_1,
+	SYS_COUNT_RX_YELLOW_PRIO_2,
+	SYS_COUNT_RX_YELLOW_PRIO_3,
+	SYS_COUNT_RX_YELLOW_PRIO_4,
+	SYS_COUNT_RX_YELLOW_PRIO_5,
+	SYS_COUNT_RX_YELLOW_PRIO_6,
+	SYS_COUNT_RX_YELLOW_PRIO_7,
+	SYS_COUNT_RX_GREEN_PRIO_0,
+	SYS_COUNT_RX_GREEN_PRIO_1,
+	SYS_COUNT_RX_GREEN_PRIO_2,
+	SYS_COUNT_RX_GREEN_PRIO_3,
+	SYS_COUNT_RX_GREEN_PRIO_4,
+	SYS_COUNT_RX_GREEN_PRIO_5,
+	SYS_COUNT_RX_GREEN_PRIO_6,
+	SYS_COUNT_RX_GREEN_PRIO_7,
 	SYS_COUNT_TX_OCTETS,
 	SYS_COUNT_TX_UNICAST,
 	SYS_COUNT_TX_MULTICAST,
@@ -352,7 +376,41 @@ enum ocelot_reg {
 	SYS_COUNT_TX_512_1023,
 	SYS_COUNT_TX_1024_1526,
 	SYS_COUNT_TX_1527_MAX,
+	SYS_COUNT_TX_YELLOW_PRIO_0,
+	SYS_COUNT_TX_YELLOW_PRIO_1,
+	SYS_COUNT_TX_YELLOW_PRIO_2,
+	SYS_COUNT_TX_YELLOW_PRIO_3,
+	SYS_COUNT_TX_YELLOW_PRIO_4,
+	SYS_COUNT_TX_YELLOW_PRIO_5,
+	SYS_COUNT_TX_YELLOW_PRIO_6,
+	SYS_COUNT_TX_YELLOW_PRIO_7,
+	SYS_COUNT_TX_GREEN_PRIO_0,
+	SYS_COUNT_TX_GREEN_PRIO_1,
+	SYS_COUNT_TX_GREEN_PRIO_2,
+	SYS_COUNT_TX_GREEN_PRIO_3,
+	SYS_COUNT_TX_GREEN_PRIO_4,
+	SYS_COUNT_TX_GREEN_PRIO_5,
+	SYS_COUNT_TX_GREEN_PRIO_6,
+	SYS_COUNT_TX_GREEN_PRIO_7,
 	SYS_COUNT_TX_AGING,
+	SYS_COUNT_DROP_LOCAL,
+	SYS_COUNT_DROP_TAIL,
+	SYS_COUNT_DROP_YELLOW_PRIO_0,
+	SYS_COUNT_DROP_YELLOW_PRIO_1,
+	SYS_COUNT_DROP_YELLOW_PRIO_2,
+	SYS_COUNT_DROP_YELLOW_PRIO_3,
+	SYS_COUNT_DROP_YELLOW_PRIO_4,
+	SYS_COUNT_DROP_YELLOW_PRIO_5,
+	SYS_COUNT_DROP_YELLOW_PRIO_6,
+	SYS_COUNT_DROP_YELLOW_PRIO_7,
+	SYS_COUNT_DROP_GREEN_PRIO_0,
+	SYS_COUNT_DROP_GREEN_PRIO_1,
+	SYS_COUNT_DROP_GREEN_PRIO_2,
+	SYS_COUNT_DROP_GREEN_PRIO_3,
+	SYS_COUNT_DROP_GREEN_PRIO_4,
+	SYS_COUNT_DROP_GREEN_PRIO_5,
+	SYS_COUNT_DROP_GREEN_PRIO_6,
+	SYS_COUNT_DROP_GREEN_PRIO_7,
 	SYS_RESET_CFG,
 	SYS_SR_ETYPE_CFG,
 	SYS_VLAN_ETYPE_CFG,
@@ -633,13 +691,13 @@ enum ocelot_stat {
 };
 
 struct ocelot_stat_layout {
-	u32 offset;
+	u32 reg;
 	char name[ETH_GSTRING_LEN];
 };
 
 struct ocelot_stats_region {
 	struct list_head node;
-	u32 offset;
+	u32 base;
 	int count;
 	u32 *buf;
 };
@@ -877,8 +935,8 @@ struct ocelot_policer {
 	u32 burst; /* bytes */
 };
 
-#define ocelot_bulk_read_rix(ocelot, reg, ri, buf, count) \
-	__ocelot_bulk_read_ix(ocelot, reg, reg##_RSZ * (ri), buf, count)
+#define ocelot_bulk_read(ocelot, reg, buf, count) \
+	__ocelot_bulk_read_ix(ocelot, reg, 0, buf, count)
 
 #define ocelot_read_ix(ocelot, reg, gi, ri) \
 	__ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri))
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH v2 08/13] tracing: Improve panic/die notifiers
From: Steven Rostedt @ 2022-08-16 14:14 UTC (permalink / raw)
  To: Guilherme G. Piccoli
  Cc: akpm, bhe, pmladek, kexec, linux-kernel, linux-hyperv, netdev,
	x86, kernel-dev, kernel, halves, fabiomirmar, alejandro.j.jimenez,
	andriy.shevchenko, arnd, bp, corbet, d.hatayama, dave.hansen,
	dyoung, feng.tang, gregkh, mikelley, hidehiro.kawai.ez, jgross,
	john.ogness, keescook, luto, mhiramat, mingo, paulmck, peterz,
	senozhatsky, stern, tglx, vgoyal, vkuznets, will, Sergei Shtylyov
In-Reply-To: <20220719195325.402745-9-gpiccoli@igalia.com>

On Tue, 19 Jul 2022 16:53:21 -0300
"Guilherme G. Piccoli" <gpiccoli@igalia.com> wrote:


Sorry for the late review, but this fell to the bottom of my queue :-/

> +/*
> + * The idea is to execute the following die/panic callback early, in order
> + * to avoid showing irrelevant information in the trace (like other panic
> + * notifier functions); we are the 2nd to run, after hung_task/rcu_stall
> + * warnings get disabled (to prevent potential log flooding).
> + */
> +static int trace_die_panic_handler(struct notifier_block *self,
> +				unsigned long ev, void *unused)
> +{
> +	if (!ftrace_dump_on_oops)
> +		goto out;
> +
> +	if (self == &trace_die_notifier && ev != DIE_OOPS)
> +		goto out;

I really hate gotos that are not for clean ups.

> +
> +	ftrace_dump(ftrace_dump_on_oops);
> +
> +out:
> +	return NOTIFY_DONE;
> +}
> +

Just do:

static int trace_die_panic_handler(struct notifier_block *self,
				unsigned long ev, void *unused)
{
	if (!ftrace_dump_on_oops)
		return NOTIFY_DONE;

	/* The die notifier requires DIE_OOPS to trigger */
	if (self == &trace_die_notifier && ev != DIE_OOPS)
		return NOTIFY_DONE;

	ftrace_dump(ftrace_dump_on_oops);

	return NOTIFY_DONE;
}


Thanks,

Other than that, Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org>

-- Steve

^ permalink raw reply

* [PATCH net] net: ethernet: mtk_eth_soc: fix possible NULL pointer dereference in mtk_xdp_run
From: Lorenzo Bianconi @ 2022-08-16 14:16 UTC (permalink / raw)
  To: netdev
  Cc: nbd, john, sean.wang, Mark-MC.Lee, davem, edumazet, kuba, pabeni,
	matthias.bgg, linux-mediatek, ilias.apalodimas, lorenzo.bianconi,
	jbrouer

Fix possible NULL pointer dereference in mtk_xdp_run() if the
ebpf program returns XDP_TX and xdp_convert_buff_to_frame routine fails
returning NULL.

Fixes: 5886d26fd25bb ("net: ethernet: mtk_eth_soc: add xmit XDP support")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index d9426b01f462..8aff4c0c28bd 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1732,7 +1732,7 @@ static u32 mtk_xdp_run(struct mtk_eth *eth, struct mtk_rx_ring *ring,
 	case XDP_TX: {
 		struct xdp_frame *xdpf = xdp_convert_buff_to_frame(xdp);
 
-		if (mtk_xdp_submit_frame(eth, xdpf, dev, false)) {
+		if (!xdpf || mtk_xdp_submit_frame(eth, xdpf, dev, false)) {
 			count = &hw_stats->xdp_stats.rx_xdp_tx_errors;
 			act = XDP_DROP;
 			break;
-- 
2.37.2


^ permalink raw reply related

* [PATCH v2 1/2] stmmac: intel: Add a missing clk_disable_unprepare() call in intel_eth_pci_remove()
From: Christophe JAILLET @ 2022-08-16 14:23 UTC (permalink / raw)
  To: Giuseppe Cavallaro, Alexandre Torgue, Jose Abreu, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
	Joakim Zhang, Andrew Lunn
  Cc: linux-kernel, kernel-janitors, Christophe JAILLET,
	Andy Shevchenko, netdev, linux-stm32, linux-arm-kernel

Commit 09f012e64e4b ("stmmac: intel: Fix clock handling on error and remove
paths") removed this clk_disable_unprepare()

This was partly revert by commit ac322f86b56c ("net: stmmac: Fix clock
handling on remove path") which removed this clk_disable_unprepare()
because:
"
   While unloading the dwmac-intel driver, clk_disable_unprepare() is
   being called twice in stmmac_dvr_remove() and
   intel_eth_pci_remove(). This causes kernel panic on the second call.
"

However later on, commit 5ec55823438e8 ("net: stmmac: add clocks management
for gmac driver") has updated stmmac_dvr_remove() which do not call
clk_disable_unprepare() anymore.

So this call should now be called from intel_eth_pci_remove().

Fixes: 5ec55823438e8 ("net: stmmac: add clocks management for gmac driver")
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
Change in v2:
  * Fix a copy'n'paste typo from the error handling path of the probe to
    the remove function
  * Remove the big warning added below the --- in v1 (see link below if
    needed)
  * Add Reviewed-by:

v1:
  https://lore.kernel.org/all/b5b44a0c025d0fdddd9b9d23153261363089a06a.1659204745.git.christophe.jaillet@wanadoo.fr/


Andy proposed another way to fix the issue. See the thread above.
I won't be able to propose it myself.
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 52f9ed8db9c9..4f2b82a884b9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -1134,6 +1134,7 @@ static void intel_eth_pci_remove(struct pci_dev *pdev)
 
 	stmmac_dvr_remove(&pdev->dev);
 
+	clk_disable_unprepare(priv->plat->stmmac_clk);
 	clk_unregister_fixed_rate(priv->plat->stmmac_clk);
 
 	pcim_iounmap_regions(pdev, BIT(0));
-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 2/2] stmmac: intel: Simplify intel_eth_pci_remove()
From: Christophe JAILLET @ 2022-08-16 14:24 UTC (permalink / raw)
  To: Giuseppe Cavallaro, Alexandre Torgue, Jose Abreu, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin
  Cc: linux-kernel, kernel-janitors, Christophe JAILLET,
	Andy Shevchenko, netdev, linux-stm32, linux-arm-kernel
In-Reply-To: <d7c8c1dadf40df3a7c9e643f76ffadd0ccc1ad1b.1660659689.git.christophe.jaillet@wanadoo.fr>

There is no point to call pcim_iounmap_regions() in the remove function,
this frees a managed resource that would be release by the framework
anyway.

Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
Change in v2:
  * (no code change)
  * Remove the text added below the --- in v1 (see link below if
    needed)
  * Add Reviewed-by:

v1:
  https://lore.kernel.org/all/9f82d58aa4a6c34ec3c734399a4792d3aa23297f.1659204745.git.christophe.jaillet@wanadoo.fr/
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 4f2b82a884b9..9af25be42401 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -1136,8 +1136,6 @@ static void intel_eth_pci_remove(struct pci_dev *pdev)
 
 	clk_disable_unprepare(priv->plat->stmmac_clk);
 	clk_unregister_fixed_rate(priv->plat->stmmac_clk);
-
-	pcim_iounmap_regions(pdev, BIT(0));
 }
 
 static int __maybe_unused intel_eth_pci_suspend(struct device *dev)
-- 
2.34.1


^ permalink raw reply related

* Re: smsc95xx driver
From: Ferry Toth @ 2022-08-16 14:22 UTC (permalink / raw)
  To: Iryna Semenovych, netdev
  Cc: linux-usb, linux-kernel, kernel, Steve Glendinning,
	UNGLinuxDriver, David S. Miller, Jakub Kicinski, stable
In-Reply-To: <CAJU7JFAscYncnRLSNGrs4n22EzkxZBTWW6hQuk2WRGcUPwoXNw@mail.gmail.com>

Hi,

On 16-08-2022 11:44, Iryna Semenovych wrote:
> Hi folks!
>
> Recently I found the discussion in the archive about smsc95xx driver 
> patch that introduces some other issues:
> https://lore.kernel.org/netdev/93d3bb50040dd4519a65187d3412973831d2d797.camel@collabora.com/
>
> I am struggling with the similar/the same issue that is described in 
> detail here:
> https://github.com/raspberrypi/linux/issues/5116
>
I believe that a number patches have just been backported for usbnet: 
smsc95xx for 5.15 and 5.18 that might resolve your issue.

I did find another crash:

DMA-API: xhci-hcd xhci-hcd.1.auto: cacheline tracking EEXIST, > > > 
overlapping mappings aren't supported But it appears happens in the hub 
code as other hubs then smsc95xx also have that error. This one has not 
yet been resolved.

> Does anybody know if this issue is even related to smsc95xx driver 
> changes or how it can be fixed?
> I would really appreciate any help.
>
> Thanks in advance!
>
> -- 
> *Best regards, *
> *Iryna Semenovych*
> Software Engineer
>
> T:   +49 157 31090173
> M: iryna.semenovych@chargex.de
> W: www.chargex.de <http://www.chargex.de>
>
> ChargeX GmbH
> Landsberger Str. 318a, 80687 München

^ permalink raw reply

* Re: [PATCH v2 08/13] tracing: Improve panic/die notifiers
From: Alan Stern @ 2022-08-16 14:57 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Guilherme G. Piccoli, akpm, bhe, pmladek, kexec, linux-kernel,
	linux-hyperv, netdev, x86, kernel-dev, kernel, halves,
	fabiomirmar, alejandro.j.jimenez, andriy.shevchenko, arnd, bp,
	corbet, d.hatayama, dave.hansen, dyoung, feng.tang, gregkh,
	mikelley, hidehiro.kawai.ez, jgross, john.ogness, keescook, luto,
	mhiramat, mingo, paulmck, peterz, senozhatsky, tglx, vgoyal,
	vkuznets, will, Sergei Shtylyov
In-Reply-To: <20220816101445.184ebb7c@gandalf.local.home>

On Tue, Aug 16, 2022 at 10:14:45AM -0400, Steven Rostedt wrote:
> On Tue, 19 Jul 2022 16:53:21 -0300
> "Guilherme G. Piccoli" <gpiccoli@igalia.com> wrote:
> 
> 
> Sorry for the late review, but this fell to the bottom of my queue :-/
> 
> > +/*
> > + * The idea is to execute the following die/panic callback early, in order
> > + * to avoid showing irrelevant information in the trace (like other panic
> > + * notifier functions); we are the 2nd to run, after hung_task/rcu_stall
> > + * warnings get disabled (to prevent potential log flooding).
> > + */
> > +static int trace_die_panic_handler(struct notifier_block *self,
> > +				unsigned long ev, void *unused)
> > +{
> > +	if (!ftrace_dump_on_oops)
> > +		goto out;
> > +
> > +	if (self == &trace_die_notifier && ev != DIE_OOPS)
> > +		goto out;
> 
> I really hate gotos that are not for clean ups.
> 
> > +
> > +	ftrace_dump(ftrace_dump_on_oops);
> > +
> > +out:
> > +	return NOTIFY_DONE;
> > +}
> > +
> 
> Just do:
> 
> static int trace_die_panic_handler(struct notifier_block *self,
> 				unsigned long ev, void *unused)
> {
> 	if (!ftrace_dump_on_oops)
> 		return NOTIFY_DONE;
> 
> 	/* The die notifier requires DIE_OOPS to trigger */
> 	if (self == &trace_die_notifier && ev != DIE_OOPS)
> 		return NOTIFY_DONE;
> 
> 	ftrace_dump(ftrace_dump_on_oops);
> 
> 	return NOTIFY_DONE;
> }

Or better yet:

	if (ftrace_dump_on_oops) {

		/* The die notifier requires DIE_OOPS to trigger */
		if (self != &trace_die_notifier || ev == DIE_OOPS)
			ftrace_dump(ftrace_dump_on_oops);
	}
	return NOTIFY_DONE;

Alan Stern

> Thanks,
> 
> Other than that, Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org>
> 
> -- Steve

^ permalink raw reply

* [PATCH ipsec] xfrm: policy: fix md_dst skb->dev xmit null pointer dereference
From: Nikolay Aleksandrov @ 2022-08-16 14:58 UTC (permalink / raw)
  To: netdev
  Cc: davem, edumazet, pabeni, kuba, Nikolay Aleksandrov,
	Steffen Klassert, Daniel Borkmann

When we try to transmit an skb with metadata_dst attached (i.e. skb->dev
== NULL) through xfrm interface we can hit a null pointer dereference[1]
in xfrmi_xmit2() -> xfrm_lookup_with_ifid() due to the check for a
loopback skb device when there's no policy which dereferences skb->dev
unconditionally. Not having skb->dev can be interepreted as it not being
a loopback device, so just add a check for a null skb->dev.

With this fix xfrm interface's Tx error counters go up as usual.

[1] net-next calltrace captured via netconsole:
  BUG: kernel NULL pointer dereference, address: 00000000000000c0
  #PF: supervisor read access in kernel mode
  #PF: error_code(0x0000) - not-present page
  PGD 0 P4D 0
  Oops: 0000 [#1] PREEMPT SMP
  CPU: 1 PID: 7231 Comm: ping Kdump: loaded Not tainted 5.19.0+ #24
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.0-1.fc36 04/01/2014
  RIP: 0010:xfrm_lookup_with_ifid+0x5eb/0xa60
  Code: 8d 74 24 38 e8 26 a4 37 00 48 89 c1 e9 12 fc ff ff 49 63 ed 41 83 fd be 0f 85 be 01 00 00 41 be ff ff ff ff 45 31 ed 48 8b 03 <f6> 80 c0 00 00 00 08 75 0f 41 80 bc 24 19 0d 00 00 01 0f 84 1e 02
  RSP: 0018:ffffb0db82c679f0 EFLAGS: 00010246
  RAX: 0000000000000000 RBX: ffffd0db7fcad430 RCX: ffffb0db82c67a10
  RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffb0db82c67a80
  RBP: ffffb0db82c67a80 R08: ffffb0db82c67a14 R09: 0000000000000000
  R10: 0000000000000000 R11: ffff8fa449667dc8 R12: ffffffff966db880
  R13: 0000000000000000 R14: 00000000ffffffff R15: 0000000000000000
  FS:  00007ff35c83f000(0000) GS:ffff8fa478480000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 00000000000000c0 CR3: 000000001ebb7000 CR4: 0000000000350ee0
  Call Trace:
   <TASK>
   xfrmi_xmit+0xde/0x460
   ? tcf_bpf_act+0x13d/0x2a0
   dev_hard_start_xmit+0x72/0x1e0
   __dev_queue_xmit+0x251/0xd30
   ip_finish_output2+0x140/0x550
   ip_push_pending_frames+0x56/0x80
   raw_sendmsg+0x663/0x10a0
   ? try_charge_memcg+0x3fd/0x7a0
   ? __mod_memcg_lruvec_state+0x93/0x110
   ? sock_sendmsg+0x30/0x40
   sock_sendmsg+0x30/0x40
   __sys_sendto+0xeb/0x130
   ? handle_mm_fault+0xae/0x280
   ? do_user_addr_fault+0x1e7/0x680
   ? kvm_read_and_reset_apf_flags+0x3b/0x50
   __x64_sys_sendto+0x20/0x30
   do_syscall_64+0x34/0x80
   entry_SYSCALL_64_after_hwframe+0x46/0xb0
  RIP: 0033:0x7ff35cac1366
  Code: eb 0b 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 41 89 ca 64 8b 04 25 18 00 00 00 85 c0 75 11 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 72 c3 90 55 48 83 ec 30 44 89 4c 24 2c 4c 89
  RSP: 002b:00007fff738e4028 EFLAGS: 00000246 ORIG_RAX: 000000000000002c
  RAX: ffffffffffffffda RBX: 00007fff738e57b0 RCX: 00007ff35cac1366
  RDX: 0000000000000040 RSI: 0000557164e4b450 RDI: 0000000000000003
  RBP: 0000557164e4b450 R08: 00007fff738e7a2c R09: 0000000000000010
  R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000040
  R13: 00007fff738e5770 R14: 00007fff738e4030 R15: 0000001d00000001
   </TASK>
  Modules linked in: netconsole veth br_netfilter bridge bonding virtio_net [last unloaded: netconsole]
  CR2: 00000000000000c0

CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Daniel Borkmann <daniel@iogearbox.net>
Fixes: 2d151d39073a ("xfrm: Add possibility to set the default to block if we have no policy")
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
---
I wasn't sure if the target tree should be -net or -ipsec. The patch
applies to both cleanly in case it should go through -net.

To test the fix I attached a very simple egress bpf program to the xfrm
interface which just adds an empty md_dst to all transmitted skbs.

 net/xfrm/xfrm_policy.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 4f8bbb825abc..cc6ab79609e2 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -3162,7 +3162,7 @@ struct dst_entry *xfrm_lookup_with_ifid(struct net *net,
 	return dst;
 
 nopol:
-	if (!(dst_orig->dev->flags & IFF_LOOPBACK) &&
+	if ((!dst_orig->dev || !(dst_orig->dev->flags & IFF_LOOPBACK)) &&
 	    net->xfrm.policy_default[dir] == XFRM_USERPOLICY_BLOCK) {
 		err = -EPERM;
 		goto error;
-- 
2.36.1


^ permalink raw reply related

* Re: [syzbot] upstream boot error: general protection fault in nl80211_put_iface_combinations
From: Johannes Berg @ 2022-08-16 15:11 UTC (permalink / raw)
  To: syzbot, davem, edumazet, kuba, linux-kernel, linux-wireless,
	netdev, pabeni, syzkaller-bugs
In-Reply-To: <00000000000033169005e657a852@google.com>

Hmm.

> HEAD commit:    568035b01cfb Linux 6.0-rc1
> git tree:       upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=145d8a47080000
> kernel config:  https://syzkaller.appspot.com/x/.config?x=126b81cc3ce4f07e
> 

I can't reproduce this, and I don't see anything obviously wrong with
the code there in hwsim either.

Similarly with
https://syzkaller.appspot.com/bug?extid=655209e079e67502f2da

Anyone have any ideas what to do next?

johannes

^ permalink raw reply

* Re: [PATCH v16 mfd 8/8] mfd: ocelot: add support for the vsc7512 chip via spi
From: Colin Foster @ 2022-08-16 15:20 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Ido Schimmel, Uwe Kleine-König, linux-arm Mailing List,
	open list:GPIO SUBSYSTEM, netdev, Linux Kernel Mailing List,
	devicetree, Terry Bowman, Vladimir Oltean, Wolfram Sang,
	Microchip Linux Driver Support, Steen Hegelund, Lars Povlsen,
	Linus Walleij, Paolo Abeni, Jakub Kicinski, Eric Dumazet,
	David S. Miller, Russell King, Heiner Kallweit, Andrew Lunn,
	Krzysztof Kozlowski, Rob Herring, Lee Jones, katie.morris,
	Jonathan Cameron, Dan Williams, Lee Jones
In-Reply-To: <CAHp75VeH_Gx4t+FSqH4LrTHNcwqGxDxRUF26kj3A=CopS=XkgQ@mail.gmail.com>

On Tue, Aug 16, 2022 at 11:52:53AM +0300, Andy Shevchenko wrote:
> On Mon, Aug 15, 2022 at 5:35 PM Ido Schimmel <idosch@idosch.org> wrote:
> >
> > On Mon, Aug 15, 2022 at 07:19:13AM -0700, Colin Foster wrote:
> > > Something is going on that I don't fully understand with <asm/byteorder.h>.
> > > I don't quite see how ocelot-core is throwing all sorts of errors in x86
> > > builds now:
> > >
> > > https://patchwork.hopto.org/static/nipa/667471/12942993/build_allmodconfig_warn/stderr
> > >
> > > Snippet from there:
> > >
> > > /home/nipa/nipa/tests/patch/build_32bit/build_32bit.sh: line 21: ccache gcc: command not found
> > > ../drivers/mfd/ocelot-spi.c: note: in included file (through ../include/linux/bitops.h, ../include/linux/kernel.h, ../arch/x86/include/asm/percpu.h, ../arch/x86/include/asm/current.h, ../include/linux/sched.h, ...):
> > > ../arch/x86/include/asm/bitops.h:66:1: warning: unreplaced symbol 'return'
> > > ../drivers/mfd/ocelot-spi.c: note: in included file (through ../include/linux/bitops.h, ../include/linux/kernel.h, ../arch/x86/include/asm/percpu.h, ../arch/x86/include/asm/current.h, ../include/linux/sched.h, ...):
> > > ../include/asm-generic/bitops/generic-non-atomic.h:29:9: warning: unreplaced symbol 'mask'
> > > ../include/asm-generic/bitops/generic-non-atomic.h:30:9: warning: unreplaced symbol 'p'
> > > ../include/asm-generic/bitops/generic-non-atomic.h:32:10: warning: unreplaced symbol 'p'
> > > ../include/asm-generic/bitops/generic-non-atomic.h:32:16: warning: unreplaced symbol 'mask'
> > > ../include/asm-generic/bitops/generic-non-atomic.h:27:1: warning: unreplaced symbol 'return'
> > > ../drivers/mfd/ocelot-spi.c: note: in included file (through ../arch/x86/include/asm/bitops.h, ../include/linux/bitops.h, ../include/linux/kernel.h, ../arch/x86/include/asm/percpu.h, ../arch/x86/include/asm/current.h, ...):
> > > ../include/asm-generic/bitops/instrumented-non-atomic.h:26:1: warning: unreplaced symbol 'return'
> > >
> > >
> > > <asm/byteorder.h> was included in both drivers/mfd/ocelot-spi.c and
> > > drivers/mfd/ocelot.h previously, though Andy pointed out there didn't
> > > seem to be any users... and I didn't either. I'm sure there's something
> > > I must be missing.
> >
> > I got similar errors in our internal CI yesterday. Fixed by compiling
> > sparse from git:
> > https://git.kernel.org/pub/scm/devel/sparse/sparse.git/commit/?id=0e1aae55e49cad7ea43848af5b58ff0f57e7af99
> >
> > The update is also available in the "testing" repo in case you are
> > running Fedora 35 / 36:
> > https://bodhi.fedoraproject.org/updates/FEDORA-2022-c58b53730f
> > https://bodhi.fedoraproject.org/updates/FEDORA-2022-2bc333ccac
> 
> Debian still produces the same errors which makes sparse useless.

I haven't jumped into this one yet. But everything seems to be compiling
and running in ARM.

Do you think this is a false positive / unrelated to this patch? Or do
you think this is a true error that I did wrong? I haven't been around
for too many releases, so I'm not sure if this is common after an -rc1.

> 
> -- 
> With Best Regards,
> Andy Shevchenko

^ permalink raw reply

* Re: [PATCH ipsec] xfrm: policy: fix md_dst skb->dev xmit null pointer dereference
From: Nikolay Aleksandrov @ 2022-08-16 15:27 UTC (permalink / raw)
  To: netdev; +Cc: davem, edumazet, pabeni, kuba, Steffen Klassert, Daniel Borkmann
In-Reply-To: <20220816145838.13951-1-razor@blackwall.org>

Self-NAK, sorry for the noise. I meant dst->dev, not skb->dev obviously.
I'll send v2 with fixed subject.

^ permalink raw reply

* [PATCH] dt-bindings: Fix incorrect "the the" corrections
From: Geert Uytterhoeven @ 2022-08-16 15:30 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Slark Xiao
  Cc: Andy Gross, Bjorn Andersson, Niklas Söderlund, devicetree,
	linux-arm-msm, linux-renesas-soc, netdev, linux-kernel,
	Geert Uytterhoeven

Lots of double occurrences of "the" were replaced by single occurrences,
but some of them should become "to the" instead.

Fixes: 12e5bde18d7f6ca4 ("dt-bindings: Fix typo in comment")

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 Documentation/devicetree/bindings/net/qcom-emac.txt         | 2 +-
 Documentation/devicetree/bindings/thermal/rcar-thermal.yaml | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/qcom-emac.txt b/Documentation/devicetree/bindings/net/qcom-emac.txt
index e6cb2291471c4c11..7ae8aa14863454d2 100644
--- a/Documentation/devicetree/bindings/net/qcom-emac.txt
+++ b/Documentation/devicetree/bindings/net/qcom-emac.txt
@@ -14,7 +14,7 @@ MAC node:
 - mac-address : The 6-byte MAC address. If present, it is the default
 	MAC address.
 - internal-phy : phandle to the internal PHY node
-- phy-handle : phandle the external PHY node
+- phy-handle : phandle to the external PHY node
 
 Internal PHY node:
 - compatible : Should be "qcom,fsm9900-emac-sgmii" or "qcom,qdf2432-emac-sgmii".
diff --git a/Documentation/devicetree/bindings/thermal/rcar-thermal.yaml b/Documentation/devicetree/bindings/thermal/rcar-thermal.yaml
index 00dcbdd361442981..119998d10ff41836 100644
--- a/Documentation/devicetree/bindings/thermal/rcar-thermal.yaml
+++ b/Documentation/devicetree/bindings/thermal/rcar-thermal.yaml
@@ -42,7 +42,7 @@ properties:
     description:
       Address ranges of the thermal registers. If more then one range is given
       the first one must be the common registers followed by each sensor
-      according the datasheet.
+      according to the datasheet.
     minItems: 1
     maxItems: 4
 
-- 
2.25.1


^ permalink raw reply related

* [PATCH ipsec v2] xfrm: policy: fix metadata dst->dev xmit null pointer dereference
From: Nikolay Aleksandrov @ 2022-08-16 15:30 UTC (permalink / raw)
  To: netdev
  Cc: davem, edumazet, pabeni, kuba, Nikolay Aleksandrov,
	Steffen Klassert, Daniel Borkmann
In-Reply-To: <20220816145838.13951-1-razor@blackwall.org>

When we try to transmit an skb with metadata_dst attached (i.e. dst->dev
== NULL) through xfrm interface we can hit a null pointer dereference[1]
in xfrmi_xmit2() -> xfrm_lookup_with_ifid() due to the check for a
loopback skb device when there's no policy which dereferences dst->dev
unconditionally. Not having dst->dev can be interepreted as it not being
a loopback device, so just add a check for a null dst_orig->dev.

With this fix xfrm interface's Tx error counters go up as usual.

[1] net-next calltrace captured via netconsole:
  BUG: kernel NULL pointer dereference, address: 00000000000000c0
  #PF: supervisor read access in kernel mode
  #PF: error_code(0x0000) - not-present page
  PGD 0 P4D 0
  Oops: 0000 [#1] PREEMPT SMP
  CPU: 1 PID: 7231 Comm: ping Kdump: loaded Not tainted 5.19.0+ #24
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.0-1.fc36 04/01/2014
  RIP: 0010:xfrm_lookup_with_ifid+0x5eb/0xa60
  Code: 8d 74 24 38 e8 26 a4 37 00 48 89 c1 e9 12 fc ff ff 49 63 ed 41 83 fd be 0f 85 be 01 00 00 41 be ff ff ff ff 45 31 ed 48 8b 03 <f6> 80 c0 00 00 00 08 75 0f 41 80 bc 24 19 0d 00 00 01 0f 84 1e 02
  RSP: 0018:ffffb0db82c679f0 EFLAGS: 00010246
  RAX: 0000000000000000 RBX: ffffd0db7fcad430 RCX: ffffb0db82c67a10
  RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffb0db82c67a80
  RBP: ffffb0db82c67a80 R08: ffffb0db82c67a14 R09: 0000000000000000
  R10: 0000000000000000 R11: ffff8fa449667dc8 R12: ffffffff966db880
  R13: 0000000000000000 R14: 00000000ffffffff R15: 0000000000000000
  FS:  00007ff35c83f000(0000) GS:ffff8fa478480000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 00000000000000c0 CR3: 000000001ebb7000 CR4: 0000000000350ee0
  Call Trace:
   <TASK>
   xfrmi_xmit+0xde/0x460
   ? tcf_bpf_act+0x13d/0x2a0
   dev_hard_start_xmit+0x72/0x1e0
   __dev_queue_xmit+0x251/0xd30
   ip_finish_output2+0x140/0x550
   ip_push_pending_frames+0x56/0x80
   raw_sendmsg+0x663/0x10a0
   ? try_charge_memcg+0x3fd/0x7a0
   ? __mod_memcg_lruvec_state+0x93/0x110
   ? sock_sendmsg+0x30/0x40
   sock_sendmsg+0x30/0x40
   __sys_sendto+0xeb/0x130
   ? handle_mm_fault+0xae/0x280
   ? do_user_addr_fault+0x1e7/0x680
   ? kvm_read_and_reset_apf_flags+0x3b/0x50
   __x64_sys_sendto+0x20/0x30
   do_syscall_64+0x34/0x80
   entry_SYSCALL_64_after_hwframe+0x46/0xb0
  RIP: 0033:0x7ff35cac1366
  Code: eb 0b 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 41 89 ca 64 8b 04 25 18 00 00 00 85 c0 75 11 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 72 c3 90 55 48 83 ec 30 44 89 4c 24 2c 4c 89
  RSP: 002b:00007fff738e4028 EFLAGS: 00000246 ORIG_RAX: 000000000000002c
  RAX: ffffffffffffffda RBX: 00007fff738e57b0 RCX: 00007ff35cac1366
  RDX: 0000000000000040 RSI: 0000557164e4b450 RDI: 0000000000000003
  RBP: 0000557164e4b450 R08: 00007fff738e7a2c R09: 0000000000000010
  R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000040
  R13: 00007fff738e5770 R14: 00007fff738e4030 R15: 0000001d00000001
   </TASK>
  Modules linked in: netconsole veth br_netfilter bridge bonding virtio_net [last unloaded: netconsole]
  CR2: 00000000000000c0

CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Daniel Borkmann <daniel@iogearbox.net>
Fixes: 2d151d39073a ("xfrm: Add possibility to set the default to block if we have no policy")
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
---
v2: adjust commit msg and subject for dst->dev (s/skb/dst/)

I wasn't sure if the target tree should be -net or -ipsec. The patch
applies to both cleanly in case it should go through -net.

To test the fix I attached a very simple egress bpf program to the xfrm
interface which just adds an empty md_dst to all transmitted skbs.

 net/xfrm/xfrm_policy.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 4f8bbb825abc..cc6ab79609e2 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -3162,7 +3162,7 @@ struct dst_entry *xfrm_lookup_with_ifid(struct net *net,
 	return dst;
 
 nopol:
-	if (!(dst_orig->dev->flags & IFF_LOOPBACK) &&
+	if ((!dst_orig->dev || !(dst_orig->dev->flags & IFF_LOOPBACK)) &&
 	    net->xfrm.policy_default[dir] == XFRM_USERPOLICY_BLOCK) {
 		err = -EPERM;
 		goto error;
-- 
2.36.1


^ permalink raw reply related

* [PATCH bpf-next 1/2] Benchmark test added: bench_bpf_htab_batch_ops
From: Sagarika Sharma @ 2022-08-16 15:33 UTC (permalink / raw)
  To: Brian Vazquez, Sagarika Sharma, Andrii Nakryiko, Mykola Lysenko,
	Alexei Starovoitov, Daniel Borkmann, Yonghong Song,
	Stanislav Fomichev, Luigi Rizzo
  Cc: linux-kernel, netdev, bpf, Sagarika Sharma

The benchmark test is a tool to measure the different methods
of iterating through bpf hashmaps, specifically the function
bpf_map_lookup_batch() and the combination of the two functions
bpf_get_next_key()/bpf_map_lookup_elem(). The test will be
extended to also measure bpf_iter. The shell script
bench_bpf_htab_batch_ops.sh runs the benchmark test with a range
of parameters (e.g. the capacity of the hashmap, the number of
entries put in the map, and the setting of the n_prefetch module
parameter)

Signed-off-by: Sagarika Sharma <sharmasagarika@google.com>
---
 tools/testing/selftests/bpf/Makefile          |   3 +-
 tools/testing/selftests/bpf/bench.c           |  26 +-
 .../bpf/benchs/bench_bpf_htab_batch_ops.c     | 237 ++++++++++++++++++
 .../benchs/run_bench_bpf_htab_batch_ops.sh    |  28 +++
 4 files changed, 292 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/benchs/bench_bpf_htab_batch_ops.c
 create mode 100755 tools/testing/selftests/bpf/benchs/run_bench_bpf_htab_batch_ops.sh

diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 8d59ec7f4c2d..772d8339c400 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -589,7 +589,8 @@ $(OUTPUT)/bench: $(OUTPUT)/bench.o \
 		 $(OUTPUT)/bench_strncmp.o \
 		 $(OUTPUT)/bench_bpf_hashmap_full_update.o \
 		 $(OUTPUT)/bench_local_storage.o \
-		 $(OUTPUT)/bench_local_storage_rcu_tasks_trace.o
+		 $(OUTPUT)/bench_local_storage_rcu_tasks_trace.o \
+		 $(OUTPUT)/bench_bpf_htab_batch_ops.o
 	$(call msg,BINARY,,$@)
 	$(Q)$(CC) $(CFLAGS) $(LDFLAGS) $(filter %.a %.o,$^) $(LDLIBS) -o $@
 
diff --git a/tools/testing/selftests/bpf/bench.c b/tools/testing/selftests/bpf/bench.c
index c1f20a147462..55714e8071c8 100644
--- a/tools/testing/selftests/bpf/bench.c
+++ b/tools/testing/selftests/bpf/bench.c
@@ -12,6 +12,8 @@
 #include "bench.h"
 #include "testing_helpers.h"
 
+#define STK_SIZE (0xfffffff)
+
 struct env env = {
 	.warmup_sec = 1,
 	.duration_sec = 5,
@@ -275,6 +277,7 @@ extern struct argp bench_bpf_loop_argp;
 extern struct argp bench_local_storage_argp;
 extern struct argp bench_local_storage_rcu_tasks_trace_argp;
 extern struct argp bench_strncmp_argp;
+extern struct argp bench_bpf_htab_batch_ops_argp;
 
 static const struct argp_child bench_parsers[] = {
 	{ &bench_ringbufs_argp, 0, "Ring buffers benchmark", 0 },
@@ -284,6 +287,7 @@ static const struct argp_child bench_parsers[] = {
 	{ &bench_strncmp_argp, 0, "bpf_strncmp helper benchmark", 0 },
 	{ &bench_local_storage_rcu_tasks_trace_argp, 0,
 		"local_storage RCU Tasks Trace slowdown benchmark", 0 },
+	{ &bench_bpf_htab_batch_ops_argp, 0, "bpf_htab_ops benchmark", 0},
 	{},
 };
 
@@ -490,6 +494,8 @@ extern const struct bench bench_local_storage_cache_seq_get;
 extern const struct bench bench_local_storage_cache_interleaved_get;
 extern const struct bench bench_local_storage_cache_hashmap_control;
 extern const struct bench bench_local_storage_tasks_trace;
+extern const struct bench bench_bpf_htab_batch_ops;
+extern const struct bench bench_bpf_htab_element_ops;
 
 static const struct bench *benchs[] = {
 	&bench_count_global,
@@ -529,6 +535,8 @@ static const struct bench *benchs[] = {
 	&bench_local_storage_cache_interleaved_get,
 	&bench_local_storage_cache_hashmap_control,
 	&bench_local_storage_tasks_trace,
+	&bench_bpf_htab_batch_ops,
+	&bench_bpf_htab_element_ops,
 };
 
 static void setup_benchmark()
@@ -585,7 +593,23 @@ static void setup_benchmark()
 		env.prod_cpus.next_cpu = env.cons_cpus.next_cpu;
 
 	for (i = 0; i < env.producer_cnt; i++) {
-		err = pthread_create(&state.producers[i], NULL,
+		pthread_attr_t attr_producer;
+
+		err = pthread_attr_init(&attr_producer);
+		if (err) {
+			fprintf(stderr, "failed to initialize pthread attr #%d: %d\n",
+				i, -errno);
+			exit(1);
+		}
+
+		err = pthread_attr_setstacksize(&attr_producer, STK_SIZE);
+		if (err) {
+			fprintf(stderr, "failed to set pthread stacksize #%d: %d\n",
+				i, -errno);
+			exit(1);
+		}
+
+		err = pthread_create(&state.producers[i], &attr_producer,
 				     bench->producer_thread, (void *)(long)i);
 		if (err) {
 			fprintf(stderr, "failed to create producer thread #%d: %d\n",
diff --git a/tools/testing/selftests/bpf/benchs/bench_bpf_htab_batch_ops.c b/tools/testing/selftests/bpf/benchs/bench_bpf_htab_batch_ops.c
new file mode 100644
index 000000000000..ea98c2e97bff
--- /dev/null
+++ b/tools/testing/selftests/bpf/benchs/bench_bpf_htab_batch_ops.c
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <errno.h>
+#include <bpf/bpf.h>
+#include <bpf/libbpf.h>
+#include <argp.h>
+#include "bench.h"
+#include <bpf_util.h>
+
+/* A hash table of the size DEFAULT_NUM_ENTRIES
+ * makes evident the effect of optimizing
+ * functions that iterate through the map
+ */
+#define DEFAULT_NUM_ENTRIES 40000
+#define VALUE_SIZE 4
+
+int map_fd, method_flag, hits;
+
+static struct {
+	__u32 capacity;
+	__u32 num_entries;
+} args = {
+	.capacity = DEFAULT_NUM_ENTRIES,
+	.num_entries = DEFAULT_NUM_ENTRIES,
+};
+
+enum {
+	ARG_CAPACITY = 8000,
+	ARG_NUM_ENTRIES = 8001,
+};
+
+static const struct argp_option opts[] = {
+	{ "capacity", ARG_CAPACITY, "capacity", 0,
+		"Set hashtable capacity"},
+	{"num_entries", ARG_NUM_ENTRIES, "num_entries", 0,
+		"Set number of entries in the hashtable"},
+	{}
+};
+
+static error_t parse_arg(int key, char *arg, struct argp_state *state)
+{
+	switch (key) {
+	case ARG_CAPACITY:
+		args.capacity = strtol(arg, NULL, 10);
+		break;
+	case ARG_NUM_ENTRIES:
+		args.num_entries = strtol(arg, NULL, 10);
+		break;
+	default:
+		return ARGP_ERR_UNKNOWN;
+	}
+
+	return 0;
+}
+
+const struct argp bench_bpf_htab_batch_ops_argp = {
+	.options = opts,
+	.parser = parse_arg,
+};
+
+static void validate(void)
+{
+	if (args.num_entries > args.capacity) {
+		fprintf(stderr, "num_entries must be less than hash table capacity");
+		exit(1);
+	}
+
+	if (env.producer_cnt != 1) {
+		fprintf(stderr, "benchmark doesn't support multi-producer!\n");
+		exit(1);
+	}
+
+	if (env.consumer_cnt != 1) {
+		fprintf(stderr, "benchmark doesn't support multi-consumer!\n");
+		exit(1);
+	}
+}
+
+static inline void loop_bpf_map_lookup_batch(void)
+{
+	int num_cpus = bpf_num_possible_cpus();
+	typedef struct { int v[VALUE_SIZE]; /* padding */ } __bpf_percpu_val_align value[num_cpus];
+	int offset = 0, out_batch = 0, in_batch = 0;
+	DECLARE_LIBBPF_OPTS(bpf_map_batch_opts, operts,
+		.elem_flags = 0,
+		.flags = 0,
+	);
+	value pcpu_values[args.num_entries];
+	__u32 count = args.num_entries;
+	double keys[args.num_entries];
+	int *in_batch_ptr = NULL;
+	int err;
+
+	while (true) {
+		err = bpf_map_lookup_batch(map_fd, in_batch_ptr, &out_batch,
+			keys + offset, pcpu_values + offset, &count, &operts);
+
+		if (err && errno != ENOENT) {
+			fprintf(stderr, "Failed to lookup entries using bpf_map_lookup_batch\n");
+			exit(1);
+		}
+
+		hits += count;
+
+		if (count == args.num_entries) {
+			count = args.num_entries;
+			offset = out_batch = 0;
+			in_batch_ptr = NULL;
+		} else {
+			offset = count;
+			count = args.num_entries - count;
+			in_batch = out_batch;
+			in_batch_ptr = &in_batch;
+		}
+	}
+
+}
+
+static inline void loop_bpf_element_lookup(void)
+{
+	int num_cpus = bpf_num_possible_cpus();
+	typedef struct { int v[VALUE_SIZE]; /* padding */ } __bpf_percpu_val_align value[num_cpus];
+	double prev_key = -1, key;
+	value value_of_key;
+	int err;
+
+	while (true) {
+
+		while (bpf_map_get_next_key(map_fd, &prev_key, &key) == 0) {
+			err = bpf_map_lookup_elem(map_fd, &key, &value_of_key);
+			if (err) {
+				fprintf(stderr, "failed to lookup element using bpf_map_lookup_elem\n");
+				exit(1);
+			}
+			hits += 1;
+			prev_key = key;
+		}
+		prev_key = -1;
+
+	}
+
+}
+
+static void *producer(void *input)
+{
+	switch (method_flag) {
+	case 0:
+		loop_bpf_map_lookup_batch();
+		break;
+	case 1:
+		loop_bpf_element_lookup();
+		break;
+	}
+	return NULL;
+}
+
+static void *consumer(void *input)
+{
+	return NULL;
+}
+
+static void measure(struct bench_res *res)
+{
+	res->hits = hits;
+	hits = 0;
+}
+
+
+static void setup(void)
+{
+
+	typedef struct { int v[VALUE_SIZE]; /* padding */ } __bpf_percpu_val_align value[bpf_num_possible_cpus()];
+	DECLARE_LIBBPF_OPTS(bpf_map_batch_opts, operts,
+		.elem_flags = 0,
+		.flags = 0,
+	);
+	value pcpu_values[args.num_entries];
+	__u32 count = args.num_entries;
+	double keys[args.num_entries];
+	int err;
+
+	map_fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_HASH, "hash_map", sizeof(double),
+		(VALUE_SIZE*sizeof(int)), args.capacity, NULL);
+	if (map_fd < 0) {
+		fprintf(stderr, "error creating map using bpf_map_create\n");
+		exit(1);
+	}
+
+	for (double i = 0; i < args.num_entries; i++) {
+		keys[(int)i] = i + 1;
+		for (int j = 0; j < bpf_num_possible_cpus(); j++) {
+			for (int k = 0; k < VALUE_SIZE; k++)
+				bpf_percpu(pcpu_values[(int)i], j)[k] = (int)i + j + k;
+		}
+	}
+
+	err = bpf_map_update_batch(map_fd, keys, pcpu_values, &count, &operts);
+	if (err < 0) {
+		fprintf(stderr, "Failed to populate map using bpf_map_update_batch\n");
+		exit(1);
+	}
+
+}
+
+static void bench_bpf_map_lookup_batch_setup(void)
+{
+	setup();
+	method_flag = 0;
+}
+
+static void bench_element_lookup_setup(void)
+{
+	setup();
+	method_flag = 1;
+}
+
+const struct bench bench_bpf_htab_batch_ops = {
+	.name = "htab-batch-ops",
+	.validate = validate,
+	.setup = bench_bpf_map_lookup_batch_setup,
+	.producer_thread = producer,
+	.consumer_thread = consumer,
+	.measure = measure,
+	.report_progress = ops_report_progress,
+	.report_final = ops_report_final,
+};
+
+const struct bench bench_bpf_htab_element_ops = {
+	.name = "htab-element-ops",
+	.validate = validate,
+	.setup = bench_element_lookup_setup,
+	.producer_thread = producer,
+	.consumer_thread = consumer,
+	.measure = measure,
+	.report_progress = ops_report_progress,
+	.report_final = ops_report_final,
+};
diff --git a/tools/testing/selftests/bpf/benchs/run_bench_bpf_htab_batch_ops.sh b/tools/testing/selftests/bpf/benchs/run_bench_bpf_htab_batch_ops.sh
new file mode 100755
index 000000000000..624f403c1865
--- /dev/null
+++ b/tools/testing/selftests/bpf/benchs/run_bench_bpf_htab_batch_ops.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+source ./benchs/run_common.sh
+
+set -eufo pipefail
+
+map_capacity=40000
+header "bpf_get_next_key & bpf_map_lookup_elem"
+for t in 40000 10000 2500; do
+subtitle "map capacity: $map_capacity, num_entries: $t"
+        summarize_ops "bpf_element_ops: " \
+                "$($RUN_BENCH -p 1 --num_entries $t htab-element-ops)"
+        printf "\n"
+done
+
+header "bpf_map_lookup_batch with prefetch"
+for t in 40000 10000 2500; do
+for n in {0..20}; do
+#this range of n_prefetch shows the speedup and subsequent
+#deterioration as n_prefetch grows larger
+subtitle "map capacity: $map_capacity, num_entries: $t, n_prefetch: $n"
+        echo $n > /sys/module/hashtab/parameters/n_prefetch
+        summarize_ops "bpf_batch_ops: " \
+                "$($RUN_BENCH -p 1 --num_entries $t htab-batch-ops)"
+        printf "\n"
+done
+done
-- 
2.37.1.595.g718a3a8f04-goog


^ permalink raw reply related

* Re: [syzbot] upstream boot error: general protection fault in nl80211_put_iface_combinations
From: Guenter Roeck @ 2022-08-16 15:33 UTC (permalink / raw)
  To: Johannes Berg
  Cc: syzbot, davem, edumazet, kuba, linux-kernel, linux-wireless,
	netdev, pabeni, syzkaller-bugs
In-Reply-To: <6a7b0bc82647440a9036a8e637807da618552cc5.camel@sipsolutions.net>

On Tue, Aug 16, 2022 at 05:11:32PM +0200, Johannes Berg wrote:
> Hmm.
> 
> > HEAD commit:    568035b01cfb Linux 6.0-rc1
> > git tree:       upstream
> > console output: https://syzkaller.appspot.com/x/log.txt?x=145d8a47080000
> > kernel config:  https://syzkaller.appspot.com/x/.config?x=126b81cc3ce4f07e
> > 
> 
> I can't reproduce this, and I don't see anything obviously wrong with
> the code there in hwsim either.
> 
> Similarly with
> https://syzkaller.appspot.com/bug?extid=655209e079e67502f2da
> 
> Anyone have any ideas what to do next?
> 
Ignore it. It is caused by a problem in virtio. See revert series at
https://lore.kernel.org/lkml/20220816053602.173815-1-mst@redhat.com/

Guenter

> johannes

^ permalink raw reply

* Re: [syzbot] upstream boot error: general protection fault in nl80211_put_iface_combinations
From: Johannes Berg @ 2022-08-16 15:34 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: syzbot, davem, edumazet, kuba, linux-kernel, linux-wireless,
	netdev, pabeni, syzkaller-bugs
In-Reply-To: <20220816153345.GA2905014@roeck-us.net>

On Tue, 2022-08-16 at 08:33 -0700, Guenter Roeck wrote:
> On Tue, Aug 16, 2022 at 05:11:32PM +0200, Johannes Berg wrote:
> > Hmm.
> > 
> > > HEAD commit:    568035b01cfb Linux 6.0-rc1
> > > git tree:       upstream
> > > console output: https://syzkaller.appspot.com/x/log.txt?x=145d8a47080000
> > > kernel config:  https://syzkaller.appspot.com/x/.config?x=126b81cc3ce4f07e
> > > 
> > 
> > I can't reproduce this, and I don't see anything obviously wrong with
> > the code there in hwsim either.
> > 
> > Similarly with
> > https://syzkaller.appspot.com/bug?extid=655209e079e67502f2da
> > 
> > Anyone have any ideas what to do next?
> > 
> Ignore it. It is caused by a problem in virtio. See revert series at
> https://lore.kernel.org/lkml/20220816053602.173815-1-mst@redhat.com/
> 

Oh! OK, great, thanks! :)

johannes

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox