diff options
author | loos <loos@FreeBSD.org> | 2013-07-23 13:56:38 +0000 |
---|---|---|
committer | loos <loos@FreeBSD.org> | 2013-07-23 13:56:38 +0000 |
commit | e4f13850f70c2edd8f1918455575694b72741b3e (patch) | |
tree | 32395f066ef0466740d4e137c2ced3772250ba58 /sys/dev/etherswitch | |
parent | 88d161491f8f0902491f8df563668a7f3524d4f7 (diff) | |
download | FreeBSD-src-e4f13850f70c2edd8f1918455575694b72741b3e.zip FreeBSD-src-e4f13850f70c2edd8f1918455575694b72741b3e.tar.gz |
Add a new flag (ETHERSWITCH_VID_VALID) to say what vlangroups are in use.
This fix the case when etherswitch is printing the information of port 0
vlan group (in port based vlan mode) with no member ports.
Add the ETHERSWITCH_VID_VALID support to ip17x driver.
Add the ETHERSWITCH_VID_VALID support to rt8366 driver.
arswitch doesn't need to be updated as it doesn't support vlans management
yet.
Approved by: adrian (mentor)
Diffstat (limited to 'sys/dev/etherswitch')
-rw-r--r-- | sys/dev/etherswitch/etherswitch.h | 2 | ||||
-rw-r--r-- | sys/dev/etherswitch/ip17x/ip175c.c | 4 | ||||
-rw-r--r-- | sys/dev/etherswitch/ip17x/ip175d.c | 6 | ||||
-rw-r--r-- | sys/dev/etherswitch/ip17x/ip17x_vlans.c | 30 | ||||
-rw-r--r-- | sys/dev/etherswitch/rtl8366/rtl8366rb.c | 2 |
5 files changed, 33 insertions, 11 deletions
diff --git a/sys/dev/etherswitch/etherswitch.h b/sys/dev/etherswitch/etherswitch.h index bb0167b..2619019 100644 --- a/sys/dev/etherswitch/etherswitch.h +++ b/sys/dev/etherswitch/etherswitch.h @@ -26,6 +26,8 @@ struct etherswitch_phyreg { typedef struct etherswitch_phyreg etherswitch_phyreg_t; #define ETHERSWITCH_NAMEMAX 64 +#define ETHERSWITCH_VID_MASK 0xfff +#define ETHERSWITCH_VID_VALID (1 << 12) #define ETHERSWITCH_VLAN_ISL (1 << 0) /* ISL */ #define ETHERSWITCH_VLAN_PORT (1 << 1) /* Port based vlan */ #define ETHERSWITCH_VLAN_DOT1Q (1 << 2) /* 802.1q */ diff --git a/sys/dev/etherswitch/ip17x/ip175c.c b/sys/dev/etherswitch/ip17x/ip175c.c index b106e29..ced23c0 100644 --- a/sys/dev/etherswitch/ip17x/ip175c.c +++ b/sys/dev/etherswitch/ip17x/ip175c.c @@ -147,9 +147,9 @@ ip175c_dot1q_vlan_setup(struct ip17x_softc *sc) memset(vlans, 0, sizeof(vlans)); for (i = 0; i < IP17X_MAX_VLANS; i++) { v = &sc->vlan[i]; - if (v->vlanid == 0) + if ((v->vlanid & ETHERSWITCH_VID_VALID) == 0) continue; - vlans[v->vlanid] = v->ports; + vlans[v->vlanid & ETHERSWITCH_VID_MASK] = v->ports; } for (j = 0, i = 1; i <= IP17X_MAX_VLANS / 2; i++) { diff --git a/sys/dev/etherswitch/ip17x/ip175d.c b/sys/dev/etherswitch/ip17x/ip175d.c index 8bc2843..1e6eee2 100644 --- a/sys/dev/etherswitch/ip17x/ip175d.c +++ b/sys/dev/etherswitch/ip17x/ip175d.c @@ -94,7 +94,8 @@ ip175d_hw_setup(struct ip17x_softc *sc) striptag[i] = 0; v = &sc->vlan[i]; - if (v->vlanid == 0 || sc->vlan_mode == 0) { + if ((v->vlanid & ETHERSWITCH_VID_VALID) == 0 || + sc->vlan_mode == 0) { /* Vlangroup disabled. Reset the filter. */ ip17x_writephy(sc->sc_dev, 22, 14 + i, i + 1); ports[i] = 0x3f; @@ -105,7 +106,8 @@ ip175d_hw_setup(struct ip17x_softc *sc) ports[i] = v->ports; /* Setup the filter, write the VLAN id. */ - ip17x_writephy(sc->sc_dev, 22, 14 + i, v->vlanid); + ip17x_writephy(sc->sc_dev, 22, 14 + i, + v->vlanid & ETHERSWITCH_VID_MASK); for (j = 0; j < MII_NPHY; j++) { if ((ports[i] & (1 << j)) == 0) diff --git a/sys/dev/etherswitch/ip17x/ip17x_vlans.c b/sys/dev/etherswitch/ip17x/ip17x_vlans.c index 80bfc8b..7c2c66d 100644 --- a/sys/dev/etherswitch/ip17x/ip17x_vlans.c +++ b/sys/dev/etherswitch/ip17x/ip17x_vlans.c @@ -74,7 +74,7 @@ ip17x_reset_vlans(struct ip17x_softc *sc, uint32_t vlan_mode) if (((1 << phy) & sc->phymask) == 0) continue; v = &sc->vlan[i]; - v->vlanid = i++; + v->vlanid = i++ | ETHERSWITCH_VID_VALID; v->ports = (1 << sc->cpuport); for (j = 0; j < MII_NPHY; j++) { if (((1 << j) & sc->phymask) == 0) @@ -90,10 +90,10 @@ ip17x_reset_vlans(struct ip17x_softc *sc, uint32_t vlan_mode) * members of vlan 1. */ v = &sc->vlan[0]; - v->vlanid = 1; - /* Set PVID for everyone. */ + v->vlanid = 1 | ETHERSWITCH_VID_VALID; + /* Set PVID to 1 for everyone. */ for (i = 0; i < sc->numports; i++) - sc->pvid[i] = v->vlanid; + sc->pvid[i] = 1; for (i = 0; i < MII_NPHY; i++) { if ((sc->phymask & (1 << i)) == 0) continue; @@ -148,11 +148,29 @@ ip17x_setvgroup(device_t dev, etherswitch_vlangroup_t *vg) return (EINVAL); /* IP175C don't support VLAN IDs > 15. */ - if (IP17X_IS_SWITCH(sc, IP175C) && vg->es_vid > IP175C_LAST_VLAN) + if (IP17X_IS_SWITCH(sc, IP175C) && + (vg->es_vid & ETHERSWITCH_VID_MASK) > IP175C_LAST_VLAN) return (EINVAL); /* Vlan ID. */ - sc->vlan[vg->es_vlangroup].vlanid = vg->es_vid; + if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) { + for (i = 0; i < sc->info.es_nvlangroups; i++) { + /* Is this Vlan ID already set in another vlangroup ? */ + if (i != vg->es_vlangroup && + sc->vlan[i].vlanid & ETHERSWITCH_VID_VALID && + (sc->vlan[i].vlanid & ETHERSWITCH_VID_MASK) == + (vg->es_vid & ETHERSWITCH_VID_MASK)) + return (EINVAL); + } + sc->vlan[vg->es_vlangroup].vlanid = vg->es_vid & + ETHERSWITCH_VID_MASK; + /* Setting the vlanid to zero disables the vlangroup. */ + if (sc->vlan[vg->es_vlangroup].vlanid == 0) { + sc->vlan[vg->es_vlangroup].ports = 0; + return (sc->hal.ip17x_hw_setup(sc)); + } + sc->vlan[vg->es_vlangroup].vlanid |= ETHERSWITCH_VID_VALID; + } /* Member Ports. */ sc->vlan[vg->es_vlangroup].ports = 0; diff --git a/sys/dev/etherswitch/rtl8366/rtl8366rb.c b/sys/dev/etherswitch/rtl8366/rtl8366rb.c index d4b1ee96..1bc88a6 100644 --- a/sys/dev/etherswitch/rtl8366/rtl8366rb.c +++ b/sys/dev/etherswitch/rtl8366/rtl8366rb.c @@ -619,7 +619,7 @@ rtl_getvgroup(device_t dev, etherswitch_vlangroup_t *vg) for (i=0; i<3; i++) vmcr[i] = rtl_readreg(dev, RTL8366RB_VMCR(i, vg->es_vlangroup)); - vg->es_vid = RTL8366RB_VMCR_VID(vmcr); + vg->es_vid = RTL8366RB_VMCR_VID(vmcr) | ETHERSWITCH_VID_VALID; vg->es_member_ports = RTL8366RB_VMCR_MEMBER(vmcr); vg->es_untagged_ports = RTL8366RB_VMCR_UNTAG(vmcr); vg->es_fid = RTL8366RB_VMCR_FID(vmcr); |