rtl8366rb.c revision 268233
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: head/sys/dev/etherswitch/rtl8366/rtl8366rb.c 268233 2014-07-03 19:50:50Z loos $
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
63struct 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
75static 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
103static int callout_blocked = 0;
104static int iic_select_retries = 0;
105static int phy_access_retries = 0;
106static SYSCTL_NODE(_debug, OID_AUTO, rtl8366rb, CTLFLAG_RD, 0, "rtl8366rb");
107SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, callout_blocked, CTLFLAG_RW, &callout_blocked, 0,
108	"number of times the callout couldn't acquire the bus");
109SYSCTL_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");
111SYSCTL_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
119static int smi_probe(device_t dev);
120static int smi_read(device_t dev, uint16_t addr, uint16_t *data, int sleep);
121static int smi_write(device_t dev, uint16_t addr, uint16_t data, int sleep);
122static int smi_rmw(device_t dev, uint16_t addr, uint16_t mask, uint16_t data, int sleep);
123static void rtl8366rb_tick(void *arg);
124static int rtl8366rb_ifmedia_upd(struct ifnet *);
125static void rtl8366rb_ifmedia_sts(struct ifnet *, struct ifmediareq *);
126
127static void
128rtl8366rb_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
140static int
141rtl8366rb_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
149static void
150rtl8366rb_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
184static int
185rtl8366rb_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
236static int
237rtl8366rb_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
257static void
258rtl8366rb_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
289static void
290rtl833rb_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
318static void
319rtl8366rb_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
327static int
328smi_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;
364out:
365	iicbus_stop(iicbus);
366	iicbus_release_bus(iicbus, dev);
367	return (err == 0 ? 0 : ENXIO);
368}
369
370static int
371smi_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
391static int
392smi_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
406static int
407smi_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
432static int
433smi_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
454out:
455	iicbus_stop(iicbus);
456	return (err);
457}
458
459static int
460smi_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
481static int
482smi_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
496static int
497smi_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
511static int
512smi_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
535static etherswitch_info_t *
536rtl_getinfo(device_t dev)
537{
538	return (&etherswitch_info);
539}
540
541static int
542rtl_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
550static int
551rtl_writereg(device_t dev, int reg, int value)
552{
553	return (smi_write(dev, reg, value, RTL_WAITOK));
554}
555
556static int
557rtl_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		ifmr->ifm_count = 0;
583		smi_read(dev, RTL8366RB_PLSR_BASE + (RTL8366RB_NUM_PHYS)/2, &v, RTL_WAITOK);
584		v = v >> (8 * ((RTL8366RB_NUM_PHYS) % 2));
585		rtl8366rb_update_ifmedia(v, &ifmr->ifm_status, &ifmr->ifm_active);
586		ifmr->ifm_current = ifmr->ifm_active;
587		ifmr->ifm_mask = 0;
588		ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID;
589	}
590	return (0);
591}
592
593static int
594rtl_setport(device_t dev, etherswitch_port_t *p)
595{
596	int i, err, vlangroup;
597	struct rtl8366rb_softc *sc;
598	struct ifmedia *ifm;
599	struct mii_data *mii;
600
601	if (p->es_port < 0 || p->es_port >= RTL8366RB_NUM_PHYS)
602		return (ENXIO);
603	sc = device_get_softc(dev);
604	vlangroup = -1;
605	for (i = 0; i < RTL8366RB_NUM_VLANS; i++) {
606		if ((sc->vid[i] & ETHERSWITCH_VID_MASK) == p->es_pvid) {
607			vlangroup = i;
608			break;
609		}
610	}
611	if (vlangroup == -1)
612		return (ENXIO);
613	err = smi_rmw(dev, RTL8366RB_PVCR_REG(p->es_port),
614		RTL8366RB_PVCR_VAL(p->es_port, RTL8366RB_PVCR_PORT_MASK),
615		RTL8366RB_PVCR_VAL(p->es_port, vlangroup), RTL_WAITOK);
616	if (err)
617		return (err);
618	if (p->es_port == RTL8366RB_CPU_PORT)
619		return (0);
620	mii = device_get_softc(sc->miibus[p->es_port]);
621	ifm = &mii->mii_media;
622	err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCSIFMEDIA);
623	return (err);
624}
625
626static int
627rtl_getvgroup(device_t dev, etherswitch_vlangroup_t *vg)
628{
629	struct rtl8366rb_softc *sc;
630	uint16_t vmcr[3];
631	int i;
632
633	for (i=0; i<3; i++)
634		vmcr[i] = rtl_readreg(dev, RTL8366RB_VMCR(i, vg->es_vlangroup));
635
636	sc = device_get_softc(dev);
637	vg->es_vid = sc->vid[vg->es_vlangroup];
638	vg->es_member_ports = RTL8366RB_VMCR_MEMBER(vmcr);
639	vg->es_untagged_ports = RTL8366RB_VMCR_UNTAG(vmcr);
640	vg->es_fid = RTL8366RB_VMCR_FID(vmcr);
641	return (0);
642}
643
644static int
645rtl_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
646{
647	struct rtl8366rb_softc *sc;
648	int g = vg->es_vlangroup;
649
650	sc = device_get_softc(dev);
651	sc->vid[g] = vg->es_vid;
652	/* VLAN group disabled ? */
653	if (vg->es_member_ports == 0 && vg->es_untagged_ports == 0 && vg->es_vid == 0)
654		return (0);
655	sc->vid[g] |= ETHERSWITCH_VID_VALID;
656	rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_DOT1Q_REG, g),
657		(vg->es_vid << RTL8366RB_VMCR_DOT1Q_VID_SHIFT) & RTL8366RB_VMCR_DOT1Q_VID_MASK);
658	rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_MU_REG, g),
659		((vg->es_member_ports << RTL8366RB_VMCR_MU_MEMBER_SHIFT) & RTL8366RB_VMCR_MU_MEMBER_MASK) |
660		((vg->es_untagged_ports << RTL8366RB_VMCR_MU_UNTAG_SHIFT) & RTL8366RB_VMCR_MU_UNTAG_MASK));
661	rtl_writereg(dev, RTL8366RB_VMCR(RTL8366RB_VMCR_FID_REG, g),
662		vg->es_fid);
663	return (0);
664}
665
666static int
667rtl_getconf(device_t dev, etherswitch_conf_t *conf)
668{
669
670	/* Return the VLAN mode. */
671	conf->cmd = ETHERSWITCH_CONF_VLAN_MODE;
672	conf->vlan_mode = ETHERSWITCH_VLAN_DOT1Q;
673
674	return (0);
675}
676
677static int
678rtl_readphy(device_t dev, int phy, int reg)
679{
680	struct rtl8366rb_softc *sc = device_get_softc(dev);
681	uint16_t data = 0;
682	int err, i, sleep;
683
684	if (phy < 0 || phy >= RTL8366RB_NUM_PHYS)
685		return (ENXIO);
686	if (reg < 0 || reg >= RTL8366RB_NUM_PHY_REG)
687		return (ENXIO);
688	sleep = RTL_WAITOK;
689	err = smi_acquire(sc, sleep);
690	if (err != 0)
691		return (EBUSY);
692	for (i = RTL_IICBUS_RETRIES; i--; ) {
693		err = smi_write_locked(sc, RTL8366RB_PACR, RTL8366RB_PACR_READ, sleep);
694		if (err == 0)
695			err = smi_write_locked(sc, RTL8366RB_PHYREG(phy, 0, reg), 0, sleep);
696		if (err == 0) {
697			err = smi_read_locked(sc, RTL8366RB_PADR, &data, sleep);
698			break;
699		}
700		DEBUG_INCRVAR(phy_access_retries);
701		DPRINTF(dev, "rtl_readphy(): chip not responsive, retrying %d more times\n", i);
702		pause("rtl_readphy", RTL_IICBUS_RETRY_SLEEP);
703	}
704	smi_release(sc, sleep);
705	DEVERR(dev, err, "rtl_readphy()=%d: phy=%d.%02x\n", phy, reg);
706	return (data);
707}
708
709static int
710rtl_writephy(device_t dev, int phy, int reg, int data)
711{
712	struct rtl8366rb_softc *sc = device_get_softc(dev);
713	int err, i, sleep;
714
715	if (phy < 0 || phy >= RTL8366RB_NUM_PHYS)
716		return (ENXIO);
717	if (reg < 0 || reg >= RTL8366RB_NUM_PHY_REG)
718		return (ENXIO);
719	sleep = RTL_WAITOK;
720	err = smi_acquire(sc, sleep);
721	if (err != 0)
722		return (EBUSY);
723	for (i = RTL_IICBUS_RETRIES; i--; ) {
724		err = smi_write_locked(sc, RTL8366RB_PACR, RTL8366RB_PACR_WRITE, sleep);
725		if (err == 0)
726			err = smi_write_locked(sc, RTL8366RB_PHYREG(phy, 0, reg), data, sleep);
727		if (err == 0) {
728			break;
729		}
730		DEBUG_INCRVAR(phy_access_retries);
731		DPRINTF(dev, "rtl_writephy(): chip not responsive, retrying %d more tiems\n", i);
732		pause("rtl_writephy", RTL_IICBUS_RETRY_SLEEP);
733	}
734	smi_release(sc, sleep);
735	DEVERR(dev, err, "rtl_writephy()=%d: phy=%d.%02x\n", phy, reg);
736	return (err == 0 ? 0 : EIO);
737}
738
739static int
740rtl8366rb_ifmedia_upd(struct ifnet *ifp)
741{
742	struct rtl8366rb_softc *sc = ifp->if_softc;
743	struct mii_data *mii = device_get_softc(sc->miibus[ifp->if_dunit]);
744
745	mii_mediachg(mii);
746	return (0);
747}
748
749static void
750rtl8366rb_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
751{
752	struct rtl8366rb_softc *sc = ifp->if_softc;
753	struct mii_data *mii = device_get_softc(sc->miibus[ifp->if_dunit]);
754
755	mii_pollstat(mii);
756	ifmr->ifm_active = mii->mii_media_active;
757	ifmr->ifm_status = mii->mii_media_status;
758}
759
760
761static device_method_t rtl8366rb_methods[] = {
762	/* Device interface */
763	DEVMETHOD(device_identify,	rtl8366rb_identify),
764	DEVMETHOD(device_probe,		rtl8366rb_probe),
765	DEVMETHOD(device_attach,	rtl8366rb_attach),
766	DEVMETHOD(device_detach,	rtl8366rb_detach),
767
768	/* bus interface */
769	DEVMETHOD(bus_add_child,	device_add_child_ordered),
770
771	/* MII interface */
772	DEVMETHOD(miibus_readreg,	rtl_readphy),
773	DEVMETHOD(miibus_writereg,	rtl_writephy),
774
775	/* etherswitch interface */
776	DEVMETHOD(etherswitch_getconf,	rtl_getconf),
777	DEVMETHOD(etherswitch_getinfo,	rtl_getinfo),
778	DEVMETHOD(etherswitch_readreg,	rtl_readreg),
779	DEVMETHOD(etherswitch_writereg,	rtl_writereg),
780	DEVMETHOD(etherswitch_readphyreg,	rtl_readphy),
781	DEVMETHOD(etherswitch_writephyreg,	rtl_writephy),
782	DEVMETHOD(etherswitch_getport,	rtl_getport),
783	DEVMETHOD(etherswitch_setport,	rtl_setport),
784	DEVMETHOD(etherswitch_getvgroup,	rtl_getvgroup),
785	DEVMETHOD(etherswitch_setvgroup,	rtl_setvgroup),
786
787	DEVMETHOD_END
788};
789
790DEFINE_CLASS_0(rtl8366rb, rtl8366rb_driver, rtl8366rb_methods,
791    sizeof(struct rtl8366rb_softc));
792static devclass_t rtl8366rb_devclass;
793
794DRIVER_MODULE(rtl8366rb, iicbus, rtl8366rb_driver, rtl8366rb_devclass, 0, 0);
795DRIVER_MODULE(miibus, rtl8366rb, miibus_driver, miibus_devclass, 0, 0);
796DRIVER_MODULE(etherswitch, rtl8366rb, etherswitch_driver, etherswitch_devclass, 0, 0);
797MODULE_VERSION(rtl8366rb, 1);
798MODULE_DEPEND(rtl8366rb, iicbus, 1, 1, 1); /* XXX which versions? */
799MODULE_DEPEND(rtl8366rb, miibus, 1, 1, 1); /* XXX which versions? */
800MODULE_DEPEND(rtl8366rb, etherswitch, 1, 1, 1); /* XXX which versions? */
801