aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Galabov <sgalabov@FreeBSD.org>2017-02-20 08:10:41 +0000
committerStanislav Galabov <sgalabov@FreeBSD.org>2017-02-20 08:10:41 +0000
commit31735ccf8af9186150a7de24784b28d6683d7555 (patch)
treed70378689a19e3bf4aa571b89a2240d1c540b152
parentc2863c0a7e3aac49f3a1153a1db7cfb29b985a86 (diff)
downloadsrc-31735ccf8af9186150a7de24784b28d6683d7555.tar.gz
src-31735ccf8af9186150a7de24784b28d6683d7555.zip
etherswitch: Fix RT305x vlan group operation
Fix an issue which prevents proper operation (addition/removal of members) of RT305x vlan groups. Tested by: yamori813@yahoo.co.jp Submitted by: yamori813@yahoo.co.jp (initial version) Reviewed by: adrian Differential Revision: https://reviews.freebsd.org/D9607
Notes
Notes: svn path=/head/; revision=313988
-rw-r--r--sys/dev/etherswitch/mtkswitch/mtkswitch_rt3050.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/sys/dev/etherswitch/mtkswitch/mtkswitch_rt3050.c b/sys/dev/etherswitch/mtkswitch/mtkswitch_rt3050.c
index 44b5807beaba..e3ea80fe2a1d 100644
--- a/sys/dev/etherswitch/mtkswitch/mtkswitch_rt3050.c
+++ b/sys/dev/etherswitch/mtkswitch/mtkswitch_rt3050.c
@@ -405,11 +405,38 @@ mtkswitch_vlan_setvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v)
MTKSWITCH_LOCK(sc);
/* First, see if we can accomodate the request at all */
val = MTKSWITCH_READ(sc, MTKSWITCH_POC2);
- if ((val & POC2_UNTAG_VLAN) == 0 ||
- sc->sc_switchtype == MTK_SWITCH_RT3050) {
+ if (sc->sc_switchtype == MTK_SWITCH_RT3050 ||
+ (val & POC2_UNTAG_VLAN) == 0) {
+ /*
+ * There are 2 things we can't support in per-port untagging
+ * mode:
+ * 1. Adding a port as an untagged member if the port is not
+ * set up to do untagging.
+ * 2. Adding a port as a tagged member if the port is set up
+ * to do untagging.
+ */
val &= VUB_MASK;
+
+ /* get all untagged members from the member list */
tmp = v->es_untagged_ports & v->es_member_ports;
- if (val != tmp) {
+ /* fail if untagged members are not a subset of all members */
+ if (tmp != v->es_untagged_ports) {
+ /* Cannot accomodate request */
+ MTKSWITCH_UNLOCK(sc);
+ return (ENOTSUP);
+ }
+
+ /* fail if any untagged member is set up to do tagging */
+ if ((tmp & val) != tmp) {
+ /* Cannot accomodate request */
+ MTKSWITCH_UNLOCK(sc);
+ return (ENOTSUP);
+ }
+
+ /* now, get the list of all tagged members */
+ tmp = v->es_member_ports & ~tmp;
+ /* fail if any tagged member is set up to do untagging */
+ if ((tmp & val) != 0) {
/* Cannot accomodate request */
MTKSWITCH_UNLOCK(sc);
return (ENOTSUP);