aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Bowling <kbowling@FreeBSD.org>2026-08-10 15:08:49 +0000
committerKevin Bowling <kbowling@FreeBSD.org>2026-08-10 16:33:12 +0000
commit877f0ee40c2af801c5ca758a37b3ebddc560dad2 (patch)
tree3397fab2535e7a1e2e142146cdae60ef23b2f78b
parentdd532ad13371dcabc07d05052a7a256fc83c6ead (diff)
ixgbe: Preserve VF jumbo frame size across PF resets
sc->max_frame_size represents the largest frame requested by the PF or an active VF. The MTU callback replaces it with the PF frame size, so a subsequent reinitialization can program MHADD below an active VF's jumbo-frame request. Recompute the aggregate before hardware initialization and use it when programming MHADD. Recompute after each VF LPE request as well, so a reduced request can lower the hardware limit when no other function needs the previous value. MFC after: 2 weeks
-rw-r--r--sys/dev/ixgbe/if_ix.c6
-rw-r--r--sys/dev/ixgbe/if_sriov.c7
2 files changed, 9 insertions, 4 deletions
diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c
index cd8acf6685a8..252ae352829e 100644
--- a/sys/dev/ixgbe/if_ix.c
+++ b/sys/dev/ixgbe/if_ix.c
@@ -3973,6 +3973,10 @@ ixgbe_if_init(if_ctx_t ctx)
INIT_DEBUGOUT("ixgbe_if_init: begin");
+ /* Preserve the largest frame requested by the PF or an active VF. */
+ sc->max_frame_size = if_getmtu(ifp) + IXGBE_MTU_HDR;
+ ixgbe_recalculate_max_frame(sc);
+
/* Queue indices may change with IOV mode */
ixgbe_align_all_queue_indices(sc);
@@ -4010,7 +4014,7 @@ ixgbe_if_init(if_ctx_t ctx)
ixgbe_config_gpie(sc);
/* Set MTU size */
- if (if_getmtu(ifp) > ETHERMTU) {
+ if (sc->max_frame_size > ETHER_MAX_LEN) {
/* aka IXGBE_MAXFRS on 82599 and newer */
mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
mhadd &= ~IXGBE_MHADD_MFS_MASK;
diff --git a/sys/dev/ixgbe/if_sriov.c b/sys/dev/ixgbe/if_sriov.c
index 93555d11e72e..4ca61d078c8e 100644
--- a/sys/dev/ixgbe/if_sriov.c
+++ b/sys/dev/ixgbe/if_sriov.c
@@ -1150,7 +1150,7 @@ ixgbe_vf_set_lpe(struct ixgbe_softc *sc, struct ixgbe_vf *vf, uint32_t *msg)
}
vf->maximum_frame_size = vf_max_size;
- ixgbe_update_max_frame(sc, vf->maximum_frame_size);
+ ixgbe_recalculate_max_frame(sc);
/*
* We might have to disable reception to this VF if the frame size is
@@ -1161,7 +1161,7 @@ ixgbe_vf_set_lpe(struct ixgbe_softc *sc, struct ixgbe_vf *vf, uint32_t *msg)
mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
pf_max_size = (mhadd & IXGBE_MHADD_MFS_MASK) >> IXGBE_MHADD_MFS_SHIFT;
- if (pf_max_size < sc->max_frame_size) {
+ if (pf_max_size != sc->max_frame_size) {
mhadd &= ~IXGBE_MHADD_MFS_MASK;
mhadd |= sc->max_frame_size << IXGBE_MHADD_MFS_SHIFT;
IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd);
@@ -2107,12 +2107,13 @@ ixgbe_activate_vfs(struct ixgbe_softc *sc)
} /* ixgbe_activate_vfs */
-/* Check the max frame setting of all active VF's */
+/* Recompute the maximum frame setting of the PF and all active VFs. */
void
ixgbe_recalculate_max_frame(struct ixgbe_softc *sc)
{
struct ixgbe_vf *vf;
+ sc->max_frame_size = if_getmtu(iflib_get_ifp(sc->ctx)) + IXGBE_MTU_HDR;
for (int i = 0; i < sc->num_vfs; i++) {
vf = &sc->vfs[i];
if (vf->flags & IXGBE_VF_ACTIVE)