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