summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDaniel Palmer <daniel@0x0f.com>2026-10-25 11:45:14 +0900
committerJakub Kicinski <kuba@kernel.org>2026-10-28 16:34:39 -0700
commit7cceaba6ffbc34be198ab0ee2a669ca657d6a681 (patch)
treed24186b5a6e89f9e470cf6396d36575c602ed8dd /drivers
parentca87a2dffbb550fc934647d5e8d1c4ae85590132 (diff)
net: i825xx: 82596: use MMIO accessors for the MVME16x PORT/CA registers
On the MVME16x the two port registers need to be written in order to latch the correct 32bit value. The way the code is currently written means that modern GCC can decide to optimize the writes and break that latching. Convert the MVME16x specific register accesses to use the proper io accessors to restore the latching and make the driver functional again. The Patch was tested by me on real Hardware (Motorola MVME177). On the Board is a Intel i82596CA 10Mb Ethernet Chip Stepping C. Reported-by: Denis Ahrens <denis@h3q.com> Signed-off-by: Daniel Palmer <daniel@0x0f.com> Tested-by: Denis Ahrens <denis@h3q.com> Link: https://patch.msgid.link/20261025024514.802862-1-daniel@0x0f.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/i825xx/82596.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/drivers/net/ethernet/i825xx/82596.c b/drivers/net/ethernet/i825xx/82596.c
index 773d7aa29ef5..bb8798b0d3ae 100644
--- a/drivers/net/ethernet/i825xx/82596.c
+++ b/drivers/net/ethernet/i825xx/82596.c
@@ -196,11 +196,10 @@ enum commands {
#define TX_TIMEOUT (HZ/20)
-struct i596_reg {
- unsigned short porthi;
- unsigned short portlo;
- unsigned long ca;
-};
+/* MVME16x: the 82596 PORT and CA registers */
+#define MVME_I596_PORT_HI 0x00
+#define MVME_I596_PORT_LO 0x02
+#define MVME_I596_CA 0x04
#define EOF 0x8000
#define SIZE_MASK 0x3fff
@@ -375,7 +374,9 @@ static inline void CA(struct net_device *dev)
{
#ifdef ENABLE_MVME16x_NET
if (MACH_IS_MVME16x) {
- ((struct i596_reg *) dev->base_addr)->ca = 1;
+ void __iomem *regs = (void __iomem *)dev->base_addr;
+
+ __raw_writel(1, regs + MVME_I596_CA);
}
#endif
#ifdef ENABLE_BVME6000_NET
@@ -392,9 +393,15 @@ static inline void MPU_PORT(struct net_device *dev, int c, volatile void *x)
{
#ifdef ENABLE_MVME16x_NET
if (MACH_IS_MVME16x) {
- struct i596_reg *p = (struct i596_reg *) (dev->base_addr);
- p->porthi = ((c) | (u32) (x)) & 0xffff;
- p->portlo = ((c) | (u32) (x)) >> 16;
+ void __iomem *regs = (void __iomem *)dev->base_addr;
+ u32 v = (u32)c | (u32)x;
+
+ /*
+ * The 32bit value is latched on the write of the lo register,
+ * so the 16bit writes must happen in this order.
+ */
+ __raw_writew(v & 0xffff, regs + MVME_I596_PORT_HI);
+ __raw_writew(v >> 16, regs + MVME_I596_PORT_LO);
}
#endif
#ifdef ENABLE_BVME6000_NET