From 1331b8c0176a09ffdaf47914ee7542582ef8f719 Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Sun, 26 Jul 2026 17:19:16 +0900 Subject: [PATCH] rtl8168d: DMA barriers + drop false RTL8125 claim from config.toml - device.rs: release fence before tppoll doorbell write; acquire fence after the OWN-bit read on the receive descriptor. The Realtek descriptor hand-off is the same OWN-bit protocol as e1000d, and the same reordering argument applies: on aarch64 with relaxed ordering the device can clear OWN and update length+status in any order, and without a fence we can observe OWN=0 paired with a stale length and compute a partial read. - config.toml: drop the description's RTL8125 reference. The rtl8168d register layout does not support rtl8125 (a 2.5GbE chip with its own register layout and PHY init sequence); the description now matches the actual capability. --- drivers/net/rtl8168d/config.toml | 2 +- drivers/net/rtl8168d/src/device.rs | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/net/rtl8168d/config.toml b/drivers/net/rtl8168d/config.toml index ee98e345f3..5c57ac7563 100644 --- a/drivers/net/rtl8168d/config.toml +++ b/drivers/net/rtl8168d/config.toml @@ -1,5 +1,5 @@ [[drivers]] -name = "RTL8168 NIC" +name = "RTL8168/8169 NIC" class = 0x02 ids = { 0x10ec = [0x8168, 0x8169] } command = ["rtl8168d"] diff --git a/drivers/net/rtl8168d/src/device.rs b/drivers/net/rtl8168d/src/device.rs index 7229a52def..f140a31243 100644 --- a/drivers/net/rtl8168d/src/device.rs +++ b/drivers/net/rtl8168d/src/device.rs @@ -95,7 +95,9 @@ impl NetworkAdapter for Rtl8168 { } let rd = &mut self.receive_ring[self.receive_i]; - if !rd.ctrl.readf(OWN) { + let own = rd.ctrl.readf(OWN); + if !own { + core::sync::atomic::fence(core::sync::atomic::Ordering::Acquire); let rd_len = rd.ctrl.read() & 0x3FFF; let data = &self.receive_buffer[self.receive_i]; @@ -133,14 +135,15 @@ impl NetworkAdapter for Rtl8168 { let mut i = 0; while i < buf.len() && i < data.len() { - data[i].write(buf[i]); - i += 1; - } + data[i].write(buf[i]); + i += 1; + } - let eor = td.ctrl.read() & EOR; - td.ctrl.write(OWN | eor | FS | LS | i as u32); + let eor = td.ctrl.read() & EOR; + td.ctrl.write(OWN | eor | FS | LS | i as u32); - self.regs.tppoll.writef(1 << 6, true); //Notify of normal priority packet + core::sync::atomic::fence(core::sync::atomic::Ordering::Release); + self.regs.tppoll.writef(1 << 6, true); //Notify of normal priority packet while self.regs.tppoll.readf(1 << 6) { std::hint::spin_loop();