aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrzysztof Galazka <kgalazka@FreeBSD.org>2025-11-17 15:30:26 +0000
committerKrzysztof Galazka <kgalazka@FreeBSD.org>2025-11-17 15:30:35 +0000
commit1839526b7315cae62efbd2d1493e6243439effcb (patch)
treeced84b7c52c3bf28a65c03026ab58f33a014ac5f
parentbf2dc446d12953c67fa54698952b9072e3c660ce (diff)
igb(4): Fix VLAN support on VFs
Virtual Functions are considered untrusted and have no control over VLAN filtering configuration in HW. To allow using VLANs on VF intreface driver has to assume that VLAN HW Filtering is always enabled and pass requests for adding or removing VLAN tags to Physical Function driver using Mailbox API. Signed-off-by: Krzysztof Galazka <krzysztof.galazka@intel.com> Approved by: kbowling (mentor) Reviewed by: erj (previous version) Tested by: gowtham.kumar.ks_intel.com MFC after: 1 week Sponsored by: Intel Corporation Differential Revision: https://reviews.freebsd.org/D53245
-rw-r--r--sys/dev/e1000/if_em.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index e3d839b828ed..b8ea3168330b 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -4023,7 +4023,15 @@ em_if_vlan_register(if_ctx_t ctx, u16 vtag)
bit = vtag & 0x1F;
sc->shadow_vfta[index] |= (1 << bit);
++sc->num_vlans;
- em_if_vlan_filter_write(sc);
+ if (!sc->vf_ifp)
+ em_if_vlan_filter_write(sc);
+ else
+ /*
+ * Physical funtion may reject registering VLAN
+ * but we have no way to inform the stack
+ * about that.
+ */
+ e1000_vfta_set_vf(&sc->hw, vtag, true);
}
static void
@@ -4036,7 +4044,10 @@ em_if_vlan_unregister(if_ctx_t ctx, u16 vtag)
bit = vtag & 0x1F;
sc->shadow_vfta[index] &= ~(1 << bit);
--sc->num_vlans;
- em_if_vlan_filter_write(sc);
+ if (!sc->vf_ifp)
+ em_if_vlan_filter_write(sc);
+ else
+ e1000_vfta_set_vf(&sc->hw, vtag, false);
}
static bool
@@ -4094,22 +4105,15 @@ em_if_vlan_filter_write(struct e1000_softc *sc)
{
struct e1000_hw *hw = &sc->hw;
- if (sc->vf_ifp)
- return;
+ KASSERT(!sc->vf_ifp, ("VLAN filter write on VF\n"));
/* Disable interrupts for lem(4) devices during the filter change */
if (hw->mac.type < em_mac_min)
em_if_intr_disable(sc->ctx);
for (int i = 0; i < EM_VFTA_SIZE; i++)
- if (sc->shadow_vfta[i] != 0) {
- /* XXXKB: incomplete VF support, we returned above */
- if (sc->vf_ifp)
- e1000_vfta_set_vf(hw, sc->shadow_vfta[i],
- true);
- else
- e1000_write_vfta(hw, i, sc->shadow_vfta[i]);
- }
+ if (sc->shadow_vfta[i] != 0)
+ e1000_write_vfta(hw, i, sc->shadow_vfta[i]);
/* Re-enable interrupts for lem-class devices */
if (hw->mac.type < em_mac_min)
@@ -4124,8 +4128,10 @@ em_setup_vlan_hw_support(if_ctx_t ctx)
if_t ifp = iflib_get_ifp(ctx);
u32 reg;
- /* XXXKB: Return early if we are a VF until VF decap and filter
- * management is ready and tested.
+ /*
+ * Only PFs have control over VLAN HW filtering
+ * configuration. VFs have to act as if it's always
+ * enabled.
*/
if (sc->vf_ifp)
return;