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