Index: sys/dev/e1000/if_em.c =================================================================== --- sys/dev/e1000/if_em.c +++ sys/dev/e1000/if_em.c @@ -3411,6 +3411,7 @@ bit = vtag & 0x1F; adapter->shadow_vfta[index] |= (1 << bit); ++adapter->num_vlans; + em_setup_vlan_hw_support(adapter); } static void @@ -3423,11 +3424,13 @@ bit = vtag & 0x1F; adapter->shadow_vfta[index] &= ~(1 << bit); --adapter->num_vlans; + em_setup_vlan_hw_support(adapter); } static void em_setup_vlan_hw_support(struct adapter *adapter) { + struct ifnet *ifp = iflib_get_ifp(adapter->ctx); struct e1000_hw *hw = &adapter->hw; u32 reg; @@ -3440,18 +3443,33 @@ if (adapter->num_vlans == 0) return; + if (adapter->vf_ifp) + e1000_rlpml_set_vf(hw, + adapter->shared->isc_max_frame_size + VLAN_TAG_SIZE); + + if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING && + !em_disable_crc_stripping) { + reg = E1000_READ_REG(hw, E1000_CTRL); + reg |= E1000_CTRL_VME; + E1000_WRITE_REG(hw, E1000_CTRL, reg); + } + + /* If we aren't doing HW filtering, we're done */ + if ((ifp->if_capenable & IFCAP_VLAN_HWFILTER) == 0 || + em_disable_crc_stripping) + return; + /* * A soft reset zero's out the VFTA, so * we need to repopulate it now. */ for (int i = 0; i < EM_VFTA_SIZE; i++) - if (adapter->shadow_vfta[i] != 0) - E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, - i, adapter->shadow_vfta[i]); - - reg = E1000_READ_REG(hw, E1000_CTRL); - reg |= E1000_CTRL_VME; - E1000_WRITE_REG(hw, E1000_CTRL, reg); + if (adapter->shadow_vfta[i] != 0) { + if (adapter->vf_ifp) + e1000_vfta_set_vf(hw, adapter->shadow_vfta[i], TRUE); + else + e1000_write_vfta(hw, i, adapter->shadow_vfta[i]); + } /* Enable the Filter Table */ reg = E1000_READ_REG(hw, E1000_RCTL);