Page MenuHomeFreeBSD

D61453.1794698209.diff
No OneTemporary

Authored By
Unknown
Size
10 KB
Referenced Files
None
Subscribers
None

D61453.1794698209.diff

diff --git a/share/man/man4/ix.4 b/share/man/man4/ix.4
--- a/share/man/man4/ix.4
+++ b/share/man/man4/ix.4
@@ -29,7 +29,7 @@
.\"
.\" * Other names and brands may be claimed as the property of others.
.\"
-.Dd September 2, 2026
+.Dd November 12, 2026
.Dt IX 4
.Os
.Sh NAME
@@ -281,7 +281,32 @@
.Pp
This feature is only supported on E610 devices.
.It Va dev.ix.?.eee_state
-Enable or disable Energy Efficient Ethernet on supported devices.
+Request Energy Efficient Ethernet (EEE) on supported devices.
+Set to 0 to disable EEE or 1 to enable it.
+Reading this variable returns the requested setting, not the negotiated
+EEE status.
+Reads and writes fail with
+.Er EPERM
+while the device is in firmware recovery mode.
+.Pp
+Changes are applied asynchronously by reinitializing the interface if it
+is administratively up.
+When the interface is down, the driver updates the PHY without bringing
+up the host interface, so a link shared with a management controller can
+still be configured.
+An EEE update can renegotiate that physical link.
+Changes made while suspended are saved and applied after resume, even if
+the interface remains down.
+A successful write does not confirm that the hardware accepted the setting.
+Failures in the EEE setup step are logged without aborting initialization.
+The requested setting is retained for subsequent initialization attempts.
+Writing the same value has no effect, including after a failed attempt.
+To retry, bring the interface down and back up.
+.Pp
+EEE operates only when negotiated with a supporting link partner at a
+supported link speed.
+The requested policy can be enabled even if the current link speed does
+not support EEE.
.It Va dev.ix.?.eee.tx_lpi_count
Count transmit Low Power Idle events.
.It Va dev.ix.?.eee.rx_lpi_count
diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c
--- a/sys/dev/ixgbe/if_ix.c
+++ b/sys/dev/ixgbe/if_ix.c
@@ -253,6 +253,8 @@
static void ixgbe_add_media_types(if_ctx_t);
static void ixgbe_update_stats_counters(struct ixgbe_softc *);
static void ixgbe_config_link(if_ctx_t);
+static void ixgbe_apply_eee(struct ixgbe_softc *);
+static void ixgbe_apply_eee_if_down(struct ixgbe_softc *);
static void ixgbe_get_slot_info(struct ixgbe_softc *);
static void ixgbe_fw_mode_timer(void *);
static void ixgbe_fw_mode_timer_pause(struct ixgbe_softc *);
@@ -3948,7 +3950,8 @@
SYSCTL_ADD_PROC(ctx_list, child, OID_AUTO, "eee_state",
CTLTYPE_INT | CTLFLAG_RW, sc, 0,
- ixgbe_sysctl_eee_state, "I", "EEE Power Save State");
+ ixgbe_sysctl_eee_state, "I",
+ "Requested EEE Power Save State");
eee_node = SYSCTL_ADD_NODE(ctx_list, child, OID_AUTO, "eee",
CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
@@ -4100,6 +4103,8 @@
{
struct ixgbe_softc *sc = iflib_get_softc(ctx);
+ /* Keep EEE updates away from a device that is powering down. */
+ sc->eee_power_blocked = true;
ixgbe_fw_mode_timer_pause(sc);
ixgbe_prepare_wakeup(ctx, event != IFLIB_POWER_DETACH);
return (0);
@@ -4251,6 +4256,9 @@
hw->wol_enabled = false;
sc->wol_filters = 0;
ixgbe_fw_mode_timer_resume(sc);
+ sc->eee_power_blocked = false;
+ /* An administratively down interface will not be initialized. */
+ ixgbe_apply_eee_if_down(sc);
return (0);
} /* ixgbe_if_resume */
@@ -4383,6 +4391,11 @@
iflib_init_failed(ctx);
return;
}
+ /* Enable PHY power before applying the cached link policy. */
+ ixgbe_set_phy_power(hw, true);
+
+ /* Replay EEE policy after reset, before enabling any queues. */
+ ixgbe_apply_eee(sc);
sc->iov_mta_valid = false;
sc->iov_vfta_valid = false;
@@ -4501,9 +4514,6 @@
/* Set moderation on the Link interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EITR(sc->vector), IXGBE_LINK_ITR);
- /* Enable power to the phy. */
- ixgbe_set_phy_power(hw, true);
-
/* Config/Enable Link */
ixgbe_config_link(ctx);
@@ -5221,6 +5231,8 @@
}
ixgbe_if_update_admin_status(ctx);
ixgbe_apply_ldo_link_state(sc, false);
+ /* The interface may have gone down after the sysctl queued a reset. */
+ ixgbe_apply_eee_if_down(sc);
/* reprogram the RAR[0] in case user changed it. */
ixgbe_set_rar(&sc->hw, 0, sc->hw.mac.addr, 0, IXGBE_RAH_AV);
@@ -5305,6 +5317,42 @@
}
} /* ixgbe_link_speed_to_str */
+/* Called with the context lock held and the device accessible. */
+static void
+ixgbe_apply_eee(struct ixgbe_softc *sc)
+{
+ s32 status;
+
+ sx_assert(iflib_ctx_lock_get(sc->ctx), SA_XLOCKED);
+ if ((sc->feat_cap & IXGBE_FEATURE_EEE) == 0)
+ return;
+ status = ixgbe_setup_eee(&sc->hw,
+ (sc->feat_en & IXGBE_FEATURE_EEE) != 0);
+ if (status != IXGBE_SUCCESS)
+ device_printf(sc->dev,
+ "EEE setup failed: %d; retaining requested policy\n",
+ status);
+}
+
+/*
+ * A down host interface may still share an active PHY with a BMC, and no
+ * initialization follows to replay the policy.
+ */
+static void
+ixgbe_apply_eee_if_down(struct ixgbe_softc *sc)
+{
+ if_ctx_t ctx = sc->ctx;
+
+ sx_assert(iflib_ctx_lock_get(ctx), SA_XLOCKED);
+ if (sc->eee_power_blocked ||
+ (if_getflags(iflib_get_ifp(ctx)) & IFF_UP) != 0 ||
+ iflib_is_running(ctx) ||
+ atomic_load_acq_int(&sc->recovery_mode) != 0 ||
+ sc->overtemp_shutdown_pending)
+ return;
+ ixgbe_apply_eee(sc);
+}
+
/************************************************************************
* ixgbe_update_link_status - Update OS on link state
*
@@ -5867,6 +5915,7 @@
ixgbe_sysctl_advertise(SYSCTL_HANDLER_ARGS)
{
struct ixgbe_softc *sc;
+ struct sx *ctx_lock;
int error, advertise;
sc = (struct ixgbe_softc *)arg1;
@@ -5879,7 +5928,15 @@
if ((error) || (req->newptr == NULL))
return (error);
- return ixgbe_set_advertise(sc, advertise);
+ /* Serialize the PHY update with init and other PHY configuration. */
+ ctx_lock = iflib_ctx_lock_get(sc->ctx);
+ sx_xlock(ctx_lock);
+ if (iflib_in_detach(sc->ctx))
+ error = ENXIO;
+ else
+ error = ixgbe_set_advertise(sc, advertise);
+ sx_xunlock(ctx_lock);
+ return (error);
} /* ixgbe_sysctl_advertise */
/************************************************************************
@@ -6296,30 +6353,27 @@
* Values:
* 0 - disable EEE
* 1 - enable EEE
- * (none) - get current device EEE state
+ * (none) - get requested device EEE state
************************************************************************/
static int
ixgbe_sysctl_eee_state(SYSCTL_HANDLER_ARGS)
{
struct ixgbe_softc *sc = (struct ixgbe_softc *)arg1;
device_t dev = sc->dev;
- if_t ifp = iflib_get_ifp(sc->ctx);
- int curr_eee, new_eee, error = 0;
- s32 retval;
+ struct sx *ctx_lock = iflib_ctx_lock_get(sc->ctx);
+ int new_eee, error;
if (atomic_load_acq_int(&sc->recovery_mode))
return (EPERM);
- curr_eee = new_eee = !!(sc->feat_en & IXGBE_FEATURE_EEE);
+ sx_xlock(ctx_lock);
+ new_eee = !!(sc->feat_en & IXGBE_FEATURE_EEE);
+ sx_xunlock(ctx_lock);
error = sysctl_handle_int(oidp, &new_eee, 0, req);
if ((error) || (req->newptr == NULL))
return (error);
- /* Nothing to do */
- if (new_eee == curr_eee)
- return (0);
-
/* Not supported */
if (!(sc->feat_cap & IXGBE_FEATURE_EEE))
return (EINVAL);
@@ -6328,33 +6382,30 @@
if ((new_eee < 0) || (new_eee > 1))
return (EINVAL);
- /* If link speed is <= 1Gbps and EEE is being enabled, log info */
- if (sc->hw.mac.type == ixgbe_mac_E610 &&
- new_eee &&
- sc->link_speed <= IXGBE_LINK_SPEED_1GB_FULL) {
- device_printf(dev,
- "Energy Efficient Ethernet (EEE) feature is not "
- "supported on link speeds equal to or below 1Gbps. "
- "EEE is supported on speeds above 1Gbps.\n");
- return (EINVAL);
- }
-
- retval = ixgbe_setup_eee(&sc->hw, new_eee);
- if (retval) {
- device_printf(dev, "Error in EEE setup: 0x%08X\n", retval);
- return (EINVAL);
+ sx_xlock(ctx_lock);
+ if (iflib_in_detach(sc->ctx)) {
+ error = ENXIO;
+ goto out;
}
+ /* The state may have changed while copying the sysctl value. */
+ if (new_eee == !!(sc->feat_en & IXGBE_FEATURE_EEE))
+ goto out;
- /* Restart auto-neg */
- if_init(ifp, ifp);
-
- device_printf(dev, "New EEE state: %d\n", new_eee);
-
- /* Cache new value */
+ /* Keep the request until it can be applied, including after suspend. */
if (new_eee)
sc->feat_en |= IXGBE_FEATURE_EEE;
else
sc->feat_en &= ~IXGBE_FEATURE_EEE;
+ device_printf(dev, "Requested EEE state: %d\n", new_eee);
+
+ if ((if_getflags(iflib_get_ifp(sc->ctx)) & IFF_UP) != 0) {
+ iflib_request_reset_if_up(sc->ctx);
+ iflib_admin_intr_deferred(sc->ctx);
+ } else {
+ ixgbe_apply_eee_if_down(sc);
+ }
+out:
+ sx_xunlock(ctx_lock);
return (error);
} /* ixgbe_sysctl_eee_state */
diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h
--- a/sys/dev/ixgbe/ixgbe.h
+++ b/sys/dev/ixgbe/ixgbe.h
@@ -450,6 +450,8 @@
bool link_up;
bool link_enabled;
bool led_active;
+ /* No EEE updates while powering down; iflib context lock. */
+ bool eee_power_blocked;
u32 vector;
u16 dmac;
u32 phy_layer;
diff --git a/sys/dev/ixgbe/ixgbe_e610.c b/sys/dev/ixgbe/ixgbe_e610.c
--- a/sys/dev/ixgbe/ixgbe_e610.c
+++ b/sys/dev/ixgbe/ixgbe_e610.c
@@ -78,6 +78,7 @@
case ixgbe_aci_opc_get_phy_caps:
case ixgbe_aci_opc_get_link_status:
case ixgbe_aci_opc_get_link_topo:
+ case ixgbe_aci_opc_set_phy_cfg:
return true;
}
@@ -255,7 +256,8 @@
}
if (desc->retval != IXGBE_ACI_RC_OK) {
- hw->aci.last_status = (enum ixgbe_aci_err)desc->retval;
+ hw->aci.last_status = (enum ixgbe_aci_err)
+ IXGBE_LE16_TO_CPU(desc->retval);
status = IXGBE_ERR_ACI_ERROR;
break;
}
@@ -325,6 +327,10 @@
if (!is_cmd_for_retry || status == IXGBE_SUCCESS ||
(last_status != IXGBE_ACI_RC_EBUSY && status != IXGBE_ERR_ACI_ERROR))
break;
+ /* Only retry PHY updates on an explicit busy response. */
+ if (opcode == ixgbe_aci_opc_set_phy_cfg &&
+ last_status != IXGBE_ACI_RC_EBUSY)
+ break;
if (buf)
memcpy(buf, buf_cpy, buf_size);
@@ -5050,11 +5056,6 @@
if (status != IXGBE_SUCCESS)
return status;
- ixgbe_copy_phy_caps_to_cfg(&phy_caps, &phy_cfg);
-
- phy_cfg.caps |= IXGBE_ACI_PHY_ENA_LINK;
- phy_cfg.caps |= IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT;
-
/* setup only speeds which are defined for [0x0601/0x0600].eee_cap */
if (enable_eee) {
if (hw->phy.eee_speeds_advertised & IXGBE_LINK_SPEED_100_FULL)
@@ -5069,6 +5070,14 @@
eee_cap |= IXGBE_ACI_PHY_EEE_EN_10GBASE_T;
}
+ /* Avoid restarting the link when the EEE policy already matches. */
+ if (phy_caps.eee_cap == IXGBE_CPU_TO_LE16(eee_cap))
+ return IXGBE_SUCCESS;
+
+ ixgbe_copy_phy_caps_to_cfg(&phy_caps, &phy_cfg);
+ /* An EEE update must not enable a disabled physical link. */
+ phy_cfg.caps |= IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT;
+
/* Set EEE capability for particular PHY types */
phy_cfg.eee_cap = IXGBE_CPU_TO_LE16(eee_cap);

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 14, 11:16 PM (12 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41733687
Default Alt Text
D61453.1794698209.diff (10 KB)

Event Timeline