[PATCH 2/3] net: ag71xx: remove MMIO read-back drain from register writes
From: Rosen Penev
Date: Sun Jun 28 2026 - 19:11:10 EST
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 <rosenp@xxxxxxxxx>
---
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