xref: /openbsd-src/sys/dev/usb/if_udav.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /*	$OpenBSD: if_udav.c,v 1.67 2014/07/13 15:52:49 mpi Exp $ */
2 /*	$NetBSD: if_udav.c,v 1.3 2004/04/23 17:25:25 itojun Exp $	*/
3 /*	$nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $	*/
4 /*
5  * Copyright (c) 2003
6  *     Shingo WATANABE <nabe@nabechan.org>.  All rights reserved.
7  * Copyright (c) 2014
8  *     Takayoshi SASANO <uaa@uaa.org.uk> (RD9700 support)
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the author nor the names of any co-contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  */
35 
36 /*
37  * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY)
38  * The spec can be found at the following url.
39  *  http://www.meworks.net/userfile/24247/DM9601-DS-P03-102908.pdf
40  */
41 
42 /*
43  * TODO:
44  *	Interrupt Endpoint support
45  *	External PHYs
46  */
47 
48 #include "bpfilter.h"
49 
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/rwlock.h>
53 #include <sys/mbuf.h>
54 #include <sys/kernel.h>
55 #include <sys/socket.h>
56 
57 #include <sys/device.h>
58 
59 #include <net/if.h>
60 #include <net/if_arp.h>
61 #include <net/if_dl.h>
62 #include <net/if_media.h>
63 
64 #if NBPFILTER > 0
65 #include <net/bpf.h>
66 #endif
67 
68 #include <netinet/in.h>
69 #include <netinet/if_ether.h>
70 
71 #include <dev/mii/mii.h>
72 #include <dev/mii/miivar.h>
73 
74 #include <dev/usb/usb.h>
75 #include <dev/usb/usbdi.h>
76 #include <dev/usb/usbdi_util.h>
77 #include <dev/usb/usbdevs.h>
78 
79 #include <dev/usb/if_udavreg.h>
80 
81 int udav_match(struct device *, void *, void *);
82 void udav_attach(struct device *, struct device *, void *);
83 int udav_detach(struct device *, int);
84 
85 struct cfdriver udav_cd = {
86 	NULL, "udav", DV_IFNET
87 };
88 
89 const struct cfattach udav_ca = {
90 	sizeof(struct udav_softc), udav_match, udav_attach, udav_detach
91 };
92 
93 int udav_openpipes(struct udav_softc *);
94 int udav_rx_list_init(struct udav_softc *);
95 int udav_tx_list_init(struct udav_softc *);
96 int udav_newbuf(struct udav_softc *, struct udav_chain *, struct mbuf *);
97 void udav_start(struct ifnet *);
98 int udav_send(struct udav_softc *, struct mbuf *, int);
99 void udav_txeof(struct usbd_xfer *, void *, usbd_status);
100 void udav_rxeof(struct usbd_xfer *, void *, usbd_status);
101 void udav_tick(void *);
102 void udav_tick_task(void *);
103 int udav_ioctl(struct ifnet *, u_long, caddr_t);
104 void udav_stop_task(struct udav_softc *);
105 void udav_stop(struct ifnet *, int);
106 void udav_watchdog(struct ifnet *);
107 int udav_ifmedia_change(struct ifnet *);
108 void udav_ifmedia_status(struct ifnet *, struct ifmediareq *);
109 void udav_lock_mii(struct udav_softc *);
110 void udav_unlock_mii(struct udav_softc *);
111 int udav_miibus_readreg(struct device *, int, int);
112 void udav_miibus_writereg(struct device *, int, int, int);
113 void udav_miibus_statchg(struct device *);
114 int udav_init(struct ifnet *);
115 void udav_iff(struct udav_softc *);
116 void udav_reset(struct udav_softc *);
117 
118 int udav_csr_read(struct udav_softc *, int, void *, int);
119 int udav_csr_write(struct udav_softc *, int, void *, int);
120 int udav_csr_read1(struct udav_softc *, int);
121 int udav_csr_write1(struct udav_softc *, int, unsigned char);
122 
123 #if 0
124 int udav_mem_read(struct udav_softc *, int, void *, int);
125 int udav_mem_write(struct udav_softc *, int, void *, int);
126 int udav_mem_write1(struct udav_softc *, int, unsigned char);
127 #endif
128 
129 /* Macros */
130 #ifdef UDAV_DEBUG
131 #define DPRINTF(x)	do { if (udavdebug) printf x; } while(0)
132 #define DPRINTFN(n,x)	do { if (udavdebug >= (n)) printf x; } while(0)
133 int udavdebug = 0;
134 #else
135 #define DPRINTF(x)
136 #define DPRINTFN(n,x)
137 #endif
138 
139 #define	UDAV_SETBIT(sc, reg, x)	\
140 	udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) | (x))
141 
142 #define	UDAV_CLRBIT(sc, reg, x)	\
143 	udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x))
144 
145 static const struct udav_type {
146 	struct usb_devno udav_dev;
147 	u_int16_t udav_flags;
148 #define UDAV_EXT_PHY	0x0001
149 #define UDAV_RD9700	0x0002
150 } udav_devs [] = {
151 	{{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC }, 0 },
152 	{{ USB_VENDOR_DAVICOM, USB_PRODUCT_DAVICOM_DM9601 }, 0 },
153 	{{ USB_VENDOR_DAVICOM, USB_PRODUCT_DAVICOM_WK668 }, 0 },
154 	{{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601 }, 0 },
155 	{{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268 }, 0 },
156 	{{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ZT6688 }, 0 },
157 	{{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515 }, 0 },
158 	{{ USB_VENDOR_UNKNOWN4, USB_PRODUCT_UNKNOWN4_DM9601 }, 0 },
159 	{{ USB_VENDOR_UNKNOWN6, USB_PRODUCT_UNKNOWN6_DM9601 }, 0 },
160 	{{ USB_VENDOR_UNKNOWN4, USB_PRODUCT_UNKNOWN4_RD9700 }, UDAV_RD9700 },
161 };
162 #define udav_lookup(v, p) ((struct udav_type *)usb_lookup(udav_devs, v, p))
163 
164 
165 /* Probe */
166 int
167 udav_match(struct device *parent, void *match, void *aux)
168 {
169 	struct usb_attach_arg *uaa = aux;
170 
171 	if (uaa->iface != NULL)
172 		return (UMATCH_NONE);
173 
174 	return (udav_lookup(uaa->vendor, uaa->product) != NULL ?
175 		UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
176 }
177 
178 /* Attach */
179 void
180 udav_attach(struct device *parent, struct device *self, void *aux)
181 {
182 	struct udav_softc *sc = (struct udav_softc *)self;
183 	struct usb_attach_arg *uaa = aux;
184 	struct usbd_device *dev = uaa->device;
185 	struct usbd_interface *iface;
186 	usbd_status err;
187 	usb_interface_descriptor_t *id;
188 	usb_endpoint_descriptor_t *ed;
189 	char *devname = sc->sc_dev.dv_xname;
190 	struct ifnet *ifp;
191 	struct mii_data *mii;
192 	u_char eaddr[ETHER_ADDR_LEN];
193 	int i, s;
194 
195 	printf("%s: ", devname);
196 
197 	sc->sc_udev = dev;
198 
199 	/* Move the device into the configured state. */
200 	err = usbd_set_config_no(dev, UDAV_CONFIG_NO, 1);
201 	if (err) {
202 		printf("setting config no failed\n");
203 		goto bad;
204 	}
205 
206 	usb_init_task(&sc->sc_tick_task, udav_tick_task, sc,
207 	    USB_TASK_TYPE_GENERIC);
208 	rw_init(&sc->sc_mii_lock, "udavmii");
209 	usb_init_task(&sc->sc_stop_task, (void (*)(void *)) udav_stop_task, sc,
210 	    USB_TASK_TYPE_GENERIC);
211 
212 	/* get control interface */
213 	err = usbd_device2interface_handle(dev, UDAV_IFACE_INDEX, &iface);
214 	if (err) {
215 		printf("failed to get interface, err=%s\n", usbd_errstr(err));
216 		goto bad;
217 	}
218 
219 	sc->sc_ctl_iface = iface;
220 	sc->sc_flags = udav_lookup(uaa->vendor, uaa->product)->udav_flags;
221 
222 	/* get interface descriptor */
223 	id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
224 
225 	/* find endpoints */
226 	sc->sc_bulkin_no = sc->sc_bulkout_no = sc->sc_intrin_no = -1;
227 	for (i = 0; i < id->bNumEndpoints; i++) {
228 		ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
229 		if (ed == NULL) {
230 			printf("couldn't get endpoint %d\n", i);
231 			goto bad;
232 		}
233 		if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
234 		    UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
235 			sc->sc_bulkin_no = ed->bEndpointAddress; /* RX */
236 		else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
237 			 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
238 			sc->sc_bulkout_no = ed->bEndpointAddress; /* TX */
239 		else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT &&
240 			 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
241 			sc->sc_intrin_no = ed->bEndpointAddress; /* Status */
242 	}
243 
244 	if (sc->sc_bulkin_no == -1 || sc->sc_bulkout_no == -1 ||
245 	    sc->sc_intrin_no == -1) {
246 		printf("missing endpoint\n");
247 		goto bad;
248 	}
249 
250 	s = splnet();
251 
252 	/* reset the adapter */
253 	udav_reset(sc);
254 
255 	/* Get Ethernet Address */
256 	err = udav_csr_read(sc, UDAV_PAR, (void *)eaddr, ETHER_ADDR_LEN);
257 	if (err) {
258 		printf("read MAC address failed\n");
259 		splx(s);
260 		goto bad;
261 	}
262 
263 	/* Print Ethernet Address */
264 	printf("address %s\n", ether_sprintf(eaddr));
265 
266         bcopy(eaddr, (char *)&sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN);
267 
268 	/* initialize interface information */
269 	ifp = GET_IFP(sc);
270 	ifp->if_softc = sc;
271 	strlcpy(ifp->if_xname, devname, IFNAMSIZ);
272 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
273 	ifp->if_start = udav_start;
274 	ifp->if_ioctl = udav_ioctl;
275 	ifp->if_watchdog = udav_watchdog;
276 
277 	IFQ_SET_READY(&ifp->if_snd);
278 
279 	/*
280 	 * Do ifmedia setup.
281 	 */
282 	mii = &sc->sc_mii;
283 	mii->mii_ifp = ifp;
284 	mii->mii_readreg = udav_miibus_readreg;
285 	mii->mii_writereg = udav_miibus_writereg;
286 	mii->mii_statchg = udav_miibus_statchg;
287 	mii->mii_flags = MIIF_AUTOTSLEEP;
288 	ifmedia_init(&mii->mii_media, 0,
289 		     udav_ifmedia_change, udav_ifmedia_status);
290 	if (sc->sc_flags & UDAV_RD9700) {
291 		/* no MII-PHY */
292 		ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
293 		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
294 	} else {
295 		mii_attach(self, mii, 0xffffffff,
296 			   MII_PHY_ANY, MII_OFFSET_ANY, 0);
297 		if (LIST_FIRST(&mii->mii_phys) == NULL) {
298 			ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE,
299 				    0, NULL);
300 			ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
301 		} else
302 			ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
303 	}
304 
305 	/* attach the interface */
306 	if_attach(ifp);
307 	ether_ifattach(ifp);
308 
309 	timeout_set(&sc->sc_stat_ch, udav_tick, sc);
310 
311 	splx(s);
312 
313 	return;
314 
315  bad:
316 	usbd_deactivate(sc->sc_udev);
317 }
318 
319 /* detach */
320 int
321 udav_detach(struct device *self, int flags)
322 {
323 	struct udav_softc *sc = (struct udav_softc *)self;
324 	struct ifnet *ifp = GET_IFP(sc);
325 	int s;
326 
327 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
328 
329 
330 	if (timeout_initialized(&sc->sc_stat_ch))
331 		timeout_del(&sc->sc_stat_ch);
332 
333 	/* Remove any pending tasks */
334 	usb_rem_task(sc->sc_udev, &sc->sc_tick_task);
335 	usb_rem_task(sc->sc_udev, &sc->sc_stop_task);
336 
337 	s = splusb();
338 
339 	if (--sc->sc_refcnt >= 0) {
340 		/* Wait for processes to go away */
341 		usb_detach_wait(&sc->sc_dev);
342 	}
343 	if (ifp->if_flags & IFF_RUNNING)
344 		udav_stop(GET_IFP(sc), 1);
345 
346 	if (!(sc->sc_flags & UDAV_RD9700))
347 		mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
348 	ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
349 	if (ifp->if_softc != NULL) {
350 		ether_ifdetach(ifp);
351 		if_detach(ifp);
352 	}
353 
354 #ifdef DIAGNOSTIC
355 	if (sc->sc_pipe_tx != NULL)
356 		printf("%s: detach has active tx endpoint.\n",
357 		       sc->sc_dev.dv_xname);
358 	if (sc->sc_pipe_rx != NULL)
359 		printf("%s: detach has active rx endpoint.\n",
360 		       sc->sc_dev.dv_xname);
361 	if (sc->sc_pipe_intr != NULL)
362 		printf("%s: detach has active intr endpoint.\n",
363 		       sc->sc_dev.dv_xname);
364 #endif
365 	splx(s);
366 
367 	return (0);
368 }
369 
370 #if 0
371 /* read memory */
372 int
373 udav_mem_read(struct udav_softc *sc, int offset, void *buf, int len)
374 {
375 	usb_device_request_t req;
376 	usbd_status err;
377 
378 	if (sc == NULL)
379 		return (0);
380 
381 	DPRINTFN(0x200,
382 		("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
383 
384 	if (usbd_is_dying(sc->sc_udev))
385 		return (0);
386 
387 	offset &= 0xffff;
388 	len &= 0xff;
389 
390 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
391 	req.bRequest = UDAV_REQ_MEM_READ;
392 	USETW(req.wValue, 0x0000);
393 	USETW(req.wIndex, offset);
394 	USETW(req.wLength, len);
395 
396 	sc->sc_refcnt++;
397 	err = usbd_do_request(sc->sc_udev, &req, buf);
398 	if (--sc->sc_refcnt < 0)
399 		usb_detach_wakeup(&sc->sc_dev);
400 	if (err) {
401 		DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
402 			 sc->sc_dev.dv_xname, __func__, offset, err));
403 	}
404 
405 	return (err);
406 }
407 
408 /* write memory */
409 int
410 udav_mem_write(struct udav_softc *sc, int offset, void *buf, int len)
411 {
412 	usb_device_request_t req;
413 	usbd_status err;
414 
415 	if (sc == NULL)
416 		return (0);
417 
418 	DPRINTFN(0x200,
419 		("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
420 
421 	if (usbd_is_dying(sc->sc_udev))
422 		return (0);
423 
424 	offset &= 0xffff;
425 	len &= 0xff;
426 
427 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
428 	req.bRequest = UDAV_REQ_MEM_WRITE;
429 	USETW(req.wValue, 0x0000);
430 	USETW(req.wIndex, offset);
431 	USETW(req.wLength, len);
432 
433 	sc->sc_refcnt++;
434 	err = usbd_do_request(sc->sc_udev, &req, buf);
435 	if (--sc->sc_refcnt < 0)
436 		usb_detach_wakeup(&sc->sc_dev);
437 	if (err) {
438 		DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
439 			 sc->sc_dev.dv_xname, __func__, offset, err));
440 	}
441 
442 	return (err);
443 }
444 
445 /* write memory */
446 int
447 udav_mem_write1(struct udav_softc *sc, int offset, unsigned char ch)
448 {
449 	usb_device_request_t req;
450 	usbd_status err;
451 
452 	if (sc == NULL)
453 		return (0);
454 
455 	DPRINTFN(0x200,
456 		("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
457 
458 	if (usbd_is_dying(sc->sc_udev))
459 		return (0);
460 
461 	offset &= 0xffff;
462 
463 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
464 	req.bRequest = UDAV_REQ_MEM_WRITE1;
465 	USETW(req.wValue, ch);
466 	USETW(req.wIndex, offset);
467 	USETW(req.wLength, 0x0000);
468 
469 	sc->sc_refcnt++;
470 	err = usbd_do_request(sc->sc_udev, &req, NULL);
471 	if (--sc->sc_refcnt < 0)
472 		usb_detach_wakeup(&sc->sc_dev);
473 	if (err) {
474 		DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
475 			 sc->sc_dev.dv_xname, __func__, offset, err));
476 	}
477 
478 	return (err);
479 }
480 #endif
481 
482 /* read register(s) */
483 int
484 udav_csr_read(struct udav_softc *sc, int offset, void *buf, int len)
485 {
486 	usb_device_request_t req;
487 	usbd_status err;
488 
489 	if (sc == NULL)
490 		return (0);
491 
492 	DPRINTFN(0x200,
493 		("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
494 
495 	if (usbd_is_dying(sc->sc_udev))
496 		return (0);
497 
498 	offset &= 0xff;
499 	len &= 0xff;
500 
501 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
502 	req.bRequest = UDAV_REQ_REG_READ;
503 	USETW(req.wValue, 0x0000);
504 	USETW(req.wIndex, offset);
505 	USETW(req.wLength, len);
506 
507 	sc->sc_refcnt++;
508 	err = usbd_do_request(sc->sc_udev, &req, buf);
509 	if (--sc->sc_refcnt < 0)
510 		usb_detach_wakeup(&sc->sc_dev);
511 	if (err) {
512 		DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
513 			 sc->sc_dev.dv_xname, __func__, offset, err));
514 	}
515 
516 	return (err);
517 }
518 
519 /* write register(s) */
520 int
521 udav_csr_write(struct udav_softc *sc, int offset, void *buf, int len)
522 {
523 	usb_device_request_t req;
524 	usbd_status err;
525 
526 	if (sc == NULL)
527 		return (0);
528 
529 	DPRINTFN(0x200,
530 		("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
531 
532 	if (usbd_is_dying(sc->sc_udev))
533 		return (0);
534 
535 	offset &= 0xff;
536 	len &= 0xff;
537 
538 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
539 	req.bRequest = UDAV_REQ_REG_WRITE;
540 	USETW(req.wValue, 0x0000);
541 	USETW(req.wIndex, offset);
542 	USETW(req.wLength, len);
543 
544 	sc->sc_refcnt++;
545 	err = usbd_do_request(sc->sc_udev, &req, buf);
546 	if (--sc->sc_refcnt < 0)
547 		usb_detach_wakeup(&sc->sc_dev);
548 	if (err) {
549 		DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
550 			 sc->sc_dev.dv_xname, __func__, offset, err));
551 	}
552 
553 	return (err);
554 }
555 
556 int
557 udav_csr_read1(struct udav_softc *sc, int offset)
558 {
559 	u_int8_t val = 0;
560 
561 	if (sc == NULL)
562 		return (0);
563 
564 	DPRINTFN(0x200,
565 		("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
566 
567 	return (udav_csr_read(sc, offset, &val, 1) ? 0 : val);
568 }
569 
570 /* write a register */
571 int
572 udav_csr_write1(struct udav_softc *sc, int offset, unsigned char ch)
573 {
574 	usb_device_request_t req;
575 	usbd_status err;
576 
577 	if (sc == NULL)
578 		return (0);
579 
580 	DPRINTFN(0x200,
581 		("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
582 
583 	if (usbd_is_dying(sc->sc_udev))
584 		return (0);
585 
586 	offset &= 0xff;
587 
588 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
589 	req.bRequest = UDAV_REQ_REG_WRITE1;
590 	USETW(req.wValue, ch);
591 	USETW(req.wIndex, offset);
592 	USETW(req.wLength, 0x0000);
593 
594 	sc->sc_refcnt++;
595 	err = usbd_do_request(sc->sc_udev, &req, NULL);
596 	if (--sc->sc_refcnt < 0)
597 		usb_detach_wakeup(&sc->sc_dev);
598 	if (err) {
599 		DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
600 			 sc->sc_dev.dv_xname, __func__, offset, err));
601 	}
602 
603 	return (err);
604 }
605 
606 int
607 udav_init(struct ifnet *ifp)
608 {
609 	struct udav_softc *sc = ifp->if_softc;
610 	struct mii_data *mii = GET_MII(sc);
611 	u_char *eaddr;
612 	int s;
613 
614 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
615 
616 	s = splnet();
617 
618 	/* Cancel pending I/O and free all TX/RX buffers */
619 	udav_stop(ifp, 1);
620 
621         eaddr = sc->sc_ac.ac_enaddr;
622 	udav_csr_write(sc, UDAV_PAR, eaddr, ETHER_ADDR_LEN);
623 
624 	/* Initialize network control register */
625 	/*  Disable loopback  */
626 	UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1);
627 
628 	/* Initialize RX control register */
629 	UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC);
630 
631 	/* Initialize transmit ring */
632 	if (udav_tx_list_init(sc) == ENOBUFS) {
633 		printf("%s: tx list init failed\n", sc->sc_dev.dv_xname);
634 		splx(s);
635 		return (EIO);
636 	}
637 
638 	/* Initialize receive ring */
639 	if (udav_rx_list_init(sc) == ENOBUFS) {
640 		printf("%s: rx list init failed\n", sc->sc_dev.dv_xname);
641 		splx(s);
642 		return (EIO);
643 	}
644 
645 	/* Program promiscuous mode and multicast filters */
646 	udav_iff(sc);
647 
648 	/* Enable RX */
649 	UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_RXEN);
650 
651 	/* clear POWER_DOWN state of internal PHY */
652 	UDAV_SETBIT(sc, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0);
653 	UDAV_CLRBIT(sc, UDAV_GPR, UDAV_GPR_GEPIO0);
654 
655 	if (!(sc->sc_flags & UDAV_RD9700))
656 		mii_mediachg(mii);
657 
658 	if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) {
659 		if (udav_openpipes(sc)) {
660 			splx(s);
661 			return (EIO);
662 		}
663 	}
664 
665 	ifp->if_flags |= IFF_RUNNING;
666 	ifp->if_flags &= ~IFF_OACTIVE;
667 
668 	splx(s);
669 
670 	timeout_add_sec(&sc->sc_stat_ch, 1);
671 
672 	return (0);
673 }
674 
675 void
676 udav_reset(struct udav_softc *sc)
677 {
678 	int i;
679 
680 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
681 
682 	if (usbd_is_dying(sc->sc_udev))
683 		return;
684 
685 	/* Select PHY */
686 #if 1
687 	/*
688 	 * XXX: force select internal phy.
689 	 *	external phy routines are not tested.
690 	 */
691 	UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
692 #else
693 	if (sc->sc_flags & UDAV_EXT_PHY) {
694 		UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
695 	} else {
696 		UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
697 	}
698 #endif
699 
700 	UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_RST);
701 
702 	for (i = 0; i < UDAV_TX_TIMEOUT; i++) {
703 		if (!(udav_csr_read1(sc, UDAV_NCR) & UDAV_NCR_RST))
704 			break;
705 		delay(10);	/* XXX */
706 	}
707 	delay(10000);		/* XXX */
708 }
709 
710 #define UDAV_BITS	6
711 
712 void
713 udav_iff(struct udav_softc *sc)
714 {
715 	struct ifnet *ifp = GET_IFP(sc);
716 	struct arpcom *ac = &sc->sc_ac;
717 	struct ether_multi *enm;
718 	struct ether_multistep step;
719 	u_int8_t hashes[8];
720 	int h = 0;
721 
722 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
723 
724 	if (usbd_is_dying(sc->sc_udev))
725 		return;
726 
727 	UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC);
728 	memset(hashes, 0x00, sizeof(hashes));
729 	ifp->if_flags &= ~IFF_ALLMULTI;
730 
731 	if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
732 		ifp->if_flags |= IFF_ALLMULTI;
733 		UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL);
734 		if (ifp->if_flags & IFF_PROMISC)
735 			UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_PRMSC);
736 	} else {
737 		hashes[7] |= 0x80;	/* broadcast address */
738 
739 		/* now program new ones */
740 		ETHER_FIRST_MULTI(step, ac, enm);
741 		while (enm != NULL) {
742 			h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) &
743 			    ((1 << UDAV_BITS) - 1);
744 
745 			hashes[h>>3] |= 1 << (h & 0x7);
746 
747 			ETHER_NEXT_MULTI(step, enm);
748 		}
749 	}
750 
751 	udav_csr_write(sc, UDAV_MAR, hashes, sizeof(hashes));
752 }
753 
754 int
755 udav_openpipes(struct udav_softc *sc)
756 {
757 	struct udav_chain *c;
758 	usbd_status err;
759 	int i;
760 	int error = 0;
761 
762 	if (usbd_is_dying(sc->sc_udev))
763 		return (EIO);
764 
765 	sc->sc_refcnt++;
766 
767 	/* Open RX pipe */
768 	err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkin_no,
769 			     USBD_EXCLUSIVE_USE, &sc->sc_pipe_rx);
770 	if (err) {
771 		printf("%s: open rx pipe failed: %s\n",
772 		       sc->sc_dev.dv_xname, usbd_errstr(err));
773 		error = EIO;
774 		goto done;
775 	}
776 
777 	/* Open TX pipe */
778 	err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkout_no,
779 			     USBD_EXCLUSIVE_USE, &sc->sc_pipe_tx);
780 	if (err) {
781 		printf("%s: open tx pipe failed: %s\n",
782 		       sc->sc_dev.dv_xname, usbd_errstr(err));
783 		error = EIO;
784 		goto done;
785 	}
786 
787 #if 0
788 	/* XXX: interrupt endpoint is not yet supported */
789 	/* Open Interrupt pipe */
790 	err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_intrin_no,
791 				  USBD_EXCLUSIVE_USE, &sc->sc_pipe_intr, sc,
792 				  &sc->sc_cdata.udav_ibuf, UDAV_INTR_PKGLEN,
793 				  udav_intr, UDAV_INTR_INTERVAL);
794 	if (err) {
795 		printf("%s: open intr pipe failed: %s\n",
796 		       sc->sc_dev.dv_xname, usbd_errstr(err));
797 		error = EIO;
798 		goto done;
799 	}
800 #endif
801 
802 
803 	/* Start up the receive pipe. */
804 	for (i = 0; i < UDAV_RX_LIST_CNT; i++) {
805 		c = &sc->sc_cdata.udav_rx_chain[i];
806 		usbd_setup_xfer(c->udav_xfer, sc->sc_pipe_rx,
807 				c, c->udav_buf, UDAV_BUFSZ,
808 				USBD_SHORT_XFER_OK | USBD_NO_COPY,
809 				USBD_NO_TIMEOUT, udav_rxeof);
810 		(void)usbd_transfer(c->udav_xfer);
811 		DPRINTF(("%s: %s: start read\n", sc->sc_dev.dv_xname,
812 			 __func__));
813 	}
814 
815  done:
816 	if (--sc->sc_refcnt < 0)
817 		usb_detach_wakeup(&sc->sc_dev);
818 
819 	return (error);
820 }
821 
822 int
823 udav_newbuf(struct udav_softc *sc, struct udav_chain *c, struct mbuf *m)
824 {
825 	struct mbuf *m_new = NULL;
826 
827 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
828 
829 	if (m == NULL) {
830 		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
831 		if (m_new == NULL) {
832 			printf("%s: no memory for rx list "
833 			       "-- packet dropped!\n", sc->sc_dev.dv_xname);
834 			return (ENOBUFS);
835 		}
836 		MCLGET(m_new, M_DONTWAIT);
837 		if (!(m_new->m_flags & M_EXT)) {
838 			printf("%s: no memory for rx list "
839 			       "-- packet dropped!\n", sc->sc_dev.dv_xname);
840 			m_freem(m_new);
841 			return (ENOBUFS);
842 		}
843 		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
844 	} else {
845 		m_new = m;
846 		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
847 		m_new->m_data = m_new->m_ext.ext_buf;
848 	}
849 
850 	m_adj(m_new, ETHER_ALIGN);
851 	c->udav_mbuf = m_new;
852 
853 	return (0);
854 }
855 
856 
857 int
858 udav_rx_list_init(struct udav_softc *sc)
859 {
860 	struct udav_cdata *cd;
861 	struct udav_chain *c;
862 	int i;
863 
864 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
865 
866 	cd = &sc->sc_cdata;
867 	for (i = 0; i < UDAV_RX_LIST_CNT; i++) {
868 		c = &cd->udav_rx_chain[i];
869 		c->udav_sc = sc;
870 		c->udav_idx = i;
871 		if (udav_newbuf(sc, c, NULL) == ENOBUFS)
872 			return (ENOBUFS);
873 		if (c->udav_xfer == NULL) {
874 			c->udav_xfer = usbd_alloc_xfer(sc->sc_udev);
875 			if (c->udav_xfer == NULL)
876 				return (ENOBUFS);
877 			c->udav_buf = usbd_alloc_buffer(c->udav_xfer, UDAV_BUFSZ);
878 			if (c->udav_buf == NULL) {
879 				usbd_free_xfer(c->udav_xfer);
880 				return (ENOBUFS);
881 			}
882 		}
883 	}
884 
885 	return (0);
886 }
887 
888 int
889 udav_tx_list_init(struct udav_softc *sc)
890 {
891 	struct udav_cdata *cd;
892 	struct udav_chain *c;
893 	int i;
894 
895 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
896 
897 	cd = &sc->sc_cdata;
898 	for (i = 0; i < UDAV_TX_LIST_CNT; i++) {
899 		c = &cd->udav_tx_chain[i];
900 		c->udav_sc = sc;
901 		c->udav_idx = i;
902 		c->udav_mbuf = NULL;
903 		if (c->udav_xfer == NULL) {
904 			c->udav_xfer = usbd_alloc_xfer(sc->sc_udev);
905 			if (c->udav_xfer == NULL)
906 				return (ENOBUFS);
907 			c->udav_buf = usbd_alloc_buffer(c->udav_xfer, UDAV_BUFSZ);
908 			if (c->udav_buf == NULL) {
909 				usbd_free_xfer(c->udav_xfer);
910 				return (ENOBUFS);
911 			}
912 		}
913 	}
914 
915 	return (0);
916 }
917 
918 void
919 udav_start(struct ifnet *ifp)
920 {
921 	struct udav_softc *sc = ifp->if_softc;
922 	struct mbuf *m_head = NULL;
923 
924 	DPRINTF(("%s: %s: enter, link=%d\n", sc->sc_dev.dv_xname,
925 		 __func__, sc->sc_link));
926 
927 	if (usbd_is_dying(sc->sc_udev))
928 		return;
929 
930 	if (!sc->sc_link)
931 		return;
932 
933 	if (ifp->if_flags & IFF_OACTIVE)
934 		return;
935 
936 	IFQ_POLL(&ifp->if_snd, m_head);
937 	if (m_head == NULL)
938 		return;
939 
940 	if (udav_send(sc, m_head, 0)) {
941 		ifp->if_flags |= IFF_OACTIVE;
942 		return;
943 	}
944 
945 	IFQ_DEQUEUE(&ifp->if_snd, m_head);
946 
947 #if NBPFILTER > 0
948 	if (ifp->if_bpf)
949 		bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
950 #endif
951 
952 	ifp->if_flags |= IFF_OACTIVE;
953 
954 	/* Set a timeout in case the chip goes out to lunch. */
955 	ifp->if_timer = 5;
956 }
957 
958 int
959 udav_send(struct udav_softc *sc, struct mbuf *m, int idx)
960 {
961 	int total_len;
962 	struct udav_chain *c;
963 	usbd_status err;
964 
965 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname,__func__));
966 
967 	c = &sc->sc_cdata.udav_tx_chain[idx];
968 
969 	/* Copy the mbuf data into a contiguous buffer */
970 	/*  first 2 bytes are packet length */
971 	m_copydata(m, 0, m->m_pkthdr.len, c->udav_buf + 2);
972 	c->udav_mbuf = m;
973 	total_len = m->m_pkthdr.len;
974 	if (total_len < UDAV_MIN_FRAME_LEN) {
975 		memset(c->udav_buf + 2 + total_len, 0,
976 		    UDAV_MIN_FRAME_LEN - total_len);
977 		total_len = UDAV_MIN_FRAME_LEN;
978 	}
979 
980 	/* Frame length is specified in the first 2bytes of the buffer */
981 	c->udav_buf[0] = (u_int8_t)total_len;
982 	c->udav_buf[1] = (u_int8_t)(total_len >> 8);
983 	total_len += 2;
984 
985 	usbd_setup_xfer(c->udav_xfer, sc->sc_pipe_tx, c, c->udav_buf, total_len,
986 			USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
987 			UDAV_TX_TIMEOUT, udav_txeof);
988 
989 	/* Transmit */
990 	sc->sc_refcnt++;
991 	err = usbd_transfer(c->udav_xfer);
992 	if (--sc->sc_refcnt < 0)
993 		usb_detach_wakeup(&sc->sc_dev);
994 	if (err != USBD_IN_PROGRESS) {
995 		printf("%s: udav_send error=%s\n", sc->sc_dev.dv_xname,
996 		       usbd_errstr(err));
997 		/* Stop the interface */
998 		usb_add_task(sc->sc_udev, &sc->sc_stop_task);
999 		return (EIO);
1000 	}
1001 
1002 	DPRINTF(("%s: %s: send %d bytes\n", sc->sc_dev.dv_xname,
1003 		 __func__, total_len));
1004 
1005 	sc->sc_cdata.udav_tx_cnt++;
1006 
1007 	return (0);
1008 }
1009 
1010 void
1011 udav_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1012 {
1013 	struct udav_chain *c = priv;
1014 	struct udav_softc *sc = c->udav_sc;
1015 	struct ifnet *ifp = GET_IFP(sc);
1016 	int s;
1017 
1018 	if (usbd_is_dying(sc->sc_udev))
1019 		return;
1020 
1021 	s = splnet();
1022 
1023 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
1024 
1025 	ifp->if_timer = 0;
1026 	ifp->if_flags &= ~IFF_OACTIVE;
1027 
1028 	if (status != USBD_NORMAL_COMPLETION) {
1029 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1030 			splx(s);
1031 			return;
1032 		}
1033 		ifp->if_oerrors++;
1034 		printf("%s: usb error on tx: %s\n", sc->sc_dev.dv_xname,
1035 		       usbd_errstr(status));
1036 		if (status == USBD_STALLED) {
1037 			sc->sc_refcnt++;
1038 			usbd_clear_endpoint_stall_async(sc->sc_pipe_tx);
1039 			if (--sc->sc_refcnt < 0)
1040 				usb_detach_wakeup(&sc->sc_dev);
1041 		}
1042 		splx(s);
1043 		return;
1044 	}
1045 
1046 	ifp->if_opackets++;
1047 
1048 	m_freem(c->udav_mbuf);
1049 	c->udav_mbuf = NULL;
1050 
1051 	if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1052 		udav_start(ifp);
1053 
1054 	splx(s);
1055 }
1056 
1057 void
1058 udav_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1059 {
1060 	struct udav_chain *c = priv;
1061 	struct udav_softc *sc = c->udav_sc;
1062 	struct ifnet *ifp = GET_IFP(sc);
1063 	struct udav_rx_hdr *h;
1064 	struct mbuf *m;
1065 	u_int32_t total_len;
1066 	int s;
1067 
1068 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname,__func__));
1069 
1070 	if (usbd_is_dying(sc->sc_udev))
1071 		return;
1072 
1073 	if (status != USBD_NORMAL_COMPLETION) {
1074 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1075 			return;
1076 		sc->sc_rx_errs++;
1077 		if (usbd_ratecheck(&sc->sc_rx_notice)) {
1078 			printf("%s: %u usb errors on rx: %s\n",
1079 			       sc->sc_dev.dv_xname, sc->sc_rx_errs,
1080 			       usbd_errstr(status));
1081 			sc->sc_rx_errs = 0;
1082 		}
1083 		if (status == USBD_STALLED) {
1084 			sc->sc_refcnt++;
1085 			usbd_clear_endpoint_stall_async(sc->sc_pipe_rx);
1086 			if (--sc->sc_refcnt < 0)
1087 				usb_detach_wakeup(&sc->sc_dev);
1088 		}
1089 		goto done;
1090 	}
1091 
1092 	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
1093 
1094 	if (total_len < UDAV_RX_HDRLEN) {
1095 		ifp->if_ierrors++;
1096 		goto done;
1097 	}
1098 
1099 	h = (struct udav_rx_hdr *)c->udav_buf;
1100 	total_len = UGETW(h->length) - ETHER_CRC_LEN;
1101 
1102 	DPRINTF(("%s: RX Status: 0x%02x\n", sc->sc_dev.dv_xname, h->pktstat));
1103 
1104 	if (h->pktstat & UDAV_RSR_LCS) {
1105 		ifp->if_collisions++;
1106 		goto done;
1107 	}
1108 
1109 	/* RX status may still be correct but total_len is bogus */
1110 	if (total_len < sizeof(struct ether_header) ||
1111 	    h->pktstat & UDAV_RSR_ERR ||
1112 	    total_len > UDAV_BUFSZ ) {
1113 		ifp->if_ierrors++;
1114 		goto done;
1115 	}
1116 
1117 	/* copy data to mbuf */
1118 	m = c->udav_mbuf;
1119 	memcpy(mtod(m, char *), c->udav_buf + UDAV_RX_HDRLEN, total_len);
1120 
1121 	ifp->if_ipackets++;
1122 
1123 	m->m_pkthdr.len = m->m_len = total_len;
1124 	m->m_pkthdr.rcvif = ifp;
1125 
1126 	s = splnet();
1127 
1128 	if (udav_newbuf(sc, c, NULL) == ENOBUFS) {
1129 		ifp->if_ierrors++;
1130 		goto done1;
1131 	}
1132 
1133 #if NBPFILTER > 0
1134 	if (ifp->if_bpf)
1135 		bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
1136 #endif
1137 
1138 	DPRINTF(("%s: %s: deliver %d\n", sc->sc_dev.dv_xname,
1139 		 __func__, m->m_len));
1140 	ether_input_mbuf(ifp, m);
1141 
1142  done1:
1143 	splx(s);
1144 
1145  done:
1146 	/* Setup new transfer */
1147 	usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->udav_buf, UDAV_BUFSZ,
1148 			USBD_SHORT_XFER_OK | USBD_NO_COPY,
1149 			USBD_NO_TIMEOUT, udav_rxeof);
1150 	sc->sc_refcnt++;
1151 	usbd_transfer(xfer);
1152 	if (--sc->sc_refcnt < 0)
1153 		usb_detach_wakeup(&sc->sc_dev);
1154 
1155 	DPRINTF(("%s: %s: start rx\n", sc->sc_dev.dv_xname, __func__));
1156 }
1157 
1158 int
1159 udav_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1160 {
1161 	struct udav_softc *sc = ifp->if_softc;
1162 	struct ifaddr *ifa = (struct ifaddr *)data;
1163 	struct ifreq *ifr = (struct ifreq *)data;
1164 	int s, error = 0;
1165 
1166 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
1167 
1168 	if (usbd_is_dying(sc->sc_udev))
1169 		return (EIO);
1170 
1171 	s = splnet();
1172 
1173 	switch (cmd) {
1174 	case SIOCSIFADDR:
1175 		ifp->if_flags |= IFF_UP;
1176 		if (!(ifp->if_flags & IFF_RUNNING))
1177 			udav_init(ifp);
1178 
1179 #ifdef INET
1180 		if (ifa->ifa_addr->sa_family == AF_INET)
1181 			arp_ifinit(&sc->sc_ac, ifa);
1182 #endif
1183 		break;
1184 
1185 	case SIOCSIFFLAGS:
1186 		if (ifp->if_flags & IFF_UP) {
1187 			if (ifp->if_flags & IFF_RUNNING)
1188 				error = ENETRESET;
1189 			else
1190 				udav_init(ifp);
1191 		} else {
1192 			if (ifp->if_flags & IFF_RUNNING)
1193 				udav_stop(ifp, 1);
1194 		}
1195 		break;
1196 
1197 	case SIOCGIFMEDIA:
1198 	case SIOCSIFMEDIA:
1199 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
1200 		break;
1201 
1202 	default:
1203 		error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
1204 	}
1205 
1206 	if (error == ENETRESET) {
1207 		if (ifp->if_flags & IFF_RUNNING)
1208 			udav_iff(sc);
1209 		error = 0;
1210 	}
1211 
1212 	splx(s);
1213 	return (error);
1214 }
1215 
1216 void
1217 udav_watchdog(struct ifnet *ifp)
1218 {
1219 	struct udav_softc *sc = ifp->if_softc;
1220 	struct udav_chain *c;
1221 	usbd_status stat;
1222 	int s;
1223 
1224 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
1225 
1226 	ifp->if_oerrors++;
1227 	printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
1228 
1229 	s = splusb();
1230 	c = &sc->sc_cdata.udav_tx_chain[0];
1231 	usbd_get_xfer_status(c->udav_xfer, NULL, NULL, NULL, &stat);
1232 	udav_txeof(c->udav_xfer, c, stat);
1233 
1234 	if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1235 		udav_start(ifp);
1236 	splx(s);
1237 }
1238 
1239 void
1240 udav_stop_task(struct udav_softc *sc)
1241 {
1242 	udav_stop(GET_IFP(sc), 1);
1243 }
1244 
1245 /* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
1246 void
1247 udav_stop(struct ifnet *ifp, int disable)
1248 {
1249 	struct udav_softc *sc = ifp->if_softc;
1250 	usbd_status err;
1251 	int i;
1252 
1253 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
1254 
1255 	ifp->if_timer = 0;
1256 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1257 
1258 	udav_reset(sc);
1259 
1260 	timeout_del(&sc->sc_stat_ch);
1261 
1262 	/* Stop transfers */
1263 	/* RX endpoint */
1264 	if (sc->sc_pipe_rx != NULL) {
1265 		usbd_abort_pipe(sc->sc_pipe_rx);
1266 		err = usbd_close_pipe(sc->sc_pipe_rx);
1267 		if (err)
1268 			printf("%s: close rx pipe failed: %s\n",
1269 			       sc->sc_dev.dv_xname, usbd_errstr(err));
1270 		sc->sc_pipe_rx = NULL;
1271 	}
1272 
1273 	/* TX endpoint */
1274 	if (sc->sc_pipe_tx != NULL) {
1275 		usbd_abort_pipe(sc->sc_pipe_tx);
1276 		err = usbd_close_pipe(sc->sc_pipe_tx);
1277 		if (err)
1278 			printf("%s: close tx pipe failed: %s\n",
1279 			       sc->sc_dev.dv_xname, usbd_errstr(err));
1280 		sc->sc_pipe_tx = NULL;
1281 	}
1282 
1283 #if 0
1284 	/* XXX: Interrupt endpoint is not yet supported!! */
1285 	/* Interrupt endpoint */
1286 	if (sc->sc_pipe_intr != NULL) {
1287 		usbd_abort_pipe(sc->sc_pipe_intr);
1288 		err = usbd_close_pipe(sc->sc_pipe_intr);
1289 		if (err)
1290 			printf("%s: close intr pipe failed: %s\n",
1291 			       sc->sc_dev.dv_xname, usbd_errstr(err));
1292 		sc->sc_pipe_intr = NULL;
1293 	}
1294 #endif
1295 
1296 	/* Free RX resources. */
1297 	for (i = 0; i < UDAV_RX_LIST_CNT; i++) {
1298 		if (sc->sc_cdata.udav_rx_chain[i].udav_mbuf != NULL) {
1299 			m_freem(sc->sc_cdata.udav_rx_chain[i].udav_mbuf);
1300 			sc->sc_cdata.udav_rx_chain[i].udav_mbuf = NULL;
1301 		}
1302 		if (sc->sc_cdata.udav_rx_chain[i].udav_xfer != NULL) {
1303 			usbd_free_xfer(sc->sc_cdata.udav_rx_chain[i].udav_xfer);
1304 			sc->sc_cdata.udav_rx_chain[i].udav_xfer = NULL;
1305 		}
1306 	}
1307 
1308 	/* Free TX resources. */
1309 	for (i = 0; i < UDAV_TX_LIST_CNT; i++) {
1310 		if (sc->sc_cdata.udav_tx_chain[i].udav_mbuf != NULL) {
1311 			m_freem(sc->sc_cdata.udav_tx_chain[i].udav_mbuf);
1312 			sc->sc_cdata.udav_tx_chain[i].udav_mbuf = NULL;
1313 		}
1314 		if (sc->sc_cdata.udav_tx_chain[i].udav_xfer != NULL) {
1315 			usbd_free_xfer(sc->sc_cdata.udav_tx_chain[i].udav_xfer);
1316 			sc->sc_cdata.udav_tx_chain[i].udav_xfer = NULL;
1317 		}
1318 	}
1319 
1320 	sc->sc_link = 0;
1321 }
1322 
1323 /* Set media options */
1324 int
1325 udav_ifmedia_change(struct ifnet *ifp)
1326 {
1327 	struct udav_softc *sc = ifp->if_softc;
1328 	struct mii_data *mii = GET_MII(sc);
1329 
1330 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
1331 
1332 	if (usbd_is_dying(sc->sc_udev))
1333 		return (0);
1334 
1335 	sc->sc_link = 0;
1336 
1337 	if (sc->sc_flags & UDAV_RD9700)
1338 		return (0);
1339 
1340 	if (mii->mii_instance) {
1341 		struct mii_softc *miisc;
1342 		for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
1343 		     miisc = LIST_NEXT(miisc, mii_list))
1344 			mii_phy_reset(miisc);
1345 	}
1346 
1347 	return (mii_mediachg(mii));
1348 }
1349 
1350 /* Report current media status. */
1351 void
1352 udav_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
1353 {
1354 	struct udav_softc *sc = ifp->if_softc;
1355 	struct mii_data *mii = GET_MII(sc);
1356 
1357 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
1358 
1359 	if (usbd_is_dying(sc->sc_udev))
1360 		return;
1361 
1362 	if ((ifp->if_flags & IFF_RUNNING) == 0) {
1363 		ifmr->ifm_active = IFM_ETHER | IFM_NONE;
1364 		ifmr->ifm_status = 0;
1365 		return;
1366 	}
1367 
1368 	if (sc->sc_flags & UDAV_RD9700) {
1369 		ifmr->ifm_active = IFM_ETHER | IFM_10_T;
1370 		ifmr->ifm_status = IFM_AVALID;
1371 		if (sc->sc_link) ifmr->ifm_status |= IFM_ACTIVE;
1372 		return;
1373 	}
1374 
1375 	mii_pollstat(mii);
1376 	ifmr->ifm_active = mii->mii_media_active;
1377 	ifmr->ifm_status = mii->mii_media_status;
1378 }
1379 
1380 void
1381 udav_tick(void *xsc)
1382 {
1383 	struct udav_softc *sc = xsc;
1384 
1385 	if (sc == NULL)
1386 		return;
1387 
1388 	DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname,
1389 			__func__));
1390 
1391 	/* Perform periodic stuff in process context */
1392 	usb_add_task(sc->sc_udev, &sc->sc_tick_task);
1393 }
1394 
1395 void
1396 udav_tick_task(void *xsc)
1397 {
1398 	struct udav_softc *sc = xsc;
1399 	struct ifnet *ifp;
1400 	struct mii_data *mii;
1401 	int s, sts;
1402 
1403 	if (sc == NULL)
1404 		return;
1405 
1406 	DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname,
1407 			__func__));
1408 
1409 	if (usbd_is_dying(sc->sc_udev))
1410 		return;
1411 
1412 	ifp = GET_IFP(sc);
1413 	mii = GET_MII(sc);
1414 
1415 	if (mii == NULL)
1416 		return;
1417 
1418 	s = splnet();
1419 
1420 	if (sc->sc_flags & UDAV_RD9700) {
1421 		sts = udav_csr_read1(sc, UDAV_NSR) & UDAV_NSR_LINKST;
1422 		if (!sts)
1423 			sc->sc_link = 0;
1424 	} else {
1425 		mii_tick(mii);
1426 		sts = (mii->mii_media_status & IFM_ACTIVE &&
1427 		       IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) ? 1 : 0;
1428 	}
1429 
1430 	if (!sc->sc_link && sts) {
1431 		DPRINTF(("%s: %s: got link\n",
1432 			 sc->sc_dev.dv_xname, __func__));
1433 		sc->sc_link++;
1434 		if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1435 			   udav_start(ifp);
1436 	}
1437 
1438 	timeout_add_sec(&sc->sc_stat_ch, 1);
1439 
1440 	splx(s);
1441 }
1442 
1443 /* Get exclusive access to the MII registers */
1444 void
1445 udav_lock_mii(struct udav_softc *sc)
1446 {
1447 	DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname,
1448 			__func__));
1449 
1450 	sc->sc_refcnt++;
1451 	rw_enter_write(&sc->sc_mii_lock);
1452 }
1453 
1454 void
1455 udav_unlock_mii(struct udav_softc *sc)
1456 {
1457 	DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname,
1458 		       __func__));
1459 
1460 	rw_exit_write(&sc->sc_mii_lock);
1461 	if (--sc->sc_refcnt < 0)
1462 		usb_detach_wakeup(&sc->sc_dev);
1463 }
1464 
1465 int
1466 udav_miibus_readreg(struct device *dev, int phy, int reg)
1467 {
1468 	struct udav_softc *sc;
1469 	u_int8_t val[2];
1470 	u_int16_t data16;
1471 
1472 	if (dev == NULL)
1473 		return (0);
1474 
1475 	sc = (void *)dev;
1476 
1477 	DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
1478 		 sc->sc_dev.dv_xname, __func__, phy, reg));
1479 
1480 	if (usbd_is_dying(sc->sc_udev)) {
1481 #ifdef DIAGNOSTIC
1482 		printf("%s: %s: dying\n", sc->sc_dev.dv_xname,
1483 		       __func__);
1484 #endif
1485 		return (0);
1486 	}
1487 
1488 	/* XXX: one PHY only for the internal PHY */
1489 	if (phy != 0) {
1490 		DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1491 			 sc->sc_dev.dv_xname, __func__, phy));
1492 		return (0);
1493 	}
1494 
1495 	udav_lock_mii(sc);
1496 
1497 	/* select internal PHY and set PHY register address */
1498 	udav_csr_write1(sc, UDAV_EPAR,
1499 			UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
1500 
1501 	/* select PHY operation and start read command */
1502 	udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR);
1503 
1504 	/* XXX: should be wait? */
1505 
1506 	/* end read command */
1507 	UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRR);
1508 
1509 	/* retrieve the result from data registers */
1510 	udav_csr_read(sc, UDAV_EPDRL, val, 2);
1511 
1512 	udav_unlock_mii(sc);
1513 
1514 	data16 = val[0] | (val[1] << 8);
1515 
1516 	DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
1517 		 sc->sc_dev.dv_xname, __func__, phy, reg, data16));
1518 
1519 	return (data16);
1520 }
1521 
1522 void
1523 udav_miibus_writereg(struct device *dev, int phy, int reg, int data)
1524 {
1525 	struct udav_softc *sc;
1526 	u_int8_t val[2];
1527 
1528 	if (dev == NULL)
1529 		return;
1530 
1531 	sc = (void *)dev;
1532 
1533 	DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
1534 		 sc->sc_dev.dv_xname, __func__, phy, reg, data));
1535 
1536 	if (usbd_is_dying(sc->sc_udev)) {
1537 #ifdef DIAGNOSTIC
1538 		printf("%s: %s: dying\n", sc->sc_dev.dv_xname,
1539 		       __func__);
1540 #endif
1541 		return;
1542 	}
1543 
1544 	/* XXX: one PHY only for the internal PHY */
1545 	if (phy != 0) {
1546 		DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
1547 			 sc->sc_dev.dv_xname, __func__, phy));
1548 		return;
1549 	}
1550 
1551 	udav_lock_mii(sc);
1552 
1553 	/* select internal PHY and set PHY register address */
1554 	udav_csr_write1(sc, UDAV_EPAR,
1555 			UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
1556 
1557 	/* put the value to the data registers */
1558 	val[0] = data & 0xff;
1559 	val[1] = (data >> 8) & 0xff;
1560 	udav_csr_write(sc, UDAV_EPDRL, val, 2);
1561 
1562 	/* select PHY operation and start write command */
1563 	udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW);
1564 
1565 	/* XXX: should be wait? */
1566 
1567 	/* end write command */
1568 	UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRW);
1569 
1570 	udav_unlock_mii(sc);
1571 
1572 	return;
1573 }
1574 
1575 void
1576 udav_miibus_statchg(struct device *dev)
1577 {
1578 #ifdef UDAV_DEBUG
1579 	struct udav_softc *sc;
1580 
1581 	if (dev == NULL)
1582 		return;
1583 
1584 	sc = (void *)dev;
1585 	DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));
1586 #endif
1587 	/* Nothing to do */
1588 }
1589