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