xref: /netbsd-src/sys/dev/usb/if_aue.c (revision 5aefcfdc06931dd97e76246d2fe0302f7b3fe094)
1 /*	$NetBSD: if_aue.c,v 1.50 2000/12/14 07:51:36 thorpej Exp $	*/
2 /*
3  * Copyright (c) 1997, 1998, 1999, 2000
4  *	Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *	This product includes software developed by Bill Paul.
17  * 4. Neither the name of the author nor the names of any co-contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31  * THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * $FreeBSD: src/sys/dev/usb/if_aue.c,v 1.11 2000/01/14 01:36:14 wpaul Exp $
34  */
35 
36 /*
37  * ADMtek AN986 Pegasus USB to ethernet driver. Datasheet is available
38  * from http://www.admtek.com.tw.
39  *
40  * Written by Bill Paul <wpaul@ee.columbia.edu>
41  * Electrical Engineering Department
42  * Columbia University, New York City
43  */
44 
45 /*
46  * The Pegasus chip uses four USB "endpoints" to provide 10/100 ethernet
47  * support: the control endpoint for reading/writing registers, burst
48  * read endpoint for packet reception, burst write for packet transmission
49  * and one for "interrupts." The chip uses the same RX filter scheme
50  * as the other ADMtek ethernet parts: one perfect filter entry for the
51  * the station address and a 64-bit multicast hash table. The chip supports
52  * both MII and HomePNA attachments.
53  *
54  * Since the maximum data transfer speed of USB is supposed to be 12Mbps,
55  * you're never really going to get 100Mbps speeds from this device. I
56  * think the idea is to allow the device to connect to 10 or 100Mbps
57  * networks, not necessarily to provide 100Mbps performance. Also, since
58  * the controller uses an external PHY chip, it's possible that board
59  * designers might simply choose a 10Mbps PHY.
60  *
61  * Registers are accessed using usbd_do_request(). Packet transfers are
62  * done using usbd_transfer() and friends.
63  */
64 
65 /*
66  * Ported to NetBSD and somewhat rewritten by Lennart Augustsson.
67  */
68 
69 /*
70  * TODO:
71  * better error messages from rxstat
72  * split out if_auevar.h
73  * add thread to avoid register reads from interrupt context
74  * more error checks
75  * investigate short rx problem
76  * proper cleanup on errors
77  */
78 
79 #if defined(__NetBSD__)
80 #include "opt_inet.h"
81 #include "opt_ns.h"
82 #include "bpfilter.h"
83 #include "rnd.h"
84 #elif defined(__OpenBSD__)
85 #include "bpfilter.h"
86 #endif /* defined(__OpenBSD__) */
87 
88 #include <sys/param.h>
89 #include <sys/systm.h>
90 #include <sys/sockio.h>
91 #include <sys/mbuf.h>
92 #include <sys/malloc.h>
93 #include <sys/kernel.h>
94 #include <sys/socket.h>
95 
96 #if defined(__FreeBSD__)
97 
98 #include <net/ethernet.h>
99 #include <machine/clock.h>	/* for DELAY */
100 #include <sys/bus.h>
101 /* "controller miibus0" required.  See GENERIC if you get errors here. */
102 #include "miibus_if.h"
103 
104 #elif defined(__NetBSD__) || defined(__OpenBSD__)
105 
106 #include <sys/device.h>
107 #if NRND > 0
108 #include <sys/rnd.h>
109 #endif
110 
111 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
112 
113 #include <net/if.h>
114 #if defined(__NetBSD__) || defined(__FreeBSD__)
115 #include <net/if_arp.h>
116 #endif
117 #include <net/if_dl.h>
118 #include <net/if_media.h>
119 
120 #if defined(__NetBSD__) || defined(__OpenBSD__)
121 #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
122 #else
123 #define BPF_MTAP(ifp, m) bpf_mtap((ifp), (m))
124 #endif
125 
126 #if defined(__FreeBSD__) || NBPFILTER > 0
127 #include <net/bpf.h>
128 #endif
129 
130 #if defined(__NetBSD__)
131 #include <net/if_ether.h>
132 #ifdef INET
133 #include <netinet/in.h>
134 #include <netinet/if_inarp.h>
135 #endif
136 #endif /* defined(__NetBSD__) */
137 
138 #if defined(__OpenBSD__)
139 #ifdef INET
140 #include <netinet/in.h>
141 #include <netinet/in_systm.h>
142 #include <netinet/in_var.h>
143 #include <netinet/ip.h>
144 #include <netinet/if_ether.h>
145 #endif
146 #endif /* defined(__OpenBSD__) */
147 
148 #if defined(__NetBSD__) || defined(__OpenBSD__)
149 #ifdef NS
150 #include <netns/ns.h>
151 #include <netns/ns_if.h>
152 #endif
153 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
154 
155 #include <dev/mii/mii.h>
156 #include <dev/mii/miivar.h>
157 
158 #include <dev/usb/usb.h>
159 #include <dev/usb/usbdi.h>
160 #include <dev/usb/usbdi_util.h>
161 #include <dev/usb/usbdevs.h>
162 
163 #ifdef __FreeBSD__
164 #include <dev/usb/usb_ethersubr.h>
165 #endif
166 
167 #include <dev/usb/if_auereg.h>
168 
169 #ifdef AUE_DEBUG
170 #define DPRINTF(x)	if (auedebug) logprintf x
171 #define DPRINTFN(n,x)	if (auedebug >= (n)) logprintf x
172 int	auedebug = 0;
173 #else
174 #define DPRINTF(x)
175 #define DPRINTFN(n,x)
176 #endif
177 
178 /*
179  * Various supported device vendors/products.
180  */
181 struct aue_type {
182 	u_int16_t		aue_vid;
183 	u_int16_t		aue_did;
184 	char			aue_linksys;
185 };
186 
187 Static struct aue_type aue_devs[] = {
188   { USB_VENDOR_BILLIONTON,	USB_PRODUCT_BILLIONTON_USB100,	0 },
189   { USB_VENDOR_MELCO, 		USB_PRODUCT_MELCO_LUATX1, 	0 },
190   { USB_VENDOR_MELCO, 		USB_PRODUCT_MELCO_LUATX5, 	0 },
191   { USB_VENDOR_LINKSYS,		USB_PRODUCT_LINKSYS_USB100TX,	1 },
192   { USB_VENDOR_LINKSYS,		USB_PRODUCT_LINKSYS_USB100H1,	1 },
193   { USB_VENDOR_LINKSYS,		USB_PRODUCT_LINKSYS_USB10TA,	1 },
194   { USB_VENDOR_ADMTEK,		USB_PRODUCT_ADMTEK_PEGASUS,	0 },
195   { USB_VENDOR_DLINK,		USB_PRODUCT_DLINK_DSB650,	1 },
196   { USB_VENDOR_DLINK,		USB_PRODUCT_DLINK_DSB650TX,	1 },
197   { USB_VENDOR_DLINK,		USB_PRODUCT_DLINK_DSB650TX_PNA,	0 },
198   { USB_VENDOR_SMC,		USB_PRODUCT_SMC_2202USB,	0 },
199   { USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_FETHER_USB_TX, 0 },
200   { USB_VENDOR_IODATA,		USB_PRODUCT_IODATA_USBETTX,	0 },
201   { USB_VENDOR_KINGSTON,	USB_PRODUCT_KINGSTON_KNU101TX,  0 },
202   { 0, 0, 0 }
203 };
204 
205 USB_DECLARE_DRIVER(aue);
206 
207 Static struct aue_type *aue_lookup(u_int16_t vendor, u_int16_t product);
208 Static int aue_tx_list_init(struct aue_softc *);
209 Static int aue_rx_list_init(struct aue_softc *);
210 Static int aue_newbuf(struct aue_softc *, struct aue_chain *, struct mbuf *);
211 Static int aue_send(struct aue_softc *, struct mbuf *, int);
212 Static void aue_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
213 Static void aue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
214 Static void aue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
215 Static void aue_tick(void *);
216 Static void aue_start(struct ifnet *);
217 Static int aue_ioctl(struct ifnet *, u_long, caddr_t);
218 Static void aue_init(void *);
219 Static void aue_stop(struct aue_softc *);
220 Static void aue_watchdog(struct ifnet *);
221 #ifdef __FreeBSD__
222 Static void aue_shutdown(device_ptr_t);
223 #endif
224 Static int aue_openpipes(struct aue_softc *);
225 Static int aue_ifmedia_upd(struct ifnet *);
226 Static void aue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
227 
228 Static int aue_eeprom_getword(struct aue_softc *, int);
229 Static void aue_read_mac(struct aue_softc *, u_char *);
230 Static int aue_miibus_readreg(device_ptr_t, int, int);
231 #if defined(__FreeBSD__)
232 Static int aue_miibus_writereg(device_ptr_t, int, int, int);
233 #elif defined(__NetBSD__) || defined(__OpenBSD__)
234 Static void aue_miibus_writereg(device_ptr_t, int, int, int);
235 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
236 Static void aue_miibus_statchg(device_ptr_t);
237 
238 Static void aue_setmulti(struct aue_softc *);
239 Static u_int32_t aue_crc(caddr_t);
240 Static void aue_reset(struct aue_softc *);
241 
242 Static int aue_csr_read_1(struct aue_softc *, int);
243 Static int aue_csr_write_1(struct aue_softc *, int, int);
244 Static int aue_csr_read_2(struct aue_softc *, int);
245 Static int aue_csr_write_2(struct aue_softc *, int, int);
246 
247 #if defined(__FreeBSD__)
248 #if !defined(lint)
249 static const char rcsid[] =
250   "$FreeBSD: src/sys/dev/usb/if_aue.c,v 1.11 2000/01/14 01:36:14 wpaul Exp $";
251 #endif
252 
253 Static void aue_rxstart(struct ifnet *);
254 
255 Static struct usb_qdat aue_qdat;
256 
257 Static device_method_t aue_methods[] = {
258 	/* Device interface */
259 	DEVMETHOD(device_probe,		aue_match),
260 	DEVMETHOD(device_attach,	aue_attach),
261 	DEVMETHOD(device_detach,	aue_detach),
262 	DEVMETHOD(device_shutdown,	aue_shutdown),
263 
264 	/* bus interface */
265 	DEVMETHOD(bus_print_child,	bus_generic_print_child),
266 	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
267 
268 	/* MII interface */
269 	DEVMETHOD(miibus_readreg,	aue_miibus_readreg),
270 	DEVMETHOD(miibus_writereg,	aue_miibus_writereg),
271 	DEVMETHOD(miibus_statchg,	aue_miibus_statchg),
272 
273 	{ 0, 0 }
274 };
275 
276 Static driver_t aue_driver = {
277 	"aue",
278 	aue_methods,
279 	sizeof(struct aue_softc)
280 };
281 
282 Static devclass_t aue_devclass;
283 
284 DRIVER_MODULE(if_aue, uhub, aue_driver, aue_devclass, usbd_driver_load, 0);
285 DRIVER_MODULE(miibus, aue, miibus_driver, miibus_devclass, 0, 0);
286 
287 #endif /* __FreeBSD__ */
288 
289 #define AUE_DO_REQUEST(dev, req, data)			\
290 	usbd_do_request_flags(dev, req, data, USBD_NO_TSLEEP, NULL)
291 
292 #define AUE_SETBIT(sc, reg, x)				\
293 	aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x))
294 
295 #define AUE_CLRBIT(sc, reg, x)				\
296 	aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) & ~(x))
297 
298 Static int
299 aue_csr_read_1(struct aue_softc *sc, int reg)
300 {
301 	usb_device_request_t	req;
302 	usbd_status		err;
303 	uByte			val = 0;
304 	int			s;
305 
306 	if (sc->aue_dying)
307 		return (0);
308 
309 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
310 	req.bRequest = AUE_UR_READREG;
311 	USETW(req.wValue, 0);
312 	USETW(req.wIndex, reg);
313 	USETW(req.wLength, 1);
314 
315 	s = splusb();
316 	err = AUE_DO_REQUEST(sc->aue_udev, &req, &val);
317 	splx(s);
318 
319 	if (err) {
320 		DPRINTF(("%s: aue_csr_read_1: reg=0x%x err=%s\n",
321 			 USBDEVNAME(sc->aue_dev), reg, usbd_errstr(err)));
322 		return (0);
323 	}
324 
325 	return (val);
326 }
327 
328 Static int
329 aue_csr_read_2(struct aue_softc *sc, int reg)
330 {
331 	usb_device_request_t	req;
332 	usbd_status		err;
333 	uWord			val;
334 	int			s;
335 
336 	if (sc->aue_dying)
337 		return (0);
338 
339 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
340 	req.bRequest = AUE_UR_READREG;
341 	USETW(req.wValue, 0);
342 	USETW(req.wIndex, reg);
343 	USETW(req.wLength, 2);
344 
345 	s = splusb();
346 	err = AUE_DO_REQUEST(sc->aue_udev, &req, &val);
347 	splx(s);
348 
349 	if (err) {
350 		DPRINTF(("%s: aue_csr_read_2: reg=0x%x err=%s\n",
351 			 USBDEVNAME(sc->aue_dev), reg, usbd_errstr(err)));
352 		return (0);
353 	}
354 
355 	return (UGETW(val));
356 }
357 
358 Static int
359 aue_csr_write_1(struct aue_softc *sc, int reg, int aval)
360 {
361 	usb_device_request_t	req;
362 	usbd_status		err;
363 	int			s;
364 	uByte			val;
365 
366 	if (sc->aue_dying)
367 		return (0);
368 
369 	val = aval;
370 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
371 	req.bRequest = AUE_UR_WRITEREG;
372 	USETW(req.wValue, val);
373 	USETW(req.wIndex, reg);
374 	USETW(req.wLength, 1);
375 
376 	s = splusb();
377 	err = AUE_DO_REQUEST(sc->aue_udev, &req, &val);
378 	splx(s);
379 
380 	if (err) {
381 		DPRINTF(("%s: aue_csr_write_1: reg=0x%x err=%s\n",
382 			 USBDEVNAME(sc->aue_dev), reg, usbd_errstr(err)));
383 		return (-1);
384 	}
385 
386 	return (0);
387 }
388 
389 Static int
390 aue_csr_write_2(struct aue_softc *sc, int reg, int aval)
391 {
392 	usb_device_request_t	req;
393 	usbd_status		err;
394 	int			s;
395 	uWord			val;
396 
397 	if (sc->aue_dying)
398 		return (0);
399 
400 	USETW(val, aval);
401 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
402 	req.bRequest = AUE_UR_WRITEREG;
403 	USETW(req.wValue, aval);
404 	USETW(req.wIndex, reg);
405 	USETW(req.wLength, 2);
406 
407 	s = splusb();
408 	err = AUE_DO_REQUEST(sc->aue_udev, &req, &val);
409 	splx(s);
410 
411 	if (err) {
412 		DPRINTF(("%s: aue_csr_write_2: reg=0x%x err=%s\n",
413 			 USBDEVNAME(sc->aue_dev), reg, usbd_errstr(err)));
414 		return (-1);
415 	}
416 
417 	return (0);
418 }
419 
420 /*
421  * Read a word of data stored in the EEPROM at address 'addr.'
422  */
423 Static int
424 aue_eeprom_getword(struct aue_softc *sc, int addr)
425 {
426 	int		i;
427 
428 	aue_csr_write_1(sc, AUE_EE_REG, addr);
429 	aue_csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ);
430 
431 	for (i = 0; i < AUE_TIMEOUT; i++) {
432 		if (aue_csr_read_1(sc, AUE_EE_CTL) & AUE_EECTL_DONE)
433 			break;
434 	}
435 
436 	if (i == AUE_TIMEOUT) {
437 		printf("%s: EEPROM read timed out\n",
438 		    USBDEVNAME(sc->aue_dev));
439 	}
440 
441 	return (aue_csr_read_2(sc, AUE_EE_DATA));
442 }
443 
444 /*
445  * Read the MAC from the EEPROM.  It's at offset 0.
446  */
447 Static void
448 aue_read_mac(struct aue_softc *sc, u_char *dest)
449 {
450 	int			i;
451 	int			off = 0;
452 	int			word;
453 
454 	DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__));
455 
456 	for (i = 0; i < 3; i++) {
457 		word = aue_eeprom_getword(sc, off + i);
458 		dest[2 * i] = (u_char)word;
459 		dest[2 * i + 1] = (u_char)(word >> 8);
460 	}
461 }
462 
463 Static int
464 aue_miibus_readreg(device_ptr_t dev, int phy, int reg)
465 {
466 	struct aue_softc	*sc = USBGETSOFTC(dev);
467 	int			i;
468 	u_int16_t		val;
469 
470 	/*
471 	 * The Am79C901 HomePNA PHY actually contains
472 	 * two transceivers: a 1Mbps HomePNA PHY and a
473 	 * 10Mbps full/half duplex ethernet PHY with
474 	 * NWAY autoneg. However in the ADMtek adapter,
475 	 * only the 1Mbps PHY is actually connected to
476 	 * anything, so we ignore the 10Mbps one. It
477 	 * happens to be configured for MII address 3,
478 	 * so we filter that out.
479 	 */
480 	if (sc->aue_vendor == USB_VENDOR_ADMTEK &&
481 	    sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) {
482 		if (phy != 1)
483 			return (0);
484 	}
485 
486 	aue_csr_write_1(sc, AUE_PHY_ADDR, phy);
487 	aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_READ);
488 
489 	for (i = 0; i < AUE_TIMEOUT; i++) {
490 		if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE)
491 			break;
492 	}
493 
494 	if (i == AUE_TIMEOUT) {
495 		printf("%s: MII read timed out\n",
496 		    USBDEVNAME(sc->aue_dev));
497 	}
498 
499 	val = aue_csr_read_2(sc, AUE_PHY_DATA);
500 
501 	DPRINTFN(11,("%s: %s: phy=%d reg=%d => 0x%04x\n",
502 		     USBDEVNAME(sc->aue_dev), __FUNCTION__, phy, reg, val));
503 
504 	return (val);
505 }
506 
507 #if defined(__FreeBSD__)
508 Static int
509 #elif defined(__NetBSD__) || defined(__OpenBSD__)
510 Static void
511 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
512 aue_miibus_writereg(device_ptr_t dev, int phy, int reg, int data)
513 {
514 	struct aue_softc	*sc = USBGETSOFTC(dev);
515 	int			i;
516 
517 	if (sc->aue_vendor == USB_VENDOR_ADMTEK &&
518 	    sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) {
519 		if (phy == 3)
520 #if defined(__FreeBSD__)
521 			return (0);
522 #elif defined(__NetBSD__) || defined(__OpenBSD__)
523 			return;
524 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
525 	}
526 
527 	DPRINTFN(11,("%s: %s: phy=%d reg=%d data=0x%04x\n",
528 		     USBDEVNAME(sc->aue_dev), __FUNCTION__, phy, reg, data));
529 
530 	aue_csr_write_2(sc, AUE_PHY_DATA, data);
531 	aue_csr_write_1(sc, AUE_PHY_ADDR, phy);
532 	aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_WRITE);
533 
534 	for (i = 0; i < AUE_TIMEOUT; i++) {
535 		if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE)
536 			break;
537 	}
538 
539 	if (i == AUE_TIMEOUT) {
540 		printf("%s: MII read timed out\n",
541 		    USBDEVNAME(sc->aue_dev));
542 	}
543 
544 #if defined(__FreeBSD__)
545 	return (0);
546 #endif
547 }
548 
549 Static void
550 aue_miibus_statchg(device_ptr_t dev)
551 {
552 	struct aue_softc	*sc = USBGETSOFTC(dev);
553 	struct mii_data		*mii = GET_MII(sc);
554 
555 	DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__));
556 
557 	AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
558 
559 	if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) {
560 		AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL);
561 	} else {
562 		AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL);
563 	}
564 
565 	if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
566 		AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX);
567 	else
568 		AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX);
569 
570 	AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
571 
572 	/*
573 	 * Set the LED modes on the LinkSys adapter.
574 	 * This turns on the 'dual link LED' bin in the auxmode
575 	 * register of the Broadcom PHY.
576 	 */
577 	if (sc->aue_linksys) {
578 		u_int16_t auxmode;
579 		auxmode = aue_miibus_readreg(dev, 0, 0x1b);
580 		aue_miibus_writereg(dev, 0, 0x1b, auxmode | 0x04);
581 	}
582 }
583 
584 #define AUE_POLY	0xEDB88320
585 #define AUE_BITS	6
586 
587 Static u_int32_t
588 aue_crc(caddr_t addr)
589 {
590 	u_int32_t		idx, bit, data, crc;
591 
592 	/* Compute CRC for the address value. */
593 	crc = 0xFFFFFFFF; /* initial value */
594 
595 	for (idx = 0; idx < 6; idx++) {
596 		for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1)
597 			crc = (crc >> 1) ^ (((crc ^ data) & 1) ? AUE_POLY : 0);
598 	}
599 
600 	return (crc & ((1 << AUE_BITS) - 1));
601 }
602 
603 Static void
604 aue_setmulti(struct aue_softc *sc)
605 {
606 	struct ifnet		*ifp;
607 #if defined(__FreeBSD__)
608 	struct ifmultiaddr	*ifma;
609 #elif defined(__NetBSD__) || defined(__OpenBSD__)
610 	struct ether_multi	*enm;
611 	struct ether_multistep	step;
612 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
613 	u_int32_t		h = 0, i;
614 
615 	DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__));
616 
617 	ifp = GET_IFP(sc);
618 
619 	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
620 		AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
621 		return;
622 	}
623 
624 	AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
625 
626 	/* first, zot all the existing hash bits */
627 	for (i = 0; i < 8; i++)
628 		aue_csr_write_1(sc, AUE_MAR0 + i, 0);
629 
630 	/* now program new ones */
631 #if defined(__FreeBSD__)
632 	for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL;
633 	    ifma = ifma->ifma_link.le_next) {
634 		if (ifma->ifma_addr->sa_family != AF_LINK)
635 			continue;
636 		h = aue_crc(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
637 		AUE_SETBIT(sc, AUE_MAR + (h >> 3), 1 << (h & 0x7));
638 	}
639 #elif defined(__NetBSD__) || defined(__OpenBSD__)
640 #if defined(__NetBSD__)
641 	ETHER_FIRST_MULTI(step, &sc->aue_ec, enm);
642 #else
643 	ETHER_FIRST_MULTI(step, &sc->arpcom, enm);
644 #endif
645 	while (enm != NULL) {
646 #if 1
647 		if (memcmp(enm->enm_addrlo,
648 			   enm->enm_addrhi, ETHER_ADDR_LEN) != 0) {
649 			ifp->if_flags |= IFF_ALLMULTI;
650 			AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
651 			return;
652 		}
653 #endif
654 		h = aue_crc(enm->enm_addrlo);
655 		AUE_SETBIT(sc, AUE_MAR + (h >> 3), 1 << (h & 0x7));
656 		ETHER_NEXT_MULTI(step, enm);
657 	}
658 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
659 }
660 
661 Static void
662 aue_reset(struct aue_softc *sc)
663 {
664 	int		i;
665 
666 	DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__));
667 
668 	AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_RESETMAC);
669 
670 	for (i = 0; i < AUE_TIMEOUT; i++) {
671 		if (!(aue_csr_read_1(sc, AUE_CTL1) & AUE_CTL1_RESETMAC))
672 			break;
673 	}
674 
675 	if (i == AUE_TIMEOUT)
676 		printf("%s: reset failed\n", USBDEVNAME(sc->aue_dev));
677 
678 	/*
679 	 * The PHY(s) attached to the Pegasus chip may be held
680 	 * in reset until we flip on the GPIO outputs. Make sure
681 	 * to set the GPIO pins high so that the PHY(s) will
682 	 * be enabled.
683 	 *
684 	 * Note: We force all of the GPIO pins low first, *then*
685 	 * enable the ones we want.
686   	 */
687 	aue_csr_write_1(sc, AUE_GPIO0,
688 	    AUE_GPIO_OUT0 | AUE_GPIO_SEL0);
689   	aue_csr_write_1(sc, AUE_GPIO0,
690 	    AUE_GPIO_OUT0 | AUE_GPIO_SEL0 | AUE_GPIO_SEL1);
691 
692 	/* Grrr. LinkSys has to be different from everyone else. */
693 	if (sc->aue_linksys) {
694 		aue_csr_write_1(sc, AUE_GPIO0,
695 		    AUE_GPIO_SEL0 | AUE_GPIO_SEL1);
696 		aue_csr_write_1(sc, AUE_GPIO0,
697 		    AUE_GPIO_SEL0 | AUE_GPIO_SEL1 | AUE_GPIO_OUT0);
698 	}
699 
700 	/* Wait a little while for the chip to get its brains in order. */
701 	delay(10000);		/* XXX */
702 }
703 
704 Static struct aue_type *
705 aue_lookup(u_int16_t vendor, u_int16_t product)
706 {
707 	struct aue_type	*t;
708 
709 	for (t = aue_devs; t->aue_vid != 0; t++)
710 		if (vendor == t->aue_vid && product == t->aue_did)
711 			return (t);
712 	return (NULL);
713 }
714 
715 /*
716  * Probe for a Pegasus chip.
717  */
718 USB_MATCH(aue)
719 {
720 	USB_MATCH_START(aue, uaa);
721 
722 	if (uaa->iface != NULL)
723 		return (UMATCH_NONE);
724 
725 	return (aue_lookup(uaa->vendor, uaa->product) != NULL ?
726 		UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
727 }
728 
729 /*
730  * Attach the interface. Allocate softc structures, do ifmedia
731  * setup and ethernet/BPF attach.
732  */
733 USB_ATTACH(aue)
734 {
735 	USB_ATTACH_START(aue, sc, uaa);
736 	char			devinfo[1024];
737 	int			s;
738 	u_char			eaddr[ETHER_ADDR_LEN];
739 	struct ifnet		*ifp;
740 	struct mii_data		*mii;
741 	usbd_device_handle	dev = uaa->device;
742 	usbd_interface_handle	iface;
743 	usbd_status		err;
744 	usb_interface_descriptor_t	*id;
745 	usb_endpoint_descriptor_t	*ed;
746 	int			i;
747 
748 #ifdef __FreeBSD__
749 	bzero(sc, sizeof(struct aue_softc));
750 #endif
751 
752 	DPRINTFN(5,(" : aue_attach: sc=%p", sc));
753 
754 	usbd_devinfo(dev, 0, devinfo);
755 	USB_ATTACH_SETUP;
756 	printf("%s: %s\n", USBDEVNAME(sc->aue_dev), devinfo);
757 
758 	err = usbd_set_config_no(dev, AUE_CONFIG_NO, 1);
759 	if (err) {
760 		printf("%s: setting config no failed\n",
761 		    USBDEVNAME(sc->aue_dev));
762 		USB_ATTACH_ERROR_RETURN;
763 	}
764 
765 	err = usbd_device2interface_handle(dev, AUE_IFACE_IDX, &iface);
766 	if (err) {
767 		printf("%s: getting interface handle failed\n",
768 		    USBDEVNAME(sc->aue_dev));
769 		USB_ATTACH_ERROR_RETURN;
770 	}
771 
772 	sc->aue_linksys = aue_lookup(uaa->vendor, uaa->product)->aue_linksys;
773 
774 	sc->aue_udev = dev;
775 	sc->aue_iface = iface;
776 	sc->aue_product = uaa->product;
777 	sc->aue_vendor = uaa->vendor;
778 
779 	id = usbd_get_interface_descriptor(iface);
780 
781 	/* Find endpoints. */
782 	for (i = 0; i < id->bNumEndpoints; i++) {
783 		ed = usbd_interface2endpoint_descriptor(iface, i);
784 		if (ed == NULL) {
785 			printf("%s: couldn't get endpoint descriptor %d\n",
786 			    USBDEVNAME(sc->aue_dev), i);
787 			USB_ATTACH_ERROR_RETURN;
788 		}
789 		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
790 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
791 			sc->aue_ed[AUE_ENDPT_RX] = ed->bEndpointAddress;
792 		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
793 			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
794 			sc->aue_ed[AUE_ENDPT_TX] = ed->bEndpointAddress;
795 		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
796 			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
797 			sc->aue_ed[AUE_ENDPT_INTR] = ed->bEndpointAddress;
798 		}
799 	}
800 
801 	if (sc->aue_ed[AUE_ENDPT_RX] == 0 || sc->aue_ed[AUE_ENDPT_TX] == 0 ||
802 	    sc->aue_ed[AUE_ENDPT_INTR] == 0) {
803 		printf("%s: missing endpoint\n", USBDEVNAME(sc->aue_dev));
804 		USB_ATTACH_ERROR_RETURN;
805 	}
806 
807 
808 	s = splimp();
809 
810 	/* Reset the adapter. */
811 	aue_reset(sc);
812 
813 	/*
814 	 * Get station address from the EEPROM.
815 	 */
816 	aue_read_mac(sc, eaddr);
817 
818 	/*
819 	 * A Pegasus chip was detected. Inform the world.
820 	 */
821 	ifp = GET_IFP(sc);
822 #if defined(__FreeBSD__)
823 	printf("%s: Ethernet address: %6D\n", USBDEVNAME(sc->aue_dev),
824 	    eaddr, ":");
825 
826 	bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
827 
828 	ifp->if_softc = sc;
829 	ifp->if_unit = sc->aue_unit;
830 	ifp->if_name = "aue";
831 	ifp->if_mtu = ETHERMTU;
832 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
833 	ifp->if_ioctl = aue_ioctl;
834 	ifp->if_output = ether_output;
835 	ifp->if_start = aue_start;
836 	ifp->if_watchdog = aue_watchdog;
837 	ifp->if_init = aue_init;
838 	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
839 
840 	/*
841 	 * Do MII setup.
842 	 * NOTE: Doing this causes child devices to be attached to us,
843 	 * which we would normally disconnect at in the detach routine
844 	 * using device_delete_child(). However the USB code is set up
845 	 * such that when this driver is removed, all childred devices
846 	 * are removed as well. In effect, the USB code ends up detaching
847 	 * all of our children for us, so we don't have to do is ourselves
848 	 * in aue_detach(). It's important to point this out since if
849 	 * we *do* try to detach the child devices ourselves, we will
850 	 * end up getting the children deleted twice, which will crash
851 	 * the system.
852 	 */
853 	if (mii_phy_probe(self, &sc->aue_miibus,
854 	    aue_ifmedia_upd, aue_ifmedia_sts)) {
855 		printf("%s: MII without any PHY!\n", USBDEVNAME(sc->aue_dev));
856 		splx(s);
857 		USB_ATTACH_ERROR_RETURN;
858 	}
859 
860 	aue_qdat.ifp = ifp;
861 	aue_qdat.if_rxstart = aue_rxstart;
862 
863 	/*
864 	 * Call MI attach routines.
865 	 */
866 	if_attach(ifp);
867 	ether_ifattach(ifp);
868 	bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
869 
870 	usb_register_netisr();
871 
872 #elif defined(__NetBSD__) || defined(__OpenBSD__)
873 
874 	printf("%s: Ethernet address %s\n", USBDEVNAME(sc->aue_dev),
875 	    ether_sprintf(eaddr));
876 
877 	/* Initialize interface info.*/
878 	ifp->if_softc = sc;
879 	ifp->if_mtu = ETHERMTU;
880 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
881 	ifp->if_ioctl = aue_ioctl;
882 	ifp->if_start = aue_start;
883 	ifp->if_watchdog = aue_watchdog;
884 #if defined(__OpenBSD__)
885 	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
886 #endif
887 	strncpy(ifp->if_xname, USBDEVNAME(sc->aue_dev), IFNAMSIZ);
888 
889 	IFQ_SET_READY(&ifp->if_snd);
890 
891 	/* Initialize MII/media info. */
892 	mii = &sc->aue_mii;
893 	mii->mii_ifp = ifp;
894 	mii->mii_readreg = aue_miibus_readreg;
895 	mii->mii_writereg = aue_miibus_writereg;
896 	mii->mii_statchg = aue_miibus_statchg;
897 	ifmedia_init(&mii->mii_media, 0, aue_ifmedia_upd, aue_ifmedia_sts);
898 	mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
899 	if (LIST_FIRST(&mii->mii_phys) == NULL) {
900 		ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
901 		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
902 	} else
903 		ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
904 
905 	/* Attach the interface. */
906 	if_attach(ifp);
907 	Ether_ifattach(ifp, eaddr);
908 #if NRND > 0
909 	rnd_attach_source(&sc->rnd_source, USBDEVNAME(sc->aue_dev),
910 	    RND_TYPE_NET, 0);
911 #endif
912 
913 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
914 
915 	usb_callout_init(sc->aue_stat_ch);
916 
917 	sc->aue_attached = 1;
918 	splx(s);
919 
920 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->aue_udev,
921 			   USBDEV(sc->aue_dev));
922 
923 	USB_ATTACH_SUCCESS_RETURN;
924 }
925 
926 USB_DETACH(aue)
927 {
928 	USB_DETACH_START(aue, sc);
929 	struct ifnet		*ifp = GET_IFP(sc);
930 	int			s;
931 
932 	DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__));
933 
934 	s = splusb();
935 
936 	usb_uncallout(sc->aue_stat_ch, aue_tick, sc);
937 
938 	if (!sc->aue_attached) {
939 		/* Detached before attached finished, so just bail out. */
940 		splx(s);
941 		return (0);
942 	}
943 
944 	if (ifp->if_flags & IFF_RUNNING)
945 		aue_stop(sc);
946 
947 #if defined(__NetBSD__)
948 #if NRND > 0
949 	rnd_detach_source(&sc->rnd_source);
950 #endif
951 	mii_detach(&sc->aue_mii, MII_PHY_ANY, MII_OFFSET_ANY);
952 	ifmedia_delete_instance(&sc->aue_mii.mii_media, IFM_INST_ANY);
953 	ether_ifdetach(ifp);
954 #endif /* __NetBSD__ */
955 
956 	if_detach(ifp);
957 
958 #ifdef DIAGNOSTIC
959 	if (sc->aue_ep[AUE_ENDPT_TX] != NULL ||
960 	    sc->aue_ep[AUE_ENDPT_RX] != NULL ||
961 	    sc->aue_ep[AUE_ENDPT_INTR] != NULL)
962 		printf("%s: detach has active endpoints\n",
963 		       USBDEVNAME(sc->aue_dev));
964 #endif
965 
966 	sc->aue_attached = 0;
967 	splx(s);
968 
969 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->aue_udev,
970 			   USBDEV(sc->aue_dev));
971 
972 	return (0);
973 }
974 
975 #if defined(__NetBSD__) || defined(__OpenBSD__)
976 int
977 aue_activate(device_ptr_t self, enum devact act)
978 {
979 	struct aue_softc *sc = (struct aue_softc *)self;
980 
981 	DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__));
982 
983 	switch (act) {
984 	case DVACT_ACTIVATE:
985 		return (EOPNOTSUPP);
986 		break;
987 
988 	case DVACT_DEACTIVATE:
989 		if_deactivate(&sc->aue_ec.ec_if);
990 		sc->aue_dying = 1;
991 		break;
992 	}
993 	return (0);
994 }
995 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
996 
997 /*
998  * Initialize an RX descriptor and attach an MBUF cluster.
999  */
1000 Static int
1001 aue_newbuf(struct aue_softc *sc, struct aue_chain *c, struct mbuf *m)
1002 {
1003 	struct mbuf		*m_new = NULL;
1004 
1005 	DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__FUNCTION__));
1006 
1007 	if (m == NULL) {
1008 		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1009 		if (m_new == NULL) {
1010 			printf("%s: no memory for rx list "
1011 			    "-- packet dropped!\n", USBDEVNAME(sc->aue_dev));
1012 			return (ENOBUFS);
1013 		}
1014 
1015 		MCLGET(m_new, M_DONTWAIT);
1016 		if (!(m_new->m_flags & M_EXT)) {
1017 			printf("%s: no memory for rx list "
1018 			    "-- packet dropped!\n", USBDEVNAME(sc->aue_dev));
1019 			m_freem(m_new);
1020 			return (ENOBUFS);
1021 		}
1022 		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1023 	} else {
1024 		m_new = m;
1025 		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1026 		m_new->m_data = m_new->m_ext.ext_buf;
1027 	}
1028 
1029 	m_adj(m_new, ETHER_ALIGN);
1030 	c->aue_mbuf = m_new;
1031 
1032 	return (0);
1033 }
1034 
1035 Static int
1036 aue_rx_list_init(struct aue_softc *sc)
1037 {
1038 	struct aue_cdata	*cd;
1039 	struct aue_chain	*c;
1040 	int			i;
1041 
1042 	DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__));
1043 
1044 	cd = &sc->aue_cdata;
1045 	for (i = 0; i < AUE_RX_LIST_CNT; i++) {
1046 		c = &cd->aue_rx_chain[i];
1047 		c->aue_sc = sc;
1048 		c->aue_idx = i;
1049 		if (aue_newbuf(sc, c, NULL) == ENOBUFS)
1050 			return (ENOBUFS);
1051 		if (c->aue_xfer == NULL) {
1052 			c->aue_xfer = usbd_alloc_xfer(sc->aue_udev);
1053 			if (c->aue_xfer == NULL)
1054 				return (ENOBUFS);
1055 			c->aue_buf = usbd_alloc_buffer(c->aue_xfer, AUE_BUFSZ);
1056 			if (c->aue_buf == NULL)
1057 				return (ENOBUFS); /* XXX free xfer */
1058 		}
1059 	}
1060 
1061 	return (0);
1062 }
1063 
1064 Static int
1065 aue_tx_list_init(struct aue_softc *sc)
1066 {
1067 	struct aue_cdata	*cd;
1068 	struct aue_chain	*c;
1069 	int			i;
1070 
1071 	DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__));
1072 
1073 	cd = &sc->aue_cdata;
1074 	for (i = 0; i < AUE_TX_LIST_CNT; i++) {
1075 		c = &cd->aue_tx_chain[i];
1076 		c->aue_sc = sc;
1077 		c->aue_idx = i;
1078 		c->aue_mbuf = NULL;
1079 		if (c->aue_xfer == NULL) {
1080 			c->aue_xfer = usbd_alloc_xfer(sc->aue_udev);
1081 			if (c->aue_xfer == NULL)
1082 				return (ENOBUFS);
1083 			c->aue_buf = usbd_alloc_buffer(c->aue_xfer, AUE_BUFSZ);
1084 			if (c->aue_buf == NULL)
1085 				return (ENOBUFS);
1086 		}
1087 	}
1088 
1089 	return (0);
1090 }
1091 
1092 Static void
1093 aue_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1094 {
1095 	struct aue_softc	*sc = priv;
1096 	struct ifnet		*ifp = GET_IFP(sc);
1097 	struct aue_intrpkt	*p = &sc->aue_cdata.aue_ibuf;
1098 
1099 	DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__FUNCTION__));
1100 
1101 	if (sc->aue_dying)
1102 		return;
1103 
1104 	if (!(ifp->if_flags & IFF_RUNNING))
1105 		return;
1106 
1107 	if (status != USBD_NORMAL_COMPLETION) {
1108 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1109 			return;
1110 		}
1111 		sc->aue_intr_errs++;
1112 		if (usbd_ratecheck(&sc->aue_rx_notice)) {
1113 			printf("%s: %u usb errors on intr: %s\n",
1114 			    USBDEVNAME(sc->aue_dev), sc->aue_rx_errs,
1115 			    usbd_errstr(status));
1116 			sc->aue_intr_errs = 0;
1117 		}
1118 		if (status == USBD_STALLED)
1119 			usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]);
1120 		return;
1121 	}
1122 
1123 	if (p->aue_txstat0)
1124 		ifp->if_oerrors++;
1125 
1126 	if (p->aue_txstat0 & (AUE_TXSTAT0_LATECOLL | AUE_TXSTAT0_EXCESSCOLL))
1127 		ifp->if_collisions++;
1128 }
1129 
1130 #if defined(__FreeBSD__)
1131 Static void
1132 aue_rxstart(struct ifnet *ifp)
1133 {
1134 	struct aue_softc	*sc;
1135 	struct aue_chain	*c;
1136 
1137 	sc = ifp->if_softc;
1138 	c = &sc->aue_cdata.aue_rx_chain[sc->aue_cdata.aue_rx_prod];
1139 
1140 	if (aue_newbuf(sc, c, NULL) == ENOBUFS) {
1141 		ifp->if_ierrors++;
1142 		return;
1143 	}
1144 
1145 	/* Setup new transfer. */
1146 	usbd_setup_xfer(c->aue_xfer, sc->aue_ep[AUE_ENDPT_RX],
1147 	    c, mtod(c->aue_mbuf, char *), AUE_BUFSZ, USBD_SHORT_XFER_OK,
1148 	    USBD_NO_TIMEOUT, aue_rxeof);
1149 	usbd_transfer(c->aue_xfer);
1150 }
1151 #endif
1152 
1153 /*
1154  * A frame has been uploaded: pass the resulting mbuf chain up to
1155  * the higher level protocols.
1156  */
1157 Static void
1158 aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1159 {
1160 	struct aue_chain	*c = priv;
1161 	struct aue_softc	*sc = c->aue_sc;
1162 	struct ifnet		*ifp = GET_IFP(sc);
1163 	struct mbuf		*m;
1164 	u_int32_t		total_len;
1165 	struct aue_rxpkt	r;
1166 #if defined(__NetBSD__) || defined(__OpenBSD__)
1167 	int			s;
1168 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1169 
1170 	DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__FUNCTION__));
1171 
1172 	if (sc->aue_dying)
1173 		return;
1174 
1175 	if (!(ifp->if_flags & IFF_RUNNING))
1176 		return;
1177 
1178 	if (status != USBD_NORMAL_COMPLETION) {
1179 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1180 			return;
1181 		sc->aue_rx_errs++;
1182 		if (usbd_ratecheck(&sc->aue_rx_notice)) {
1183 			printf("%s: %u usb errors on rx: %s\n",
1184 			    USBDEVNAME(sc->aue_dev), sc->aue_rx_errs,
1185 			    usbd_errstr(status));
1186 			sc->aue_rx_errs = 0;
1187 		}
1188 		if (status == USBD_STALLED)
1189 			usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]);
1190 		goto done;
1191 	}
1192 
1193 	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
1194 
1195 	memcpy(mtod(c->aue_mbuf, char*), c->aue_buf, total_len);
1196 
1197 	if (total_len <= 4 + ETHER_CRC_LEN) {
1198 		ifp->if_ierrors++;
1199 		goto done;
1200 	}
1201 
1202 	memcpy(&r, c->aue_buf + total_len - 4, sizeof(r));
1203 
1204 	/* Turn off all the non-error bits in the rx status word. */
1205 	r.aue_rxstat &= AUE_RXSTAT_MASK;
1206 	if (r.aue_rxstat) {
1207 		ifp->if_ierrors++;
1208 		goto done;
1209 	}
1210 
1211 	/* No errors; receive the packet. */
1212 	m = c->aue_mbuf;
1213 	total_len -= ETHER_CRC_LEN + 4;
1214 	m->m_pkthdr.len = m->m_len = total_len;
1215 	ifp->if_ipackets++;
1216 
1217 #if defined(__FreeBSD__)
1218 	m->m_pkthdr.rcvif = (struct ifnet *)&kue_qdat;
1219 	/* Put the packet on the special USB input queue. */
1220 	usb_ether_input(m);
1221 
1222 	return;
1223 
1224 #elif defined(__NetBSD__) || defined(__OpenBSD__)
1225 	m->m_pkthdr.rcvif = ifp;
1226 
1227 	s = splimp();
1228 
1229 	/* XXX ugly */
1230 	if (aue_newbuf(sc, c, NULL) == ENOBUFS) {
1231 		ifp->if_ierrors++;
1232 		goto done1;
1233 	}
1234 
1235 #if NBPFILTER > 0
1236 	/*
1237 	 * Handle BPF listeners. Let the BPF user see the packet, but
1238 	 * don't pass it up to the ether_input() layer unless it's
1239 	 * a broadcast packet, multicast packet, matches our ethernet
1240 	 * address or the interface is in promiscuous mode.
1241 	 */
1242 	if (ifp->if_bpf)
1243 		BPF_MTAP(ifp, m);
1244 #endif
1245 
1246 	DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->aue_dev),
1247 		    __FUNCTION__, m->m_len));
1248 	IF_INPUT(ifp, m);
1249  done1:
1250 	splx(s);
1251 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1252 
1253  done:
1254 
1255 	/* Setup new transfer. */
1256 	usbd_setup_xfer(xfer, sc->aue_ep[AUE_ENDPT_RX],
1257 	    c, c->aue_buf, AUE_BUFSZ,
1258 	    USBD_SHORT_XFER_OK | USBD_NO_COPY,
1259 	    USBD_NO_TIMEOUT, aue_rxeof);
1260 	usbd_transfer(xfer);
1261 
1262 	DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->aue_dev),
1263 		    __FUNCTION__));
1264 }
1265 
1266 /*
1267  * A frame was downloaded to the chip. It's safe for us to clean up
1268  * the list buffers.
1269  */
1270 
1271 Static void
1272 aue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1273 {
1274 	struct aue_chain	*c = priv;
1275 	struct aue_softc	*sc = c->aue_sc;
1276 	struct ifnet		*ifp = GET_IFP(sc);
1277 	int			s;
1278 
1279 	if (sc->aue_dying)
1280 		return;
1281 
1282 	s = splimp();
1283 
1284 	DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->aue_dev),
1285 		    __FUNCTION__, status));
1286 
1287 	ifp->if_timer = 0;
1288 	ifp->if_flags &= ~IFF_OACTIVE;
1289 
1290 	if (status != USBD_NORMAL_COMPLETION) {
1291 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1292 			splx(s);
1293 			return;
1294 		}
1295 		ifp->if_oerrors++;
1296 		printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->aue_dev),
1297 		    usbd_errstr(status));
1298 		if (status == USBD_STALLED)
1299 			usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_TX]);
1300 		splx(s);
1301 		return;
1302 	}
1303 
1304 	ifp->if_opackets++;
1305 
1306 #if defined(__FreeBSD__)
1307 	c->aue_mbuf->m_pkthdr.rcvif = ifp;
1308 	usb_tx_done(c->aue_mbuf);
1309   	c->aue_mbuf = NULL;
1310 #elif defined(__NetBSD__) || defined(__OpenBSD__)
1311 	m_freem(c->aue_mbuf);
1312 	c->aue_mbuf = NULL;
1313 
1314 	if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1315 		aue_start(ifp);
1316 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1317 
1318 	splx(s);
1319 }
1320 
1321 Static void
1322 aue_tick(void *xsc)
1323 {
1324 	struct aue_softc	*sc = xsc;
1325 	struct ifnet		*ifp;
1326 	struct mii_data		*mii;
1327 	int			s;
1328 
1329 	DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__FUNCTION__));
1330 
1331 	if (sc == NULL)
1332 		return;
1333 
1334 	if (sc->aue_dying)
1335 		return;
1336 
1337 	ifp = GET_IFP(sc);
1338 	mii = GET_MII(sc);
1339 	if (mii == NULL)
1340 		return;
1341 
1342 	s = splimp();
1343 
1344 	mii_tick(mii);
1345 	if (!sc->aue_link) {
1346 		mii_pollstat(mii);
1347 		if (mii->mii_media_status & IFM_ACTIVE &&
1348 		    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
1349 			DPRINTFN(2,("%s: %s: got link\n",
1350 				    USBDEVNAME(sc->aue_dev),__FUNCTION__));
1351 			sc->aue_link++;
1352 			if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1353 				aue_start(ifp);
1354 		}
1355 	}
1356 
1357 	usb_callout(sc->aue_stat_ch, hz, aue_tick, sc);
1358 
1359 	splx(s);
1360 }
1361 
1362 Static int
1363 aue_send(struct aue_softc *sc, struct mbuf *m, int idx)
1364 {
1365 	int			total_len;
1366 	struct aue_chain	*c;
1367 	usbd_status		err;
1368 
1369 	DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__FUNCTION__));
1370 
1371 	c = &sc->aue_cdata.aue_tx_chain[idx];
1372 
1373 	/*
1374 	 * Copy the mbuf data into a contiguous buffer, leaving two
1375 	 * bytes at the beginning to hold the frame length.
1376 	 */
1377 	m_copydata(m, 0, m->m_pkthdr.len, c->aue_buf + 2);
1378 	c->aue_mbuf = m;
1379 
1380 	/*
1381 	 * The ADMtek documentation says that the packet length is
1382 	 * supposed to be specified in the first two bytes of the
1383 	 * transfer, however it actually seems to ignore this info
1384 	 * and base the frame size on the bulk transfer length.
1385 	 */
1386 	c->aue_buf[0] = (u_int8_t)m->m_pkthdr.len;
1387 	c->aue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
1388 	total_len = m->m_pkthdr.len + 2;
1389 
1390 	usbd_setup_xfer(c->aue_xfer, sc->aue_ep[AUE_ENDPT_TX],
1391 	    c, c->aue_buf, total_len, USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
1392 	    AUE_TX_TIMEOUT, aue_txeof);
1393 
1394 	/* Transmit */
1395 	err = usbd_transfer(c->aue_xfer);
1396 	if (err != USBD_IN_PROGRESS) {
1397 		printf("%s: aue_send error=%s\n", USBDEVNAME(sc->aue_dev),
1398 		       usbd_errstr(err));
1399 		aue_stop(sc);
1400 		return (EIO);
1401 	}
1402 	DPRINTFN(5,("%s: %s: send %d bytes\n", USBDEVNAME(sc->aue_dev),
1403 		    __FUNCTION__, total_len));
1404 
1405 	sc->aue_cdata.aue_tx_cnt++;
1406 
1407 	return (0);
1408 }
1409 
1410 Static void
1411 aue_start(struct ifnet *ifp)
1412 {
1413 	struct aue_softc	*sc = ifp->if_softc;
1414 	struct mbuf		*m_head = NULL;
1415 
1416 	DPRINTFN(5,("%s: %s: enter, link=%d\n", USBDEVNAME(sc->aue_dev),
1417 		    __FUNCTION__, sc->aue_link));
1418 
1419 	if (sc->aue_dying)
1420 		return;
1421 
1422 	if (!sc->aue_link)
1423 		return;
1424 
1425 	if (ifp->if_flags & IFF_OACTIVE)
1426 		return;
1427 
1428 	IFQ_POLL(&ifp->if_snd, m_head);
1429 	if (m_head == NULL)
1430 		return;
1431 
1432 	if (aue_send(sc, m_head, 0)) {
1433 		ifp->if_flags |= IFF_OACTIVE;
1434 		return;
1435 	}
1436 
1437 	IFQ_DEQUEUE(&ifp->if_snd, m_head);
1438 
1439 #if NBPFILTER > 0
1440 	/*
1441 	 * If there's a BPF listener, bounce a copy of this frame
1442 	 * to him.
1443 	 */
1444 	if (ifp->if_bpf)
1445 		BPF_MTAP(ifp, m_head);
1446 #endif
1447 
1448 	ifp->if_flags |= IFF_OACTIVE;
1449 
1450 	/*
1451 	 * Set a timeout in case the chip goes out to lunch.
1452 	 */
1453 	ifp->if_timer = 5;
1454 }
1455 
1456 Static void
1457 aue_init(void *xsc)
1458 {
1459 	struct aue_softc	*sc = xsc;
1460 	struct ifnet		*ifp = GET_IFP(sc);
1461 	struct mii_data		*mii = GET_MII(sc);
1462 	int			i, s;
1463 	u_char			*eaddr;
1464 
1465 	DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__));
1466 
1467 	if (sc->aue_dying)
1468 		return;
1469 
1470 	if (ifp->if_flags & IFF_RUNNING)
1471 		return;
1472 
1473 	s = splimp();
1474 
1475 	/*
1476 	 * Cancel pending I/O and free all RX/TX buffers.
1477 	 */
1478 	aue_reset(sc);
1479 
1480 #if defined(__FreeBSD__) || defined(__OpenBSD__)
1481 	eaddr = sc->arpcom.ac_enaddr;
1482 #elif defined(__NetBSD__)
1483 	eaddr = LLADDR(ifp->if_sadl);
1484 #endif /* defined(__NetBSD__) */
1485 	for (i = 0; i < ETHER_ADDR_LEN; i++)
1486 		aue_csr_write_1(sc, AUE_PAR0 + i, eaddr[i]);
1487 
1488 	 /* If we want promiscuous mode, set the allframes bit. */
1489 	if (ifp->if_flags & IFF_PROMISC)
1490 		AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
1491 	else
1492 		AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
1493 
1494 	/* Init TX ring. */
1495 	if (aue_tx_list_init(sc) == ENOBUFS) {
1496 		printf("%s: tx list init failed\n", USBDEVNAME(sc->aue_dev));
1497 		splx(s);
1498 		return;
1499 	}
1500 
1501 	/* Init RX ring. */
1502 	if (aue_rx_list_init(sc) == ENOBUFS) {
1503 		printf("%s: rx list init failed\n", USBDEVNAME(sc->aue_dev));
1504 		splx(s);
1505 		return;
1506 	}
1507 
1508 	/* Load the multicast filter. */
1509 	aue_setmulti(sc);
1510 
1511 	/* Enable RX and TX */
1512 	aue_csr_write_1(sc, AUE_CTL0, AUE_CTL0_RXSTAT_APPEND | AUE_CTL0_RX_ENB);
1513 	AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_TX_ENB);
1514 	AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_EP3_CLR);
1515 
1516 	mii_mediachg(mii);
1517 
1518 	if (sc->aue_ep[AUE_ENDPT_RX] == NULL) {
1519 		if (aue_openpipes(sc)) {
1520 			splx(s);
1521 			return;
1522 		}
1523 	}
1524 
1525 	ifp->if_flags |= IFF_RUNNING;
1526 	ifp->if_flags &= ~IFF_OACTIVE;
1527 
1528 	splx(s);
1529 
1530 	usb_callout(sc->aue_stat_ch, hz, aue_tick, sc);
1531 }
1532 
1533 Static int
1534 aue_openpipes(struct aue_softc *sc)
1535 {
1536 	struct aue_chain	*c;
1537 	usbd_status		err;
1538 	int i;
1539 
1540 	/* Open RX and TX pipes. */
1541 	err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_RX],
1542 	    USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_RX]);
1543 	if (err) {
1544 		printf("%s: open rx pipe failed: %s\n",
1545 		    USBDEVNAME(sc->aue_dev), usbd_errstr(err));
1546 		return (EIO);
1547 	}
1548 	err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_TX],
1549 	    USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_TX]);
1550 	if (err) {
1551 		printf("%s: open tx pipe failed: %s\n",
1552 		    USBDEVNAME(sc->aue_dev), usbd_errstr(err));
1553 		return (EIO);
1554 	}
1555 	err = usbd_open_pipe_intr(sc->aue_iface, sc->aue_ed[AUE_ENDPT_INTR],
1556 	    USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_INTR], sc,
1557 	    &sc->aue_cdata.aue_ibuf, AUE_INTR_PKTLEN, aue_intr,
1558 	    AUE_INTR_INTERVAL);
1559 	if (err) {
1560 		printf("%s: open intr pipe failed: %s\n",
1561 		    USBDEVNAME(sc->aue_dev), usbd_errstr(err));
1562 		return (EIO);
1563 	}
1564 
1565 	/* Start up the receive pipe. */
1566 	for (i = 0; i < AUE_RX_LIST_CNT; i++) {
1567 		c = &sc->aue_cdata.aue_rx_chain[i];
1568 		usbd_setup_xfer(c->aue_xfer, sc->aue_ep[AUE_ENDPT_RX],
1569 		    c, c->aue_buf, AUE_BUFSZ,
1570 		    USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
1571 		    aue_rxeof);
1572 		(void)usbd_transfer(c->aue_xfer); /* XXX */
1573 		DPRINTFN(5,("%s: %s: start read\n", USBDEVNAME(sc->aue_dev),
1574 			    __FUNCTION__));
1575 
1576 	}
1577 	return (0);
1578 }
1579 
1580 /*
1581  * Set media options.
1582  */
1583 Static int
1584 aue_ifmedia_upd(struct ifnet *ifp)
1585 {
1586 	struct aue_softc	*sc = ifp->if_softc;
1587 	struct mii_data		*mii = GET_MII(sc);
1588 
1589 	DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__));
1590 
1591 	if (sc->aue_dying)
1592 		return (0);
1593 
1594 	sc->aue_link = 0;
1595 	if (mii->mii_instance) {
1596 		struct mii_softc	*miisc;
1597 		for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
1598 		    miisc = LIST_NEXT(miisc, mii_list))
1599 			 mii_phy_reset(miisc);
1600 	}
1601 	mii_mediachg(mii);
1602 
1603 	return (0);
1604 }
1605 
1606 /*
1607  * Report current media status.
1608  */
1609 Static void
1610 aue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
1611 {
1612 	struct aue_softc	*sc = ifp->if_softc;
1613 	struct mii_data		*mii = GET_MII(sc);
1614 
1615 	DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__));
1616 
1617 	mii_pollstat(mii);
1618 	ifmr->ifm_active = mii->mii_media_active;
1619 	ifmr->ifm_status = mii->mii_media_status;
1620 }
1621 
1622 Static int
1623 aue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
1624 {
1625 	struct aue_softc	*sc = ifp->if_softc;
1626 #if defined(__NetBSD__) || defined(__OpenBSD__)
1627 	struct ifaddr 		*ifa = (struct ifaddr *)data;
1628 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1629 	struct ifreq		*ifr = (struct ifreq *)data;
1630 	struct mii_data		*mii;
1631 	int			s, error = 0;
1632 
1633 	if (sc->aue_dying)
1634 		return (EIO);
1635 
1636 	s = splimp();
1637 
1638 	switch(command) {
1639 #if defined(__FreeBSD__)
1640 	case SIOCSIFADDR:
1641 	case SIOCGIFADDR:
1642 	case SIOCSIFMTU:
1643 		error = ether_ioctl(ifp, command, data);
1644 		break;
1645 #elif defined(__NetBSD__) || defined(__OpenBSD__)
1646 	case SIOCSIFADDR:
1647 		ifp->if_flags |= IFF_UP;
1648 		aue_init(sc);
1649 
1650 		switch (ifa->ifa_addr->sa_family) {
1651 #ifdef INET
1652 		case AF_INET:
1653 #if defined(__NetBSD__)
1654 			arp_ifinit(ifp, ifa);
1655 #else
1656 			arp_ifinit(&sc->arpcom, ifa);
1657 #endif
1658 			break;
1659 #endif /* INET */
1660 #ifdef NS
1661 		case AF_NS:
1662 		    {
1663 			struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
1664 
1665 			if (ns_nullhost(*ina))
1666 				ina->x_host = *(union ns_host *)
1667 					LLADDR(ifp->if_sadl);
1668 			else
1669 				memcpy(LLADDR(ifp->if_sadl),
1670 				       ina->x_host.c_host,
1671 				       ifp->if_addrlen);
1672 			break;
1673 		    }
1674 #endif /* NS */
1675 		}
1676 		break;
1677 
1678 	case SIOCSIFMTU:
1679 		if (ifr->ifr_mtu > ETHERMTU)
1680 			error = EINVAL;
1681 		else
1682 			ifp->if_mtu = ifr->ifr_mtu;
1683 		break;
1684 
1685 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1686 	case SIOCSIFFLAGS:
1687 		if (ifp->if_flags & IFF_UP) {
1688 			if (ifp->if_flags & IFF_RUNNING &&
1689 			    ifp->if_flags & IFF_PROMISC &&
1690 			    !(sc->aue_if_flags & IFF_PROMISC)) {
1691 				AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
1692 			} else if (ifp->if_flags & IFF_RUNNING &&
1693 			    !(ifp->if_flags & IFF_PROMISC) &&
1694 			    sc->aue_if_flags & IFF_PROMISC) {
1695 				AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC);
1696 			} else if (!(ifp->if_flags & IFF_RUNNING))
1697 				aue_init(sc);
1698 		} else {
1699 			if (ifp->if_flags & IFF_RUNNING)
1700 				aue_stop(sc);
1701 		}
1702 		sc->aue_if_flags = ifp->if_flags;
1703 		error = 0;
1704 		break;
1705 	case SIOCADDMULTI:
1706 	case SIOCDELMULTI:
1707 #if defined(__NetBSD__) || defined(__OpenBSD__)
1708 		error = (command == SIOCADDMULTI) ?
1709 			ether_addmulti(ifr, &sc->aue_ec) :
1710 			ether_delmulti(ifr, &sc->aue_ec);
1711 		if (error == ENETRESET) {
1712 			aue_init(sc);
1713 		}
1714 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1715 		aue_setmulti(sc);
1716 		error = 0;
1717 		break;
1718 	case SIOCGIFMEDIA:
1719 	case SIOCSIFMEDIA:
1720 		mii = GET_MII(sc);
1721 		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
1722 		break;
1723 	default:
1724 		error = EINVAL;
1725 		break;
1726 	}
1727 
1728 	splx(s);
1729 
1730 	return (error);
1731 }
1732 
1733 Static void
1734 aue_watchdog(struct ifnet *ifp)
1735 {
1736 	struct aue_softc	*sc = ifp->if_softc;
1737 
1738 	DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__));
1739 
1740 	ifp->if_oerrors++;
1741 	printf("%s: watchdog timeout\n", USBDEVNAME(sc->aue_dev));
1742 
1743 	/*
1744 	 * The polling business is a kludge to avoid allowing the
1745 	 * USB code to call tsleep() in usbd_delay_ms(), which will
1746 	 * kill us since the watchdog routine is invoked from
1747 	 * interrupt context.
1748 	 */
1749 	usbd_set_polling(sc->aue_udev, 1);
1750 	aue_stop(sc);
1751 	aue_init(sc);
1752 	usbd_set_polling(sc->aue_udev, 0);
1753 
1754 	if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1755 		aue_start(ifp);
1756 }
1757 
1758 /*
1759  * Stop the adapter and free any mbufs allocated to the
1760  * RX and TX lists.
1761  */
1762 Static void
1763 aue_stop(struct aue_softc *sc)
1764 {
1765 	usbd_status		err;
1766 	struct ifnet		*ifp;
1767 	int			i;
1768 
1769 	DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__));
1770 
1771 	ifp = GET_IFP(sc);
1772 	ifp->if_timer = 0;
1773 
1774 	aue_csr_write_1(sc, AUE_CTL0, 0);
1775 	aue_csr_write_1(sc, AUE_CTL1, 0);
1776 	aue_reset(sc);
1777 	usb_uncallout(sc->aue_stat_ch, aue_tick, sc);
1778 
1779 	/* Stop transfers. */
1780 	if (sc->aue_ep[AUE_ENDPT_RX] != NULL) {
1781 		err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_RX]);
1782 		if (err) {
1783 			printf("%s: abort rx pipe failed: %s\n",
1784 			    USBDEVNAME(sc->aue_dev), usbd_errstr(err));
1785 		}
1786 		err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_RX]);
1787 		if (err) {
1788 			printf("%s: close rx pipe failed: %s\n",
1789 			    USBDEVNAME(sc->aue_dev), usbd_errstr(err));
1790 		}
1791 		sc->aue_ep[AUE_ENDPT_RX] = NULL;
1792 	}
1793 
1794 	if (sc->aue_ep[AUE_ENDPT_TX] != NULL) {
1795 		err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_TX]);
1796 		if (err) {
1797 			printf("%s: abort tx pipe failed: %s\n",
1798 			    USBDEVNAME(sc->aue_dev), usbd_errstr(err));
1799 		}
1800 		err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_TX]);
1801 		if (err) {
1802 			printf("%s: close tx pipe failed: %s\n",
1803 			    USBDEVNAME(sc->aue_dev), usbd_errstr(err));
1804 		}
1805 		sc->aue_ep[AUE_ENDPT_TX] = NULL;
1806 	}
1807 
1808 	if (sc->aue_ep[AUE_ENDPT_INTR] != NULL) {
1809 		err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_INTR]);
1810 		if (err) {
1811 			printf("%s: abort intr pipe failed: %s\n",
1812 			    USBDEVNAME(sc->aue_dev), usbd_errstr(err));
1813 		}
1814 		err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_INTR]);
1815 		if (err) {
1816 			printf("%s: close intr pipe failed: %s\n",
1817 			    USBDEVNAME(sc->aue_dev), usbd_errstr(err));
1818 		}
1819 		sc->aue_ep[AUE_ENDPT_INTR] = NULL;
1820 	}
1821 
1822 	/* Free RX resources. */
1823 	for (i = 0; i < AUE_RX_LIST_CNT; i++) {
1824 		if (sc->aue_cdata.aue_rx_chain[i].aue_mbuf != NULL) {
1825 			m_freem(sc->aue_cdata.aue_rx_chain[i].aue_mbuf);
1826 			sc->aue_cdata.aue_rx_chain[i].aue_mbuf = NULL;
1827 		}
1828 		if (sc->aue_cdata.aue_rx_chain[i].aue_xfer != NULL) {
1829 			usbd_free_xfer(sc->aue_cdata.aue_rx_chain[i].aue_xfer);
1830 			sc->aue_cdata.aue_rx_chain[i].aue_xfer = NULL;
1831 		}
1832 	}
1833 
1834 	/* Free TX resources. */
1835 	for (i = 0; i < AUE_TX_LIST_CNT; i++) {
1836 		if (sc->aue_cdata.aue_tx_chain[i].aue_mbuf != NULL) {
1837 			m_freem(sc->aue_cdata.aue_tx_chain[i].aue_mbuf);
1838 			sc->aue_cdata.aue_tx_chain[i].aue_mbuf = NULL;
1839 		}
1840 		if (sc->aue_cdata.aue_tx_chain[i].aue_xfer != NULL) {
1841 			usbd_free_xfer(sc->aue_cdata.aue_tx_chain[i].aue_xfer);
1842 			sc->aue_cdata.aue_tx_chain[i].aue_xfer = NULL;
1843 		}
1844 	}
1845 
1846 	sc->aue_link = 0;
1847 
1848 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1849 }
1850 
1851 #ifdef __FreeBSD__
1852 /*
1853  * Stop all chip I/O so that the kernel's probe routines don't
1854  * get confused by errant DMAs when rebooting.
1855  */
1856 Static void
1857 aue_shutdown(device_ptr_t dev)
1858 {
1859 	struct aue_softc	*sc = USBGETSOFTC(dev);
1860 
1861 	DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__));
1862 
1863 	aue_reset(sc);
1864 	aue_stop(sc);
1865 }
1866 #endif
1867