]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/etherswitch/rtl8366/rtl8366rb.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / etherswitch / rtl8366 / rtl8366rb.c
1 /*-
2  * Copyright (c) 2011-2012 Stefan Bethke.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
13  *
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
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28
29 #include <sys/param.h>
30 #include <sys/bus.h>
31 #include <sys/errno.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
34 #include <sys/socket.h>
35 #include <sys/sockio.h>
36 #include <sys/sysctl.h>
37 #include <sys/systm.h>
38
39 #include <net/if.h>
40 #include <net/if_arp.h>
41 #include <net/ethernet.h>
42 #include <net/if_dl.h>
43 #include <net/if_media.h>
44 #include <net/if_types.h>
45
46 #include <machine/bus.h>
47 #include <dev/iicbus/iic.h>
48 #include <dev/iicbus/iiconf.h>
49 #include <dev/iicbus/iicbus.h>
50 #include <dev/mii/mii.h>
51 #include <dev/mii/miivar.h>
52
53 #include <dev/etherswitch/etherswitch.h>
54 #include <dev/etherswitch/rtl8366/rtl8366rbvar.h>
55
56 #include "iicbus_if.h"
57 #include "miibus_if.h"
58 #include "etherswitch_if.h"
59
60
61 struct rtl8366rb_softc {
62         struct mtx      sc_mtx;         /* serialize access to softc */
63         int             smi_acquired;   /* serialize access to SMI/I2C bus */
64         struct mtx      callout_mtx;    /* serialize callout */
65         device_t        dev;
66         int             vid[RTL8366RB_NUM_VLANS];
67         char            *ifname[RTL8366RB_NUM_PHYS];
68         device_t        miibus[RTL8366RB_NUM_PHYS];
69         struct ifnet    *ifp[RTL8366RB_NUM_PHYS];
70         struct callout  callout_tick;
71 };
72
73 static etherswitch_info_t etherswitch_info = {
74         .es_nports =            RTL8366RB_NUM_PORTS,
75         .es_nvlangroups =       RTL8366RB_NUM_VLANS,
76         .es_name =                      "Realtek RTL8366RB"
77 };
78
79 #define RTL_LOCK(_sc)   mtx_lock(&(_sc)->sc_mtx)
80 #define RTL_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
81 #define RTL_LOCK_ASSERT(_sc, _what)     mtx_assert(&(_s)c->sc_mtx, (_what))
82 #define RTL_TRYLOCK(_sc)        mtx_trylock(&(_sc)->sc_mtx)
83
84 #define RTL_WAITOK      0
85 #define RTL_NOWAIT      1
86
87 #define RTL_SMI_ACQUIRED        1
88 #define RTL_SMI_ACQUIRED_ASSERT(_sc) \
89         KASSERT((_sc)->smi_acquired == RTL_SMI_ACQUIRED, ("smi must be acquired @%s", __FUNCTION__))
90
91 #if defined(DEBUG)
92 #define DPRINTF(dev, args...) device_printf(dev, args)
93 #define DEVERR(dev, err, fmt, args...) do { \
94                 if (err != 0) device_printf(dev, fmt, err, args); \
95         } while (0)
96 #define DEBUG_INCRVAR(var)      do { \
97                 var++; \
98         } while (0)
99
100 static int callout_blocked = 0;
101 static int iic_select_retries = 0;
102 static int phy_access_retries = 0;
103 static SYSCTL_NODE(_debug, OID_AUTO, rtl8366rb, CTLFLAG_RD, 0, "rtl8366rb");
104 SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, callout_blocked, CTLFLAG_RW, &callout_blocked, 0,
105         "number of times the callout couldn't acquire the bus");
106 SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, iic_select_retries, CTLFLAG_RW, &iic_select_retries, 0,
107         "number of times the I2C bus selection had to be retried");
108 SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, phy_access_retries, CTLFLAG_RW, &phy_access_retries, 0,
109         "number of times PHY register access had to be retried");
110 #else
111 #define DPRINTF(dev, args...)
112 #define DEVERR(dev, err, fmt, args...)
113 #define DEBUG_INCRVAR(var)
114 #endif
115
116 static int smi_probe(device_t dev);
117 static int smi_read(device_t dev, uint16_t addr, uint16_t *data, int sleep);
118 static int smi_write(device_t dev, uint16_t addr, uint16_t data, int sleep);
119 static int smi_rmw(device_t dev, uint16_t addr, uint16_t mask, uint16_t data, int sleep);
120 static void rtl8366rb_tick(void *arg);
121 static int rtl8366rb_ifmedia_upd(struct ifnet *);
122 static void rtl8366rb_ifmedia_sts(struct ifnet *, struct ifmediareq *);
123
124 static void
125 rtl8366rb_identify(driver_t *driver, device_t parent)
126 {
127         device_t child;
128         struct iicbus_ivar *devi;
129
130         if (device_find_child(parent, "rtl8366rb", -1) == NULL) {
131                 child = BUS_ADD_CHILD(parent, 0, "rtl8366rb", -1);
132                 devi = IICBUS_IVAR(child);
133                 devi->addr = RTL8366RB_IIC_ADDR;
134         }
135 }
136
137 static int
138 rtl8366rb_probe(device_t dev)
139 {
140         if (smi_probe(dev) != 0)
141                 return (ENXIO);
142         device_set_desc(dev, "RTL8366RB Ethernet Switch Controller");
143         return (BUS_PROBE_DEFAULT);
144 }
145
146 static void
147 rtl8366rb_init(device_t dev)
148 {
149         /* Initialisation for TL-WR1043ND */
150         smi_rmw(dev, RTL8366RB_RCR,
151                 RTL8366RB_RCR_HARD_RESET,
152                 RTL8366RB_RCR_HARD_RESET, RTL_WAITOK);
153         DELAY(100000);
154         /* Enable 16 VLAN mode */
155         smi_rmw(dev, RTL8366RB_SGCR,
156                 RTL8366RB_SGCR_EN_VLAN | RTL8366RB_SGCR_EN_VLAN_4KTB,
157                 RTL8366RB_SGCR_EN_VLAN, RTL_WAITOK);
158         /* remove port 0 form VLAN 0 */
159         smi_rmw(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_MU_REG, 0),
160                 (1 << 0), 0, RTL_WAITOK);
161         /* add port 0 untagged and port 5 tagged to VLAN 1 */
162         smi_rmw(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_MU_REG, 1),
163                 ((1 << 5 | 1 << 0) << RTL8366RB_VMCR_MU_MEMBER_SHIFT)
164                         | ((1 << 5 | 1 << 0) << RTL8366RB_VMCR_MU_UNTAG_SHIFT),
165                 ((1 << 5 | 1 << 0) << RTL8366RB_VMCR_MU_MEMBER_SHIFT
166                         | ((1 << 0) << RTL8366RB_VMCR_MU_UNTAG_SHIFT)),
167                 RTL_WAITOK);
168         /* set PVLAN 1 for port 0 */
169         smi_rmw(dev, RTL8366RB_PVCR_REG(0),
170                 RTL8366RB_PVCR_VAL(0, RTL8366RB_PVCR_PORT_MASK),
171                 RTL8366RB_PVCR_VAL(0, 1), RTL_WAITOK);
172 }
173
174 static int
175 rtl8366rb_attach(device_t dev)
176 {
177         uint16_t rev = 0;
178         struct rtl8366rb_softc *sc;
179         char name[IFNAMSIZ];
180         int err = 0;
181         int i;
182
183         sc = device_get_softc(dev);
184         bzero(sc, sizeof(*sc));
185         sc->dev = dev;
186         mtx_init(&sc->sc_mtx, "rtl8366rb", NULL, MTX_DEF);
187         sc->smi_acquired = 0;
188         mtx_init(&sc->callout_mtx, "rtl8366rbcallout", NULL, MTX_DEF);
189
190         rtl8366rb_init(dev);
191         smi_read(dev, RTL8366RB_CVCR, &rev, RTL_WAITOK);
192         device_printf(dev, "rev. %d\n", rev & 0x000f);
193
194         /* attach miibus and phys */
195         /* PHYs need an interface, so we generate a dummy one */
196         for (i = 0; i < RTL8366RB_NUM_PHYS; i++) {
197                 sc->ifp[i] = if_alloc(IFT_ETHER);
198                 sc->ifp[i]->if_softc = sc;
199                 sc->ifp[i]->if_flags |= IFF_UP | IFF_BROADCAST | IFF_DRV_RUNNING
200                         | IFF_SIMPLEX;
201                 snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(dev));
202                 sc->ifname[i] = malloc(strlen(name)+1, M_DEVBUF, M_WAITOK);
203                 bcopy(name, sc->ifname[i], strlen(name)+1);
204                 if_initname(sc->ifp[i], sc->ifname[i], i);
205                 err = mii_attach(dev, &sc->miibus[i], sc->ifp[i], rtl8366rb_ifmedia_upd, \
206                         rtl8366rb_ifmedia_sts, BMSR_DEFCAPMASK, \
207                         i, MII_OFFSET_ANY, 0);
208                 if (err != 0) {
209                         device_printf(dev, "attaching PHY %d failed\n", i);
210                         return (err);
211                 }
212         }
213
214         bus_generic_probe(dev);
215         bus_enumerate_hinted_children(dev);
216         err = bus_generic_attach(dev);
217         if (err != 0)
218                 return (err);
219         
220         callout_init_mtx(&sc->callout_tick, &sc->callout_mtx, 0);
221         rtl8366rb_tick(sc);
222         
223         return (err);
224 }
225
226 static int
227 rtl8366rb_detach(device_t dev)
228 {
229         struct rtl8366rb_softc *sc = device_get_softc(dev);
230         int i;
231
232         for (i=0; i < RTL8366RB_NUM_PHYS; i++) {
233                 if (sc->miibus[i])
234                         device_delete_child(dev, sc->miibus[i]);
235                 if (sc->ifp[i] != NULL)
236                         if_free(sc->ifp[i]);
237                 free(sc->ifname[i], M_DEVBUF);
238         }
239         bus_generic_detach(dev);
240         callout_drain(&sc->callout_tick);
241         mtx_destroy(&sc->callout_mtx);
242         mtx_destroy(&sc->sc_mtx);
243
244         return (0);
245 }
246
247 static void
248 rtl8366rb_update_ifmedia(int portstatus, u_int *media_status, u_int *media_active)
249 {
250         *media_active = IFM_ETHER;
251         *media_status = IFM_AVALID;
252         if ((portstatus & RTL8366RB_PLSR_LINK) != 0)
253                 *media_status |= IFM_ACTIVE;
254         else {
255                 *media_active |= IFM_NONE;
256                 return;
257         }
258         switch (portstatus & RTL8366RB_PLSR_SPEED_MASK) {
259         case RTL8366RB_PLSR_SPEED_10:
260                 *media_active |= IFM_10_T;
261                 break;
262         case RTL8366RB_PLSR_SPEED_100:
263                 *media_active |= IFM_100_TX;
264                 break;
265         case RTL8366RB_PLSR_SPEED_1000:
266                 *media_active |= IFM_1000_T;
267                 break;
268         }
269         if ((portstatus & RTL8366RB_PLSR_FULLDUPLEX) == 0)
270                 *media_active |= IFM_FDX;
271         else
272                 *media_active |= IFM_HDX;
273         if ((portstatus & RTL8366RB_PLSR_TXPAUSE) != 0)
274                 *media_active |= IFM_ETH_TXPAUSE;
275         if ((portstatus & RTL8366RB_PLSR_RXPAUSE) != 0)
276                 *media_active |= IFM_ETH_RXPAUSE;
277 }
278
279 static void
280 rtl833rb_miipollstat(struct rtl8366rb_softc *sc)
281 {
282         int i;
283         struct mii_data *mii;
284         struct mii_softc *miisc;
285         uint16_t value;
286         int portstatus;
287
288         for (i = 0; i < RTL8366RB_NUM_PHYS; i++) {
289                 mii = device_get_softc(sc->miibus[i]);
290                 if ((i % 2) == 0) {
291                         if (smi_read(sc->dev, RTL8366RB_PLSR_BASE + i/2, &value, RTL_NOWAIT) != 0) {
292                                 DEBUG_INCRVAR(callout_blocked);
293                                 return;
294                         }
295                         portstatus = value & 0xff;
296                 } else {
297                         portstatus = (value >> 8) & 0xff;
298                 }
299                 rtl8366rb_update_ifmedia(portstatus, &mii->mii_media_status, &mii->mii_media_active);
300                 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) {
301                         if (IFM_INST(mii->mii_media.ifm_cur->ifm_media) != miisc->mii_inst)
302                                 continue;
303                         mii_phy_update(miisc, MII_POLLSTAT);
304                 }
305         }       
306 }
307
308 static void
309 rtl8366rb_tick(void *arg)
310 {
311         struct rtl8366rb_softc *sc = arg;
312
313         rtl833rb_miipollstat(sc);
314         callout_reset(&sc->callout_tick, hz, rtl8366rb_tick, sc);
315 }
316
317 static int
318 smi_probe(device_t dev)
319 {
320         device_t iicbus, iicha;
321         int err, i;
322         uint16_t chipid;
323         char bytes[2];
324         int xferd;
325
326         bytes[0] = RTL8366RB_CIR & 0xff;
327         bytes[1] = (RTL8366RB_CIR >> 8) & 0xff;
328         iicbus = device_get_parent(dev);
329         iicha = device_get_parent(iicbus);
330         iicbus_reset(iicbus, IIC_FASTEST, RTL8366RB_IIC_ADDR, NULL);
331         for (i=3; i--; ) {
332                 IICBUS_STOP(iicha);
333                 /*
334                  * we go directly to the host adapter because iicbus.c
335                  * only issues a stop on a bus that was successfully started.
336                  */
337         }
338         err = iicbus_request_bus(iicbus, dev, IIC_WAIT);
339         if (err != 0)
340                 goto out;
341         err = iicbus_start(iicbus, RTL8366RB_IIC_ADDR | RTL_IICBUS_READ, RTL_IICBUS_TIMEOUT);
342         if (err != 0)
343                 goto out;
344         err = iicbus_write(iicbus, bytes, 2, &xferd, RTL_IICBUS_TIMEOUT);
345         if (err != 0)
346                 goto out;
347         err = iicbus_read(iicbus, bytes, 2, &xferd, IIC_LAST_READ, 0);
348         if (err != 0)
349                 goto out;
350         chipid = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
351         DPRINTF(dev, "chip id 0x%04x\n", chipid);
352         if (chipid != RTL8366RB_CIR_ID8366RB)
353                 err = ENXIO;
354 out:
355         iicbus_stop(iicbus);
356         iicbus_release_bus(iicbus, dev);
357         return (err == 0 ? 0 : ENXIO);
358 }
359
360 static int
361 smi_acquire(struct rtl8366rb_softc *sc, int sleep)
362 {
363         int r = 0;
364         if (sleep == RTL_WAITOK)
365                 RTL_LOCK(sc);
366         else
367                 if (RTL_TRYLOCK(sc) == 0)
368                         return (EWOULDBLOCK);
369         if (sc->smi_acquired == RTL_SMI_ACQUIRED)
370                 r = EBUSY;
371         else {
372                 r = iicbus_request_bus(device_get_parent(sc->dev), sc->dev, \
373                         sleep == RTL_WAITOK ? IIC_WAIT : IIC_DONTWAIT);
374                 if (r == 0)
375                         sc->smi_acquired = RTL_SMI_ACQUIRED;
376         }
377         RTL_UNLOCK(sc);
378         return (r);
379 }
380
381 static int
382 smi_release(struct rtl8366rb_softc *sc, int sleep)
383 {
384         if (sleep == RTL_WAITOK)
385                 RTL_LOCK(sc);
386         else
387                 if (RTL_TRYLOCK(sc) == 0)
388                         return (EWOULDBLOCK);
389         RTL_SMI_ACQUIRED_ASSERT(sc);
390         iicbus_release_bus(device_get_parent(sc->dev), sc->dev);
391         sc->smi_acquired = 0;
392         RTL_UNLOCK(sc);
393         return (0);
394 }
395
396 static int
397 smi_select(device_t dev, int op, int sleep)
398 {
399         int err, i;
400         device_t iicbus = device_get_parent(dev);
401         struct iicbus_ivar *devi = IICBUS_IVAR(dev);
402         int slave = devi->addr;
403
404         RTL_SMI_ACQUIRED_ASSERT((struct rtl8366rb_softc *)device_get_softc(dev));
405         /*
406          * The chip does not use clock stretching when it is busy,
407          * instead ignoring the command. Retry a few times.
408          */
409         for (i = RTL_IICBUS_RETRIES; i--; ) {
410                 err = iicbus_start(iicbus, slave | op, RTL_IICBUS_TIMEOUT);
411                 if (err != IIC_ENOACK)
412                         break;
413                 if (sleep == RTL_WAITOK) {
414                         DEBUG_INCRVAR(iic_select_retries);
415                         pause("smi_select", RTL_IICBUS_RETRY_SLEEP);
416                 } else
417                         break;
418         }
419         return (err);
420 }
421
422 static int
423 smi_read_locked(struct rtl8366rb_softc *sc, uint16_t addr, uint16_t *data, int sleep)
424 {
425         int err;
426         device_t iicbus = device_get_parent(sc->dev);
427         char bytes[2];
428         int xferd;
429
430         RTL_SMI_ACQUIRED_ASSERT(sc);
431         bytes[0] = addr & 0xff;
432         bytes[1] = (addr >> 8) & 0xff;
433         err = smi_select(sc->dev, RTL_IICBUS_READ, sleep);
434         if (err != 0)
435                 goto out;
436         err = iicbus_write(iicbus, bytes, 2, &xferd, RTL_IICBUS_TIMEOUT);
437         if (err != 0)
438                 goto out;
439         err = iicbus_read(iicbus, bytes, 2, &xferd, IIC_LAST_READ, 0);
440         if (err != 0)
441                 goto out;
442         *data = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
443
444 out:
445         iicbus_stop(iicbus);
446         return (err);
447 }
448
449 static int
450 smi_write_locked(struct rtl8366rb_softc *sc, uint16_t addr, uint16_t data, int sleep)
451 {
452         int err;
453         device_t iicbus = device_get_parent(sc->dev);
454         char bytes[4];
455         int xferd;
456
457         RTL_SMI_ACQUIRED_ASSERT(sc);
458         bytes[0] = addr & 0xff;
459         bytes[1] = (addr >> 8) & 0xff;
460         bytes[2] = data & 0xff;
461         bytes[3] = (data >> 8) & 0xff;
462
463         err = smi_select(sc->dev, RTL_IICBUS_WRITE, sleep);
464         if (err == 0)
465                 err = iicbus_write(iicbus, bytes, 4, &xferd, RTL_IICBUS_TIMEOUT);
466         iicbus_stop(iicbus);
467
468         return (err);
469 }
470
471 static int
472 smi_read(device_t dev, uint16_t addr, uint16_t *data, int sleep)
473 {
474         struct rtl8366rb_softc *sc = device_get_softc(dev);
475         int err;
476
477         err = smi_acquire(sc, sleep);
478         if (err != 0)
479                 return (EBUSY);
480         err = smi_read_locked(sc, addr, data, sleep);
481         smi_release(sc, sleep);
482         DEVERR(dev, err, "smi_read()=%d: addr=%04x\n", addr);
483         return (err == 0 ? 0 : EIO);
484 }
485
486 static int
487 smi_write(device_t dev, uint16_t addr, uint16_t data, int sleep)
488 {
489         struct rtl8366rb_softc *sc = device_get_softc(dev);
490         int err;
491         
492         err = smi_acquire(sc, sleep);
493         if (err != 0)
494                 return (EBUSY);
495         err = smi_write_locked(sc, addr, data, sleep);
496         smi_release(sc, sleep);
497         DEVERR(dev, err, "smi_write()=%d: addr=%04x\n", addr);
498         return (err == 0 ? 0 : EIO);
499 }
500
501 static int
502 smi_rmw(device_t dev, uint16_t addr, uint16_t mask, uint16_t data, int sleep)
503 {
504         struct rtl8366rb_softc *sc = device_get_softc(dev);
505         int err;
506         uint16_t oldv, newv;
507         
508         err = smi_acquire(sc, sleep);
509         if (err != 0)
510                 return (EBUSY);
511         if (err == 0) {
512                 err = smi_read_locked(sc, addr, &oldv, sleep);
513                 if (err == 0) {
514                         newv = oldv & ~mask;
515                         newv |= data & mask;
516                         if (newv != oldv)
517                                 err = smi_write_locked(sc, addr, newv, sleep);
518                 }
519         }
520         smi_release(sc, sleep);
521         DEVERR(dev, err, "smi_rmw()=%d: addr=%04x\n", addr);
522         return (err == 0 ? 0 : EIO);
523 }
524
525 static etherswitch_info_t *
526 rtl_getinfo(device_t dev)
527 {
528         return (&etherswitch_info);
529 }
530
531 static int
532 rtl_readreg(device_t dev, int reg)
533 {
534         uint16_t data = 0;
535
536         smi_read(dev, reg, &data, RTL_WAITOK);
537         return (data);
538 }
539
540 static int
541 rtl_writereg(device_t dev, int reg, int value)
542 {
543         return (smi_write(dev, reg, value, RTL_WAITOK));
544 }
545
546 static int
547 rtl_getport(device_t dev, etherswitch_port_t *p)
548 {
549         struct rtl8366rb_softc *sc;
550         struct ifmedia *ifm;
551         struct mii_data *mii;
552         struct ifmediareq *ifmr = &p->es_ifmr;
553         uint16_t v;
554         int err, vlangroup;
555         
556         if (p->es_port < 0 || p->es_port >= RTL8366RB_NUM_PORTS)
557                 return (ENXIO);
558         sc = device_get_softc(dev);
559         vlangroup = RTL8366RB_PVCR_GET(p->es_port,
560                 rtl_readreg(dev, RTL8366RB_PVCR_REG(p->es_port)));
561         p->es_pvid = sc->vid[vlangroup];
562         
563         if (p->es_port < RTL8366RB_NUM_PHYS) {
564                 mii = device_get_softc(sc->miibus[p->es_port]);
565                 ifm = &mii->mii_media;
566                 err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCGIFMEDIA);
567                 if (err)
568                         return (err);
569         } else {
570                 /* fill in fixed values for CPU port */
571                 ifmr->ifm_count = 0;
572                 smi_read(dev, RTL8366RB_PLSR_BASE + (RTL8366RB_NUM_PHYS)/2, &v, RTL_WAITOK);
573                 v = v >> (8 * ((RTL8366RB_NUM_PHYS) % 2));
574                 rtl8366rb_update_ifmedia(v, &ifmr->ifm_status, &ifmr->ifm_active);
575                 ifmr->ifm_current = ifmr->ifm_active;
576                 ifmr->ifm_mask = 0;
577                 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID;
578         }
579         return (0);
580 }
581
582 static int
583 rtl_setport(device_t dev, etherswitch_port_t *p)
584 {
585         int i, err, vlangroup;
586         struct rtl8366rb_softc *sc;
587         struct ifmedia *ifm;
588         struct mii_data *mii;
589
590         if (p->es_port < 0 || p->es_port >= RTL8366RB_NUM_PHYS)
591                 return (ENXIO);
592         sc = device_get_softc(dev);
593         vlangroup = -1;
594         for (i = 0; i < RTL8366RB_NUM_VLANS; i++) {
595                 if (sc->vid[i] == p->es_pvid) {
596                         vlangroup = i;
597                         break;
598                 }
599         }
600         if (vlangroup == -1)
601                 return (ENXIO);
602         err = smi_rmw(dev, RTL8366RB_PVCR_REG(p->es_port),
603                 RTL8366RB_PVCR_VAL(p->es_port, RTL8366RB_PVCR_PORT_MASK),
604                 RTL8366RB_PVCR_VAL(p->es_port, vlangroup), RTL_WAITOK);
605         if (err)
606                 return (err);
607         mii = device_get_softc(sc->miibus[p->es_port]);
608         ifm = &mii->mii_media;
609         err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCSIFMEDIA);
610         return (err);
611 }
612
613 static int
614 rtl_getvgroup(device_t dev, etherswitch_vlangroup_t *vg)
615 {
616         uint16_t vmcr[3];
617         int i;
618         
619         for (i=0; i<3; i++)
620                 vmcr[i] = rtl_readreg(dev, RTL8366RB_VMCR(i, vg->es_vlangroup));
621                 
622         vg->es_vid = RTL8366RB_VMCR_VID(vmcr) | ETHERSWITCH_VID_VALID;
623         vg->es_member_ports = RTL8366RB_VMCR_MEMBER(vmcr);
624         vg->es_untagged_ports = RTL8366RB_VMCR_UNTAG(vmcr);
625         vg->es_fid = RTL8366RB_VMCR_FID(vmcr);
626         return (0);
627 }
628
629 static int
630 rtl_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
631 {
632         struct rtl8366rb_softc *sc;
633         int g = vg->es_vlangroup;
634
635         sc = device_get_softc(dev);
636         sc->vid[g] = vg->es_vid;
637         rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_DOT1Q_REG, g),
638                 (vg->es_vid << RTL8366RB_VMCR_DOT1Q_VID_SHIFT) & RTL8366RB_VMCR_DOT1Q_VID_MASK);
639         rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_MU_REG, g),
640                 ((vg->es_member_ports << RTL8366RB_VMCR_MU_MEMBER_SHIFT) & RTL8366RB_VMCR_MU_MEMBER_MASK) |
641                 ((vg->es_untagged_ports << RTL8366RB_VMCR_MU_UNTAG_SHIFT) & RTL8366RB_VMCR_MU_UNTAG_MASK));
642         rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_FID_REG, g),
643                 vg->es_fid);
644         return (0);
645 }
646
647 static int
648 rtl_readphy(device_t dev, int phy, int reg)
649 {
650         struct rtl8366rb_softc *sc = device_get_softc(dev);
651         uint16_t data = 0;
652         int err, i, sleep;
653
654         if (phy < 0 || phy >= RTL8366RB_NUM_PHYS)
655                 return (ENXIO);
656         if (reg < 0 || reg >= RTL8366RB_NUM_PHY_REG)
657                 return (ENXIO);
658         sleep = RTL_WAITOK;
659         err = smi_acquire(sc, sleep);
660         if (err != 0)
661                 return (EBUSY);
662         for (i = RTL_IICBUS_RETRIES; i--; ) {
663                 err = smi_write_locked(sc, RTL8366RB_PACR, RTL8366RB_PACR_READ, sleep);
664                 if (err == 0)
665                         err = smi_write_locked(sc, RTL8366RB_PHYREG(phy, 0, reg), 0, sleep);
666                 if (err == 0) {
667                         err = smi_read_locked(sc, RTL8366RB_PADR, &data, sleep);
668                         break;
669                 }
670                 DEBUG_INCRVAR(phy_access_retries);
671                 DPRINTF(dev, "rtl_readphy(): chip not responsive, retrying %d more times\n", i);
672                 pause("rtl_readphy", RTL_IICBUS_RETRY_SLEEP);
673         }
674         smi_release(sc, sleep);
675         DEVERR(dev, err, "rtl_readphy()=%d: phy=%d.%02x\n", phy, reg);
676         return (data);
677 }
678
679 static int
680 rtl_writephy(device_t dev, int phy, int reg, int data)
681 {
682         struct rtl8366rb_softc *sc = device_get_softc(dev);
683         int err, i, sleep;
684         
685         if (phy < 0 || phy >= RTL8366RB_NUM_PHYS)
686                 return (ENXIO);
687         if (reg < 0 || reg >= RTL8366RB_NUM_PHY_REG)
688                 return (ENXIO);
689         sleep = RTL_WAITOK;
690         err = smi_acquire(sc, sleep);
691         if (err != 0)
692                 return (EBUSY);
693         for (i = RTL_IICBUS_RETRIES; i--; ) {
694                 err = smi_write_locked(sc, RTL8366RB_PACR, RTL8366RB_PACR_WRITE, sleep);
695                 if (err == 0)
696                         err = smi_write_locked(sc, RTL8366RB_PHYREG(phy, 0, reg), data, sleep);
697                 if (err == 0) {
698                         break;
699                 }
700                 DEBUG_INCRVAR(phy_access_retries);
701                 DPRINTF(dev, "rtl_writephy(): chip not responsive, retrying %d more tiems\n", i);
702                 pause("rtl_writephy", RTL_IICBUS_RETRY_SLEEP);
703         }
704         smi_release(sc, sleep);
705         DEVERR(dev, err, "rtl_writephy()=%d: phy=%d.%02x\n", phy, reg);
706         return (err == 0 ? 0 : EIO);
707 }
708
709 static int
710 rtl8366rb_ifmedia_upd(struct ifnet *ifp)
711 {
712         struct rtl8366rb_softc *sc = ifp->if_softc;
713         struct mii_data *mii = device_get_softc(sc->miibus[ifp->if_dunit]);
714         
715         mii_mediachg(mii);
716         return (0);
717 }
718
719 static void
720 rtl8366rb_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
721 {
722         struct rtl8366rb_softc *sc = ifp->if_softc;
723         struct mii_data *mii = device_get_softc(sc->miibus[ifp->if_dunit]);
724
725         mii_pollstat(mii);
726         ifmr->ifm_active = mii->mii_media_active;
727         ifmr->ifm_status = mii->mii_media_status;
728 }
729
730
731 static device_method_t rtl8366rb_methods[] = {
732         /* Device interface */
733         DEVMETHOD(device_identify,      rtl8366rb_identify),
734         DEVMETHOD(device_probe,         rtl8366rb_probe),
735         DEVMETHOD(device_attach,        rtl8366rb_attach),
736         DEVMETHOD(device_detach,        rtl8366rb_detach),
737         
738         /* bus interface */
739         DEVMETHOD(bus_add_child,        device_add_child_ordered),
740         
741         /* MII interface */
742         DEVMETHOD(miibus_readreg,       rtl_readphy),
743         DEVMETHOD(miibus_writereg,      rtl_writephy),
744
745         /* etherswitch interface */
746         DEVMETHOD(etherswitch_getinfo,  rtl_getinfo),
747         DEVMETHOD(etherswitch_readreg,  rtl_readreg),
748         DEVMETHOD(etherswitch_writereg, rtl_writereg),
749         DEVMETHOD(etherswitch_readphyreg,       rtl_readphy),
750         DEVMETHOD(etherswitch_writephyreg,      rtl_writephy),
751         DEVMETHOD(etherswitch_getport,  rtl_getport),
752         DEVMETHOD(etherswitch_setport,  rtl_setport),
753         DEVMETHOD(etherswitch_getvgroup,        rtl_getvgroup),
754         DEVMETHOD(etherswitch_setvgroup,        rtl_setvgroup),
755
756         DEVMETHOD_END
757 };
758
759 DEFINE_CLASS_0(rtl8366rb, rtl8366rb_driver, rtl8366rb_methods,
760     sizeof(struct rtl8366rb_softc));
761 static devclass_t rtl8366rb_devclass;
762
763 DRIVER_MODULE(rtl8366rb, iicbus, rtl8366rb_driver, rtl8366rb_devclass, 0, 0);
764 DRIVER_MODULE(miibus, rtl8366rb, miibus_driver, miibus_devclass, 0, 0);
765 DRIVER_MODULE(etherswitch, rtl8366rb, etherswitch_driver, etherswitch_devclass, 0, 0);
766 MODULE_VERSION(rtl8366rb, 1);
767 MODULE_DEPEND(rtl8366rb, iicbus, 1, 1, 1); /* XXX which versions? */
768 MODULE_DEPEND(rtl8366rb, miibus, 1, 1, 1); /* XXX which versions? */
769 MODULE_DEPEND(rtl8366rb, etherswitch, 1, 1, 1); /* XXX which versions? */