diff options
-rw-r--r-- | sbin/etherswitchcfg/etherswitchcfg.8 | 8 | ||||
-rw-r--r-- | sbin/etherswitchcfg/etherswitchcfg.c | 13 | ||||
-rw-r--r-- | sys/dev/etherswitch/etherswitch.h | 2 | ||||
-rw-r--r-- | sys/dev/etherswitch/rtl8366/rtl8366rb.c | 30 |
4 files changed, 34 insertions, 19 deletions
diff --git a/sbin/etherswitchcfg/etherswitchcfg.8 b/sbin/etherswitchcfg/etherswitchcfg.8 index 4f3bc92..88e06f7 100644 --- a/sbin/etherswitchcfg/etherswitchcfg.8 +++ b/sbin/etherswitchcfg/etherswitchcfg.8 @@ -62,9 +62,9 @@ To set the register value, use the form instance.register=value. .Ss port The port command selects one of the ports of the switch. It supports the following commands: -.Bl -tag -width ".Ar vlangroup number" -compact -.It Ar vlangroup number -Sets the VLAN group number that is used to process incoming frames that are not tagged. +.Bl -tag -width ".Ar pvid number" -compact +.It Ar pvid number +Sets the default port VID that is used to process incoming frames that are not tagged. .It Ar media mediaspec Specifies the physical media configuration to be configured for a port. .It Ar mediaopt mediaoption @@ -104,7 +104,7 @@ Configure VLAN group 1 with a VID of 2 and makes ports 0 and 5 members, while excluding all other ports. Port 5 will send and receive tagged frames, while port 0 will be untagged. Incoming untagged frames on port 0 are assigned to vlangroup1. -.Dl # etherswitchcfg vlangroup1 vlan 2 members 0,5t port0 vlangroup 1 +.Dl # etherswitchcfg vlangroup1 vlan 2 members 0,5t port0 pvid 2 .Sh SEE ALSO .Xr etherswitch 4 .Sh HISTORY diff --git a/sbin/etherswitchcfg/etherswitchcfg.c b/sbin/etherswitchcfg/etherswitchcfg.c index a3f286e..3e0b451 100644 --- a/sbin/etherswitchcfg/etherswitchcfg.c +++ b/sbin/etherswitchcfg/etherswitchcfg.c @@ -131,19 +131,20 @@ write_phyregister(struct cfg *cfg, int phy, int reg, int val) } static void -set_port_vlangroup(struct cfg *cfg, char *argv[]) +set_port_vid(struct cfg *cfg, char *argv[]) { int v; etherswitch_port_t p; v = strtol(argv[1], NULL, 0); - if (v < 0 || v >= cfg->info.es_nvlangroups) - errx(EX_USAGE, "vlangroup must be between 0 and %d", cfg->info.es_nvlangroups-1); + if (v < 0 || v > IEEE802DOT1Q_VID_MAX) + errx(EX_USAGE, "pvid must be between 0 and %d", + IEEE802DOT1Q_VID_MAX); bzero(&p, sizeof(p)); p.es_port = cfg->unit; if (ioctl(cfg->fd, IOETHERSWITCHGETPORT, &p) != 0) err(EX_OSERR, "ioctl(IOETHERSWITCHGETPORT)"); - p.es_vlangroup = v; + p.es_pvid = v; if (ioctl(cfg->fd, IOETHERSWITCHSETPORT, &p) != 0) err(EX_OSERR, "ioctl(IOETHERSWITCHSETPORT)"); } @@ -302,7 +303,7 @@ print_port(struct cfg *cfg, int port) if (ioctl(cfg->fd, IOETHERSWITCHGETPORT, &p) != 0) err(EX_OSERR, "ioctl(IOETHERSWITCHGETPORT)"); printf("port%d:\n", port); - printf("\tvlangroup: %d\n", p.es_vlangroup); + printf("\tpvid: %d\n", p.es_pvid); printf("\tmedia: "); print_media_word(p.es_ifmr.ifm_current, 1); if (p.es_ifmr.ifm_active != p.es_ifmr.ifm_current) { @@ -506,7 +507,7 @@ main(int argc, char *argv[]) } static struct cmds cmds[] = { - { MODE_PORT, "vlangroup", 1, set_port_vlangroup }, + { MODE_PORT, "pvid", 1, set_port_vid }, { MODE_PORT, "media", 1, set_port_media }, { MODE_PORT, "mediaopt", 1, set_port_mediaopt }, { MODE_VLANGROUP, "vlan", 1, set_vlangroup_vid }, diff --git a/sys/dev/etherswitch/etherswitch.h b/sys/dev/etherswitch/etherswitch.h index 8b02f69..b570039 100644 --- a/sys/dev/etherswitch/etherswitch.h +++ b/sys/dev/etherswitch/etherswitch.h @@ -36,7 +36,7 @@ typedef struct etherswitch_info etherswitch_info_t; struct etherswitch_port { int es_port; - int es_vlangroup; + int es_pvid; union { struct ifreq es_uifr; struct ifmediareq es_uifmr; diff --git a/sys/dev/etherswitch/rtl8366/rtl8366rb.c b/sys/dev/etherswitch/rtl8366/rtl8366rb.c index 9b64851..d4b1ee96 100644 --- a/sys/dev/etherswitch/rtl8366/rtl8366rb.c +++ b/sys/dev/etherswitch/rtl8366/rtl8366rb.c @@ -63,6 +63,7 @@ struct rtl8366rb_softc { int smi_acquired; /* serialize access to SMI/I2C bus */ struct mtx callout_mtx; /* serialize callout */ device_t dev; + int vid[RTL8366RB_NUM_VLANS]; char *ifname[RTL8366RB_NUM_PHYS]; device_t miibus[RTL8366RB_NUM_PHYS]; struct ifnet *ifp[RTL8366RB_NUM_PHYS]; @@ -70,8 +71,8 @@ struct rtl8366rb_softc { }; static etherswitch_info_t etherswitch_info = { - .es_nports = 6, - .es_nvlangroups = 16, + .es_nports = RTL8366RB_NUM_PORTS, + .es_nvlangroups = RTL8366RB_NUM_VLANS, .es_name = "Realtek RTL8366RB" }; @@ -550,15 +551,16 @@ rtl_getport(device_t dev, etherswitch_port_t *p) struct mii_data *mii; struct ifmediareq *ifmr = &p->es_ifmr; uint16_t v; - int err; + int err, vlangroup; if (p->es_port < 0 || p->es_port >= RTL8366RB_NUM_PORTS) return (ENXIO); - p->es_vlangroup = RTL8366RB_PVCR_GET(p->es_port, + sc = device_get_softc(dev); + vlangroup = RTL8366RB_PVCR_GET(p->es_port, rtl_readreg(dev, RTL8366RB_PVCR_REG(p->es_port))); + p->es_pvid = sc->vid[vlangroup]; if (p->es_port < RTL8366RB_NUM_PHYS) { - sc = device_get_softc(dev); mii = device_get_softc(sc->miibus[p->es_port]); ifm = &mii->mii_media; err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCGIFMEDIA); @@ -580,19 +582,28 @@ rtl_getport(device_t dev, etherswitch_port_t *p) static int rtl_setport(device_t dev, etherswitch_port_t *p) { - int err; + int i, err, vlangroup; struct rtl8366rb_softc *sc; struct ifmedia *ifm; struct mii_data *mii; if (p->es_port < 0 || p->es_port >= RTL8366RB_NUM_PHYS) return (ENXIO); + sc = device_get_softc(dev); + vlangroup = -1; + for (i = 0; i < RTL8366RB_NUM_VLANS; i++) { + if (sc->vid[i] == p->es_pvid) { + vlangroup = i; + break; + } + } + if (vlangroup == -1) + return (ENXIO); err = smi_rmw(dev, RTL8366RB_PVCR_REG(p->es_port), RTL8366RB_PVCR_VAL(p->es_port, RTL8366RB_PVCR_PORT_MASK), - RTL8366RB_PVCR_VAL(p->es_port, p->es_vlangroup), RTL_WAITOK); + RTL8366RB_PVCR_VAL(p->es_port, vlangroup), RTL_WAITOK); if (err) return (err); - sc = device_get_softc(dev); mii = device_get_softc(sc->miibus[p->es_port]); ifm = &mii->mii_media; err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCSIFMEDIA); @@ -618,8 +629,11 @@ rtl_getvgroup(device_t dev, etherswitch_vlangroup_t *vg) static int rtl_setvgroup(device_t dev, etherswitch_vlangroup_t *vg) { + struct rtl8366rb_softc *sc; int g = vg->es_vlangroup; + sc = device_get_softc(dev); + sc->vid[g] = vg->es_vid; rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_DOT1Q_REG, g), (vg->es_vid << RTL8366RB_VMCR_DOT1Q_VID_SHIFT) & RTL8366RB_VMCR_DOT1Q_VID_MASK); rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_MU_REG, g), |