1 /* $OpenBSD: if_atu.c,v 1.61 2005/07/01 04:09:19 jsg 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/malloc.h>
57 #include <sys/kthread.h>
58 #include <sys/queue.h>
59 #include <sys/device.h>
60
61 #include <machine/bus.h>
62
63 #include <dev/usb/usb.h>
64 #include <dev/usb/usbdi.h>
65 #include <dev/usb/usbdi_util.h>
66 #include <dev/usb/usbdivar.h>
67
68 #include <dev/usb/usbdevs.h>
69
70 #if NBPFILTER > 0
71 #include <net/bpf.h>
72 #endif
73
74 #include <net/if.h>
75 #include <net/if_dl.h>
76 #include <net/if_media.h>
77
78 #ifdef INET
79 #include <netinet/in.h>
80 #include <netinet/if_ether.h>
81 #endif
82
83 #include <net80211/ieee80211_var.h>
84 #include <net80211/ieee80211_radiotap.h>
85
86 #ifdef USB_DEBUG
87 #define ATU_DEBUG
88 #endif
89
90 #include <dev/usb/if_atureg.h>
91
92 #ifdef ATU_DEBUG
93 #define DPRINTF(x) do { if (atudebug) printf x; } while (0)
94 #define DPRINTFN(n,x) do { if (atudebug>(n)) printf x; } while (0)
95 int atudebug = 1;
96 #else
97 #define DPRINTF(x)
98 #define DPRINTFN(n,x)
99 #endif
100
101 USB_DECLARE_DRIVER_CLASS(atu, DV_IFNET);
102
103 /*
104 * Various supported device vendors/products/radio type.
105 */
106 struct atu_type atu_devs[] = {
107 { USB_VENDOR_3COM, USB_PRODUCT_3COM_3CRSHEW696,
108 RadioRFMD, ATU_NO_QUIRK },
109 { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_BWU613,
110 RadioRFMD, ATU_NO_QUIRK },
111 { USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_2664W,
112 AT76C503_rfmd_acc, ATU_NO_QUIRK },
113 { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL300,
114 RadioIntersil, ATU_NO_QUIRK },
115 { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL400,
116 RadioRFMD, ATU_NO_QUIRK },
117 { USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_802UAT1,
118 RadioRFMD, ATU_NO_QUIRK },
119 { USB_VENDOR_ADDTRON, USB_PRODUCT_ADDTRON_AWU120,
120 RadioIntersil, ATU_NO_QUIRK },
121 { USB_VENDOR_AINCOMM, USB_PRODUCT_AINCOMM_AWU2000B,
122 RadioRFMD2958, ATU_NO_QUIRK },
123 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_VOYAGER1010,
124 RadioIntersil, ATU_NO_QUIRK },
125 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013I,
126 RadioIntersil, ATU_NO_QUIRK },
127 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013,
128 RadioRFMD, ATU_NO_QUIRK },
129 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I1,
130 RadioIntersil, ATU_NO_QUIRK },
131 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I2,
132 AT76C503_i3863, ATU_NO_QUIRK },
133 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503RFMD,
134 RadioRFMD, ATU_NO_QUIRK },
135 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD,
136 AT76C505_rfmd, ATU_NO_QUIRK },
137 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD2958,
138 RadioRFMD2958, ATU_NO_QUIRK },
139 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505A, /* SMC2662 V.4 */
140 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
141 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505AS, /* quirk? */
142 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
143 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_WN210,
144 RadioRFMD, ATU_NO_QUIRK },
145 { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D6050,
146 RadioRFMD, ATU_NO_QUIRK },
147 { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_C11U,
148 RadioIntersil, ATU_NO_QUIRK },
149 { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_WL210,
150 RadioIntersil, ATU_NO_QUIRK },
151 { USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQWLAN,
152 RadioRFMD, ATU_NO_QUIRK },
153 { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLUSB_11_STICK,
154 RadioRFMD2958, ATU_NO_QUIRK },
155 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CHUSB611G,
156 RadioRFMD2958, ATU_NO_QUIRK },
157 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL200U,
158 RadioRFMD, ATU_NO_QUIRK },
159 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL240U,
160 RadioRFMD2958, ATU_NO_QUIRK },
161 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_XH1153,
162 RadioRFMD, ATU_NO_QUIRK },
163 { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWL120E,
164 RadioRFMD, ATU_NO_QUIRK },
165 { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWLBM101,
166 RadioRFMD, ATU_NO_QUIRK },
167 { USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_WLAN, /* quirk? */
168 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
169 { USB_VENDOR_HP, USB_PRODUCT_HP_HN210W,
170 RadioIntersil, ATU_NO_QUIRK },
171 { USB_VENDOR_INTEL, USB_PRODUCT_INTEL_AP310,
172 RadioIntersil, ATU_NO_QUIRK },
173 { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBWNB11A,
174 RadioIntersil, ATU_NO_QUIRK },
175 { USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_2662WAR,
176 RadioRFMD, ATU_NO_QUIRK },
177 { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_WUSB11,
178 RadioIntersil, ATU_NO_QUIRK },
179 { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_WUSB11,
180 RadioRFMD, 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 } atu_radfirm[] = {
214 { RadioRFMD, "atu-rfmd-int", "atu-rfmd-ext" },
215 { RadioRFMD2958, "atu-rfmd2958-int", "atu-rfmd2958-ext" },
216 { RadioRFMD2958_SMC, "atu-rfmd2958smc-int", "atu-rfmd2958smc-ext" },
217 { RadioIntersil, "atu-intersil-int", "atu-intersil-ext" },
218 {
219 AT76C503_i3863,
220 "atu-at76c503-i3863-int",
221 "atu-at76c503-i3863-ext"
222 },
223 {
224 AT76C503_rfmd_acc,
225 "atu-at76c503-rfmd-acc-int",
226 "atu-at76c503-rfmd-acc-ext"
227 },
228 {
229 AT76C505_rfmd,
230 "atu-at76c505-rfmd-int",
231 "atu-at76c505-rfmd-ext"
232 }
233 };
234
235 int atu_newbuf(struct atu_softc *, struct atu_chain *, struct mbuf *);
236 void atu_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
237 void atu_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
238 void atu_start(struct ifnet *);
239 int atu_ioctl(struct ifnet *, u_long, caddr_t);
240 int atu_init(struct ifnet *);
241 void atu_stop(struct ifnet *, int);
242 void atu_watchdog(struct ifnet *);
243 usbd_status atu_usb_request(struct atu_softc *sc, u_int8_t type,
244 u_int8_t request, u_int16_t value, u_int16_t index,
245 u_int16_t length, u_int8_t *data);
246 int atu_send_command(struct atu_softc *sc, u_int8_t *command, int size);
247 int atu_get_cmd_status(struct atu_softc *sc, u_int8_t cmd,
248 u_int8_t *status);
249 int atu_wait_completion(struct atu_softc *sc, u_int8_t cmd,
250 u_int8_t *status);
251 int atu_send_mib(struct atu_softc *sc, u_int8_t type,
252 u_int8_t size, u_int8_t index, void *data);
253 int atu_get_mib(struct atu_softc *sc, u_int8_t type,
254 u_int8_t size, u_int8_t index, u_int8_t *buf);
255 #if 0
256 int atu_start_ibss(struct atu_softc *sc);
257 #endif
258 int atu_start_scan(struct atu_softc *sc);
259 int atu_switch_radio(struct atu_softc *sc, int state);
260 int atu_initial_config(struct atu_softc *sc);
261 int atu_join(struct atu_softc *sc, struct ieee80211_node *node);
262 int8_t atu_get_dfu_state(struct atu_softc *sc);
263 u_int8_t atu_get_opmode(struct atu_softc *sc, u_int8_t *mode);
264 void atu_internal_firmware(void *);
265 void atu_external_firmware(void *);
266 int atu_get_card_config(struct atu_softc *sc);
267 int atu_media_change(struct ifnet *ifp);
268 void atu_media_status(struct ifnet *ifp, struct ifmediareq *req);
269 int atu_tx_list_init(struct atu_softc *);
270 int atu_rx_list_init(struct atu_softc *);
271 void atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch,
272 int listlen);
273
274 #ifdef ATU_DEBUG
275 void atu_print_a_bunch_of_debug_things(struct atu_softc *sc);
276 #endif
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
atu_usb_request(struct atu_softc * sc,u_int8_t type,u_int8_t request,u_int16_t value,u_int16_t index,u_int16_t length,u_int8_t * data)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 usbd_xfer_handle 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", USBDEVNAME(sc->atu_dev), request,
306 value, index, length));
307 } else {
308 DPRINTFN(20, ("%s: req=%02x val=%02x ind=%02x "
309 "len=%02x [%8D]\n", USBDEVNAME(sc->atu_dev),
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, 0);
320
321 err = usbd_sync_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: transfered 0x%x bytes in\n",
329 USBDEVNAME(sc->atu_dev), total_len));
330 DPRINTFN(20, ("%s: dump [%10D]\n",
331 USBDEVNAME(sc->atu_dev), data, " "));
332 } else {
333 if (total_len != length)
334 DPRINTF(("%s: ARG! wrote only %x bytes\n",
335 USBDEVNAME(sc->atu_dev), 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
atu_send_command(struct atu_softc * sc,u_int8_t * command,int size)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
atu_get_cmd_status(struct atu_softc * sc,u_int8_t cmd,u_int8_t * status)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
atu_wait_completion(struct atu_softc * sc,u_int8_t cmd,u_int8_t * status)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 USBDEVNAME(sc->atu_dev), 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 USBDEVNAME(sc->atu_dev),
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 USBDEVNAME(sc->atu_dev)));
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
atu_send_mib(struct atu_softc * sc,u_int8_t type,u_int8_t size,u_int8_t index,void * data)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 USBDEVNAME(sc->atu_dev)));
459 return atu_wait_completion(sc, CMD_SET_MIB, NULL);
460 }
461
462 int
atu_get_mib(struct atu_softc * sc,u_int8_t type,u_int8_t size,u_int8_t index,u_int8_t * buf)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 USBDEVNAME(sc->atu_dev)));
499 return err;
500 }
501
502 /* Wait for the adapter to do it's thing */
503 err = atu_wait_completion(sc, CMD_START_IBSS, NULL);
504 if (err) {
505 DPRINTF(("%s: error waiting for start_ibss\n",
506 USBDEVNAME(sc->atu_dev)));
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 USBDEVNAME(sc->atu_dev)));
515 return err;
516 }
517
518 DPRINTF(("%s: started a new IBSS (BSSID=%s)\n",
519 USBDEVNAME(sc->atu_dev), ether_sprintf(sc->atu_bssid)));
520 return 0;
521 }
522 #endif
523
524 int
atu_start_scan(struct atu_softc * sc)525 atu_start_scan(struct atu_softc *sc)
526 {
527 struct atu_cmd_do_scan Scan;
528 usbd_status err;
529 int Cnt;
530
531 memset(&Scan, 0, sizeof(Scan));
532
533 Scan.Cmd = CMD_START_SCAN;
534 Scan.Reserved = 0;
535 USETW(Scan.Size, sizeof(Scan) - 4);
536
537 /* use the broadcast BSSID (in active scan) */
538 for (Cnt=0; Cnt<6; Cnt++)
539 Scan.BSSID[Cnt] = 0xff;
540
541 memset(Scan.SSID, 0x00, sizeof(Scan.SSID));
542 memcpy(Scan.SSID, sc->atu_ssid, sc->atu_ssidlen);
543 Scan.SSID_Len = sc->atu_ssidlen;
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 /* wether 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 USBDEVNAME(sc->atu_dev), sizeof(Scan)));
565 DPRINTFN(20, ("%s: scan cmd: %52D\n", USBDEVNAME(sc->atu_dev),
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
atu_switch_radio(struct atu_softc * sc,int state)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 USBDEVNAME(sc->atu_dev), state ? "on" : "off"));
619 sc->atu_radio_on = state;
620 }
621 return 0;
622 }
623
624 int
atu_initial_config(struct atu_softc * sc)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", USBDEVNAME(sc->atu_dev)));
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 USBDEVNAME(sc->atu_dev)));
640 return err;
641 }
642
643 /*
644 DPRINTF(("%s: sending reg-domain\n", USBDEVNAME(sc->atu_dev)));
645 err = atu_send_mib(sc, MIB_PHY__REG_DOMAIN, NR(0x30));
646 if (err) {
647 DPRINTF(("%s: error setting mac-addr\n",
648 USBDEVNAME(sc->atu_dev)));
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].wk_len) {
678 case 5:
679 cmd.EncryptionType = ATU_WEP_40BITS;
680 break;
681 case 13:
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].wk_key,
692 ic->ic_nw_keys[i].wk_len);
693 }
694
695 /* Setting the SSID here doesn't seem to do anything */
696 memset(cmd.SSID, 0, sizeof(cmd.SSID));
697 memcpy(cmd.SSID, sc->atu_ssid, sc->atu_ssidlen);
698 cmd.SSID_Len = sc->atu_ssidlen;
699
700 cmd.ShortPreamble = 0;
701 USETW(cmd.BeaconPeriod, 100);
702 /* cmd.BeaconPeriod = 65535; */
703
704 /*
705 * TODO:
706 * read reg domain MIB_PHY @ 0x17 (1 byte), (reply = 0x30)
707 * we should do something usefull with this info. right now it's just
708 * ignored
709 */
710 err = atu_get_mib(sc, MIB_PHY__REG_DOMAIN, ®_domain);
711 if (err) {
712 DPRINTF(("%s: could not get regdomain!\n",
713 USBDEVNAME(sc->atu_dev)));
714 } else {
715 DPRINTF(("%s: we're in reg domain 0x%x according to the "
716 "adapter\n", USBDEVNAME(sc->atu_dev), reg_domain));
717 }
718
719 #ifdef ATU_DEBUG
720 if (atudebug) {
721 DPRINTFN(20, ("%s: configlen=%02x\n", USBDEVNAME(sc->atu_dev),
722 sizeof(cmd)));
723 DPRINTFN(20, ("%s: configdata= %108D\n",
724 USBDEVNAME(sc->atu_dev), (u_int8_t *)&cmd, " "));
725 }
726 #endif /* ATU_DEBUG */
727
728 /* Windoze : driver says exclude-unencrypted=1 & encr-type=1 */
729
730 err = atu_send_command(sc, (u_int8_t *)&cmd, sizeof(cmd));
731 if (err)
732 return err;
733 err = atu_wait_completion(sc, CMD_STARTUP, NULL);
734 if (err)
735 return err;
736
737 /* Turn on radio now */
738 err = atu_switch_radio(sc, 1);
739 if (err)
740 return err;
741
742 /* preamble type = short */
743 err = atu_send_mib(sc, MIB_LOCAL__PREAMBLE, NR(PREAMBLE_SHORT));
744 if (err)
745 return err;
746
747 /* frag = 1536 */
748 err = atu_send_mib(sc, MIB_MAC__FRAG, NR(2346));
749 if (err)
750 return err;
751
752 /* rts = 1536 */
753 err = atu_send_mib(sc, MIB_MAC__RTS, NR(2347));
754 if (err)
755 return err;
756
757 /* auto rate fallback = 1 */
758 err = atu_send_mib(sc, MIB_LOCAL__AUTO_RATE_FALLBACK, NR(1));
759 if (err)
760 return err;
761
762 /* power mode = full on, no power saving */
763 err = atu_send_mib(sc, MIB_MAC_MGMT__POWER_MODE,
764 NR(POWER_MODE_ACTIVE));
765 if (err)
766 return err;
767
768 DPRINTFN(10, ("%s: completed initial config\n",
769 USBDEVNAME(sc->atu_dev)));
770 return 0;
771 }
772
773 int
atu_join(struct atu_softc * sc,struct ieee80211_node * node)774 atu_join(struct atu_softc *sc, struct ieee80211_node *node)
775 {
776 struct atu_cmd_join join;
777 u_int8_t status;
778 usbd_status err;
779
780 memset(&join, 0, sizeof(join));
781
782 join.Cmd = CMD_JOIN;
783 join.Reserved = 0x00;
784 USETW(join.Size, sizeof(join) - 4);
785
786 DPRINTFN(15, ("%s: pre-join sc->atu_bssid=%s\n",
787 USBDEVNAME(sc->atu_dev), ether_sprintf(sc->atu_bssid)));
788 DPRINTFN(15, ("%s: mode=%d\n", USBDEVNAME(sc->atu_dev),
789 sc->atu_mode));
790 memcpy(join.bssid, node->ni_bssid, IEEE80211_ADDR_LEN);
791 memset(join.essid, 0x00, 32);
792 memcpy(join.essid, node->ni_essid, node->ni_esslen);
793 join.essid_size = node->ni_esslen;
794 if (node->ni_capinfo & IEEE80211_CAPINFO_IBSS)
795 join.bss_type = AD_HOC_MODE;
796 else
797 join.bss_type = INFRASTRUCTURE_MODE;
798 join.channel = ieee80211_chan2ieee(&sc->sc_ic, node->ni_chan);
799
800 USETW(join.timeout, ATU_JOIN_TIMEOUT);
801 join.reserved = 0x00;
802
803 DPRINTFN(10, ("%s: trying to join BSSID=%s\n",
804 USBDEVNAME(sc->atu_dev), ether_sprintf(join.bssid)));
805 err = atu_send_command(sc, (u_int8_t *)&join, sizeof(join));
806 if (err) {
807 DPRINTF(("%s: ERROR trying to join IBSS\n",
808 USBDEVNAME(sc->atu_dev)));
809 return err;
810 }
811 err = atu_wait_completion(sc, CMD_JOIN, &status);
812 if (err) {
813 DPRINTF(("%s: error joining BSS!\n",
814 USBDEVNAME(sc->atu_dev)));
815 return err;
816 }
817 if (status != STATUS_COMPLETE) {
818 DPRINTF(("%s: error joining... [status=%02x]\n",
819 USBDEVNAME(sc->atu_dev), status));
820 return status;
821 } else {
822 DPRINTFN(10, ("%s: joined BSS\n", USBDEVNAME(sc->atu_dev)));
823 }
824 return err;
825 }
826
827 /*
828 * Get the state of the DFU unit
829 */
830 int8_t
atu_get_dfu_state(struct atu_softc * sc)831 atu_get_dfu_state(struct atu_softc *sc)
832 {
833 u_int8_t state;
834
835 if (atu_usb_request(sc, DFU_GETSTATE, 0, 0, 1, &state))
836 return -1;
837 return state;
838 }
839
840 /*
841 * Get MAC opmode
842 */
843 u_int8_t
atu_get_opmode(struct atu_softc * sc,u_int8_t * mode)844 atu_get_opmode(struct atu_softc *sc, u_int8_t *mode)
845 {
846
847 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 0x0001,
848 0x0000, 1, mode);
849 }
850
851 /*
852 * Upload the internal firmware into the device
853 */
854 void
atu_internal_firmware(void * arg)855 atu_internal_firmware(void *arg)
856 {
857 struct atu_softc *sc = arg;
858 u_char state, *ptr = NULL, *firm = NULL, status[6];
859 int block_size, block = 0, err, i;
860 size_t bytes_left = 0;
861 char *name = "unknown-device";
862
863 /*
864 * Uploading firmware is done with the DFU (Device Firmware Upgrade)
865 * interface. See "Universal Serial Bus - Device Class Specification
866 * for Device Firmware Upgrade" pdf for details of the protocol.
867 * Maybe this could be moved to a seperate 'firmware driver' once more
868 * device drivers need it... For now we'll just do it here.
869 *
870 * Just for your information, the Atmel's DFU descriptor looks like
871 * this:
872 *
873 * 07 size
874 * 21 type
875 * 01 capabilities : only firmware download, need reset
876 * after download
877 * 13 05 detach timeout : max 1299ms between DFU_DETACH and
878 * reset
879 * 00 04 max bytes of firmware per transaction : 1024
880 */
881
882 /* Choose the right firmware for the device */
883 for (i = 0; i < sizeof(atu_radfirm)/sizeof(atu_radfirm[0]); i++)
884 if (sc->atu_radio == atu_radfirm[i].atur_type)
885 name = atu_radfirm[i].atur_internal;
886
887 DPRINTF(("%s: loading firmware %s...\n",
888 USBDEVNAME(sc->atu_dev), name));
889 err = loadfirmware(name, &firm, &bytes_left);
890 if (err != 0) {
891 printf("%s: %s loadfirmware error %d\n",
892 USBDEVNAME(sc->atu_dev), name, err);
893 return;
894 }
895
896 ptr = firm;
897 state = atu_get_dfu_state(sc);
898
899 while (block >= 0 && state > 0) {
900 switch (state) {
901 case DFUState_DnLoadSync:
902 /* get DFU status */
903 err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0 , 6,
904 status);
905 if (err) {
906 DPRINTF(("%s: dfu_getstatus failed!\n",
907 USBDEVNAME(sc->atu_dev)));
908 free(firm, M_DEVBUF);
909 return;
910 }
911 /* success means state => DnLoadIdle */
912 state = DFUState_DnLoadIdle;
913 continue;
914 break;
915
916 case DFUState_DFUIdle:
917 case DFUState_DnLoadIdle:
918 if (bytes_left>=DFU_MaxBlockSize)
919 block_size = DFU_MaxBlockSize;
920 else
921 block_size = bytes_left;
922 DPRINTFN(15, ("%s: firmware block %d\n",
923 USBDEVNAME(sc->atu_dev), block));
924
925 err = atu_usb_request(sc, DFU_DNLOAD, block++, 0,
926 block_size, ptr);
927 if (err) {
928 DPRINTF(("%s: dfu_dnload failed\n",
929 USBDEVNAME(sc->atu_dev)));
930 free(firm, M_DEVBUF);
931 return;
932 }
933
934 ptr += block_size;
935 bytes_left -= block_size;
936 if (block_size == 0)
937 block = -1;
938 break;
939
940 default:
941 usbd_delay_ms(sc->atu_udev, 100);
942 DPRINTFN(20, ("%s: sleeping for a while\n",
943 USBDEVNAME(sc->atu_dev)));
944 break;
945 }
946
947 state = atu_get_dfu_state(sc);
948 }
949 free(firm, M_DEVBUF);
950
951 if (state != DFUState_ManifestSync) {
952 DPRINTF(("%s: state != manifestsync... eek!\n",
953 USBDEVNAME(sc->atu_dev)));
954 }
955
956 err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0, 6, status);
957 if (err) {
958 DPRINTF(("%s: dfu_getstatus failed!\n",
959 USBDEVNAME(sc->atu_dev)));
960 return;
961 }
962
963 DPRINTFN(15, ("%s: sending remap\n", USBDEVNAME(sc->atu_dev)));
964 err = atu_usb_request(sc, DFU_REMAP, 0, 0, 0, NULL);
965 if ((err) && (! sc->atu_quirk & ATU_QUIRK_NO_REMAP)) {
966 DPRINTF(("%s: remap failed!\n", USBDEVNAME(sc->atu_dev)));
967 return;
968 }
969
970 /* after a lot of trying and measuring I found out the device needs
971 * about 56 miliseconds after sending the remap command before
972 * it's ready to communicate again. So we'll wait just a little bit
973 * longer than that to be sure...
974 */
975 usbd_delay_ms(sc->atu_udev, 56+100);
976
977 printf("%s: reattaching after firmware upload\n",
978 USBDEVNAME(sc->atu_dev));
979 usb_needs_reattach(sc->atu_udev);
980 }
981
982 void
atu_external_firmware(void * arg)983 atu_external_firmware(void *arg)
984 {
985 struct atu_softc *sc = arg;
986 u_char *ptr = NULL, *firm = NULL;
987 int block_size, block = 0, err, i;
988 size_t bytes_left = 0;
989 char *name = "unknown-device";
990
991 for (i = 0; i < sizeof(atu_radfirm)/sizeof(atu_radfirm[0]); i++)
992 if (sc->atu_radio == atu_radfirm[i].atur_type)
993 name = atu_radfirm[i].atur_external;
994
995 DPRINTF(("%s: loading external firmware %s\n",
996 USBDEVNAME(sc->atu_dev), name));
997 err = loadfirmware(name, &firm, &bytes_left);
998 if (err != 0) {
999 printf("%s: %s loadfirmware error %d\n",
1000 USBDEVNAME(sc->atu_dev), name, err);
1001 return;
1002 }
1003 ptr = firm;
1004
1005 while (bytes_left) {
1006 if (bytes_left > 1024)
1007 block_size = 1024;
1008 else
1009 block_size = bytes_left;
1010
1011 DPRINTFN(15, ("%s: block:%d size:%d\n",
1012 USBDEVNAME(sc->atu_dev), block, block_size));
1013 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e,
1014 0x0802, block, block_size, ptr);
1015 if (err) {
1016 DPRINTF(("%s: could not load external firmware "
1017 "block\n", USBDEVNAME(sc->atu_dev)));
1018 free(firm, M_DEVBUF);
1019 return;
1020 }
1021
1022 ptr += block_size;
1023 block++;
1024 bytes_left -= block_size;
1025 }
1026 free(firm, M_DEVBUF);
1027
1028 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0802,
1029 block, 0, NULL);
1030 if (err) {
1031 DPRINTF(("%s: could not load last zero-length firmware "
1032 "block\n", USBDEVNAME(sc->atu_dev)));
1033 return;
1034 }
1035
1036 /*
1037 * The SMC2662w V.4 seems to require some time to do it's thing with
1038 * the external firmware... 20 ms isn't enough, but 21 ms works 100
1039 * times out of 100 tries. We'll wait a bit longer just to be sure
1040 */
1041 if (sc->atu_quirk & ATU_QUIRK_FW_DELAY)
1042 usbd_delay_ms(sc->atu_udev, 21 + 100);
1043
1044 DPRINTFN(10, ("%s: external firmware upload done\n",
1045 USBDEVNAME(sc->atu_dev)));
1046 /* complete configuration after the firmwares have been uploaded */
1047 atu_complete_attach(sc);
1048 }
1049
1050 int
atu_get_card_config(struct atu_softc * sc)1051 atu_get_card_config(struct atu_softc *sc)
1052 {
1053 struct ieee80211com *ic = &sc->sc_ic;
1054 struct atu_rfmd_conf rfmd_conf;
1055 struct atu_intersil_conf intersil_conf;
1056 int err;
1057
1058 switch (sc->atu_radio) {
1059
1060 case RadioRFMD:
1061 case RadioRFMD2958:
1062 case RadioRFMD2958_SMC:
1063 case AT76C503_rfmd_acc:
1064 case AT76C505_rfmd:
1065 err = atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33,
1066 0x0a02, 0x0000, sizeof(rfmd_conf),
1067 (u_int8_t *)&rfmd_conf);
1068 if (err) {
1069 DPRINTF(("%s: could not get rfmd config!\n",
1070 USBDEVNAME(sc->atu_dev)));
1071 return err;
1072 }
1073 memcpy(ic->ic_myaddr, rfmd_conf.MACAddr, IEEE80211_ADDR_LEN);
1074 break;
1075
1076 case RadioIntersil:
1077 case AT76C503_i3863:
1078 err = atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33,
1079 0x0902, 0x0000, sizeof(intersil_conf),
1080 (u_int8_t *)&intersil_conf);
1081 if (err) {
1082 DPRINTF(("%s: could not get intersil config!\n",
1083 USBDEVNAME(sc->atu_dev)));
1084 return err;
1085 }
1086 memcpy(ic->ic_myaddr, intersil_conf.MACAddr,
1087 IEEE80211_ADDR_LEN);
1088 break;
1089 }
1090 return 0;
1091 }
1092
1093 /*
1094 * Probe for an AT76c503 chip.
1095 */
USB_MATCH(atu)1096 USB_MATCH(atu)
1097 {
1098 USB_MATCH_START(atu, uaa);
1099 int i;
1100
1101 if (!uaa->iface)
1102 return(UMATCH_NONE);
1103
1104 for (i = 0; i < sizeof(atu_devs)/sizeof(atu_devs[0]); i++) {
1105 struct atu_type *t = &atu_devs[i];
1106
1107 if (uaa->vendor == t->atu_vid &&
1108 uaa->product == t->atu_pid) {
1109 return(UMATCH_VENDOR_PRODUCT);
1110 }
1111 }
1112 return(UMATCH_NONE);
1113 }
1114
1115 int
atu_media_change(struct ifnet * ifp)1116 atu_media_change(struct ifnet *ifp)
1117 {
1118 #ifdef ATU_DEBUG
1119 struct atu_softc *sc = ifp->if_softc;
1120 #endif /* ATU_DEBUG */
1121 int err;
1122
1123 DPRINTFN(10, ("%s: atu_media_change\n", USBDEVNAME(sc->atu_dev)));
1124
1125 err = ieee80211_media_change(ifp);
1126 if (err == ENETRESET) {
1127 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
1128 (IFF_RUNNING|IFF_UP))
1129 atu_init(ifp);
1130 err = 0;
1131 }
1132
1133 return (err);
1134 }
1135
1136 void
atu_media_status(struct ifnet * ifp,struct ifmediareq * req)1137 atu_media_status(struct ifnet *ifp, struct ifmediareq *req)
1138 {
1139 #ifdef ATU_DEBUG
1140 struct atu_softc *sc = ifp->if_softc;
1141 #endif /* ATU_DEBUG */
1142
1143 DPRINTFN(10, ("%s: atu_media_status\n", USBDEVNAME(sc->atu_dev)));
1144
1145 ieee80211_media_status(ifp, req);
1146 }
1147
1148 void
atu_task(void * arg)1149 atu_task(void *arg)
1150 {
1151 struct atu_softc *sc = (struct atu_softc *)arg;
1152 struct ieee80211com *ic = &sc->sc_ic;
1153 struct ifnet *ifp = &ic->ic_if;
1154 usbd_status err;
1155 int s;
1156
1157 DPRINTFN(10, ("%s: atu_task\n", USBDEVNAME(sc->atu_dev)));
1158
1159 if (sc->sc_state != ATU_S_OK)
1160 return;
1161
1162 switch (sc->sc_cmd) {
1163 case ATU_C_SCAN:
1164
1165 err = atu_start_scan(sc);
1166 if (err) {
1167 DPRINTFN(1, ("%s: atu_init: couldn't start scan!\n",
1168 USBDEVNAME(sc->atu_dev)));
1169 return;
1170 }
1171
1172 err = atu_wait_completion(sc, CMD_START_SCAN, NULL);
1173 if (err) {
1174 DPRINTF(("%s: atu_init: error waiting for scan\n",
1175 USBDEVNAME(sc->atu_dev)));
1176 return;
1177 }
1178
1179 DPRINTF(("%s: ==========================> END OF SCAN!\n",
1180 USBDEVNAME(sc->atu_dev)));
1181
1182 s = splnet();
1183 /* ieee80211_next_scan(ifp); */
1184 ieee80211_end_scan(ifp);
1185 splx(s);
1186
1187 DPRINTF(("%s: ----------------------======> END OF SCAN2!\n",
1188 USBDEVNAME(sc->atu_dev)));
1189 break;
1190
1191 case ATU_C_JOIN:
1192 atu_join(sc, ic->ic_bss);
1193 }
1194 }
1195
1196 int
atu_newstate(struct ieee80211com * ic,enum ieee80211_state nstate,int arg)1197 atu_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1198 {
1199 struct ifnet *ifp = &ic->ic_if;
1200 struct atu_softc *sc = ifp->if_softc;
1201 enum ieee80211_state ostate = ic->ic_state;
1202
1203 DPRINTFN(10, ("%s: atu_newstate: %s -> %s\n", USBDEVNAME(sc->atu_dev),
1204 ieee80211_state_name[ostate], ieee80211_state_name[nstate]));
1205
1206 switch (nstate) {
1207 case IEEE80211_S_SCAN:
1208 memcpy(ic->ic_chan_scan, ic->ic_chan_active,
1209 sizeof(ic->ic_chan_active));
1210 ieee80211_free_allnodes(ic);
1211
1212 /* tell the event thread that we want a scan */
1213 sc->sc_cmd = ATU_C_SCAN;
1214 usb_add_task(sc->atu_udev, &sc->sc_task);
1215
1216 /* handle this ourselves */
1217 ic->ic_state = nstate;
1218 return (0);
1219
1220 case IEEE80211_S_AUTH:
1221 case IEEE80211_S_RUN:
1222 if (ostate == IEEE80211_S_SCAN) {
1223 sc->sc_cmd = ATU_C_JOIN;
1224 usb_add_task(sc->atu_udev, &sc->sc_task);
1225 }
1226 break;
1227 default:
1228 /* nothing to do */
1229 break;
1230 }
1231
1232 return (*sc->sc_newstate)(ic, nstate, arg);
1233 }
1234
1235 /*
1236 * Attach the interface. Allocate softc structures, do
1237 * setup and ethernet/BPF attach.
1238 */
USB_ATTACH(atu)1239 USB_ATTACH(atu)
1240 {
1241 USB_ATTACH_START(atu, sc, uaa);
1242 char devinfo[1024];
1243 usbd_status err;
1244 usbd_device_handle dev = uaa->device;
1245 u_int8_t mode, channel;
1246 int i;
1247
1248 sc->sc_state = ATU_S_UNCONFIG;
1249
1250 usbd_devinfo(uaa->device, 0, devinfo, sizeof devinfo);
1251 USB_ATTACH_SETUP;
1252 printf("%s: %s", USBDEVNAME(sc->atu_dev), devinfo);
1253
1254 err = usbd_set_config_no(dev, ATU_CONFIG_NO, 1);
1255 if (err) {
1256 printf("%s: setting config no failed\n",
1257 USBDEVNAME(sc->atu_dev));
1258 USB_ATTACH_ERROR_RETURN;
1259 }
1260
1261 err = usbd_device2interface_handle(dev, ATU_IFACE_IDX, &sc->atu_iface);
1262 if (err) {
1263 printf("%s: getting interface handle failed\n",
1264 USBDEVNAME(sc->atu_dev));
1265 USB_ATTACH_ERROR_RETURN;
1266 }
1267
1268 sc->atu_unit = self->dv_unit;
1269 sc->atu_udev = dev;
1270
1271 /*
1272 * look up the radio_type for the device
1273 * basically does the same as USB_MATCH
1274 */
1275 for (i = 0; i < sizeof(atu_devs)/sizeof(atu_devs[0]); i++) {
1276 struct atu_type *t = &atu_devs[i];
1277
1278 if (uaa->vendor == t->atu_vid &&
1279 uaa->product == t->atu_pid) {
1280 sc->atu_radio = t->atu_radio;
1281 sc->atu_quirk = t->atu_quirk;
1282 }
1283 }
1284
1285 /*
1286 * Check in the interface descriptor if we're in DFU mode
1287 * If we're in DFU mode, we upload the external firmware
1288 * If we're not, the PC must have rebooted without power-cycling
1289 * the device.. I've tried this out, a reboot only requeres the
1290 * external firmware to be reloaded :)
1291 *
1292 * Hmm. The at76c505a doesn't report a DFU descriptor when it's
1293 * in DFU mode... Let's just try to get the opmode
1294 */
1295 err = atu_get_opmode(sc, &mode);
1296 DPRINTFN(20, ("%s: opmode: %d\n", USBDEVNAME(sc->atu_dev), mode));
1297 if (err || (mode != MODE_NETCARD && mode != MODE_NOFLASHNETCARD)) {
1298 DPRINTF(("%s: starting internal firmware download\n",
1299 USBDEVNAME(sc->atu_dev)));
1300
1301 printf("\n");
1302
1303 if (rootvp == NULL)
1304 mountroothook_establish(atu_internal_firmware, sc);
1305 else
1306 atu_internal_firmware(sc);
1307 /*
1308 * atu_internal_firmware will cause a reset of the device
1309 * so we don't want to do any more configuration after this
1310 * point.
1311 */
1312 USB_ATTACH_SUCCESS_RETURN;
1313 }
1314
1315 uaa->iface = sc->atu_iface;
1316
1317 if (mode != MODE_NETCARD) {
1318 DPRINTFN(15, ("%s: device needs external firmware\n",
1319 USBDEVNAME(sc->atu_dev)));
1320
1321 if (mode != MODE_NOFLASHNETCARD) {
1322 DPRINTF(("%s: EEK! unexpected opmode=%d\n",
1323 USBDEVNAME(sc->atu_dev), mode));
1324 }
1325
1326 /*
1327 * There is no difference in opmode before and after external
1328 * firmware upload with the SMC2662 V.4 . So instead we'll try
1329 * to read the channel number. If we succeed, external
1330 * firmwaremust have been already uploaded...
1331 */
1332 if (sc->atu_radio != RadioIntersil) {
1333 err = atu_get_mib(sc, MIB_PHY__CHANNEL, &channel);
1334 if (!err) {
1335 DPRINTF(("%s: external firmware has already"
1336 " been downloaded\n",
1337 USBDEVNAME(sc->atu_dev)));
1338 atu_complete_attach(sc);
1339 USB_ATTACH_SUCCESS_RETURN;
1340 }
1341 }
1342
1343 if (rootvp == NULL)
1344 mountroothook_establish(atu_external_firmware, sc);
1345 else
1346 atu_external_firmware(sc);
1347
1348 /*
1349 * atu_external_firmware will call atu_complete_attach after
1350 * it's finished so we can just return.
1351 */
1352 } else {
1353 /* all the firmwares are in place, so complete the attach */
1354 atu_complete_attach(sc);
1355 }
1356
1357 USB_ATTACH_SUCCESS_RETURN;
1358 }
1359
1360 void
atu_complete_attach(struct atu_softc * sc)1361 atu_complete_attach(struct atu_softc *sc)
1362 {
1363 struct ieee80211com *ic = &sc->sc_ic;
1364 struct ifnet *ifp = &ic->ic_if;
1365 usb_interface_descriptor_t *id;
1366 usb_endpoint_descriptor_t *ed;
1367 usbd_status err;
1368 int i;
1369 #ifdef ATU_DEBUG
1370 struct atu_fw fw;
1371 #endif
1372
1373 id = usbd_get_interface_descriptor(sc->atu_iface);
1374
1375 /* Find endpoints. */
1376 for (i = 0; i < id->bNumEndpoints; i++) {
1377 ed = usbd_interface2endpoint_descriptor(sc->atu_iface, i);
1378 if (!ed) {
1379 DPRINTF(("%s: num_endp:%d\n", USBDEVNAME(sc->atu_dev),
1380 sc->atu_iface->idesc->bNumEndpoints));
1381 DPRINTF(("%s: couldn't get ep %d\n",
1382 USBDEVNAME(sc->atu_dev), i));
1383 return;
1384 }
1385 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
1386 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1387 sc->atu_ed[ATU_ENDPT_RX] = ed->bEndpointAddress;
1388 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
1389 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1390 sc->atu_ed[ATU_ENDPT_TX] = ed->bEndpointAddress;
1391 }
1392 }
1393
1394 /* read device config & get MAC address */
1395 err = atu_get_card_config(sc);
1396 if (err) {
1397 printf("\n%s: could not get card cfg!\n",
1398 USBDEVNAME(sc->atu_dev));
1399 return;
1400 }
1401
1402 #ifdef ATU_DEBUG
1403 /* DEBUG : try to get firmware version */
1404 err = atu_get_mib(sc, MIB_FW_VERSION, sizeof(fw), 0,
1405 (u_int8_t *)&fw);
1406 if (!err) {
1407 DPRINTFN(15, ("%s: firmware: maj:%d min:%d patch:%d "
1408 "build:%d\n", USBDEVNAME(sc->atu_dev), fw.major, fw.minor,
1409 fw.patch, fw.build));
1410 } else {
1411 DPRINTF(("%s: get firmware version failed\n",
1412 USBDEVNAME(sc->atu_dev)));
1413 }
1414 #endif /* ATU_DEBUG */
1415
1416 /* Show the world our MAC address */
1417 printf(": address %s\n", ether_sprintf(ic->ic_myaddr));
1418
1419 sc->atu_cdata.atu_tx_inuse = 0;
1420
1421 bzero(sc->atu_bssid, ETHER_ADDR_LEN);
1422 sc->atu_ssidlen = strlen(ATU_DEFAULT_SSID);
1423 memcpy(sc->atu_ssid, ATU_DEFAULT_SSID, sc->atu_ssidlen);
1424 sc->atu_channel = ATU_DEFAULT_CHANNEL;
1425 sc->atu_desired_channel = IEEE80211_CHAN_ANY;
1426 sc->atu_mode = INFRASTRUCTURE_MODE;
1427
1428 ic->ic_softc = sc;
1429 ic->ic_phytype = IEEE80211_T_DS;
1430 ic->ic_opmode = IEEE80211_M_STA;
1431 ic->ic_state = IEEE80211_S_INIT;
1432 ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_WEP | IEEE80211_C_SCANALL;
1433
1434 i = 0;
1435 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[i++] = 2;
1436 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[i++] = 4;
1437 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[i++] = 11;
1438 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[i++] = 22;
1439 ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = i;
1440
1441 for (i = 1; i <= 14; i++) {
1442 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B |
1443 IEEE80211_CHAN_PASSIVE;
1444 ic->ic_channels[i].ic_freq = ieee80211_ieee2mhz(i,
1445 ic->ic_channels[i].ic_flags);
1446 }
1447
1448 ic->ic_ibss_chan = &ic->ic_channels[0];
1449
1450 ifp->if_softc = sc;
1451 memcpy(ifp->if_xname, USBDEVNAME(sc->atu_dev), IFNAMSIZ);
1452 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1453 ifp->if_start = atu_start;
1454 ifp->if_ioctl = atu_ioctl;
1455 ifp->if_watchdog = atu_watchdog;
1456 ifp->if_mtu = ATU_DEFAULT_MTU;
1457 IFQ_SET_READY(&ifp->if_snd);
1458
1459 /* Call MI attach routine. */
1460 if_attach(ifp);
1461 ieee80211_ifattach(ifp);
1462
1463 sc->sc_newstate = ic->ic_newstate;
1464 ic->ic_newstate = atu_newstate;
1465
1466 /* setup ifmedia interface */
1467 ieee80211_media_init(ifp, atu_media_change, atu_media_status);
1468
1469 usb_init_task(&sc->sc_task, atu_task, sc);
1470
1471 #if NBPFILTER > 0
1472 bpfattach(&sc->sc_radiobpf, &sc->sc_ic.ic_if, DLT_IEEE802_11_RADIO,
1473 sizeof(struct ieee80211_frame) + 64);
1474
1475 bzero(&sc->sc_rxtapu, sizeof(sc->sc_rxtapu));
1476 sc->sc_rxtap.rr_ihdr.it_len = sizeof(sc->sc_rxtapu);
1477 sc->sc_rxtap.rr_ihdr.it_present = htole32(ATU_RX_RADIOTAP_PRESENT);
1478
1479 bzero(&sc->sc_txtapu, sizeof(sc->sc_txtapu));
1480 sc->sc_txtap.rt_ihdr.it_len = sizeof(sc->sc_txtapu);
1481 sc->sc_txtap.rt_ihdr.it_present = htole32(ATU_TX_RADIOTAP_PRESENT);
1482 #endif
1483
1484 sc->sc_state = ATU_S_OK;
1485 }
1486
USB_DETACH(atu)1487 USB_DETACH(atu)
1488 {
1489 USB_DETACH_START(atu, sc);
1490 struct ifnet *ifp = &sc->sc_ic.ic_if;
1491
1492 DPRINTFN(10, ("%s: atu_detach state=%d\n", USBDEVNAME(sc->atu_dev),
1493 sc->sc_state));
1494
1495 if (sc->sc_state != ATU_S_UNCONFIG) {
1496 atu_stop(ifp, 1);
1497 #if NBPFILTER > 0
1498 bpfdetach(ifp);
1499 #endif
1500 ieee80211_ifdetach(ifp);
1501 if_detach(ifp);
1502
1503 if (sc->atu_ep[ATU_ENDPT_TX] != NULL)
1504 usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]);
1505 if (sc->atu_ep[ATU_ENDPT_RX] != NULL)
1506 usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]);
1507
1508 usb_rem_task(sc->atu_udev, &sc->sc_task);
1509 }
1510
1511 return(0);
1512 }
1513
1514 int
atu_activate(device_ptr_t self,enum devact act)1515 atu_activate(device_ptr_t self, enum devact act)
1516 {
1517 struct atu_softc *sc = (struct atu_softc *)self;
1518
1519 switch (act) {
1520 case DVACT_ACTIVATE:
1521 return (EOPNOTSUPP);
1522 break;
1523 case DVACT_DEACTIVATE:
1524 if (sc->sc_state != ATU_S_UNCONFIG) {
1525 if_deactivate(&sc->atu_ec.ec_if);
1526 sc->sc_state = ATU_S_DEAD;
1527 }
1528 break;
1529 }
1530 return (0);
1531 }
1532
1533 /*
1534 * Initialize an RX descriptor and attach an MBUF cluster.
1535 */
1536 int
atu_newbuf(struct atu_softc * sc,struct atu_chain * c,struct mbuf * m)1537 atu_newbuf(struct atu_softc *sc, struct atu_chain *c, struct mbuf *m)
1538 {
1539 struct mbuf *m_new = NULL;
1540
1541 if (m == NULL) {
1542 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1543 if (m_new == NULL) {
1544 DPRINTF(("%s: no memory for rx list\n",
1545 USBDEVNAME(sc->atu_dev)));
1546 return(ENOBUFS);
1547 }
1548
1549 MCLGET(m_new, M_DONTWAIT);
1550 if (!(m_new->m_flags & M_EXT)) {
1551 DPRINTF(("%s: no memory for rx list\n",
1552 USBDEVNAME(sc->atu_dev)));
1553 m_freem(m_new);
1554 return(ENOBUFS);
1555 }
1556 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1557 } else {
1558 m_new = m;
1559 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1560 m_new->m_data = m_new->m_ext.ext_buf;
1561 }
1562 c->atu_mbuf = m_new;
1563 return(0);
1564 }
1565
1566 int
atu_rx_list_init(struct atu_softc * sc)1567 atu_rx_list_init(struct atu_softc *sc)
1568 {
1569 struct atu_cdata *cd = &sc->atu_cdata;
1570 struct atu_chain *c;
1571 int i;
1572
1573 DPRINTFN(15, ("%s: atu_rx_list_init: enter\n",
1574 USBDEVNAME(sc->atu_dev)));
1575
1576 for (i = 0; i < ATU_RX_LIST_CNT; i++) {
1577 c = &cd->atu_rx_chain[i];
1578 c->atu_sc = sc;
1579 c->atu_idx = i;
1580 if (c->atu_xfer == NULL) {
1581 c->atu_xfer = usbd_alloc_xfer(sc->atu_udev);
1582 if (c->atu_xfer == NULL)
1583 return (ENOBUFS);
1584 c->atu_buf = usbd_alloc_buffer(c->atu_xfer,
1585 ATU_RX_BUFSZ);
1586 if (c->atu_buf == NULL) /* XXX free xfer */
1587 return (ENOBUFS);
1588 if (atu_newbuf(sc, c, NULL) == ENOBUFS) /* XXX free? */
1589 return(ENOBUFS);
1590 }
1591 }
1592 return (0);
1593 }
1594
1595 int
atu_tx_list_init(struct atu_softc * sc)1596 atu_tx_list_init(struct atu_softc *sc)
1597 {
1598 struct atu_cdata *cd = &sc->atu_cdata;
1599 struct atu_chain *c;
1600 int i;
1601
1602 DPRINTFN(15, ("%s: atu_tx_list_init\n",
1603 USBDEVNAME(sc->atu_dev)));
1604
1605 SLIST_INIT(&cd->atu_tx_free);
1606 sc->atu_cdata.atu_tx_inuse = 0;
1607
1608 for (i = 0; i < ATU_TX_LIST_CNT; i++) {
1609 c = &cd->atu_tx_chain[i];
1610 c->atu_sc = sc;
1611 c->atu_idx = i;
1612 if (c->atu_xfer == NULL) {
1613 c->atu_xfer = usbd_alloc_xfer(sc->atu_udev);
1614 if (c->atu_xfer == NULL)
1615 return(ENOBUFS);
1616 c->atu_mbuf = NULL;
1617 c->atu_buf = usbd_alloc_buffer(c->atu_xfer,
1618 ATU_TX_BUFSZ);
1619 if (c->atu_buf == NULL)
1620 return(ENOBUFS); /* XXX free xfer */
1621 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, atu_list);
1622 }
1623 }
1624 return(0);
1625 }
1626
1627 void
atu_xfer_list_free(struct atu_softc * sc,struct atu_chain * ch,int listlen)1628 atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch,
1629 int listlen)
1630 {
1631 int i;
1632
1633 /* Free resources. */
1634 for (i = 0; i < listlen; i++) {
1635 if (ch[i].atu_buf != NULL)
1636 ch[i].atu_buf = NULL;
1637 if (ch[i].atu_mbuf != NULL) {
1638 m_freem(ch[i].atu_mbuf);
1639 ch[i].atu_mbuf = NULL;
1640 }
1641 if (ch[i].atu_xfer != NULL) {
1642 usbd_free_xfer(ch[i].atu_xfer);
1643 ch[i].atu_xfer = NULL;
1644 }
1645 }
1646 }
1647
1648 /*
1649 * A frame has been uploaded: pass the resulting mbuf chain up to
1650 * the higher level protocols.
1651 */
1652 void
atu_rxeof(usbd_xfer_handle xfer,usbd_private_handle priv,usbd_status status)1653 atu_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1654 {
1655 struct atu_chain *c = (struct atu_chain *)priv;
1656 struct atu_softc *sc = c->atu_sc;
1657 struct ieee80211com *ic = &sc->sc_ic;
1658 struct ifnet *ifp = &ic->ic_if;
1659 struct atu_rx_hdr *h;
1660 struct ieee80211_frame *wh;
1661 struct ieee80211_node *ni;
1662 struct mbuf *m;
1663 u_int32_t len;
1664 int s;
1665
1666 DPRINTFN(25, ("%s: atu_rxeof\n", USBDEVNAME(sc->atu_dev)));
1667
1668 if (sc->sc_state != ATU_S_OK)
1669 return;
1670
1671 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP))
1672 goto done;
1673
1674 if (status != USBD_NORMAL_COMPLETION) {
1675 DPRINTF(("%s: status != USBD_NORMAL_COMPLETION\n",
1676 USBDEVNAME(sc->atu_dev)));
1677 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1678 return;
1679 }
1680 #if 0
1681 if (status == USBD_IOERROR) {
1682 DPRINTF(("%s: rx: EEK! lost device?\n",
1683 USBDEVNAME(sc->atu_dev)));
1684
1685 /*
1686 * My experience with USBD_IOERROR is that trying to
1687 * restart the transfer will always fail and we'll
1688 * keep on looping restarting transfers untill someone
1689 * pulls the plug of the device.
1690 * So we don't restart the transfer, but just let it
1691 * die... If someone knows of a situation where we can
1692 * recover from USBD_IOERROR, let me know.
1693 */
1694 splx(s);
1695 return;
1696 }
1697 #endif /* 0 */
1698
1699 if (usbd_ratecheck(&sc->atu_rx_notice)) {
1700 DPRINTF(("%s: usb error on rx: %s\n",
1701 USBDEVNAME(sc->atu_dev), usbd_errstr(status)));
1702 }
1703 if (status == USBD_STALLED)
1704 usbd_clear_endpoint_stall(
1705 sc->atu_ep[ATU_ENDPT_RX]);
1706 goto done;
1707 }
1708
1709 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
1710
1711 if (len <= 1) {
1712 DPRINTF(("%s: atu_rxeof: too short\n",
1713 USBDEVNAME(sc->atu_dev)));
1714 goto done;
1715 }
1716
1717 h = (struct atu_rx_hdr *)c->atu_buf;
1718 len = UGETW(h->length) - 4; /* XXX magic number */
1719
1720 m = c->atu_mbuf;
1721 memcpy(mtod(m, char *), c->atu_buf + ATU_RX_HDRLEN, len);
1722 m->m_pkthdr.rcvif = ifp;
1723 m->m_pkthdr.len = m->m_len = len;
1724
1725 wh = mtod(m, struct ieee80211_frame *);
1726 ni = ieee80211_find_rxnode(ic, wh);
1727
1728 ifp->if_ipackets++;
1729
1730 s = splnet();
1731
1732 if (atu_newbuf(sc, c, NULL) == ENOBUFS) {
1733 ifp->if_ierrors++;
1734 goto done1; /* XXX if we can't allocate, why restart it? */
1735 }
1736
1737 #if NBPFILTER > 0
1738 if (sc->sc_radiobpf != NULL) {
1739 struct mbuf mb;
1740 struct atu_rx_radiotap_header *rr = &sc->sc_rxtap;
1741
1742 rr->rr_flags = 0;
1743 rr->rr_chan_freq =
1744 htole16(ic->ic_bss->ni_chan->ic_freq);
1745 rr->rr_chan_flags =
1746 htole16(ic->ic_bss->ni_chan->ic_flags);
1747 rr->rr_antsignal = h->rssi;
1748
1749 M_DUP_PKTHDR(&mb, m);
1750 mb.m_data = (caddr_t)rr;
1751 mb.m_len = sizeof(sc->sc_txtapu);
1752 mb.m_next = m;
1753 mb.m_pkthdr.len += mb.m_len;
1754 bpf_mtap(sc->sc_radiobpf, &mb);
1755 }
1756 #endif /* NPBFILTER > 0 */
1757
1758 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1759 /*
1760 * WEP is decrypted by hardware. Clear WEP bit
1761 * header for ieee80211_input().
1762 */
1763 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
1764 }
1765
1766 ieee80211_input(ifp, m, ni, h->rssi, UGETDW(h->rx_time));
1767
1768 ieee80211_release_node(ic, ni);
1769 done1:
1770 splx(s);
1771 done:
1772 /* Setup new transfer. */
1773 usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX], c, c->atu_buf,
1774 ATU_RX_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
1775 atu_rxeof);
1776 usbd_transfer(c->atu_xfer);
1777 }
1778
1779 /*
1780 * A frame was downloaded to the chip. It's safe for us to clean up
1781 * the list buffers.
1782 */
1783 void
atu_txeof(usbd_xfer_handle xfer,usbd_private_handle priv,usbd_status status)1784 atu_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1785 {
1786 struct atu_chain *c = (struct atu_chain *)priv;
1787 struct atu_softc *sc = c->atu_sc;
1788 struct ifnet *ifp = &sc->sc_ic.ic_if;
1789 usbd_status err;
1790 int s;
1791
1792 DPRINTFN(25, ("%s: atu_txeof status=%d\n", USBDEVNAME(sc->atu_dev),
1793 status));
1794
1795 if (c->atu_mbuf != NULL) {
1796 m_freem(c->atu_mbuf);
1797 c->atu_mbuf = NULL;
1798 }
1799
1800 if (status != USBD_NORMAL_COMPLETION) {
1801 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1802 return;
1803
1804 DPRINTF(("%s: usb error on tx: %s\n", USBDEVNAME(sc->atu_dev),
1805 usbd_errstr(status)));
1806 if (status == USBD_STALLED)
1807 usbd_clear_endpoint_stall(sc->atu_ep[ATU_ENDPT_TX]);
1808 return;
1809 }
1810
1811 usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL, &err);
1812
1813 if (err)
1814 ifp->if_oerrors++;
1815 else
1816 ifp->if_opackets++;
1817
1818 s = splnet();
1819 SLIST_INSERT_HEAD(&sc->atu_cdata.atu_tx_free, c, atu_list);
1820 sc->atu_cdata.atu_tx_inuse--;
1821 if (sc->atu_cdata.atu_tx_inuse == 0)
1822 ifp->if_timer = 0;
1823 ifp->if_flags &= ~IFF_OACTIVE;
1824 splx(s);
1825
1826 atu_start(ifp);
1827 }
1828
1829 u_int8_t
atu_calculate_padding(int size)1830 atu_calculate_padding(int size)
1831 {
1832 size %= 64;
1833
1834 if (size < 50)
1835 return (50 - size);
1836 if (size >=61)
1837 return (64 + 50 - size);
1838 return (0);
1839 }
1840
1841 int
atu_tx_start(struct atu_softc * sc,struct ieee80211_node * ni,struct atu_chain * c,struct mbuf * m)1842 atu_tx_start(struct atu_softc *sc, struct ieee80211_node *ni,
1843 struct atu_chain *c, struct mbuf *m)
1844 {
1845 int len;
1846 struct atu_tx_hdr *h;
1847 usbd_status err;
1848 u_int8_t pad;
1849 struct ieee80211com *ic = &sc->sc_ic;
1850
1851 DPRINTFN(25, ("%s: atu_tx_start\n", USBDEVNAME(sc->atu_dev)));
1852
1853 /* Don't try to send when we're shutting down the driver */
1854 if (sc->sc_state != ATU_S_OK) {
1855 m_freem(m);
1856 return(EIO);
1857 }
1858
1859 #if NBPFILTER > 0
1860 if (sc->sc_radiobpf != NULL) {
1861 struct mbuf mb;
1862 struct atu_tx_radiotap_header *rt = &sc->sc_txtap;
1863
1864 rt->rt_flags = 0;
1865 rt->rt_chan_freq =
1866 htole16(ic->ic_bss->ni_chan->ic_freq);
1867 rt->rt_chan_flags =
1868 htole16(ic->ic_bss->ni_chan->ic_flags);
1869
1870 M_DUP_PKTHDR(&mb, m);
1871 mb.m_data = (caddr_t)rt;
1872 mb.m_len = sizeof(sc->sc_txtapu);
1873 mb.m_next = m;
1874 mb.m_pkthdr.len += mb.m_len;
1875 bpf_mtap(sc->sc_radiobpf, &mb);
1876 }
1877 #endif
1878
1879 /*
1880 * Copy the mbuf data into a contiguous buffer, leaving
1881 * enough room for the atmel headers
1882 */
1883 len = m->m_pkthdr.len;
1884
1885 m_copydata(m, 0, m->m_pkthdr.len, c->atu_buf + ATU_TX_HDRLEN);
1886
1887 h = (struct atu_tx_hdr *)c->atu_buf;
1888 memset(h, 0, ATU_TX_HDRLEN);
1889 USETW(h->length, len);
1890 h->tx_rate = 4; /* XXX rate = auto */
1891 len += ATU_TX_HDRLEN;
1892
1893 pad = atu_calculate_padding(len);
1894 len += pad;
1895 h->padding = pad;
1896
1897 c->atu_length = len;
1898 c->atu_mbuf = m;
1899
1900 usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_TX],
1901 c, c->atu_buf, c->atu_length, USBD_NO_COPY, ATU_TX_TIMEOUT,
1902 atu_txeof);
1903
1904 /* Let's get this thing into the air! */
1905 c->atu_in_xfer = 1;
1906 err = usbd_transfer(c->atu_xfer);
1907 if (err != USBD_IN_PROGRESS) {
1908 DPRINTFN(25, ("%s: atu_tx_start: err=%d\n",
1909 USBDEVNAME(sc->atu_dev), err));
1910 c->atu_mbuf = NULL;
1911 m_freem(m);
1912 return(EIO);
1913 }
1914
1915 return (0);
1916 }
1917
1918 void
atu_start(struct ifnet * ifp)1919 atu_start(struct ifnet *ifp)
1920 {
1921 struct atu_softc *sc = ifp->if_softc;
1922 struct ieee80211com *ic = &sc->sc_ic;
1923 struct atu_cdata *cd = &sc->atu_cdata;
1924 struct ieee80211_node *ni;
1925 struct ieee80211_frame *wh;
1926 struct atu_chain *c;
1927 struct mbuf *m = NULL;
1928 int s;
1929
1930 DPRINTFN(25, ("%s: atu_start: enter\n", USBDEVNAME(sc->atu_dev)));
1931
1932 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) {
1933 DPRINTFN(30, ("%s: atu_start: not running or up\n",
1934 USBDEVNAME(sc->atu_dev)));
1935 return;
1936 }
1937
1938 if (ifp->if_flags & IFF_OACTIVE) {
1939 DPRINTFN(30, ("%s: atu_start: IFF_OACTIVE\n",
1940 USBDEVNAME(sc->atu_dev)));
1941 return;
1942 }
1943
1944 for (;;) {
1945 /* grab a TX buffer */
1946 s = splnet();
1947 c = SLIST_FIRST(&cd->atu_tx_free);
1948 if (c != NULL) {
1949 SLIST_REMOVE_HEAD(&cd->atu_tx_free, atu_list);
1950 cd->atu_tx_inuse++;
1951 if (cd->atu_tx_inuse == ATU_TX_LIST_CNT)
1952 ifp->if_flags |= IFF_OACTIVE;
1953 }
1954 splx(s);
1955 if (c == NULL) {
1956 DPRINTFN(10, ("%s: out of tx xfers\n",
1957 USBDEVNAME(sc->atu_dev)));
1958 ifp->if_flags |= IFF_OACTIVE;
1959 break;
1960 }
1961
1962 /*
1963 * Poll the management queue for frames, it has priority over
1964 * normal data frames.
1965 */
1966 IF_DEQUEUE(&ic->ic_mgtq, m);
1967 if (m == NULL) {
1968 DPRINTFN(10, ("%s: atu_start: data packet\n",
1969 USBDEVNAME(sc->atu_dev)));
1970 if (ic->ic_state != IEEE80211_S_RUN) {
1971 DPRINTFN(25, ("%s: no data till running\n",
1972 USBDEVNAME(sc->atu_dev)));
1973 /* put the xfer back on the list */
1974 s = splnet();
1975 SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
1976 atu_list);
1977 cd->atu_tx_inuse--;
1978 splx(s);
1979 break;
1980 }
1981
1982 IFQ_DEQUEUE(&ifp->if_snd, m);
1983 if (m == NULL) {
1984 DPRINTFN(25, ("%s: nothing to send\n",
1985 USBDEVNAME(sc->atu_dev)));
1986 s = splnet();
1987 SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
1988 atu_list);
1989 cd->atu_tx_inuse--;
1990 splx(s);
1991 break;
1992 }
1993
1994 #if NBPFILTER > 0
1995 if (ifp->if_bpf)
1996 bpf_mtap(ifp->if_bpf, m);
1997 #endif
1998
1999 m = ieee80211_encap(ifp, m, &ni);
2000 if (m == NULL)
2001 goto bad;
2002 wh = mtod(m, struct ieee80211_frame *);
2003
2004 #if NBPFILTER > 0
2005 if (ic->ic_rawbpf != NULL)
2006 bpf_mtap(ic->ic_rawbpf, m);
2007 #endif
2008 } else {
2009 DPRINTFN(25, ("%s: atu_start: mgmt packet\n",
2010 USBDEVNAME(sc->atu_dev)));
2011
2012 /*
2013 * Hack! The referenced node pointer is in the
2014 * rcvif field of the packet header. This is
2015 * placed there by ieee80211_mgmt_output because
2016 * we need to hold the reference with the frame
2017 * and there's no other way (other than packet
2018 * tags which we consider too expensive to use)
2019 * to pass it along.
2020 */
2021 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
2022 m->m_pkthdr.rcvif = NULL;
2023
2024 wh = mtod(m, struct ieee80211_frame *);
2025 /* sc->sc_stats.ast_tx_mgmt++; */
2026 }
2027
2028 if (atu_tx_start(sc, ni, c, m)) {
2029 bad:
2030 s = splnet();
2031 SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
2032 atu_list);
2033 cd->atu_tx_inuse--;
2034 splx(s);
2035 /* ifp_if_oerrors++; */
2036 if (ni != NULL)
2037 ieee80211_release_node(ic, ni);
2038 continue;
2039 }
2040 ifp->if_timer = 5;
2041 }
2042 }
2043
2044 int
atu_init(struct ifnet * ifp)2045 atu_init(struct ifnet *ifp)
2046 {
2047 struct atu_softc *sc = ifp->if_softc;
2048 struct ieee80211com *ic = &sc->sc_ic;
2049 struct atu_chain *c;
2050 usbd_status err;
2051 int i, s;
2052
2053 s = splnet();
2054
2055 DPRINTFN(10, ("%s: atu_init\n", USBDEVNAME(sc->atu_dev)));
2056
2057 if (ifp->if_flags & IFF_RUNNING) {
2058 splx(s);
2059 return(0);
2060 }
2061
2062 /* Init TX ring */
2063 if (atu_tx_list_init(sc))
2064 printf("%s: tx list init failed\n", USBDEVNAME(sc->atu_dev));
2065
2066 /* Init RX ring */
2067 if (atu_rx_list_init(sc))
2068 printf("%s: rx list init failed\n", USBDEVNAME(sc->atu_dev));
2069
2070 /* Load the multicast filter. */
2071 /*atu_setmulti(sc); */
2072
2073 /* Open RX and TX pipes. */
2074 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_RX],
2075 USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_RX]);
2076 if (err) {
2077 DPRINTF(("%s: open rx pipe failed: %s\n",
2078 USBDEVNAME(sc->atu_dev), usbd_errstr(err)));
2079 splx(s);
2080 return(EIO);
2081 }
2082
2083 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_TX],
2084 USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_TX]);
2085 if (err) {
2086 DPRINTF(("%s: open tx pipe failed: %s\n",
2087 USBDEVNAME(sc->atu_dev), usbd_errstr(err)));
2088 splx(s);
2089 return(EIO);
2090 }
2091
2092 /* Start up the receive pipe. */
2093 for (i = 0; i < ATU_RX_LIST_CNT; i++) {
2094 c = &sc->atu_cdata.atu_rx_chain[i];
2095
2096 usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX], c,
2097 c->atu_buf, ATU_RX_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
2098 USBD_NO_TIMEOUT, atu_rxeof);
2099 usbd_transfer(c->atu_xfer);
2100 }
2101
2102 DPRINTFN(10, ("%s: starting up using MAC=%s\n",
2103 USBDEVNAME(sc->atu_dev), ether_sprintf(ic->ic_myaddr)));
2104
2105 /* Do initial setup */
2106 err = atu_initial_config(sc);
2107 if (err) {
2108 DPRINTF(("%s: initial config failed!\n",
2109 USBDEVNAME(sc->atu_dev)));
2110 splx(s);
2111 return(EIO);
2112 }
2113 DPRINTFN(10, ("%s: initialised transceiver\n",
2114 USBDEVNAME(sc->atu_dev)));
2115
2116 /* sc->atu_rxfilt = ATU_RXFILT_UNICAST|ATU_RXFILT_BROADCAST; */
2117
2118 /* If we want promiscuous mode, set the allframes bit. */
2119 /*
2120 if (ifp->if_flags & IFF_PROMISC)
2121 sc->atu_rxfilt |= ATU_RXFILT_PROMISC;
2122 */
2123
2124 ifp->if_flags |= IFF_RUNNING;
2125 ifp->if_flags &= ~IFF_OACTIVE;
2126 splx(s);
2127
2128 /* XXX the following HAS to be replaced */
2129 s = splnet();
2130 err = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2131 if (err)
2132 DPRINTFN(1, ("%s: atu_init: error calling "
2133 "ieee80211_net_state", USBDEVNAME(sc->atu_dev)));
2134 splx(s);
2135
2136 return 0;
2137 }
2138
2139 #ifdef ATU_DEBUG
2140 void
atu_print_a_bunch_of_debug_things(struct atu_softc * sc)2141 atu_print_a_bunch_of_debug_things(struct atu_softc *sc)
2142 {
2143 usbd_status err;
2144 u_int8_t tmp[32];
2145
2146 /* DEBUG */
2147 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_BSSID, tmp)))
2148 return;
2149 DPRINTF(("%s: DEBUG: current BSSID=%s\n", USBDEVNAME(sc->atu_dev),
2150 ether_sprintf(tmp)));
2151
2152 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__BEACON_PERIOD, tmp)))
2153 return;
2154 DPRINTF(("%s: DEBUG: beacon period=%d\n", USBDEVNAME(sc->atu_dev),
2155 tmp[0]));
2156
2157 if ((err = atu_get_mib(sc, MIB_MAC_WEP__PRIVACY_INVOKED, tmp)))
2158 return;
2159 DPRINTF(("%s: DEBUG: privacy invoked=%d\n", USBDEVNAME(sc->atu_dev),
2160 tmp[0]));
2161
2162 if ((err = atu_get_mib(sc, MIB_MAC_WEP__ENCR_LEVEL, tmp)))
2163 return;
2164 DPRINTF(("%s: DEBUG: encr_level=%d\n", USBDEVNAME(sc->atu_dev),
2165 tmp[0]));
2166
2167 if ((err = atu_get_mib(sc, MIB_MAC_WEP__ICV_ERROR_COUNT, tmp)))
2168 return;
2169 DPRINTF(("%s: DEBUG: icv error count=%d\n", USBDEVNAME(sc->atu_dev),
2170 *(short *)tmp));
2171
2172 if ((err = atu_get_mib(sc, MIB_MAC_WEP__EXCLUDED_COUNT, tmp)))
2173 return;
2174 DPRINTF(("%s: DEBUG: wep excluded count=%d\n",
2175 USBDEVNAME(sc->atu_dev), *(short *)tmp));
2176
2177 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__POWER_MODE, tmp)))
2178 return;
2179 DPRINTF(("%s: DEBUG: power mode=%d\n", USBDEVNAME(sc->atu_dev),
2180 tmp[0]));
2181
2182 if ((err = atu_get_mib(sc, MIB_PHY__CHANNEL, tmp)))
2183 return;
2184 DPRINTF(("%s: DEBUG: channel=%d\n", USBDEVNAME(sc->atu_dev), tmp[0]));
2185
2186 if ((err = atu_get_mib(sc, MIB_PHY__REG_DOMAIN, tmp)))
2187 return;
2188 DPRINTF(("%s: DEBUG: reg domain=%d\n", USBDEVNAME(sc->atu_dev),
2189 tmp[0]));
2190
2191 if ((err = atu_get_mib(sc, MIB_LOCAL__SSID_SIZE, tmp)))
2192 return;
2193 DPRINTF(("%s: DEBUG: ssid size=%d\n", USBDEVNAME(sc->atu_dev),
2194 tmp[0]));
2195
2196 if ((err = atu_get_mib(sc, MIB_LOCAL__BEACON_ENABLE, tmp)))
2197 return;
2198 DPRINTF(("%s: DEBUG: beacon enable=%d\n", USBDEVNAME(sc->atu_dev),
2199 tmp[0]));
2200
2201 if ((err = atu_get_mib(sc, MIB_LOCAL__AUTO_RATE_FALLBACK, tmp)))
2202 return;
2203 DPRINTF(("%s: DEBUG: auto rate fallback=%d\n",
2204 USBDEVNAME(sc->atu_dev), tmp[0]));
2205
2206 if ((err = atu_get_mib(sc, MIB_MAC_ADDR__ADDR, tmp)))
2207 return;
2208 DPRINTF(("%s: DEBUG: mac addr=%s\n", USBDEVNAME(sc->atu_dev),
2209 ether_sprintf(tmp)));
2210
2211 if ((err = atu_get_mib(sc, MIB_MAC__DESIRED_SSID, tmp)))
2212 return;
2213 DPRINTF(("%s: DEBUG: desired ssid=%s\n", USBDEVNAME(sc->atu_dev),
2214 tmp));
2215
2216 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_ESSID, tmp)))
2217 return;
2218 DPRINTF(("%s: DEBUG: current ESSID=%s\n", USBDEVNAME(sc->atu_dev),
2219 tmp));
2220 }
2221 #endif /* ATU_DEBUG */
2222
2223 int
atu_ioctl(struct ifnet * ifp,u_long command,caddr_t data)2224 atu_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
2225 {
2226 struct atu_softc *sc = ifp->if_softc;
2227 struct ifaddr *ifa;
2228 int err = 0, s;
2229
2230 s = splnet();
2231 switch (command) {
2232 case SIOCSIFADDR:
2233 DPRINTFN(15, ("%s: SIOCSIFADDR\n", USBDEVNAME(sc->atu_dev)));
2234
2235 ifa = (struct ifaddr *)data;
2236 ifp->if_flags |= IFF_UP;
2237 atu_init(ifp);
2238
2239 switch (ifa->ifa_addr->sa_family) {
2240 #ifdef INET
2241 case AF_INET:
2242 arp_ifinit(&sc->sc_ic.ic_ac, ifa);
2243 break;
2244 #endif /* INET */
2245 }
2246 break;
2247
2248 case SIOCSIFFLAGS:
2249 DPRINTFN(15, ("%s: SIOCSIFFLAGS\n", USBDEVNAME(sc->atu_dev)));
2250
2251 if (ifp->if_flags & IFF_UP) {
2252 if (ifp->if_flags & IFF_RUNNING &&
2253 ifp->if_flags & IFF_PROMISC &&
2254 !(sc->atu_if_flags & IFF_PROMISC)) {
2255 /* enable promisc */
2256 #if 0
2257 sc->atu_rxfilt |= ATU_RXFILT_PROMISC;
2258 atu_setword(sc, ATU_CMD_SET_PKT_FILTER,
2259 sc->atu_rxfilt);
2260 #endif
2261 } else if (ifp->if_flags & IFF_RUNNING &&
2262 !(ifp->if_flags & IFF_PROMISC) &&
2263 sc->atu_if_flags & IFF_PROMISC) {
2264 /* disable promisc */
2265 #if 0
2266 sc->atu_rxfilt &= ~ATU_RXFILT_PROMISC;
2267 atu_setword(sc, ATU_CMD_SET_PKT_FILTER,
2268 sc->atu_rxfilt);
2269 #endif
2270 } else if (!(ifp->if_flags & IFF_RUNNING))
2271 atu_init(ifp);
2272
2273 DPRINTFN(15, ("%s: ioctl calling atu_init()\n",
2274 USBDEVNAME(sc->atu_dev)));
2275 atu_init(ifp);
2276 err = atu_switch_radio(sc, 1);
2277 } else {
2278 if (ifp->if_flags & IFF_RUNNING)
2279 atu_stop(ifp, 0);
2280 err = atu_switch_radio(sc, 0);
2281 }
2282 sc->atu_if_flags = ifp->if_flags;
2283 err = 0;
2284 break;
2285
2286 case SIOCADDMULTI:
2287 DPRINTFN(15, ("%s: SIOCADDMULTI\n", USBDEVNAME(sc->atu_dev)));
2288 /* TODO: implement */
2289 err = 0;
2290 break;
2291
2292 case SIOCDELMULTI:
2293 DPRINTFN(15, ("%s: SIOCDELMULTI\n", USBDEVNAME(sc->atu_dev)));
2294 /* TODO: implement */
2295 err = 0;
2296 break;
2297
2298 default:
2299 DPRINTFN(15, ("%s: ieee80211_ioctl (%lu)\n",
2300 USBDEVNAME(sc->atu_dev), command));
2301 err = ieee80211_ioctl(ifp, command, data);
2302 break;
2303 }
2304
2305 if (err == ENETRESET) {
2306 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
2307 (IFF_RUNNING|IFF_UP)) {
2308 DPRINTF(("%s: atu_ioctl(): netreset\n",
2309 USBDEVNAME(sc->atu_dev)));
2310 atu_init(ifp);
2311 }
2312 err = 0;
2313 }
2314
2315 splx(s);
2316 return (err);
2317 }
2318
2319 void
atu_watchdog(struct ifnet * ifp)2320 atu_watchdog(struct ifnet *ifp)
2321 {
2322 struct atu_softc *sc = ifp->if_softc;
2323 struct atu_chain *c;
2324 usbd_status stat;
2325 int cnt, s;
2326
2327 DPRINTF(("%s: atu_watchdog\n", USBDEVNAME(sc->atu_dev)));
2328
2329 ifp->if_timer = 0;
2330
2331 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP))
2332 return;
2333
2334 if (sc->sc_state != ATU_S_OK)
2335 return;
2336
2337 sc = ifp->if_softc;
2338 s = splnet();
2339 ifp->if_oerrors++;
2340 DPRINTF(("%s: watchdog timeout\n", USBDEVNAME(sc->atu_dev)));
2341
2342 /*
2343 * TODO:
2344 * we should change this since we have multiple TX tranfers...
2345 */
2346 for (cnt = 0; cnt < ATU_TX_LIST_CNT; cnt++) {
2347 c = &sc->atu_cdata.atu_tx_chain[cnt];
2348 if (c->atu_in_xfer) {
2349 usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL,
2350 &stat);
2351 atu_txeof(c->atu_xfer, c, stat);
2352 }
2353 }
2354
2355 if (!IFQ_IS_EMPTY(&ifp->if_snd))
2356 atu_start(ifp);
2357 splx(s);
2358
2359 ieee80211_watchdog(ifp);
2360 }
2361
2362 /*
2363 * Stop the adapter and free any mbufs allocated to the
2364 * RX and TX lists.
2365 */
2366 void
atu_stop(struct ifnet * ifp,int disable)2367 atu_stop(struct ifnet *ifp, int disable)
2368 {
2369 struct atu_softc *sc = ifp->if_softc;
2370 struct atu_cdata *cd;
2371 usbd_status err;
2372 int s;
2373
2374 s = splnet();
2375 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2376 ifp->if_timer = 0;
2377
2378 /* Stop transfers. */
2379 if (sc->atu_ep[ATU_ENDPT_RX] != NULL) {
2380 err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]);
2381 if (err) {
2382 DPRINTF(("%s: abort rx pipe failed: %s\n",
2383 USBDEVNAME(sc->atu_dev), usbd_errstr(err)));
2384 }
2385 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_RX]);
2386 if (err) {
2387 DPRINTF(("%s: close rx pipe failed: %s\n",
2388 USBDEVNAME(sc->atu_dev), usbd_errstr(err)));
2389 }
2390 sc->atu_ep[ATU_ENDPT_RX] = NULL;
2391 }
2392
2393 if (sc->atu_ep[ATU_ENDPT_TX] != NULL) {
2394 err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]);
2395 if (err) {
2396 DPRINTF(("%s: abort tx pipe failed: %s\n",
2397 USBDEVNAME(sc->atu_dev), usbd_errstr(err)));
2398 }
2399 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_TX]);
2400 if (err) {
2401 DPRINTF(("%s: close tx pipe failed: %s\n",
2402 USBDEVNAME(sc->atu_dev), usbd_errstr(err)));
2403 }
2404 sc->atu_ep[ATU_ENDPT_TX] = NULL;
2405 }
2406
2407 /* Free RX/TX/MGMT list resources. */
2408 cd = &sc->atu_cdata;
2409 atu_xfer_list_free(sc, cd->atu_rx_chain, ATU_RX_LIST_CNT);
2410 atu_xfer_list_free(sc, cd->atu_tx_chain, ATU_TX_LIST_CNT);
2411
2412 /* Let's be nice and turn off the radio before we leave */
2413 atu_switch_radio(sc, 0);
2414
2415 splx(s);
2416 }
2417