git: b0c14eae1060 - main - re(4): add hw.re.aspm_disable loader tunable
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 19 Jul 2026 18:50:52 UTC
The branch main has been updated by adrian:
URL: https://cgit.FreeBSD.org/src/commit/?id=b0c14eae10609f7d688b31d112de2a641d9cc516
commit b0c14eae10609f7d688b31d112de2a641d9cc516
Author: Jérémie Jourdin <jeremie@jourdin.org>
AuthorDate: 2026-07-19 18:49:12 +0000
Commit: Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2026-07-19 18:49:14 +0000
re(4): add hw.re.aspm_disable loader tunable
re(4) has unconditionally disabled ASPM L0s/L1 and CLKREQ at attach
for years; on laptops this costs 200mW+ (requested by adrian@ in the PR).
Make it a tunable following the existing hw.re.* pattern:
* default 1 keeps today's behavior;
* 0 preserves the firmware-configured ASPM state at attach and
skips the watchdog re-assert from the previous revision.
Documented in re.4.
* Verified on RTL8168H (XID 0x541): with hw.re.aspm_disable=0,
attach no longer logs "ASPM disabled" and pciconf -lcb shows
the firmware Link Control state preserved -- including Clock PM,
which the unconditional code previously cleared.
* Default (1) is behaviorally identical to the current driver.
* Note the tunable also stops the driver clearing CLKREQ, a small power
win even where firmware leaves L0s/L1 off.
Reviewed by: adrian
Differential Revision: https://reviews.freebsd.org/D58280
PR: kern/166724
---
share/man/man4/re.4 | 11 ++++++++++-
sys/dev/re/if_re.c | 17 +++++++++++++----
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/share/man/man4/re.4 b/share/man/man4/re.4
index 0020af64b330..6d190c944b34 100644
--- a/share/man/man4/re.4
+++ b/share/man/man4/re.4
@@ -28,7 +28,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
.\" THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd June 9, 2026
+.Dd July 13, 2026
.Dt RE 4
.Os
.Sh NAME
@@ -182,6 +182,15 @@ Tunables can be set at the
prompt before booting the kernel or stored in
.Xr loader.conf 5 .
.Bl -tag -width "xxxxxx"
+.It Va hw.re.aspm_disable
+This tunable controls whether the driver disables PCI Express ASPM
+(the L0s and L1 link states and CLKREQ) on the device.
+ASPM is a known trigger of transmit stalls and watchdog timeouts on
+many supported controllers, so it is disabled by default.
+Set to 0 to keep the ASPM configuration programmed by the firmware,
+trading reliability under sustained transmit load for lower link
+power consumption.
+The default value is 1.
.It Va hw.re.intr_filter
This tunable makes driver use interrupt filter handler on
controllers that support MSI/MSI-X capability.
diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c
index 5a3e8e68d26f..5a1e8ad554cb 100644
--- a/sys/dev/re/if_re.c
+++ b/sys/dev/re/if_re.c
@@ -167,6 +167,8 @@ static int msix_disable = 0;
TUNABLE_INT("hw.re.msix_disable", &msix_disable);
static int prefer_iomap = 0;
TUNABLE_INT("hw.re.prefer_iomap", &prefer_iomap);
+static int aspm_disable = 1;
+TUNABLE_INT("hw.re.aspm_disable", &aspm_disable);
#define RE_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP)
@@ -1369,8 +1371,14 @@ re_attach(device_t dev)
CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF);
}
- /* Disable ASPM L0S/L1 and CLKREQ. */
- if (sc->rl_expcap != 0) {
+ /*
+ * Disable ASPM L0S/L1 and CLKREQ. ASPM is implicated in Tx
+ * stalls and watchdog timeouts on many chip revisions, so it
+ * is turned off by default; set the hw.re.aspm_disable tunable
+ * to 0 to keep the firmware-configured ASPM state and trade
+ * reliability under sustained load for link power management.
+ */
+ if (aspm_disable != 0 && sc->rl_expcap != 0) {
cap = pci_read_config(dev, sc->rl_expcap +
PCIER_LINK_CAP, 2);
if ((cap & PCIEM_LINK_CAP_ASPM) != 0) {
@@ -3658,11 +3666,12 @@ re_watchdog(struct rl_softc *sc)
}
/*
- * ASPM is a common cause of these Tx timeouts. Make sure L0s/L1
+ * ASPM is a common cause of these Tx timeouts. Unless the
+ * administrator has opted to keep ASPM enabled, make sure L0s/L1
* and CLKREQ are still disabled on the link before reinitializing;
* firmware or a power transition may have re-armed them.
*/
- if (sc->rl_expcap != 0) {
+ if (aspm_disable != 0 && sc->rl_expcap != 0) {
uint16_t ctl;
ctl = pci_read_config(sc->rl_dev,