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