if_udav.c revision 227843
1/*	$NetBSD: if_udav.c,v 1.2 2003/09/04 15:17:38 tsutsui Exp $	*/
2/*	$nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $	*/
3/*	$FreeBSD: head/sys/dev/usb/net/if_udav.c 227843 2011-11-22 21:28:20Z marius $	*/
4/*-
5 * Copyright (c) 2003
6 *     Shingo WATANABE <nabe@nabechan.org>.  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 * 3. Neither the name of the author nor the names of any co-contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 */
33
34/*
35 * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY)
36 * The spec can be found at the following url.
37 *   http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-P01-930914.pdf
38 */
39
40/*
41 * TODO:
42 *	Interrupt Endpoint support
43 *	External PHYs
44 */
45
46#include <sys/cdefs.h>
47__FBSDID("$FreeBSD: head/sys/dev/usb/net/if_udav.c 227843 2011-11-22 21:28:20Z marius $");
48
49#include <sys/stdint.h>
50#include <sys/stddef.h>
51#include <sys/param.h>
52#include <sys/queue.h>
53#include <sys/types.h>
54#include <sys/systm.h>
55#include <sys/kernel.h>
56#include <sys/bus.h>
57#include <sys/module.h>
58#include <sys/lock.h>
59#include <sys/mutex.h>
60#include <sys/condvar.h>
61#include <sys/sysctl.h>
62#include <sys/sx.h>
63#include <sys/unistd.h>
64#include <sys/callout.h>
65#include <sys/malloc.h>
66#include <sys/priv.h>
67
68#include <dev/usb/usb.h>
69#include <dev/usb/usbdi.h>
70#include <dev/usb/usbdi_util.h>
71#include "usbdevs.h"
72
73#define	USB_DEBUG_VAR udav_debug
74#include <dev/usb/usb_debug.h>
75#include <dev/usb/usb_process.h>
76
77#include <dev/usb/net/usb_ethernet.h>
78#include <dev/usb/net/if_udavreg.h>
79
80/* prototypes */
81
82static device_probe_t udav_probe;
83static device_attach_t udav_attach;
84static device_detach_t udav_detach;
85
86static usb_callback_t udav_bulk_write_callback;
87static usb_callback_t udav_bulk_read_callback;
88static usb_callback_t udav_intr_callback;
89
90static uether_fn_t udav_attach_post;
91static uether_fn_t udav_init;
92static uether_fn_t udav_stop;
93static uether_fn_t udav_start;
94static uether_fn_t udav_tick;
95static uether_fn_t udav_setmulti;
96static uether_fn_t udav_setpromisc;
97
98static int	udav_csr_read(struct udav_softc *, uint16_t, void *, int);
99static int	udav_csr_write(struct udav_softc *, uint16_t, void *, int);
100static uint8_t	udav_csr_read1(struct udav_softc *, uint16_t);
101static int	udav_csr_write1(struct udav_softc *, uint16_t, uint8_t);
102static void	udav_reset(struct udav_softc *);
103static int	udav_ifmedia_upd(struct ifnet *);
104static void	udav_ifmedia_status(struct ifnet *, struct ifmediareq *);
105
106static miibus_readreg_t udav_miibus_readreg;
107static miibus_writereg_t udav_miibus_writereg;
108static miibus_statchg_t udav_miibus_statchg;
109
110static const struct usb_config udav_config[UDAV_N_TRANSFER] = {
111
112	[UDAV_BULK_DT_WR] = {
113		.type = UE_BULK,
114		.endpoint = UE_ADDR_ANY,
115		.direction = UE_DIR_OUT,
116		.bufsize = (MCLBYTES + 2),
117		.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
118		.callback = udav_bulk_write_callback,
119		.timeout = 10000,	/* 10 seconds */
120	},
121
122	[UDAV_BULK_DT_RD] = {
123		.type = UE_BULK,
124		.endpoint = UE_ADDR_ANY,
125		.direction = UE_DIR_IN,
126		.bufsize = (MCLBYTES + 3),
127		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
128		.callback = udav_bulk_read_callback,
129		.timeout = 0,	/* no timeout */
130	},
131
132	[UDAV_INTR_DT_RD] = {
133		.type = UE_INTERRUPT,
134		.endpoint = UE_ADDR_ANY,
135		.direction = UE_DIR_IN,
136		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
137		.bufsize = 0,	/* use wMaxPacketSize */
138		.callback = udav_intr_callback,
139	},
140};
141
142static device_method_t udav_methods[] = {
143	/* Device interface */
144	DEVMETHOD(device_probe, udav_probe),
145	DEVMETHOD(device_attach, udav_attach),
146	DEVMETHOD(device_detach, udav_detach),
147
148	/* MII interface */
149	DEVMETHOD(miibus_readreg, udav_miibus_readreg),
150	DEVMETHOD(miibus_writereg, udav_miibus_writereg),
151	DEVMETHOD(miibus_statchg, udav_miibus_statchg),
152
153	DEVMETHOD_END
154};
155
156static driver_t udav_driver = {
157	.name = "udav",
158	.methods = udav_methods,
159	.size = sizeof(struct udav_softc),
160};
161
162static devclass_t udav_devclass;
163
164DRIVER_MODULE(udav, uhub, udav_driver, udav_devclass, NULL, 0);
165DRIVER_MODULE(miibus, udav, miibus_driver, miibus_devclass, 0, 0);
166MODULE_DEPEND(udav, uether, 1, 1, 1);
167MODULE_DEPEND(udav, usb, 1, 1, 1);
168MODULE_DEPEND(udav, ether, 1, 1, 1);
169MODULE_DEPEND(udav, miibus, 1, 1, 1);
170MODULE_VERSION(udav, 1);
171
172static const struct usb_ether_methods udav_ue_methods = {
173	.ue_attach_post = udav_attach_post,
174	.ue_start = udav_start,
175	.ue_init = udav_init,
176	.ue_stop = udav_stop,
177	.ue_tick = udav_tick,
178	.ue_setmulti = udav_setmulti,
179	.ue_setpromisc = udav_setpromisc,
180	.ue_mii_upd = udav_ifmedia_upd,
181	.ue_mii_sts = udav_ifmedia_status,
182};
183
184#ifdef USB_DEBUG
185static int udav_debug = 0;
186
187static SYSCTL_NODE(_hw_usb, OID_AUTO, udav, CTLFLAG_RW, 0, "USB udav");
188SYSCTL_INT(_hw_usb_udav, OID_AUTO, debug, CTLFLAG_RW, &udav_debug, 0,
189    "Debug level");
190#endif
191
192#define	UDAV_SETBIT(sc, reg, x)	\
193	udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) | (x))
194
195#define	UDAV_CLRBIT(sc, reg, x)	\
196	udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x))
197
198static const STRUCT_USB_HOST_ID udav_devs[] = {
199	/* ShanTou DM9601 USB NIC */
200	{USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601, 0)},
201	/* ShanTou ST268 USB NIC */
202	{USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268, 0)},
203	/* Corega USB-TXC */
204	{USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC, 0)},
205	/* ShanTou AMD8515 USB NIC */
206	{USB_VPI(USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515, 0)},
207	/* Kontron AG USB Ethernet */
208	{USB_VPI(USB_VENDOR_KONTRON, USB_PRODUCT_KONTRON_DM9601, 0)},
209	{USB_VPI(USB_VENDOR_KONTRON, USB_PRODUCT_KONTRON_JP1082, 0)},
210};
211
212static void
213udav_attach_post(struct usb_ether *ue)
214{
215	struct udav_softc *sc = uether_getsc(ue);
216
217	/* reset the adapter */
218	udav_reset(sc);
219
220	/* Get Ethernet Address */
221	udav_csr_read(sc, UDAV_PAR, ue->ue_eaddr, ETHER_ADDR_LEN);
222}
223
224static int
225udav_probe(device_t dev)
226{
227	struct usb_attach_arg *uaa = device_get_ivars(dev);
228
229	if (uaa->usb_mode != USB_MODE_HOST)
230		return (ENXIO);
231	if (uaa->info.bConfigIndex != UDAV_CONFIG_INDEX)
232		return (ENXIO);
233	if (uaa->info.bIfaceIndex != UDAV_IFACE_INDEX)
234		return (ENXIO);
235
236	return (usbd_lookup_id_by_uaa(udav_devs, sizeof(udav_devs), uaa));
237}
238
239static int
240udav_attach(device_t dev)
241{
242	struct usb_attach_arg *uaa = device_get_ivars(dev);
243	struct udav_softc *sc = device_get_softc(dev);
244	struct usb_ether *ue = &sc->sc_ue;
245	uint8_t iface_index;
246	int error;
247
248	sc->sc_flags = USB_GET_DRIVER_INFO(uaa);
249
250	device_set_usb_desc(dev);
251
252	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
253
254	iface_index = UDAV_IFACE_INDEX;
255	error = usbd_transfer_setup(uaa->device, &iface_index,
256	    sc->sc_xfer, udav_config, UDAV_N_TRANSFER, sc, &sc->sc_mtx);
257	if (error) {
258		device_printf(dev, "allocating USB transfers failed\n");
259		goto detach;
260	}
261
262	ue->ue_sc = sc;
263	ue->ue_dev = dev;
264	ue->ue_udev = uaa->device;
265	ue->ue_mtx = &sc->sc_mtx;
266	ue->ue_methods = &udav_ue_methods;
267
268	error = uether_ifattach(ue);
269	if (error) {
270		device_printf(dev, "could not attach interface\n");
271		goto detach;
272	}
273
274	return (0);			/* success */
275
276detach:
277	udav_detach(dev);
278	return (ENXIO);			/* failure */
279}
280
281static int
282udav_detach(device_t dev)
283{
284	struct udav_softc *sc = device_get_softc(dev);
285	struct usb_ether *ue = &sc->sc_ue;
286
287	usbd_transfer_unsetup(sc->sc_xfer, UDAV_N_TRANSFER);
288	uether_ifdetach(ue);
289	mtx_destroy(&sc->sc_mtx);
290
291	return (0);
292}
293
294#if 0
295static int
296udav_mem_read(struct udav_softc *sc, uint16_t offset, void *buf,
297    int len)
298{
299	struct usb_device_request req;
300
301	len &= 0xff;
302
303	req.bmRequestType = UT_READ_VENDOR_DEVICE;
304	req.bRequest = UDAV_REQ_MEM_READ;
305	USETW(req.wValue, 0x0000);
306	USETW(req.wIndex, offset);
307	USETW(req.wLength, len);
308
309	return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
310}
311
312static int
313udav_mem_write(struct udav_softc *sc, uint16_t offset, void *buf,
314    int len)
315{
316	struct usb_device_request req;
317
318	len &= 0xff;
319
320	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
321	req.bRequest = UDAV_REQ_MEM_WRITE;
322	USETW(req.wValue, 0x0000);
323	USETW(req.wIndex, offset);
324	USETW(req.wLength, len);
325
326	return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
327}
328
329static int
330udav_mem_write1(struct udav_softc *sc, uint16_t offset,
331    uint8_t ch)
332{
333	struct usb_device_request req;
334
335	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
336	req.bRequest = UDAV_REQ_MEM_WRITE1;
337	USETW(req.wValue, ch);
338	USETW(req.wIndex, offset);
339	USETW(req.wLength, 0x0000);
340
341	return (uether_do_request(&sc->sc_ue, &req, NULL, 1000));
342}
343#endif
344
345static int
346udav_csr_read(struct udav_softc *sc, uint16_t offset, void *buf, int len)
347{
348	struct usb_device_request req;
349
350	len &= 0xff;
351
352	req.bmRequestType = UT_READ_VENDOR_DEVICE;
353	req.bRequest = UDAV_REQ_REG_READ;
354	USETW(req.wValue, 0x0000);
355	USETW(req.wIndex, offset);
356	USETW(req.wLength, len);
357
358	return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
359}
360
361static int
362udav_csr_write(struct udav_softc *sc, uint16_t offset, void *buf, int len)
363{
364	struct usb_device_request req;
365
366	offset &= 0xff;
367	len &= 0xff;
368
369	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
370	req.bRequest = UDAV_REQ_REG_WRITE;
371	USETW(req.wValue, 0x0000);
372	USETW(req.wIndex, offset);
373	USETW(req.wLength, len);
374
375	return (uether_do_request(&sc->sc_ue, &req, buf, 1000));
376}
377
378static uint8_t
379udav_csr_read1(struct udav_softc *sc, uint16_t offset)
380{
381	uint8_t val;
382
383	udav_csr_read(sc, offset, &val, 1);
384	return (val);
385}
386
387static int
388udav_csr_write1(struct udav_softc *sc, uint16_t offset,
389    uint8_t ch)
390{
391	struct usb_device_request req;
392
393	offset &= 0xff;
394
395	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
396	req.bRequest = UDAV_REQ_REG_WRITE1;
397	USETW(req.wValue, ch);
398	USETW(req.wIndex, offset);
399	USETW(req.wLength, 0x0000);
400
401	return (uether_do_request(&sc->sc_ue, &req, NULL, 1000));
402}
403
404static void
405udav_init(struct usb_ether *ue)
406{
407	struct udav_softc *sc = ue->ue_sc;
408	struct ifnet *ifp = uether_getifp(&sc->sc_ue);
409
410	UDAV_LOCK_ASSERT(sc, MA_OWNED);
411
412	/*
413	 * Cancel pending I/O
414	 */
415	udav_stop(ue);
416
417	/* set MAC address */
418	udav_csr_write(sc, UDAV_PAR, IF_LLADDR(ifp), ETHER_ADDR_LEN);
419
420	/* initialize network control register */
421
422	/* disable loopback  */
423	UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1);
424
425	/* Initialize RX control register */
426	UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC);
427
428	/* load multicast filter and update promiscious mode bit */
429	udav_setpromisc(ue);
430
431	/* enable RX */
432	UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_RXEN);
433
434	/* clear POWER_DOWN state of internal PHY */
435	UDAV_SETBIT(sc, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0);
436	UDAV_CLRBIT(sc, UDAV_GPR, UDAV_GPR_GEPIO0);
437
438	usbd_xfer_set_stall(sc->sc_xfer[UDAV_BULK_DT_WR]);
439
440	ifp->if_drv_flags |= IFF_DRV_RUNNING;
441	udav_start(ue);
442}
443
444static void
445udav_reset(struct udav_softc *sc)
446{
447	int i;
448
449	/* Select PHY */
450#if 1
451	/*
452	 * XXX: force select internal phy.
453	 *	external phy routines are not tested.
454	 */
455	UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
456#else
457	if (sc->sc_flags & UDAV_EXT_PHY)
458		UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
459	else
460		UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
461#endif
462
463	UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_RST);
464
465	for (i = 0; i < UDAV_TX_TIMEOUT; i++) {
466		if (!(udav_csr_read1(sc, UDAV_NCR) & UDAV_NCR_RST))
467			break;
468		if (uether_pause(&sc->sc_ue, hz / 100))
469			break;
470	}
471
472	uether_pause(&sc->sc_ue, hz / 100);
473}
474
475#define	UDAV_BITS	6
476static void
477udav_setmulti(struct usb_ether *ue)
478{
479	struct udav_softc *sc = ue->ue_sc;
480	struct ifnet *ifp = uether_getifp(&sc->sc_ue);
481	struct ifmultiaddr *ifma;
482	uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
483	int h = 0;
484
485	UDAV_LOCK_ASSERT(sc, MA_OWNED);
486
487	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
488		UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC);
489		return;
490	}
491
492	/* first, zot all the existing hash bits */
493	memset(hashtbl, 0x00, sizeof(hashtbl));
494	hashtbl[7] |= 0x80;	/* broadcast address */
495	udav_csr_write(sc, UDAV_MAR, hashtbl, sizeof(hashtbl));
496
497	/* now program new ones */
498	if_maddr_rlock(ifp);
499	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
500	{
501		if (ifma->ifma_addr->sa_family != AF_LINK)
502			continue;
503		h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
504		    ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
505		hashtbl[h / 8] |= 1 << (h % 8);
506	}
507	if_maddr_runlock(ifp);
508
509	/* disable all multicast */
510	UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL);
511
512	/* write hash value to the register */
513	udav_csr_write(sc, UDAV_MAR, hashtbl, sizeof(hashtbl));
514}
515
516static void
517udav_setpromisc(struct usb_ether *ue)
518{
519	struct udav_softc *sc = ue->ue_sc;
520	struct ifnet *ifp = uether_getifp(&sc->sc_ue);
521	uint8_t rxmode;
522
523	rxmode = udav_csr_read1(sc, UDAV_RCR);
524	rxmode &= ~(UDAV_RCR_ALL | UDAV_RCR_PRMSC);
525
526	if (ifp->if_flags & IFF_PROMISC)
527		rxmode |= UDAV_RCR_ALL | UDAV_RCR_PRMSC;
528	else if (ifp->if_flags & IFF_ALLMULTI)
529		rxmode |= UDAV_RCR_ALL;
530
531	/* write new mode bits */
532	udav_csr_write1(sc, UDAV_RCR, rxmode);
533}
534
535static void
536udav_start(struct usb_ether *ue)
537{
538	struct udav_softc *sc = ue->ue_sc;
539
540	/*
541	 * start the USB transfers, if not already started:
542	 */
543	usbd_transfer_start(sc->sc_xfer[UDAV_INTR_DT_RD]);
544	usbd_transfer_start(sc->sc_xfer[UDAV_BULK_DT_RD]);
545	usbd_transfer_start(sc->sc_xfer[UDAV_BULK_DT_WR]);
546}
547
548static void
549udav_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
550{
551	struct udav_softc *sc = usbd_xfer_softc(xfer);
552	struct ifnet *ifp = uether_getifp(&sc->sc_ue);
553	struct usb_page_cache *pc;
554	struct mbuf *m;
555	int extra_len;
556	int temp_len;
557	uint8_t buf[2];
558
559	switch (USB_GET_STATE(xfer)) {
560	case USB_ST_TRANSFERRED:
561		DPRINTFN(11, "transfer complete\n");
562		ifp->if_opackets++;
563
564		/* FALLTHROUGH */
565	case USB_ST_SETUP:
566tr_setup:
567		if ((sc->sc_flags & UDAV_FLAG_LINK) == 0) {
568			/*
569			 * don't send anything if there is no link !
570			 */
571			return;
572		}
573		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
574
575		if (m == NULL)
576			return;
577		if (m->m_pkthdr.len > MCLBYTES)
578			m->m_pkthdr.len = MCLBYTES;
579		if (m->m_pkthdr.len < UDAV_MIN_FRAME_LEN) {
580			extra_len = UDAV_MIN_FRAME_LEN - m->m_pkthdr.len;
581		} else {
582			extra_len = 0;
583		}
584
585		temp_len = (m->m_pkthdr.len + extra_len);
586
587		/*
588		 * the frame length is specified in the first 2 bytes of the
589		 * buffer
590		 */
591		buf[0] = (uint8_t)(temp_len);
592		buf[1] = (uint8_t)(temp_len >> 8);
593
594		temp_len += 2;
595
596		pc = usbd_xfer_get_frame(xfer, 0);
597		usbd_copy_in(pc, 0, buf, 2);
598		usbd_m_copy_in(pc, 2, m, 0, m->m_pkthdr.len);
599
600		if (extra_len)
601			usbd_frame_zero(pc, temp_len - extra_len, extra_len);
602		/*
603		 * if there's a BPF listener, bounce a copy
604		 * of this frame to him:
605		 */
606		BPF_MTAP(ifp, m);
607
608		m_freem(m);
609
610		usbd_xfer_set_frame_len(xfer, 0, temp_len);
611		usbd_transfer_submit(xfer);
612		return;
613
614	default:			/* Error */
615		DPRINTFN(11, "transfer error, %s\n",
616		    usbd_errstr(error));
617
618		ifp->if_oerrors++;
619
620		if (error != USB_ERR_CANCELLED) {
621			/* try to clear stall first */
622			usbd_xfer_set_stall(xfer);
623			goto tr_setup;
624		}
625		return;
626	}
627}
628
629static void
630udav_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
631{
632	struct udav_softc *sc = usbd_xfer_softc(xfer);
633	struct usb_ether *ue = &sc->sc_ue;
634	struct ifnet *ifp = uether_getifp(ue);
635	struct usb_page_cache *pc;
636	struct udav_rxpkt stat;
637	int len;
638	int actlen;
639
640	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
641
642	switch (USB_GET_STATE(xfer)) {
643	case USB_ST_TRANSFERRED:
644
645		if (actlen < sizeof(stat) + ETHER_CRC_LEN) {
646			ifp->if_ierrors++;
647			goto tr_setup;
648		}
649		pc = usbd_xfer_get_frame(xfer, 0);
650		usbd_copy_out(pc, 0, &stat, sizeof(stat));
651		actlen -= sizeof(stat);
652		len = min(actlen, le16toh(stat.pktlen));
653		len -= ETHER_CRC_LEN;
654
655		if (stat.rxstat & UDAV_RSR_LCS) {
656			ifp->if_collisions++;
657			goto tr_setup;
658		}
659		if (stat.rxstat & UDAV_RSR_ERR) {
660			ifp->if_ierrors++;
661			goto tr_setup;
662		}
663		uether_rxbuf(ue, pc, sizeof(stat), len);
664		/* FALLTHROUGH */
665	case USB_ST_SETUP:
666tr_setup:
667		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
668		usbd_transfer_submit(xfer);
669		uether_rxflush(ue);
670		return;
671
672	default:			/* Error */
673		DPRINTF("bulk read error, %s\n",
674		    usbd_errstr(error));
675
676		if (error != USB_ERR_CANCELLED) {
677			/* try to clear stall first */
678			usbd_xfer_set_stall(xfer);
679			goto tr_setup;
680		}
681		return;
682	}
683}
684
685static void
686udav_intr_callback(struct usb_xfer *xfer, usb_error_t error)
687{
688	switch (USB_GET_STATE(xfer)) {
689	case USB_ST_TRANSFERRED:
690	case USB_ST_SETUP:
691tr_setup:
692		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
693		usbd_transfer_submit(xfer);
694		return;
695
696	default:			/* Error */
697		if (error != USB_ERR_CANCELLED) {
698			/* try to clear stall first */
699			usbd_xfer_set_stall(xfer);
700			goto tr_setup;
701		}
702		return;
703	}
704}
705
706static void
707udav_stop(struct usb_ether *ue)
708{
709	struct udav_softc *sc = ue->ue_sc;
710	struct ifnet *ifp = uether_getifp(&sc->sc_ue);
711
712	UDAV_LOCK_ASSERT(sc, MA_OWNED);
713
714	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
715	sc->sc_flags &= ~UDAV_FLAG_LINK;
716
717	/*
718	 * stop all the transfers, if not already stopped:
719	 */
720	usbd_transfer_stop(sc->sc_xfer[UDAV_BULK_DT_WR]);
721	usbd_transfer_stop(sc->sc_xfer[UDAV_BULK_DT_RD]);
722	usbd_transfer_stop(sc->sc_xfer[UDAV_INTR_DT_RD]);
723
724	udav_reset(sc);
725}
726
727static int
728udav_ifmedia_upd(struct ifnet *ifp)
729{
730	struct udav_softc *sc = ifp->if_softc;
731	struct mii_data *mii = GET_MII(sc);
732	struct mii_softc *miisc;
733
734	UDAV_LOCK_ASSERT(sc, MA_OWNED);
735
736        sc->sc_flags &= ~UDAV_FLAG_LINK;
737	LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
738		PHY_RESET(miisc);
739	mii_mediachg(mii);
740	return (0);
741}
742
743static void
744udav_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
745{
746	struct udav_softc *sc = ifp->if_softc;
747	struct mii_data *mii = GET_MII(sc);
748
749	UDAV_LOCK(sc);
750	mii_pollstat(mii);
751	ifmr->ifm_active = mii->mii_media_active;
752	ifmr->ifm_status = mii->mii_media_status;
753	UDAV_UNLOCK(sc);
754}
755
756static void
757udav_tick(struct usb_ether *ue)
758{
759	struct udav_softc *sc = ue->ue_sc;
760	struct mii_data *mii = GET_MII(sc);
761
762	UDAV_LOCK_ASSERT(sc, MA_OWNED);
763
764	mii_tick(mii);
765	if ((sc->sc_flags & UDAV_FLAG_LINK) == 0
766	    && mii->mii_media_status & IFM_ACTIVE &&
767	    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
768		sc->sc_flags |= UDAV_FLAG_LINK;
769		udav_start(ue);
770	}
771}
772
773static int
774udav_miibus_readreg(device_t dev, int phy, int reg)
775{
776	struct udav_softc *sc = device_get_softc(dev);
777	uint16_t data16;
778	uint8_t val[2];
779	int locked;
780
781	/* XXX: one PHY only for the internal PHY */
782	if (phy != 0)
783		return (0);
784
785	locked = mtx_owned(&sc->sc_mtx);
786	if (!locked)
787		UDAV_LOCK(sc);
788
789	/* select internal PHY and set PHY register address */
790	udav_csr_write1(sc, UDAV_EPAR,
791	    UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
792
793	/* select PHY operation and start read command */
794	udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR);
795
796	/* XXX: should we wait? */
797
798	/* end read command */
799	UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRR);
800
801	/* retrieve the result from data registers */
802	udav_csr_read(sc, UDAV_EPDRL, val, 2);
803
804	data16 = (val[0] | (val[1] << 8));
805
806	DPRINTFN(11, "phy=%d reg=0x%04x => 0x%04x\n",
807	    phy, reg, data16);
808
809	if (!locked)
810		UDAV_UNLOCK(sc);
811	return (data16);
812}
813
814static int
815udav_miibus_writereg(device_t dev, int phy, int reg, int data)
816{
817	struct udav_softc *sc = device_get_softc(dev);
818	uint8_t val[2];
819	int locked;
820
821	/* XXX: one PHY only for the internal PHY */
822	if (phy != 0)
823		return (0);
824
825	locked = mtx_owned(&sc->sc_mtx);
826	if (!locked)
827		UDAV_LOCK(sc);
828
829	/* select internal PHY and set PHY register address */
830	udav_csr_write1(sc, UDAV_EPAR,
831	    UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
832
833	/* put the value to the data registers */
834	val[0] = (data & 0xff);
835	val[1] = (data >> 8) & 0xff;
836	udav_csr_write(sc, UDAV_EPDRL, val, 2);
837
838	/* select PHY operation and start write command */
839	udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW);
840
841	/* XXX: should we wait? */
842
843	/* end write command */
844	UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRW);
845
846	if (!locked)
847		UDAV_UNLOCK(sc);
848	return (0);
849}
850
851static void
852udav_miibus_statchg(device_t dev)
853{
854	/* nothing to do */
855}
856