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