]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/etherswitch/rtl8366/rtl8366rb.c
Initial import of DTS files from Linux
[FreeBSD/FreeBSD.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/lock.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>
41
42 #include <net/if.h>
43 #include <net/if_var.h>
44 #include <net/ethernet.h>
45 #include <net/if_media.h>
46 #include <net/if_types.h>
47
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>
54
55 #include <dev/etherswitch/etherswitch.h>
56 #include <dev/etherswitch/rtl8366/rtl8366rbvar.h>
57
58 #include "iicbus_if.h"
59 #include "miibus_if.h"
60 #include "etherswitch_if.h"
61
62
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 */
67         device_t        dev;
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;
73 };
74
75 static etherswitch_info_t etherswitch_info = {
76         .es_nports =            RTL8366RB_NUM_PORTS,
77         .es_nvlangroups =       RTL8366RB_NUM_VLANS,
78         .es_name =                      "Realtek RTL8366RB"
79 };
80
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)
85
86 #define RTL_WAITOK      0
87 #define RTL_NOWAIT      1
88
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__))
92
93 #if defined(DEBUG)
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); \
97         } while (0)
98 #define DEBUG_INCRVAR(var)      do { \
99                 var++; \
100         } while (0)
101
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");
112 #else
113 #define DPRINTF(dev, args...)
114 #define DEVERR(dev, err, fmt, args...)
115 #define DEBUG_INCRVAR(var)
116 #endif
117
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 *);
125
126 static void
127 rtl8366rb_identify(driver_t *driver, device_t parent)
128 {
129         device_t child;
130         struct iicbus_ivar *devi;
131
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;
136         }
137 }
138
139 static int
140 rtl8366rb_probe(device_t dev)
141 {
142         if (smi_probe(dev) != 0)
143                 return (ENXIO);
144         device_set_desc(dev, "RTL8366RB Ethernet Switch Controller");
145         return (BUS_PROBE_DEFAULT);
146 }
147
148 static void
149 rtl8366rb_init(device_t dev)
150 {
151         /* Initialisation for TL-WR1043ND */
152         smi_rmw(dev, RTL8366RB_RCR,
153                 RTL8366RB_RCR_HARD_RESET,
154                 RTL8366RB_RCR_HARD_RESET, RTL_WAITOK);
155         DELAY(100000);
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)),
169                 RTL_WAITOK);
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);
174 }
175
176 static int
177 rtl8366rb_attach(device_t dev)
178 {
179         uint16_t rev = 0;
180         struct rtl8366rb_softc *sc;
181         char name[IFNAMSIZ];
182         int err = 0;
183         int i;
184
185         sc = device_get_softc(dev);
186         bzero(sc, sizeof(*sc));
187         sc->dev = dev;
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);
191
192         rtl8366rb_init(dev);
193         smi_read(dev, RTL8366RB_CVCR, &rev, RTL_WAITOK);
194         device_printf(dev, "rev. %d\n", rev & 0x000f);
195
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
202                         | IFF_SIMPLEX;
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);
210                 if (err != 0) {
211                         device_printf(dev, "attaching PHY %d failed\n", i);
212                         return (err);
213                 }
214         }
215
216         bus_generic_probe(dev);
217         bus_enumerate_hinted_children(dev);
218         err = bus_generic_attach(dev);
219         if (err != 0)
220                 return (err);
221         
222         callout_init_mtx(&sc->callout_tick, &sc->callout_mtx, 0);
223         rtl8366rb_tick(sc);
224         
225         return (err);
226 }
227
228 static int
229 rtl8366rb_detach(device_t dev)
230 {
231         struct rtl8366rb_softc *sc = device_get_softc(dev);
232         int i;
233
234         for (i=0; i < RTL8366RB_NUM_PHYS; i++) {
235                 if (sc->miibus[i])
236                         device_delete_child(dev, sc->miibus[i]);
237                 if (sc->ifp[i] != NULL)
238                         if_free(sc->ifp[i]);
239                 free(sc->ifname[i], M_DEVBUF);
240         }
241         bus_generic_detach(dev);
242         callout_drain(&sc->callout_tick);
243         mtx_destroy(&sc->callout_mtx);
244         mtx_destroy(&sc->sc_mtx);
245
246         return (0);
247 }
248
249 static void
250 rtl8366rb_update_ifmedia(int portstatus, u_int *media_status, u_int *media_active)
251 {
252         *media_active = IFM_ETHER;
253         *media_status = IFM_AVALID;
254         if ((portstatus & RTL8366RB_PLSR_LINK) != 0)
255                 *media_status |= IFM_ACTIVE;
256         else {
257                 *media_active |= IFM_NONE;
258                 return;
259         }
260         switch (portstatus & RTL8366RB_PLSR_SPEED_MASK) {
261         case RTL8366RB_PLSR_SPEED_10:
262                 *media_active |= IFM_10_T;
263                 break;
264         case RTL8366RB_PLSR_SPEED_100:
265                 *media_active |= IFM_100_TX;
266                 break;
267         case RTL8366RB_PLSR_SPEED_1000:
268                 *media_active |= IFM_1000_T;
269                 break;
270         }
271         if ((portstatus & RTL8366RB_PLSR_FULLDUPLEX) == 0)
272                 *media_active |= IFM_FDX;
273         else
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;
279 }
280
281 static void
282 rtl833rb_miipollstat(struct rtl8366rb_softc *sc)
283 {
284         int i;
285         struct mii_data *mii;
286         struct mii_softc *miisc;
287         uint16_t value;
288         int portstatus;
289
290         for (i = 0; i < RTL8366RB_NUM_PHYS; i++) {
291                 mii = device_get_softc(sc->miibus[i]);
292                 if ((i % 2) == 0) {
293                         if (smi_read(sc->dev, RTL8366RB_PLSR_BASE + i/2, &value, RTL_NOWAIT) != 0) {
294                                 DEBUG_INCRVAR(callout_blocked);
295                                 return;
296                         }
297                         portstatus = value & 0xff;
298                 } else {
299                         portstatus = (value >> 8) & 0xff;
300                 }
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)
304                                 continue;
305                         mii_phy_update(miisc, MII_POLLSTAT);
306                 }
307         }       
308 }
309
310 static void
311 rtl8366rb_tick(void *arg)
312 {
313         struct rtl8366rb_softc *sc = arg;
314
315         rtl833rb_miipollstat(sc);
316         callout_reset(&sc->callout_tick, hz, rtl8366rb_tick, sc);
317 }
318
319 static int
320 smi_probe(device_t dev)
321 {
322         device_t iicbus, iicha;
323         int err, i;
324         uint16_t chipid;
325         char bytes[2];
326         int xferd;
327
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);
333         for (i=3; i--; ) {
334                 IICBUS_STOP(iicha);
335                 /*
336                  * we go directly to the host adapter because iicbus.c
337                  * only issues a stop on a bus that was successfully started.
338                  */
339         }
340         err = iicbus_request_bus(iicbus, dev, IIC_WAIT);
341         if (err != 0)
342                 goto out;
343         err = iicbus_start(iicbus, RTL8366RB_IIC_ADDR | RTL_IICBUS_READ, RTL_IICBUS_TIMEOUT);
344         if (err != 0)
345                 goto out;
346         err = iicbus_write(iicbus, bytes, 2, &xferd, RTL_IICBUS_TIMEOUT);
347         if (err != 0)
348                 goto out;
349         err = iicbus_read(iicbus, bytes, 2, &xferd, IIC_LAST_READ, 0);
350         if (err != 0)
351                 goto out;
352         chipid = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
353         DPRINTF(dev, "chip id 0x%04x\n", chipid);
354         if (chipid != RTL8366RB_CIR_ID8366RB)
355                 err = ENXIO;
356 out:
357         iicbus_stop(iicbus);
358         iicbus_release_bus(iicbus, dev);
359         return (err == 0 ? 0 : ENXIO);
360 }
361
362 static int
363 smi_acquire(struct rtl8366rb_softc *sc, int sleep)
364 {
365         int r = 0;
366         if (sleep == RTL_WAITOK)
367                 RTL_LOCK(sc);
368         else
369                 if (RTL_TRYLOCK(sc) == 0)
370                         return (EWOULDBLOCK);
371         if (sc->smi_acquired == RTL_SMI_ACQUIRED)
372                 r = EBUSY;
373         else {
374                 r = iicbus_request_bus(device_get_parent(sc->dev), sc->dev, \
375                         sleep == RTL_WAITOK ? IIC_WAIT : IIC_DONTWAIT);
376                 if (r == 0)
377                         sc->smi_acquired = RTL_SMI_ACQUIRED;
378         }
379         RTL_UNLOCK(sc);
380         return (r);
381 }
382
383 static int
384 smi_release(struct rtl8366rb_softc *sc, int sleep)
385 {
386         if (sleep == RTL_WAITOK)
387                 RTL_LOCK(sc);
388         else
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;
394         RTL_UNLOCK(sc);
395         return (0);
396 }
397
398 static int
399 smi_select(device_t dev, int op, int sleep)
400 {
401         int err, i;
402         device_t iicbus = device_get_parent(dev);
403         struct iicbus_ivar *devi = IICBUS_IVAR(dev);
404         int slave = devi->addr;
405
406         RTL_SMI_ACQUIRED_ASSERT((struct rtl8366rb_softc *)device_get_softc(dev));
407         /*
408          * The chip does not use clock stretching when it is busy,
409          * instead ignoring the command. Retry a few times.
410          */
411         for (i = RTL_IICBUS_RETRIES; i--; ) {
412                 err = iicbus_start(iicbus, slave | op, RTL_IICBUS_TIMEOUT);
413                 if (err != IIC_ENOACK)
414                         break;
415                 if (sleep == RTL_WAITOK) {
416                         DEBUG_INCRVAR(iic_select_retries);
417                         pause("smi_select", RTL_IICBUS_RETRY_SLEEP);
418                 } else
419                         break;
420         }
421         return (err);
422 }
423
424 static int
425 smi_read_locked(struct rtl8366rb_softc *sc, uint16_t addr, uint16_t *data, int sleep)
426 {
427         int err;
428         device_t iicbus = device_get_parent(sc->dev);
429         char bytes[2];
430         int xferd;
431
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);
436         if (err != 0)
437                 goto out;
438         err = iicbus_write(iicbus, bytes, 2, &xferd, RTL_IICBUS_TIMEOUT);
439         if (err != 0)
440                 goto out;
441         err = iicbus_read(iicbus, bytes, 2, &xferd, IIC_LAST_READ, 0);
442         if (err != 0)
443                 goto out;
444         *data = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
445
446 out:
447         iicbus_stop(iicbus);
448         return (err);
449 }
450
451 static int
452 smi_write_locked(struct rtl8366rb_softc *sc, uint16_t addr, uint16_t data, int sleep)
453 {
454         int err;
455         device_t iicbus = device_get_parent(sc->dev);
456         char bytes[4];
457         int xferd;
458
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;
464
465         err = smi_select(sc->dev, RTL_IICBUS_WRITE, sleep);
466         if (err == 0)
467                 err = iicbus_write(iicbus, bytes, 4, &xferd, RTL_IICBUS_TIMEOUT);
468         iicbus_stop(iicbus);
469
470         return (err);
471 }
472
473 static int
474 smi_read(device_t dev, uint16_t addr, uint16_t *data, int sleep)
475 {
476         struct rtl8366rb_softc *sc = device_get_softc(dev);
477         int err;
478
479         err = smi_acquire(sc, sleep);
480         if (err != 0)
481                 return (EBUSY);
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);
486 }
487
488 static int
489 smi_write(device_t dev, uint16_t addr, uint16_t data, int sleep)
490 {
491         struct rtl8366rb_softc *sc = device_get_softc(dev);
492         int err;
493         
494         err = smi_acquire(sc, sleep);
495         if (err != 0)
496                 return (EBUSY);
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);
501 }
502
503 static int
504 smi_rmw(device_t dev, uint16_t addr, uint16_t mask, uint16_t data, int sleep)
505 {
506         struct rtl8366rb_softc *sc = device_get_softc(dev);
507         int err;
508         uint16_t oldv, newv;
509         
510         err = smi_acquire(sc, sleep);
511         if (err != 0)
512                 return (EBUSY);
513         if (err == 0) {
514                 err = smi_read_locked(sc, addr, &oldv, sleep);
515                 if (err == 0) {
516                         newv = oldv & ~mask;
517                         newv |= data & mask;
518                         if (newv != oldv)
519                                 err = smi_write_locked(sc, addr, newv, sleep);
520                 }
521         }
522         smi_release(sc, sleep);
523         DEVERR(dev, err, "smi_rmw()=%d: addr=%04x\n", addr);
524         return (err == 0 ? 0 : EIO);
525 }
526
527 static etherswitch_info_t *
528 rtl_getinfo(device_t dev)
529 {
530         return (&etherswitch_info);
531 }
532
533 static int
534 rtl_readreg(device_t dev, int reg)
535 {
536         uint16_t data = 0;
537
538         smi_read(dev, reg, &data, RTL_WAITOK);
539         return (data);
540 }
541
542 static int
543 rtl_writereg(device_t dev, int reg, int value)
544 {
545         return (smi_write(dev, reg, value, RTL_WAITOK));
546 }
547
548 static int
549 rtl_getport(device_t dev, etherswitch_port_t *p)
550 {
551         struct rtl8366rb_softc *sc;
552         struct ifmedia *ifm;
553         struct mii_data *mii;
554         struct ifmediareq *ifmr = &p->es_ifmr;
555         uint16_t v;
556         int err, vlangroup;
557         
558         if (p->es_port < 0 || p->es_port >= RTL8366RB_NUM_PORTS)
559                 return (ENXIO);
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];
564         
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);
569                 if (err)
570                         return (err);
571         } else {
572                 /* fill in fixed values for CPU port */
573                 ifmr->ifm_count = 0;
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;
578                 ifmr->ifm_mask = 0;
579                 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID;
580         }
581         return (0);
582 }
583
584 static int
585 rtl_setport(device_t dev, etherswitch_port_t *p)
586 {
587         int i, err, vlangroup;
588         struct rtl8366rb_softc *sc;
589         struct ifmedia *ifm;
590         struct mii_data *mii;
591
592         if (p->es_port < 0 || p->es_port >= RTL8366RB_NUM_PHYS)
593                 return (ENXIO);
594         sc = device_get_softc(dev);
595         vlangroup = -1;
596         for (i = 0; i < RTL8366RB_NUM_VLANS; i++) {
597                 if (sc->vid[i] == p->es_pvid) {
598                         vlangroup = i;
599                         break;
600                 }
601         }
602         if (vlangroup == -1)
603                 return (ENXIO);
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);
607         if (err)
608                 return (err);
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);
612         return (err);
613 }
614
615 static int
616 rtl_getvgroup(device_t dev, etherswitch_vlangroup_t *vg)
617 {
618         uint16_t vmcr[3];
619         int i;
620         
621         for (i=0; i<3; i++)
622                 vmcr[i] = rtl_readreg(dev, RTL8366RB_VMCR(i, vg->es_vlangroup));
623                 
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);
628         return (0);
629 }
630
631 static int
632 rtl_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
633 {
634         struct rtl8366rb_softc *sc;
635         int g = vg->es_vlangroup;
636
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),
645                 vg->es_fid);
646         return (0);
647 }
648
649 static int
650 rtl_readphy(device_t dev, int phy, int reg)
651 {
652         struct rtl8366rb_softc *sc = device_get_softc(dev);
653         uint16_t data = 0;
654         int err, i, sleep;
655
656         if (phy < 0 || phy >= RTL8366RB_NUM_PHYS)
657                 return (ENXIO);
658         if (reg < 0 || reg >= RTL8366RB_NUM_PHY_REG)
659                 return (ENXIO);
660         sleep = RTL_WAITOK;
661         err = smi_acquire(sc, sleep);
662         if (err != 0)
663                 return (EBUSY);
664         for (i = RTL_IICBUS_RETRIES; i--; ) {
665                 err = smi_write_locked(sc, RTL8366RB_PACR, RTL8366RB_PACR_READ, sleep);
666                 if (err == 0)
667                         err = smi_write_locked(sc, RTL8366RB_PHYREG(phy, 0, reg), 0, sleep);
668                 if (err == 0) {
669                         err = smi_read_locked(sc, RTL8366RB_PADR, &data, sleep);
670                         break;
671                 }
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);
675         }
676         smi_release(sc, sleep);
677         DEVERR(dev, err, "rtl_readphy()=%d: phy=%d.%02x\n", phy, reg);
678         return (data);
679 }
680
681 static int
682 rtl_writephy(device_t dev, int phy, int reg, int data)
683 {
684         struct rtl8366rb_softc *sc = device_get_softc(dev);
685         int err, i, sleep;
686         
687         if (phy < 0 || phy >= RTL8366RB_NUM_PHYS)
688                 return (ENXIO);
689         if (reg < 0 || reg >= RTL8366RB_NUM_PHY_REG)
690                 return (ENXIO);
691         sleep = RTL_WAITOK;
692         err = smi_acquire(sc, sleep);
693         if (err != 0)
694                 return (EBUSY);
695         for (i = RTL_IICBUS_RETRIES; i--; ) {
696                 err = smi_write_locked(sc, RTL8366RB_PACR, RTL8366RB_PACR_WRITE, sleep);
697                 if (err == 0)
698                         err = smi_write_locked(sc, RTL8366RB_PHYREG(phy, 0, reg), data, sleep);
699                 if (err == 0) {
700                         break;
701                 }
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);
705         }
706         smi_release(sc, sleep);
707         DEVERR(dev, err, "rtl_writephy()=%d: phy=%d.%02x\n", phy, reg);
708         return (err == 0 ? 0 : EIO);
709 }
710
711 static int
712 rtl8366rb_ifmedia_upd(struct ifnet *ifp)
713 {
714         struct rtl8366rb_softc *sc = ifp->if_softc;
715         struct mii_data *mii = device_get_softc(sc->miibus[ifp->if_dunit]);
716         
717         mii_mediachg(mii);
718         return (0);
719 }
720
721 static void
722 rtl8366rb_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
723 {
724         struct rtl8366rb_softc *sc = ifp->if_softc;
725         struct mii_data *mii = device_get_softc(sc->miibus[ifp->if_dunit]);
726
727         mii_pollstat(mii);
728         ifmr->ifm_active = mii->mii_media_active;
729         ifmr->ifm_status = mii->mii_media_status;
730 }
731
732
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),
739         
740         /* bus interface */
741         DEVMETHOD(bus_add_child,        device_add_child_ordered),
742         
743         /* MII interface */
744         DEVMETHOD(miibus_readreg,       rtl_readphy),
745         DEVMETHOD(miibus_writereg,      rtl_writephy),
746
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),
757
758         DEVMETHOD_END
759 };
760
761 DEFINE_CLASS_0(rtl8366rb, rtl8366rb_driver, rtl8366rb_methods,
762     sizeof(struct rtl8366rb_softc));
763 static devclass_t rtl8366rb_devclass;
764
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? */