Index: sys/dev/etherswitch/rtl8366/rtl8366rb.c =================================================================== --- sys/dev/etherswitch/rtl8366/rtl8366rb.c +++ sys/dev/etherswitch/rtl8366/rtl8366rb.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Hiroki Mori + * Copyright (c) 2015 Hiroki Mori. * Copyright (c) 2011-2012 Stefan Bethke. * All rights reserved. * @@ -74,6 +74,7 @@ struct ifnet *ifp[RTL8366_NUM_PHYS]; struct callout callout_tick; etherswitch_info_t info; + int chip_type; /* 0 = RTL8366RB, 1 = RTL8366SR */ }; #define RTL_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) @@ -121,7 +122,6 @@ static int rtl8366rb_ifmedia_upd(struct ifnet *); static void rtl8366rb_ifmedia_sts(struct ifnet *, struct ifmediareq *); -static int chip_type = 0; /* 0 = RTL8366RB, 1 = RTL8366SR */ static void rtl8366rb_identify(driver_t *driver, device_t parent) @@ -139,9 +139,14 @@ 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); - if(chip_type == 0) + if(sc->chip_type == 0) device_set_desc(dev, "RTL8366RB Ethernet Switch Controller"); else device_set_desc(dev, "RTL8366SR Ethernet Switch Controller"); @@ -151,8 +156,10 @@ static void rtl8366rb_init(device_t dev) { - int i; struct rtl8366rb_softc *sc; + int i; + + sc = device_get_softc(dev); /* Initialisation for TL-WR1043ND */ #ifdef RTL8366_SOFT_RESET @@ -171,7 +178,6 @@ 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. */ @@ -193,14 +199,14 @@ 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; @@ -213,7 +219,7 @@ sc->info.es_nports = RTL8366_NUM_PORTS; sc->info.es_nvlangroups = RTL8366_NUM_VLANS; sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q; - if(chip_type == 0) + if(sc->chip_type == 0) sprintf(sc->info.es_name, "Realtek RTL8366RB"); else sprintf(sc->info.es_name, "Realtek RTL8366SR"); @@ -253,9 +259,11 @@ static int rtl8366rb_detach(device_t dev) { - struct rtl8366rb_softc *sc = device_get_softc(dev); + struct rtl8366rb_softc *sc; int 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]); @@ -335,7 +343,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); @@ -344,12 +354,15 @@ static int smi_probe(device_t dev) { + struct rtl8366rb_softc *sc; device_t iicbus, iicha; int err, i, j; uint16_t chipid; char bytes[2]; int xferd; + sc = device_get_softc(dev); + iicbus = device_get_parent(dev); iicha = device_get_parent(iicbus); @@ -384,13 +397,13 @@ chipid = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff); if (i == 0 && chipid == RTL8366RB_CIR_ID8366RB) { DPRINTF(dev, "chip id 0x%04x\n", chipid); - chip_type = 0; + sc->chip_type = 0; err = 0; break; } if (i == 1 && chipid == RTL8366SR_CIR_ID8366SR) { DPRINTF(dev, "chip id 0x%04x\n", chipid); - chip_type = 1; + sc->chip_type = 1; err = 0; break; } @@ -446,14 +459,21 @@ 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(chip_type == 1) { // RTL8366SR work around + 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))); @@ -479,10 +499,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; @@ -506,10 +528,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; @@ -527,9 +551,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); @@ -542,9 +568,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); @@ -557,10 +585,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); @@ -581,7 +611,9 @@ static etherswitch_info_t * rtl_getinfo(device_t dev) { - struct rtl8366rb_softc *sc = device_get_softc(dev); + struct rtl8366rb_softc *sc; + + sc = device_get_softc(dev); return (&sc->info); } @@ -589,7 +621,9 @@ 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); @@ -607,13 +641,16 @@ 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; + sc = device_get_softc(dev); + + ifmr = &p->es_ifmr; + if (p->es_port < 0 || p->es_port >= RTL8366_NUM_PORTS) return (ENXIO); - sc = device_get_softc(dev); 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; @@ -647,14 +684,15 @@ 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; + sc = device_get_softc(dev); + if (p->es_port < 0 || p->es_port >= RTL8366_NUM_PORTS) return (ENXIO); - sc = device_get_softc(dev); vlangroup = -1; for (i = 0; i < RTL8366_NUM_VLANS; i++) { if ((sc->vid[i] & ETHERSWITCH_VID_MASK) == p->es_pvid) { @@ -681,13 +719,14 @@ rtl_getvgroup(device_t dev, etherswitch_vlangroup_t *vg) { struct rtl8366rb_softc *sc; - uint16_t vmcr[RTL8366_VMCR_MULT]; + uint16_t vmcr[3]; int i; + sc = device_get_softc(dev); + for (i=0; ies_vlangroup)); - sc = device_get_softc(dev); vg->es_vid = sc->vid[vg->es_vlangroup]; vg->es_member_ports = RTL8366_VMCR_MEMBER(vmcr); vg->es_untagged_ports = RTL8366_VMCR_UNTAG(vmcr); @@ -699,9 +738,12 @@ 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) @@ -709,7 +751,7 @@ sc->vid[g] |= ETHERSWITCH_VID_VALID; rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_DOT1Q_REG, g), (vg->es_vid << RTL8366_VMCR_DOT1Q_VID_SHIFT) & RTL8366_VMCR_DOT1Q_VID_MASK); - if(chip_type == 0) { + 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)); @@ -738,10 +780,14 @@ 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; + sc = device_get_softc(dev); + + data = 0; + if (phy < 0 || phy >= RTL8366_NUM_PHYS) return (ENXIO); if (reg < 0 || reg >= RTL8366_NUM_PHY_REG) @@ -770,9 +816,11 @@ 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; + sc = device_get_softc(dev); + if (phy < 0 || phy >= RTL8366_NUM_PHYS) return (ENXIO); if (reg < 0 || reg >= RTL8366_NUM_PHY_REG) @@ -800,8 +848,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); @@ -810,8 +861,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,5 +1,5 @@ /*- - * Copyright (c) 2015 Hiroki Mori + * Copyright (c) 2015 Hiroki Mori. * Copyright (c) 2011-2012 Stefan Bethke. * All rights reserved. * @@ -66,7 +66,7 @@ #define RTL8366_SSCR2_DROP_UNKNOWN_DA 0x0001 /* Port Link Status: two ports per register */ -#define RTL8366_PLSR_BASE (chip_type == 0 ? 0x0014 : 0x0060) +#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 @@ -78,8 +78,8 @@ #define RTL8366_PLSR_NO_AUTO 0x80 /* VLAN Member Configuration, 3 or 2 registers per VLAN */ -#define RTL8366_VMCR_BASE (chip_type == 0 ? 0x0020 : 0x0016) -#define RTL8366_VMCR_MULT (chip_type == 0 ? 3 : 2) +#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 @@ -87,12 +87,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 (chip_type == 0 ? 0x00ff : 0x003f) -#define RTL8366_VMCR_MU_UNTAG_SHIFT (chip_type == 0 ? 8 : 6) -#define RTL8366_VMCR_MU_UNTAG_MASK (chip_type == 0 ? 0xff00 : 0x0fc0) -#define RTL8366_VMCR_FID_REG (chip_type == 0 ? 2 : 1) -#define RTL8366_VMCR_FID_FID_SHIFT (chip_type == 0 ? 0 : 12) -#define RTL8366_VMCR_FID_FID_MASK (chip_type == 0 ? 0x0007 : 0x7000) +#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 */ @@ -111,7 +111,7 @@ >> RTL8366_VMCR_MU_UNTAG_SHIFT) /* Forwarding ID */ #define RTL8366_VMCR_FID(_r) \ - (chip_type == 0 ? (_r[RTL8366_VMCR_FID_REG] & RTL8366_VMCR_FID_FID_MASK) : \ + (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)) @@ -120,7 +120,7 @@ * Determines the VID for untagged ingress frames through * index into VMC. */ -#define RTL8366_PVCR_BASE (chip_type == 0 ? 0x0063 : 0x0058) +#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 @@ -138,7 +138,7 @@ #define RTL8366_RCR_SOFT_RESET 0x0002 /* Chip Version Control: CHIP_VER[3:0] */ -#define RTL8366_CVCR (chip_type == 0 ? 0x050A : 0x0104) +#define RTL8366_CVCR (sc->chip_type == 0 ? 0x050A : 0x0104) /* Chip Identifier */ #define RTL8366RB_CIR 0x0509 #define RTL8366RB_CIR_ID8366RB 0x5937 @@ -150,7 +150,7 @@ /* MIB registers */ #define RTL8366_MCNT_BASE 0x1000 -#define RTL8366_MCTLR (chip_type == 0 ? 0x13f0 : 0x11F0) +#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 @@ -162,15 +162,15 @@ (1 << ((_p) + 2)) /* PHY Access Control */ -#define RTL8366_PACR (chip_type == 0 ? 0x8000 : 0x8028) +#define RTL8366_PACR (sc->chip_type == 0 ? 0x8000 : 0x8028) #define RTL8366_PACR_WRITE 0x0000 #define RTL8366_PACR_READ 0x0001 /* PHY Access Data */ -#define RTL8366_PADR (chip_type == 0 ? 0x8002 : 0x8029) +#define RTL8366_PADR (sc->chip_type == 0 ? 0x8002 : 0x8029) #define RTL8366_PHYREG(phy, page, reg) \ - (0x8000 | (1 << (((phy) & 0x1f) + 9)) | (((page) & (chip_type == 0 ? 0xf : 0x7)) << 5) | ((reg) & 0x1f)) + (0x8000 | (1 << (((phy) & 0x1f) + 9)) | (((page) & (sc->chip_type == 0 ? 0xf : 0x7)) << 5) | ((reg) & 0x1f)) /* general characteristics of the chip */ #define RTL8366_CPU_PORT 5