2 * Copyright (c) 2011-2012 Stefan Bethke.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/param.h>
31 #include <sys/errno.h>
32 #include <sys/kernel.h>
34 #include <sys/malloc.h>
35 #include <sys/module.h>
36 #include <sys/mutex.h>
37 #include <sys/socket.h>
38 #include <sys/sockio.h>
39 #include <sys/sysctl.h>
40 #include <sys/systm.h>
43 #include <net/if_var.h>
44 #include <net/ethernet.h>
45 #include <net/if_media.h>
46 #include <net/if_types.h>
48 #include <machine/bus.h>
49 #include <dev/iicbus/iic.h>
50 #include <dev/iicbus/iiconf.h>
51 #include <dev/iicbus/iicbus.h>
52 #include <dev/mii/mii.h>
53 #include <dev/mii/miivar.h>
55 #include <dev/etherswitch/etherswitch.h>
56 #include <dev/etherswitch/rtl8366/rtl8366rbvar.h>
58 #include "iicbus_if.h"
59 #include "miibus_if.h"
60 #include "etherswitch_if.h"
63 struct rtl8366rb_softc {
64 struct mtx sc_mtx; /* serialize access to softc */
65 int smi_acquired; /* serialize access to SMI/I2C bus */
66 struct mtx callout_mtx; /* serialize callout */
68 int vid[RTL8366RB_NUM_VLANS];
69 char *ifname[RTL8366RB_NUM_PHYS];
70 device_t miibus[RTL8366RB_NUM_PHYS];
71 struct ifnet *ifp[RTL8366RB_NUM_PHYS];
72 struct callout callout_tick;
75 static etherswitch_info_t etherswitch_info = {
76 .es_nports = RTL8366RB_NUM_PORTS,
77 .es_nvlangroups = RTL8366RB_NUM_VLANS,
78 .es_name = "Realtek RTL8366RB"
81 #define RTL_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
82 #define RTL_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
83 #define RTL_LOCK_ASSERT(_sc, _what) mtx_assert(&(_s)c->sc_mtx, (_what))
84 #define RTL_TRYLOCK(_sc) mtx_trylock(&(_sc)->sc_mtx)
89 #define RTL_SMI_ACQUIRED 1
90 #define RTL_SMI_ACQUIRED_ASSERT(_sc) \
91 KASSERT((_sc)->smi_acquired == RTL_SMI_ACQUIRED, ("smi must be acquired @%s", __FUNCTION__))
94 #define DPRINTF(dev, args...) device_printf(dev, args)
95 #define DEVERR(dev, err, fmt, args...) do { \
96 if (err != 0) device_printf(dev, fmt, err, args); \
98 #define DEBUG_INCRVAR(var) do { \
102 static int callout_blocked = 0;
103 static int iic_select_retries = 0;
104 static int phy_access_retries = 0;
105 static SYSCTL_NODE(_debug, OID_AUTO, rtl8366rb, CTLFLAG_RD, 0, "rtl8366rb");
106 SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, callout_blocked, CTLFLAG_RW, &callout_blocked, 0,
107 "number of times the callout couldn't acquire the bus");
108 SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, iic_select_retries, CTLFLAG_RW, &iic_select_retries, 0,
109 "number of times the I2C bus selection had to be retried");
110 SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, phy_access_retries, CTLFLAG_RW, &phy_access_retries, 0,
111 "number of times PHY register access had to be retried");
113 #define DPRINTF(dev, args...)
114 #define DEVERR(dev, err, fmt, args...)
115 #define DEBUG_INCRVAR(var)
118 static int smi_probe(device_t dev);
119 static int smi_read(device_t dev, uint16_t addr, uint16_t *data, int sleep);
120 static int smi_write(device_t dev, uint16_t addr, uint16_t data, int sleep);
121 static int smi_rmw(device_t dev, uint16_t addr, uint16_t mask, uint16_t data, int sleep);
122 static void rtl8366rb_tick(void *arg);
123 static int rtl8366rb_ifmedia_upd(struct ifnet *);
124 static void rtl8366rb_ifmedia_sts(struct ifnet *, struct ifmediareq *);
127 rtl8366rb_identify(driver_t *driver, device_t parent)
130 struct iicbus_ivar *devi;
132 if (device_find_child(parent, "rtl8366rb", -1) == NULL) {
133 child = BUS_ADD_CHILD(parent, 0, "rtl8366rb", -1);
134 devi = IICBUS_IVAR(child);
135 devi->addr = RTL8366RB_IIC_ADDR;
140 rtl8366rb_probe(device_t dev)
142 if (smi_probe(dev) != 0)
144 device_set_desc(dev, "RTL8366RB Ethernet Switch Controller");
145 return (BUS_PROBE_DEFAULT);
149 rtl8366rb_init(device_t dev)
151 /* Initialisation for TL-WR1043ND */
152 smi_rmw(dev, RTL8366RB_RCR,
153 RTL8366RB_RCR_HARD_RESET,
154 RTL8366RB_RCR_HARD_RESET, RTL_WAITOK);
156 /* Enable 16 VLAN mode */
157 smi_rmw(dev, RTL8366RB_SGCR,
158 RTL8366RB_SGCR_EN_VLAN | RTL8366RB_SGCR_EN_VLAN_4KTB,
159 RTL8366RB_SGCR_EN_VLAN, RTL_WAITOK);
160 /* remove port 0 form VLAN 0 */
161 smi_rmw(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_MU_REG, 0),
162 (1 << 0), 0, RTL_WAITOK);
163 /* add port 0 untagged and port 5 tagged to VLAN 1 */
164 smi_rmw(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_MU_REG, 1),
165 ((1 << 5 | 1 << 0) << RTL8366RB_VMCR_MU_MEMBER_SHIFT)
166 | ((1 << 5 | 1 << 0) << RTL8366RB_VMCR_MU_UNTAG_SHIFT),
167 ((1 << 5 | 1 << 0) << RTL8366RB_VMCR_MU_MEMBER_SHIFT
168 | ((1 << 0) << RTL8366RB_VMCR_MU_UNTAG_SHIFT)),
170 /* set PVLAN 1 for port 0 */
171 smi_rmw(dev, RTL8366RB_PVCR_REG(0),
172 RTL8366RB_PVCR_VAL(0, RTL8366RB_PVCR_PORT_MASK),
173 RTL8366RB_PVCR_VAL(0, 1), RTL_WAITOK);
177 rtl8366rb_attach(device_t dev)
180 struct rtl8366rb_softc *sc;
185 sc = device_get_softc(dev);
186 bzero(sc, sizeof(*sc));
188 mtx_init(&sc->sc_mtx, "rtl8366rb", NULL, MTX_DEF);
189 sc->smi_acquired = 0;
190 mtx_init(&sc->callout_mtx, "rtl8366rbcallout", NULL, MTX_DEF);
193 smi_read(dev, RTL8366RB_CVCR, &rev, RTL_WAITOK);
194 device_printf(dev, "rev. %d\n", rev & 0x000f);
196 /* attach miibus and phys */
197 /* PHYs need an interface, so we generate a dummy one */
198 for (i = 0; i < RTL8366RB_NUM_PHYS; i++) {
199 sc->ifp[i] = if_alloc(IFT_ETHER);
200 sc->ifp[i]->if_softc = sc;
201 sc->ifp[i]->if_flags |= IFF_UP | IFF_BROADCAST | IFF_DRV_RUNNING
203 snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(dev));
204 sc->ifname[i] = malloc(strlen(name)+1, M_DEVBUF, M_WAITOK);
205 bcopy(name, sc->ifname[i], strlen(name)+1);
206 if_initname(sc->ifp[i], sc->ifname[i], i);
207 err = mii_attach(dev, &sc->miibus[i], sc->ifp[i], rtl8366rb_ifmedia_upd, \
208 rtl8366rb_ifmedia_sts, BMSR_DEFCAPMASK, \
209 i, MII_OFFSET_ANY, 0);
211 device_printf(dev, "attaching PHY %d failed\n", i);
216 bus_generic_probe(dev);
217 bus_enumerate_hinted_children(dev);
218 err = bus_generic_attach(dev);
222 callout_init_mtx(&sc->callout_tick, &sc->callout_mtx, 0);
229 rtl8366rb_detach(device_t dev)
231 struct rtl8366rb_softc *sc = device_get_softc(dev);
234 for (i=0; i < RTL8366RB_NUM_PHYS; i++) {
236 device_delete_child(dev, sc->miibus[i]);
237 if (sc->ifp[i] != NULL)
239 free(sc->ifname[i], M_DEVBUF);
241 bus_generic_detach(dev);
242 callout_drain(&sc->callout_tick);
243 mtx_destroy(&sc->callout_mtx);
244 mtx_destroy(&sc->sc_mtx);
250 rtl8366rb_update_ifmedia(int portstatus, u_int *media_status, u_int *media_active)
252 *media_active = IFM_ETHER;
253 *media_status = IFM_AVALID;
254 if ((portstatus & RTL8366RB_PLSR_LINK) != 0)
255 *media_status |= IFM_ACTIVE;
257 *media_active |= IFM_NONE;
260 switch (portstatus & RTL8366RB_PLSR_SPEED_MASK) {
261 case RTL8366RB_PLSR_SPEED_10:
262 *media_active |= IFM_10_T;
264 case RTL8366RB_PLSR_SPEED_100:
265 *media_active |= IFM_100_TX;
267 case RTL8366RB_PLSR_SPEED_1000:
268 *media_active |= IFM_1000_T;
271 if ((portstatus & RTL8366RB_PLSR_FULLDUPLEX) == 0)
272 *media_active |= IFM_FDX;
274 *media_active |= IFM_HDX;
275 if ((portstatus & RTL8366RB_PLSR_TXPAUSE) != 0)
276 *media_active |= IFM_ETH_TXPAUSE;
277 if ((portstatus & RTL8366RB_PLSR_RXPAUSE) != 0)
278 *media_active |= IFM_ETH_RXPAUSE;
282 rtl833rb_miipollstat(struct rtl8366rb_softc *sc)
285 struct mii_data *mii;
286 struct mii_softc *miisc;
290 for (i = 0; i < RTL8366RB_NUM_PHYS; i++) {
291 mii = device_get_softc(sc->miibus[i]);
293 if (smi_read(sc->dev, RTL8366RB_PLSR_BASE + i/2, &value, RTL_NOWAIT) != 0) {
294 DEBUG_INCRVAR(callout_blocked);
297 portstatus = value & 0xff;
299 portstatus = (value >> 8) & 0xff;
301 rtl8366rb_update_ifmedia(portstatus, &mii->mii_media_status, &mii->mii_media_active);
302 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) {
303 if (IFM_INST(mii->mii_media.ifm_cur->ifm_media) != miisc->mii_inst)
305 mii_phy_update(miisc, MII_POLLSTAT);
311 rtl8366rb_tick(void *arg)
313 struct rtl8366rb_softc *sc = arg;
315 rtl833rb_miipollstat(sc);
316 callout_reset(&sc->callout_tick, hz, rtl8366rb_tick, sc);
320 smi_probe(device_t dev)
322 device_t iicbus, iicha;
328 bytes[0] = RTL8366RB_CIR & 0xff;
329 bytes[1] = (RTL8366RB_CIR >> 8) & 0xff;
330 iicbus = device_get_parent(dev);
331 iicha = device_get_parent(iicbus);
332 iicbus_reset(iicbus, IIC_FASTEST, RTL8366RB_IIC_ADDR, NULL);
336 * we go directly to the host adapter because iicbus.c
337 * only issues a stop on a bus that was successfully started.
340 err = iicbus_request_bus(iicbus, dev, IIC_WAIT);
343 err = iicbus_start(iicbus, RTL8366RB_IIC_ADDR | RTL_IICBUS_READ, RTL_IICBUS_TIMEOUT);
346 err = iicbus_write(iicbus, bytes, 2, &xferd, RTL_IICBUS_TIMEOUT);
349 err = iicbus_read(iicbus, bytes, 2, &xferd, IIC_LAST_READ, 0);
352 chipid = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
353 DPRINTF(dev, "chip id 0x%04x\n", chipid);
354 if (chipid != RTL8366RB_CIR_ID8366RB)
358 iicbus_release_bus(iicbus, dev);
359 return (err == 0 ? 0 : ENXIO);
363 smi_acquire(struct rtl8366rb_softc *sc, int sleep)
366 if (sleep == RTL_WAITOK)
369 if (RTL_TRYLOCK(sc) == 0)
370 return (EWOULDBLOCK);
371 if (sc->smi_acquired == RTL_SMI_ACQUIRED)
374 r = iicbus_request_bus(device_get_parent(sc->dev), sc->dev, \
375 sleep == RTL_WAITOK ? IIC_WAIT : IIC_DONTWAIT);
377 sc->smi_acquired = RTL_SMI_ACQUIRED;
384 smi_release(struct rtl8366rb_softc *sc, int sleep)
386 if (sleep == RTL_WAITOK)
389 if (RTL_TRYLOCK(sc) == 0)
390 return (EWOULDBLOCK);
391 RTL_SMI_ACQUIRED_ASSERT(sc);
392 iicbus_release_bus(device_get_parent(sc->dev), sc->dev);
393 sc->smi_acquired = 0;
399 smi_select(device_t dev, int op, int sleep)
402 device_t iicbus = device_get_parent(dev);
403 struct iicbus_ivar *devi = IICBUS_IVAR(dev);
404 int slave = devi->addr;
406 RTL_SMI_ACQUIRED_ASSERT((struct rtl8366rb_softc *)device_get_softc(dev));
408 * The chip does not use clock stretching when it is busy,
409 * instead ignoring the command. Retry a few times.
411 for (i = RTL_IICBUS_RETRIES; i--; ) {
412 err = iicbus_start(iicbus, slave | op, RTL_IICBUS_TIMEOUT);
413 if (err != IIC_ENOACK)
415 if (sleep == RTL_WAITOK) {
416 DEBUG_INCRVAR(iic_select_retries);
417 pause("smi_select", RTL_IICBUS_RETRY_SLEEP);
425 smi_read_locked(struct rtl8366rb_softc *sc, uint16_t addr, uint16_t *data, int sleep)
428 device_t iicbus = device_get_parent(sc->dev);
432 RTL_SMI_ACQUIRED_ASSERT(sc);
433 bytes[0] = addr & 0xff;
434 bytes[1] = (addr >> 8) & 0xff;
435 err = smi_select(sc->dev, RTL_IICBUS_READ, sleep);
438 err = iicbus_write(iicbus, bytes, 2, &xferd, RTL_IICBUS_TIMEOUT);
441 err = iicbus_read(iicbus, bytes, 2, &xferd, IIC_LAST_READ, 0);
444 *data = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
452 smi_write_locked(struct rtl8366rb_softc *sc, uint16_t addr, uint16_t data, int sleep)
455 device_t iicbus = device_get_parent(sc->dev);
459 RTL_SMI_ACQUIRED_ASSERT(sc);
460 bytes[0] = addr & 0xff;
461 bytes[1] = (addr >> 8) & 0xff;
462 bytes[2] = data & 0xff;
463 bytes[3] = (data >> 8) & 0xff;
465 err = smi_select(sc->dev, RTL_IICBUS_WRITE, sleep);
467 err = iicbus_write(iicbus, bytes, 4, &xferd, RTL_IICBUS_TIMEOUT);
474 smi_read(device_t dev, uint16_t addr, uint16_t *data, int sleep)
476 struct rtl8366rb_softc *sc = device_get_softc(dev);
479 err = smi_acquire(sc, sleep);
482 err = smi_read_locked(sc, addr, data, sleep);
483 smi_release(sc, sleep);
484 DEVERR(dev, err, "smi_read()=%d: addr=%04x\n", addr);
485 return (err == 0 ? 0 : EIO);
489 smi_write(device_t dev, uint16_t addr, uint16_t data, int sleep)
491 struct rtl8366rb_softc *sc = device_get_softc(dev);
494 err = smi_acquire(sc, sleep);
497 err = smi_write_locked(sc, addr, data, sleep);
498 smi_release(sc, sleep);
499 DEVERR(dev, err, "smi_write()=%d: addr=%04x\n", addr);
500 return (err == 0 ? 0 : EIO);
504 smi_rmw(device_t dev, uint16_t addr, uint16_t mask, uint16_t data, int sleep)
506 struct rtl8366rb_softc *sc = device_get_softc(dev);
510 err = smi_acquire(sc, sleep);
514 err = smi_read_locked(sc, addr, &oldv, sleep);
519 err = smi_write_locked(sc, addr, newv, sleep);
522 smi_release(sc, sleep);
523 DEVERR(dev, err, "smi_rmw()=%d: addr=%04x\n", addr);
524 return (err == 0 ? 0 : EIO);
527 static etherswitch_info_t *
528 rtl_getinfo(device_t dev)
530 return (ðerswitch_info);
534 rtl_readreg(device_t dev, int reg)
538 smi_read(dev, reg, &data, RTL_WAITOK);
543 rtl_writereg(device_t dev, int reg, int value)
545 return (smi_write(dev, reg, value, RTL_WAITOK));
549 rtl_getport(device_t dev, etherswitch_port_t *p)
551 struct rtl8366rb_softc *sc;
553 struct mii_data *mii;
554 struct ifmediareq *ifmr = &p->es_ifmr;
558 if (p->es_port < 0 || p->es_port >= RTL8366RB_NUM_PORTS)
560 sc = device_get_softc(dev);
561 vlangroup = RTL8366RB_PVCR_GET(p->es_port,
562 rtl_readreg(dev, RTL8366RB_PVCR_REG(p->es_port)));
563 p->es_pvid = sc->vid[vlangroup];
565 if (p->es_port < RTL8366RB_NUM_PHYS) {
566 mii = device_get_softc(sc->miibus[p->es_port]);
567 ifm = &mii->mii_media;
568 err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCGIFMEDIA);
572 /* fill in fixed values for CPU port */
574 smi_read(dev, RTL8366RB_PLSR_BASE + (RTL8366RB_NUM_PHYS)/2, &v, RTL_WAITOK);
575 v = v >> (8 * ((RTL8366RB_NUM_PHYS) % 2));
576 rtl8366rb_update_ifmedia(v, &ifmr->ifm_status, &ifmr->ifm_active);
577 ifmr->ifm_current = ifmr->ifm_active;
579 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID;
585 rtl_setport(device_t dev, etherswitch_port_t *p)
587 int i, err, vlangroup;
588 struct rtl8366rb_softc *sc;
590 struct mii_data *mii;
592 if (p->es_port < 0 || p->es_port >= RTL8366RB_NUM_PHYS)
594 sc = device_get_softc(dev);
596 for (i = 0; i < RTL8366RB_NUM_VLANS; i++) {
597 if (sc->vid[i] == p->es_pvid) {
604 err = smi_rmw(dev, RTL8366RB_PVCR_REG(p->es_port),
605 RTL8366RB_PVCR_VAL(p->es_port, RTL8366RB_PVCR_PORT_MASK),
606 RTL8366RB_PVCR_VAL(p->es_port, vlangroup), RTL_WAITOK);
609 mii = device_get_softc(sc->miibus[p->es_port]);
610 ifm = &mii->mii_media;
611 err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCSIFMEDIA);
616 rtl_getvgroup(device_t dev, etherswitch_vlangroup_t *vg)
622 vmcr[i] = rtl_readreg(dev, RTL8366RB_VMCR(i, vg->es_vlangroup));
624 vg->es_vid = RTL8366RB_VMCR_VID(vmcr) | ETHERSWITCH_VID_VALID;
625 vg->es_member_ports = RTL8366RB_VMCR_MEMBER(vmcr);
626 vg->es_untagged_ports = RTL8366RB_VMCR_UNTAG(vmcr);
627 vg->es_fid = RTL8366RB_VMCR_FID(vmcr);
632 rtl_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
634 struct rtl8366rb_softc *sc;
635 int g = vg->es_vlangroup;
637 sc = device_get_softc(dev);
638 sc->vid[g] = vg->es_vid;
639 rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_DOT1Q_REG, g),
640 (vg->es_vid << RTL8366RB_VMCR_DOT1Q_VID_SHIFT) & RTL8366RB_VMCR_DOT1Q_VID_MASK);
641 rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_MU_REG, g),
642 ((vg->es_member_ports << RTL8366RB_VMCR_MU_MEMBER_SHIFT) & RTL8366RB_VMCR_MU_MEMBER_MASK) |
643 ((vg->es_untagged_ports << RTL8366RB_VMCR_MU_UNTAG_SHIFT) & RTL8366RB_VMCR_MU_UNTAG_MASK));
644 rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_FID_REG, g),
650 rtl_readphy(device_t dev, int phy, int reg)
652 struct rtl8366rb_softc *sc = device_get_softc(dev);
656 if (phy < 0 || phy >= RTL8366RB_NUM_PHYS)
658 if (reg < 0 || reg >= RTL8366RB_NUM_PHY_REG)
661 err = smi_acquire(sc, sleep);
664 for (i = RTL_IICBUS_RETRIES; i--; ) {
665 err = smi_write_locked(sc, RTL8366RB_PACR, RTL8366RB_PACR_READ, sleep);
667 err = smi_write_locked(sc, RTL8366RB_PHYREG(phy, 0, reg), 0, sleep);
669 err = smi_read_locked(sc, RTL8366RB_PADR, &data, sleep);
672 DEBUG_INCRVAR(phy_access_retries);
673 DPRINTF(dev, "rtl_readphy(): chip not responsive, retrying %d more times\n", i);
674 pause("rtl_readphy", RTL_IICBUS_RETRY_SLEEP);
676 smi_release(sc, sleep);
677 DEVERR(dev, err, "rtl_readphy()=%d: phy=%d.%02x\n", phy, reg);
682 rtl_writephy(device_t dev, int phy, int reg, int data)
684 struct rtl8366rb_softc *sc = device_get_softc(dev);
687 if (phy < 0 || phy >= RTL8366RB_NUM_PHYS)
689 if (reg < 0 || reg >= RTL8366RB_NUM_PHY_REG)
692 err = smi_acquire(sc, sleep);
695 for (i = RTL_IICBUS_RETRIES; i--; ) {
696 err = smi_write_locked(sc, RTL8366RB_PACR, RTL8366RB_PACR_WRITE, sleep);
698 err = smi_write_locked(sc, RTL8366RB_PHYREG(phy, 0, reg), data, sleep);
702 DEBUG_INCRVAR(phy_access_retries);
703 DPRINTF(dev, "rtl_writephy(): chip not responsive, retrying %d more tiems\n", i);
704 pause("rtl_writephy", RTL_IICBUS_RETRY_SLEEP);
706 smi_release(sc, sleep);
707 DEVERR(dev, err, "rtl_writephy()=%d: phy=%d.%02x\n", phy, reg);
708 return (err == 0 ? 0 : EIO);
712 rtl8366rb_ifmedia_upd(struct ifnet *ifp)
714 struct rtl8366rb_softc *sc = ifp->if_softc;
715 struct mii_data *mii = device_get_softc(sc->miibus[ifp->if_dunit]);
722 rtl8366rb_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
724 struct rtl8366rb_softc *sc = ifp->if_softc;
725 struct mii_data *mii = device_get_softc(sc->miibus[ifp->if_dunit]);
728 ifmr->ifm_active = mii->mii_media_active;
729 ifmr->ifm_status = mii->mii_media_status;
733 static device_method_t rtl8366rb_methods[] = {
734 /* Device interface */
735 DEVMETHOD(device_identify, rtl8366rb_identify),
736 DEVMETHOD(device_probe, rtl8366rb_probe),
737 DEVMETHOD(device_attach, rtl8366rb_attach),
738 DEVMETHOD(device_detach, rtl8366rb_detach),
741 DEVMETHOD(bus_add_child, device_add_child_ordered),
744 DEVMETHOD(miibus_readreg, rtl_readphy),
745 DEVMETHOD(miibus_writereg, rtl_writephy),
747 /* etherswitch interface */
748 DEVMETHOD(etherswitch_getinfo, rtl_getinfo),
749 DEVMETHOD(etherswitch_readreg, rtl_readreg),
750 DEVMETHOD(etherswitch_writereg, rtl_writereg),
751 DEVMETHOD(etherswitch_readphyreg, rtl_readphy),
752 DEVMETHOD(etherswitch_writephyreg, rtl_writephy),
753 DEVMETHOD(etherswitch_getport, rtl_getport),
754 DEVMETHOD(etherswitch_setport, rtl_setport),
755 DEVMETHOD(etherswitch_getvgroup, rtl_getvgroup),
756 DEVMETHOD(etherswitch_setvgroup, rtl_setvgroup),
761 DEFINE_CLASS_0(rtl8366rb, rtl8366rb_driver, rtl8366rb_methods,
762 sizeof(struct rtl8366rb_softc));
763 static devclass_t rtl8366rb_devclass;
765 DRIVER_MODULE(rtl8366rb, iicbus, rtl8366rb_driver, rtl8366rb_devclass, 0, 0);
766 DRIVER_MODULE(miibus, rtl8366rb, miibus_driver, miibus_devclass, 0, 0);
767 DRIVER_MODULE(etherswitch, rtl8366rb, etherswitch_driver, etherswitch_devclass, 0, 0);
768 MODULE_VERSION(rtl8366rb, 1);
769 MODULE_DEPEND(rtl8366rb, iicbus, 1, 1, 1); /* XXX which versions? */
770 MODULE_DEPEND(rtl8366rb, miibus, 1, 1, 1); /* XXX which versions? */
771 MODULE_DEPEND(rtl8366rb, etherswitch, 1, 1, 1); /* XXX which versions? */