xref: /openbsd/sys/dev/usb/if_atu.c (revision 09467b48)
1 /*	$OpenBSD: if_atu.c,v 1.132 2020/07/31 10:49:32 mglocker Exp $ */
2 /*
3  * Copyright (c) 2003, 2004
4  *	Daan Vreeken <Danovitsch@Vitsch.net>.  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 Daan Vreeken.
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 Daan Vreeken 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 Daan Vreeken 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 
34 /*
35  * Atmel AT76c503 / AT76c503a / AT76c505 / AT76c505a  USB WLAN driver
36  * version 0.5 - 2004-08-03
37  *
38  * Originally written by Daan Vreeken <Danovitsch @ Vitsch . net>
39  *  http://vitsch.net/bsd/atuwi
40  *
41  * Contributed to by :
42  *  Chris Whitehouse, Alistair Phillips, Peter Pilka, Martijn van Buul,
43  *  Suihong Liang, Arjan van Leeuwen, Stuart Walsh
44  *
45  * Ported to OpenBSD by Theo de Raadt and David Gwynne.
46  */
47 
48 #include "bpfilter.h"
49 
50 #include <sys/param.h>
51 #include <sys/sockio.h>
52 #include <sys/mbuf.h>
53 #include <sys/kernel.h>
54 #include <sys/socket.h>
55 #include <sys/systm.h>
56 #include <sys/timeout.h>
57 #include <sys/queue.h>
58 #include <sys/device.h>
59 
60 #include <machine/bus.h>
61 
62 #include <dev/usb/usb.h>
63 #include <dev/usb/usbdi.h>
64 #include <dev/usb/usbdi_util.h>
65 #include <dev/usb/usbdivar.h>
66 
67 #include <dev/usb/usbdevs.h>
68 
69 #if NBPFILTER > 0
70 #include <net/bpf.h>
71 #endif
72 
73 #include <net/if.h>
74 #include <net/if_media.h>
75 
76 #include <netinet/in.h>
77 #include <netinet/if_ether.h>
78 
79 #include <net80211/ieee80211_var.h>
80 #include <net80211/ieee80211_radiotap.h>
81 
82 #include <dev/usb/if_atureg.h>
83 
84 #ifdef ATU_DEBUG
85 #define DPRINTF(x)	do { if (atudebug) printf x; } while (0)
86 #define DPRINTFN(n,x)	do { if (atudebug>(n)) printf x; } while (0)
87 int atudebug = 1;
88 #else
89 #define DPRINTF(x)
90 #define DPRINTFN(n,x)
91 #endif
92 
93 int atu_match(struct device *, void *, void *);
94 void atu_attach(struct device *, struct device *, void *);
95 int atu_detach(struct device *, int);
96 
97 struct cfdriver atu_cd = {
98 	NULL, "atu", DV_IFNET
99 };
100 
101 const struct cfattach atu_ca = {
102 	sizeof(struct atu_softc), atu_match, atu_attach, atu_detach
103 };
104 
105 /*
106  * Various supported device vendors/products/radio type.
107  */
108 struct atu_type atu_devs[] = {
109 	{ USB_VENDOR_3COM,	USB_PRODUCT_3COM_3CRSHEW696,
110 	  RadioRFMD,		ATU_NO_QUIRK },
111 	{ USB_VENDOR_ABOCOM,	USB_PRODUCT_ABOCOM_BWU613,
112 	  RadioRFMD,		ATU_NO_QUIRK },
113 	{ USB_VENDOR_ACCTON,	USB_PRODUCT_ACCTON_2664W,
114 	  AT76C503_rfmd_acc,	ATU_NO_QUIRK },
115 	{ USB_VENDOR_ACERP,	USB_PRODUCT_ACERP_AWL300,
116 	  RadioIntersil,	ATU_NO_QUIRK },
117 	{ USB_VENDOR_ACERP,	USB_PRODUCT_ACERP_AWL400,
118 	  RadioRFMD,		ATU_NO_QUIRK },
119 	{ USB_VENDOR_ACTIONTEC,	USB_PRODUCT_ACTIONTEC_802UAT1,
120 	  RadioRFMD,		ATU_NO_QUIRK },
121 	{ USB_VENDOR_ADDTRON,	USB_PRODUCT_ADDTRON_AWU120,
122 	  RadioIntersil,	ATU_NO_QUIRK },
123 	{ USB_VENDOR_AINCOMM,	USB_PRODUCT_AINCOMM_AWU2000B,
124 	  RadioRFMD2958,	ATU_NO_QUIRK },
125 	{ USB_VENDOR_ASKEY,	USB_PRODUCT_ASKEY_VOYAGER1010,
126 	  RadioIntersil,	ATU_NO_QUIRK },
127 	{ USB_VENDOR_ASKEY,	USB_PRODUCT_ASKEY_WLL013I,
128 	  RadioIntersil,	ATU_NO_QUIRK },
129 	{ USB_VENDOR_ASKEY,	USB_PRODUCT_ASKEY_WLL013,
130 	  RadioRFMD,		ATU_NO_QUIRK },
131 	{ USB_VENDOR_ATMEL,	USB_PRODUCT_ATMEL_AT76C503I1,
132 	  RadioIntersil,	ATU_NO_QUIRK },
133 	{ USB_VENDOR_ATMEL,	USB_PRODUCT_ATMEL_AT76C503I2,
134 	  AT76C503_i3863,	ATU_NO_QUIRK },
135 	{ USB_VENDOR_ATMEL,	USB_PRODUCT_ATMEL_AT76C503RFMD,
136 	  RadioRFMD,		ATU_NO_QUIRK },
137 	{ USB_VENDOR_ATMEL,	USB_PRODUCT_ATMEL_AT76C505RFMD,
138 	  AT76C505_rfmd,	ATU_NO_QUIRK },
139 	{ USB_VENDOR_ATMEL,	USB_PRODUCT_ATMEL_AT76C505RFMD2958,
140 	  RadioRFMD2958,	ATU_NO_QUIRK },
141 	{ USB_VENDOR_ATMEL,	USB_PRODUCT_ATMEL_AT76C505A, /* SMC2662 V.4 */
142 	  RadioRFMD2958_SMC,	ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
143 	{ USB_VENDOR_ATMEL,	USB_PRODUCT_ATMEL_AT76C505AS, /* quirk? */
144 	  RadioRFMD2958_SMC,	ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
145 	{ USB_VENDOR_ATMEL,	USB_PRODUCT_ATMEL_WN210,
146 	  RadioRFMD,		ATU_NO_QUIRK },
147 	{ USB_VENDOR_BELKIN,	USB_PRODUCT_BELKIN_F5D6050,
148 	  RadioRFMD,		ATU_NO_QUIRK },
149 	{ USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_C11U,
150 	  RadioIntersil,	ATU_NO_QUIRK },
151 	{ USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_WL210,
152 	  RadioIntersil,	ATU_NO_QUIRK },
153 	{ USB_VENDOR_COMPAQ,	USB_PRODUCT_COMPAQ_IPAQWLAN,
154 	  RadioRFMD,		ATU_NO_QUIRK },
155 	{ USB_VENDOR_COREGA,	USB_PRODUCT_COREGA_WLUSB_11_STICK,
156 	  RadioRFMD2958,	ATU_NO_QUIRK },
157 	{ USB_VENDOR_DICKSMITH,	USB_PRODUCT_DICKSMITH_CHUSB611G,
158 	  RadioRFMD2958,	ATU_NO_QUIRK },
159 	{ USB_VENDOR_DICKSMITH,	USB_PRODUCT_DICKSMITH_WL200U,
160 	  RadioRFMD,		ATU_NO_QUIRK },
161 	{ USB_VENDOR_DICKSMITH,	USB_PRODUCT_DICKSMITH_WL240U,
162 	  RadioRFMD2958,	ATU_NO_QUIRK },
163 	{ USB_VENDOR_DICKSMITH,	USB_PRODUCT_DICKSMITH_XH1153,
164 	  RadioRFMD,		ATU_NO_QUIRK },
165 	{ USB_VENDOR_DLINK,	USB_PRODUCT_DLINK_DWL120E,
166 	  RadioRFMD,		ATU_NO_QUIRK },
167 	{ USB_VENDOR_GIGABYTE,	USB_PRODUCT_GIGABYTE_GNWLBM101,
168 	  RadioRFMD,		ATU_NO_QUIRK },
169 	{ USB_VENDOR_GIGASET,	USB_PRODUCT_GIGASET_WLAN, /* quirk? */
170 	  RadioRFMD2958_SMC,	ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
171 	{ USB_VENDOR_HP,	USB_PRODUCT_HP_HN210W,
172 	  RadioIntersil,	ATU_NO_QUIRK },
173 	{ USB_VENDOR_INTEL,	USB_PRODUCT_INTEL_AP310,
174 	  RadioIntersil,	ATU_NO_QUIRK },
175 	{ USB_VENDOR_IODATA,	USB_PRODUCT_IODATA_USBWNB11A,
176 	  RadioIntersil,	ATU_NO_QUIRK },
177 	{ USB_VENDOR_LEXAR,	USB_PRODUCT_LEXAR_2662WAR,
178 	  RadioRFMD,		ATU_NO_QUIRK },
179 	{ USB_VENDOR_LINKSYS,	USB_PRODUCT_LINKSYS_WUSB11,
180 	  RadioIntersil,	ATU_NO_QUIRK },
181 	{ USB_VENDOR_LINKSYS2,	USB_PRODUCT_LINKSYS2_NWU11B,
182 	  RadioRFMD,		ATU_NO_QUIRK },
183 	{ USB_VENDOR_LINKSYS3,	USB_PRODUCT_LINKSYS3_WUSB11V28,
184 	  RadioRFMD2958,	ATU_NO_QUIRK },
185 	{ USB_VENDOR_MSI,	USB_PRODUCT_MSI_WLAN,
186 	  RadioRFMD2958,	ATU_NO_QUIRK },
187 	{ USB_VENDOR_NETGEAR2,	USB_PRODUCT_NETGEAR2_MA101,
188 	  RadioIntersil,	ATU_NO_QUIRK },
189 	{ USB_VENDOR_NETGEAR2,	USB_PRODUCT_NETGEAR2_MA101B,
190 	  RadioRFMD,		ATU_NO_QUIRK },
191 	{ USB_VENDOR_OQO,	USB_PRODUCT_OQO_WIFI01,
192 	  RadioRFMD2958_SMC,	ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
193 	{ USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_GW_US11S,
194 	  RadioRFMD,		ATU_NO_QUIRK },
195 	{ USB_VENDOR_SAMSUNG,	USB_PRODUCT_SAMSUNG_SWL2100W,
196 	  AT76C503_i3863,	ATU_NO_QUIRK },
197 	{ USB_VENDOR_SIEMENS2,	USB_PRODUCT_SIEMENS2_WLL013,
198 	  RadioRFMD,		ATU_NO_QUIRK },
199 	{ USB_VENDOR_SMC3,	USB_PRODUCT_SMC3_2662WV1,
200 	  RadioIntersil,	ATU_NO_QUIRK },
201 	{ USB_VENDOR_SMC3,	USB_PRODUCT_SMC3_2662WV2,
202 	  AT76C503_rfmd_acc,	ATU_NO_QUIRK },
203 	{ USB_VENDOR_TEKRAM,	USB_PRODUCT_TEKRAM_U300C,
204 	  RadioIntersil,	ATU_NO_QUIRK },
205 	{ USB_VENDOR_ZCOM,	USB_PRODUCT_ZCOM_M4Y750,
206 	  RadioIntersil,	ATU_NO_QUIRK },
207 };
208 
209 struct atu_radfirm {
210 	enum	atu_radio_type atur_type;
211 	char	*atur_internal;
212 	char	*atur_external;
213 	u_int8_t max_rssi;
214 } atu_radfirm[] = {
215 	{ RadioRFMD,		"atu-rfmd-int",		"atu-rfmd-ext",	0 },
216 	{ RadioRFMD2958,	"atu-rfmd2958-int",	"atu-rfmd2958-ext", 81 },
217 	{ RadioRFMD2958_SMC,	"atu-rfmd2958smc-int",	"atu-rfmd2958smc-ext", 0 },
218 	{ RadioIntersil,	"atu-intersil-int",	"atu-intersil-ext", 0 },
219 	{
220 		AT76C503_i3863,
221 		"atu-at76c503-i3863-int",
222 		"atu-at76c503-i3863-ext",
223 		0
224 	},
225 	{
226 		AT76C503_rfmd_acc,
227 		"atu-at76c503-rfmd-acc-int",
228 		"atu-at76c503-rfmd-acc-ext",
229 		0
230 	},
231 	{
232 		AT76C505_rfmd,
233 		"atu-at76c505-rfmd-int",
234 		"atu-at76c505-rfmd-ext",
235 		0
236 	}
237 };
238 
239 int	atu_newbuf(struct atu_softc *, struct atu_chain *, struct mbuf *);
240 void	atu_rxeof(struct usbd_xfer *, void *, usbd_status);
241 void	atu_txeof(struct usbd_xfer *, void *, usbd_status);
242 void	atu_start(struct ifnet *);
243 int	atu_ioctl(struct ifnet *, u_long, caddr_t);
244 int	atu_init(struct ifnet *);
245 void	atu_stop(struct ifnet *, int);
246 void	atu_watchdog(struct ifnet *);
247 usbd_status atu_usb_request(struct atu_softc *sc, u_int8_t type,
248 	    u_int8_t request, u_int16_t value, u_int16_t index,
249 	    u_int16_t length, u_int8_t *data);
250 int	atu_send_command(struct atu_softc *sc, u_int8_t *command, int size);
251 int	atu_get_cmd_status(struct atu_softc *sc, u_int8_t cmd,
252 	    u_int8_t *status);
253 int	atu_wait_completion(struct atu_softc *sc, u_int8_t cmd,
254 	    u_int8_t *status);
255 int	atu_send_mib(struct atu_softc *sc, u_int8_t type,
256 	    u_int8_t size, u_int8_t index, void *data);
257 int	atu_get_mib(struct atu_softc *sc, u_int8_t type,
258 	    u_int8_t size, u_int8_t index, u_int8_t *buf);
259 #if 0
260 int	atu_start_ibss(struct atu_softc *sc);
261 #endif
262 int	atu_start_scan(struct atu_softc *sc);
263 int	atu_switch_radio(struct atu_softc *sc, int state);
264 int	atu_initial_config(struct atu_softc *sc);
265 int	atu_join(struct atu_softc *sc, struct ieee80211_node *node);
266 int8_t	atu_get_dfu_state(struct atu_softc *sc);
267 u_int8_t atu_get_opmode(struct atu_softc *sc, u_int8_t *mode);
268 void	atu_internal_firmware(struct device *);
269 void	atu_external_firmware(struct device *);
270 int	atu_get_card_config(struct atu_softc *sc);
271 int	atu_media_change(struct ifnet *ifp);
272 void	atu_media_status(struct ifnet *ifp, struct ifmediareq *req);
273 int	atu_tx_list_init(struct atu_softc *);
274 int	atu_rx_list_init(struct atu_softc *);
275 void	atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch,
276 	    int listlen);
277 
278 void atu_task(void *);
279 int atu_newstate(struct ieee80211com *, enum ieee80211_state, int);
280 int atu_tx_start(struct atu_softc *, struct ieee80211_node *,
281     struct atu_chain *, struct mbuf *);
282 void atu_complete_attach(struct atu_softc *);
283 u_int8_t atu_calculate_padding(int);
284 
285 usbd_status
286 atu_usb_request(struct atu_softc *sc, u_int8_t type,
287     u_int8_t request, u_int16_t value, u_int16_t index, u_int16_t length,
288     u_int8_t *data)
289 {
290 	usb_device_request_t	req;
291 	struct usbd_xfer	*xfer;
292 	usbd_status		err;
293 	int			total_len = 0, s;
294 
295 	req.bmRequestType = type;
296 	req.bRequest = request;
297 	USETW(req.wValue, value);
298 	USETW(req.wIndex, index);
299 	USETW(req.wLength, length);
300 
301 #ifdef ATU_DEBUG
302 	if (atudebug) {
303 		if ((data == NULL) || (type & UT_READ)) {
304 			DPRINTFN(20, ("%s: req=%02x val=%02x ind=%02x "
305 			    "len=%02x\n", sc->atu_dev.dv_xname, request,
306 			    value, index, length));
307 		} else {
308 			DPRINTFN(20, ("%s: req=%02x val=%02x ind=%02x "
309 			    "len=%02x [%8D]\n", sc->atu_dev.dv_xname,
310 			    request, value, index, length, data, " "));
311 		}
312 	}
313 #endif /* ATU_DEBUG */
314 
315 	s = splnet();
316 
317 	xfer = usbd_alloc_xfer(sc->atu_udev);
318 	usbd_setup_default_xfer(xfer, sc->atu_udev, 0, 500000, &req, data,
319 	    length, USBD_SHORT_XFER_OK | USBD_SYNCHRONOUS, 0);
320 
321 	err = usbd_transfer(xfer);
322 
323 	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
324 
325 #ifdef ATU_DEBUG
326 	if (atudebug) {
327 		if (type & UT_READ) {
328 			DPRINTFN(20, ("%s: transferred 0x%x bytes in\n",
329 			    sc->atu_dev.dv_xname, total_len));
330 			DPRINTFN(20, ("%s: dump [%10D]\n",
331 			    sc->atu_dev.dv_xname, data, " "));
332 		} else {
333 			if (total_len != length)
334 				DPRINTF(("%s: ARG! wrote only %x bytes\n",
335 				    sc->atu_dev.dv_xname, total_len));
336 		}
337 	}
338 #endif /* ATU_DEBUG */
339 
340 	usbd_free_xfer(xfer);
341 
342 	splx(s);
343 	return(err);
344 }
345 
346 int
347 atu_send_command(struct atu_softc *sc, u_int8_t *command, int size)
348 {
349 	return atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000,
350 	    0x0000, size, command);
351 }
352 
353 int
354 atu_get_cmd_status(struct atu_softc *sc, u_int8_t cmd, u_int8_t *status)
355 {
356 	/*
357 	 * all other drivers (including Windoze) request 40 bytes of status
358 	 * and get a short-xfer of just 6 bytes. we can save 34 bytes of
359 	 * buffer if we just request those 6 bytes in the first place :)
360 	 */
361 	/*
362 	return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd,
363 	    0x0000, 40, status);
364 	*/
365 	return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd,
366 	    0x0000, 6, status);
367 }
368 
369 int
370 atu_wait_completion(struct atu_softc *sc, u_int8_t cmd, u_int8_t *status)
371 {
372 	int			idle_count = 0, err;
373 	u_int8_t		statusreq[6];
374 
375 	DPRINTFN(15, ("%s: wait-completion: cmd=%02x\n",
376 	    sc->atu_dev.dv_xname, cmd));
377 
378 	while (1) {
379 		err = atu_get_cmd_status(sc, cmd, statusreq);
380 		if (err)
381 			return err;
382 
383 #ifdef ATU_DEBUG
384 		if (atudebug) {
385 			DPRINTFN(20, ("%s: status=%s cmd=%02x\n",
386 			    sc->atu_dev.dv_xname,
387 			ether_sprintf(statusreq), cmd));
388 		}
389 #endif /* ATU_DEBUG */
390 
391 		/*
392 		 * during normal operations waiting on STATUS_IDLE
393 		 * will never happen more than once
394 		 */
395 		if ((statusreq[5] == STATUS_IDLE) && (idle_count++ > 20)) {
396 			DPRINTF(("%s: AAARRGGG!!! FIX ME!\n",
397 			    sc->atu_dev.dv_xname));
398 			return 0;
399 		}
400 
401 		if ((statusreq[5] != STATUS_IN_PROGRESS) &&
402 		    (statusreq[5] != STATUS_IDLE)) {
403 			if (status != NULL)
404 				*status = statusreq[5];
405 			return 0;
406 		}
407 		usbd_delay_ms(sc->atu_udev, 25);
408 	}
409 }
410 
411 int
412 atu_send_mib(struct atu_softc *sc, u_int8_t type, u_int8_t size,
413     u_int8_t index, void *data)
414 {
415 	int				err;
416 	struct atu_cmd_set_mib		request;
417 
418 	/*
419 	 * We don't construct a MIB packet first and then memcpy it into an
420 	 * Atmel-command-packet, we just construct it the right way at once :)
421 	 */
422 
423 	memset(&request, 0, sizeof(request));
424 
425 	request.AtCmd = CMD_SET_MIB;
426 	USETW(request.AtSize, size + 4);
427 
428 	request.MIBType = type;
429 	request.MIBSize = size;
430 	request.MIBIndex = index;
431 	request.MIBReserved = 0;
432 
433 	/*
434 	 * For 1 and 2 byte requests we assume a direct value,
435 	 * everything bigger than 2 bytes we assume a pointer to the data
436 	 */
437 	switch (size) {
438 	case 0:
439 		break;
440 	case 1:
441 		request.data[0]=(long)data & 0x000000ff;
442 		break;
443 	case 2:
444 		request.data[0]=(long)data & 0x000000ff;
445 		request.data[1]=(long)data >> 8;
446 		break;
447 	default:
448 		memcpy(request.data, data, size);
449 		break;
450 	}
451 
452 	err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000,
453 	    0x0000, size+8, (uByte *)&request);
454 	if (err)
455 		return (err);
456 
457 	DPRINTFN(15, ("%s: sendmib : waitcompletion...\n",
458 	    sc->atu_dev.dv_xname));
459 	return atu_wait_completion(sc, CMD_SET_MIB, NULL);
460 }
461 
462 int
463 atu_get_mib(struct atu_softc *sc, u_int8_t type, u_int8_t size,
464     u_int8_t index, u_int8_t *buf)
465 {
466 
467 	/* linux/at76c503.c - 478 */
468 	return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x033,
469 	    type << 8, index, size, buf);
470 }
471 
472 #if 0
473 int
474 atu_start_ibss(struct atu_softc *sc)
475 {
476 	int				err;
477 	struct atu_cmd_start_ibss	Request;
478 
479 	Request.Cmd = CMD_START_IBSS;
480 	Request.Reserved = 0;
481 	Request.Size = sizeof(Request) - 4;
482 
483 	memset(Request.BSSID, 0x00, sizeof(Request.BSSID));
484 	memset(Request.SSID, 0x00, sizeof(Request.SSID));
485 	memcpy(Request.SSID, sc->atu_ssid, sc->atu_ssidlen);
486 	Request.SSIDSize = sc->atu_ssidlen;
487 	if (sc->atu_desired_channel != IEEE80211_CHAN_ANY)
488 		Request.Channel = (u_int8_t)sc->atu_desired_channel;
489 	else
490 		Request.Channel = ATU_DEFAULT_CHANNEL;
491 	Request.BSSType = AD_HOC_MODE;
492 	memset(Request.Res, 0x00, sizeof(Request.Res));
493 
494 	/* Write config to adapter */
495 	err = atu_send_command(sc, (u_int8_t *)&Request, sizeof(Request));
496 	if (err) {
497 		DPRINTF(("%s: start ibss failed!\n",
498 		    sc->atu_dev.dv_xname));
499 		return err;
500 	}
501 
502 	/* Wait for the adapter to do its thing */
503 	err = atu_wait_completion(sc, CMD_START_IBSS, NULL);
504 	if (err) {
505 		DPRINTF(("%s: error waiting for start_ibss\n",
506 		    sc->atu_dev.dv_xname));
507 		return err;
508 	}
509 
510 	/* Get the current BSSID */
511 	err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_BSSID, sc->atu_bssid);
512 	if (err) {
513 		DPRINTF(("%s: could not get BSSID!\n",
514 		    sc->atu_dev.dv_xname));
515 		return err;
516 	}
517 
518 	DPRINTF(("%s: started a new IBSS (BSSID=%s)\n",
519 	    sc->atu_dev.dv_xname, ether_sprintf(sc->atu_bssid)));
520 	return 0;
521 }
522 #endif
523 
524 int
525 atu_start_scan(struct atu_softc *sc)
526 {
527 	struct ieee80211com		*ic = &sc->sc_ic;
528 	struct atu_cmd_do_scan		Scan;
529 	usbd_status			err;
530 	int				Cnt;
531 
532 	memset(&Scan, 0, sizeof(Scan));
533 
534 	Scan.Cmd = CMD_START_SCAN;
535 	Scan.Reserved = 0;
536 	USETW(Scan.Size, sizeof(Scan) - 4);
537 
538 	/* use the broadcast BSSID (in active scan) */
539 	for (Cnt=0; Cnt<6; Cnt++)
540 		Scan.BSSID[Cnt] = 0xff;
541 
542 	memcpy(Scan.SSID, ic->ic_des_essid, ic->ic_des_esslen);
543 	Scan.SSID_Len = ic->ic_des_esslen;
544 
545 	/* default values for scan */
546 	Scan.ScanType = ATU_SCAN_ACTIVE;
547 	if (sc->atu_desired_channel != IEEE80211_CHAN_ANY)
548 		Scan.Channel = (u_int8_t)sc->atu_desired_channel;
549 	else
550 		Scan.Channel = sc->atu_channel;
551 
552 	/* we like scans to be quick :) */
553 	/* the time we wait before sending probe's */
554 	USETW(Scan.ProbeDelay, 0);
555 	/* the time we stay on one channel */
556 	USETW(Scan.MinChannelTime, 100);
557 	USETW(Scan.MaxChannelTime, 200);
558 	/* whether or not we scan all channels */
559 	Scan.InternationalScan = 0xc1;
560 
561 #ifdef ATU_DEBUG
562 	if (atudebug) {
563 		DPRINTFN(20, ("%s: scan cmd len=%02x\n",
564 		    sc->atu_dev.dv_xname, sizeof(Scan)));
565 		DPRINTFN(20, ("%s: scan cmd: %52D\n", sc->atu_dev.dv_xname,
566 		    (u_int8_t *)&Scan, " "));
567 	}
568 #endif /* ATU_DEBUG */
569 
570 	/* Write config to adapter */
571 	err = atu_send_command(sc, (u_int8_t *)&Scan, sizeof(Scan));
572 	if (err)
573 		return err;
574 
575 	/*
576 	 * We don't wait for the command to finish... the mgmt-thread will do
577 	 * that for us
578 	 */
579 	/*
580 	err = atu_wait_completion(sc, CMD_START_SCAN, NULL);
581 	if (err)
582 		return err;
583 	*/
584 	return 0;
585 }
586 
587 int
588 atu_switch_radio(struct atu_softc *sc, int state)
589 {
590 	usbd_status		err;
591 	struct atu_cmd		CmdRadio;
592 
593 	if (sc->atu_radio == RadioIntersil) {
594 		/*
595 		 * Intersil doesn't seem to need/support switching the radio
596 		 * on/off
597 		 */
598 		return 0;
599 	}
600 
601 	memset(&CmdRadio, 0, sizeof(CmdRadio));
602 	CmdRadio.Cmd = CMD_RADIO_ON;
603 
604 	if (sc->atu_radio_on != state) {
605 		if (state == 0)
606 			CmdRadio.Cmd = CMD_RADIO_OFF;
607 
608 		err = atu_send_command(sc, (u_int8_t *)&CmdRadio,
609 		    sizeof(CmdRadio));
610 		if (err)
611 			return err;
612 
613 		err = atu_wait_completion(sc, CmdRadio.Cmd, NULL);
614 		if (err)
615 			return err;
616 
617 		DPRINTFN(10, ("%s: radio turned %s\n",
618 		    sc->atu_dev.dv_xname, state ? "on" : "off"));
619 		sc->atu_radio_on = state;
620 	}
621 	return 0;
622 }
623 
624 int
625 atu_initial_config(struct atu_softc *sc)
626 {
627 	struct ieee80211com		*ic = &sc->sc_ic;
628 	u_int32_t			i;
629 	usbd_status			err;
630 /*	u_int8_t			rates[4] = {0x82, 0x84, 0x8B, 0x96};*/
631 	u_int8_t			rates[4] = {0x82, 0x04, 0x0B, 0x16};
632 	struct atu_cmd_card_config	cmd;
633 	u_int8_t			reg_domain;
634 
635 	DPRINTFN(10, ("%s: sending mac-addr\n", sc->atu_dev.dv_xname));
636 	err = atu_send_mib(sc, MIB_MAC_ADDR__ADDR, ic->ic_myaddr);
637 	if (err) {
638 		DPRINTF(("%s: error setting mac-addr\n",
639 		    sc->atu_dev.dv_xname));
640 		return err;
641 	}
642 
643 	/*
644 	DPRINTF(("%s: sending reg-domain\n", sc->atu_dev.dv_xname));
645 	err = atu_send_mib(sc, MIB_PHY__REG_DOMAIN, NR(0x30));
646 	if (err) {
647 		DPRINTF(("%s: error setting mac-addr\n",
648 		    sc->atu_dev.dv_xname));
649 		return err;
650 	}
651 	*/
652 
653 	memset(&cmd, 0, sizeof(cmd));
654 	cmd.Cmd = CMD_STARTUP;
655 	cmd.Reserved = 0;
656 	USETW(cmd.Size, sizeof(cmd) - 4);
657 
658 	if (sc->atu_desired_channel != IEEE80211_CHAN_ANY)
659 		cmd.Channel = (u_int8_t)sc->atu_desired_channel;
660 	else
661 		cmd.Channel = sc->atu_channel;
662 	cmd.AutoRateFallback = 1;
663 	memcpy(cmd.BasicRateSet, rates, 4);
664 
665 	/* ShortRetryLimit should be 7 according to 802.11 spec */
666 	cmd.ShortRetryLimit = 7;
667 	USETW(cmd.RTS_Threshold, 2347);
668 	USETW(cmd.FragThreshold, 2346);
669 
670 	/* Doesn't seem to work, but we'll set it to 1 anyway */
671 	cmd.PromiscuousMode = 1;
672 
673 	/* this goes into the beacon we transmit */
674 	cmd.PrivacyInvoked = (ic->ic_flags & IEEE80211_F_WEPON) ? 1 : 0;
675 
676 	cmd.ExcludeUnencrypted = 0;
677 	switch (ic->ic_nw_keys[ic->ic_wep_txkey].k_cipher) {
678 	case IEEE80211_CIPHER_WEP40:
679 		cmd.EncryptionType = ATU_WEP_40BITS;
680 		break;
681 	case IEEE80211_CIPHER_WEP104:
682 		cmd.EncryptionType = ATU_WEP_104BITS;
683 		break;
684 	default:
685 		cmd.EncryptionType = ATU_WEP_OFF;
686 		break;
687 	}
688 
689 	cmd.WEP_DefaultKeyID = ic->ic_wep_txkey;
690 	for (i = 0; i < IEEE80211_WEP_NKID; i++) {
691 		memcpy(cmd.WEP_DefaultKey[i], ic->ic_nw_keys[i].k_key,
692 		    ic->ic_nw_keys[i].k_len);
693 	}
694 
695 	/* Setting the SSID here doesn't seem to do anything */
696 	memcpy(cmd.SSID, ic->ic_des_essid, ic->ic_des_esslen);
697 	cmd.SSID_Len = ic->ic_des_esslen;
698 
699 	cmd.ShortPreamble = 0;
700 	USETW(cmd.BeaconPeriod, 100);
701 	/* cmd.BeaconPeriod = 65535; */
702 
703 	/*
704 	 * TODO:
705 	 * read reg domain MIB_PHY @ 0x17 (1 byte), (reply = 0x30)
706 	 * we should do something useful with this info. right now it's just
707 	 * ignored
708 	 */
709 	err = atu_get_mib(sc, MIB_PHY__REG_DOMAIN, &reg_domain);
710 	if (err) {
711 		DPRINTF(("%s: could not get regdomain!\n",
712 		    sc->atu_dev.dv_xname));
713 	} else {
714 		DPRINTF(("%s: we're in reg domain 0x%x according to the "
715 		    "adapter\n", sc->atu_dev.dv_xname, reg_domain));
716 	}
717 
718 #ifdef ATU_DEBUG
719 	if (atudebug) {
720 		DPRINTFN(20, ("%s: configlen=%02x\n", sc->atu_dev.dv_xname,
721 		    sizeof(cmd)));
722 		DPRINTFN(20, ("%s: configdata= %108D\n",
723 		    sc->atu_dev.dv_xname, (u_int8_t *)&cmd, " "));
724 	}
725 #endif /* ATU_DEBUG */
726 
727 	/* Windoze : driver says exclude-unencrypted=1 & encr-type=1 */
728 
729 	err = atu_send_command(sc, (u_int8_t *)&cmd, sizeof(cmd));
730 	if (err)
731 		return err;
732 	err = atu_wait_completion(sc, CMD_STARTUP, NULL);
733 	if (err)
734 		return err;
735 
736 	/* Turn on radio now */
737 	err = atu_switch_radio(sc, 1);
738 	if (err)
739 		return err;
740 
741 	/* preamble type = short */
742 	err = atu_send_mib(sc, MIB_LOCAL__PREAMBLE, NR(PREAMBLE_SHORT));
743 	if (err)
744 		return err;
745 
746 	/* frag = 1536 */
747 	err = atu_send_mib(sc, MIB_MAC__FRAG, NR(2346));
748 	if (err)
749 		return err;
750 
751 	/* rts = 1536 */
752 	err = atu_send_mib(sc, MIB_MAC__RTS, NR(2347));
753 	if (err)
754 		return err;
755 
756 	/* auto rate fallback = 1 */
757 	err = atu_send_mib(sc, MIB_LOCAL__AUTO_RATE_FALLBACK, NR(1));
758 	if (err)
759 		return err;
760 
761 	/* power mode = full on, no power saving */
762 	err = atu_send_mib(sc, MIB_MAC_MGMT__POWER_MODE,
763 	    NR(POWER_MODE_ACTIVE));
764 	if (err)
765 		return err;
766 
767 	DPRINTFN(10, ("%s: completed initial config\n",
768 	   sc->atu_dev.dv_xname));
769 	return 0;
770 }
771 
772 int
773 atu_join(struct atu_softc *sc, struct ieee80211_node *node)
774 {
775 	struct atu_cmd_join		join;
776 	u_int8_t			status;
777 	usbd_status			err;
778 
779 	memset(&join, 0, sizeof(join));
780 
781 	join.Cmd = CMD_JOIN;
782 	join.Reserved = 0x00;
783 	USETW(join.Size, sizeof(join) - 4);
784 
785 	DPRINTFN(15, ("%s: pre-join sc->atu_bssid=%s\n",
786 	    sc->atu_dev.dv_xname, ether_sprintf(sc->atu_bssid)));
787 	DPRINTFN(15, ("%s: mode=%d\n", sc->atu_dev.dv_xname,
788 	    sc->atu_mode));
789 	memcpy(join.bssid, node->ni_bssid, IEEE80211_ADDR_LEN);
790 	memcpy(join.essid, node->ni_essid, node->ni_esslen);
791 	join.essid_size = node->ni_esslen;
792 	if (node->ni_capinfo & IEEE80211_CAPINFO_IBSS)
793 		join.bss_type = AD_HOC_MODE;
794 	else
795 		join.bss_type = INFRASTRUCTURE_MODE;
796 	join.channel = ieee80211_chan2ieee(&sc->sc_ic, node->ni_chan);
797 
798 	USETW(join.timeout, ATU_JOIN_TIMEOUT);
799 	join.reserved = 0x00;
800 
801 	DPRINTFN(10, ("%s: trying to join BSSID=%s\n",
802 	    sc->atu_dev.dv_xname, ether_sprintf(join.bssid)));
803 	err = atu_send_command(sc, (u_int8_t *)&join, sizeof(join));
804 	if (err) {
805 		DPRINTF(("%s: ERROR trying to join IBSS\n",
806 		    sc->atu_dev.dv_xname));
807 		return err;
808 	}
809 	err = atu_wait_completion(sc, CMD_JOIN, &status);
810 	if (err) {
811 		DPRINTF(("%s: error joining BSS!\n",
812 		    sc->atu_dev.dv_xname));
813 		return err;
814 	}
815 	if (status != STATUS_COMPLETE) {
816 		DPRINTF(("%s: error joining... [status=%02x]\n",
817 		    sc->atu_dev.dv_xname, status));
818 		return status;
819 	} else {
820 		DPRINTFN(10, ("%s: joined BSS\n", sc->atu_dev.dv_xname));
821 	}
822 	return err;
823 }
824 
825 /*
826  * Get the state of the DFU unit
827  */
828 int8_t
829 atu_get_dfu_state(struct atu_softc *sc)
830 {
831 	u_int8_t	state;
832 
833 	if (atu_usb_request(sc, DFU_GETSTATE, 0, 0, 1, &state))
834 		return -1;
835 	return state;
836 }
837 
838 /*
839  * Get MAC opmode
840  */
841 u_int8_t
842 atu_get_opmode(struct atu_softc *sc, u_int8_t *mode)
843 {
844 
845 	return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 0x0001,
846 	    0x0000, 1, mode);
847 }
848 
849 /*
850  * Upload the internal firmware into the device
851  */
852 void
853 atu_internal_firmware(struct device *self)
854 {
855 	struct atu_softc *sc = (struct atu_softc *)self;
856 	u_char	state, *ptr = NULL, *firm = NULL, status[6];
857 	int block_size, block = 0, err, i;
858 	size_t	firm_len, bytes_left = 0;
859 	char	*name = "unknown-device";
860 
861 	/*
862 	 * Uploading firmware is done with the DFU (Device Firmware Upgrade)
863 	 * interface. See "Universal Serial Bus - Device Class Specification
864 	 * for Device Firmware Upgrade" pdf for details of the protocol.
865 	 * Maybe this could be moved to a separate 'firmware driver' once more
866 	 * device drivers need it... For now we'll just do it here.
867 	 *
868 	 * Just for your information, the Atmel's DFU descriptor looks like
869 	 * this:
870 	 *
871 	 * 07		size
872 	 * 21		type
873 	 * 01		capabilities : only firmware download, need reset
874 	 *		  after download
875 	 * 13 05	detach timeout : max 1299ms between DFU_DETACH and
876 	 *		  reset
877 	 * 00 04	max bytes of firmware per transaction : 1024
878 	 */
879 
880 	/* Choose the right firmware for the device */
881 	for (i = 0; i < nitems(atu_radfirm); i++)
882 		if (sc->atu_radio == atu_radfirm[i].atur_type)
883 			name = atu_radfirm[i].atur_internal;
884 
885 	DPRINTF(("%s: loading firmware %s...\n",
886 	    sc->atu_dev.dv_xname, name));
887 	err = loadfirmware(name, &firm, &firm_len);
888 	if (err != 0) {
889 		printf("%s: %s loadfirmware error %d\n",
890 		    sc->atu_dev.dv_xname, name, err);
891 		goto fail;
892 	}
893 
894 	ptr = firm;
895 	bytes_left = firm_len;
896 	state = atu_get_dfu_state(sc);
897 
898 	while (block >= 0 && state > 0) {
899 		switch (state) {
900 		case DFUState_DnLoadSync:
901 			/* get DFU status */
902 			err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0 , 6,
903 			    status);
904 			if (err) {
905 				DPRINTF(("%s: dfu_getstatus failed!\n",
906 				    sc->atu_dev.dv_xname));
907 				free(firm, M_DEVBUF, firm_len);
908 				goto fail;
909 			}
910 			/* success means state => DnLoadIdle */
911 			state = DFUState_DnLoadIdle;
912 			continue;
913 			break;
914 
915 		case DFUState_DFUIdle:
916 		case DFUState_DnLoadIdle:
917 			if (bytes_left>=DFU_MaxBlockSize)
918 				block_size = DFU_MaxBlockSize;
919 			else
920 				block_size = bytes_left;
921 			DPRINTFN(15, ("%s: firmware block %d\n",
922 			    sc->atu_dev.dv_xname, block));
923 
924 			err = atu_usb_request(sc, DFU_DNLOAD, block++, 0,
925 			    block_size, ptr);
926 			if (err) {
927 				DPRINTF(("%s: dfu_dnload failed\n",
928 				    sc->atu_dev.dv_xname));
929 				free(firm, M_DEVBUF, firm_len);
930 				goto fail;
931 			}
932 
933 			ptr += block_size;
934 			bytes_left -= block_size;
935 			if (block_size == 0)
936 				block = -1;
937 			break;
938 
939 		default:
940 			DPRINTFN(20, ("%s: sleeping for a while\n",
941 			    sc->atu_dev.dv_xname));
942 			usbd_delay_ms(sc->atu_udev, 100);
943 			break;
944 		}
945 
946 		state = atu_get_dfu_state(sc);
947 	}
948 	free(firm, M_DEVBUF, firm_len);
949 
950 	if (state != DFUState_ManifestSync) {
951 		DPRINTF(("%s: state != manifestsync... eek!\n",
952 		    sc->atu_dev.dv_xname));
953 	}
954 
955 	err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0, 6, status);
956 	if (err) {
957 		DPRINTF(("%s: dfu_getstatus failed!\n",
958 		    sc->atu_dev.dv_xname));
959 		goto fail;
960 	}
961 
962 	DPRINTFN(15, ("%s: sending remap\n", sc->atu_dev.dv_xname));
963 	err = atu_usb_request(sc, DFU_REMAP, 0, 0, 0, NULL);
964 	if ((err) && (!ISSET(sc->atu_quirk, ATU_QUIRK_NO_REMAP))) {
965 		DPRINTF(("%s: remap failed!\n", sc->atu_dev.dv_xname));
966 		goto fail;
967 	}
968 
969 	/* after a lot of trying and measuring I found out the device needs
970 	 * about 56 milliseconds after sending the remap command before
971 	 * it's ready to communicate again. So we'll wait just a little bit
972 	 * longer than that to be sure...
973 	 */
974 	usbd_delay_ms(sc->atu_udev, 56+100);
975 
976 	printf("%s: reattaching after firmware upload\n",
977 	    sc->atu_dev.dv_xname);
978 	usb_needs_reattach(sc->atu_udev);
979 
980 fail:
981 	usbd_deactivate(sc->atu_udev);
982 }
983 
984 void
985 atu_external_firmware(struct device *self)
986 {
987 	struct atu_softc *sc = (struct atu_softc *)self;
988 	u_char	*ptr = NULL, *firm = NULL;
989 	int	block_size, block = 0, err, i;
990 	size_t	firm_len, bytes_left = 0;
991 	char	*name = "unknown-device";
992 
993 	for (i = 0; i < nitems(atu_radfirm); i++)
994 		if (sc->atu_radio == atu_radfirm[i].atur_type)
995 			name = atu_radfirm[i].atur_external;
996 
997 	DPRINTF(("%s: loading external firmware %s\n",
998 	    sc->atu_dev.dv_xname, name));
999 	err = loadfirmware(name, &firm, &firm_len);
1000 	if (err != 0) {
1001 		printf("%s: %s loadfirmware error %d\n",
1002 		    sc->atu_dev.dv_xname, name, err);
1003 		return;
1004 	}
1005 	ptr = firm;
1006 	bytes_left = firm_len;
1007 
1008 	while (bytes_left) {
1009 		if (bytes_left > 1024)
1010 			block_size = 1024;
1011 		else
1012 			block_size = bytes_left;
1013 
1014 		DPRINTFN(15, ("%s: block:%d size:%d\n",
1015 		    sc->atu_dev.dv_xname, block, block_size));
1016 		err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e,
1017 		    0x0802, block, block_size, ptr);
1018 		if (err) {
1019 			DPRINTF(("%s: could not load external firmware "
1020 			    "block\n", sc->atu_dev.dv_xname));
1021 			free(firm, M_DEVBUF, firm_len);
1022 			return;
1023 		}
1024 
1025 		ptr += block_size;
1026 		block++;
1027 		bytes_left -= block_size;
1028 	}
1029 	free(firm, M_DEVBUF, firm_len);
1030 
1031 	err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0802,
1032 	    block, 0, NULL);
1033 	if (err) {
1034 		DPRINTF(("%s: could not load last zero-length firmware "
1035 		    "block\n", sc->atu_dev.dv_xname));
1036 		return;
1037 	}
1038 
1039 	/*
1040 	 * The SMC2662w V.4 seems to require some time to do its thing with
1041 	 * the external firmware... 20 ms isn't enough, but 21 ms works 100
1042 	 * times out of 100 tries. We'll wait a bit longer just to be sure
1043 	 */
1044 	if (sc->atu_quirk & ATU_QUIRK_FW_DELAY)
1045 		usbd_delay_ms(sc->atu_udev, 21 + 100);
1046 
1047 	DPRINTFN(10, ("%s: external firmware upload done\n",
1048 	    sc->atu_dev.dv_xname));
1049 	/* complete configuration after the firmwares have been uploaded */
1050 	atu_complete_attach(sc);
1051 }
1052 
1053 int
1054 atu_get_card_config(struct atu_softc *sc)
1055 {
1056 	struct ieee80211com		*ic = &sc->sc_ic;
1057 	struct atu_rfmd_conf		rfmd_conf;
1058 	struct atu_intersil_conf	intersil_conf;
1059 	int				err;
1060 
1061 	switch (sc->atu_radio) {
1062 
1063 	case RadioRFMD:
1064 	case RadioRFMD2958:
1065 	case RadioRFMD2958_SMC:
1066 	case AT76C503_rfmd_acc:
1067 	case AT76C505_rfmd:
1068 		err = atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33,
1069 		    0x0a02, 0x0000, sizeof(rfmd_conf),
1070 		    (u_int8_t *)&rfmd_conf);
1071 		if (err) {
1072 			DPRINTF(("%s: could not get rfmd config!\n",
1073 			    sc->atu_dev.dv_xname));
1074 			return err;
1075 		}
1076 		memcpy(ic->ic_myaddr, rfmd_conf.MACAddr, IEEE80211_ADDR_LEN);
1077 		break;
1078 
1079 	case RadioIntersil:
1080 	case AT76C503_i3863:
1081 		err = atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33,
1082 		    0x0902, 0x0000, sizeof(intersil_conf),
1083 		    (u_int8_t *)&intersil_conf);
1084 		if (err) {
1085 			DPRINTF(("%s: could not get intersil config!\n",
1086 			    sc->atu_dev.dv_xname));
1087 			return err;
1088 		}
1089 		memcpy(ic->ic_myaddr, intersil_conf.MACAddr,
1090 		    IEEE80211_ADDR_LEN);
1091 		break;
1092 	}
1093 	return 0;
1094 }
1095 
1096 /*
1097  * Probe for an AT76c503 chip.
1098  */
1099 int
1100 atu_match(struct device *parent, void *match, void *aux)
1101 {
1102 	struct usb_attach_arg	*uaa = aux;
1103 	int			i;
1104 
1105 	if (uaa->iface == NULL || uaa->configno != ATU_CONFIG_NO)
1106 		return(UMATCH_NONE);
1107 
1108 	for (i = 0; i < nitems(atu_devs); i++) {
1109 		struct atu_type *t = &atu_devs[i];
1110 
1111 		if (uaa->vendor == t->atu_vid &&
1112 		    uaa->product == t->atu_pid) {
1113 			return(UMATCH_VENDOR_PRODUCT);
1114 		}
1115 	}
1116 	return(UMATCH_NONE);
1117 }
1118 
1119 int
1120 atu_media_change(struct ifnet *ifp)
1121 {
1122 #ifdef ATU_DEBUG
1123 	struct atu_softc	*sc = ifp->if_softc;
1124 #endif /* ATU_DEBUG */
1125 	int			err;
1126 
1127 	DPRINTFN(10, ("%s: atu_media_change\n", sc->atu_dev.dv_xname));
1128 
1129 	err = ieee80211_media_change(ifp);
1130 	if (err == ENETRESET) {
1131 		if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
1132 		    (IFF_RUNNING|IFF_UP))
1133 			atu_init(ifp);
1134 		err = 0;
1135 	}
1136 
1137 	return (err);
1138 }
1139 
1140 void
1141 atu_media_status(struct ifnet *ifp, struct ifmediareq *req)
1142 {
1143 #ifdef ATU_DEBUG
1144 	struct atu_softc	*sc = ifp->if_softc;
1145 #endif /* ATU_DEBUG */
1146 
1147 	DPRINTFN(10, ("%s: atu_media_status\n", sc->atu_dev.dv_xname));
1148 
1149 	ieee80211_media_status(ifp, req);
1150 }
1151 
1152 void
1153 atu_task(void *arg)
1154 {
1155 	struct atu_softc	*sc = (struct atu_softc *)arg;
1156 	struct ieee80211com	*ic = &sc->sc_ic;
1157 	struct ifnet		*ifp = &ic->ic_if;
1158 	usbd_status		err;
1159 	int			s;
1160 
1161 	DPRINTFN(10, ("%s: atu_task\n", sc->atu_dev.dv_xname));
1162 
1163 	if (usbd_is_dying(sc->atu_udev))
1164 		return;
1165 
1166 	switch (sc->sc_cmd) {
1167 	case ATU_C_SCAN:
1168 
1169 		err = atu_start_scan(sc);
1170 		if (err) {
1171 			DPRINTFN(1, ("%s: atu_init: couldn't start scan!\n",
1172 			    sc->atu_dev.dv_xname));
1173 			return;
1174 		}
1175 
1176 		err = atu_wait_completion(sc, CMD_START_SCAN, NULL);
1177 		if (err) {
1178 			DPRINTF(("%s: atu_init: error waiting for scan\n",
1179 			    sc->atu_dev.dv_xname));
1180 			return;
1181 		}
1182 
1183 		DPRINTF(("%s: ==========================> END OF SCAN!\n",
1184 		    sc->atu_dev.dv_xname));
1185 
1186 		s = splnet();
1187 		/* ieee80211_next_scan(ifp); */
1188 		ieee80211_end_scan(ifp);
1189 		splx(s);
1190 
1191 		DPRINTF(("%s: ----------------------======> END OF SCAN2!\n",
1192 		    sc->atu_dev.dv_xname));
1193 		break;
1194 
1195 	case ATU_C_JOIN:
1196 		atu_join(sc, ic->ic_bss);
1197 	}
1198 }
1199 
1200 int
1201 atu_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1202 {
1203 	struct ifnet		*ifp = &ic->ic_if;
1204 	struct atu_softc	*sc = ifp->if_softc;
1205 	enum ieee80211_state	ostate = ic->ic_state;
1206 
1207 	switch (nstate) {
1208 	case IEEE80211_S_SCAN:
1209 		memcpy(ic->ic_chan_scan, ic->ic_chan_active,
1210 		    sizeof(ic->ic_chan_active));
1211 		ieee80211_node_cleanup(ic, ic->ic_bss);
1212 
1213 		/* tell the event thread that we want a scan */
1214 		sc->sc_cmd = ATU_C_SCAN;
1215 		usb_add_task(sc->atu_udev, &sc->sc_task);
1216 
1217 		/* handle this ourselves */
1218 		if (ifp->if_flags & IFF_DEBUG)
1219 			printf("%s: %s -> %s\n", ifp->if_xname,
1220 			    ieee80211_state_name[ic->ic_state],
1221 			    ieee80211_state_name[nstate]);
1222 		ieee80211_set_link_state(ic, LINK_STATE_DOWN);
1223 		ic->ic_state = nstate;
1224 		return (0);
1225 
1226 	case IEEE80211_S_AUTH:
1227 	case IEEE80211_S_RUN:
1228 		if (ostate == IEEE80211_S_SCAN) {
1229 			sc->sc_cmd = ATU_C_JOIN;
1230 			usb_add_task(sc->atu_udev, &sc->sc_task);
1231 		}
1232 		break;
1233 	default:
1234 		/* nothing to do */
1235 		break;
1236 	}
1237 
1238 	return (*sc->sc_newstate)(ic, nstate, arg);
1239 }
1240 
1241 /*
1242  * Attach the interface. Allocate softc structures, do
1243  * setup and ethernet/BPF attach.
1244  */
1245 void
1246 atu_attach(struct device *parent, struct device *self, void *aux)
1247 {
1248 	struct atu_softc		*sc = (struct atu_softc *)self;
1249 	struct usb_attach_arg		*uaa = aux;
1250 	usbd_status			err;
1251 	struct usbd_device		*dev = uaa->device;
1252 	u_int8_t			mode, channel;
1253 	int i;
1254 
1255 	sc->atu_unit = self->dv_unit;
1256 	sc->atu_udev = dev;
1257 
1258 	err = usbd_device2interface_handle(dev, ATU_IFACE_IDX, &sc->atu_iface);
1259 	if (err) {
1260 		printf("%s: getting interface handle failed\n",
1261 		    sc->atu_dev.dv_xname);
1262 		goto fail;
1263 	}
1264 
1265 	/*
1266 	 * look up the radio_type for the device
1267 	 * basically does the same as USB_MATCH
1268 	 */
1269 	for (i = 0; i < nitems(atu_devs); i++) {
1270 		struct atu_type *t = &atu_devs[i];
1271 
1272 		if (uaa->vendor == t->atu_vid &&
1273 		    uaa->product == t->atu_pid) {
1274 			sc->atu_radio = t->atu_radio;
1275 			sc->atu_quirk = t->atu_quirk;
1276 		}
1277 	}
1278 
1279 	/*
1280 	 * Check in the interface descriptor if we're in DFU mode
1281 	 * If we're in DFU mode, we upload the external firmware
1282 	 * If we're not, the PC must have rebooted without power-cycling
1283 	 * the device.. I've tried this out, a reboot only requeres the
1284 	 * external firmware to be reloaded :)
1285 	 *
1286 	 * Hmm. The at76c505a doesn't report a DFU descriptor when it's
1287 	 * in DFU mode... Let's just try to get the opmode
1288 	 */
1289 	err = atu_get_opmode(sc, &mode);
1290 	DPRINTFN(20, ("%s: opmode: %d\n", sc->atu_dev.dv_xname, mode));
1291 	if (err || (mode != MODE_NETCARD && mode != MODE_NOFLASHNETCARD)) {
1292 		DPRINTF(("%s: starting internal firmware download\n",
1293 		    sc->atu_dev.dv_xname));
1294 
1295 		config_mountroot(self, atu_internal_firmware);
1296 		/*
1297 		 * atu_internal_firmware will cause a reset of the device
1298 		 * so we don't want to do any more configuration after this
1299 		 * point.
1300 		 */
1301 		return;
1302 	}
1303 
1304 	uaa->iface = sc->atu_iface;
1305 
1306 	if (mode != MODE_NETCARD) {
1307 		DPRINTFN(15, ("%s: device needs external firmware\n",
1308 		    sc->atu_dev.dv_xname));
1309 
1310 		if (mode != MODE_NOFLASHNETCARD) {
1311 			DPRINTF(("%s: EEK! unexpected opmode=%d\n",
1312 			    sc->atu_dev.dv_xname, mode));
1313 		}
1314 
1315 		/*
1316 		 * There is no difference in opmode before and after external
1317 		 * firmware upload with the SMC2662 V.4 . So instead we'll try
1318 		 * to read the channel number. If we succeed, external
1319 		 * firmwaremust have been already uploaded...
1320 		 */
1321 		if (sc->atu_radio != RadioIntersil) {
1322 			err = atu_get_mib(sc, MIB_PHY__CHANNEL, &channel);
1323 			if (!err) {
1324 				DPRINTF(("%s: external firmware has already"
1325 				    " been downloaded\n",
1326 				    sc->atu_dev.dv_xname));
1327 				atu_complete_attach(sc);
1328 				return;
1329 			}
1330 		}
1331 
1332 		config_mountroot(self, atu_external_firmware);
1333 
1334 		/*
1335 		 * atu_external_firmware will call atu_complete_attach after
1336 		 * it's finished so we can just return.
1337 		 */
1338 	} else {
1339 		/* all the firmwares are in place, so complete the attach */
1340 		atu_complete_attach(sc);
1341 	}
1342 fail:
1343 	usbd_deactivate(sc->atu_udev);
1344 }
1345 
1346 void
1347 atu_complete_attach(struct atu_softc *sc)
1348 {
1349 	struct ieee80211com		*ic = &sc->sc_ic;
1350 	struct ifnet			*ifp = &ic->ic_if;
1351 	usb_interface_descriptor_t	*id;
1352 	usb_endpoint_descriptor_t	*ed;
1353 	usbd_status			err;
1354 	int				i;
1355 #ifdef ATU_DEBUG
1356 	struct atu_fw			fw;
1357 #endif
1358 
1359 	id = usbd_get_interface_descriptor(sc->atu_iface);
1360 
1361 	/* Find endpoints. */
1362 	for (i = 0; i < id->bNumEndpoints; i++) {
1363 		ed = usbd_interface2endpoint_descriptor(sc->atu_iface, i);
1364 		if (!ed) {
1365 			DPRINTF(("%s: num_endp:%d\n", sc->atu_dev.dv_xname,
1366 			    sc->atu_iface->idesc->bNumEndpoints));
1367 			DPRINTF(("%s: couldn't get ep %d\n",
1368 			    sc->atu_dev.dv_xname, i));
1369 			goto fail;
1370 		}
1371 		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
1372 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1373 			sc->atu_ed[ATU_ENDPT_RX] = ed->bEndpointAddress;
1374 		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
1375 			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1376 			sc->atu_ed[ATU_ENDPT_TX] = ed->bEndpointAddress;
1377 		}
1378 	}
1379 
1380 	/* read device config & get MAC address */
1381 	err = atu_get_card_config(sc);
1382 	if (err) {
1383 		printf("%s: could not get card cfg!\n",
1384 		    sc->atu_dev.dv_xname);
1385 		goto fail;
1386 	}
1387 
1388 #ifdef ATU_DEBUG
1389 	/* DEBUG : try to get firmware version */
1390 	err = atu_get_mib(sc, MIB_FW_VERSION, sizeof(fw), 0,
1391 	    (u_int8_t *)&fw);
1392 	if (!err) {
1393 		DPRINTFN(15, ("%s: firmware: maj:%d min:%d patch:%d "
1394 		    "build:%d\n", sc->atu_dev.dv_xname, fw.major, fw.minor,
1395 		    fw.patch, fw.build));
1396 	} else {
1397 		DPRINTF(("%s: get firmware version failed\n",
1398 		    sc->atu_dev.dv_xname));
1399 	}
1400 #endif /* ATU_DEBUG */
1401 
1402 	/* Show the world our MAC address */
1403 	printf("%s: address %s\n", sc->atu_dev.dv_xname,
1404 	    ether_sprintf(ic->ic_myaddr));
1405 
1406 	sc->atu_cdata.atu_tx_inuse = 0;
1407 
1408 	bzero(sc->atu_bssid, ETHER_ADDR_LEN);
1409 	sc->atu_channel = ATU_DEFAULT_CHANNEL;
1410 	sc->atu_desired_channel = IEEE80211_CHAN_ANY;
1411 	sc->atu_mode = INFRASTRUCTURE_MODE;
1412 
1413 	ic->ic_softc = sc;
1414 	ic->ic_phytype = IEEE80211_T_DS;
1415 	ic->ic_opmode = IEEE80211_M_STA;
1416 	ic->ic_state = IEEE80211_S_INIT;
1417 	ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_WEP | IEEE80211_C_SCANALL;
1418 	ic->ic_max_rssi = atu_radfirm[sc->atu_radio].max_rssi;
1419 
1420 	ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
1421 
1422 	for (i = 1; i <= 14; i++) {
1423 		ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B |
1424 		    IEEE80211_CHAN_PASSIVE;
1425 		ic->ic_channels[i].ic_freq = ieee80211_ieee2mhz(i,
1426 		    ic->ic_channels[i].ic_flags);
1427 	}
1428 
1429 	ic->ic_ibss_chan = &ic->ic_channels[0];
1430 
1431 	ifp->if_softc = sc;
1432 	memcpy(ifp->if_xname, sc->atu_dev.dv_xname, IFNAMSIZ);
1433 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1434 	ifp->if_start = atu_start;
1435 	ifp->if_ioctl = atu_ioctl;
1436 	ifp->if_watchdog = atu_watchdog;
1437 	ifp->if_mtu = ATU_DEFAULT_MTU;
1438 
1439 	/* Call MI attach routine. */
1440 	if_attach(ifp);
1441 	ieee80211_ifattach(ifp);
1442 
1443 	sc->sc_newstate = ic->ic_newstate;
1444 	ic->ic_newstate = atu_newstate;
1445 
1446 	/* setup ifmedia interface */
1447 	ieee80211_media_init(ifp, atu_media_change, atu_media_status);
1448 
1449 	usb_init_task(&sc->sc_task, atu_task, sc, USB_TASK_TYPE_GENERIC);
1450 
1451 #if NBPFILTER > 0
1452 	bpfattach(&sc->sc_radiobpf, &sc->sc_ic.ic_if, DLT_IEEE802_11_RADIO,
1453 	    sizeof(struct ieee80211_frame) + 64);
1454 
1455 	bzero(&sc->sc_rxtapu, sizeof(sc->sc_rxtapu));
1456 	sc->sc_rxtap.rr_ihdr.it_len = sizeof(sc->sc_rxtapu);
1457 	sc->sc_rxtap.rr_ihdr.it_present = htole32(ATU_RX_RADIOTAP_PRESENT);
1458 
1459 	bzero(&sc->sc_txtapu, sizeof(sc->sc_txtapu));
1460 	sc->sc_txtap.rt_ihdr.it_len = sizeof(sc->sc_txtapu);
1461 	sc->sc_txtap.rt_ihdr.it_present = htole32(ATU_TX_RADIOTAP_PRESENT);
1462 #endif
1463 
1464 fail:
1465 	usbd_deactivate(sc->atu_udev);
1466 }
1467 
1468 int
1469 atu_detach(struct device *self, int flags)
1470 {
1471 	struct atu_softc	*sc = (struct atu_softc *)self;
1472 	struct ifnet		*ifp = &sc->sc_ic.ic_if;
1473 
1474 	DPRINTFN(10, ("%s: atu_detach\n", sc->atu_dev.dv_xname));
1475 
1476 	if (ifp->if_flags & IFF_RUNNING)
1477 		atu_stop(ifp, 1);
1478 
1479 	usb_rem_task(sc->atu_udev, &sc->sc_task);
1480 
1481 	if (sc->atu_ep[ATU_ENDPT_TX] != NULL)
1482 		usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]);
1483 	if (sc->atu_ep[ATU_ENDPT_RX] != NULL)
1484 		usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]);
1485 
1486 	if (ifp->if_softc != NULL) {
1487 		ieee80211_ifdetach(ifp);
1488 		if_detach(ifp);
1489 	}
1490 
1491 	return(0);
1492 }
1493 
1494 /*
1495  * Initialize an RX descriptor and attach an MBUF cluster.
1496  */
1497 int
1498 atu_newbuf(struct atu_softc *sc, struct atu_chain *c, struct mbuf *m)
1499 {
1500 	struct mbuf		*m_new = NULL;
1501 
1502 	if (m == NULL) {
1503 		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1504 		if (m_new == NULL) {
1505 			DPRINTF(("%s: no memory for rx list\n",
1506 			    sc->atu_dev.dv_xname));
1507 			return(ENOBUFS);
1508 		}
1509 
1510 		MCLGET(m_new, M_DONTWAIT);
1511 		if (!(m_new->m_flags & M_EXT)) {
1512 			DPRINTF(("%s: no memory for rx list\n",
1513 			    sc->atu_dev.dv_xname));
1514 			m_freem(m_new);
1515 			return(ENOBUFS);
1516 		}
1517 		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1518 	} else {
1519 		m_new = m;
1520 		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1521 		m_new->m_data = m_new->m_ext.ext_buf;
1522 	}
1523 	c->atu_mbuf = m_new;
1524 	return(0);
1525 }
1526 
1527 int
1528 atu_rx_list_init(struct atu_softc *sc)
1529 {
1530 	struct atu_cdata	*cd = &sc->atu_cdata;
1531 	struct atu_chain	*c;
1532 	int			i;
1533 
1534 	DPRINTFN(15, ("%s: atu_rx_list_init: enter\n",
1535 	    sc->atu_dev.dv_xname));
1536 
1537 	for (i = 0; i < ATU_RX_LIST_CNT; i++) {
1538 		c = &cd->atu_rx_chain[i];
1539 		c->atu_sc = sc;
1540 		c->atu_idx = i;
1541 		if (c->atu_xfer == NULL) {
1542 			c->atu_xfer = usbd_alloc_xfer(sc->atu_udev);
1543 			if (c->atu_xfer == NULL)
1544 				return (ENOBUFS);
1545 			c->atu_buf = usbd_alloc_buffer(c->atu_xfer,
1546 			    ATU_RX_BUFSZ);
1547 			if (c->atu_buf == NULL) /* XXX free xfer */
1548 				return (ENOBUFS);
1549 			if (atu_newbuf(sc, c, NULL) == ENOBUFS) /* XXX free? */
1550 				return(ENOBUFS);
1551 		}
1552 	}
1553 	return (0);
1554 }
1555 
1556 int
1557 atu_tx_list_init(struct atu_softc *sc)
1558 {
1559 	struct atu_cdata	*cd = &sc->atu_cdata;
1560 	struct atu_chain	*c;
1561 	int			i;
1562 
1563 	DPRINTFN(15, ("%s: atu_tx_list_init\n",
1564 	    sc->atu_dev.dv_xname));
1565 
1566 	SLIST_INIT(&cd->atu_tx_free);
1567 	sc->atu_cdata.atu_tx_inuse = 0;
1568 
1569 	for (i = 0; i < ATU_TX_LIST_CNT; i++) {
1570 		c = &cd->atu_tx_chain[i];
1571 		c->atu_sc = sc;
1572 		c->atu_idx = i;
1573 		if (c->atu_xfer == NULL) {
1574 			c->atu_xfer = usbd_alloc_xfer(sc->atu_udev);
1575 			if (c->atu_xfer == NULL)
1576 				return(ENOBUFS);
1577 			c->atu_mbuf = NULL;
1578 			c->atu_buf = usbd_alloc_buffer(c->atu_xfer,
1579 			    ATU_TX_BUFSZ);
1580 			if (c->atu_buf == NULL)
1581 				return(ENOBUFS); /* XXX free xfer */
1582 			SLIST_INSERT_HEAD(&cd->atu_tx_free, c, atu_list);
1583 		}
1584 	}
1585 	return(0);
1586 }
1587 
1588 void
1589 atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch,
1590     int listlen)
1591 {
1592 	int			i;
1593 
1594 	/* Free resources. */
1595 	for (i = 0; i < listlen; i++) {
1596 		if (ch[i].atu_buf != NULL)
1597 			ch[i].atu_buf = NULL;
1598 		if (ch[i].atu_mbuf != NULL) {
1599 			m_freem(ch[i].atu_mbuf);
1600 			ch[i].atu_mbuf = NULL;
1601 		}
1602 		if (ch[i].atu_xfer != NULL) {
1603 			usbd_free_xfer(ch[i].atu_xfer);
1604 			ch[i].atu_xfer = NULL;
1605 		}
1606 	}
1607 }
1608 
1609 /*
1610  * A frame has been uploaded: pass the resulting mbuf chain up to
1611  * the higher level protocols.
1612  */
1613 void
1614 atu_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1615 {
1616 	struct atu_chain	*c = (struct atu_chain *)priv;
1617 	struct atu_softc	*sc = c->atu_sc;
1618 	struct ieee80211com	*ic = &sc->sc_ic;
1619 	struct ifnet		*ifp = &ic->ic_if;
1620 	struct atu_rx_hdr	*h;
1621 	struct ieee80211_frame	*wh;
1622 	struct ieee80211_rxinfo	rxi;
1623 	struct ieee80211_node	*ni;
1624 	struct mbuf		*m;
1625 	u_int32_t		len;
1626 	int			s;
1627 
1628 	DPRINTFN(25, ("%s: atu_rxeof\n", sc->atu_dev.dv_xname));
1629 
1630 	if (usbd_is_dying(sc->atu_udev))
1631 		return;
1632 
1633 	if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP))
1634 		goto done;
1635 
1636 	if (status != USBD_NORMAL_COMPLETION) {
1637 		DPRINTF(("%s: status != USBD_NORMAL_COMPLETION\n",
1638 		    sc->atu_dev.dv_xname));
1639 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1640 			return;
1641 		}
1642 #if 0
1643 		if (status == USBD_IOERROR) {
1644 			DPRINTF(("%s: rx: EEK! lost device?\n",
1645 			    sc->atu_dev.dv_xname));
1646 
1647 			/*
1648 			 * My experience with USBD_IOERROR is that trying to
1649 			 * restart the transfer will always fail and we'll
1650 			 * keep on looping restarting transfers untill someone
1651 			 * pulls the plug of the device.
1652 			 * So we don't restart the transfer, but just let it
1653 			 * die... If someone knows of a situation where we can
1654 			 * recover from USBD_IOERROR, let me know.
1655 			 */
1656 			splx(s);
1657 			return;
1658 		}
1659 #endif /* 0 */
1660 
1661 		if (usbd_ratecheck(&sc->atu_rx_notice)) {
1662 			DPRINTF(("%s: usb error on rx: %s\n",
1663 			    sc->atu_dev.dv_xname, usbd_errstr(status)));
1664 		}
1665 		if (status == USBD_STALLED)
1666 			usbd_clear_endpoint_stall_async(
1667 			    sc->atu_ep[ATU_ENDPT_RX]);
1668 		goto done;
1669 	}
1670 
1671 	usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
1672 
1673 	if (len < ATU_RX_HDRLEN) {
1674 		DPRINTF(("%s: atu_rxeof: too short\n",
1675 		    sc->atu_dev.dv_xname));
1676 		ic->ic_stats.is_rx_tooshort++;
1677 		ifp->if_ierrors++;
1678 		goto done;
1679 	}
1680 
1681 	h = (struct atu_rx_hdr *)c->atu_buf;
1682 	len = UGETW(h->length);
1683 	if (len < IEEE80211_MIN_LEN) {
1684 		ic->ic_stats.is_rx_tooshort++;
1685 		ifp->if_ierrors++;
1686 		goto done;
1687 	}
1688 	if (len > ATU_RX_BUFSZ) {
1689 		ifp->if_ierrors++;
1690 		goto done;
1691 	}
1692 	len -= IEEE80211_CRC_LEN;
1693 
1694 	m = c->atu_mbuf;
1695 	memcpy(mtod(m, char *), c->atu_buf + ATU_RX_HDRLEN, len);
1696 	m->m_pkthdr.len = m->m_len = len;
1697 
1698 	wh = mtod(m, struct ieee80211_frame *);
1699 	ni = ieee80211_find_rxnode(ic, wh);
1700 
1701 	s = splnet();
1702 
1703 	if (atu_newbuf(sc, c, NULL) == ENOBUFS) {
1704 		ifp->if_ierrors++;
1705 		goto done1; /* XXX if we can't allocate, why restart it? */
1706 	}
1707 
1708 #if NBPFILTER > 0
1709 	if (sc->sc_radiobpf != NULL) {
1710 		struct mbuf mb;
1711 		struct atu_rx_radiotap_header *rr = &sc->sc_rxtap;
1712 
1713 		rr->rr_flags = 0;
1714 		rr->rr_chan_freq =
1715 		    htole16(ic->ic_bss->ni_chan->ic_freq);
1716 		rr->rr_chan_flags =
1717 		    htole16(ic->ic_bss->ni_chan->ic_flags);
1718 		rr->rr_rssi = h->rssi;
1719 		rr->rr_max_rssi = ic->ic_max_rssi;
1720 
1721 		mb.m_data = (caddr_t)rr;
1722 		mb.m_len = sizeof(sc->sc_txtapu);
1723 		mb.m_next = m;
1724 		mb.m_nextpkt = NULL;
1725 		mb.m_type = 0;
1726 		mb.m_flags = 0;
1727 		bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_IN);
1728 	}
1729 #endif /* NBPFILTER > 0 */
1730 
1731 	rxi.rxi_flags = 0;
1732 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1733 		/*
1734 		 * WEP is decrypted by hardware. Clear WEP bit
1735 		 * header for ieee80211_input().
1736 		 */
1737 		wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
1738 		rxi.rxi_flags |= IEEE80211_RXI_HWDEC;
1739 	}
1740 
1741 	rxi.rxi_rssi = h->rssi;
1742 	rxi.rxi_tstamp = UGETDW(h->rx_time);
1743 	ieee80211_input(ifp, m, ni, &rxi);
1744 
1745 done1:
1746 	ieee80211_release_node(ic, ni);
1747 	splx(s);
1748 done:
1749 	/* Setup new transfer. */
1750 	usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX], c, c->atu_buf,
1751 	    ATU_RX_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
1752 		atu_rxeof);
1753 	usbd_transfer(c->atu_xfer);
1754 }
1755 
1756 /*
1757  * A frame was downloaded to the chip. It's safe for us to clean up
1758  * the list buffers.
1759  */
1760 void
1761 atu_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1762 {
1763 	struct atu_chain	*c = (struct atu_chain *)priv;
1764 	struct atu_softc	*sc = c->atu_sc;
1765 	struct ifnet		*ifp = &sc->sc_ic.ic_if;
1766 	usbd_status		err;
1767 	int			s;
1768 
1769 	DPRINTFN(25, ("%s: atu_txeof status=%d\n", sc->atu_dev.dv_xname,
1770 	    status));
1771 
1772 	if (c->atu_mbuf != NULL) {
1773 		m_freem(c->atu_mbuf);
1774 		c->atu_mbuf = NULL;
1775 	}
1776 
1777 	if (status != USBD_NORMAL_COMPLETION) {
1778 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1779 			return;
1780 
1781 		DPRINTF(("%s: usb error on tx: %s\n", sc->atu_dev.dv_xname,
1782 		    usbd_errstr(status)));
1783 		if (status == USBD_STALLED)
1784 			usbd_clear_endpoint_stall_async(sc->atu_ep[ATU_ENDPT_TX]);
1785 		return;
1786 	}
1787 
1788 	usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL, &err);
1789 
1790 	if (err)
1791 		ifp->if_oerrors++;
1792 
1793 	s = splnet();
1794 	SLIST_INSERT_HEAD(&sc->atu_cdata.atu_tx_free, c, atu_list);
1795 	sc->atu_cdata.atu_tx_inuse--;
1796 	if (sc->atu_cdata.atu_tx_inuse == 0)
1797 		ifp->if_timer = 0;
1798 	ifq_clr_oactive(&ifp->if_snd);
1799 	splx(s);
1800 
1801 	atu_start(ifp);
1802 }
1803 
1804 u_int8_t
1805 atu_calculate_padding(int size)
1806 {
1807 	size %= 64;
1808 
1809 	if (size < 50)
1810 		return (50 - size);
1811 	if (size >=61)
1812 		return (64 + 50 - size);
1813 	return (0);
1814 }
1815 
1816 int
1817 atu_tx_start(struct atu_softc *sc, struct ieee80211_node *ni,
1818     struct atu_chain *c, struct mbuf *m)
1819 {
1820 	int			len;
1821 	struct atu_tx_hdr	*h;
1822 	usbd_status		err;
1823 	u_int8_t		pad;
1824 #if NBPFILTER > 0
1825 	struct ieee80211com *ic = &sc->sc_ic;
1826 #endif
1827 
1828 	DPRINTFN(25, ("%s: atu_tx_start\n", sc->atu_dev.dv_xname));
1829 
1830 	/* Don't try to send when we're shutting down the driver */
1831 	if (usbd_is_dying(sc->atu_udev)) {
1832 		m_freem(m);
1833 		return(EIO);
1834 	}
1835 
1836 #if NBPFILTER > 0
1837 	if (sc->sc_radiobpf != NULL) {
1838 		struct mbuf mb;
1839 		struct atu_tx_radiotap_header *rt = &sc->sc_txtap;
1840 
1841 		rt->rt_flags = 0;
1842 		rt->rt_chan_freq =
1843 		    htole16(ic->ic_bss->ni_chan->ic_freq);
1844 		rt->rt_chan_flags =
1845 		    htole16(ic->ic_bss->ni_chan->ic_flags);
1846 
1847 		mb.m_data = (caddr_t)rt;
1848 		mb.m_len = sizeof(sc->sc_txtapu);
1849 		mb.m_next = m;
1850 		mb.m_nextpkt = NULL;
1851 		mb.m_type = 0;
1852 		mb.m_flags = 0;
1853 		bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_OUT);
1854 	}
1855 #endif
1856 
1857 	/*
1858 	 * Copy the mbuf data into a contiguous buffer, leaving
1859 	 * enough room for the atmel headers
1860 	 */
1861 	len = m->m_pkthdr.len;
1862 
1863 	m_copydata(m, 0, m->m_pkthdr.len, c->atu_buf + ATU_TX_HDRLEN);
1864 
1865 	h = (struct atu_tx_hdr *)c->atu_buf;
1866 	memset(h, 0, ATU_TX_HDRLEN);
1867 	USETW(h->length, len);
1868 	h->tx_rate = 4; /* XXX rate = auto */
1869 	len += ATU_TX_HDRLEN;
1870 
1871 	pad = atu_calculate_padding(len);
1872 	len += pad;
1873 	h->padding = pad;
1874 
1875 	c->atu_length = len;
1876 	c->atu_mbuf = m;
1877 
1878 	usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_TX],
1879 	    c, c->atu_buf, c->atu_length, USBD_NO_COPY, ATU_TX_TIMEOUT,
1880 	    atu_txeof);
1881 
1882 	/* Let's get this thing into the air! */
1883 	c->atu_in_xfer = 1;
1884 	err = usbd_transfer(c->atu_xfer);
1885 	if (err != USBD_IN_PROGRESS) {
1886 		DPRINTFN(25, ("%s: atu_tx_start: err=%d\n",
1887 		    sc->atu_dev.dv_xname, err));
1888 		c->atu_mbuf = NULL;
1889 		m_freem(m);
1890 		return(EIO);
1891 	}
1892 
1893 	return (0);
1894 }
1895 
1896 void
1897 atu_start(struct ifnet *ifp)
1898 {
1899 	struct atu_softc	*sc = ifp->if_softc;
1900 	struct ieee80211com	*ic = &sc->sc_ic;
1901 	struct atu_cdata	*cd = &sc->atu_cdata;
1902 	struct ieee80211_node	*ni;
1903 	struct ieee80211_frame	*wh;
1904 	struct atu_chain	*c;
1905 	struct mbuf		*m = NULL;
1906 	int			s;
1907 
1908 	DPRINTFN(25, ("%s: atu_start: enter\n", sc->atu_dev.dv_xname));
1909 
1910 	if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) {
1911 		DPRINTFN(30, ("%s: atu_start: not running or up\n",
1912 		    sc->atu_dev.dv_xname));
1913 		return;
1914 	}
1915 
1916 	if (ifq_is_oactive(&ifp->if_snd)) {
1917 		DPRINTFN(30, ("%s: atu_start: oactive\n",
1918 		    sc->atu_dev.dv_xname));
1919 		return;
1920 	}
1921 
1922 	for (;;) {
1923 		/* grab a TX buffer */
1924 		s = splnet();
1925 		c = SLIST_FIRST(&cd->atu_tx_free);
1926 		if (c != NULL) {
1927 			SLIST_REMOVE_HEAD(&cd->atu_tx_free, atu_list);
1928 			cd->atu_tx_inuse++;
1929 			if (cd->atu_tx_inuse == ATU_TX_LIST_CNT)
1930 				ifq_set_oactive(&ifp->if_snd);
1931 		}
1932 		splx(s);
1933 		if (c == NULL) {
1934 			DPRINTFN(10, ("%s: out of tx xfers\n",
1935 			    sc->atu_dev.dv_xname));
1936 			ifq_set_oactive(&ifp->if_snd);
1937 			break;
1938 		}
1939 
1940 		/*
1941 		 * Poll the management queue for frames, it has priority over
1942 		 * normal data frames.
1943 		 */
1944 		m = mq_dequeue(&ic->ic_mgtq);
1945 		if (m == NULL) {
1946 			DPRINTFN(10, ("%s: atu_start: data packet\n",
1947 			    sc->atu_dev.dv_xname));
1948 			if (ic->ic_state != IEEE80211_S_RUN) {
1949 				DPRINTFN(25, ("%s: no data till running\n",
1950 				    sc->atu_dev.dv_xname));
1951 				/* put the xfer back on the list */
1952 				s = splnet();
1953 				SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
1954 				    atu_list);
1955 				cd->atu_tx_inuse--;
1956 				splx(s);
1957 				break;
1958 			}
1959 
1960 			m = ifq_dequeue(&ifp->if_snd);
1961 			if (m == NULL) {
1962 				DPRINTFN(25, ("%s: nothing to send\n",
1963 				    sc->atu_dev.dv_xname));
1964 				s = splnet();
1965 				SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
1966 				    atu_list);
1967 				cd->atu_tx_inuse--;
1968 				splx(s);
1969 				break;
1970 			}
1971 
1972 #if NBPFILTER > 0
1973 			if (ifp->if_bpf)
1974 				bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
1975 #endif
1976 
1977 			m = ieee80211_encap(ifp, m, &ni);
1978 			if (m == NULL)
1979 				goto bad;
1980 			wh = mtod(m, struct ieee80211_frame *);
1981 
1982 #if NBPFILTER > 0
1983 			if (ic->ic_rawbpf != NULL)
1984 				bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT);
1985 #endif
1986 		} else {
1987 			DPRINTFN(25, ("%s: atu_start: mgmt packet\n",
1988 			    sc->atu_dev.dv_xname));
1989 
1990 			ni = m->m_pkthdr.ph_cookie;
1991 
1992 			wh = mtod(m, struct ieee80211_frame *);
1993 			/* sc->sc_stats.ast_tx_mgmt++; */
1994 		}
1995 
1996 		if (atu_tx_start(sc, ni, c, m)) {
1997 bad:
1998 			s = splnet();
1999 			SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
2000 			    atu_list);
2001 			cd->atu_tx_inuse--;
2002 			splx(s);
2003 			/* ifp_if_oerrors++; */
2004 			if (ni != NULL)
2005 				ieee80211_release_node(ic, ni);
2006 			continue;
2007 		}
2008 		ifp->if_timer = 5;
2009 	}
2010 }
2011 
2012 int
2013 atu_init(struct ifnet *ifp)
2014 {
2015 	struct atu_softc	*sc = ifp->if_softc;
2016 	struct ieee80211com	*ic = &sc->sc_ic;
2017 	struct atu_chain	*c;
2018 	usbd_status		err;
2019 	int			i, s;
2020 
2021 	s = splnet();
2022 
2023 	DPRINTFN(10, ("%s: atu_init\n", sc->atu_dev.dv_xname));
2024 
2025 	if (ifp->if_flags & IFF_RUNNING) {
2026 		splx(s);
2027 		return(0);
2028 	}
2029 
2030 	/* Init TX ring */
2031 	if (atu_tx_list_init(sc))
2032 		printf("%s: tx list init failed\n", sc->atu_dev.dv_xname);
2033 
2034 	/* Init RX ring */
2035 	if (atu_rx_list_init(sc))
2036 		printf("%s: rx list init failed\n", sc->atu_dev.dv_xname);
2037 
2038 	/* Load the multicast filter. */
2039 	/*atu_setmulti(sc); */
2040 
2041 	/* Open RX and TX pipes. */
2042 	err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_RX],
2043 	    USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_RX]);
2044 	if (err) {
2045 		DPRINTF(("%s: open rx pipe failed: %s\n",
2046 		    sc->atu_dev.dv_xname, usbd_errstr(err)));
2047 		splx(s);
2048 		return(EIO);
2049 	}
2050 
2051 	err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_TX],
2052 	    USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_TX]);
2053 	if (err) {
2054 		DPRINTF(("%s: open tx pipe failed: %s\n",
2055 		    sc->atu_dev.dv_xname, usbd_errstr(err)));
2056 		splx(s);
2057 		return(EIO);
2058 	}
2059 
2060 	/* Start up the receive pipe. */
2061 	for (i = 0; i < ATU_RX_LIST_CNT; i++) {
2062 		c = &sc->atu_cdata.atu_rx_chain[i];
2063 
2064 		usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX], c,
2065 		    c->atu_buf, ATU_RX_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
2066 		    USBD_NO_TIMEOUT, atu_rxeof);
2067 		usbd_transfer(c->atu_xfer);
2068 	}
2069 
2070 	DPRINTFN(10, ("%s: starting up using MAC=%s\n",
2071 	    sc->atu_dev.dv_xname, ether_sprintf(ic->ic_myaddr)));
2072 
2073 	/* Do initial setup */
2074 	err = atu_initial_config(sc);
2075 	if (err) {
2076 		DPRINTF(("%s: initial config failed!\n",
2077 		    sc->atu_dev.dv_xname));
2078 		splx(s);
2079 		return(EIO);
2080 	}
2081 	DPRINTFN(10, ("%s: initialised transceiver\n",
2082 	    sc->atu_dev.dv_xname));
2083 
2084 	/* sc->atu_rxfilt = ATU_RXFILT_UNICAST|ATU_RXFILT_BROADCAST; */
2085 
2086 	/* If we want promiscuous mode, set the allframes bit. */
2087 	/*
2088 	if (ifp->if_flags & IFF_PROMISC)
2089 		sc->atu_rxfilt |= ATU_RXFILT_PROMISC;
2090 	*/
2091 
2092 	ifp->if_flags |= IFF_RUNNING;
2093 	ifq_clr_oactive(&ifp->if_snd);
2094 	splx(s);
2095 
2096 	/* XXX the following HAS to be replaced */
2097 	s = splnet();
2098 	err = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2099 	if (err)
2100 		DPRINTFN(1, ("%s: atu_init: error calling "
2101 		    "ieee80211_net_state", sc->atu_dev.dv_xname));
2102 	splx(s);
2103 
2104 	return 0;
2105 }
2106 
2107 int
2108 atu_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
2109 {
2110 	struct atu_softc	*sc = ifp->if_softc;
2111 	int			err = 0, s;
2112 
2113 	s = splnet();
2114 	switch (command) {
2115 	case SIOCSIFADDR:
2116 		DPRINTFN(15, ("%s: SIOCSIFADDR\n", sc->atu_dev.dv_xname));
2117 
2118 		ifp->if_flags |= IFF_UP;
2119 		atu_init(ifp);
2120 		break;
2121 
2122 	case SIOCSIFFLAGS:
2123 		DPRINTFN(15, ("%s: SIOCSIFFLAGS\n", sc->atu_dev.dv_xname));
2124 
2125 		if (ifp->if_flags & IFF_UP) {
2126 			if (ifp->if_flags & IFF_RUNNING &&
2127 			    ifp->if_flags & IFF_PROMISC &&
2128 			    !(sc->atu_if_flags & IFF_PROMISC)) {
2129 /* enable promisc */
2130 #if 0
2131 				sc->atu_rxfilt |= ATU_RXFILT_PROMISC;
2132 				atu_setword(sc, ATU_CMD_SET_PKT_FILTER,
2133 				    sc->atu_rxfilt);
2134 #endif
2135 			} else if (ifp->if_flags & IFF_RUNNING &&
2136 			    !(ifp->if_flags & IFF_PROMISC) &&
2137 			    sc->atu_if_flags & IFF_PROMISC) {
2138 /* disable promisc */
2139 #if 0
2140 				sc->atu_rxfilt &= ~ATU_RXFILT_PROMISC;
2141 				atu_setword(sc, ATU_CMD_SET_PKT_FILTER,
2142 				    sc->atu_rxfilt);
2143 #endif
2144 			} else if (!(ifp->if_flags & IFF_RUNNING))
2145 				atu_init(ifp);
2146 
2147 			DPRINTFN(15, ("%s: ioctl calling atu_init()\n",
2148 			    sc->atu_dev.dv_xname));
2149 			atu_init(ifp);
2150 			err = atu_switch_radio(sc, 1);
2151 		} else {
2152 			if (ifp->if_flags & IFF_RUNNING)
2153 				atu_stop(ifp, 0);
2154 			err = atu_switch_radio(sc, 0);
2155 		}
2156 		sc->atu_if_flags = ifp->if_flags;
2157 		err = 0;
2158 		break;
2159 
2160 	case SIOCADDMULTI:
2161 		DPRINTFN(15, ("%s: SIOCADDMULTI\n", sc->atu_dev.dv_xname));
2162 		/* TODO: implement */
2163 		err = 0;
2164 		break;
2165 
2166 	case SIOCDELMULTI:
2167 		DPRINTFN(15, ("%s: SIOCDELMULTI\n", sc->atu_dev.dv_xname));
2168 		/* TODO: implement */
2169 		err = 0;
2170 		break;
2171 
2172 	default:
2173 		DPRINTFN(15, ("%s: ieee80211_ioctl (%lu)\n",
2174 		    sc->atu_dev.dv_xname, command));
2175 		err = ieee80211_ioctl(ifp, command, data);
2176 		break;
2177 	}
2178 
2179 	if (err == ENETRESET) {
2180 		if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
2181 		    (IFF_RUNNING|IFF_UP)) {
2182 			DPRINTF(("%s: atu_ioctl(): netreset\n",
2183 			    sc->atu_dev.dv_xname));
2184 			atu_init(ifp);
2185 		}
2186 		err = 0;
2187 	}
2188 
2189 	splx(s);
2190 	return (err);
2191 }
2192 
2193 void
2194 atu_watchdog(struct ifnet *ifp)
2195 {
2196 	struct atu_softc	*sc = ifp->if_softc;
2197 	struct atu_chain	*c;
2198 	usbd_status		stat;
2199 	int			cnt, s;
2200 
2201 	DPRINTF(("%s: atu_watchdog\n", sc->atu_dev.dv_xname));
2202 
2203 	ifp->if_timer = 0;
2204 
2205 	if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP))
2206 		return;
2207 
2208 	if (usbd_is_dying(sc->atu_udev))
2209 		return;
2210 
2211 	sc = ifp->if_softc;
2212 	s = splnet();
2213 	ifp->if_oerrors++;
2214 	DPRINTF(("%s: watchdog timeout\n", sc->atu_dev.dv_xname));
2215 
2216 	/*
2217 	 * TODO:
2218 	 * we should change this since we have multiple TX transfers...
2219 	 */
2220 	for (cnt = 0; cnt < ATU_TX_LIST_CNT; cnt++) {
2221 		c = &sc->atu_cdata.atu_tx_chain[cnt];
2222 		if (c->atu_in_xfer) {
2223 			usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL,
2224 			    &stat);
2225 			atu_txeof(c->atu_xfer, c, stat);
2226 		}
2227 	}
2228 
2229 	if (!ifq_empty(&ifp->if_snd))
2230 		atu_start(ifp);
2231 	splx(s);
2232 
2233 	ieee80211_watchdog(ifp);
2234 }
2235 
2236 /*
2237  * Stop the adapter and free any mbufs allocated to the
2238  * RX and TX lists.
2239  */
2240 void
2241 atu_stop(struct ifnet *ifp, int disable)
2242 {
2243 	struct atu_softc	*sc = ifp->if_softc;
2244 	struct atu_cdata	*cd;
2245 	usbd_status		err;
2246 	int s;
2247 
2248 	s = splnet();
2249 	ifp->if_flags &= ~IFF_RUNNING;
2250 	ifq_clr_oactive(&ifp->if_snd);
2251 	ifp->if_timer = 0;
2252 
2253 	/* Stop transfers. */
2254 	if (sc->atu_ep[ATU_ENDPT_RX] != NULL) {
2255 		err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_RX]);
2256 		if (err) {
2257 			DPRINTF(("%s: close rx pipe failed: %s\n",
2258 			    sc->atu_dev.dv_xname, usbd_errstr(err)));
2259 		}
2260 		sc->atu_ep[ATU_ENDPT_RX] = NULL;
2261 	}
2262 
2263 	if (sc->atu_ep[ATU_ENDPT_TX] != NULL) {
2264 		err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_TX]);
2265 		if (err) {
2266 			DPRINTF(("%s: close tx pipe failed: %s\n",
2267 			    sc->atu_dev.dv_xname, usbd_errstr(err)));
2268 		}
2269 		sc->atu_ep[ATU_ENDPT_TX] = NULL;
2270 	}
2271 
2272 	/* Free RX/TX/MGMT list resources. */
2273 	cd = &sc->atu_cdata;
2274 	atu_xfer_list_free(sc, cd->atu_rx_chain, ATU_RX_LIST_CNT);
2275 	atu_xfer_list_free(sc, cd->atu_tx_chain, ATU_TX_LIST_CNT);
2276 
2277 	/* Let's be nice and turn off the radio before we leave */
2278 	atu_switch_radio(sc, 0);
2279 
2280 	splx(s);
2281 }
2282