diff options
| author | Kevin Bowling <kbowling@FreeBSD.org> | 2026-08-10 15:08:49 +0000 |
|---|---|---|
| committer | Kevin Bowling <kbowling@FreeBSD.org> | 2026-08-10 16:33:12 +0000 |
| commit | 877f0ee40c2af801c5ca758a37b3ebddc560dad2 (patch) | |
| tree | 3397fab2535e7a1e2e142146cdae60ef23b2f78b | |
| parent | dd532ad13371dcabc07d05052a7a256fc83c6ead (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.c | 6 | ||||
| -rw-r--r-- | sys/dev/ixgbe/if_sriov.c | 7 |
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) |
