Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/etherswitch/mtkswitch/mtkswitch_rt3050.c
Show First 20 Lines • Show All 399 Lines • ▼ Show 20 Lines | mtkswitch_vlan_setvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v) | ||||
if ((sc->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) || | if ((sc->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) || | ||||
(v->es_vlangroup > sc->info.es_nvlangroups)) | (v->es_vlangroup > sc->info.es_nvlangroups)) | ||||
return (EINVAL); | return (EINVAL); | ||||
MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED); | MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED); | ||||
MTKSWITCH_LOCK(sc); | MTKSWITCH_LOCK(sc); | ||||
/* First, see if we can accomodate the request at all */ | /* First, see if we can accomodate the request at all */ | ||||
val = MTKSWITCH_READ(sc, MTKSWITCH_POC2); | val = MTKSWITCH_READ(sc, MTKSWITCH_POC2); | ||||
if ((val & POC2_UNTAG_VLAN) == 0 || | if (sc->sc_switchtype == MTK_SWITCH_RT3050 || | ||||
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; | val &= VUB_MASK; | ||||
/* get all untagged members from the member list */ | |||||
tmp = v->es_untagged_ports & v->es_member_ports; | 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 */ | /* Cannot accomodate request */ | ||||
MTKSWITCH_UNLOCK(sc); | MTKSWITCH_UNLOCK(sc); | ||||
return (ENOTSUP); | return (ENOTSUP); | ||||
} | } | ||||
} else { | } else { | ||||
/* Prefer per-Vlan untag and set its members */ | /* Prefer per-Vlan untag and set its members */ | ||||
val = MTKSWITCH_READ(sc, MTKSWITCH_VUB(v->es_vlangroup)); | val = MTKSWITCH_READ(sc, MTKSWITCH_VUB(v->es_vlangroup)); | ||||
val &= ~(VUB_MASK << VUB_OFF(v->es_vlangroup)); | val &= ~(VUB_MASK << VUB_OFF(v->es_vlangroup)); | ||||
▲ Show 20 Lines • Show All 78 Lines • Show Last 20 Lines |