Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Implement VLAN hardware filter function(ETHERCAP_VLAN_HWFILT...
details: https://anonhg.NetBSD.org/src/rev/53818cc06270
branches: trunk
changeset: 962375:53818cc06270
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Wed Jul 17 03:26:24 2019 +0000
description:
Implement VLAN hardware filter function(ETHERCAP_VLAN_HWFILTER).
First proposed by jmcneill in 2017 and modified by me.
How to use:
- Set callback function:
ether_set_vlan_cb(struct ethercom *, ether_vlancb_t)
- Callback. This function is called when a vlan is attached/detached to the
parent interface:
int (*ether_vlancb_t)(struct ethercom *ec, uint16_t vlanid, bool set);
- ifconfig(8)
ifconfig ixg0 [-]vlan-hwfilter
Note that ETHERCAP_VLAN_HWFILTER is set by default on ixg(4) because
the PF driver usually enable "all block" filter by default.
diffstat:
sbin/ifconfig/ether.c | 6 +-
sys/dev/pci/ixgbe/ixgbe.c | 97 +++++++++++++++++++++++-------
sys/dev/pci/ixgbe/ixgbe.h | 5 +-
sys/dev/pci/ixgbe/ixv.c | 142 ++++++++++++++++++++++++++++++++-------------
sys/net/if_ether.h | 17 +++++-
sys/net/if_ethersubr.c | 13 +++-
sys/net/if_vlan.c | 65 ++++++++++++++++----
7 files changed, 256 insertions(+), 89 deletions(-)
diffs (truncated from 758 to 300 lines):
diff -r f9417b873d61 -r 53818cc06270 sbin/ifconfig/ether.c
--- a/sbin/ifconfig/ether.c Wed Jul 17 03:09:16 2019 +0000
+++ b/sbin/ifconfig/ether.c Wed Jul 17 03:26:24 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ether.c,v 1.5 2019/07/17 03:09:16 msaitoh Exp $ */
+/* $NetBSD: ether.c,v 1.6 2019/07/17 03:26:24 msaitoh Exp $ */
/*
* Copyright (c) 1983, 1993
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: ether.c,v 1.5 2019/07/17 03:09:16 msaitoh Exp $");
+__RCSID("$NetBSD: ether.c,v 1.6 2019/07/17 03:26:24 msaitoh Exp $");
#endif /* not lint */
#include <sys/param.h>
@@ -64,9 +64,7 @@
#define MAX_PRINT_LEN 55
static const struct kwinst ethercapskw[] = {
-#if 0 /* notyet */
IFKW("vlan-hwfilter", ETHERCAP_VLAN_HWFILTER),
-#endif
IFKW("vlan-hwtagging", ETHERCAP_VLAN_HWTAGGING),
IFKW("eee", ETHERCAP_EEE)
};
diff -r f9417b873d61 -r 53818cc06270 sys/dev/pci/ixgbe/ixgbe.c
--- a/sys/dev/pci/ixgbe/ixgbe.c Wed Jul 17 03:09:16 2019 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.c Wed Jul 17 03:26:24 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.192 2019/07/04 09:02:24 msaitoh Exp $ */
+/* $NetBSD: ixgbe.c,v 1.193 2019/07/17 03:26:24 msaitoh Exp $ */
/******************************************************************************
@@ -220,10 +220,9 @@
static void ixgbe_eitr_write(struct adapter *, uint32_t, uint32_t);
static void ixgbe_setup_vlan_hw_support(struct adapter *);
-#if 0
-static void ixgbe_register_vlan(void *, struct ifnet *, u16);
-static void ixgbe_unregister_vlan(void *, struct ifnet *, u16);
-#endif
+static int ixgbe_vlan_cb(struct ethercom *, uint16_t, bool);
+static int ixgbe_register_vlan(void *, struct ifnet *, u16);
+static int ixgbe_unregister_vlan(void *, struct ifnet *, u16);
static void ixgbe_add_device_sysctls(struct adapter *);
static void ixgbe_add_hw_stats(struct adapter *);
@@ -905,6 +904,9 @@
/* Enable WoL (if supported) */
ixgbe_check_wol_support(adapter);
+ /* Register for VLAN events */
+ ether_set_vlan_cb(&adapter->osdep.ec, ixgbe_vlan_cb);
+
/* Verify adapter fan is still functional (if applicable) */
if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL) {
u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
@@ -2299,7 +2301,20 @@
return sysctl_lookup(SYSCTLFN_CALL(&node));
} /* ixgbe_sysctl_rdt_handler */
-#if 0 /* XXX Badly need to overhaul vlan(4) on NetBSD. */
+static int
+ixgbe_vlan_cb(struct ethercom *ec, uint16_t vid, bool set)
+{
+ struct ifnet *ifp = &ec->ec_if;
+ int rv;
+
+ if (set)
+ rv = ixgbe_register_vlan(ifp->if_softc, ifp, vid);
+ else
+ rv = ixgbe_unregister_vlan(ifp->if_softc, ifp, vid);
+
+ return rv;
+}
+
/************************************************************************
* ixgbe_register_vlan
*
@@ -2308,24 +2323,30 @@
* just creates the entry in the soft version of the
* VFTA, init will repopulate the real table.
************************************************************************/
-static void
+static int
ixgbe_register_vlan(void *arg, struct ifnet *ifp, u16 vtag)
{
struct adapter *adapter = ifp->if_softc;
u16 index, bit;
+ int error;
if (ifp->if_softc != arg) /* Not our event */
- return;
+ return EINVAL;
if ((vtag == 0) || (vtag > 4095)) /* Invalid */
- return;
+ return EINVAL;
IXGBE_CORE_LOCK(adapter);
index = (vtag >> 5) & 0x7F;
bit = vtag & 0x1F;
adapter->shadow_vfta[index] |= (1 << bit);
- ixgbe_setup_vlan_hw_support(adapter);
+ error = adapter->hw.mac.ops.set_vfta(&adapter->hw, vtag, 0, true,
+ true);
IXGBE_CORE_UNLOCK(adapter);
+ if (error != 0)
+ error = EACCES;
+
+ return error;
} /* ixgbe_register_vlan */
/************************************************************************
@@ -2333,27 +2354,31 @@
*
* Run via vlan unconfig EVENT, remove our entry in the soft vfta.
************************************************************************/
-static void
+static int
ixgbe_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
{
struct adapter *adapter = ifp->if_softc;
u16 index, bit;
+ int error;
if (ifp->if_softc != arg)
- return;
+ return EINVAL;
if ((vtag == 0) || (vtag > 4095)) /* Invalid */
- return;
+ return EINVAL;
IXGBE_CORE_LOCK(adapter);
index = (vtag >> 5) & 0x7F;
bit = vtag & 0x1F;
adapter->shadow_vfta[index] &= ~(1 << bit);
- /* Re-init to load the changes */
- ixgbe_setup_vlan_hw_support(adapter);
+ error = adapter->hw.mac.ops.set_vfta(&adapter->hw, vtag, 0, false,
+ true);
IXGBE_CORE_UNLOCK(adapter);
+ if (error != 0)
+ error = EACCES;
+
+ return error;
} /* ixgbe_unregister_vlan */
-#endif
static void
ixgbe_setup_vlan_hw_support(struct adapter *adapter)
@@ -2363,6 +2388,7 @@
struct rx_ring *rxr;
int i;
u32 ctrl;
+ struct vlanid_list *vlanidp;
bool hwtagging;
/*
@@ -2391,14 +2417,21 @@
rxr->vtag_strip = hwtagging ? TRUE : FALSE;
}
- /*
- * A soft reset zero's out the VFTA, so
- * we need to repopulate it now.
- */
+ /* Cleanup shadow_vfta */
for (i = 0; i < IXGBE_VFTA_SIZE; i++)
- if (adapter->shadow_vfta[i] != 0)
- IXGBE_WRITE_REG(hw, IXGBE_VFTA(i),
- adapter->shadow_vfta[i]);
+ adapter->shadow_vfta[i] = 0;
+ /* Generate shadow_vfta from ec_vids */
+ mutex_enter(ec->ec_lock);
+ SIMPLEQ_FOREACH(vlanidp, &ec->ec_vids, vid_list) {
+ uint32_t idx;
+
+ idx = vlanidp->vid / 32;
+ KASSERT(idx < IXGBE_VFTA_SIZE);
+ adapter->shadow_vfta[idx] |= 1 << vlanidp->vid % 32;
+ }
+ mutex_exit(ec->ec_lock);
+ for (i = 0; i < IXGBE_VFTA_SIZE; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_VFTA(i), adapter->shadow_vfta[i]);
ctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
/* Enable the Filter Table if enabled */
@@ -4107,6 +4140,7 @@
/* Update saved flags. See ixgbe_ifflags_cb() */
adapter->if_flags = ifp->if_flags;
+ adapter->ec_capenable = adapter->osdep.ec.ec_capenable;
/* Now inform the stack we're ready */
ifp->if_flags |= IFF_RUNNING;
@@ -6151,8 +6185,23 @@
} else if ((change & IFF_PROMISC) != 0)
ixgbe_set_promisc(adapter);
+ /* Check for ec_capenable. */
+ change = ec->ec_capenable ^ adapter->ec_capenable;
+ adapter->ec_capenable = ec->ec_capenable;
+ if ((change & ~(ETHERCAP_VLAN_MTU | ETHERCAP_VLAN_HWTAGGING
+ | ETHERCAP_VLAN_HWFILTER)) != 0) {
+ rv = ENETRESET;
+ goto out;
+ }
+
+ /*
+ * Special handling is not required for ETHERCAP_VLAN_MTU.
+ * MAXFRS(MHADD) does not include the 4bytes of the VLAN header.
+ */
+
/* Set up VLAN support and filter */
- ixgbe_setup_vlan_hw_support(adapter);
+ if ((change & (ETHERCAP_VLAN_HWTAGGING | ETHERCAP_VLAN_HWFILTER)) != 0)
+ ixgbe_setup_vlan_hw_support(adapter);
out:
IXGBE_CORE_UNLOCK(adapter);
diff -r f9417b873d61 -r 53818cc06270 sys/dev/pci/ixgbe/ixgbe.h
--- a/sys/dev/pci/ixgbe/ixgbe.h Wed Jul 17 03:09:16 2019 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.h Wed Jul 17 03:26:24 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.h,v 1.55 2019/06/27 05:55:40 msaitoh Exp $ */
+/* $NetBSD: ixgbe.h,v 1.56 2019/07/17 03:26:24 msaitoh Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -475,7 +475,8 @@
struct ifmedia media;
callout_t timer;
- int if_flags;
+ int if_flags; /* saved ifp->if_flags */
+ int ec_capenable; /* saved ec->ec_capenable */
kmutex_t core_mtx;
diff -r f9417b873d61 -r 53818cc06270 sys/dev/pci/ixgbe/ixv.c
--- a/sys/dev/pci/ixgbe/ixv.c Wed Jul 17 03:09:16 2019 +0000
+++ b/sys/dev/pci/ixgbe/ixv.c Wed Jul 17 03:26:24 2019 +0000
@@ -1,4 +1,4 @@
-/*$NetBSD: ixv.c,v 1.119 2019/07/17 03:09:16 msaitoh Exp $*/
+/*$NetBSD: ixv.c,v 1.120 2019/07/17 03:26:24 msaitoh Exp $*/
/******************************************************************************
@@ -120,11 +120,10 @@
static u8 * ixv_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
static void ixv_eitr_write(struct adapter *, uint32_t, uint32_t);
-static void ixv_setup_vlan_support(struct adapter *);
-#if 0
-static void ixv_register_vlan(void *, struct ifnet *, u16);
-static void ixv_unregister_vlan(void *, struct ifnet *, u16);
-#endif
+static int ixv_setup_vlan_support(struct adapter *);
+static int ixv_vlan_cb(struct ethercom *, uint16_t, bool);
+static int ixv_register_vlan(void *, struct ifnet *, u16);
+static int ixv_unregister_vlan(void *, struct ifnet *, u16);
static void ixv_add_device_sysctls(struct adapter *);
static void ixv_save_stats(struct adapter *);
@@ -471,12 +470,7 @@
}
/* Register for VLAN events */
-#if 0 /* XXX delete after write? */
- adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
- ixv_register_vlan, adapter, EVENTHANDLER_PRI_FIRST);
- adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
- ixv_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
-#endif
+ ether_set_vlan_cb(&adapter->osdep.ec, ixv_vlan_cb);
/* Sysctls for limiting the amount of work done in the taskqueues */
ixv_set_sysctl_value(adapter, "rx_processing_limit",
@@ -618,14 +612,6 @@
/* Drain the Mailbox(link) queue */
softint_disestablish(adapter->link_si);
- /* Unregister VLAN events */
-#if 0 /* XXX msaitoh delete after write? */
- if (adapter->vlan_attach != NULL)
- EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach);
- if (adapter->vlan_detach != NULL)
- EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach);
-#endif
-
ether_ifdetach(adapter->ifp);
callout_halt(&adapter->timer, NULL);
@@ -823,6 +809,7 @@
Home |
Main Index |
Thread Index |
Old Index