From 38187938f52283143308dd219db35d889da55ea4 Mon Sep 17 00:00:00 2001 From: Jérémie Jourdin Date: Sun, 19 Jul 2026 11:39:49 -0700 Subject: re(4): quiesce RTL8168G+ and reset before freeing buffers in re_stop() The STOPREQ command written by re_stop() is not defined for RTL8168G and later; issuing it can wedge the MAC. Replace it on those parts with the vendor-documented sequence: * settle delay * bounded poll for Tx queue empty * clear TE/RE * then bounded poll of the MCU command register (0xD3) FIFO-empty bits. Also reset the controller before the Rx/Tx buffer free: a controller that has not quiesced keeps DMAing stale, still-owned descriptors pointing at freed mbufs (use-after-free under INVARIANTS, cross-NIC mbuf corruption reported in the PR). Adds the RL_MCU_* register definitions. All waits are bounded; error paths only. * iperf3 --bidir at line rate against RTL8168H (XID 0x541); previously wedged the controller until power cycle, with the quiesce the reset path recovers. * Deployed in production on an RTL8168H fleet since 2026-07-01. Reviewed by: adrian Differential Revision: https://reviews.freebsd.org/D58276 PR: kern/166724 --- sys/dev/rl/if_rlreg.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'sys/dev/rl') diff --git a/sys/dev/rl/if_rlreg.h b/sys/dev/rl/if_rlreg.h index 10e25fcb5373..0db4b2066ce6 100644 --- a/sys/dev/rl/if_rlreg.h +++ b/sys/dev/rl/if_rlreg.h @@ -145,6 +145,14 @@ #define RL_INTRMOD 0x00E2 /* 16 bits */ #define RL_MISC 0x00F0 +/* + * MCU command / FIFO status register (RTL8168G and later). Polled to + * confirm the on-chip TX/RX FIFOs have drained before a controller reset. + */ +#define RL_MCU_CMD 0x00D3 +#define RL_MCU_TXFIFO_EMPTY 0x20 /* bit 5 */ +#define RL_MCU_RXFIFO_EMPTY 0x10 /* bit 4 */ + /* * TX config register bits */ -- cgit v1.3