svn commit: r249752 - in head: sbin/etherswitchcfg sys/dev/etherswitch sys/dev/etherswitch/rtl8366

Adrian Chadd adrian at FreeBSD.org
Mon Apr 22 05:52:20 UTC 2013


Author: adrian
Date: Mon Apr 22 05:52:18 2013
New Revision: 249752
URL: http://svnweb.freebsd.org/changeset/base/249752

Log:
  Convert over the etherswitch framework to use VLAN IDs per port, rather
  than VLAN groups.
  
  Some chips (eg this rtl8366rb) has a VLAN group per port - you first
  define a set of VLANs in a vlan group, then you assign a VLAN group
  to a port.
  
  Other chips (eg the AR8xxx switch chips) have a VLAN ID array per
  port - there's no group per se, just a list of vlans that can be
  configured.
  
  So for now, the switch API will use the latter and rely on drivers
  doing the heavy lifting if one wishes to use the VLAN group method.
  Maybe later on both can be supported.
  
  PR:		kern/177878
  PR:		kern/177873
  Submitted by:	Luiz Otavio O Souza <loos.br at gmail.com>
  Reviewed by:	ray

Modified:
  head/sbin/etherswitchcfg/etherswitchcfg.8
  head/sbin/etherswitchcfg/etherswitchcfg.c
  head/sys/dev/etherswitch/etherswitch.h
  head/sys/dev/etherswitch/rtl8366/rtl8366rb.c

Modified: head/sbin/etherswitchcfg/etherswitchcfg.8
==============================================================================
--- head/sbin/etherswitchcfg/etherswitchcfg.8	Mon Apr 22 05:52:06 2013	(r249751)
+++ head/sbin/etherswitchcfg/etherswitchcfg.8	Mon Apr 22 05:52:18 2013	(r249752)
@@ -62,9 +62,9 @@ To set the register value, use the form 
 .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 a
 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

Modified: head/sbin/etherswitchcfg/etherswitchcfg.c
==============================================================================
--- head/sbin/etherswitchcfg/etherswitchcfg.c	Mon Apr 22 05:52:06 2013	(r249751)
+++ head/sbin/etherswitchcfg/etherswitchcfg.c	Mon Apr 22 05:52:18 2013	(r249752)
@@ -131,19 +131,20 @@ write_phyregister(struct cfg *cfg, int p
 }
 
 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 },

Modified: head/sys/dev/etherswitch/etherswitch.h
==============================================================================
--- head/sys/dev/etherswitch/etherswitch.h	Mon Apr 22 05:52:06 2013	(r249751)
+++ head/sys/dev/etherswitch/etherswitch.h	Mon Apr 22 05:52:18 2013	(r249752)
@@ -36,7 +36,7 @@ typedef struct etherswitch_info etherswi
 
 struct etherswitch_port {
 	int		es_port;
-	int		es_vlangroup;
+	int		es_pvid;
 	union {
 		struct ifreq		es_uifr;
 		struct ifmediareq	es_uifmr;

Modified: head/sys/dev/etherswitch/rtl8366/rtl8366rb.c
==============================================================================
--- head/sys/dev/etherswitch/rtl8366/rtl8366rb.c	Mon Apr 22 05:52:06 2013	(r249751)
+++ head/sys/dev/etherswitch/rtl8366/rtl8366rb.c	Mon Apr 22 05:52:18 2013	(r249752)
@@ -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_po
 	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_po
 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_
 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),


More information about the svn-src-all mailing list