]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/etherswitch/rtl8366/rtl8366rb.c
MFV r355890:
[FreeBSD/FreeBSD.git] / sys / dev / etherswitch / rtl8366 / rtl8366rb.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2015-2016 Hiroki Mori.
5  * Copyright (c) 2011-2012 Stefan Bethke.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31
32 #include "opt_etherswitch.h"
33
34 #include <sys/param.h>
35 #include <sys/bus.h>
36 #include <sys/errno.h>
37 #include <sys/kernel.h>
38 #include <sys/lock.h>
39 #include <sys/malloc.h>
40 #include <sys/module.h>
41 #include <sys/mutex.h>
42 #include <sys/socket.h>
43 #include <sys/sockio.h>
44 #include <sys/sysctl.h>
45 #include <sys/systm.h>
46
47 #include <net/if.h>
48 #include <net/if_var.h>
49 #include <net/ethernet.h>
50 #include <net/if_media.h>
51 #include <net/if_types.h>
52
53 #include <machine/bus.h>
54 #include <dev/iicbus/iic.h>
55 #include <dev/iicbus/iiconf.h>
56 #include <dev/iicbus/iicbus.h>
57 #include <dev/mii/mii.h>
58 #include <dev/mii/miivar.h>
59 #include <dev/mdio/mdio.h>
60
61 #include <dev/etherswitch/etherswitch.h>
62 #include <dev/etherswitch/rtl8366/rtl8366rbvar.h>
63
64 #include "mdio_if.h"
65 #include "iicbus_if.h"
66 #include "miibus_if.h"
67 #include "etherswitch_if.h"
68
69
70 struct rtl8366rb_softc {
71         struct mtx      sc_mtx;         /* serialize access to softc */
72         int             smi_acquired;   /* serialize access to SMI/I2C bus */
73         struct mtx      callout_mtx;    /* serialize callout */
74         device_t        dev;
75         int             vid[RTL8366_NUM_VLANS];
76         char            *ifname[RTL8366_NUM_PHYS];
77         device_t        miibus[RTL8366_NUM_PHYS];
78         struct ifnet    *ifp[RTL8366_NUM_PHYS];
79         struct callout  callout_tick;
80         etherswitch_info_t      info;
81         int             chip_type;
82         int             phy4cpu;
83         int             numphys;
84 };
85
86 #define RTL_LOCK(_sc)   mtx_lock(&(_sc)->sc_mtx)
87 #define RTL_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
88 #define RTL_LOCK_ASSERT(_sc, _what)     mtx_assert(&(_s)c->sc_mtx, (_what))
89 #define RTL_TRYLOCK(_sc)        mtx_trylock(&(_sc)->sc_mtx)
90
91 #define RTL_WAITOK      0
92 #define RTL_NOWAIT      1
93
94 #define RTL_SMI_ACQUIRED        1
95 #define RTL_SMI_ACQUIRED_ASSERT(_sc) \
96         KASSERT((_sc)->smi_acquired == RTL_SMI_ACQUIRED, ("smi must be acquired @%s", __FUNCTION__))
97
98 #if defined(DEBUG)
99 #define DPRINTF(dev, args...) device_printf(dev, args)
100 #define DEVERR(dev, err, fmt, args...) do { \
101                 if (err != 0) device_printf(dev, fmt, err, args); \
102         } while (0)
103 #define DEBUG_INCRVAR(var)      do { \
104                 var++; \
105         } while (0)
106
107 static int callout_blocked = 0;
108 static int iic_select_retries = 0;
109 static int phy_access_retries = 0;
110 static SYSCTL_NODE(_debug, OID_AUTO, rtl8366rb, CTLFLAG_RD, 0, "rtl8366rb");
111 SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, callout_blocked, CTLFLAG_RW, &callout_blocked, 0,
112         "number of times the callout couldn't acquire the bus");
113 SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, iic_select_retries, CTLFLAG_RW, &iic_select_retries, 0,
114         "number of times the I2C bus selection had to be retried");
115 SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, phy_access_retries, CTLFLAG_RW, &phy_access_retries, 0,
116         "number of times PHY register access had to be retried");
117 #else
118 #define DPRINTF(dev, args...)
119 #define DEVERR(dev, err, fmt, args...)
120 #define DEBUG_INCRVAR(var)
121 #endif
122
123 static int smi_probe(device_t dev);
124 static int smi_read(device_t dev, uint16_t addr, uint16_t *data, int sleep);
125 static int smi_write(device_t dev, uint16_t addr, uint16_t data, int sleep);
126 static int smi_rmw(device_t dev, uint16_t addr, uint16_t mask, uint16_t data, int sleep);
127 static void rtl8366rb_tick(void *arg);
128 static int rtl8366rb_ifmedia_upd(struct ifnet *);
129 static void rtl8366rb_ifmedia_sts(struct ifnet *, struct ifmediareq *);
130
131 static void
132 rtl8366rb_identify(driver_t *driver, device_t parent)
133 {
134         device_t child;
135         struct iicbus_ivar *devi;
136
137         if (device_find_child(parent, "rtl8366rb", -1) == NULL) {
138                 child = BUS_ADD_CHILD(parent, 0, "rtl8366rb", -1);
139                 devi = IICBUS_IVAR(child);
140                 devi->addr = RTL8366_IIC_ADDR;
141         }
142 }
143
144 static int
145 rtl8366rb_probe(device_t dev)
146 {
147         struct rtl8366rb_softc *sc;
148
149         sc = device_get_softc(dev);
150
151         bzero(sc, sizeof(*sc));
152         if (smi_probe(dev) != 0)
153                 return (ENXIO);
154         if (sc->chip_type == RTL8366RB)
155                 device_set_desc(dev, "RTL8366RB Ethernet Switch Controller");
156         else
157                 device_set_desc(dev, "RTL8366SR Ethernet Switch Controller");
158         return (BUS_PROBE_DEFAULT);
159 }
160
161 static void
162 rtl8366rb_init(device_t dev)
163 {
164         struct rtl8366rb_softc *sc;
165         int i;
166
167         sc = device_get_softc(dev);
168
169         /* Initialisation for TL-WR1043ND */
170 #ifdef RTL8366_SOFT_RESET
171         smi_rmw(dev, RTL8366_RCR,
172                 RTL8366_RCR_SOFT_RESET,
173                 RTL8366_RCR_SOFT_RESET, RTL_WAITOK);
174 #else
175         smi_rmw(dev, RTL8366_RCR,
176                 RTL8366_RCR_HARD_RESET,
177                 RTL8366_RCR_HARD_RESET, RTL_WAITOK);
178 #endif
179         /* hard reset not return ack */
180         DELAY(100000);
181         /* Enable 16 VLAN mode */
182         smi_rmw(dev, RTL8366_SGCR,
183                 RTL8366_SGCR_EN_VLAN | RTL8366_SGCR_EN_VLAN_4KTB,
184                 RTL8366_SGCR_EN_VLAN, RTL_WAITOK);
185         /* Initialize our vlan table. */
186         for (i = 0; i <= 1; i++)
187                 sc->vid[i] = (i + 1) | ETHERSWITCH_VID_VALID;
188         /* Remove port 0 from VLAN 1. */
189         smi_rmw(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, 0),
190                 (1 << 0), 0, RTL_WAITOK);
191         /* Add port 0 untagged and port 5 tagged to VLAN 2. */
192         smi_rmw(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, 1),
193                 ((1 << 5 | 1 << 0) << RTL8366_VMCR_MU_MEMBER_SHIFT)
194                         | ((1 << 5 | 1 << 0) << RTL8366_VMCR_MU_UNTAG_SHIFT),
195                 ((1 << 5 | 1 << 0) << RTL8366_VMCR_MU_MEMBER_SHIFT
196                         | ((1 << 0) << RTL8366_VMCR_MU_UNTAG_SHIFT)),
197                 RTL_WAITOK);
198         /* Set PVID 2 for port 0. */
199         smi_rmw(dev, RTL8366_PVCR_REG(0),
200                 RTL8366_PVCR_VAL(0, RTL8366_PVCR_PORT_MASK),
201                 RTL8366_PVCR_VAL(0, 1), RTL_WAITOK);
202 }
203
204 static int
205 rtl8366rb_attach(device_t dev)
206 {
207         struct rtl8366rb_softc *sc;
208         uint16_t rev = 0;
209         char name[IFNAMSIZ];
210         int err = 0;
211         int i;
212
213         sc = device_get_softc(dev);
214
215         sc->dev = dev;
216         mtx_init(&sc->sc_mtx, "rtl8366rb", NULL, MTX_DEF);
217         sc->smi_acquired = 0;
218         mtx_init(&sc->callout_mtx, "rtl8366rbcallout", NULL, MTX_DEF);
219
220         rtl8366rb_init(dev);
221         smi_read(dev, RTL8366_CVCR, &rev, RTL_WAITOK);
222         device_printf(dev, "rev. %d\n", rev & 0x000f);
223
224         sc->phy4cpu = 0;
225         (void) resource_int_value(device_get_name(dev), device_get_unit(dev),
226             "phy4cpu", &sc->phy4cpu);
227
228         sc->numphys = sc->phy4cpu ? RTL8366_NUM_PHYS - 1 : RTL8366_NUM_PHYS;
229
230         sc->info.es_nports = sc->numphys + 1;
231         sc->info.es_nvlangroups = RTL8366_NUM_VLANS;
232         sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q;
233         if (sc->chip_type == RTL8366RB)
234                 sprintf(sc->info.es_name, "Realtek RTL8366RB");
235         else
236                 sprintf(sc->info.es_name, "Realtek RTL8366SR");
237
238         /* attach miibus and phys */
239         /* PHYs need an interface, so we generate a dummy one */
240         for (i = 0; i < sc->numphys; i++) {
241                 sc->ifp[i] = if_alloc(IFT_ETHER);
242                 if (sc->ifp[i] == NULL) {
243                         device_printf(dev, "couldn't allocate ifnet structure\n");
244                         err = ENOMEM;
245                         break;
246                 }
247
248                 sc->ifp[i]->if_softc = sc;
249                 sc->ifp[i]->if_flags |= IFF_UP | IFF_BROADCAST | IFF_DRV_RUNNING
250                         | IFF_SIMPLEX;
251                 snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(dev));
252                 sc->ifname[i] = malloc(strlen(name)+1, M_DEVBUF, M_WAITOK);
253                 bcopy(name, sc->ifname[i], strlen(name)+1);
254                 if_initname(sc->ifp[i], sc->ifname[i], i);
255                 err = mii_attach(dev, &sc->miibus[i], sc->ifp[i], rtl8366rb_ifmedia_upd, \
256                         rtl8366rb_ifmedia_sts, BMSR_DEFCAPMASK, \
257                         i, MII_OFFSET_ANY, 0);
258                 if (err != 0) {
259                         device_printf(dev, "attaching PHY %d failed\n", i);
260                         return (err);
261                 }
262         }
263
264         bus_generic_probe(dev);
265         bus_enumerate_hinted_children(dev);
266         err = bus_generic_attach(dev);
267         if (err != 0)
268                 return (err);
269         
270         callout_init_mtx(&sc->callout_tick, &sc->callout_mtx, 0);
271         rtl8366rb_tick(sc);
272         
273         return (err);
274 }
275
276 static int
277 rtl8366rb_detach(device_t dev)
278 {
279         struct rtl8366rb_softc *sc;
280         int i;
281
282         sc = device_get_softc(dev);
283
284         for (i=0; i < sc->numphys; i++) {
285                 if (sc->miibus[i])
286                         device_delete_child(dev, sc->miibus[i]);
287                 if (sc->ifp[i] != NULL)
288                         if_free(sc->ifp[i]);
289                 free(sc->ifname[i], M_DEVBUF);
290         }
291         bus_generic_detach(dev);
292         callout_drain(&sc->callout_tick);
293         mtx_destroy(&sc->callout_mtx);
294         mtx_destroy(&sc->sc_mtx);
295
296         return (0);
297 }
298
299 static void
300 rtl8366rb_update_ifmedia(int portstatus, u_int *media_status, u_int *media_active)
301 {
302         *media_active = IFM_ETHER;
303         *media_status = IFM_AVALID;
304         if ((portstatus & RTL8366_PLSR_LINK) != 0)
305                 *media_status |= IFM_ACTIVE;
306         else {
307                 *media_active |= IFM_NONE;
308                 return;
309         }
310         switch (portstatus & RTL8366_PLSR_SPEED_MASK) {
311         case RTL8366_PLSR_SPEED_10:
312                 *media_active |= IFM_10_T;
313                 break;
314         case RTL8366_PLSR_SPEED_100:
315                 *media_active |= IFM_100_TX;
316                 break;
317         case RTL8366_PLSR_SPEED_1000:
318                 *media_active |= IFM_1000_T;
319                 break;
320         }
321         if ((portstatus & RTL8366_PLSR_FULLDUPLEX) != 0)
322                 *media_active |= IFM_FDX;
323         else
324                 *media_active |= IFM_HDX;
325         if ((portstatus & RTL8366_PLSR_TXPAUSE) != 0)
326                 *media_active |= IFM_ETH_TXPAUSE;
327         if ((portstatus & RTL8366_PLSR_RXPAUSE) != 0)
328                 *media_active |= IFM_ETH_RXPAUSE;
329 }
330
331 static void
332 rtl833rb_miipollstat(struct rtl8366rb_softc *sc)
333 {
334         int i;
335         struct mii_data *mii;
336         struct mii_softc *miisc;
337         uint16_t value;
338         int portstatus;
339
340         for (i = 0; i < sc->numphys; i++) {
341                 mii = device_get_softc(sc->miibus[i]);
342                 if ((i % 2) == 0) {
343                         if (smi_read(sc->dev, RTL8366_PLSR_BASE + i/2, &value, RTL_NOWAIT) != 0) {
344                                 DEBUG_INCRVAR(callout_blocked);
345                                 return;
346                         }
347                         portstatus = value & 0xff;
348                 } else {
349                         portstatus = (value >> 8) & 0xff;
350                 }
351                 rtl8366rb_update_ifmedia(portstatus, &mii->mii_media_status, &mii->mii_media_active);
352                 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) {
353                         if (IFM_INST(mii->mii_media.ifm_cur->ifm_media) != miisc->mii_inst)
354                                 continue;
355                         mii_phy_update(miisc, MII_POLLSTAT);
356                 }
357         }       
358 }
359
360 static void
361 rtl8366rb_tick(void *arg)
362 {
363         struct rtl8366rb_softc *sc;
364
365         sc = arg;
366
367         rtl833rb_miipollstat(sc);
368         callout_reset(&sc->callout_tick, hz, rtl8366rb_tick, sc);
369 }
370
371 static int
372 smi_probe(device_t dev)
373 {
374         struct rtl8366rb_softc *sc;
375         device_t iicbus, iicha;
376         int err, i, j;
377         uint16_t chipid;
378         char bytes[2];
379         int xferd;
380
381         sc = device_get_softc(dev);
382
383         iicbus = device_get_parent(dev);
384         iicha = device_get_parent(iicbus);
385
386         for (i = 0; i < 2; ++i) {
387                 iicbus_reset(iicbus, IIC_FASTEST, RTL8366_IIC_ADDR, NULL);
388                 for (j=3; j--; ) {
389                         IICBUS_STOP(iicha);
390                         /*
391                          * we go directly to the host adapter because iicbus.c
392                          * only issues a stop on a bus that was successfully started.
393                          */
394                 }
395                 err = iicbus_request_bus(iicbus, dev, IIC_WAIT);
396                 if (err != 0)
397                         goto out;
398                 err = iicbus_start(iicbus, RTL8366_IIC_ADDR | RTL_IICBUS_READ, RTL_IICBUS_TIMEOUT);
399                 if (err != 0)
400                         goto out;
401                 if (i == 0) {
402                         bytes[0] = RTL8366RB_CIR & 0xff;
403                         bytes[1] = (RTL8366RB_CIR >> 8) & 0xff;
404                 } else {
405                         bytes[0] = RTL8366SR_CIR & 0xff;
406                         bytes[1] = (RTL8366SR_CIR >> 8) & 0xff;
407                 }
408                 err = iicbus_write(iicbus, bytes, 2, &xferd, RTL_IICBUS_TIMEOUT);
409                 if (err != 0)
410                         goto out;
411                 err = iicbus_read(iicbus, bytes, 2, &xferd, IIC_LAST_READ, 0);
412                 if (err != 0)
413                         goto out;
414                 chipid = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
415                 if (i == 0 && chipid == RTL8366RB_CIR_ID8366RB) {
416                         DPRINTF(dev, "chip id 0x%04x\n", chipid);
417                         sc->chip_type = RTL8366RB;
418                         err = 0;
419                         break;
420                 }
421                 if (i == 1 && chipid == RTL8366SR_CIR_ID8366SR) {
422                         DPRINTF(dev, "chip id 0x%04x\n", chipid);
423                         sc->chip_type = RTL8366SR;
424                         err = 0;
425                         break;
426                 }
427                 if (i == 0) {
428                         iicbus_stop(iicbus);
429                         iicbus_release_bus(iicbus, dev);
430                 }
431         }
432         if (i == 2)
433                 err = ENXIO;
434 out:
435         iicbus_stop(iicbus);
436         iicbus_release_bus(iicbus, dev);
437         return (err == 0 ? 0 : ENXIO);
438 }
439
440 static int
441 smi_acquire(struct rtl8366rb_softc *sc, int sleep)
442 {
443         int r = 0;
444         if (sleep == RTL_WAITOK)
445                 RTL_LOCK(sc);
446         else
447                 if (RTL_TRYLOCK(sc) == 0)
448                         return (EWOULDBLOCK);
449         if (sc->smi_acquired == RTL_SMI_ACQUIRED)
450                 r = EBUSY;
451         else {
452                 r = iicbus_request_bus(device_get_parent(sc->dev), sc->dev, \
453                         sleep == RTL_WAITOK ? IIC_WAIT : IIC_DONTWAIT);
454                 if (r == 0)
455                         sc->smi_acquired = RTL_SMI_ACQUIRED;
456         }
457         RTL_UNLOCK(sc);
458         return (r);
459 }
460
461 static int
462 smi_release(struct rtl8366rb_softc *sc, int sleep)
463 {
464         if (sleep == RTL_WAITOK)
465                 RTL_LOCK(sc);
466         else
467                 if (RTL_TRYLOCK(sc) == 0)
468                         return (EWOULDBLOCK);
469         RTL_SMI_ACQUIRED_ASSERT(sc);
470         iicbus_release_bus(device_get_parent(sc->dev), sc->dev);
471         sc->smi_acquired = 0;
472         RTL_UNLOCK(sc);
473         return (0);
474 }
475
476 static int
477 smi_select(device_t dev, int op, int sleep)
478 {
479         struct rtl8366rb_softc *sc;
480         int err, i;
481         device_t iicbus;
482         struct iicbus_ivar *devi;
483         int slave;
484
485         sc = device_get_softc(dev);
486
487         iicbus = device_get_parent(dev);
488         devi = IICBUS_IVAR(dev);
489         slave = devi->addr;
490
491         RTL_SMI_ACQUIRED_ASSERT((struct rtl8366rb_softc *)device_get_softc(dev));
492
493         if (sc->chip_type == RTL8366SR) {   // RTL8366SR work around
494                 // this is same work around at probe
495                 for (int i=3; i--; )
496                         IICBUS_STOP(device_get_parent(device_get_parent(dev)));
497         }
498         /*
499          * The chip does not use clock stretching when it is busy,
500          * instead ignoring the command. Retry a few times.
501          */
502         for (i = RTL_IICBUS_RETRIES; i--; ) {
503                 err = iicbus_start(iicbus, slave | op, RTL_IICBUS_TIMEOUT);
504                 if (err != IIC_ENOACK)
505                         break;
506                 if (sleep == RTL_WAITOK) {
507                         DEBUG_INCRVAR(iic_select_retries);
508                         pause("smi_select", RTL_IICBUS_RETRY_SLEEP);
509                 } else
510                         break;
511         }
512         return (err);
513 }
514
515 static int
516 smi_read_locked(struct rtl8366rb_softc *sc, uint16_t addr, uint16_t *data, int sleep)
517 {
518         int err;
519         device_t iicbus;
520         char bytes[2];
521         int xferd;
522
523         iicbus = device_get_parent(sc->dev);
524
525         RTL_SMI_ACQUIRED_ASSERT(sc);
526         bytes[0] = addr & 0xff;
527         bytes[1] = (addr >> 8) & 0xff;
528         err = smi_select(sc->dev, RTL_IICBUS_READ, sleep);
529         if (err != 0)
530                 goto out;
531         err = iicbus_write(iicbus, bytes, 2, &xferd, RTL_IICBUS_TIMEOUT);
532         if (err != 0)
533                 goto out;
534         err = iicbus_read(iicbus, bytes, 2, &xferd, IIC_LAST_READ, 0);
535         if (err != 0)
536                 goto out;
537         *data = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
538
539 out:
540         iicbus_stop(iicbus);
541         return (err);
542 }
543
544 static int
545 smi_write_locked(struct rtl8366rb_softc *sc, uint16_t addr, uint16_t data, int sleep)
546 {
547         int err;
548         device_t iicbus;
549         char bytes[4];
550         int xferd;
551
552         iicbus = device_get_parent(sc->dev);
553
554         RTL_SMI_ACQUIRED_ASSERT(sc);
555         bytes[0] = addr & 0xff;
556         bytes[1] = (addr >> 8) & 0xff;
557         bytes[2] = data & 0xff;
558         bytes[3] = (data >> 8) & 0xff;
559
560         err = smi_select(sc->dev, RTL_IICBUS_WRITE, sleep);
561         if (err == 0)
562                 err = iicbus_write(iicbus, bytes, 4, &xferd, RTL_IICBUS_TIMEOUT);
563         iicbus_stop(iicbus);
564
565         return (err);
566 }
567
568 static int
569 smi_read(device_t dev, uint16_t addr, uint16_t *data, int sleep)
570 {
571         struct rtl8366rb_softc *sc;
572         int err;
573
574         sc = device_get_softc(dev);
575
576         err = smi_acquire(sc, sleep);
577         if (err != 0)
578                 return (EBUSY);
579         err = smi_read_locked(sc, addr, data, sleep);
580         smi_release(sc, sleep);
581         DEVERR(dev, err, "smi_read()=%d: addr=%04x\n", addr);
582         return (err == 0 ? 0 : EIO);
583 }
584
585 static int
586 smi_write(device_t dev, uint16_t addr, uint16_t data, int sleep)
587 {
588         struct rtl8366rb_softc *sc;
589         int err;
590         
591         sc = device_get_softc(dev);
592
593         err = smi_acquire(sc, sleep);
594         if (err != 0)
595                 return (EBUSY);
596         err = smi_write_locked(sc, addr, data, sleep);
597         smi_release(sc, sleep);
598         DEVERR(dev, err, "smi_write()=%d: addr=%04x\n", addr);
599         return (err == 0 ? 0 : EIO);
600 }
601
602 static int
603 smi_rmw(device_t dev, uint16_t addr, uint16_t mask, uint16_t data, int sleep)
604 {
605         struct rtl8366rb_softc *sc;
606         int err;
607         uint16_t oldv, newv;
608         
609         sc = device_get_softc(dev);
610
611         err = smi_acquire(sc, sleep);
612         if (err != 0)
613                 return (EBUSY);
614         if (err == 0) {
615                 err = smi_read_locked(sc, addr, &oldv, sleep);
616                 if (err == 0) {
617                         newv = oldv & ~mask;
618                         newv |= data & mask;
619                         if (newv != oldv)
620                                 err = smi_write_locked(sc, addr, newv, sleep);
621                 }
622         }
623         smi_release(sc, sleep);
624         DEVERR(dev, err, "smi_rmw()=%d: addr=%04x\n", addr);
625         return (err == 0 ? 0 : EIO);
626 }
627
628 static etherswitch_info_t *
629 rtl_getinfo(device_t dev)
630 {
631         struct rtl8366rb_softc *sc;
632
633         sc = device_get_softc(dev);
634
635         return (&sc->info);
636 }
637
638 static int
639 rtl_readreg(device_t dev, int reg)
640 {
641         uint16_t data;
642
643         data = 0;
644
645         smi_read(dev, reg, &data, RTL_WAITOK);
646         return (data);
647 }
648
649 static int
650 rtl_writereg(device_t dev, int reg, int value)
651 {
652         return (smi_write(dev, reg, value, RTL_WAITOK));
653 }
654
655 static int
656 rtl_getport(device_t dev, etherswitch_port_t *p)
657 {
658         struct rtl8366rb_softc *sc;
659         struct ifmedia *ifm;
660         struct mii_data *mii;
661         struct ifmediareq *ifmr;
662         uint16_t v;
663         int err, vlangroup;
664         
665         sc = device_get_softc(dev);
666
667         ifmr = &p->es_ifmr;
668
669         if (p->es_port < 0 || p->es_port >= (sc->numphys + 1))
670                 return (ENXIO);
671         if (sc->phy4cpu && p->es_port == sc->numphys) {
672                 vlangroup = RTL8366_PVCR_GET(p->es_port + 1,
673                     rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port + 1)));
674         } else {
675                 vlangroup = RTL8366_PVCR_GET(p->es_port,
676                     rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port)));
677         }
678         p->es_pvid = sc->vid[vlangroup] & ETHERSWITCH_VID_MASK;
679         
680         if (p->es_port < sc->numphys) {
681                 mii = device_get_softc(sc->miibus[p->es_port]);
682                 ifm = &mii->mii_media;
683                 err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCGIFMEDIA);
684                 if (err)
685                         return (err);
686         } else {
687                 /* fill in fixed values for CPU port */
688                 p->es_flags |= ETHERSWITCH_PORT_CPU;
689                 smi_read(dev, RTL8366_PLSR_BASE + (RTL8366_NUM_PHYS)/2, &v, RTL_WAITOK);
690                 v = v >> (8 * ((RTL8366_NUM_PHYS) % 2));
691                 rtl8366rb_update_ifmedia(v, &ifmr->ifm_status, &ifmr->ifm_active);
692                 ifmr->ifm_current = ifmr->ifm_active;
693                 ifmr->ifm_mask = 0;
694                 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID;
695                 /* Return our static media list. */
696                 if (ifmr->ifm_count > 0) {
697                         ifmr->ifm_count = 1;
698                         ifmr->ifm_ulist[0] = IFM_MAKEWORD(IFM_ETHER, IFM_1000_T,
699                             IFM_FDX, 0);
700                 } else
701                         ifmr->ifm_count = 0;
702         }
703         return (0);
704 }
705
706 static int
707 rtl_setport(device_t dev, etherswitch_port_t *p)
708 {
709         struct rtl8366rb_softc *sc;
710         int i, err, vlangroup;
711         struct ifmedia *ifm;
712         struct mii_data *mii;
713         int port;
714
715         sc = device_get_softc(dev);
716
717         if (p->es_port < 0 || p->es_port >= (sc->numphys + 1))
718                 return (ENXIO);
719         vlangroup = -1;
720         for (i = 0; i < RTL8366_NUM_VLANS; i++) {
721                 if ((sc->vid[i] & ETHERSWITCH_VID_MASK) == p->es_pvid) {
722                         vlangroup = i;
723                         break;
724                 }
725         }
726         if (vlangroup == -1)
727                 return (ENXIO);
728         if (sc->phy4cpu && p->es_port == sc->numphys) {
729                 port = p->es_port + 1;
730         } else {
731                 port = p->es_port;
732         }
733         err = smi_rmw(dev, RTL8366_PVCR_REG(port),
734             RTL8366_PVCR_VAL(port, RTL8366_PVCR_PORT_MASK),
735             RTL8366_PVCR_VAL(port, vlangroup), RTL_WAITOK);
736         if (err)
737                 return (err);
738         /* CPU Port */
739         if (p->es_port == sc->numphys)
740                 return (0);
741         mii = device_get_softc(sc->miibus[p->es_port]);
742         ifm = &mii->mii_media;
743         err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCSIFMEDIA);
744         return (err);
745 }
746
747 static int
748 rtl_getvgroup(device_t dev, etherswitch_vlangroup_t *vg)
749 {
750         struct rtl8366rb_softc *sc;
751         uint16_t vmcr[3];
752         int i;
753         int member, untagged;
754         
755         sc = device_get_softc(dev);
756
757         for (i=0; i<RTL8366_VMCR_MULT; i++)
758                 vmcr[i] = rtl_readreg(dev, RTL8366_VMCR(i, vg->es_vlangroup));
759                 
760         vg->es_vid = sc->vid[vg->es_vlangroup];
761         member = RTL8366_VMCR_MEMBER(vmcr);
762         untagged = RTL8366_VMCR_UNTAG(vmcr);
763         if (sc->phy4cpu) {
764                 vg->es_member_ports = ((member & 0x20) >> 1) | (member & 0x0f);
765                 vg->es_untagged_ports = ((untagged & 0x20) >> 1) | (untagged & 0x0f);
766         } else {
767                 vg->es_member_ports = member;
768                 vg->es_untagged_ports = untagged;
769         }
770         vg->es_fid = RTL8366_VMCR_FID(vmcr);
771         return (0);
772 }
773
774 static int
775 rtl_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
776 {
777         struct rtl8366rb_softc *sc;
778         int g;
779         int member, untagged;
780
781         sc = device_get_softc(dev);
782
783         g = vg->es_vlangroup;
784
785         sc->vid[g] = vg->es_vid;
786         /* VLAN group disabled ? */
787         if (vg->es_member_ports == 0 && vg->es_untagged_ports == 0 && vg->es_vid == 0)
788                 return (0);
789         sc->vid[g] |= ETHERSWITCH_VID_VALID;
790         rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_DOT1Q_REG, g),
791                 (vg->es_vid << RTL8366_VMCR_DOT1Q_VID_SHIFT) & RTL8366_VMCR_DOT1Q_VID_MASK);
792         if (sc->phy4cpu) {
793                 /* add space at phy4 */
794                 member = (vg->es_member_ports & 0x0f) |
795                     ((vg->es_member_ports & 0x10) << 1);
796                 untagged = (vg->es_untagged_ports & 0x0f) |
797                     ((vg->es_untagged_ports & 0x10) << 1);
798         } else {
799                 member = vg->es_member_ports;
800                 untagged = vg->es_untagged_ports;
801         }
802         if (sc->chip_type == RTL8366RB) {
803                 rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, g),
804                     ((member << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
805                     ((untagged << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK));
806                 rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_FID_REG, g),
807                     vg->es_fid);
808         } else {
809                 rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, g),
810                     ((member << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
811                     ((untagged << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK) |
812                     ((vg->es_fid << RTL8366_VMCR_FID_FID_SHIFT) & RTL8366_VMCR_FID_FID_MASK));
813         }
814         return (0);
815 }
816
817 static int
818 rtl_getconf(device_t dev, etherswitch_conf_t *conf)
819 {
820
821         /* Return the VLAN mode. */
822         conf->cmd = ETHERSWITCH_CONF_VLAN_MODE;
823         conf->vlan_mode = ETHERSWITCH_VLAN_DOT1Q;
824
825         return (0);
826 }
827
828 static int
829 rtl_readphy(device_t dev, int phy, int reg)
830 {
831         struct rtl8366rb_softc *sc;
832         uint16_t data;
833         int err, i, sleep;
834
835         sc = device_get_softc(dev);
836
837         data = 0;
838
839         if (phy < 0 || phy >= RTL8366_NUM_PHYS)
840                 return (ENXIO);
841         if (reg < 0 || reg >= RTL8366_NUM_PHY_REG)
842                 return (ENXIO);
843         sleep = RTL_WAITOK;
844         err = smi_acquire(sc, sleep);
845         if (err != 0)
846                 return (EBUSY);
847         for (i = RTL_IICBUS_RETRIES; i--; ) {
848                 err = smi_write_locked(sc, RTL8366_PACR, RTL8366_PACR_READ, sleep);
849                 if (err == 0)
850                         err = smi_write_locked(sc, RTL8366_PHYREG(phy, 0, reg), 0, sleep);
851                 if (err == 0) {
852                         err = smi_read_locked(sc, RTL8366_PADR, &data, sleep);
853                         break;
854                 }
855                 DEBUG_INCRVAR(phy_access_retries);
856                 DPRINTF(dev, "rtl_readphy(): chip not responsive, retrying %d more times\n", i);
857                 pause("rtl_readphy", RTL_IICBUS_RETRY_SLEEP);
858         }
859         smi_release(sc, sleep);
860         DEVERR(dev, err, "rtl_readphy()=%d: phy=%d.%02x\n", phy, reg);
861         return (data);
862 }
863
864 static int
865 rtl_writephy(device_t dev, int phy, int reg, int data)
866 {
867         struct rtl8366rb_softc *sc;
868         int err, i, sleep;
869         
870         sc = device_get_softc(dev);
871
872         if (phy < 0 || phy >= RTL8366_NUM_PHYS)
873                 return (ENXIO);
874         if (reg < 0 || reg >= RTL8366_NUM_PHY_REG)
875                 return (ENXIO);
876         sleep = RTL_WAITOK;
877         err = smi_acquire(sc, sleep);
878         if (err != 0)
879                 return (EBUSY);
880         for (i = RTL_IICBUS_RETRIES; i--; ) {
881                 err = smi_write_locked(sc, RTL8366_PACR, RTL8366_PACR_WRITE, sleep);
882                 if (err == 0)
883                         err = smi_write_locked(sc, RTL8366_PHYREG(phy, 0, reg), data, sleep);
884                 if (err == 0) {
885                         break;
886                 }
887                 DEBUG_INCRVAR(phy_access_retries);
888                 DPRINTF(dev, "rtl_writephy(): chip not responsive, retrying %d more tiems\n", i);
889                 pause("rtl_writephy", RTL_IICBUS_RETRY_SLEEP);
890         }
891         smi_release(sc, sleep);
892         DEVERR(dev, err, "rtl_writephy()=%d: phy=%d.%02x\n", phy, reg);
893         return (err == 0 ? 0 : EIO);
894 }
895
896 static int
897 rtl8366rb_ifmedia_upd(struct ifnet *ifp)
898 {
899         struct rtl8366rb_softc *sc;
900         struct mii_data *mii;
901         
902         sc = ifp->if_softc;
903         mii = device_get_softc(sc->miibus[ifp->if_dunit]);
904         
905         mii_mediachg(mii);
906         return (0);
907 }
908
909 static void
910 rtl8366rb_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
911 {
912         struct rtl8366rb_softc *sc;
913         struct mii_data *mii;
914
915         sc = ifp->if_softc;
916         mii = device_get_softc(sc->miibus[ifp->if_dunit]);
917
918         mii_pollstat(mii);
919         ifmr->ifm_active = mii->mii_media_active;
920         ifmr->ifm_status = mii->mii_media_status;
921 }
922
923
924 static device_method_t rtl8366rb_methods[] = {
925         /* Device interface */
926         DEVMETHOD(device_identify,      rtl8366rb_identify),
927         DEVMETHOD(device_probe,         rtl8366rb_probe),
928         DEVMETHOD(device_attach,        rtl8366rb_attach),
929         DEVMETHOD(device_detach,        rtl8366rb_detach),
930         
931         /* bus interface */
932         DEVMETHOD(bus_add_child,        device_add_child_ordered),
933         
934         /* MII interface */
935         DEVMETHOD(miibus_readreg,       rtl_readphy),
936         DEVMETHOD(miibus_writereg,      rtl_writephy),
937
938         /* MDIO interface */
939         DEVMETHOD(mdio_readreg,         rtl_readphy),
940         DEVMETHOD(mdio_writereg,        rtl_writephy),
941
942         /* etherswitch interface */
943         DEVMETHOD(etherswitch_getconf,  rtl_getconf),
944         DEVMETHOD(etherswitch_getinfo,  rtl_getinfo),
945         DEVMETHOD(etherswitch_readreg,  rtl_readreg),
946         DEVMETHOD(etherswitch_writereg, rtl_writereg),
947         DEVMETHOD(etherswitch_readphyreg,       rtl_readphy),
948         DEVMETHOD(etherswitch_writephyreg,      rtl_writephy),
949         DEVMETHOD(etherswitch_getport,  rtl_getport),
950         DEVMETHOD(etherswitch_setport,  rtl_setport),
951         DEVMETHOD(etherswitch_getvgroup,        rtl_getvgroup),
952         DEVMETHOD(etherswitch_setvgroup,        rtl_setvgroup),
953
954         DEVMETHOD_END
955 };
956
957 DEFINE_CLASS_0(rtl8366rb, rtl8366rb_driver, rtl8366rb_methods,
958     sizeof(struct rtl8366rb_softc));
959 static devclass_t rtl8366rb_devclass;
960
961 DRIVER_MODULE(rtl8366rb, iicbus, rtl8366rb_driver, rtl8366rb_devclass, 0, 0);
962 DRIVER_MODULE(miibus, rtl8366rb, miibus_driver, miibus_devclass, 0, 0);
963 DRIVER_MODULE(mdio, rtl8366rb, mdio_driver, mdio_devclass, 0, 0);
964 DRIVER_MODULE(etherswitch, rtl8366rb, etherswitch_driver, etherswitch_devclass, 0, 0);
965 MODULE_VERSION(rtl8366rb, 1);
966 MODULE_DEPEND(rtl8366rb, iicbus, 1, 1, 1); /* XXX which versions? */
967 MODULE_DEPEND(rtl8366rb, miibus, 1, 1, 1); /* XXX which versions? */
968 MODULE_DEPEND(rtl8366rb, etherswitch, 1, 1, 1); /* XXX which versions? */