Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135745981
D6796.id18833.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
29 KB
Referenced Files
None
Subscribers
None
D6796.id18833.diff
View Options
Index: sys/conf/options
===================================================================
--- sys/conf/options
+++ sys/conf/options
@@ -985,3 +985,6 @@
# GPIO and child devices
GPIO_SPI_DEBUG opt_gpio.h
+
+# etherswitch(4) driver
+RTL8366_SOFT_RESET opt_etherswitch.h
Index: sys/dev/etherswitch/rtl8366/rtl8366rb.c
===================================================================
--- sys/dev/etherswitch/rtl8366/rtl8366rb.c
+++ sys/dev/etherswitch/rtl8366/rtl8366rb.c
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2015 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 @@
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 @@
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 @@
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 @@
{
*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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
static etherswitch_info_t *
rtl_getinfo(device_t dev)
{
- return (ðerswitch_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 @@
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 @@
} 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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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;
Index: sys/dev/etherswitch/rtl8366/rtl8366rbvar.h
===================================================================
--- sys/dev/etherswitch/rtl8366/rtl8366rbvar.h
+++ sys/dev/etherswitch/rtl8366/rtl8366rbvar.h
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2015 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
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 13, 10:41 AM (10 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25253576
Default Alt Text
D6796.id18833.diff (29 KB)
Attached To
Mode
D6796: Add RTL8366SR support at etherswitch driver
Attached
Detach File
Event Timeline
Log In to Comment