Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src add support VLAN HW filter
details: https://anonhg.NetBSD.org/src/rev/06847119b11f
branches: trunk
changeset: 848796:06847119b11f
user: ryo <ryo%NetBSD.org@localhost>
date: Mon Feb 10 05:53:11 2020 +0000
description:
add support VLAN HW filter
diffstat:
share/man/man4/aq.4 | 9 ++----
sys/dev/pci/if_aq.c | 78 ++++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 69 insertions(+), 18 deletions(-)
diffs (194 lines):
diff -r 19b4a5a743cf -r 06847119b11f share/man/man4/aq.4
--- a/share/man/man4/aq.4 Mon Feb 10 05:07:28 2020 +0000
+++ b/share/man/man4/aq.4 Mon Feb 10 05:53:11 2020 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: aq.4,v 1.2 2020/01/01 20:13:19 wiz Exp $
+.\" $NetBSD: aq.4,v 1.3 2020/02/10 05:53:11 ryo Exp $
.\"
.\" Copyright (c) 2020 Ryo Shimizu <ryo%nerv.org@localhost>
.\" All rights reserved.
@@ -24,7 +24,7 @@
.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd January 1, 2020
+.Dd February 10, 2020
.Dt AQ 4
.Os
.Sh NAME
@@ -71,6 +71,7 @@
.Xr ifmedia 4 ,
.Xr netintro 4 ,
.Xr pci 4 ,
+.Xr vlan 4 ,
.Xr ifconfig 8
.Sh HISTORY
The
@@ -80,7 +81,3 @@
and is based on the
.Fx
driver of the same name, but has been drastically rewritten by Ryo Shimizu.
-.Sh BUGS
-The
-.Nm
-driver does not support the VLAN hardware filter.
diff -r 19b4a5a743cf -r 06847119b11f sys/dev/pci/if_aq.c
--- a/sys/dev/pci/if_aq.c Mon Feb 10 05:07:28 2020 +0000
+++ b/sys/dev/pci/if_aq.c Mon Feb 10 05:53:11 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_aq.c,v 1.9 2020/02/10 05:07:28 ryo Exp $ */
+/* $NetBSD: if_aq.c,v 1.10 2020/02/10 05:53:12 ryo Exp $ */
/**
* aQuantia Corporation Network Driver
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_aq.c,v 1.9 2020/02/10 05:07:28 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_aq.c,v 1.10 2020/02/10 05:53:12 ryo Exp $");
#ifdef _KERNEL_OPT
#include "opt_if_aq.h"
@@ -1051,6 +1051,7 @@
static int aq_ifmedia_change(struct ifnet * const);
static void aq_ifmedia_status(struct ifnet * const, struct ifmediareq *);
+static int aq_vlan_cb(struct ethercom *ec, uint16_t vid, bool set);
static int aq_ifflags_cb(struct ethercom *);
static int aq_init(struct ifnet *);
static void aq_send_common_locked(struct ifnet *, struct aq_softc *,
@@ -1404,14 +1405,15 @@
#if notyet
/* TODO */
sc->sc_ethercom.ec_capabilities |= ETHERCAP_EEE;
- sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_HWFILTER;
#endif
sc->sc_ethercom.ec_capabilities |=
ETHERCAP_JUMBO_MTU |
ETHERCAP_VLAN_MTU |
- ETHERCAP_VLAN_HWTAGGING;
+ ETHERCAP_VLAN_HWTAGGING |
+ ETHERCAP_VLAN_HWFILTER;
sc->sc_ethercom.ec_capenable |=
- ETHERCAP_VLAN_HWTAGGING;
+ ETHERCAP_VLAN_HWTAGGING |
+ ETHERCAP_VLAN_HWFILTER;
ifp->if_capabilities = 0;
ifp->if_capenable = 0;
@@ -1446,6 +1448,7 @@
if_attach(ifp);
if_deferred_start_init(ifp, NULL);
ether_ifattach(ifp, sc->sc_enaddr.ether_addr_octet);
+ ether_set_vlan_cb(&sc->sc_ethercom, aq_vlan_cb);
ether_set_ifflags_cb(&sc->sc_ethercom, aq_ifflags_cb);
aq_enable_intr(sc, true, false); /* only intr about link */
@@ -2944,7 +2947,7 @@
ETHERTYPE_QINQ);
AQ_WRITE_REG_BIT(sc, RPF_VLAN_TPID_REG, RPF_VLAN_TPID_INNER,
ETHERTYPE_VLAN);
- AQ_WRITE_REG_BIT(sc, RPF_VLAN_MODE_REG, RPF_VLAN_MODE_PROMISC, 1);
+ AQ_WRITE_REG_BIT(sc, RPF_VLAN_MODE_REG, RPF_VLAN_MODE_PROMISC, 0);
if (sc->sc_features & FEATURES_REV_B) {
AQ_WRITE_REG_BIT(sc, RPF_VLAN_MODE_REG,
@@ -3216,18 +3219,55 @@
}
static void
-aq_update_vlan_filters(struct aq_softc *sc)
+aq_set_vlan_filters(struct aq_softc *sc)
{
- /* XXX: notyet. vlan always promisc */
+ struct ethercom *ec = &sc->sc_ethercom;
+ struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+ struct vlanid_list *vlanidp;
int i;
- for (i = 0; i < RPF_VLAN_MAX_FILTERS; i++) {
+ ETHER_LOCK(ec);
+
+ /* disable all vlan filters */
+ for (i = 0; i < RPF_VLAN_MAX_FILTERS; i++)
+ AQ_WRITE_REG(sc, RPF_VLAN_FILTER_REG(i), 0);
+
+ /* count VID */
+ i = 0;
+ SIMPLEQ_FOREACH(vlanidp, &ec->ec_vids, vid_list)
+ i++;
+
+ if (((sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_HWFILTER) == 0) ||
+ (ifp->if_flags & IFF_PROMISC) ||
+ (i > RPF_VLAN_MAX_FILTERS)) {
+ /*
+ * no vlan hwfilter, in promiscuous mode, or too many VID?
+ * must receive all VID
+ */
+ AQ_WRITE_REG_BIT(sc, RPF_VLAN_MODE_REG,
+ RPF_VLAN_MODE_PROMISC, 1);
+ goto done;
+ }
+
+ /* receive only selected VID */
+ AQ_WRITE_REG_BIT(sc, RPF_VLAN_MODE_REG, RPF_VLAN_MODE_PROMISC, 0);
+ i = 0;
+ SIMPLEQ_FOREACH(vlanidp, &ec->ec_vids, vid_list) {
AQ_WRITE_REG_BIT(sc, RPF_VLAN_FILTER_REG(i),
- RPF_VLAN_FILTER_EN, 0);
+ RPF_VLAN_FILTER_EN, 1);
AQ_WRITE_REG_BIT(sc, RPF_VLAN_FILTER_REG(i),
RPF_VLAN_FILTER_RXQ_EN, 0);
+ AQ_WRITE_REG_BIT(sc, RPF_VLAN_FILTER_REG(i),
+ RPF_VLAN_FILTER_RXQ, 0);
+ AQ_WRITE_REG_BIT(sc, RPF_VLAN_FILTER_REG(i),
+ RPF_VLAN_FILTER_ACTION, RPF_ACTION_HOST);
+ AQ_WRITE_REG_BIT(sc, RPF_VLAN_FILTER_REG(i),
+ RPF_VLAN_FILTER_ID, vlanidp->vid);
+ i++;
}
- AQ_WRITE_REG_BIT(sc, RPF_VLAN_MODE_REG, RPF_VLAN_MODE_PROMISC, 1);
+
+ done:
+ ETHER_UNLOCK(ec);
}
static int
@@ -4389,6 +4429,16 @@
}
static int
+aq_vlan_cb(struct ethercom *ec, uint16_t vid, bool set)
+{
+ struct ifnet *ifp = &ec->ec_if;
+ struct aq_softc *sc = ifp->if_softc;
+
+ aq_set_vlan_filters(sc);
+ return 0;
+}
+
+static int
aq_ifflags_cb(struct ethercom *ec)
{
struct ifnet *ifp = &ec->ec_if;
@@ -4412,6 +4462,10 @@
}
}
+ /* vlan configuration depends on also interface promiscuous mode */
+ if ((ecchange & ETHERCAP_VLAN_HWFILTER) || (iffchange & IFF_PROMISC))
+ aq_set_vlan_filters(sc);
+
sc->sc_ec_capenable = ec->ec_capenable;
sc->sc_if_flags = ifp->if_flags;
@@ -4428,7 +4482,7 @@
AQ_LOCK(sc);
- aq_update_vlan_filters(sc);
+ aq_set_vlan_filters(sc);
aq_set_capability(sc);
for (i = 0; i < sc->sc_nqueues; i++) {
Home |
Main Index |
Thread Index |
Old Index