Page MenuHomeFreeBSD

D31979.id95240.diff
No OneTemporary

D31979.id95240.diff

Index: sys/dev/igc/if_igc.c
===================================================================
--- sys/dev/igc/if_igc.c
+++ sys/dev/igc/if_igc.c
@@ -117,6 +117,11 @@
static void igc_update_stats_counters(struct igc_adapter *);
static void igc_add_hw_stats(struct igc_adapter *adapter);
static int igc_if_set_promisc(if_ctx_t ctx, int flags);
+static bool igc_if_vlan_filter_capable(struct igc_adapter *);
+static bool igc_if_vlan_filter_used(struct igc_adapter *);
+static void igc_if_vlan_filter_enable(struct igc_adapter *);
+static void igc_if_vlan_filter_disable(struct igc_adapter *);
+static void igc_if_vlan_filter_write(struct igc_adapter *);
static void igc_setup_vlan_hw_support(struct igc_adapter *);
static int igc_sysctl_nvm_info(SYSCTL_HANDLER_ARGS);
static void igc_print_nvm_info(struct igc_adapter *);
@@ -844,18 +849,8 @@
adapter->rx_mbuf_sz = iflib_get_rx_mbuf_sz(ctx);
igc_initialize_receive_unit(ctx);
- /* Use real VLAN Filter support? */
- if (if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING) {
- if (if_getcapenable(ifp) & IFCAP_VLAN_HWFILTER)
- /* Use real VLAN Filter support */
- igc_setup_vlan_hw_support(adapter);
- else {
- u32 ctrl;
- ctrl = IGC_READ_REG(&adapter->hw, IGC_CTRL);
- ctrl |= IGC_CTRL_VME;
- IGC_WRITE_REG(&adapter->hw, IGC_CTRL, ctrl);
- }
- }
+ /* Set up VLAN support and filter */
+ igc_setup_vlan_hw_support(adapter);
/* Don't lose promiscuous settings */
igc_if_set_promisc(ctx, IFF_PROMISC);
@@ -1112,14 +1107,19 @@
if (flags & IFF_PROMISC) {
reg_rctl |= (IGC_RCTL_UPE | IGC_RCTL_MPE);
+ igc_if_vlan_filter_disable(adapter);
/* Turn this on if you want to see bad packets */
if (igc_debug_sbp)
reg_rctl |= IGC_RCTL_SBP;
IGC_WRITE_REG(&adapter->hw, IGC_RCTL, reg_rctl);
- } else if (flags & IFF_ALLMULTI) {
- reg_rctl |= IGC_RCTL_MPE;
- reg_rctl &= ~IGC_RCTL_UPE;
- IGC_WRITE_REG(&adapter->hw, IGC_RCTL, reg_rctl);
+ } else {
+ if (flags & IFF_ALLMULTI) {
+ reg_rctl |= IGC_RCTL_MPE;
+ reg_rctl &= ~IGC_RCTL_UPE;
+ IGC_WRITE_REG(&adapter->hw, IGC_RCTL, reg_rctl);
+ }
+ if (igc_if_vlan_filter_used(adapter))
+ igc_if_vlan_filter_enable(adapter);
}
return (0);
}
@@ -2147,6 +2147,7 @@
bit = vtag & 0x1F;
adapter->shadow_vfta[index] |= (1 << bit);
++adapter->num_vlans;
+ igc_if_vlan_filter_write(adapter);
}
static void
@@ -2159,41 +2160,100 @@
bit = vtag & 0x1F;
adapter->shadow_vfta[index] &= ~(1 << bit);
--adapter->num_vlans;
+ igc_if_vlan_filter_write(adapter);
+}
+
+static bool
+igc_if_vlan_filter_capable(struct igc_adapter *adapter)
+{
+ if_softc_ctx_t scctx = adapter->shared;
+
+ if ((scctx->isc_capenable & IFCAP_VLAN_HWFILTER) &&
+ !igc_disable_crc_stripping)
+ return (true);
+
+ return (false);
+}
+
+static bool
+igc_if_vlan_filter_used(struct igc_adapter *adapter)
+{
+ if (!igc_if_vlan_filter_capable(adapter))
+ return (false);
+
+ for (int i = 0; i < IGC_VFTA_SIZE; i++)
+ if (adapter->shadow_vfta[i] != 0)
+ return (true);
+
+ return (false);
+}
+
+static void
+igc_if_vlan_filter_enable(struct igc_adapter *adapter)
+{
+ struct igc_hw *hw = &adapter->hw;
+ u32 reg;
+
+ reg = IGC_READ_REG(hw, IGC_RCTL);
+ reg &= ~IGC_RCTL_CFIEN;
+ reg |= IGC_RCTL_VFE;
+ IGC_WRITE_REG(hw, IGC_RCTL, reg);
+}
+
+static void
+igc_if_vlan_filter_disable(struct igc_adapter *adapter)
+{
+ struct igc_hw *hw = &adapter->hw;
+ u32 reg;
+
+ reg = IGC_READ_REG(hw, IGC_RCTL);
+ reg &= ~(IGC_RCTL_VFE | IGC_RCTL_CFIEN);
+ IGC_WRITE_REG(hw, IGC_RCTL, reg);
+}
+
+static void
+igc_if_vlan_filter_write(struct igc_adapter *adapter)
+{
+ struct igc_hw *hw = &adapter->hw;
+
+ for (int i = 0; i < IGC_VFTA_SIZE; i++)
+ if (adapter->shadow_vfta[i] != 0) {
+ igc_write_vfta(hw, i, adapter->shadow_vfta[i]);
+ }
}
static void
igc_setup_vlan_hw_support(struct igc_adapter *adapter)
{
+ if_softc_ctx_t scctx = adapter->shared;
struct igc_hw *hw = &adapter->hw;
u32 reg;
- /*
- * We get here thru init_locked, meaning
- * a soft reset, this has already cleared
- * the VFTA and other state, so if there
- * have been no vlan's registered do nothing.
- */
- if (adapter->num_vlans == 0)
+ if (scctx->isc_capenable & IFCAP_VLAN_HWTAGGING &&
+ !igc_disable_crc_stripping) {
+ reg = IGC_READ_REG(hw, IGC_CTRL);
+ reg |= IGC_CTRL_VME;
+ IGC_WRITE_REG(hw, IGC_CTRL, reg);
+ } else {
+ reg = IGC_READ_REG(hw, IGC_CTRL);
+ reg &= ~IGC_CTRL_VME;
+ IGC_WRITE_REG(hw, IGC_CTRL, reg);
+ }
+
+ /* If we aren't doing HW filtering, we're done */
+ if (!igc_if_vlan_filter_capable(adapter)) {
+ igc_if_vlan_filter_disable(adapter);
return;
+ }
/*
* A soft reset zero's out the VFTA, so
* we need to repopulate it now.
*/
- for (int i = 0; i < IGC_VFTA_SIZE; i++)
- if (adapter->shadow_vfta[i] != 0)
- IGC_WRITE_REG_ARRAY(hw, IGC_VFTA,
- i, adapter->shadow_vfta[i]);
-
- reg = IGC_READ_REG(hw, IGC_CTRL);
- reg |= IGC_CTRL_VME;
- IGC_WRITE_REG(hw, IGC_CTRL, reg);
+ igc_if_vlan_filter_write(adapter);
/* Enable the Filter Table */
- reg = IGC_READ_REG(hw, IGC_RCTL);
- reg &= ~IGC_RCTL_CFIEN;
- reg |= IGC_RCTL_VFE;
- IGC_WRITE_REG(hw, IGC_RCTL, reg);
+ igc_if_vlan_filter_enable(adapter);
}
static void
@@ -2469,6 +2529,7 @@
{
switch (event) {
case IFLIB_RESTART_VLAN_CONFIG:
+ return (false);
default:
return (true);
}

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 29, 7:36 PM (1 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17845157
Default Alt Text
D31979.id95240.diff (5 KB)

Event Timeline