Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Nov 2016 21:58:04 +0000 (UTC)
From:      Michael Zhilin <mizhka@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r308700 - in head/sys: conf dev/etherswitch/rtl8366
Message-ID:  <201611152158.uAFLw46E078286@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mizhka
Date: Tue Nov 15 21:58:04 2016
New Revision: 308700
URL: https://svnweb.freebsd.org/changeset/base/308700

Log:
  [etherswitch] add RTL8366SR support
  
  Add RTL8366SR support at etherswitch driver. Tested on RTL8366RB and
  RTL8366SR.
  
  Submitted by:	Hiroki Mori <yamori813@yahoo.co.jp>
  Reviewed by:	adrian, mizhka
  Approved by:	adrian(mentor)
  Differential Revision:	https://reviews.freebsd.org/D6796

Modified:
  head/sys/conf/options
  head/sys/dev/etherswitch/rtl8366/rtl8366rb.c
  head/sys/dev/etherswitch/rtl8366/rtl8366rbvar.h

Modified: head/sys/conf/options
==============================================================================
--- head/sys/conf/options	Tue Nov 15 21:49:01 2016	(r308699)
+++ head/sys/conf/options	Tue Nov 15 21:58:04 2016	(r308700)
@@ -993,6 +993,9 @@ BHND_LOGLEVEL	opt_global.h
 # GPIO and child devices
 GPIO_SPI_DEBUG	opt_gpio.h
 
+# etherswitch(4) driver
+RTL8366_SOFT_RESET opt_etherswitch.h
+
 # evdev protocol support
 EVDEV_SUPPORT	opt_evdev.h
 EVDEV_DEBUG	opt_evdev.h

Modified: head/sys/dev/etherswitch/rtl8366/rtl8366rb.c
==============================================================================
--- head/sys/dev/etherswitch/rtl8366/rtl8366rb.c	Tue Nov 15 21:49:01 2016	(r308699)
+++ head/sys/dev/etherswitch/rtl8366/rtl8366rb.c	Tue Nov 15 21:58:04 2016	(r308700)
@@ -1,4 +1,5 @@
 /*-
+ * Copyright (c) 2015-2016 Hiroki Mori.
  * Copyright (c) 2011-2012 Stefan Bethke.
  * All rights reserved.
  *
@@ -26,6 +27,8 @@
  * $FreeBSD$
  */
 
+#include "opt_etherswitch.h"
+
 #include <sys/param.h>
 #include <sys/bus.h>
 #include <sys/errno.h>
@@ -65,18 +68,13 @@ 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];
+	int		vid[RTL8366_NUM_VLANS];
+	char		*ifname[RTL8366_NUM_PHYS];
+	device_t	miibus[RTL8366_NUM_PHYS];
+	struct ifnet	*ifp[RTL8366_NUM_PHYS];
 	struct callout	callout_tick;
-};
-
-static etherswitch_info_t etherswitch_info = {
-	.es_nports =		RTL8366RB_NUM_PORTS,
-	.es_nvlangroups =	RTL8366RB_NUM_VLANS,
-	.es_name =		"Realtek RTL8366RB",
-	.es_vlan_caps =		ETHERSWITCH_VLAN_DOT1Q,
+	etherswitch_info_t	info;
+	int		chip_type;	/* 0 = RTL8366RB, 1 = RTL8366SR */
 };
 
 #define RTL_LOCK(_sc)	mtx_lock(&(_sc)->sc_mtx)
@@ -133,77 +131,101 @@ rtl8366rb_identify(driver_t *driver, dev
 	if (device_find_child(parent, "rtl8366rb", -1) == NULL) {
 		child = BUS_ADD_CHILD(parent, 0, "rtl8366rb", -1);
 		devi = IICBUS_IVAR(child);
-		devi->addr = RTL8366RB_IIC_ADDR;
+		devi->addr = RTL8366_IIC_ADDR;
 	}
 }
 
 static int
 rtl8366rb_probe(device_t dev)
 {
+	struct rtl8366rb_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	bzero(sc, sizeof(*sc));
 	if (smi_probe(dev) != 0)
 		return (ENXIO);
-	device_set_desc(dev, "RTL8366RB Ethernet Switch Controller");
+	if(sc->chip_type == 0)
+		device_set_desc(dev, "RTL8366RB Ethernet Switch Controller");
+	else
+		device_set_desc(dev, "RTL8366SR Ethernet Switch Controller");
 	return (BUS_PROBE_DEFAULT);
 }
 
 static void
 rtl8366rb_init(device_t dev)
 {
-	int i;
 	struct rtl8366rb_softc *sc;
+	int i;
+
+	sc = device_get_softc(dev);
 
 	/* Initialisation for TL-WR1043ND */
-	smi_rmw(dev, RTL8366RB_RCR,
-		RTL8366RB_RCR_HARD_RESET,
-		RTL8366RB_RCR_HARD_RESET, RTL_WAITOK);
+#ifdef RTL8366_SOFT_RESET
+	smi_rmw(dev, RTL8366_RCR,
+		RTL8366_RCR_SOFT_RESET,
+		RTL8366_RCR_SOFT_RESET, RTL_WAITOK);
+#else
+	smi_rmw(dev, RTL8366_RCR,
+		RTL8366_RCR_HARD_RESET,
+		RTL8366_RCR_HARD_RESET, RTL_WAITOK);
+#endif
+	/* hard reset not return ack */
 	DELAY(100000);
 	/* Enable 16 VLAN mode */
-	smi_rmw(dev, RTL8366RB_SGCR,
-		RTL8366RB_SGCR_EN_VLAN | RTL8366RB_SGCR_EN_VLAN_4KTB,
-		RTL8366RB_SGCR_EN_VLAN, RTL_WAITOK);
+	smi_rmw(dev, RTL8366_SGCR,
+		RTL8366_SGCR_EN_VLAN | RTL8366_SGCR_EN_VLAN_4KTB,
+		RTL8366_SGCR_EN_VLAN, RTL_WAITOK);
 	/* Initialize our vlan table. */
-	sc = device_get_softc(dev);
 	for (i = 0; i <= 1; i++)
 		sc->vid[i] = (i + 1) | ETHERSWITCH_VID_VALID;
 	/* Remove port 0 from VLAN 1. */
-	smi_rmw(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_MU_REG, 0),
+	smi_rmw(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, 0),
 		(1 << 0), 0, RTL_WAITOK);
 	/* Add port 0 untagged and port 5 tagged to VLAN 2. */
