git: 933c4f6e06c2 - main - iavf: Honor negotiated VLAN offload capabilities
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 03 Nov 2026 02:41:55 UTC
The branch main has been updated by kbowling:
URL: https://cgit.FreeBSD.org/src/commit/?id=933c4f6e06c276548783247242b75814027159eb
commit 933c4f6e06c276548783247242b75814027159eb
Author: Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-11-02 00:40:25 +0000
Commit: Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-11-03 02:41:46 +0000
iavf: Honor negotiated VLAN offload capabilities
The driver advertised VLAN offload unconditionally, even when the PF
did not grant it, as observed with an E835 VF under Hyper-V. This
tells the stack to rely on hardware tag insertion and sends the PF
unsupported VLAN filter requests.
Advertise hardware VLAN tagging and filtering only when GET_VF_RESOURCES
grants the legacy VLAN capability. Do not allocate filter shadow entries
or send ADD_VLAN/DEL_VLAN requests without that capability. Retain VLAN
MTU and checksum/TSO support for software-tagged packets.
Keep advertised capabilities stable across resets, since existing VLAN
interfaces may already rely on them. If resource rediscovery removes
previously advertised VLAN offload, leave the VF stopped and require
reattachment rather than resume with a stale offload contract. A newly
granted capability is not exposed until reattach.
MFC after: 2 weeks
Sponsored by: BBOX.io
---
sys/dev/iavf/iavf_vc_common.c | 5 +++++
sys/dev/iavf/if_iavf_iflib.c | 20 +++++++++++++++++++-
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/sys/dev/iavf/iavf_vc_common.c b/sys/dev/iavf/iavf_vc_common.c
index a605ec0901bf..c67f660f9356 100644
--- a/sys/dev/iavf/iavf_vc_common.c
+++ b/sys/dev/iavf/iavf_vc_common.c
@@ -483,6 +483,11 @@ iavf_sync_vlans(struct iavf_sc *sc)
int error, first_error;
sx_assert(iflib_ctx_lock_get(sc->vsi.ctx), SA_XLOCKED);
+ /* Software VLANs need no PF filter configuration. */
+ if ((sc->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) == 0) {
+ atomic_store_rel_32(&sc->vlan_batch_pending, 0);
+ return (0);
+ }
if (iavf_test_state(&sc->state, IAVF_STATE_RESET_PENDING) ||
iavf_test_state(&sc->state, IAVF_STATE_RESET_RECOVERY) ||
iavf_test_state(&sc->state, IAVF_STATE_VC_POLLING) ||
diff --git a/sys/dev/iavf/if_iavf_iflib.c b/sys/dev/iavf/if_iavf_iflib.c
index 304347316a75..4fb0237d2d7c 100644
--- a/sys/dev/iavf/if_iavf_iflib.c
+++ b/sys/dev/iavf/if_iavf_iflib.c
@@ -414,7 +414,11 @@ iavf_if_attach_pre(if_ctx_t ctx)
if ((sc->vf_res->vf_cap_flags & (VIRTCHNL_VF_OFFLOAD_RSS_REG |
VIRTCHNL_VF_OFFLOAD_RSS_PF)) == VIRTCHNL_VF_OFFLOAD_RSS_PF)
scctx->isc_rss_table_size = sc->vf_res->rss_lut_size;
- scctx->isc_capabilities = scctx->isc_capenable = IAVF_CAPS;
+ scctx->isc_capabilities = IAVF_CAPS;
+ if ((sc->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) == 0)
+ scctx->isc_capabilities &=
+ ~(IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWFILTER);
+ scctx->isc_capenable = scctx->isc_capabilities;
scctx->isc_tx_csum_flags = CSUM_OFFLOAD;
return (0);
@@ -1123,6 +1127,16 @@ iavf_reestablish_vc(struct iavf_sc *sc)
if (error != 0)
goto fail;
+ /* Do not keep advertising an offload that the PF no longer provides. */
+ if ((vsi->shared->isc_capabilities & IFCAP_VLAN_HWTAGGING) != 0 &&
+ (sc->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) == 0) {
+ if (iavf_mbx_log_allowed(sc))
+ device_printf(sc->dev,
+ "PF VLAN offload capabilities changed; reattach the VF\n");
+ error = ENOTSUP;
+ goto fail;
+ }
+
if (vsi->num_tx_queues > sc->vsi_res->num_queue_pairs ||
vsi->num_rx_queues > sc->vsi_res->num_queue_pairs ||
vsi->num_rx_queues + 1 > sc->vf_res->max_vectors) {
@@ -2027,6 +2041,8 @@ iavf_if_vlan_register(if_ctx_t ctx, u16 vtag)
struct iavf_sc *sc = iavf_sc_from_ctx(ctx);
struct iavf_vsi *vsi = &sc->vsi;
+ if ((vsi->shared->isc_capabilities & IFCAP_VLAN_HWFILTER) == 0)
+ return;
if ((vtag == 0) || (vtag > 4095)) /* Invalid */
return;
@@ -2054,6 +2070,8 @@ iavf_if_vlan_unregister(if_ctx_t ctx, u16 vtag)
struct iavf_vsi *vsi = &sc->vsi;
int i = 0;
+ if ((vsi->shared->isc_capabilities & IFCAP_VLAN_HWFILTER) == 0)
+ return;
if ((vtag == 0) || (vtag > 4095) || (vsi->num_vlans == 0)) /* Invalid */
return;