[PATCH 2/3] net: ag71xx: remove MMIO read-back drain from register writes
From: Rosen Penev <hidden>
Date: 2026-06-28 23:09:49
Also in:
lkml
Subsystem:
atlx ethernet drivers, networking drivers, the rest · Maintainers:
Chris Snook, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
ag71xx_wr(), ag71xx_sb() and ag71xx_cb() issue a synchronous ioread32() after every iowrite32() under the assumption that the write must be flushed to the device before any subsequent operation. On the ath79 on-chip MMIO bus the uncached __raw_writel used by iowrite32() is non-posted - the write completes before the next instruction executes. The extra ioread32() therefore serves no ordering purpose and costs at least one uncached bus round-trip per call. Remove the read-back and the associated comments, leaving the barrier that iowrite32() already provides. Small iperf3 improvement: Before: [ ID][Role] Interval Transfer Bitrate Retr [ 5][TX-C] 0.00-10.00 sec 343 MBytes 288 Mbits/sec 32 sender [ 5][TX-C] 0.00-10.00 sec 341 MBytes 286 Mbits/sec receiver [ 7][RX-C] 0.00-10.00 sec 183 MBytes 153 Mbits/sec 0 sender [ 7][RX-C] 0.00-10.00 sec 183 MBytes 153 Mbits/sec receiver After: [ ID][Role] Interval Transfer Bitrate Retr [ 5][TX-C] 0.00-10.00 sec 349 MBytes 292 Mbits/sec 28 sender [ 5][TX-C] 0.00-10.00 sec 346 MBytes 291 Mbits/sec receiver [ 7][RX-C] 0.00-10.00 sec 180 MBytes 151 Mbits/sec 0 sender [ 7][RX-C] 0.00-10.00 sec 180 MBytes 151 Mbits/sec receiver Assisted-by: opencode:big-pickle Signed-off-by: Rosen Penev <redacted> --- drivers/net/ethernet/atheros/ag71xx.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/atheros/ag71xx.c b/drivers/net/ethernet/atheros/ag71xx.c
index 1def2ad4c5ce..77f8e75e98ac 100644
--- a/drivers/net/ethernet/atheros/ag71xx.c
+++ b/drivers/net/ethernet/atheros/ag71xx.c@@ -397,11 +397,13 @@ static bool ag71xx_is(struct ag71xx *ag, enum ag71xx_type type) return ag->dcfg->type == type; } +/* ath79 on-chip MMIO bus is non-posted - iowrite32/iowrite32be completes + * before the next instruction executes. No read-back drain is needed. + */ + static void ag71xx_wr(struct ag71xx *ag, unsigned int reg, u32 value) { iowrite32(value, ag->mac_base + reg); - /* flush write */ - (void)ioread32(ag->mac_base + reg); } static u32 ag71xx_rr(struct ag71xx *ag, unsigned int reg)
@@ -411,22 +413,16 @@ static u32 ag71xx_rr(struct ag71xx *ag, unsigned int reg) static void ag71xx_sb(struct ag71xx *ag, unsigned int reg, u32 mask) { - void __iomem *r; + void __iomem *r = ag->mac_base + reg; - r = ag->mac_base + reg; iowrite32(ioread32(r) | mask, r); - /* flush write */ - (void)ioread32(r); } static void ag71xx_cb(struct ag71xx *ag, unsigned int reg, u32 mask) { - void __iomem *r; + void __iomem *r = ag->mac_base + reg; - r = ag->mac_base + reg; iowrite32(ioread32(r) & ~mask, r); - /* flush write */ - (void)ioread32(r); } static void ag71xx_int_enable(struct ag71xx *ag, u32 ints)
--
2.54.0