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
Sponsored by:   Intel Corporation
Differential Revision:	https://reviews.freebsd.org/D53245

(cherry picked from commit 1839526b7315cae62efbd2d1493e6243439effcb)
This commit is contained in:
Krzysztof Galazka 2025-11-17 16:30:26 +01:00 committed by Franco Fichtner
parent abdb9fc652
commit b3969c45f4

View file

@ -4048,7 +4048,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
@ -4061,7 +4069,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
@ -4119,22 +4130,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)
@ -4149,8 +4153,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;