Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115797684
D31979.id95240.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D31979.id95240.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D31979: igc: Fix up hw vlan ops
Attached
Detach File
Event Timeline
Log In to Comment