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