-	smi_rmw(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_MU_REG, 1),
-		((1 << 5 | 1 << 0) << RTL8366RB_VMCR_MU_MEMBER_SHIFT)
-			| ((1 << 5 | 1 << 0) << RTL8366RB_VMCR_MU_UNTAG_SHIFT),
-		((1 << 5 | 1 << 0) << RTL8366RB_VMCR_MU_MEMBER_SHIFT
-			| ((1 << 0) << RTL8366RB_VMCR_MU_UNTAG_SHIFT)),
+	smi_rmw(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, 1),
+		((1 << 5 | 1 << 0) << RTL8366_VMCR_MU_MEMBER_SHIFT)
+			| ((1 << 5 | 1 << 0) << RTL8366_VMCR_MU_UNTAG_SHIFT),
+		((1 << 5 | 1 << 0) << RTL8366_VMCR_MU_MEMBER_SHIFT
+			| ((1 << 0) << RTL8366_VMCR_MU_UNTAG_SHIFT)),
 		RTL_WAITOK);
 	/* Set PVID 2 for port 0. */
-	smi_rmw(dev, RTL8366RB_PVCR_REG(0),
-		RTL8366RB_PVCR_VAL(0, RTL8366RB_PVCR_PORT_MASK),
-		RTL8366RB_PVCR_VAL(0, 1), RTL_WAITOK);
+	smi_rmw(dev, RTL8366_PVCR_REG(0),
+		RTL8366_PVCR_VAL(0, RTL8366_PVCR_PORT_MASK),
+		RTL8366_PVCR_VAL(0, 1), RTL_WAITOK);
 }
 
 static int
 rtl8366rb_attach(device_t dev)
 {
-	uint16_t rev = 0;
 	struct rtl8366rb_softc *sc;
+	uint16_t rev = 0;
 	char name[IFNAMSIZ];
 	int err = 0;
 	int i;
 
 	sc = device_get_softc(dev);
-	bzero(sc, sizeof(*sc));
+
 	sc->dev = dev;
 	mtx_init(&sc->sc_mtx, "rtl8366rb", NULL, MTX_DEF);
 	sc->smi_acquired = 0;
 	mtx_init(&sc->callout_mtx, "rtl8366rbcallout", NULL, MTX_DEF);
 
 	rtl8366rb_init(dev);
-	smi_read(dev, RTL8366RB_CVCR, &rev, RTL_WAITOK);
+	smi_read(dev, RTL8366_CVCR, &rev, RTL_WAITOK);
 	device_printf(dev, "rev. %d\n", rev & 0x000f);
 
+	sc->info.es_nports = RTL8366_NUM_PORTS;
+	sc->info.es_nvlangroups = RTL8366_NUM_VLANS;
+	sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q;
+	if(sc->chip_type == 0)
+		sprintf(sc->info.es_name, "Realtek RTL8366RB");
+	else
+		sprintf(sc->info.es_name, "Realtek RTL8366SR");
+
 	/* attach miibus and phys */
 	/* PHYs need an interface, so we generate a dummy one */
-	for (i = 0; i < RTL8366RB_NUM_PHYS; i++) {
+	for (i = 0; i < RTL8366_NUM_PHYS; i++) {
 		sc->ifp[i] = if_alloc(IFT_ETHER);
 		sc->ifp[i]->if_softc = sc;
 		sc->ifp[i]->if_flags |= IFF_UP | IFF_BROADCAST | IFF_DRV_RUNNING
@@ -236,10 +258,12 @@ rtl8366rb_attach(device_t dev)
 static int
 rtl8366rb_detach(device_t dev)
 {
-	struct rtl8366rb_softc *sc = device_get_softc(dev);
+	struct rtl8366rb_softc *sc;
 	int i;
 
-	for (i=0; i < RTL8366RB_NUM_PHYS; i++) {
+	sc = device_get_softc(dev);
+
+	for (i=0; i < RTL8366_NUM_PHYS; i++) {
 		if (sc->miibus[i])
 			device_delete_child(dev, sc->miibus[i]);
 		if (sc->ifp[i] != NULL)
@@ -259,30 +283,30 @@ rtl8366rb_update_ifmedia(int portstatus,
 {
 	*media_active = IFM_ETHER;
 	*media_status = IFM_AVALID;
-	if ((portstatus & RTL8366RB_PLSR_LINK) != 0)
+	if ((portstatus & RTL8366_PLSR_LINK) != 0)
 		*media_status |= IFM_ACTIVE;
 	else {
 		*media_active |= IFM_NONE;
 		return;
 	}
-	switch (portstatus & RTL8366RB_PLSR_SPEED_MASK) {
-	case RTL8366RB_PLSR_SPEED_10:
+	switch (portstatus & RTL8366_PLSR_SPEED_MASK) {
+	case RTL8366_PLSR_SPEED_10:
 		*media_active |= IFM_10_T;
 		break;
-	case RTL8366RB_PLSR_SPEED_100:
+	case RTL8366_PLSR_SPEED_100:
 		*media_active |= IFM_100_TX;
 		break;
-	case RTL8366RB_PLSR_SPEED_1000:
+	case RTL8366_PLSR_SPEED_1000:
 		*media_active |= IFM_1000_T;
 		break;
 	}
-	if ((portstatus & RTL8366RB_PLSR_FULLDUPLEX) != 0)
+	if ((portstatus & RTL8366_PLSR_FULLDUPLEX) != 0)
 		*media_active |= IFM_FDX;
 	else
 		*media_active |= IFM_HDX;
-	if ((portstatus & RTL8366RB_PLSR_TXPAUSE) != 0)
+	if ((portstatus & RTL8366_PLSR_TXPAUSE) != 0)
 		*media_active |= IFM_ETH_TXPAUSE;
-	if ((portstatus & RTL8366RB_PLSR_RXPAUSE) != 0)
+	if ((portstatus & RTL8366_PLSR_RXPAUSE) != 0)
 		*media_active |= IFM_ETH_RXPAUSE;
 }
 
@@ -295,10 +319,10 @@ rtl833rb_miipollstat(struct rtl8366rb_so
 	uint16_t value;
 	int portstatus;
 
-	for (i = 0; i < RTL8366RB_NUM_PHYS; i++) {
+	for (i = 0; i < RTL8366_NUM_PHYS; i++) {
 		mii = device_get_softc(sc->miibus[i]);
 		if ((i % 2) == 0) {
-			if (smi_read(sc->dev, RTL8366RB_PLSR_BASE + i/2, &value, RTL_NOWAIT) != 0) {
+			if (smi_read(sc->dev, RTL8366_PLSR_BASE + i/2, &value, RTL_NOWAIT) != 0) {
 				DEBUG_INCRVAR(callout_blocked);
 				return;
 			}
@@ -318,7 +342,9 @@ rtl833rb_miipollstat(struct rtl8366rb_so
 static void
 rtl8366rb_tick(void *arg)
 {
-	struct rtl8366rb_softc *sc = arg;
+	struct rtl8366rb_softc *sc;
+
+	sc = arg;
 
 	rtl833rb_miipollstat(sc);
 	callout_reset(&sc->callout_tick, hz, rtl8366rb_tick, sc);
@@ -327,39 +353,65 @@ rtl8366rb_tick(void *arg)
 static int
 smi_probe(device_t dev)
 {
+	struct rtl8366rb_softc *sc;
 	device_t iicbus, iicha;
-	int err, i;
+	int err, i, j;
 	uint16_t chipid;
 	char bytes[2];
 	int xferd;
 
-	bytes[0] = RTL8366RB_CIR & 0xff;
-	bytes[1] = (RTL8366RB_CIR >> 8) & 0xff;
+	sc = device_get_softc(dev);
+
 	iicbus = device_get_parent(dev);
 	iicha = device_get_parent(iicbus);
-	iicbus_reset(iicbus, IIC_FASTEST, RTL8366RB_IIC_ADDR, NULL);
-	for (i=3; i--; ) {
-		IICBUS_STOP(iicha);
-		/*
-		 * we go directly to the host adapter because iicbus.c
-		 * only issues a stop on a bus that was successfully started.
-		 */
+
+	for(i = 0; i < 2; ++i) {
+		iicbus_reset(iicbus, IIC_FASTEST, RTL8366_IIC_ADDR, NULL);
+		for (j=3; j--; ) {
+			IICBUS_STOP(iicha);
+			/*
+			 * we go directly to the host adapter because iicbus.c
+			 * only issues a stop on a bus that was successfully started.
+			 */
+		}
+		err = iicbus_request_bus(iicbus, dev, IIC_WAIT);
+		if (err != 0)
+			goto out;
+		err = iicbus_start(iicbus, RTL8366_IIC_ADDR | RTL_IICBUS_READ, RTL_IICBUS_TIMEOUT);
+		if (err != 0)
+			goto out;
+		if(i == 0) {
+			bytes[0] = RTL8366RB_CIR & 0xff;
+			bytes[1] = (RTL8366RB_CIR >> 8) & 0xff;
+		} else {
+			bytes[0] = RTL8366SR_CIR & 0xff;
+			bytes[1] = (RTL8366SR_CIR >> 8) & 0xff;
+		}
+		err = iicbus_write(iicbus, bytes, 2, &xferd, RTL_IICBUS_TIMEOUT);
+		if (err != 0)
+			goto out;
+		err = iicbus_read(iicbus, bytes, 2, &xferd, IIC_LAST_READ, 0);
+		if (err != 0)
+			goto out;
+		chipid = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
+		if (i == 0 && chipid == RTL8366RB_CIR_ID8366RB) {
+			DPRINTF(dev, "chip id 0x%04x\n", chipid);
+			sc->chip_type = 0;
+			err = 0;
+			break;
+		}
+		if (i == 1 && chipid == RTL8366SR_CIR_ID8366SR) {
+			DPRINTF(dev, "chip id 0x%04x\n", chipid);
+			sc->chip_type = 1;
+			err = 0;
+			break;
+		}
+		if(i == 0) {
+			iicbus_stop(iicbus);
+			iicbus_release_bus(iicbus, dev);
+		}
 	}
-	err = iicbus_request_bus(iicbus, dev, IIC_WAIT);
-	if (err != 0)
-		goto out;
-	err = iicbus_start(iicbus, RTL8366RB_IIC_ADDR | RTL_IICBUS_READ, RTL_IICBUS_TIMEOUT);
-	if (err != 0)
-		goto out;
-	err = iicbus_write(iicbus, bytes, 2, &xferd, RTL_IICBUS_TIMEOUT);
-	if (err != 0)
-		goto out;
-	err = iicbus_read(iicbus, bytes, 2, &xferd, IIC_LAST_READ, 0);
-	if (err != 0)
-		goto out;
-	chipid = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
-	DPRINTF(dev, "chip id 0x%04x\n", chipid);
-	if (chipid != RTL8366RB_CIR_ID8366RB)
+	if(i == 2)
 		err = ENXIO;
 out:
 	iicbus_stop(iicbus);
@@ -406,12 +458,25 @@ smi_release(struct rtl8366rb_softc *sc, 
 static int
 smi_select(device_t dev, int op, int sleep)
 {
+	struct rtl8366rb_softc *sc;
 	int err, i;
-	device_t iicbus = device_get_parent(dev);
-	struct iicbus_ivar *devi = IICBUS_IVAR(dev);
-	int slave = devi->addr;
+	device_t iicbus;
+	struct iicbus_ivar *devi;
+	int slave;
+
+	sc = device_get_softc(dev);
+
+	iicbus = device_get_parent(dev);
+	devi = IICBUS_IVAR(dev);
+	slave = devi->addr;
 
 	RTL_SMI_ACQUIRED_ASSERT((struct rtl8366rb_softc *)device_get_softc(dev));
+
+	if(sc->chip_type == 1) {   // RTL8366SR work around
+		// this is same work around at probe
+		for (int i=3; i--; )
+			IICBUS_STOP(device_get_parent(device_get_parent(dev)));
+	}
 	/*
 	 * The chip does not use clock stretching when it is busy,
 	 * instead ignoring the command. Retry a few times.
@@ -433,10 +498,12 @@ static int
 smi_read_locked(struct rtl8366rb_softc *sc, uint16_t addr, uint16_t *data, int sleep)
 {
 	int err;
-	device_t iicbus = device_get_parent(sc->dev);
+	device_t iicbus;
 	char bytes[2];
 	int xferd;
 
+	iicbus = device_get_parent(sc->dev);
+
 	RTL_SMI_ACQUIRED_ASSERT(sc);
 	bytes[0] = addr & 0xff;
 	bytes[1] = (addr >> 8) & 0xff;
@@ -460,10 +527,12 @@ static int
 smi_write_locked(struct rtl8366rb_softc *sc, uint16_t addr, uint16_t data, int sleep)
 {
 	int err;
-	device_t iicbus = device_get_parent(sc->dev);
+	device_t iicbus;
 	char bytes[4];
 	int xferd;
 
+	iicbus = device_get_parent(sc->dev);
+
 	RTL_SMI_ACQUIRED_ASSERT(sc);
 	bytes[0] = addr & 0xff;
 	bytes[1] = (addr >> 8) & 0xff;
@@ -481,9 +550,11 @@ smi_write_locked(struct rtl8366rb_softc 
 static int
 smi_read(device_t dev, uint16_t addr, uint16_t *data, int sleep)
 {
-	struct rtl8366rb_softc *sc = device_get_softc(dev);
+	struct rtl8366rb_softc *sc;
 	int err;
 
+	sc = device_get_softc(dev);
+
 	err = smi_acquire(sc, sleep);
 	if (err != 0)
 		return (EBUSY);
@@ -496,9 +567,11 @@ smi_read(device_t dev, uint16_t addr, ui
 static int
 smi_write(device_t dev, uint16_t addr, uint16_t data, int sleep)
 {
-	struct rtl8366rb_softc *sc = device_get_softc(dev);
+	struct rtl8366rb_softc *sc;
 	int err;
 	
+	sc = device_get_softc(dev);
+
 	err = smi_acquire(sc, sleep);
 	if (err != 0)
 		return (EBUSY);
@@ -511,10 +584,12 @@ smi_write(device_t dev, uint16_t addr, u
 static int
 smi_rmw(device_t dev, uint16_t addr, uint16_t mask, uint16_t data, int sleep)
 {
-	struct rtl8366rb_softc *sc = device_get_softc(dev);
+	struct rtl8366rb_softc *sc;
 	int err;
 	uint16_t oldv, newv;
 	
+	sc = device_get_softc(dev);
+
 	err = smi_acquire(sc, sleep);
 	if (err != 0)
 		return (EBUSY);
@@ -535,13 +610,19 @@ smi_rmw(device_t dev, uint16_t addr, uin
 static etherswitch_info_t *
 rtl_getinfo(device_t dev)
 {
-	return (&etherswitch_info);
+	struct rtl8366rb_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	return (&sc->info);
 }
 
 static int
 rtl_readreg(device_t dev, int reg)
 {
-	uint16_t data = 0;
+	uint16_t data;
+
+	data = 0;
 
 	smi_read(dev, reg, &data, RTL_WAITOK);
 	return (data);
@@ -559,18 +640,21 @@ rtl_getport(device_t dev, etherswitch_po
 	struct rtl8366rb_softc *sc;
 	struct ifmedia *ifm;
 	struct mii_data *mii;
-	struct ifmediareq *ifmr = &p->es_ifmr;
+	struct ifmediareq *ifmr;
 	uint16_t v;
 	int err, vlangroup;
 	
-	if (p->es_port < 0 || p->es_port >= RTL8366RB_NUM_PORTS)
-		return (ENXIO);
 	sc = device_get_softc(dev);
-	vlangroup = RTL8366RB_PVCR_GET(p->es_port,
-		rtl_readreg(dev, RTL8366RB_PVCR_REG(p->es_port)));
+
+	ifmr = &p->es_ifmr;
+
+	if (p->es_port < 0 || p->es_port >= RTL8366_NUM_PORTS)
+		return (ENXIO);
+	vlangroup = RTL8366_PVCR_GET(p->es_port,
+		rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port)));
 	p->es_pvid = sc->vid[vlangroup] & ETHERSWITCH_VID_MASK;
 	
-	if (p->es_port < RTL8366RB_NUM_PHYS) {
+	if (p->es_port < RTL8366_NUM_PHYS) {
 		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);
@@ -579,8 +663,8 @@ rtl_getport(device_t dev, etherswitch_po
 	} else {
 		/* fill in fixed values for CPU port */
 		p->es_flags |= ETHERSWITCH_PORT_CPU;
-		smi_read(dev, RTL8366RB_PLSR_BASE + (RTL8366RB_NUM_PHYS)/2, &v, RTL_WAITOK);
-		v = v >> (8 * ((RTL8366RB_NUM_PHYS) % 2));
+		smi_read(dev, RTL8366_PLSR_BASE + (RTL8366_NUM_PHYS)/2, &v, RTL_WAITOK);
+		v = v >> (8 * ((RTL8366_NUM_PHYS) % 2));
 		rtl8366rb_update_ifmedia(v, &ifmr->ifm_status, &ifmr->ifm_active);
 		ifmr->ifm_current = ifmr->ifm_active;
 		ifmr->ifm_mask = 0;
@@ -599,16 +683,17 @@ rtl_getport(device_t dev, etherswitch_po
 static int
 rtl_setport(device_t dev, etherswitch_port_t *p)
 {
-	int i, err, vlangroup;
 	struct rtl8366rb_softc *sc;
+	int i, err, vlangroup;
 	struct ifmedia *ifm;
 	struct mii_data *mii;
 
-	if (p->es_port < 0 || p->es_port >= RTL8366RB_NUM_PORTS)
-		return (ENXIO);
 	sc = device_get_softc(dev);
+
+	if (p->es_port < 0 || p->es_port >= RTL8366_NUM_PORTS)
+		return (ENXIO);
 	vlangroup = -1;
-	for (i = 0; i < RTL8366RB_NUM_VLANS; i++) {
+	for (i = 0; i < RTL8366_NUM_VLANS; i++) {
 		if ((sc->vid[i] & ETHERSWITCH_VID_MASK) == p->es_pvid) {
 			vlangroup = i;
 			break;
@@ -616,12 +701,12 @@ rtl_setport(device_t dev, etherswitch_po
 	}
 	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, vlangroup), RTL_WAITOK);
+	err = smi_rmw(dev, RTL8366_PVCR_REG(p->es_port),
+		RTL8366_PVCR_VAL(p->es_port, RTL8366_PVCR_PORT_MASK),
+		RTL8366_PVCR_VAL(p->es_port, vlangroup), RTL_WAITOK);
 	if (err)
 		return (err);
-	if (p->es_port == RTL8366RB_CPU_PORT)
+	if (p->es_port == RTL8366_CPU_PORT)
 		return (0);
 	mii = device_get_softc(sc->miibus[p->es_port]);
 	ifm = &mii->mii_media;
@@ -636,14 +721,15 @@ rtl_getvgroup(device_t dev, etherswitch_
 	uint16_t vmcr[3];
 	int i;
 	
-	for (i=0; i<3; i++)
-		vmcr[i] = rtl_readreg(dev, RTL8366RB_VMCR(i, vg->es_vlangroup));
-		
 	sc = device_get_softc(dev);
+
+	for (i=0; i<RTL8366_VMCR_MULT; i++)
+		vmcr[i] = rtl_readreg(dev, RTL8366_VMCR(i, vg->es_vlangroup));
+		
 	vg->es_vid = sc->vid[vg->es_vlangroup];
-	vg->es_member_ports = RTL8366RB_VMCR_MEMBER(vmcr);
-	vg->es_untagged_ports = RTL8366RB_VMCR_UNTAG(vmcr);
-	vg->es_fid = RTL8366RB_VMCR_FID(vmcr);
+	vg->es_member_ports = RTL8366_VMCR_MEMBER(vmcr);
+	vg->es_untagged_ports = RTL8366_VMCR_UNTAG(vmcr);
+	vg->es_fid = RTL8366_VMCR_FID(vmcr);
 	return (0);
 }
 
@@ -651,21 +737,31 @@ static int
 rtl_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
 {
 	struct rtl8366rb_softc *sc;
-	int g = vg->es_vlangroup;
+	int g;
 
 	sc = device_get_softc(dev);
+
+	g = vg->es_vlangroup;
+
 	sc->vid[g] = vg->es_vid;
 	/* VLAN group disabled ? */
 	if (vg->es_member_ports == 0 && vg->es_untagged_ports == 0 && vg->es_vid == 0)
 		return (0);
 	sc->vid[g] |= ETHERSWITCH_VID_VALID;
-	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),
-		((vg->es_member_ports << RTL8366RB_VMCR_MU_MEMBER_SHIFT) & RTL8366RB_VMCR_MU_MEMBER_MASK) |
-		((vg->es_untagged_ports << RTL8366RB_VMCR_MU_UNTAG_SHIFT) & RTL8366RB_VMCR_MU_UNTAG_MASK));
-	rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_FID_REG, g),
-		vg->es_fid);
+	rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_DOT1Q_REG, g),
+		(vg->es_vid << RTL8366_VMCR_DOT1Q_VID_SHIFT) & RTL8366_VMCR_DOT1Q_VID_MASK);
+	if(sc->chip_type == 0) {
+		rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, g),
+	 	    ((vg->es_member_ports << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
+		    ((vg->es_untagged_ports << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK));
+		rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_FID_REG, g),
+		    vg->es_fid);
+	} else {
+		rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, g),
+		    ((vg->es_member_ports << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
+		    ((vg->es_untagged_ports << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK) |
+		    ((vg->es_fid << RTL8366_VMCR_FID_FID_SHIFT) & RTL8366_VMCR_FID_FID_MASK));
+	}
 	return (0);
 }
 
@@ -683,24 +779,28 @@ rtl_getconf(device_t dev, etherswitch_co
 static int
 rtl_readphy(device_t dev, int phy, int reg)
 {
-	struct rtl8366rb_softc *sc = device_get_softc(dev);
-	uint16_t data = 0;
+	struct rtl8366rb_softc *sc;
+	uint16_t data;
 	int err, i, sleep;
 
-	if (phy < 0 || phy >= RTL8366RB_NUM_PHYS)
+	sc = device_get_softc(dev);
+
+	data = 0;
+
+	if (phy < 0 || phy >= RTL8366_NUM_PHYS)
 		return (ENXIO);
-	if (reg < 0 || reg >= RTL8366RB_NUM_PHY_REG)
+	if (reg < 0 || reg >= RTL8366_NUM_PHY_REG)
 		return (ENXIO);
 	sleep = RTL_WAITOK;
 	err = smi_acquire(sc, sleep);
 	if (err != 0)
 		return (EBUSY);
 	for (i = RTL_IICBUS_RETRIES; i--; ) {
-		err = smi_write_locked(sc, RTL8366RB_PACR, RTL8366RB_PACR_READ, sleep);
+		err = smi_write_locked(sc, RTL8366_PACR, RTL8366_PACR_READ, sleep);
 		if (err == 0)
-			err = smi_write_locked(sc, RTL8366RB_PHYREG(phy, 0, reg), 0, sleep);
+			err = smi_write_locked(sc, RTL8366_PHYREG(phy, 0, reg), 0, sleep);
 		if (err == 0) {
-			err = smi_read_locked(sc, RTL8366RB_PADR, &data, sleep);
+			err = smi_read_locked(sc, RTL8366_PADR, &data, sleep);
 			break;
 		}
 		DEBUG_INCRVAR(phy_access_retries);
@@ -715,21 +815,23 @@ rtl_readphy(device_t dev, int phy, int r
 static int
 rtl_writephy(device_t dev, int phy, int reg, int data)
 {
-	struct rtl8366rb_softc *sc = device_get_softc(dev);
+	struct rtl8366rb_softc *sc;
 	int err, i, sleep;
 	
-	if (phy < 0 || phy >= RTL8366RB_NUM_PHYS)
+	sc = device_get_softc(dev);
+
+	if (phy < 0 || phy >= RTL8366_NUM_PHYS)
 		return (ENXIO);
-	if (reg < 0 || reg >= RTL8366RB_NUM_PHY_REG)
+	if (reg < 0 || reg >= RTL8366_NUM_PHY_REG)
 		return (ENXIO);
 	sleep = RTL_WAITOK;
 	err = smi_acquire(sc, sleep);
 	if (err != 0)
 		return (EBUSY);
 	for (i = RTL_IICBUS_RETRIES; i--; ) {
-		err = smi_write_locked(sc, RTL8366RB_PACR, RTL8366RB_PACR_WRITE, sleep);
+		err = smi_write_locked(sc, RTL8366_PACR, RTL8366_PACR_WRITE, sleep);
 		if (err == 0)
-			err = smi_write_locked(sc, RTL8366RB_PHYREG(phy, 0, reg), data, sleep);
+			err = smi_write_locked(sc, RTL8366_PHYREG(phy, 0, reg), data, sleep);
 		if (err == 0) {
 			break;
 		}
@@ -745,8 +847,11 @@ rtl_writephy(device_t dev, int phy, int 
 static int
 rtl8366rb_ifmedia_upd(struct ifnet *ifp)
 {
-	struct rtl8366rb_softc *sc = ifp->if_softc;
-	struct mii_data *mii = device_get_softc(sc->miibus[ifp->if_dunit]);
+	struct rtl8366rb_softc *sc;
+	struct mii_data *mii;
+	
+	sc = ifp->if_softc;
+	mii = device_get_softc(sc->miibus[ifp->if_dunit]);
 	
 	mii_mediachg(mii);
 	return (0);
@@ -755,8 +860,11 @@ rtl8366rb_ifmedia_upd(struct ifnet *ifp)
 static void
 rtl8366rb_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 {
-	struct rtl8366rb_softc *sc = ifp->if_softc;
-	struct mii_data *mii = device_get_softc(sc->miibus[ifp->if_dunit]);
+	struct rtl8366rb_softc *sc;
+	struct mii_data *mii;
+
+	sc = ifp->if_softc;
+	mii = device_get_softc(sc->miibus[ifp->if_dunit]);
 
 	mii_pollstat(mii);
 	ifmr->ifm_active = mii->mii_media_active;

Modified: head/sys/dev/etherswitch/rtl8366/rtl8366rbvar.h
==============================================================================
--- head/sys/dev/etherswitch/rtl8366/rtl8366rbvar.h	Tue Nov 15 21:49:01 2016	(r308699)
+++ head/sys/dev/etherswitch/rtl8366/rtl8366rbvar.h	Tue Nov 15 21:58:04 2016	(r308700)
@@ -1,4 +1,5 @@
 /*-
+ * Copyright (c) 2015-2016 Hiroki Mori.
  * Copyright (c) 2011-2012 Stefan Bethke.
  * All rights reserved.
  *
@@ -29,7 +30,7 @@
 #ifndef _DEV_ETHERSWITCH_RTL8366RBVAR_H_
 #define	_DEV_ETHERSWITCH_RTL8366RBVAR_H_
 
-#define RTL8366RB_IIC_ADDR	0xa8
+#define RTL8366_IIC_ADDR	0xa8
 #define RTL_IICBUS_TIMEOUT	100	/* us */
 #define RTL_IICBUS_READ		1
 #define	RTL_IICBUS_WRITE	0
@@ -40,138 +41,142 @@
 /* Register definitions */
 
 /* Switch Global Configuration */
-#define RTL8366RB_SGCR				0x0000
-#define RTL8366RB_SGCR_EN_BC_STORM_CTRL		0x0001
-#define RTL8366RB_SGCR_MAX_LENGTH_MASK		0x0030
-#define RTL8366RB_SGCR_MAX_LENGTH_1522		0x0000
-#define RTL8366RB_SGCR_MAX_LENGTH_1536		0x0010
-#define RTL8366RB_SGCR_MAX_LENGTH_1552		0x0020
-#define RTL8366RB_SGCR_MAX_LENGTH_9216		0x0030
-#define RTL8366RB_SGCR_EN_VLAN			0x2000
-#define RTL8366RB_SGCR_EN_VLAN_4KTB		0x4000
-#define RTL8366RB_SGCR_EN_QOS			0x8000
+#define RTL8366_SGCR				0x0000
+#define RTL8366_SGCR_EN_BC_STORM_CTRL		0x0001
+#define RTL8366_SGCR_MAX_LENGTH_MASK		0x0030
+#define RTL8366_SGCR_MAX_LENGTH_1522		0x0000
+#define RTL8366_SGCR_MAX_LENGTH_1536		0x0010
+#define RTL8366_SGCR_MAX_LENGTH_1552		0x0020
+#define RTL8366_SGCR_MAX_LENGTH_9216		0x0030
+#define RTL8366_SGCR_EN_VLAN			0x2000
+#define RTL8366_SGCR_EN_VLAN_4KTB		0x4000
+#define RTL8366_SGCR_EN_QOS			0x8000
 
 /* Port Enable Control: DISABLE_PORT[5:0] */
-#define RTL8366RB_PECR				0x0001
+#define RTL8366_PECR				0x0001
 
 /* Switch Security Control 0: DIS_LEARN[5:0] */
-#define RTL8366RB_SSCR0				0x0002
+#define RTL8366_SSCR0				0x0002
 
 /* Switch Security Control 1: DIS_AGE[5:0] */
-#define RTL8366RB_SSCR1				0x0003
+#define RTL8366_SSCR1				0x0003
 
 /* Switch Security Control 2 */
-#define RTL8366RB_SSCR2				0x0004
-#define RTL8366RB_SSCR2_DROP_UNKNOWN_DA		0x0001
+#define RTL8366_SSCR2				0x0004
+#define RTL8366_SSCR2_DROP_UNKNOWN_DA		0x0001
 
 /* Port Link Status: two ports per register */
-#define RTL8366RB_PLSR_BASE			0x0014
-#define RTL8366RB_PLSR_SPEED_MASK	0x03
-#define RTL8366RB_PLSR_SPEED_10		0x00
-#define RTL8366RB_PLSR_SPEED_100	0x01
-#define RTL8366RB_PLSR_SPEED_1000	0x02
-#define RTL8366RB_PLSR_FULLDUPLEX	0x04
-#define RTL8366RB_PLSR_LINK		0x10
-#define RTL8366RB_PLSR_TXPAUSE		0x20
-#define RTL8366RB_PLSR_RXPAUSE		0x40
-#define RTL8366RB_PLSR_NO_AUTO		0x80
-
-/* VLAN Member Configuration, 3 registers per VLAN */
-#define RTL8366RB_VMCR_BASE			0x0020
-#define RTL8366RB_VMCR_MULT		3
-#define RTL8366RB_VMCR_DOT1Q_REG	0
-#define RTL8366RB_VMCR_DOT1Q_VID_SHIFT	0
-#define RTL8366RB_VMCR_DOT1Q_VID_MASK	0x0fff
-#define RTL8366RB_VMCR_DOT1Q_PCP_SHIFT	12
-#define RTL8366RB_VMCR_DOT1Q_PCP_MASK	0x7000
-#define RTL8366RB_VMCR_MU_REG		1
-#define RTL8366RB_VMCR_MU_MEMBER_SHIFT	0
-#define RTL8366RB_VMCR_MU_MEMBER_MASK	0x00ff
-#define RTL8366RB_VMCR_MU_UNTAG_SHIFT	8
-#define RTL8366RB_VMCR_MU_UNTAG_MASK	0xff00
-#define RTL8366RB_VMCR_FID_REG		2
-#define RTL8366RB_VMCR_FID_FID_SHIFT	0
-#define RTL8366RB_VMCR_FID_FID_MASK	0x0007
-#define RTL8366RB_VMCR(_reg, _vlan) \
-	(RTL8366RB_VMCR_BASE + _reg + _vlan * RTL8366RB_VMCR_MULT)
+#define RTL8366_PLSR_BASE			(sc->chip_type == 0 ? 0x0014 : 0x0060)
+#define RTL8366_PLSR_SPEED_MASK	0x03
+#define RTL8366_PLSR_SPEED_10		0x00
+#define RTL8366_PLSR_SPEED_100	0x01
+#define RTL8366_PLSR_SPEED_1000	0x02
+#define RTL8366_PLSR_FULLDUPLEX	0x04
+#define RTL8366_PLSR_LINK		0x10
+#define RTL8366_PLSR_TXPAUSE		0x20
+#define RTL8366_PLSR_RXPAUSE		0x40
+#define RTL8366_PLSR_NO_AUTO		0x80
+
+/* VLAN Member Configuration, 3 or 2 registers per VLAN */
+#define RTL8366_VMCR_BASE			(sc->chip_type == 0 ? 0x0020 : 0x0016)
+#define RTL8366_VMCR_MULT		(sc->chip_type == 0 ? 3 : 2)
+#define RTL8366_VMCR_DOT1Q_REG	0
+#define RTL8366_VMCR_DOT1Q_VID_SHIFT	0
+#define RTL8366_VMCR_DOT1Q_VID_MASK	0x0fff
+#define RTL8366_VMCR_DOT1Q_PCP_SHIFT	12
+#define RTL8366_VMCR_DOT1Q_PCP_MASK	0x7000
+#define RTL8366_VMCR_MU_REG		1
+#define RTL8366_VMCR_MU_MEMBER_SHIFT	0
+#define RTL8366_VMCR_MU_MEMBER_MASK	(sc->chip_type == 0 ? 0x00ff : 0x003f)
+#define RTL8366_VMCR_MU_UNTAG_SHIFT	(sc->chip_type == 0 ? 8 : 6)
+#define RTL8366_VMCR_MU_UNTAG_MASK	(sc->chip_type == 0 ? 0xff00 : 0x0fc0)
+#define RTL8366_VMCR_FID_REG		(sc->chip_type == 0 ? 2 : 1)
+#define RTL8366_VMCR_FID_FID_SHIFT	(sc->chip_type == 0 ? 0 : 12)
+#define RTL8366_VMCR_FID_FID_MASK	(sc->chip_type == 0 ? 0x0007 : 0x7000)
+#define RTL8366_VMCR(_reg, _vlan) \
+	(RTL8366_VMCR_BASE + _reg + _vlan * RTL8366_VMCR_MULT)
 /* VLAN Identifier */
-#define RTL8366RB_VMCR_VID(_r) \
-	(_r[RTL8366RB_VMCR_DOT1Q_REG] & RTL8366RB_VMCR_DOT1Q_VID_MASK)
+#define RTL8366_VMCR_VID(_r) \
+	(_r[RTL8366_VMCR_DOT1Q_REG] & RTL8366_VMCR_DOT1Q_VID_MASK)
 /* Priority Code Point */
-#define RTL8366RB_VMCR_PCP(_r) \
-	((_r[RTL8366RB_VMCR_DOT1Q_REG] & RTL8366RB_VMCR_DOT1Q_PCP_MASK) \
-	>> RTL8366RB_VMCR_DOT1Q_PCP_SHIFT)
+#define RTL8366_VMCR_PCP(_r) \
+	((_r[RTL8366_VMCR_DOT1Q_REG] & RTL8366_VMCR_DOT1Q_PCP_MASK) \
+	>> RTL8366_VMCR_DOT1Q_PCP_SHIFT)
 /* Member ports */
-#define RTL8366RB_VMCR_MEMBER(_r) \
-	(_r[RTL8366RB_VMCR_MU_REG] & RTL8366RB_VMCR_MU_MEMBER_MASK)
+#define RTL8366_VMCR_MEMBER(_r) \
+	(_r[RTL8366_VMCR_MU_REG] & RTL8366_VMCR_MU_MEMBER_MASK)
 /* Untagged ports */
-#define RTL8366RB_VMCR_UNTAG(_r) \
-	((_r[RTL8366RB_VMCR_MU_REG] & RTL8366RB_VMCR_MU_UNTAG_MASK) \
-	>> RTL8366RB_VMCR_MU_UNTAG_SHIFT)
+#define RTL8366_VMCR_UNTAG(_r) \
+	((_r[RTL8366_VMCR_MU_REG] & RTL8366_VMCR_MU_UNTAG_MASK) \
+	>> RTL8366_VMCR_MU_UNTAG_SHIFT)
 /* Forwarding ID */
-#define RTL8366RB_VMCR_FID(_r) \
-	(_r[RTL8366RB_VMCR_FID_REG] & RTL8366RB_VMCR_FID_FID_MASK)
+#define RTL8366_VMCR_FID(_r) \
+	(sc->chip_type == 0 ? (_r[RTL8366_VMCR_FID_REG] & RTL8366_VMCR_FID_FID_MASK) : \
+		((_r[RTL8366_VMCR_FID_REG] & RTL8366_VMCR_FID_FID_MASK) \
+		>> RTL8366_VMCR_FID_FID_SHIFT))
 
 /*
  * Port VLAN Control, 4 ports per register
  * Determines the VID for untagged ingress frames through
  * index into VMC.
  */
-#define RTL8366RB_PVCR_BASE			0x0063
-#define RTL8366RB_PVCR_PORT_SHIFT	4
-#define RTL8366RB_PVCR_PORT_PERREG	(16 / RTL8366RB_PVCR_PORT_SHIFT)
-#define RTL8366RB_PVCR_PORT_MASK	0x000f
-#define RTL8366RB_PVCR_REG(_port) \
-	(RTL8366RB_PVCR_BASE + _port / (RTL8366RB_PVCR_PORT_PERREG))
-#define RTL8366RB_PVCR_VAL(_port, _pvlan) \
-	((_pvlan & RTL8366RB_PVCR_PORT_MASK) << \
-	((_port % RTL8366RB_PVCR_PORT_PERREG) * RTL8366RB_PVCR_PORT_SHIFT))
-#define RTL8366RB_PVCR_GET(_port, _val) \
-	(((_val) >> ((_port % RTL8366RB_PVCR_PORT_PERREG) * RTL8366RB_PVCR_PORT_SHIFT)) & RTL8366RB_PVCR_PORT_MASK)
+#define RTL8366_PVCR_BASE			(sc->chip_type == 0 ? 0x0063 : 0x0058)
+#define RTL8366_PVCR_PORT_SHIFT	4
+#define RTL8366_PVCR_PORT_PERREG	(16 / RTL8366_PVCR_PORT_SHIFT)
+#define RTL8366_PVCR_PORT_MASK	0x000f
+#define RTL8366_PVCR_REG(_port) \
+	(RTL8366_PVCR_BASE + _port / (RTL8366_PVCR_PORT_PERREG))
+#define RTL8366_PVCR_VAL(_port, _pvlan) \
+	((_pvlan & RTL8366_PVCR_PORT_MASK) << \
+	((_port % RTL8366_PVCR_PORT_PERREG) * RTL8366_PVCR_PORT_SHIFT))
+#define RTL8366_PVCR_GET(_port, _val) \
+	(((_val) >> ((_port % RTL8366_PVCR_PORT_PERREG) * RTL8366_PVCR_PORT_SHIFT)) & RTL8366_PVCR_PORT_MASK)
 
 /* Reset Control */
-#define RTL8366RB_RCR				0x0100
-#define RTL8366RB_RCR_HARD_RESET	0x0001
-#define RTL8366RB_RCR_SOFT_RESET	0x0002
+#define RTL8366_RCR				0x0100
+#define RTL8366_RCR_HARD_RESET	0x0001
+#define RTL8366_RCR_SOFT_RESET	0x0002
 
 /* Chip Version Control: CHIP_VER[3:0] */
-#define RTL8366RB_CVCR				0x050A
+#define RTL8366_CVCR				(sc->chip_type == 0 ? 0x050A : 0x0104)
 /* Chip Identifier */
 #define RTL8366RB_CIR				0x0509
 #define RTL8366RB_CIR_ID8366RB		0x5937
+#define RTL8366SR_CIR				0x0105
+#define RTL8366SR_CIR_ID8366SR		0x8366
 
 /* VLAN Ingress Control 2: [5:0] */
-#define RTL8366RB_VIC2R				0x037f
+#define RTL8366_VIC2R				0x037f
 
 /* MIB registers */
-#define RTL8366RB_MCNT_BASE			0x1000
-#define RTL8366RB_MCTLR				0x13f0
-#define RTL8366RB_MCTLR_BUSY		0x0001
-#define RTL8366RB_MCTLR_RESET		0x0002
-#define RTL8366RB_MCTLR_RESET_PORT_MASK	0x00fc
-#define RTL8366RB_MCTLR_RESET_ALL	0x0800
-
-#define RTL8366RB_MCNT(_port, _r) \
-	(RTL8366RB_MCNT_BASE + 0x50 * (_port) + (_r))
-#define RTL8366RB_MCTLR_RESET_PORT(_p) \
+#define RTL8366_MCNT_BASE			0x1000
+#define RTL8366_MCTLR				(sc->chip_type == 0 ? 0x13f0 : 0x11F0)
+#define RTL8366_MCTLR_BUSY		0x0001
+#define RTL8366_MCTLR_RESET		0x0002
+#define RTL8366_MCTLR_RESET_PORT_MASK	0x00fc
+#define RTL8366_MCTLR_RESET_ALL	0x0800
+
+#define RTL8366_MCNT(_port, _r) \
+	(RTL8366_MCNT_BASE + 0x50 * (_port) + (_r))
+#define RTL8366_MCTLR_RESET_PORT(_p) \
 	(1 << ((_p) + 2))
 
 /* PHY Access Control */
-#define RTL8366RB_PACR				0x8000
-#define RTL8366RB_PACR_WRITE		0x0000
-#define RTL8366RB_PACR_READ			0x0001
+#define RTL8366_PACR				(sc->chip_type == 0 ? 0x8000 : 0x8028)
+#define RTL8366_PACR_WRITE		0x0000
+#define RTL8366_PACR_READ			0x0001
 
 /* PHY Access Data */
-#define	RTL8366RB_PADR				0x8002
+#define	RTL8366_PADR				(sc->chip_type == 0 ? 0x8002 : 0x8029)
 
-#define RTL8366RB_PHYREG(phy, page, reg) \
-	(RTL8366RB_PACR | (1 << (((phy) & 0x1f) + 9)) | (((page) & 0xf) << 5) | ((reg) & 0x1f))
+#define RTL8366_PHYREG(phy, page, reg) \
+	(0x8000 | (1 << (((phy) & 0x1f) + 9)) | (((page) & (sc->chip_type == 0 ? 0xf : 0x7)) << 5) | ((reg) & 0x1f))
 
 /* general characteristics of the chip */
-#define	RTL8366RB_CPU_PORT			5
-#define	RTL8366RB_NUM_PORTS			6
-#define	RTL8366RB_NUM_PHYS			(RTL8366RB_NUM_PORTS-1)
-#define	RTL8366RB_NUM_VLANS			16
-#define	RTL8366RB_NUM_PHY_REG			32
+#define	RTL8366_CPU_PORT			5
+#define	RTL8366_NUM_PORTS			6
+#define	RTL8366_NUM_PHYS			(RTL8366_NUM_PORTS-1)
+#define	RTL8366_NUM_VLANS			16
+#define	RTL8366_NUM_PHY_REG			32
 
 #endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611152158.uAFLw46E078286>