2 * Copyright (c) 1997, 1998, 1999, 2000
3 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
32 * $FreeBSD: src/sys/dev/usb/if_aue.c,v 1.78 2003/12/17 14:23:07 sanpei Exp $
33 * $DragonFly: src/sys/dev/netif/aue/if_aue.c,v 1.38.2.1 2008/09/01 13:09:02 sephe Exp $
37 * ADMtek AN986 Pegasus and AN8511 Pegasus II USB to ethernet driver.
38 * Datasheet is available from http://www.admtek.com.tw.
40 * Written by Bill Paul <wpaul@ee.columbia.edu>
41 * Electrical Engineering Department
42 * Columbia University, New York City
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.
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.
61 * Registers are accessed using usbd_do_request(). Packet transfers are
62 * done using usbd_transfer() and friends.
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/sockio.h>
69 #include <sys/malloc.h>
70 #include <sys/kernel.h>
71 #include <sys/socket.h>
75 #include <net/ifq_var.h>
76 #include <net/if_arp.h>
77 #include <net/ethernet.h>
78 #include <net/if_dl.h>
79 #include <net/if_media.h>
82 #include <bus/usb/usb.h>
83 #include <bus/usb/usbdi.h>
84 #include <bus/usb/usbdi_util.h>
85 #include <bus/usb/usbdivar.h>
86 #include <bus/usb/usb_ethersubr.h>
88 #include "../mii_layer/mii.h"
89 #include "../mii_layer/miivar.h"
91 #include "if_auereg.h"
93 MODULE_DEPEND(aue
, usb
, 1, 1, 1);
94 MODULE_DEPEND(aue
, miibus
, 1, 1, 1);
96 /* "controller miibus0" required. See GENERIC if you get errors here. */
97 #include "miibus_if.h"
100 struct usb_devno aue_dev
;
102 #define LSYS 0x0001 /* use Linksys reset */
103 #define PNA 0x0002 /* has Home PNA */
104 #define PII 0x0004 /* Pegasus II chip */
107 static const struct aue_type aue_devs
[] = {
108 {{ USB_DEVICE(0x03f0, 0x811c) }, PII
}, /* HP HN210E */
109 {{ USB_DEVICE(0x0411, 0x0001) }, 0 }, /* Melco LUA-TX */
110 {{ USB_DEVICE(0x0411, 0x0005) }, 0 }, /* Melco LUA-TX */
111 {{ USB_DEVICE(0x0411, 0x0009) }, PII
}, /* Melco LUA2-TX */
112 {{ USB_DEVICE(0x045e, 0x007a) }, PII
}, /* Microsoft MN110 */
113 {{ USB_DEVICE(0x04bb, 0x0904) }, 0 }, /* I-O DATA USB ETTX */
114 {{ USB_DEVICE(0x04bb, 0x0913) }, PII
}, /* I-O DATA USB ETTX */
115 {{ USB_DEVICE(0x0506, 0x4601) }, PII
}, /* 3com HomeConnect 3C460B */
116 {{ USB_DEVICE(0x050d, 0x0121) }, PII
}, /* Belkin USB to LAN Converter */
117 {{ USB_DEVICE(0x056e, 0x200c) }, 0 }, /* Elecom LD-USB/TX */
118 {{ USB_DEVICE(0x056e, 0x4002) }, LSYS
}, /* Elecom LD-USB/TX */
119 {{ USB_DEVICE(0x056e, 0x4005) }, PII
}, /* Elecom LD-USBL/TX */
120 {{ USB_DEVICE(0x056e, 0x400b) }, 0 }, /* Elecom LD-USB/TX */
121 {{ USB_DEVICE(0x056e, 0xabc1) }, LSYS
}, /* Elecom LD-USB/TX */
122 {{ USB_DEVICE(0x05cc, 0x3000) }, 0 }, /* Elsa Microlink USB2Ethernet */
123 {{ USB_DEVICE(0x066b, 0x200c) }, LSYS
|PII
}, /* Linksys USB10TX */
124 {{ USB_DEVICE(0x066b, 0x2202) }, LSYS
}, /* Linksys USB10T */
125 {{ USB_DEVICE(0x066b, 0x2203) }, LSYS
}, /* Linksys USB100TX */
126 {{ USB_DEVICE(0x066b, 0x2204) }, LSYS
|PNA
}, /* Linksys USB100H1 */
127 {{ USB_DEVICE(0x066b, 0x2206) }, LSYS
}, /* Linksys USB10TA */
128 {{ USB_DEVICE(0x066b, 0x400b) }, LSYS
|PII
}, /* Linksys USB10TX */
129 {{ USB_DEVICE(0x067c, 0x1001) }, PII
}, /* Siemens SpeedStream USB */
130 {{ USB_DEVICE(0x0707, 0x0200) }, 0 }, /* SMC 2202USB */
131 {{ USB_DEVICE(0x0707, 0x0201) }, PII
}, /* SMC 2206USB */
132 {{ USB_DEVICE(0x07a6, 0x0986) }, PNA
}, /* ADMtek AN986 */
133 {{ USB_DEVICE(0x07a6, 0x8511) }, PII
}, /* ADMtek AN8511 */
134 {{ USB_DEVICE(0x07a6, 0x8513) }, PII
}, /* ADMtek AN8513 */
135 {{ USB_DEVICE(0x07aa, 0x0004) }, 0 }, /* Corega FEther USB-TX */
136 {{ USB_DEVICE(0x07aa, 0x000d) }, PII
}, /* Corega FEther USB-TXS */
137 {{ USB_DEVICE(0x07b8, 0x110c) }, PNA
|PII
}, /* AboCom XX1 */
138 {{ USB_DEVICE(0x07b8, 0x200c) }, PII
}, /* AboCom XX2 */
139 {{ USB_DEVICE(0x07b8, 0x4002) }, LSYS
}, /* AboCom UFE1000 */
140 {{ USB_DEVICE(0x07b8, 0x4003) }, 0 }, /* AboCom DSB650TX_PNA */
141 {{ USB_DEVICE(0x07b8, 0x4004) }, PNA
}, /* AboCom XX4 */
142 {{ USB_DEVICE(0x07b8, 0x4007) }, PNA
}, /* AboCom XX5 */
143 {{ USB_DEVICE(0x07b8, 0x400b) }, PII
}, /* AboCom XX6 */
144 {{ USB_DEVICE(0x07b8, 0x400c) }, PII
}, /* AboCom XX7 */
145 {{ USB_DEVICE(0x07b8, 0x4102) }, PII
}, /* AboCom XX8 */
146 {{ USB_DEVICE(0x07b8, 0x4104) }, PNA
}, /* AboCom XX9 */
147 {{ USB_DEVICE(0x07b8, 0xabc1) }, 0 }, /* AboCom XX10 */
148 {{ USB_DEVICE(0x083a, 0x1046) }, 0 }, /* Accton USB320-EC */
149 {{ USB_DEVICE(0x083a, 0x5046) }, PII
}, /* Accton SpeedStream 1001 */
150 {{ USB_DEVICE(0x08d1, 0x0003) }, PII
}, /* SmartBridges smartNIC 2 PnP */
151 {{ USB_DEVICE(0x08dd, 0x0986) }, 0 }, /* Billionton USB100N */
152 {{ USB_DEVICE(0x08dd, 0x0987) }, PNA
}, /* Billionton USB100LP */
153 {{ USB_DEVICE(0x08dd, 0x0988) }, 0 }, /* Billionton USB100EL */
154 {{ USB_DEVICE(0x08dd, 0x8511) }, PII
}, /* Billionton USBE100 */
155 {{ USB_DEVICE(0x0951, 0x000a) }, 0 }, /* Kingston KNU101TX */
156 {{ USB_DEVICE(0x0e66, 0x400c) }, PII
}, /* Hawking UF100 */
157 {{ USB_DEVICE(0x15e8, 0x9100) }, 0 }, /* SOHOware NUB100 */
158 {{ USB_DEVICE(0x2001, 0x200c) }, LSYS
|PII
},/* D-Link DSB650TX4 */
159 {{ USB_DEVICE(0x2001, 0x4001) }, LSYS
}, /* D-Link DSB650TX1 */
160 {{ USB_DEVICE(0x2001, 0x4002) }, LSYS
}, /* D-Link DSB650TX */
161 {{ USB_DEVICE(0x2001, 0x4003) }, PNA
}, /* D-Link DSB650TX_PNA */
162 {{ USB_DEVICE(0x2001, 0x400b) }, LSYS
|PII
}, /* D-Link DSB650TX3 */
163 {{ USB_DEVICE(0x2001, 0x4102) }, LSYS
|PII
}, /* D-Link DSB650TX2 */
164 {{ USB_DEVICE(0x2001, 0xabc1) }, LSYS
}, /* D-Link DSB650 */
166 #define aue_lookup(v, p) ((const struct aue_type *)usb_lookup(aue_devs, v, p))
168 static int aue_match(device_t
);
169 static int aue_attach(device_t
);
170 static int aue_detach(device_t
);
172 static void aue_reset_pegasus_II(struct aue_softc
*sc
);
173 static int aue_tx_list_init(struct aue_softc
*);
174 static int aue_rx_list_init(struct aue_softc
*);
175 static int aue_newbuf(struct aue_softc
*, struct aue_chain
*, struct mbuf
*);
176 static int aue_encap(struct aue_softc
*, struct mbuf
*, int);
178 static void aue_intr(usbd_xfer_handle
, usbd_private_handle
, usbd_status
);
180 static void aue_rxeof(usbd_xfer_handle
, usbd_private_handle
, usbd_status
);
181 static void aue_txeof(usbd_xfer_handle
, usbd_private_handle
, usbd_status
);
182 static void aue_tick(void *);
183 static void aue_rxstart(struct ifnet
*);
184 static void aue_start(struct ifnet
*);
185 static int aue_ioctl(struct ifnet
*, u_long
, caddr_t
, struct ucred
*);
186 static void aue_init(void *);
187 static void aue_stop(struct aue_softc
*);
188 static void aue_watchdog(struct ifnet
*);
189 static void aue_shutdown(device_t
);
190 static int aue_ifmedia_upd(struct ifnet
*);
191 static void aue_ifmedia_sts(struct ifnet
*, struct ifmediareq
*);
193 static void aue_eeprom_getword(struct aue_softc
*, int, u_int16_t
*);
194 static void aue_read_eeprom(struct aue_softc
*, caddr_t
, int, int, int);
195 static int aue_miibus_readreg(device_t
, int, int);
196 static int aue_miibus_writereg(device_t
, int, int, int);
197 static void aue_miibus_statchg(device_t
);
199 static void aue_setmulti(struct aue_softc
*);
200 static void aue_reset(struct aue_softc
*);
202 static int aue_csr_read_1(struct aue_softc
*, int);
203 static int aue_csr_write_1(struct aue_softc
*, int, int);
204 static int aue_csr_read_2(struct aue_softc
*, int);
205 static int aue_csr_write_2(struct aue_softc
*, int, int);
207 static device_method_t aue_methods
[] = {
208 /* Device interface */
209 DEVMETHOD(device_probe
, aue_match
),
210 DEVMETHOD(device_attach
, aue_attach
),
211 DEVMETHOD(device_detach
, aue_detach
),
212 DEVMETHOD(device_shutdown
, aue_shutdown
),
215 DEVMETHOD(bus_print_child
, bus_generic_print_child
),
216 DEVMETHOD(bus_driver_added
, bus_generic_driver_added
),
219 DEVMETHOD(miibus_readreg
, aue_miibus_readreg
),
220 DEVMETHOD(miibus_writereg
, aue_miibus_writereg
),
221 DEVMETHOD(miibus_statchg
, aue_miibus_statchg
),
226 static driver_t aue_driver
= {
229 sizeof(struct aue_softc
)
232 static devclass_t aue_devclass
;
234 DECLARE_DUMMY_MODULE(if_aue
);
235 DRIVER_MODULE(aue
, uhub
, aue_driver
, aue_devclass
, usbd_driver_load
, 0);
236 DRIVER_MODULE(miibus
, aue
, miibus_driver
, miibus_devclass
, 0, 0);
238 #define AUE_SETBIT(sc, reg, x) \
239 aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x))
241 #define AUE_CLRBIT(sc, reg, x) \
242 aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) & ~(x))
245 aue_csr_read_1(struct aue_softc
*sc
, int reg
)
247 usb_device_request_t req
;
256 req
.bmRequestType
= UT_READ_VENDOR_DEVICE
;
257 req
.bRequest
= AUE_UR_READREG
;
258 USETW(req
.wValue
, 0);
259 USETW(req
.wIndex
, reg
);
260 USETW(req
.wLength
, 1);
262 err
= usbd_do_request(sc
->aue_udev
, &req
, &val
);
274 aue_csr_read_2(struct aue_softc
*sc
, int reg
)
276 usb_device_request_t req
;
285 req
.bmRequestType
= UT_READ_VENDOR_DEVICE
;
286 req
.bRequest
= AUE_UR_READREG
;
287 USETW(req
.wValue
, 0);
288 USETW(req
.wIndex
, reg
);
289 USETW(req
.wLength
, 2);
291 err
= usbd_do_request(sc
->aue_udev
, &req
, &val
);
303 aue_csr_write_1(struct aue_softc
*sc
, int reg
, int val
)
305 usb_device_request_t req
;
313 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
314 req
.bRequest
= AUE_UR_WRITEREG
;
315 USETW(req
.wValue
, val
);
316 USETW(req
.wIndex
, reg
);
317 USETW(req
.wLength
, 1);
319 err
= usbd_do_request(sc
->aue_udev
, &req
, &val
);
331 aue_csr_write_2(struct aue_softc
*sc
, int reg
, int val
)
333 usb_device_request_t req
;
341 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
342 req
.bRequest
= AUE_UR_WRITEREG
;
343 USETW(req
.wValue
, val
);
344 USETW(req
.wIndex
, reg
);
345 USETW(req
.wLength
, 2);
347 err
= usbd_do_request(sc
->aue_udev
, &req
, &val
);
359 * Read a word of data stored in the EEPROM at address 'addr.'
362 aue_eeprom_getword(struct aue_softc
*sc
, int addr
, u_int16_t
*dest
)
367 aue_csr_write_1(sc
, AUE_EE_REG
, addr
);
368 aue_csr_write_1(sc
, AUE_EE_CTL
, AUE_EECTL_READ
);
370 for (i
= 0; i
< AUE_TIMEOUT
; i
++) {
371 if (aue_csr_read_1(sc
, AUE_EE_CTL
) & AUE_EECTL_DONE
)
375 if (i
== AUE_TIMEOUT
)
376 if_printf(&sc
->arpcom
.ac_if
, "EEPROM read timed out\n");
378 word
= aue_csr_read_2(sc
, AUE_EE_DATA
);
385 * Read a sequence of words from the EEPROM.
388 aue_read_eeprom(struct aue_softc
*sc
, caddr_t dest
, int off
, int cnt
, int swap
)
391 u_int16_t word
= 0, *ptr
;
393 for (i
= 0; i
< cnt
; i
++) {
394 aue_eeprom_getword(sc
, off
+ i
, &word
);
395 ptr
= (u_int16_t
*)(dest
+ (i
* 2));
406 aue_miibus_readreg(device_t dev
, int phy
, int reg
)
408 struct aue_softc
*sc
= device_get_softc(dev
);
413 * The Am79C901 HomePNA PHY actually contains
414 * two transceivers: a 1Mbps HomePNA PHY and a
415 * 10Mbps full/half duplex ethernet PHY with
416 * NWAY autoneg. However in the ADMtek adapter,
417 * only the 1Mbps PHY is actually connected to
418 * anything, so we ignore the 10Mbps one. It
419 * happens to be configured for MII address 3,
420 * so we filter that out.
422 if (sc
->aue_vendor
== 0x07a6 && sc
->aue_product
== 0x0986) {
431 aue_csr_write_1(sc
, AUE_PHY_ADDR
, phy
);
432 aue_csr_write_1(sc
, AUE_PHY_CTL
, reg
| AUE_PHYCTL_READ
);
434 for (i
= 0; i
< AUE_TIMEOUT
; i
++) {
435 if (aue_csr_read_1(sc
, AUE_PHY_CTL
) & AUE_PHYCTL_DONE
)
439 if (i
== AUE_TIMEOUT
)
440 if_printf(&sc
->arpcom
.ac_if
, "MII read timed out\n");
442 val
= aue_csr_read_2(sc
, AUE_PHY_DATA
);
448 aue_miibus_writereg(device_t dev
, int phy
, int reg
, int data
)
450 struct aue_softc
*sc
= device_get_softc(dev
);
456 aue_csr_write_2(sc
, AUE_PHY_DATA
, data
);
457 aue_csr_write_1(sc
, AUE_PHY_ADDR
, phy
);
458 aue_csr_write_1(sc
, AUE_PHY_CTL
, reg
| AUE_PHYCTL_WRITE
);
460 for (i
= 0; i
< AUE_TIMEOUT
; i
++) {
461 if (aue_csr_read_1(sc
, AUE_PHY_CTL
) & AUE_PHYCTL_DONE
)
465 if (i
== AUE_TIMEOUT
)
466 if_printf(&sc
->arpcom
.ac_if
, "MII read timed out\n");
472 aue_miibus_statchg(device_t dev
)
474 struct aue_softc
*sc
= device_get_softc(dev
);
475 struct mii_data
*mii
= GET_MII(sc
);
477 AUE_CLRBIT(sc
, AUE_CTL0
, AUE_CTL0_RX_ENB
| AUE_CTL0_TX_ENB
);
478 if (IFM_SUBTYPE(mii
->mii_media_active
) == IFM_100_TX
) {
479 AUE_SETBIT(sc
, AUE_CTL1
, AUE_CTL1_SPEEDSEL
);
481 AUE_CLRBIT(sc
, AUE_CTL1
, AUE_CTL1_SPEEDSEL
);
484 if ((mii
->mii_media_active
& IFM_GMASK
) == IFM_FDX
)
485 AUE_SETBIT(sc
, AUE_CTL1
, AUE_CTL1_DUPLEX
);
487 AUE_CLRBIT(sc
, AUE_CTL1
, AUE_CTL1_DUPLEX
);
489 AUE_SETBIT(sc
, AUE_CTL0
, AUE_CTL0_RX_ENB
| AUE_CTL0_TX_ENB
);
492 * Set the LED modes on the LinkSys adapter.
493 * This turns on the 'dual link LED' bin in the auxmode
494 * register of the Broadcom PHY.
496 if (sc
->aue_flags
& LSYS
) {
498 auxmode
= aue_miibus_readreg(dev
, 0, 0x1b);
499 aue_miibus_writereg(dev
, 0, 0x1b, auxmode
| 0x04);
508 aue_setmulti(struct aue_softc
*sc
)
511 struct ifmultiaddr
*ifma
;
514 ifp
= &sc
->arpcom
.ac_if
;
516 if (ifp
->if_flags
& IFF_ALLMULTI
|| ifp
->if_flags
& IFF_PROMISC
) {
517 AUE_SETBIT(sc
, AUE_CTL0
, AUE_CTL0_ALLMULTI
);
521 AUE_CLRBIT(sc
, AUE_CTL0
, AUE_CTL0_ALLMULTI
);
523 /* first, zot all the existing hash bits */
524 for (i
= 0; i
< 8; i
++)
525 aue_csr_write_1(sc
, AUE_MAR0
+ i
, 0);
527 /* now program new ones */
528 LIST_FOREACH(ifma
, &ifp
->if_multiaddrs
, ifma_link
)
530 if (ifma
->ifma_addr
->sa_family
!= AF_LINK
)
532 h
= ether_crc32_le(LLADDR((struct sockaddr_dl
*)
533 ifma
->ifma_addr
), ETHER_ADDR_LEN
) & ((1 << AUE_BITS
) - 1);
534 AUE_SETBIT(sc
, AUE_MAR
+ (h
>> 3), 1 << (h
& 0x7));
541 aue_reset_pegasus_II(struct aue_softc
*sc
)
543 /* Magic constants taken from Linux driver. */
544 aue_csr_write_1(sc
, AUE_REG_1D
, 0);
545 aue_csr_write_1(sc
, AUE_REG_7B
, 2);
547 if ((sc
->aue_flags
& HAS_HOME_PNA
) && mii_mode
)
548 aue_csr_write_1(sc
, AUE_REG_81
, 6);
551 aue_csr_write_1(sc
, AUE_REG_81
, 2);
555 aue_reset(struct aue_softc
*sc
)
559 AUE_SETBIT(sc
, AUE_CTL1
, AUE_CTL1_RESETMAC
);
561 for (i
= 0; i
< AUE_TIMEOUT
; i
++) {
562 if (!(aue_csr_read_1(sc
, AUE_CTL1
) & AUE_CTL1_RESETMAC
))
566 if (i
== AUE_TIMEOUT
)
567 if_printf(&sc
->arpcom
.ac_if
, "reset failed\n");
570 * The PHY(s) attached to the Pegasus chip may be held
571 * in reset until we flip on the GPIO outputs. Make sure
572 * to set the GPIO pins high so that the PHY(s) will
575 * Note: We force all of the GPIO pins low first, *then*
576 * enable the ones we want.
578 aue_csr_write_1(sc
, AUE_GPIO0
, AUE_GPIO_OUT0
|AUE_GPIO_SEL0
);
579 aue_csr_write_1(sc
, AUE_GPIO0
, AUE_GPIO_OUT0
|AUE_GPIO_SEL0
|AUE_GPIO_SEL1
);
581 if (sc
->aue_flags
& LSYS
) {
582 /* Grrr. LinkSys has to be different from everyone else. */
583 aue_csr_write_1(sc
, AUE_GPIO0
,
584 AUE_GPIO_SEL0
| AUE_GPIO_SEL1
);
585 aue_csr_write_1(sc
, AUE_GPIO0
,
586 AUE_GPIO_SEL0
| AUE_GPIO_SEL1
| AUE_GPIO_OUT0
);
589 if (sc
->aue_flags
& PII
)
590 aue_reset_pegasus_II(sc
);
592 /* Wait a little while for the chip to get its brains in order. */
599 * Probe for a Pegasus chip.
602 aue_match(device_t self
)
604 struct usb_attach_arg
*uaa
= device_get_ivars(self
);
606 if (uaa
->iface
!= NULL
)
607 return (UMATCH_NONE
);
609 return (aue_lookup(uaa
->vendor
, uaa
->product
) != NULL
?
610 UMATCH_VENDOR_PRODUCT
: UMATCH_NONE
);
614 * Attach the interface. Allocate softc structures, do ifmedia
615 * setup and ethernet/BPF attach.
618 aue_attach(device_t self
)
620 struct aue_softc
*sc
= device_get_softc(self
);
621 struct usb_attach_arg
*uaa
= device_get_ivars(self
);
622 u_char eaddr
[ETHER_ADDR_LEN
];
624 usbd_interface_handle iface
;
626 usb_interface_descriptor_t
*id
;
627 usb_endpoint_descriptor_t
*ed
;
630 sc
->aue_udev
= uaa
->device
;
631 callout_init(&sc
->aue_stat_timer
);
633 if (usbd_set_config_no(sc
->aue_udev
, AUE_CONFIG_NO
, 0)) {
634 device_printf(self
, "setting config no %d failed\n",
639 err
= usbd_device2interface_handle(uaa
->device
, AUE_IFACE_IDX
, &iface
);
641 device_printf(self
, "getting interface handle failed\n");
645 sc
->aue_iface
= iface
;
646 sc
->aue_flags
= aue_lookup(uaa
->vendor
, uaa
->product
)->aue_flags
;
648 sc
->aue_product
= uaa
->product
;
649 sc
->aue_vendor
= uaa
->vendor
;
651 id
= usbd_get_interface_descriptor(sc
->aue_iface
);
653 /* Find endpoints. */
654 for (i
= 0; i
< id
->bNumEndpoints
; i
++) {
655 ed
= usbd_interface2endpoint_descriptor(iface
, i
);
657 device_printf(self
, "couldn't get ep %d\n", i
);
660 if (UE_GET_DIR(ed
->bEndpointAddress
) == UE_DIR_IN
&&
661 UE_GET_XFERTYPE(ed
->bmAttributes
) == UE_BULK
) {
662 sc
->aue_ed
[AUE_ENDPT_RX
] = ed
->bEndpointAddress
;
663 } else if (UE_GET_DIR(ed
->bEndpointAddress
) == UE_DIR_OUT
&&
664 UE_GET_XFERTYPE(ed
->bmAttributes
) == UE_BULK
) {
665 sc
->aue_ed
[AUE_ENDPT_TX
] = ed
->bEndpointAddress
;
666 } else if (UE_GET_DIR(ed
->bEndpointAddress
) == UE_DIR_IN
&&
667 UE_GET_XFERTYPE(ed
->bmAttributes
) == UE_INTERRUPT
) {
668 sc
->aue_ed
[AUE_ENDPT_INTR
] = ed
->bEndpointAddress
;
674 ifp
= &sc
->arpcom
.ac_if
;
675 if_initname(ifp
, device_get_name(self
), device_get_unit(self
));
677 /* Reset the adapter. */
681 * Get station address from the EEPROM.
683 aue_read_eeprom(sc
, (caddr_t
)&eaddr
, 0, 3, 0);
686 ifp
->if_mtu
= ETHERMTU
;
687 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
688 ifp
->if_ioctl
= aue_ioctl
;
689 ifp
->if_start
= aue_start
;
690 ifp
->if_watchdog
= aue_watchdog
;
691 ifp
->if_init
= aue_init
;
692 ifp
->if_baudrate
= 10000000;
693 ifq_set_maxlen(&ifp
->if_snd
, IFQ_MAXLEN
);
694 ifq_set_ready(&ifp
->if_snd
);
698 * NOTE: Doing this causes child devices to be attached to us,
699 * which we would normally disconnect at in the detach routine
700 * using device_delete_child(). However the USB code is set up
701 * such that when this driver is removed, all children devices
702 * are removed as well. In effect, the USB code ends up detaching
703 * all of our children for us, so we don't have to do is ourselves
704 * in aue_detach(). It's important to point this out since if
705 * we *do* try to detach the child devices ourselves, we will
706 * end up getting the children deleted twice, which will crash
709 if (mii_phy_probe(self
, &sc
->aue_miibus
,
710 aue_ifmedia_upd
, aue_ifmedia_sts
)) {
711 device_printf(self
, "MII without any PHY!\n");
717 * Call MI attach routine.
719 ether_ifattach(ifp
, eaddr
, NULL
);
720 usb_register_netisr();
728 aue_detach(device_t dev
)
730 struct aue_softc
*sc
;
733 sc
= device_get_softc(dev
);
735 ifp
= &sc
->arpcom
.ac_if
;
738 callout_stop(&sc
->aue_stat_timer
);
741 if (sc
->aue_ep
[AUE_ENDPT_TX
] != NULL
)
742 usbd_abort_pipe(sc
->aue_ep
[AUE_ENDPT_TX
]);
743 if (sc
->aue_ep
[AUE_ENDPT_RX
] != NULL
)
744 usbd_abort_pipe(sc
->aue_ep
[AUE_ENDPT_RX
]);
746 if (sc
->aue_ep
[AUE_ENDPT_INTR
] != NULL
)
747 usbd_abort_pipe(sc
->aue_ep
[AUE_ENDPT_INTR
]);
756 * Initialize an RX descriptor and attach an MBUF cluster.
759 aue_newbuf(struct aue_softc
*sc
, struct aue_chain
*c
, struct mbuf
*m
)
761 struct mbuf
*m_new
= NULL
;
764 m_new
= m_getcl(MB_DONTWAIT
, MT_DATA
, M_PKTHDR
);
766 if_printf(&sc
->arpcom
.ac_if
,
767 "no memory for rx list -- packet dropped!\n");
770 m_new
->m_len
= m_new
->m_pkthdr
.len
= MCLBYTES
;
773 m_new
->m_len
= m_new
->m_pkthdr
.len
= MCLBYTES
;
774 m_new
->m_data
= m_new
->m_ext
.ext_buf
;
777 m_adj(m_new
, ETHER_ALIGN
);
784 aue_rx_list_init(struct aue_softc
*sc
)
786 struct aue_cdata
*cd
;
791 for (i
= 0; i
< AUE_RX_LIST_CNT
; i
++) {
792 c
= &cd
->aue_rx_chain
[i
];
795 if (aue_newbuf(sc
, c
, NULL
) == ENOBUFS
)
797 if (c
->aue_xfer
== NULL
) {
798 c
->aue_xfer
= usbd_alloc_xfer(sc
->aue_udev
);
799 if (c
->aue_xfer
== NULL
)
808 aue_tx_list_init(struct aue_softc
*sc
)
810 struct aue_cdata
*cd
;
815 for (i
= 0; i
< AUE_TX_LIST_CNT
; i
++) {
816 c
= &cd
->aue_tx_chain
[i
];
820 if (c
->aue_xfer
== NULL
) {
821 c
->aue_xfer
= usbd_alloc_xfer(sc
->aue_udev
);
822 if (c
->aue_xfer
== NULL
)
825 c
->aue_buf
= kmalloc(AUE_BUFSZ
, M_USBDEV
, M_WAITOK
);
833 aue_intr(usbd_xfer_handle xfer
, usbd_private_handle priv
, usbd_status status
)
835 struct aue_softc
*sc
= priv
;
837 struct aue_intrpkt
*p
;
840 ifp
= &sc
->arpcom
.ac_if
;
842 if (!(ifp
->if_flags
& IFF_RUNNING
)) {
847 if (status
!= USBD_NORMAL_COMPLETION
) {
848 if (status
== USBD_NOT_STARTED
|| status
== USBD_CANCELLED
) {
852 if_printf(ifp
, "usb error on intr: %s\n", usbd_errstr(status
));
853 if (status
== USBD_STALLED
)
854 usbd_clear_endpoint_stall(sc
->aue_ep
[AUE_ENDPT_RX
]);
859 usbd_get_xfer_status(xfer
, NULL
, (void **)&p
, NULL
, NULL
);
864 if (p
->aue_txstat0
& (AUE_TXSTAT0_LATECOLL
& AUE_TXSTAT0_EXCESSCOLL
))
865 ifp
->if_collisions
++;
873 aue_rxstart(struct ifnet
*ifp
)
875 struct aue_softc
*sc
;
880 c
= &sc
->aue_cdata
.aue_rx_chain
[sc
->aue_cdata
.aue_rx_prod
];
882 if (aue_newbuf(sc
, c
, NULL
) == ENOBUFS
) {
888 /* Setup new transfer. */
889 usbd_setup_xfer(c
->aue_xfer
, sc
->aue_ep
[AUE_ENDPT_RX
],
890 c
, mtod(c
->aue_mbuf
, char *), AUE_BUFSZ
, USBD_SHORT_XFER_OK
,
891 USBD_NO_TIMEOUT
, aue_rxeof
);
892 usbd_transfer(c
->aue_xfer
);
899 * A frame has been uploaded: pass the resulting mbuf chain up to
900 * the higher level protocols.
903 aue_rxeof(usbd_xfer_handle xfer
, usbd_private_handle priv
, usbd_status status
)
905 struct aue_chain
*c
= priv
;
906 struct aue_softc
*sc
= c
->aue_sc
;
915 ifp
= &sc
->arpcom
.ac_if
;
917 if (!(ifp
->if_flags
& IFF_RUNNING
))
920 if (status
!= USBD_NORMAL_COMPLETION
) {
921 if (status
== USBD_NOT_STARTED
|| status
== USBD_CANCELLED
)
923 if (usbd_ratecheck(&sc
->aue_rx_notice
)) {
924 if_printf(ifp
, "usb error on rx: %s\n",
925 usbd_errstr(status
));
927 if (status
== USBD_STALLED
)
928 usbd_clear_endpoint_stall(sc
->aue_ep
[AUE_ENDPT_RX
]);
932 usbd_get_xfer_status(xfer
, NULL
, NULL
, &total_len
, NULL
);
934 if (total_len
<= 4 + ETHER_CRC_LEN
) {
940 bcopy(mtod(m
, char *) + total_len
- 4, (char *)&r
, sizeof(r
));
942 /* Turn off all the non-error bits in the rx status word. */
943 r
.aue_rxstat
&= AUE_RXSTAT_MASK
;
950 /* No errors; receive the packet. */
951 total_len
-= (4 + ETHER_CRC_LEN
);
954 m
->m_pkthdr
.rcvif
= ifp
;
955 m
->m_pkthdr
.len
= m
->m_len
= total_len
;
957 /* Put the packet on the special USB input queue. */
963 /* Setup new transfer. */
964 usbd_setup_xfer(xfer
, sc
->aue_ep
[AUE_ENDPT_RX
],
965 c
, mtod(c
->aue_mbuf
, char *), AUE_BUFSZ
, USBD_SHORT_XFER_OK
,
966 USBD_NO_TIMEOUT
, aue_rxeof
);
971 aue_start_ipifunc(void *arg
)
973 struct ifnet
*ifp
= arg
;
974 struct lwkt_msg
*lmsg
= &ifp
->if_start_nmsg
[mycpuid
].nm_lmsg
;
977 if (lmsg
->ms_flags
& MSGF_DONE
)
978 lwkt_sendmsg(ifnet_portfn(mycpuid
), lmsg
);
983 aue_start_schedule(struct ifnet
*ifp
)
988 cpu
= ifp
->if_start_cpuid(ifp
);
990 lwkt_send_ipiq(globaldata_find(cpu
), aue_start_ipifunc
, ifp
);
993 aue_start_ipifunc(ifp
);
997 * A frame was downloaded to the chip. It's safe for us to clean up
1001 aue_txeof(usbd_xfer_handle xfer
, usbd_private_handle priv
, usbd_status status
)
1003 struct aue_chain
*c
= priv
;
1004 struct aue_softc
*sc
= c
->aue_sc
;
1008 ifp
= &sc
->arpcom
.ac_if
;
1010 if (status
!= USBD_NORMAL_COMPLETION
) {
1011 if (status
== USBD_NOT_STARTED
|| status
== USBD_CANCELLED
)
1013 if_printf(ifp
, "usb error on tx: %s\n", usbd_errstr(status
));
1014 if (status
== USBD_STALLED
)
1015 usbd_clear_endpoint_stall(sc
->aue_ep
[AUE_ENDPT_TX
]);
1019 usbd_get_xfer_status(c
->aue_xfer
, NULL
, NULL
, NULL
, &err
);
1025 /* XXX should hold serializer */
1027 ifp
->if_flags
&= ~IFF_OACTIVE
;
1029 if (!ifq_is_empty(&ifp
->if_snd
))
1030 aue_start_schedule(ifp
);
1036 struct aue_softc
*sc
= xsc
;
1038 struct mii_data
*mii
;
1043 ifp
= &sc
->arpcom
.ac_if
;
1045 lwkt_serialize_enter(ifp
->if_serializer
);
1049 lwkt_serialize_exit(ifp
->if_serializer
);
1054 if (!sc
->aue_link
&& mii
->mii_media_status
& IFM_ACTIVE
&&
1055 IFM_SUBTYPE(mii
->mii_media_active
) != IFM_NONE
) {
1057 if (!ifq_is_empty(&ifp
->if_snd
))
1058 aue_start_schedule(ifp
);
1061 callout_reset(&sc
->aue_stat_timer
, hz
, aue_tick
, sc
);
1063 lwkt_serialize_exit(ifp
->if_serializer
);
1067 aue_encap(struct aue_softc
*sc
, struct mbuf
*m
, int idx
)
1070 struct aue_chain
*c
;
1073 c
= &sc
->aue_cdata
.aue_tx_chain
[idx
];
1076 * Copy the mbuf data into a contiguous buffer, leaving two
1077 * bytes at the beginning to hold the frame length.
1079 m_copydata(m
, 0, m
->m_pkthdr
.len
, c
->aue_buf
+ 2);
1082 total_len
= m
->m_pkthdr
.len
+ 2;
1085 * The ADMtek documentation says that the packet length is
1086 * supposed to be specified in the first two bytes of the
1087 * transfer, however it actually seems to ignore this info
1088 * and base the frame size on the bulk transfer length.
1090 c
->aue_buf
[0] = (u_int8_t
)m
->m_pkthdr
.len
;
1091 c
->aue_buf
[1] = (u_int8_t
)(m
->m_pkthdr
.len
>> 8);
1093 m_freem(c
->aue_mbuf
);
1097 usbd_setup_xfer(c
->aue_xfer
, sc
->aue_ep
[AUE_ENDPT_TX
],
1098 c
, c
->aue_buf
, total_len
, USBD_FORCE_SHORT_XFER
,
1102 err
= usbd_transfer(c
->aue_xfer
);
1103 if (err
!= USBD_IN_PROGRESS
) {
1108 sc
->aue_cdata
.aue_tx_cnt
++;
1114 aue_start(struct ifnet
*ifp
)
1116 struct aue_softc
*sc
= ifp
->if_softc
;
1117 struct mbuf
*m_head
= NULL
;
1121 if (!sc
->aue_link
) {
1122 ifq_purge(&ifp
->if_snd
);
1127 if ((ifp
->if_flags
& (IFF_OACTIVE
| IFF_RUNNING
)) != IFF_RUNNING
) {
1132 m_head
= ifq_dequeue(&ifp
->if_snd
, NULL
);
1133 if (m_head
== NULL
) {
1138 if (aue_encap(sc
, m_head
, 0)) {
1139 /* aue_encap() will free m_head, if we reach here */
1140 ifp
->if_flags
|= IFF_OACTIVE
;
1146 * If there's a BPF listener, bounce a copy of this frame
1149 BPF_MTAP(ifp
, m_head
);
1151 ifp
->if_flags
|= IFF_OACTIVE
;
1154 * Set a timeout in case the chip goes out to lunch.
1165 struct aue_softc
*sc
= xsc
;
1166 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
1167 struct mii_data
*mii
= GET_MII(sc
);
1168 struct aue_chain
*c
;
1174 if (ifp
->if_flags
& IFF_RUNNING
) {
1180 * Cancel pending I/O and free all RX/TX buffers.
1184 /* Set MAC address */
1185 for (i
= 0; i
< ETHER_ADDR_LEN
; i
++)
1186 aue_csr_write_1(sc
, AUE_PAR0
+ i
, sc
->arpcom
.ac_enaddr
[i
]);
1188 /* If we want promiscuous mode, set the allframes bit. */
1189 if (ifp
->if_flags
& IFF_PROMISC
)
1190 AUE_SETBIT(sc
, AUE_CTL2
, AUE_CTL2_RX_PROMISC
);
1192 AUE_CLRBIT(sc
, AUE_CTL2
, AUE_CTL2_RX_PROMISC
);
1195 if (aue_tx_list_init(sc
) == ENOBUFS
) {
1196 if_printf(&sc
->arpcom
.ac_if
, "tx list init failed\n");
1202 if (aue_rx_list_init(sc
) == ENOBUFS
) {
1203 if_printf(&sc
->arpcom
.ac_if
, "rx list init failed\n");
1208 #ifdef AUE_INTR_PIPE
1209 sc
->aue_cdata
.aue_ibuf
= kmalloc(AUE_INTR_PKTLEN
, M_USBDEV
, M_WAITOK
);
1212 /* Load the multicast filter. */
1215 /* Enable RX and TX */
1216 aue_csr_write_1(sc
, AUE_CTL0
, AUE_CTL0_RXSTAT_APPEND
| AUE_CTL0_RX_ENB
);
1217 AUE_SETBIT(sc
, AUE_CTL0
, AUE_CTL0_TX_ENB
);
1218 AUE_SETBIT(sc
, AUE_CTL2
, AUE_CTL2_EP3_CLR
);
1222 /* Open RX and TX pipes. */
1223 err
= usbd_open_pipe(sc
->aue_iface
, sc
->aue_ed
[AUE_ENDPT_RX
],
1224 USBD_EXCLUSIVE_USE
, &sc
->aue_ep
[AUE_ENDPT_RX
]);
1226 if_printf(&sc
->arpcom
.ac_if
, "open rx pipe failed: %s\n",
1231 err
= usbd_open_pipe(sc
->aue_iface
, sc
->aue_ed
[AUE_ENDPT_TX
],
1232 USBD_EXCLUSIVE_USE
, &sc
->aue_ep
[AUE_ENDPT_TX
]);
1234 if_printf(&sc
->arpcom
.ac_if
, "open tx pipe failed: %s\n",
1240 #ifdef AUE_INTR_PIPE
1241 err
= usbd_open_pipe_intr(sc
->aue_iface
, sc
->aue_ed
[AUE_ENDPT_INTR
],
1242 USBD_SHORT_XFER_OK
, &sc
->aue_ep
[AUE_ENDPT_INTR
], sc
,
1243 sc
->aue_cdata
.aue_ibuf
, AUE_INTR_PKTLEN
, aue_intr
,
1246 if_printf(&sc
->arpcom
.ac_if
, "open intr pipe failed: %s\n",
1253 /* Start up the receive pipe. */
1254 for (i
= 0; i
< AUE_RX_LIST_CNT
; i
++) {
1255 c
= &sc
->aue_cdata
.aue_rx_chain
[i
];
1256 usbd_setup_xfer(c
->aue_xfer
, sc
->aue_ep
[AUE_ENDPT_RX
],
1257 c
, mtod(c
->aue_mbuf
, char *), AUE_BUFSZ
,
1258 USBD_SHORT_XFER_OK
, USBD_NO_TIMEOUT
, aue_rxeof
);
1259 usbd_transfer(c
->aue_xfer
);
1262 ifp
->if_flags
|= IFF_RUNNING
;
1263 ifp
->if_flags
&= ~IFF_OACTIVE
;
1265 callout_reset(&sc
->aue_stat_timer
, hz
, aue_tick
, sc
);
1273 * Set media options.
1276 aue_ifmedia_upd(struct ifnet
*ifp
)
1278 struct aue_softc
*sc
= ifp
->if_softc
;
1279 struct mii_data
*mii
= GET_MII(sc
);
1282 if (mii
->mii_instance
) {
1283 struct mii_softc
*miisc
;
1284 LIST_FOREACH(miisc
, &mii
->mii_phys
, mii_list
)
1285 mii_phy_reset(miisc
);
1293 * Report current media status.
1296 aue_ifmedia_sts(struct ifnet
*ifp
, struct ifmediareq
*ifmr
)
1298 struct aue_softc
*sc
= ifp
->if_softc
;
1299 struct mii_data
*mii
= GET_MII(sc
);
1302 ifmr
->ifm_active
= mii
->mii_media_active
;
1303 ifmr
->ifm_status
= mii
->mii_media_status
;
1309 aue_ioctl(struct ifnet
*ifp
, u_long command
, caddr_t data
, struct ucred
*cr
)
1311 struct aue_softc
*sc
= ifp
->if_softc
;
1312 struct ifreq
*ifr
= (struct ifreq
*)data
;
1313 struct mii_data
*mii
;
1320 if (ifp
->if_flags
& IFF_UP
) {
1321 if (ifp
->if_flags
& IFF_RUNNING
&&
1322 ifp
->if_flags
& IFF_PROMISC
&&
1323 !(sc
->aue_if_flags
& IFF_PROMISC
)) {
1324 AUE_SETBIT(sc
, AUE_CTL2
, AUE_CTL2_RX_PROMISC
);
1325 } else if (ifp
->if_flags
& IFF_RUNNING
&&
1326 !(ifp
->if_flags
& IFF_PROMISC
) &&
1327 sc
->aue_if_flags
& IFF_PROMISC
) {
1328 AUE_CLRBIT(sc
, AUE_CTL2
, AUE_CTL2_RX_PROMISC
);
1329 } else if (!(ifp
->if_flags
& IFF_RUNNING
))
1332 if (ifp
->if_flags
& IFF_RUNNING
)
1335 sc
->aue_if_flags
= ifp
->if_flags
;
1346 error
= ifmedia_ioctl(ifp
, ifr
, &mii
->mii_media
, command
);
1349 error
= ether_ioctl(ifp
, command
, data
);
1359 aue_watchdog(struct ifnet
*ifp
)
1361 struct aue_softc
*sc
= ifp
->if_softc
;
1362 struct aue_chain
*c
;
1365 ASSERT_SERIALIZED(ifp
->if_serializer
);
1368 if_printf(ifp
, "watchdog timeout\n");
1370 c
= &sc
->aue_cdata
.aue_tx_chain
[0];
1371 usbd_get_xfer_status(c
->aue_xfer
, NULL
, NULL
, NULL
, &stat
);
1372 aue_txeof(c
->aue_xfer
, c
, stat
);
1376 * Stop the adapter and free any mbufs allocated to the
1380 aue_stop(struct aue_softc
*sc
)
1387 ifp
= &sc
->arpcom
.ac_if
;
1390 aue_csr_write_1(sc
, AUE_CTL0
, 0);
1391 aue_csr_write_1(sc
, AUE_CTL1
, 0);
1393 callout_stop(&sc
->aue_stat_timer
);
1395 /* Stop transfers. */
1396 if (sc
->aue_ep
[AUE_ENDPT_RX
] != NULL
) {
1397 err
= usbd_abort_pipe(sc
->aue_ep
[AUE_ENDPT_RX
]);
1399 if_printf(ifp
, "abort rx pipe failed: %s\n",
1402 err
= usbd_close_pipe(sc
->aue_ep
[AUE_ENDPT_RX
]);
1404 if_printf(ifp
, "close rx pipe failed: %s\n",
1407 sc
->aue_ep
[AUE_ENDPT_RX
] = NULL
;
1410 if (sc
->aue_ep
[AUE_ENDPT_TX
] != NULL
) {
1411 err
= usbd_abort_pipe(sc
->aue_ep
[AUE_ENDPT_TX
]);
1413 if_printf(ifp
, "abort tx pipe failed: %s\n",
1416 err
= usbd_close_pipe(sc
->aue_ep
[AUE_ENDPT_TX
]);
1418 if_printf(ifp
, "close tx pipe failed: %s\n",
1421 sc
->aue_ep
[AUE_ENDPT_TX
] = NULL
;
1424 #ifdef AUE_INTR_PIPE
1425 if (sc
->aue_ep
[AUE_ENDPT_INTR
] != NULL
) {
1426 err
= usbd_abort_pipe(sc
->aue_ep
[AUE_ENDPT_INTR
]);
1428 if_printf(ifp
, "abort intr pipe failed: %s\n",
1431 err
= usbd_close_pipe(sc
->aue_ep
[AUE_ENDPT_INTR
]);
1433 if_printf(ifp
, "close intr pipe failed: %s\n",
1436 sc
->aue_ep
[AUE_ENDPT_INTR
] = NULL
;
1440 /* Free RX resources. */
1441 for (i
= 0; i
< AUE_RX_LIST_CNT
; i
++) {
1442 if (sc
->aue_cdata
.aue_rx_chain
[i
].aue_buf
!= NULL
) {
1443 kfree(sc
->aue_cdata
.aue_rx_chain
[i
].aue_buf
, M_USBDEV
);
1444 sc
->aue_cdata
.aue_rx_chain
[i
].aue_buf
= NULL
;
1446 if (sc
->aue_cdata
.aue_rx_chain
[i
].aue_mbuf
!= NULL
) {
1447 m_freem(sc
->aue_cdata
.aue_rx_chain
[i
].aue_mbuf
);
1448 sc
->aue_cdata
.aue_rx_chain
[i
].aue_mbuf
= NULL
;
1450 if (sc
->aue_cdata
.aue_rx_chain
[i
].aue_xfer
!= NULL
) {
1451 usbd_free_xfer(sc
->aue_cdata
.aue_rx_chain
[i
].aue_xfer
);
1452 sc
->aue_cdata
.aue_rx_chain
[i
].aue_xfer
= NULL
;
1456 /* Free TX resources. */
1457 for (i
= 0; i
< AUE_TX_LIST_CNT
; i
++) {
1458 if (sc
->aue_cdata
.aue_tx_chain
[i
].aue_buf
!= NULL
) {
1459 kfree(sc
->aue_cdata
.aue_tx_chain
[i
].aue_buf
, M_USBDEV
);
1460 sc
->aue_cdata
.aue_tx_chain
[i
].aue_buf
= NULL
;
1462 if (sc
->aue_cdata
.aue_tx_chain
[i
].aue_mbuf
!= NULL
) {
1463 m_freem(sc
->aue_cdata
.aue_tx_chain
[i
].aue_mbuf
);
1464 sc
->aue_cdata
.aue_tx_chain
[i
].aue_mbuf
= NULL
;
1466 if (sc
->aue_cdata
.aue_tx_chain
[i
].aue_xfer
!= NULL
) {
1467 usbd_free_xfer(sc
->aue_cdata
.aue_tx_chain
[i
].aue_xfer
);
1468 sc
->aue_cdata
.aue_tx_chain
[i
].aue_xfer
= NULL
;
1472 #ifdef AUE_INTR_PIPE
1473 if (sc
->aue_cdata
.aue_ibuf
!= NULL
) {
1474 kfree(sc
->aue_cdata
.aue_ibuf
, M_USBDEV
);
1475 sc
->aue_cdata
.aue_ibuf
= NULL
;
1481 ifp
->if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);
1488 * Stop all chip I/O so that the kernel's probe routines don't
1489 * get confused by errant DMAs when rebooting.
1492 aue_shutdown(device_t dev
)
1494 struct aue_softc
*sc
;
1497 sc
= device_get_softc(dev
);
1500 ifp
= &sc
->arpcom
.ac_if
;
1502 lwkt_serialize_enter(ifp
->if_serializer
);
1505 lwkt_serialize_exit(ifp
->if_serializer
);