summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mscc/ocelot.c
diff options
context:
space:
mode:
authorVladimir Oltean <vladimir.oltean@nxp.com>2022-08-16 15:53:51 +0200
committerJakub Kicinski <kuba@kernel.org>2022-08-18 06:58:32 +0200
commitd4c367650704de091d4c1f6bb379c0a5c389c73a (patch)
tree64d53abfdcf1702066a7b1f4e42fa286ef0ffef3 /drivers/net/ethernet/mscc/ocelot.c
parentnet: mscc: ocelot: make struct ocelot_stat_layout array indexable (diff)
downloadlinux-d4c367650704de091d4c1f6bb379c0a5c389c73a.tar.xz
linux-d4c367650704de091d4c1f6bb379c0a5c389c73a.zip
net: mscc: ocelot: keep ocelot_stat_layout by reg address, not offset
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> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net/ethernet/mscc/ocelot.c')
-rw-r--r--drivers/net/ethernet/mscc/ocelot.c11
1 files changed, 5 insertions, 6 deletions
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) {