git: df02513fd44b - main - ixgbe: Enable SR-IOV on E610 PFs
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 16 Aug 2026 01:15:48 UTC
The branch main has been updated by kbowling:
URL: https://cgit.FreeBSD.org/src/commit/?id=df02513fd44bcede0aa8833ae5c2af826f63ce10
commit df02513fd44bcede0aa8833ae5c2af826f63ce10
Author: Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-08-01 02:47:11 +0000
Commit: Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-08-16 01:14:30 +0000
ixgbe: Enable SR-IOV on E610 PFs
E610 inherits the X550-family virtualization registers, anti-spoofing
controls, and malicious-driver operations, but the frontend does not
advertise SR-IOV and cannot negotiate the mailbox revision needed by
E610 VFs.
Initialize the X550-family PF/VF mailbox registers for E610 and use
PFVFLREC for its VF reset events, following DPDK shared ixgbe code.
Advertise the E610 SR-IOV capability, accept API 1.6 only on E610, carry
the existing xcast and queue operations forward to that revision, and
return the cached physical link speed and state with the three-dword
E610 operation. Unsupported RSS and optional feature requests continue
to receive explicit failures.
SR-IOV activation also enables the existing X550-derived per-pool MDD
recovery path on E610. Document the expanded protection and link-state
coverage.
Hardware validation created 63 VFs and rejected a 64th without flapping
the running PF. Invalid TX and RX descriptor DMA independently asserted
the offender's WQBR bit, gated only that VF, preserved sibling traffic,
and recovered after the VF reset. FreeBSD ixv, FreeBSD DPDK, Linux
ixgbevf, and Linux DPDK exercised the PF mailbox and data paths.
MFC after: 2 weeks
Relnotes: yes
Sponsored by: Dirk-Willem van Gulik from Web Weaving (E610 hardware)
Sponsored by: BBOX.io
---
share/man/man4/ix.4 | 5 +++-
sys/dev/ixgbe/if_ix.c | 1 +
sys/dev/ixgbe/if_sriov.c | 61 ++++++++++++++++++++++++++++++++++++++++++---
sys/dev/ixgbe/ixgbe_mbx.c | 3 +++
sys/dev/ixgbe/ixgbe_sriov.h | 1 +
5 files changed, 67 insertions(+), 4 deletions(-)
diff --git a/share/man/man4/ix.4 b/share/man/man4/ix.4
index 433ec164688e..e175d3c7aea8 100644
--- a/share/man/man4/ix.4
+++ b/share/man/man4/ix.4
@@ -107,7 +107,7 @@ source address, so the driver does not silently weaken an enabled policy to
install secondary addresses.
.Pp
Ethertype anti-spoofing and malicious-driver detection and recovery are
-available only on X550-family devices.
+available only on X550-family devices, including X552 and X553, and on E610.
The driver cannot enable those hardware protections on earlier devices such
as 82599.
After a malicious-driver event, the PF keeps the offending VF's transmit and
@@ -123,6 +123,9 @@ configuration is destroyed and recreated.
The read-only
.Va dev.ix.N.iov_quarantined_vfs
sysctl reports quarantined VF pools as a bitmap.
+.Pp
+E610 PFs provide physical link state and speed to VFs that negotiate mailbox
+API 1.6.
.Sh HARDWARE
The
.Nm
diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c
index 7bc7a2fc831b..f581de8d7abc 100644
--- a/sys/dev/ixgbe/if_ix.c
+++ b/sys/dev/ixgbe/if_ix.c
@@ -6179,6 +6179,7 @@ ixgbe_init_device_features(struct ixgbe_softc *sc)
break;
case ixgbe_mac_E610:
sc->feat_cap |= IXGBE_FEATURE_RECOVERY_MODE;
+ sc->feat_cap |= IXGBE_FEATURE_SRIOV;
sc->feat_cap |= IXGBE_FEATURE_DBG_DUMP;
sc->feat_cap |= IXGBE_FEATURE_FW_LOGGING;
error = ixgbe_get_caps(&sc->hw);
diff --git a/sys/dev/ixgbe/if_sriov.c b/sys/dev/ixgbe/if_sriov.c
index 09954a519664..13ba3cdaf132 100644
--- a/sys/dev/ixgbe/if_sriov.c
+++ b/sys/dev/ixgbe/if_sriov.c
@@ -1252,6 +1252,14 @@ static void
ixgbe_vf_api_negotiate(struct ixgbe_softc *sc, struct ixgbe_vf *vf,
uint32_t *msg)
{
+ if (msg[1] == IXGBE_API_VER_1_6) {
+ if (sc->hw.mac.type != ixgbe_mac_E610)
+ goto failure;
+ vf->api_ver = msg[1];
+ ixgbe_send_vf_success(sc, vf, msg[0]);
+ return;
+ }
+
switch (msg[1]) {
case IXGBE_API_VER_1_0:
case IXGBE_API_VER_1_1:
@@ -1261,10 +1269,13 @@ ixgbe_vf_api_negotiate(struct ixgbe_softc *sc, struct ixgbe_vf *vf,
ixgbe_send_vf_success(sc, vf, msg[0]);
break;
default:
- vf->api_ver = IXGBE_API_VER_UNKNOWN;
- ixgbe_send_vf_failure(sc, vf, msg[0]);
- break;
+ goto failure;
}
+ return;
+
+failure:
+ vf->api_ver = IXGBE_API_VER_UNKNOWN;
+ ixgbe_send_vf_failure(sc, vf, msg[0]);
} /* ixgbe_vf_api_negotiate */
static void
@@ -1282,6 +1293,7 @@ ixgbe_vf_update_xcast_mode(struct ixgbe_softc *sc, struct ixgbe_vf *vf,
goto failure;
break;
case IXGBE_API_VER_1_3:
+ case IXGBE_API_VER_1_6:
break;
default:
goto failure;
@@ -1339,6 +1351,43 @@ ixgbe_vf_get_queues(struct ixgbe_softc *sc, struct ixgbe_vf *vf,
ixgbe_write_mbx(hw, resp, IXGBE_VF_GET_QUEUES_RESP_LEN, vf->pool);
} /* ixgbe_vf_get_queues */
+static void
+ixgbe_vf_get_link_state(struct ixgbe_softc *sc, struct ixgbe_vf *vf,
+ uint32_t *msg)
+{
+ switch (vf->api_ver) {
+ case IXGBE_API_VER_1_2:
+ case IXGBE_API_VER_1_3:
+ case IXGBE_API_VER_1_6:
+ break;
+ default:
+ ixgbe_send_vf_failure(sc, vf, msg[0]);
+ return;
+ }
+
+ msg[0] = IXGBE_VF_GET_LINK_STATE | IXGBE_VT_MSGTYPE_SUCCESS |
+ IXGBE_VT_MSGTYPE_CTS;
+ msg[1] = 1;
+ ixgbe_write_mbx(&sc->hw, msg, 2, vf->pool);
+} /* ixgbe_vf_get_link_state */
+
+static void
+ixgbe_vf_get_pf_link_state(struct ixgbe_softc *sc, struct ixgbe_vf *vf,
+ uint32_t *msg)
+{
+ if (sc->hw.mac.type != ixgbe_mac_E610 ||
+ vf->api_ver != IXGBE_API_VER_1_6) {
+ ixgbe_send_vf_failure(sc, vf, msg[0]);
+ return;
+ }
+
+ msg[0] = IXGBE_VF_GET_PF_LINK_STATE | IXGBE_VT_MSGTYPE_SUCCESS |
+ IXGBE_VT_MSGTYPE_CTS;
+ msg[1] = sc->link_speed;
+ msg[2] = sc->link_up;
+ ixgbe_write_mbx(&sc->hw, msg, 3, vf->pool);
+} /* ixgbe_vf_get_pf_link_state */
+
static bool
ixgbe_process_vf_msg(if_ctx_t ctx, struct ixgbe_vf *vf, bool reset_pending)
@@ -1409,6 +1458,12 @@ ixgbe_process_vf_msg(if_ctx_t ctx, struct ixgbe_vf *vf, bool reset_pending)
case IXGBE_VF_UPDATE_XCAST_MODE:
ixgbe_vf_update_xcast_mode(sc, vf, msg);
break;
+ case IXGBE_VF_GET_LINK_STATE:
+ ixgbe_vf_get_link_state(sc, vf, msg);
+ break;
+ case IXGBE_VF_GET_PF_LINK_STATE:
+ ixgbe_vf_get_pf_link_state(sc, vf, msg);
+ break;
default:
ixgbe_send_vf_failure(sc, vf, msg[0]);
}
diff --git a/sys/dev/ixgbe/ixgbe_mbx.c b/sys/dev/ixgbe/ixgbe_mbx.c
index a6a2721d7132..584eb62e4fd7 100644
--- a/sys/dev/ixgbe/ixgbe_mbx.c
+++ b/sys/dev/ixgbe/ixgbe_mbx.c
@@ -854,6 +854,7 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_id)
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
case ixgbe_mac_X550EM_a:
+ case ixgbe_mac_E610:
case ixgbe_mac_X540:
vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLREC(index));
break;
@@ -1246,6 +1247,7 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
hw->mac.type != ixgbe_mac_X550 &&
hw->mac.type != ixgbe_mac_X550EM_x &&
hw->mac.type != ixgbe_mac_X550EM_a &&
+ hw->mac.type != ixgbe_mac_E610 &&
hw->mac.type != ixgbe_mac_X540)
return;
@@ -1288,6 +1290,7 @@ void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id)
hw->mac.type != ixgbe_mac_X550 &&
hw->mac.type != ixgbe_mac_X550EM_x &&
hw->mac.type != ixgbe_mac_X550EM_a &&
+ hw->mac.type != ixgbe_mac_E610 &&
hw->mac.type != ixgbe_mac_X540)
return;
diff --git a/sys/dev/ixgbe/ixgbe_sriov.h b/sys/dev/ixgbe/ixgbe_sriov.h
index de0485f6e9a2..0a1eeb642366 100644
--- a/sys/dev/ixgbe/ixgbe_sriov.h
+++ b/sys/dev/ixgbe/ixgbe_sriov.h
@@ -75,6 +75,7 @@
#define IXGBE_API_VER_1_1 2
#define IXGBE_API_VER_1_2 3
#define IXGBE_API_VER_1_3 4
+#define IXGBE_API_VER_1_6 ixgbe_mbox_api_16
#define IXGBE_API_VER_UNKNOWN UINT16_MAX
#define IXGBE_NO_VM 0