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