1 /* $OpenBSD: if_athn_usb.c,v 1.65 2022/07/10 21:13:41 bluhm Exp $ */
2
3 /*-
4 * Copyright (c) 2011 Damien Bergamini <damien.bergamini@free.fr>
5 * Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /*
21 * USB front-end for Atheros AR9271 and AR7010 chipsets.
22 */
23
24 #include "bpfilter.h"
25
26 #include <sys/param.h>
27 #include <sys/sockio.h>
28 #include <sys/mbuf.h>
29 #include <sys/kernel.h>
30 #include <sys/socket.h>
31 #include <sys/systm.h>
32 #include <sys/timeout.h>
33 #include <sys/conf.h>
34 #include <sys/device.h>
35 #include <sys/endian.h>
36
37 #include <machine/bus.h>
38 #include <machine/intr.h>
39
40 #if NBPFILTER > 0
41 #include <net/bpf.h>
42 #endif
43 #include <net/if.h>
44 #include <net/if_dl.h>
45 #include <net/if_media.h>
46
47 #include <netinet/in.h>
48 #include <netinet/if_ether.h>
49
50 #include <net80211/ieee80211_var.h>
51 #include <net80211/ieee80211_amrr.h>
52 #include <net80211/ieee80211_ra.h>
53 #include <net80211/ieee80211_radiotap.h>
54
55 #include <dev/ic/athnreg.h>
56 #include <dev/ic/ar5008reg.h>
57 #include <dev/ic/athnvar.h>
58
59 #include <dev/usb/usb.h>
60 #include <dev/usb/usbdi.h>
61 #include <dev/usb/usbdi_util.h>
62 #include <dev/usb/usbdevs.h>
63
64 #include <dev/usb/if_athn_usb.h>
65
66 static const struct athn_usb_type {
67 struct usb_devno devno;
68 u_int flags;
69 } athn_usb_devs[] = {
70 {{ USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_AR9280 },
71 ATHN_USB_FLAG_AR7010 },
72 {{ USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_AR9287 },
73 ATHN_USB_FLAG_AR7010 },
74 {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_1 }},
75 {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_2 }},
76 {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_3 }},
77 {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9280 },
78 ATHN_USB_FLAG_AR7010 },
79 {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9287 },
80 ATHN_USB_FLAG_AR7010 },
81 {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_1 }},
82 {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_2 }},
83 {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_3 }},
84 {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_4 }},
85 {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_5 }},
86 {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_6 }},
87 {{ USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_AR9271 }},
88 {{ USB_VENDOR_LITEON, USB_PRODUCT_LITEON_AR9271 }},
89 {{ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1100 }},
90 {{ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNDA3200 },
91 ATHN_USB_FLAG_AR7010 },
92 {{ USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_N5HBZ0000055 },
93 ATHN_USB_FLAG_AR7010 },
94 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_UWABR100 },
95 ATHN_USB_FLAG_AR7010 },
96 {{ USB_VENDOR_VIA, USB_PRODUCT_VIA_AR9271 }}
97 };
98 #define athn_usb_lookup(v, p) \
99 ((const struct athn_usb_type *)usb_lookup(athn_usb_devs, v, p))
100
101 int athn_usb_match(struct device *, void *, void *);
102 void athn_usb_attach(struct device *, struct device *, void *);
103 int athn_usb_detach(struct device *, int);
104 void athn_usb_attachhook(struct device *);
105 int athn_usb_open_pipes(struct athn_usb_softc *);
106 void athn_usb_close_pipes(struct athn_usb_softc *);
107 int athn_usb_alloc_rx_list(struct athn_usb_softc *);
108 void athn_usb_free_rx_list(struct athn_usb_softc *);
109 int athn_usb_alloc_tx_list(struct athn_usb_softc *);
110 void athn_usb_free_tx_list(struct athn_usb_softc *);
111 int athn_usb_alloc_tx_cmd(struct athn_usb_softc *);
112 void athn_usb_free_tx_cmd(struct athn_usb_softc *);
113 void athn_usb_task(void *);
114 void athn_usb_do_async(struct athn_usb_softc *,
115 void (*)(struct athn_usb_softc *, void *), void *, int);
116 void athn_usb_wait_async(struct athn_usb_softc *);
117 int athn_usb_load_firmware(struct athn_usb_softc *);
118 int athn_usb_htc_msg(struct athn_usb_softc *, uint16_t, void *,
119 int);
120 int athn_usb_htc_setup(struct athn_usb_softc *);
121 int athn_usb_htc_connect_svc(struct athn_usb_softc *, uint16_t,
122 uint8_t, uint8_t, uint8_t *);
123 int athn_usb_wmi_xcmd(struct athn_usb_softc *, uint16_t, void *,
124 int, void *);
125 int athn_usb_read_rom(struct athn_softc *);
126 uint32_t athn_usb_read(struct athn_softc *, uint32_t);
127 void athn_usb_write(struct athn_softc *, uint32_t, uint32_t);
128 void athn_usb_write_barrier(struct athn_softc *);
129 int athn_usb_media_change(struct ifnet *);
130 void athn_usb_next_scan(void *);
131 int athn_usb_newstate(struct ieee80211com *, enum ieee80211_state,
132 int);
133 void athn_usb_newstate_cb(struct athn_usb_softc *, void *);
134 void athn_usb_newassoc(struct ieee80211com *,
135 struct ieee80211_node *, int);
136 void athn_usb_newassoc_cb(struct athn_usb_softc *, void *);
137 struct ieee80211_node *athn_usb_node_alloc(struct ieee80211com *);
138 void athn_usb_count_active_sta(void *, struct ieee80211_node *);
139 void athn_usb_newauth_cb(struct athn_usb_softc *, void *);
140 int athn_usb_newauth(struct ieee80211com *,
141 struct ieee80211_node *, int, uint16_t);
142 void athn_usb_node_free(struct ieee80211com *,
143 struct ieee80211_node *);
144 void athn_usb_node_free_cb(struct athn_usb_softc *, void *);
145 int athn_usb_ampdu_tx_start(struct ieee80211com *,
146 struct ieee80211_node *, uint8_t);
147 void athn_usb_ampdu_tx_start_cb(struct athn_usb_softc *, void *);
148 void athn_usb_ampdu_tx_stop(struct ieee80211com *,
149 struct ieee80211_node *, uint8_t);
150 void athn_usb_ampdu_tx_stop_cb(struct athn_usb_softc *, void *);
151 void athn_usb_clean_nodes(void *, struct ieee80211_node *);
152 int athn_usb_create_node(struct athn_usb_softc *,
153 struct ieee80211_node *);
154 int athn_usb_node_set_rates(struct athn_usb_softc *,
155 struct ieee80211_node *);
156 int athn_usb_remove_node(struct athn_usb_softc *,
157 struct ieee80211_node *);
158 void athn_usb_rx_enable(struct athn_softc *);
159 int athn_set_chan(struct athn_softc *, struct ieee80211_channel *,
160 struct ieee80211_channel *);
161 int athn_usb_switch_chan(struct athn_softc *,
162 struct ieee80211_channel *, struct ieee80211_channel *);
163 void athn_usb_updateedca(struct ieee80211com *);
164 void athn_usb_updateedca_cb(struct athn_usb_softc *, void *);
165 void athn_usb_updateslot(struct ieee80211com *);
166 void athn_usb_updateslot_cb(struct athn_usb_softc *, void *);
167 int athn_usb_set_key(struct ieee80211com *,
168 struct ieee80211_node *, struct ieee80211_key *);
169 void athn_usb_set_key_cb(struct athn_usb_softc *, void *);
170 void athn_usb_delete_key(struct ieee80211com *,
171 struct ieee80211_node *, struct ieee80211_key *);
172 void athn_usb_delete_key_cb(struct athn_usb_softc *, void *);
173 void athn_usb_bcneof(struct usbd_xfer *, void *,
174 usbd_status);
175 void athn_usb_swba(struct athn_usb_softc *);
176 void athn_usb_tx_status(void *, struct ieee80211_node *);
177 void athn_usb_rx_wmi_ctrl(struct athn_usb_softc *, uint8_t *, int);
178 void athn_usb_intr(struct usbd_xfer *, void *,
179 usbd_status);
180 void athn_usb_rx_radiotap(struct athn_softc *, struct mbuf *,
181 struct ar_rx_status *);
182 void athn_usb_rx_frame(struct athn_usb_softc *, struct mbuf *,
183 struct mbuf_list *);
184 void athn_usb_rxeof(struct usbd_xfer *, void *,
185 usbd_status);
186 void athn_usb_txeof(struct usbd_xfer *, void *,
187 usbd_status);
188 int athn_usb_tx(struct athn_softc *, struct mbuf *,
189 struct ieee80211_node *);
190 void athn_usb_start(struct ifnet *);
191 void athn_usb_watchdog(struct ifnet *);
192 int athn_usb_ioctl(struct ifnet *, u_long, caddr_t);
193 int athn_usb_init(struct ifnet *);
194 void athn_usb_stop(struct ifnet *);
195 void ar9271_load_ani(struct athn_softc *);
196 int ar5008_ccmp_decap(struct athn_softc *, struct mbuf *,
197 struct ieee80211_node *);
198 int ar5008_ccmp_encap(struct mbuf *, u_int, struct ieee80211_key *);
199
200 /* Shortcut. */
201 #define athn_usb_wmi_cmd(sc, cmd_id) \
202 athn_usb_wmi_xcmd(sc, cmd_id, NULL, 0, NULL)
203
204 /* Extern functions. */
205 void athn_led_init(struct athn_softc *);
206 void athn_set_led(struct athn_softc *, int);
207 void athn_btcoex_init(struct athn_softc *);
208 void athn_set_rxfilter(struct athn_softc *, uint32_t);
209 int athn_reset(struct athn_softc *, int);
210 void athn_init_pll(struct athn_softc *,
211 const struct ieee80211_channel *);
212 int athn_set_power_awake(struct athn_softc *);
213 void athn_set_power_sleep(struct athn_softc *);
214 void athn_reset_key(struct athn_softc *, int);
215 int athn_set_key(struct ieee80211com *, struct ieee80211_node *,
216 struct ieee80211_key *);
217 void athn_delete_key(struct ieee80211com *, struct ieee80211_node *,
218 struct ieee80211_key *);
219 void athn_rx_start(struct athn_softc *);
220 void athn_set_sta_timers(struct athn_softc *);
221 void athn_set_hostap_timers(struct athn_softc *);
222 void athn_set_opmode(struct athn_softc *);
223 void athn_set_bss(struct athn_softc *, struct ieee80211_node *);
224 int athn_hw_reset(struct athn_softc *, struct ieee80211_channel *,
225 struct ieee80211_channel *, int);
226 void athn_updateedca(struct ieee80211com *);
227 void athn_updateslot(struct ieee80211com *);
228
229 const struct cfattach athn_usb_ca = {
230 sizeof(struct athn_usb_softc),
231 athn_usb_match,
232 athn_usb_attach,
233 athn_usb_detach
234 };
235
236 int
athn_usb_match(struct device * parent,void * match,void * aux)237 athn_usb_match(struct device *parent, void *match, void *aux)
238 {
239 struct usb_attach_arg *uaa = aux;
240
241 if (uaa->iface == NULL || uaa->configno != 1)
242 return (UMATCH_NONE);
243
244 return ((athn_usb_lookup(uaa->vendor, uaa->product) != NULL) ?
245 UMATCH_VENDOR_PRODUCT_CONF_IFACE : UMATCH_NONE);
246 }
247
248 void
athn_usb_attach(struct device * parent,struct device * self,void * aux)249 athn_usb_attach(struct device *parent, struct device *self, void *aux)
250 {
251 struct athn_usb_softc *usc = (struct athn_usb_softc *)self;
252 struct athn_softc *sc = &usc->sc_sc;
253 struct usb_attach_arg *uaa = aux;
254
255 usc->sc_udev = uaa->device;
256 usc->sc_iface = uaa->iface;
257
258 usc->flags = athn_usb_lookup(uaa->vendor, uaa->product)->flags;
259 sc->flags |= ATHN_FLAG_USB;
260 #ifdef notyet
261 /* Check if it is a combo WiFi+Bluetooth (WB193) device. */
262 if (strncmp(product, "wb193", 5) == 0)
263 sc->flags |= ATHN_FLAG_BTCOEX3WIRE;
264 #endif
265
266 sc->ops.read = athn_usb_read;
267 sc->ops.write = athn_usb_write;
268 sc->ops.write_barrier = athn_usb_write_barrier;
269
270 usb_init_task(&usc->sc_task, athn_usb_task, sc, USB_TASK_TYPE_GENERIC);
271
272 if (athn_usb_open_pipes(usc) != 0)
273 return;
274
275 /* Allocate xfer for firmware commands. */
276 if (athn_usb_alloc_tx_cmd(usc) != 0)
277 return;
278
279 config_mountroot(self, athn_usb_attachhook);
280 }
281
282 int
athn_usb_detach(struct device * self,int flags)283 athn_usb_detach(struct device *self, int flags)
284 {
285 struct athn_usb_softc *usc = (struct athn_usb_softc *)self;
286 struct athn_softc *sc = &usc->sc_sc;
287
288 if (usc->sc_athn_attached)
289 athn_detach(sc);
290
291 /* Wait for all async commands to complete. */
292 athn_usb_wait_async(usc);
293
294 usbd_ref_wait(usc->sc_udev);
295
296 /* Abort and close Tx/Rx pipes. */
297 athn_usb_close_pipes(usc);
298
299 /* Free Tx/Rx buffers. */
300 athn_usb_free_tx_cmd(usc);
301 athn_usb_free_tx_list(usc);
302 athn_usb_free_rx_list(usc);
303
304 return (0);
305 }
306
307 void
athn_usb_attachhook(struct device * self)308 athn_usb_attachhook(struct device *self)
309 {
310 struct athn_usb_softc *usc = (struct athn_usb_softc *)self;
311 struct athn_softc *sc = &usc->sc_sc;
312 struct athn_ops *ops = &sc->ops;
313 struct ieee80211com *ic = &sc->sc_ic;
314 struct ifnet *ifp = &ic->ic_if;
315 int s, i, error;
316
317 /* Load firmware. */
318 error = athn_usb_load_firmware(usc);
319 if (error != 0) {
320 printf("%s: could not load firmware\n", sc->sc_dev.dv_xname);
321 return;
322 }
323
324 /* Setup the host transport communication interface. */
325 error = athn_usb_htc_setup(usc);
326 if (error != 0)
327 return;
328
329 /* We're now ready to attach the bus agnostic driver. */
330 s = splnet();
331 error = athn_attach(sc);
332 if (error != 0) {
333 splx(s);
334 return;
335 }
336 usc->sc_athn_attached = 1;
337 /* Override some operations for USB. */
338 ifp->if_ioctl = athn_usb_ioctl;
339 ifp->if_start = athn_usb_start;
340 ifp->if_watchdog = athn_usb_watchdog;
341 ic->ic_node_alloc = athn_usb_node_alloc;
342 ic->ic_newauth = athn_usb_newauth;
343 ic->ic_newassoc = athn_usb_newassoc;
344 #ifndef IEEE80211_STA_ONLY
345 usc->sc_node_free = ic->ic_node_free;
346 ic->ic_node_free = athn_usb_node_free;
347 #endif
348 ic->ic_updateslot = athn_usb_updateslot;
349 ic->ic_updateedca = athn_usb_updateedca;
350 ic->ic_set_key = athn_usb_set_key;
351 ic->ic_delete_key = athn_usb_delete_key;
352 #ifdef notyet
353 ic->ic_ampdu_tx_start = athn_usb_ampdu_tx_start;
354 ic->ic_ampdu_tx_stop = athn_usb_ampdu_tx_stop;
355 #endif
356 ic->ic_newstate = athn_usb_newstate;
357 ic->ic_media.ifm_change_cb = athn_usb_media_change;
358 timeout_set(&sc->scan_to, athn_usb_next_scan, usc);
359
360 ops->rx_enable = athn_usb_rx_enable;
361 splx(s);
362
363 /* Reset HW key cache entries. */
364 for (i = 0; i < sc->kc_entries; i++)
365 athn_reset_key(sc, i);
366
367 ops->enable_antenna_diversity(sc);
368
369 #ifdef ATHN_BT_COEXISTENCE
370 /* Configure bluetooth coexistence for combo chips. */
371 if (sc->flags & ATHN_FLAG_BTCOEX)
372 athn_btcoex_init(sc);
373 #endif
374 /* Configure LED. */
375 athn_led_init(sc);
376 }
377
378 int
athn_usb_open_pipes(struct athn_usb_softc * usc)379 athn_usb_open_pipes(struct athn_usb_softc *usc)
380 {
381 usb_endpoint_descriptor_t *ed;
382 int isize, error;
383
384 error = usbd_open_pipe(usc->sc_iface, AR_PIPE_TX_DATA, 0,
385 &usc->tx_data_pipe);
386 if (error != 0) {
387 printf("%s: could not open Tx bulk pipe\n",
388 usc->usb_dev.dv_xname);
389 goto fail;
390 }
391
392 error = usbd_open_pipe(usc->sc_iface, AR_PIPE_RX_DATA, 0,
393 &usc->rx_data_pipe);
394 if (error != 0) {
395 printf("%s: could not open Rx bulk pipe\n",
396 usc->usb_dev.dv_xname);
397 goto fail;
398 }
399
400 ed = usbd_get_endpoint_descriptor(usc->sc_iface, AR_PIPE_RX_INTR);
401 if (ed == NULL) {
402 printf("%s: could not retrieve Rx intr pipe descriptor\n",
403 usc->usb_dev.dv_xname);
404 goto fail;
405 }
406 isize = UGETW(ed->wMaxPacketSize);
407 if (isize == 0) {
408 printf("%s: invalid Rx intr pipe descriptor\n",
409 usc->usb_dev.dv_xname);
410 goto fail;
411 }
412 usc->ibuf = malloc(isize, M_USBDEV, M_NOWAIT);
413 if (usc->ibuf == NULL) {
414 printf("%s: could not allocate Rx intr buffer\n",
415 usc->usb_dev.dv_xname);
416 goto fail;
417 }
418 usc->ibuflen = isize;
419 error = usbd_open_pipe_intr(usc->sc_iface, AR_PIPE_RX_INTR,
420 USBD_SHORT_XFER_OK, &usc->rx_intr_pipe, usc, usc->ibuf, isize,
421 athn_usb_intr, USBD_DEFAULT_INTERVAL);
422 if (error != 0) {
423 printf("%s: could not open Rx intr pipe\n",
424 usc->usb_dev.dv_xname);
425 goto fail;
426 }
427
428 error = usbd_open_pipe(usc->sc_iface, AR_PIPE_TX_INTR, 0,
429 &usc->tx_intr_pipe);
430 if (error != 0) {
431 printf("%s: could not open Tx intr pipe\n",
432 usc->usb_dev.dv_xname);
433 goto fail;
434 }
435 fail:
436 if (error != 0)
437 athn_usb_close_pipes(usc);
438 return (error);
439 }
440
441 void
athn_usb_close_pipes(struct athn_usb_softc * usc)442 athn_usb_close_pipes(struct athn_usb_softc *usc)
443 {
444 if (usc->tx_data_pipe != NULL) {
445 usbd_close_pipe(usc->tx_data_pipe);
446 usc->tx_data_pipe = NULL;
447 }
448 if (usc->rx_data_pipe != NULL) {
449 usbd_close_pipe(usc->rx_data_pipe);
450 usc->rx_data_pipe = NULL;
451 }
452 if (usc->tx_intr_pipe != NULL) {
453 usbd_close_pipe(usc->tx_intr_pipe);
454 usc->tx_intr_pipe = NULL;
455 }
456 if (usc->rx_intr_pipe != NULL) {
457 usbd_close_pipe(usc->rx_intr_pipe);
458 usc->rx_intr_pipe = NULL;
459 }
460 if (usc->ibuf != NULL) {
461 free(usc->ibuf, M_USBDEV, usc->ibuflen);
462 usc->ibuf = NULL;
463 }
464 }
465
466 int
athn_usb_alloc_rx_list(struct athn_usb_softc * usc)467 athn_usb_alloc_rx_list(struct athn_usb_softc *usc)
468 {
469 struct athn_usb_rx_data *data;
470 int i, error = 0;
471
472 for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) {
473 data = &usc->rx_data[i];
474
475 data->sc = usc; /* Backpointer for callbacks. */
476
477 data->xfer = usbd_alloc_xfer(usc->sc_udev);
478 if (data->xfer == NULL) {
479 printf("%s: could not allocate xfer\n",
480 usc->usb_dev.dv_xname);
481 error = ENOMEM;
482 break;
483 }
484 data->buf = usbd_alloc_buffer(data->xfer, ATHN_USB_RXBUFSZ);
485 if (data->buf == NULL) {
486 printf("%s: could not allocate xfer buffer\n",
487 usc->usb_dev.dv_xname);
488 error = ENOMEM;
489 break;
490 }
491 }
492 if (error != 0)
493 athn_usb_free_rx_list(usc);
494 return (error);
495 }
496
497 void
athn_usb_free_rx_list(struct athn_usb_softc * usc)498 athn_usb_free_rx_list(struct athn_usb_softc *usc)
499 {
500 int i;
501
502 /* NB: Caller must abort pipe first. */
503 for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) {
504 if (usc->rx_data[i].xfer != NULL)
505 usbd_free_xfer(usc->rx_data[i].xfer);
506 usc->rx_data[i].xfer = NULL;
507 }
508 }
509
510 int
athn_usb_alloc_tx_list(struct athn_usb_softc * usc)511 athn_usb_alloc_tx_list(struct athn_usb_softc *usc)
512 {
513 struct athn_usb_tx_data *data;
514 int i, error = 0;
515
516 TAILQ_INIT(&usc->tx_free_list);
517 for (i = 0; i < ATHN_USB_TX_LIST_COUNT; i++) {
518 data = &usc->tx_data[i];
519
520 data->sc = usc; /* Backpointer for callbacks. */
521
522 data->xfer = usbd_alloc_xfer(usc->sc_udev);
523 if (data->xfer == NULL) {
524 printf("%s: could not allocate xfer\n",
525 usc->usb_dev.dv_xname);
526 error = ENOMEM;
527 break;
528 }
529 data->buf = usbd_alloc_buffer(data->xfer, ATHN_USB_TXBUFSZ);
530 if (data->buf == NULL) {
531 printf("%s: could not allocate xfer buffer\n",
532 usc->usb_dev.dv_xname);
533 error = ENOMEM;
534 break;
535 }
536 /* Append this Tx buffer to our free list. */
537 TAILQ_INSERT_TAIL(&usc->tx_free_list, data, next);
538 }
539 if (error != 0)
540 athn_usb_free_tx_list(usc);
541 return (error);
542 }
543
544 void
athn_usb_free_tx_list(struct athn_usb_softc * usc)545 athn_usb_free_tx_list(struct athn_usb_softc *usc)
546 {
547 int i;
548
549 /* NB: Caller must abort pipe first. */
550 for (i = 0; i < ATHN_USB_TX_LIST_COUNT; i++) {
551 if (usc->tx_data[i].xfer != NULL)
552 usbd_free_xfer(usc->tx_data[i].xfer);
553 usc->tx_data[i].xfer = NULL;
554 }
555 }
556
557 int
athn_usb_alloc_tx_cmd(struct athn_usb_softc * usc)558 athn_usb_alloc_tx_cmd(struct athn_usb_softc *usc)
559 {
560 struct athn_usb_tx_data *data = &usc->tx_cmd;
561
562 data->sc = usc; /* Backpointer for callbacks. */
563
564 data->xfer = usbd_alloc_xfer(usc->sc_udev);
565 if (data->xfer == NULL) {
566 printf("%s: could not allocate xfer\n",
567 usc->usb_dev.dv_xname);
568 return (ENOMEM);
569 }
570 data->buf = usbd_alloc_buffer(data->xfer, ATHN_USB_TXCMDSZ);
571 if (data->buf == NULL) {
572 printf("%s: could not allocate xfer buffer\n",
573 usc->usb_dev.dv_xname);
574 return (ENOMEM);
575 }
576 return (0);
577 }
578
579 void
athn_usb_free_tx_cmd(struct athn_usb_softc * usc)580 athn_usb_free_tx_cmd(struct athn_usb_softc *usc)
581 {
582 if (usc->tx_cmd.xfer != NULL)
583 usbd_free_xfer(usc->tx_cmd.xfer);
584 usc->tx_cmd.xfer = NULL;
585 }
586
587 void
athn_usb_task(void * arg)588 athn_usb_task(void *arg)
589 {
590 struct athn_usb_softc *usc = arg;
591 struct athn_usb_host_cmd_ring *ring = &usc->cmdq;
592 struct athn_usb_host_cmd *cmd;
593 int s;
594
595 /* Process host commands. */
596 s = splusb();
597 while (ring->next != ring->cur) {
598 cmd = &ring->cmd[ring->next];
599 splx(s);
600 /* Invoke callback. */
601 cmd->cb(usc, cmd->data);
602 s = splusb();
603 ring->queued--;
604 ring->next = (ring->next + 1) % ATHN_USB_HOST_CMD_RING_COUNT;
605 }
606 splx(s);
607 }
608
609 void
athn_usb_do_async(struct athn_usb_softc * usc,void (* cb)(struct athn_usb_softc *,void *),void * arg,int len)610 athn_usb_do_async(struct athn_usb_softc *usc,
611 void (*cb)(struct athn_usb_softc *, void *), void *arg, int len)
612 {
613 struct athn_usb_host_cmd_ring *ring = &usc->cmdq;
614 struct athn_usb_host_cmd *cmd;
615 int s;
616
617 if (ring->queued == ATHN_USB_HOST_CMD_RING_COUNT) {
618 printf("%s: host cmd queue overrun\n", usc->usb_dev.dv_xname);
619 return; /* XXX */
620 }
621
622 s = splusb();
623 cmd = &ring->cmd[ring->cur];
624 cmd->cb = cb;
625 KASSERT(len <= sizeof(cmd->data));
626 memcpy(cmd->data, arg, len);
627 ring->cur = (ring->cur + 1) % ATHN_USB_HOST_CMD_RING_COUNT;
628
629 /* If there is no pending command already, schedule a task. */
630 if (++ring->queued == 1)
631 usb_add_task(usc->sc_udev, &usc->sc_task);
632 splx(s);
633 }
634
635 void
athn_usb_wait_async(struct athn_usb_softc * usc)636 athn_usb_wait_async(struct athn_usb_softc *usc)
637 {
638 /* Wait for all queued asynchronous commands to complete. */
639 usb_wait_task(usc->sc_udev, &usc->sc_task);
640 }
641
642 int
athn_usb_load_firmware(struct athn_usb_softc * usc)643 athn_usb_load_firmware(struct athn_usb_softc *usc)
644 {
645 usb_device_descriptor_t *dd;
646 usb_device_request_t req;
647 const char *name;
648 u_char *fw, *ptr;
649 size_t fwsize, size;
650 uint32_t addr;
651 int s, mlen, error;
652
653 /* Determine which firmware image to load. */
654 if (usc->flags & ATHN_USB_FLAG_AR7010) {
655 dd = usbd_get_device_descriptor(usc->sc_udev);
656 name = "athn-open-ar7010";
657 } else
658 name = "athn-open-ar9271";
659 /* Read firmware image from the filesystem. */
660 if ((error = loadfirmware(name, &fw, &fwsize)) != 0) {
661 printf("%s: failed loadfirmware of file %s (error %d)\n",
662 usc->usb_dev.dv_xname, name, error);
663 return (error);
664 }
665 /* Load firmware image. */
666 ptr = fw;
667 addr = AR9271_FIRMWARE >> 8;
668 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
669 req.bRequest = AR_FW_DOWNLOAD;
670 USETW(req.wIndex, 0);
671 size = fwsize;
672 while (size > 0) {
673 mlen = MIN(size, 4096);
674
675 USETW(req.wValue, addr);
676 USETW(req.wLength, mlen);
677 error = usbd_do_request(usc->sc_udev, &req, ptr);
678 if (error != 0) {
679 free(fw, M_DEVBUF, fwsize);
680 return (error);
681 }
682 addr += mlen >> 8;
683 ptr += mlen;
684 size -= mlen;
685 }
686 free(fw, M_DEVBUF, fwsize);
687
688 /* Start firmware. */
689 if (usc->flags & ATHN_USB_FLAG_AR7010)
690 addr = AR7010_FIRMWARE_TEXT >> 8;
691 else
692 addr = AR9271_FIRMWARE_TEXT >> 8;
693 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
694 req.bRequest = AR_FW_DOWNLOAD_COMP;
695 USETW(req.wIndex, 0);
696 USETW(req.wValue, addr);
697 USETW(req.wLength, 0);
698 s = splusb();
699 usc->wait_msg_id = AR_HTC_MSG_READY;
700 error = usbd_do_request(usc->sc_udev, &req, NULL);
701 /* Wait at most 1 second for firmware to boot. */
702 if (error == 0 && usc->wait_msg_id != 0)
703 error = tsleep_nsec(&usc->wait_msg_id, 0, "athnfw",
704 SEC_TO_NSEC(1));
705 usc->wait_msg_id = 0;
706 splx(s);
707 return (error);
708 }
709
710 int
athn_usb_htc_msg(struct athn_usb_softc * usc,uint16_t msg_id,void * buf,int len)711 athn_usb_htc_msg(struct athn_usb_softc *usc, uint16_t msg_id, void *buf,
712 int len)
713 {
714 struct athn_usb_tx_data *data = &usc->tx_cmd;
715 struct ar_htc_frame_hdr *htc;
716 struct ar_htc_msg_hdr *msg;
717
718 htc = (struct ar_htc_frame_hdr *)data->buf;
719 memset(htc, 0, sizeof(*htc));
720 htc->endpoint_id = 0;
721 htc->payload_len = htobe16(sizeof(*msg) + len);
722
723 msg = (struct ar_htc_msg_hdr *)&htc[1];
724 msg->msg_id = htobe16(msg_id);
725
726 memcpy(&msg[1], buf, len);
727
728 usbd_setup_xfer(data->xfer, usc->tx_intr_pipe, NULL, data->buf,
729 sizeof(*htc) + sizeof(*msg) + len,
730 USBD_SHORT_XFER_OK | USBD_NO_COPY | USBD_SYNCHRONOUS,
731 ATHN_USB_CMD_TIMEOUT, NULL);
732 return (usbd_transfer(data->xfer));
733 }
734
735 int
athn_usb_htc_setup(struct athn_usb_softc * usc)736 athn_usb_htc_setup(struct athn_usb_softc *usc)
737 {
738 struct ar_htc_msg_config_pipe cfg;
739 int s, error;
740
741 /*
742 * Connect WMI services to USB pipes.
743 */
744 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_CONTROL,
745 AR_PIPE_TX_INTR, AR_PIPE_RX_INTR, &usc->ep_ctrl);
746 if (error != 0)
747 return (error);
748 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_BEACON,
749 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_bcn);
750 if (error != 0)
751 return (error);
752 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_CAB,
753 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_cab);
754 if (error != 0)
755 return (error);
756 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_UAPSD,
757 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_uapsd);
758 if (error != 0)
759 return (error);
760 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_MGMT,
761 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_mgmt);
762 if (error != 0)
763 return (error);
764 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_BE,
765 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[EDCA_AC_BE]);
766 if (error != 0)
767 return (error);
768 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_BK,
769 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[EDCA_AC_BK]);
770 if (error != 0)
771 return (error);
772 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_VI,
773 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[EDCA_AC_VI]);
774 if (error != 0)
775 return (error);
776 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_VO,
777 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[EDCA_AC_VO]);
778 if (error != 0)
779 return (error);
780
781 /* Set credits for WLAN Tx pipe. */
782 memset(&cfg, 0, sizeof(cfg));
783 cfg.pipe_id = UE_GET_ADDR(AR_PIPE_TX_DATA);
784 cfg.credits = (usc->flags & ATHN_USB_FLAG_AR7010) ? 45 : 33;
785 s = splusb();
786 usc->wait_msg_id = AR_HTC_MSG_CONF_PIPE_RSP;
787 error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONF_PIPE, &cfg, sizeof(cfg));
788 if (error == 0 && usc->wait_msg_id != 0)
789 error = tsleep_nsec(&usc->wait_msg_id, 0, "athnhtc",
790 SEC_TO_NSEC(1));
791 usc->wait_msg_id = 0;
792 splx(s);
793 if (error != 0) {
794 printf("%s: could not configure pipe\n",
795 usc->usb_dev.dv_xname);
796 return (error);
797 }
798
799 error = athn_usb_htc_msg(usc, AR_HTC_MSG_SETUP_COMPLETE, NULL, 0);
800 if (error != 0) {
801 printf("%s: could not complete setup\n",
802 usc->usb_dev.dv_xname);
803 return (error);
804 }
805 return (0);
806 }
807
808 int
athn_usb_htc_connect_svc(struct athn_usb_softc * usc,uint16_t svc_id,uint8_t ul_pipe,uint8_t dl_pipe,uint8_t * endpoint_id)809 athn_usb_htc_connect_svc(struct athn_usb_softc *usc, uint16_t svc_id,
810 uint8_t ul_pipe, uint8_t dl_pipe, uint8_t *endpoint_id)
811 {
812 struct ar_htc_msg_conn_svc msg;
813 struct ar_htc_msg_conn_svc_rsp rsp;
814 int s, error;
815
816 memset(&msg, 0, sizeof(msg));
817 msg.svc_id = htobe16(svc_id);
818 msg.dl_pipeid = UE_GET_ADDR(dl_pipe);
819 msg.ul_pipeid = UE_GET_ADDR(ul_pipe);
820 s = splusb();
821 usc->msg_conn_svc_rsp = &rsp;
822 usc->wait_msg_id = AR_HTC_MSG_CONN_SVC_RSP;
823 error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONN_SVC, &msg, sizeof(msg));
824 /* Wait at most 1 second for response. */
825 if (error == 0 && usc->wait_msg_id != 0)
826 error = tsleep_nsec(&usc->wait_msg_id, 0, "athnhtc",
827 SEC_TO_NSEC(1));
828 usc->wait_msg_id = 0;
829 splx(s);
830 if (error != 0) {
831 printf("%s: error waiting for service %d connection\n",
832 usc->usb_dev.dv_xname, svc_id);
833 return (error);
834 }
835 if (rsp.status != AR_HTC_SVC_SUCCESS) {
836 printf("%s: service %d connection failed, error %d\n",
837 usc->usb_dev.dv_xname, svc_id, rsp.status);
838 return (EIO);
839 }
840 DPRINTF(("service %d successfully connected to endpoint %d\n",
841 svc_id, rsp.endpoint_id));
842
843 /* Return endpoint id. */
844 *endpoint_id = rsp.endpoint_id;
845 return (0);
846 }
847
848 int
athn_usb_wmi_xcmd(struct athn_usb_softc * usc,uint16_t cmd_id,void * ibuf,int ilen,void * obuf)849 athn_usb_wmi_xcmd(struct athn_usb_softc *usc, uint16_t cmd_id, void *ibuf,
850 int ilen, void *obuf)
851 {
852 struct athn_usb_tx_data *data = &usc->tx_cmd;
853 struct ar_htc_frame_hdr *htc;
854 struct ar_wmi_cmd_hdr *wmi;
855 int s, error;
856
857 if (usbd_is_dying(usc->sc_udev))
858 return ENXIO;
859
860 s = splusb();
861 while (usc->wait_cmd_id) {
862 /*
863 * The previous USB transfer is not done yet. We can't use
864 * data->xfer until it is done or we'll cause major confusion
865 * in the USB stack.
866 */
867 tsleep_nsec(&usc->wait_cmd_id, 0, "athnwmx",
868 MSEC_TO_NSEC(ATHN_USB_CMD_TIMEOUT));
869 if (usbd_is_dying(usc->sc_udev)) {
870 splx(s);
871 return ENXIO;
872 }
873 }
874 splx(s);
875
876 htc = (struct ar_htc_frame_hdr *)data->buf;
877 memset(htc, 0, sizeof(*htc));
878 htc->endpoint_id = usc->ep_ctrl;
879 htc->payload_len = htobe16(sizeof(*wmi) + ilen);
880
881 wmi = (struct ar_wmi_cmd_hdr *)&htc[1];
882 wmi->cmd_id = htobe16(cmd_id);
883 usc->wmi_seq_no++;
884 wmi->seq_no = htobe16(usc->wmi_seq_no);
885
886 memcpy(&wmi[1], ibuf, ilen);
887
888 usbd_setup_xfer(data->xfer, usc->tx_intr_pipe, NULL, data->buf,
889 sizeof(*htc) + sizeof(*wmi) + ilen,
890 USBD_SHORT_XFER_OK | USBD_NO_COPY, ATHN_USB_CMD_TIMEOUT,
891 NULL);
892 s = splusb();
893 error = usbd_transfer(data->xfer);
894 if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) {
895 splx(s);
896 return (error);
897 }
898 usc->obuf = obuf;
899 usc->wait_cmd_id = cmd_id;
900 /*
901 * Wait for WMI command complete interrupt. In case it does not fire
902 * wait until the USB transfer times out to avoid racing the transfer.
903 */
904 error = tsleep_nsec(&usc->wait_cmd_id, 0, "athnwmi",
905 MSEC_TO_NSEC(ATHN_USB_CMD_TIMEOUT));
906 if (error) {
907 if (error == EWOULDBLOCK) {
908 printf("%s: firmware command 0x%x timed out\n",
909 usc->usb_dev.dv_xname, cmd_id);
910 error = ETIMEDOUT;
911 }
912 }
913
914 /*
915 * Both the WMI command and transfer are done or have timed out.
916 * Allow other threads to enter this function and use data->xfer.
917 */
918 usc->wait_cmd_id = 0;
919 wakeup(&usc->wait_cmd_id);
920
921 splx(s);
922 return (error);
923 }
924
925 int
athn_usb_read_rom(struct athn_softc * sc)926 athn_usb_read_rom(struct athn_softc *sc)
927 {
928 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
929 uint32_t addrs[8], vals[8], addr;
930 uint16_t *eep;
931 int i, j, error;
932
933 /* Read EEPROM by blocks of 16 bytes. */
934 eep = sc->eep;
935 addr = AR_EEPROM_OFFSET(sc->eep_base);
936 for (i = 0; i < sc->eep_size / 16; i++) {
937 for (j = 0; j < 8; j++, addr += 4)
938 addrs[j] = htobe32(addr);
939 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_READ,
940 addrs, sizeof(addrs), vals);
941 if (error != 0)
942 break;
943 for (j = 0; j < 8; j++)
944 *eep++ = betoh32(vals[j]);
945 }
946 return (error);
947 }
948
949 uint32_t
athn_usb_read(struct athn_softc * sc,uint32_t addr)950 athn_usb_read(struct athn_softc *sc, uint32_t addr)
951 {
952 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
953 uint32_t val;
954 int error;
955
956 /* Flush pending writes for strict consistency. */
957 athn_usb_write_barrier(sc);
958
959 addr = htobe32(addr);
960 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_READ,
961 &addr, sizeof(addr), &val);
962 if (error != 0)
963 return (0xdeadbeef);
964 return (betoh32(val));
965 }
966
967 void
athn_usb_write(struct athn_softc * sc,uint32_t addr,uint32_t val)968 athn_usb_write(struct athn_softc *sc, uint32_t addr, uint32_t val)
969 {
970 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
971
972 usc->wbuf[usc->wcount].addr = htobe32(addr);
973 usc->wbuf[usc->wcount].val = htobe32(val);
974 if (++usc->wcount == AR_MAX_WRITE_COUNT)
975 athn_usb_write_barrier(sc);
976 }
977
978 void
athn_usb_write_barrier(struct athn_softc * sc)979 athn_usb_write_barrier(struct athn_softc *sc)
980 {
981 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
982
983 if (usc->wcount == 0)
984 return; /* Nothing to write. */
985
986 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_WRITE,
987 usc->wbuf, usc->wcount * sizeof(usc->wbuf[0]), NULL);
988 usc->wcount = 0; /* Always flush buffer. */
989 }
990
991 int
athn_usb_media_change(struct ifnet * ifp)992 athn_usb_media_change(struct ifnet *ifp)
993 {
994 struct athn_usb_softc *usc = (struct athn_usb_softc *)ifp->if_softc;
995 int error;
996
997 if (usbd_is_dying(usc->sc_udev))
998 return ENXIO;
999
1000 error = ieee80211_media_change(ifp);
1001 if (error != ENETRESET)
1002 return (error);
1003
1004 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
1005 (IFF_UP | IFF_RUNNING)) {
1006 athn_usb_stop(ifp);
1007 error = athn_usb_init(ifp);
1008 }
1009 return (error);
1010 }
1011
1012 void
athn_usb_next_scan(void * arg)1013 athn_usb_next_scan(void *arg)
1014 {
1015 struct athn_usb_softc *usc = arg;
1016 struct athn_softc *sc = &usc->sc_sc;
1017 struct ieee80211com *ic = &sc->sc_ic;
1018 int s;
1019
1020 if (usbd_is_dying(usc->sc_udev))
1021 return;
1022
1023 usbd_ref_incr(usc->sc_udev);
1024
1025 s = splnet();
1026 if (ic->ic_state == IEEE80211_S_SCAN)
1027 ieee80211_next_scan(&ic->ic_if);
1028 splx(s);
1029
1030 usbd_ref_decr(usc->sc_udev);
1031 }
1032
1033 int
athn_usb_newstate(struct ieee80211com * ic,enum ieee80211_state nstate,int arg)1034 athn_usb_newstate(struct ieee80211com *ic, enum ieee80211_state nstate,
1035 int arg)
1036 {
1037 struct athn_usb_softc *usc = ic->ic_softc;
1038 struct athn_usb_cmd_newstate cmd;
1039
1040 /* Do it in a process context. */
1041 cmd.state = nstate;
1042 cmd.arg = arg;
1043 athn_usb_do_async(usc, athn_usb_newstate_cb, &cmd, sizeof(cmd));
1044 return (0);
1045 }
1046
1047 void
athn_usb_newstate_cb(struct athn_usb_softc * usc,void * arg)1048 athn_usb_newstate_cb(struct athn_usb_softc *usc, void *arg)
1049 {
1050 struct athn_usb_cmd_newstate *cmd = arg;
1051 struct athn_softc *sc = &usc->sc_sc;
1052 struct ieee80211com *ic = &sc->sc_ic;
1053 enum ieee80211_state ostate;
1054 uint32_t reg, imask;
1055 int s, error;
1056
1057 timeout_del(&sc->calib_to);
1058
1059 s = splnet();
1060 ostate = ic->ic_state;
1061
1062 if (ostate == IEEE80211_S_RUN && ic->ic_opmode == IEEE80211_M_STA) {
1063 athn_usb_remove_node(usc, ic->ic_bss);
1064 reg = AR_READ(sc, AR_RX_FILTER);
1065 reg = (reg & ~AR_RX_FILTER_MYBEACON) |
1066 AR_RX_FILTER_BEACON;
1067 AR_WRITE(sc, AR_RX_FILTER, reg);
1068 AR_WRITE_BARRIER(sc);
1069 }
1070 switch (cmd->state) {
1071 case IEEE80211_S_INIT:
1072 athn_set_led(sc, 0);
1073 break;
1074 case IEEE80211_S_SCAN:
1075 /* Make the LED blink while scanning. */
1076 athn_set_led(sc, !sc->led_state);
1077 error = athn_usb_switch_chan(sc, ic->ic_bss->ni_chan, NULL);
1078 if (error)
1079 printf("%s: could not switch to channel %d\n",
1080 usc->usb_dev.dv_xname,
1081 ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan));
1082 if (!usbd_is_dying(usc->sc_udev))
1083 timeout_add_msec(&sc->scan_to, 200);
1084 break;
1085 case IEEE80211_S_AUTH:
1086 athn_set_led(sc, 0);
1087 error = athn_usb_switch_chan(sc, ic->ic_bss->ni_chan, NULL);
1088 if (error)
1089 printf("%s: could not switch to channel %d\n",
1090 usc->usb_dev.dv_xname,
1091 ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan));
1092 break;
1093 case IEEE80211_S_ASSOC:
1094 break;
1095 case IEEE80211_S_RUN:
1096 athn_set_led(sc, 1);
1097
1098 if (ic->ic_opmode == IEEE80211_M_MONITOR)
1099 break;
1100
1101 if (ic->ic_opmode == IEEE80211_M_STA) {
1102 /* Create node entry for our BSS */
1103 error = athn_usb_create_node(usc, ic->ic_bss);
1104 if (error)
1105 printf("%s: could not update firmware station "
1106 "table\n", usc->usb_dev.dv_xname);
1107 }
1108 athn_set_bss(sc, ic->ic_bss);
1109 athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR);
1110 #ifndef IEEE80211_STA_ONLY
1111 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
1112 athn_usb_switch_chan(sc, ic->ic_bss->ni_chan, NULL);
1113 athn_set_hostap_timers(sc);
1114 /* Enable software beacon alert interrupts. */
1115 imask = htobe32(AR_IMR_SWBA);
1116 } else
1117 #endif
1118 {
1119 athn_set_sta_timers(sc);
1120 /* Enable beacon miss interrupts. */
1121 imask = htobe32(AR_IMR_BMISS);
1122
1123 /* Stop receiving beacons from other BSS. */
1124 reg = AR_READ(sc, AR_RX_FILTER);
1125 reg = (reg & ~AR_RX_FILTER_BEACON) |
1126 AR_RX_FILTER_MYBEACON;
1127 AR_WRITE(sc, AR_RX_FILTER, reg);
1128 AR_WRITE_BARRIER(sc);
1129 }
1130 athn_usb_wmi_xcmd(usc, AR_WMI_CMD_ENABLE_INTR,
1131 &imask, sizeof(imask), NULL);
1132 break;
1133 }
1134 (void)sc->sc_newstate(ic, cmd->state, cmd->arg);
1135 splx(s);
1136 }
1137
1138 void
athn_usb_newassoc(struct ieee80211com * ic,struct ieee80211_node * ni,int isnew)1139 athn_usb_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni,
1140 int isnew)
1141 {
1142 #ifndef IEEE80211_STA_ONLY
1143 struct athn_usb_softc *usc = ic->ic_softc;
1144
1145 if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
1146 ic->ic_state != IEEE80211_S_RUN)
1147 return;
1148
1149 /* Update the node's supported rates in a process context. */
1150 ieee80211_ref_node(ni);
1151 athn_usb_do_async(usc, athn_usb_newassoc_cb, &ni, sizeof(ni));
1152 #endif
1153 }
1154
1155 #ifndef IEEE80211_STA_ONLY
1156 void
athn_usb_newassoc_cb(struct athn_usb_softc * usc,void * arg)1157 athn_usb_newassoc_cb(struct athn_usb_softc *usc, void *arg)
1158 {
1159 struct ieee80211com *ic = &usc->sc_sc.sc_ic;
1160 struct ieee80211_node *ni = *(void **)arg;
1161 struct athn_node *an = (struct athn_node *)ni;
1162 int s;
1163
1164 if (ic->ic_state != IEEE80211_S_RUN)
1165 return;
1166
1167 s = splnet();
1168 /* NB: Node may have left before we got scheduled. */
1169 if (an->sta_index != 0)
1170 (void)athn_usb_node_set_rates(usc, ni);
1171 ieee80211_release_node(ic, ni);
1172 splx(s);
1173 }
1174 #endif
1175
1176 struct ieee80211_node *
athn_usb_node_alloc(struct ieee80211com * ic)1177 athn_usb_node_alloc(struct ieee80211com *ic)
1178 {
1179 struct athn_node *an;
1180
1181 an = malloc(sizeof(struct athn_node), M_USBDEV, M_NOWAIT | M_ZERO);
1182 return (struct ieee80211_node *)an;
1183 }
1184
1185
1186 #ifndef IEEE80211_STA_ONLY
1187 void
athn_usb_count_active_sta(void * arg,struct ieee80211_node * ni)1188 athn_usb_count_active_sta(void *arg, struct ieee80211_node *ni)
1189 {
1190 int *nsta = arg;
1191 struct athn_node *an = (struct athn_node *)ni;
1192
1193 if (an->sta_index == 0)
1194 return;
1195
1196 if ((ni->ni_state == IEEE80211_STA_AUTH ||
1197 ni->ni_state == IEEE80211_STA_ASSOC) &&
1198 ni->ni_inact < IEEE80211_INACT_MAX)
1199 (*nsta)++;
1200 }
1201
1202 struct athn_usb_newauth_cb_arg {
1203 struct ieee80211_node *ni;
1204 uint16_t seq;
1205 };
1206
1207 void
athn_usb_newauth_cb(struct athn_usb_softc * usc,void * arg)1208 athn_usb_newauth_cb(struct athn_usb_softc *usc, void *arg)
1209 {
1210 struct ieee80211com *ic = &usc->sc_sc.sc_ic;
1211 struct athn_usb_newauth_cb_arg *a = arg;
1212 struct ieee80211_node *ni = a->ni;
1213 uint16_t seq = a->seq;
1214 struct athn_node *an = (struct athn_node *)ni;
1215 int s, error = 0;
1216
1217 if (ic->ic_state != IEEE80211_S_RUN)
1218 return;
1219
1220 s = splnet();
1221 if (an->sta_index == 0) {
1222 error = athn_usb_create_node(usc, ni);
1223 if (error)
1224 printf("%s: could not add station %s to firmware "
1225 "table\n", usc->usb_dev.dv_xname,
1226 ether_sprintf(ni->ni_macaddr));
1227 }
1228 if (error == 0)
1229 ieee80211_auth_open_confirm(ic, ni, seq);
1230 ieee80211_unref_node(&ni);
1231 splx(s);
1232 }
1233 #endif
1234
1235 int
athn_usb_newauth(struct ieee80211com * ic,struct ieee80211_node * ni,int isnew,uint16_t seq)1236 athn_usb_newauth(struct ieee80211com *ic, struct ieee80211_node *ni,
1237 int isnew, uint16_t seq)
1238 {
1239 #ifndef IEEE80211_STA_ONLY
1240 struct athn_usb_softc *usc = ic->ic_softc;
1241 struct ifnet *ifp = &ic->ic_if;
1242 struct athn_node *an = (struct athn_node *)ni;
1243 int nsta;
1244 struct athn_usb_newauth_cb_arg arg;
1245
1246 if (ic->ic_opmode != IEEE80211_M_HOSTAP)
1247 return 0;
1248
1249 if (!isnew && an->sta_index != 0) /* already in firmware table */
1250 return 0;
1251
1252 /* Check if we have room in the firmware table. */
1253 nsta = 1; /* Account for default node. */
1254 ieee80211_iterate_nodes(ic, athn_usb_count_active_sta, &nsta);
1255 if (nsta >= AR_USB_MAX_STA) {
1256 if (ifp->if_flags & IFF_DEBUG)
1257 printf("%s: cannot authenticate station %s: firmware "
1258 "table is full\n", usc->usb_dev.dv_xname,
1259 ether_sprintf(ni->ni_macaddr));
1260 return ENOSPC;
1261 }
1262
1263 /*
1264 * In a process context, try to add this node to the
1265 * firmware table and confirm the AUTH request.
1266 */
1267 arg.ni = ieee80211_ref_node(ni);
1268 arg.seq = seq;
1269 athn_usb_do_async(usc, athn_usb_newauth_cb, &arg, sizeof(arg));
1270 return EBUSY;
1271 #else
1272 return 0;
1273 #endif /* IEEE80211_STA_ONLY */
1274 }
1275
1276 #ifndef IEEE80211_STA_ONLY
1277 void
athn_usb_node_free(struct ieee80211com * ic,struct ieee80211_node * ni)1278 athn_usb_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
1279 {
1280 struct athn_usb_softc *usc = ic->ic_softc;
1281 struct athn_node *an = (struct athn_node *)ni;
1282
1283 /*
1284 * Remove the node from the firmware table in a process context.
1285 * Pass an index rather than the pointer which we will free.
1286 */
1287 if (an->sta_index != 0)
1288 athn_usb_do_async(usc, athn_usb_node_free_cb,
1289 &an->sta_index, sizeof(an->sta_index));
1290 usc->sc_node_free(ic, ni);
1291 }
1292
1293 void
athn_usb_node_free_cb(struct athn_usb_softc * usc,void * arg)1294 athn_usb_node_free_cb(struct athn_usb_softc *usc, void *arg)
1295 {
1296 struct ieee80211com *ic = &usc->sc_sc.sc_ic;
1297 struct ifnet *ifp = &ic->ic_if;
1298 uint8_t sta_index = *(uint8_t *)arg;
1299 int error;
1300
1301 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE,
1302 &sta_index, sizeof(sta_index), NULL);
1303 if (error) {
1304 printf("%s: could not remove station %u from firmware table\n",
1305 usc->usb_dev.dv_xname, sta_index);
1306 return;
1307 }
1308 usc->free_node_slots |= (1 << sta_index);
1309 if (ifp->if_flags & IFF_DEBUG)
1310 printf("%s: station %u removed from firmware table\n",
1311 usc->usb_dev.dv_xname, sta_index);
1312 }
1313 #endif /* IEEE80211_STA_ONLY */
1314
1315 int
athn_usb_ampdu_tx_start(struct ieee80211com * ic,struct ieee80211_node * ni,uint8_t tid)1316 athn_usb_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
1317 uint8_t tid)
1318 {
1319 struct athn_usb_softc *usc = ic->ic_softc;
1320 struct athn_node *an = (struct athn_node *)ni;
1321 struct athn_usb_aggr_cmd cmd;
1322
1323 /* Do it in a process context. */
1324 cmd.sta_index = an->sta_index;
1325 cmd.tid = tid;
1326 athn_usb_do_async(usc, athn_usb_ampdu_tx_start_cb, &cmd, sizeof(cmd));
1327 return (0);
1328 }
1329
1330 void
athn_usb_ampdu_tx_start_cb(struct athn_usb_softc * usc,void * arg)1331 athn_usb_ampdu_tx_start_cb(struct athn_usb_softc *usc, void *arg)
1332 {
1333 struct athn_usb_aggr_cmd *cmd = arg;
1334 struct ar_htc_target_aggr aggr;
1335
1336 memset(&aggr, 0, sizeof(aggr));
1337 aggr.sta_index = cmd->sta_index;
1338 aggr.tidno = cmd->tid;
1339 aggr.aggr_enable = 1;
1340 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TX_AGGR_ENABLE,
1341 &aggr, sizeof(aggr), NULL);
1342 }
1343
1344 void
athn_usb_ampdu_tx_stop(struct ieee80211com * ic,struct ieee80211_node * ni,uint8_t tid)1345 athn_usb_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
1346 uint8_t tid)
1347 {
1348 struct athn_usb_softc *usc = ic->ic_softc;
1349 struct athn_node *an = (struct athn_node *)ni;
1350 struct athn_usb_aggr_cmd cmd;
1351
1352 /* Do it in a process context. */
1353 cmd.sta_index = an->sta_index;
1354 cmd.tid = tid;
1355 athn_usb_do_async(usc, athn_usb_ampdu_tx_stop_cb, &cmd, sizeof(cmd));
1356 }
1357
1358 void
athn_usb_ampdu_tx_stop_cb(struct athn_usb_softc * usc,void * arg)1359 athn_usb_ampdu_tx_stop_cb(struct athn_usb_softc *usc, void *arg)
1360 {
1361 struct athn_usb_aggr_cmd *cmd = arg;
1362 struct ar_htc_target_aggr aggr;
1363
1364 memset(&aggr, 0, sizeof(aggr));
1365 aggr.sta_index = cmd->sta_index;
1366 aggr.tidno = cmd->tid;
1367 aggr.aggr_enable = 0;
1368 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TX_AGGR_ENABLE,
1369 &aggr, sizeof(aggr), NULL);
1370 }
1371
1372 #ifndef IEEE80211_STA_ONLY
1373 /* Try to find a node we can evict to make room in the firmware table. */
1374 void
athn_usb_clean_nodes(void * arg,struct ieee80211_node * ni)1375 athn_usb_clean_nodes(void *arg, struct ieee80211_node *ni)
1376 {
1377 struct athn_usb_softc *usc = arg;
1378 struct ieee80211com *ic = &usc->sc_sc.sc_ic;
1379 struct athn_node *an = (struct athn_node *)ni;
1380
1381 /*
1382 * Don't remove the default node (used for management frames).
1383 * Nodes which are not in the firmware table also have index zero.
1384 */
1385 if (an->sta_index == 0)
1386 return;
1387
1388 /* Remove non-associated nodes. */
1389 if (ni->ni_state != IEEE80211_STA_AUTH &&
1390 ni->ni_state != IEEE80211_STA_ASSOC) {
1391 athn_usb_remove_node(usc, ni);
1392 return;
1393 }
1394
1395 /*
1396 * Kick off inactive associated nodes. This won't help
1397 * immediately but will help if the new STA retries later.
1398 */
1399 if (ni->ni_inact >= IEEE80211_INACT_MAX) {
1400 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
1401 IEEE80211_REASON_AUTH_EXPIRE);
1402 ieee80211_node_leave(ic, ni);
1403 }
1404 }
1405 #endif
1406
1407 int
athn_usb_create_node(struct athn_usb_softc * usc,struct ieee80211_node * ni)1408 athn_usb_create_node(struct athn_usb_softc *usc, struct ieee80211_node *ni)
1409 {
1410 struct athn_node *an = (struct athn_node *)ni;
1411 struct ar_htc_target_sta sta;
1412 int error, sta_index;
1413 #ifndef IEEE80211_STA_ONLY
1414 struct ieee80211com *ic = &usc->sc_sc.sc_ic;
1415 struct ifnet *ifp = &ic->ic_if;
1416
1417 /* Firmware cannot handle more than 8 STAs. Try to make room first. */
1418 if (ic->ic_opmode == IEEE80211_M_HOSTAP)
1419 ieee80211_iterate_nodes(ic, athn_usb_clean_nodes, usc);
1420 #endif
1421 if (usc->free_node_slots == 0x00)
1422 return ENOBUFS;
1423
1424 sta_index = ffs(usc->free_node_slots) - 1;
1425 if (sta_index < 0 || sta_index >= AR_USB_MAX_STA)
1426 return ENOSPC;
1427
1428 /* Create node entry on target. */
1429 memset(&sta, 0, sizeof(sta));
1430 IEEE80211_ADDR_COPY(sta.macaddr, ni->ni_macaddr);
1431 IEEE80211_ADDR_COPY(sta.bssid, ni->ni_bssid);
1432 sta.sta_index = sta_index;
1433 sta.maxampdu = 0xffff;
1434 if (ni->ni_flags & IEEE80211_NODE_HT)
1435 sta.flags |= htobe16(AR_HTC_STA_HT);
1436 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_CREATE,
1437 &sta, sizeof(sta), NULL);
1438 if (error != 0)
1439 return (error);
1440 an->sta_index = sta_index;
1441 usc->free_node_slots &= ~(1 << an->sta_index);
1442
1443 #ifndef IEEE80211_STA_ONLY
1444 if (ifp->if_flags & IFF_DEBUG)
1445 printf("%s: station %u (%s) added to firmware table\n",
1446 usc->usb_dev.dv_xname, sta_index,
1447 ether_sprintf(ni->ni_macaddr));
1448 #endif
1449 return athn_usb_node_set_rates(usc, ni);
1450 }
1451
1452 int
athn_usb_node_set_rates(struct athn_usb_softc * usc,struct ieee80211_node * ni)1453 athn_usb_node_set_rates(struct athn_usb_softc *usc, struct ieee80211_node *ni)
1454 {
1455 struct athn_node *an = (struct athn_node *)ni;
1456 struct ar_htc_target_rate rate;
1457 int i, j;
1458
1459 /* Setup supported rates. */
1460 memset(&rate, 0, sizeof(rate));
1461 rate.sta_index = an->sta_index;
1462 rate.isnew = 1;
1463 rate.lg_rates.rs_nrates = ni->ni_rates.rs_nrates;
1464 memcpy(rate.lg_rates.rs_rates, ni->ni_rates.rs_rates,
1465 ni->ni_rates.rs_nrates);
1466 if (ni->ni_flags & IEEE80211_NODE_HT) {
1467 rate.capflags |= htobe32(AR_RC_HT_FLAG);
1468 /* Setup HT rates. */
1469 for (i = 0, j = 0; i < IEEE80211_HT_NUM_MCS; i++) {
1470 if (!isset(ni->ni_rxmcs, i))
1471 continue;
1472 if (j >= AR_HTC_RATE_MAX)
1473 break;
1474 rate.ht_rates.rs_rates[j++] = i;
1475 }
1476 rate.ht_rates.rs_nrates = j;
1477
1478 if (ni->ni_rxmcs[1]) /* dual-stream MIMO rates */
1479 rate.capflags |= htobe32(AR_RC_DS_FLAG);
1480 #ifdef notyet
1481 if (ni->ni_htcaps & IEEE80211_HTCAP_CBW20_40)
1482 rate.capflags |= htobe32(AR_RC_40_FLAG);
1483 if (ni->ni_htcaps & IEEE80211_HTCAP_SGI40)
1484 rate.capflags |= htobe32(AR_RC_SGI_FLAG);
1485 if (ni->ni_htcaps & IEEE80211_HTCAP_SGI20)
1486 rate.capflags |= htobe32(AR_RC_SGI_FLAG);
1487 #endif
1488 }
1489
1490 return athn_usb_wmi_xcmd(usc, AR_WMI_CMD_RC_RATE_UPDATE,
1491 &rate, sizeof(rate), NULL);
1492 }
1493
1494 int
athn_usb_remove_node(struct athn_usb_softc * usc,struct ieee80211_node * ni)1495 athn_usb_remove_node(struct athn_usb_softc *usc, struct ieee80211_node *ni)
1496 {
1497 struct athn_node *an = (struct athn_node *)ni;
1498 int error;
1499 #ifndef IEEE80211_STA_ONLY
1500 struct ieee80211com *ic = &usc->sc_sc.sc_ic;
1501 struct ifnet *ifp = &ic->ic_if;
1502 #endif
1503
1504 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE,
1505 &an->sta_index, sizeof(an->sta_index), NULL);
1506 if (error) {
1507 printf("%s: could not remove station %u (%s) from "
1508 "firmware table\n", usc->usb_dev.dv_xname, an->sta_index,
1509 ether_sprintf(ni->ni_macaddr));
1510 return error;
1511 }
1512
1513 #ifndef IEEE80211_STA_ONLY
1514 if (ifp->if_flags & IFF_DEBUG)
1515 printf("%s: station %u (%s) removed from firmware table\n",
1516 usc->usb_dev.dv_xname, an->sta_index,
1517 ether_sprintf(ni->ni_macaddr));
1518 #endif
1519
1520 usc->free_node_slots |= (1 << an->sta_index);
1521 an->sta_index = 0;
1522 return 0;
1523 }
1524
1525 void
athn_usb_rx_enable(struct athn_softc * sc)1526 athn_usb_rx_enable(struct athn_softc *sc)
1527 {
1528 AR_WRITE(sc, AR_CR, AR_CR_RXE);
1529 AR_WRITE_BARRIER(sc);
1530 }
1531
1532 int
athn_usb_switch_chan(struct athn_softc * sc,struct ieee80211_channel * c,struct ieee80211_channel * extc)1533 athn_usb_switch_chan(struct athn_softc *sc, struct ieee80211_channel *c,
1534 struct ieee80211_channel *extc)
1535 {
1536 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
1537 uint16_t mode;
1538 int error;
1539
1540 /* Disable interrupts. */
1541 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR);
1542 if (error != 0)
1543 goto reset;
1544 /* Stop all Tx queues. */
1545 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_DRAIN_TXQ_ALL);
1546 if (error != 0)
1547 goto reset;
1548 /* Stop Rx. */
1549 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_STOP_RECV);
1550 if (error != 0)
1551 goto reset;
1552
1553 /* If band or bandwidth changes, we need to do a full reset. */
1554 if (c->ic_flags != sc->curchan->ic_flags ||
1555 ((extc != NULL) ^ (sc->curchanext != NULL))) {
1556 DPRINTFN(2, ("channel band switch\n"));
1557 goto reset;
1558 }
1559
1560 error = athn_set_chan(sc, c, extc);
1561 if (AR_SREV_9271(sc) && error == 0)
1562 ar9271_load_ani(sc);
1563 if (error != 0) {
1564 reset: /* Error found, try a full reset. */
1565 DPRINTFN(3, ("needs a full reset\n"));
1566 error = athn_hw_reset(sc, c, extc, 0);
1567 if (error != 0) /* Hopeless case. */
1568 return (error);
1569
1570 error = athn_set_chan(sc, c, extc);
1571 if (AR_SREV_9271(sc) && error == 0)
1572 ar9271_load_ani(sc);
1573 if (error != 0)
1574 return (error);
1575 }
1576
1577 sc->ops.set_txpower(sc, c, extc);
1578
1579 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV);
1580 if (error != 0)
1581 return (error);
1582 athn_rx_start(sc);
1583
1584 mode = htobe16(IEEE80211_IS_CHAN_2GHZ(c) ?
1585 AR_HTC_MODE_11NG : AR_HTC_MODE_11NA);
1586 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_SET_MODE,
1587 &mode, sizeof(mode), NULL);
1588 if (error != 0)
1589 return (error);
1590
1591 /* Re-enable interrupts. */
1592 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_ENABLE_INTR);
1593 return (error);
1594 }
1595
1596 void
athn_usb_updateedca(struct ieee80211com * ic)1597 athn_usb_updateedca(struct ieee80211com *ic)
1598 {
1599 struct athn_usb_softc *usc = ic->ic_softc;
1600
1601 /* Do it in a process context. */
1602 athn_usb_do_async(usc, athn_usb_updateedca_cb, NULL, 0);
1603 }
1604
1605 void
athn_usb_updateedca_cb(struct athn_usb_softc * usc,void * arg)1606 athn_usb_updateedca_cb(struct athn_usb_softc *usc, void *arg)
1607 {
1608 int s;
1609
1610 s = splnet();
1611 athn_updateedca(&usc->sc_sc.sc_ic);
1612 splx(s);
1613 }
1614
1615 void
athn_usb_updateslot(struct ieee80211com * ic)1616 athn_usb_updateslot(struct ieee80211com *ic)
1617 {
1618 struct athn_usb_softc *usc = ic->ic_softc;
1619
1620 return; /* XXX */
1621 /* Do it in a process context. */
1622 athn_usb_do_async(usc, athn_usb_updateslot_cb, NULL, 0);
1623 }
1624
1625 void
athn_usb_updateslot_cb(struct athn_usb_softc * usc,void * arg)1626 athn_usb_updateslot_cb(struct athn_usb_softc *usc, void *arg)
1627 {
1628 int s;
1629
1630 s = splnet();
1631 athn_updateslot(&usc->sc_sc.sc_ic);
1632 splx(s);
1633 }
1634
1635 int
athn_usb_set_key(struct ieee80211com * ic,struct ieee80211_node * ni,struct ieee80211_key * k)1636 athn_usb_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
1637 struct ieee80211_key *k)
1638 {
1639 struct athn_usb_softc *usc = ic->ic_softc;
1640 struct athn_usb_cmd_key cmd;
1641
1642 /* Defer setting of WEP keys until interface is brought up. */
1643 if ((ic->ic_if.if_flags & (IFF_UP | IFF_RUNNING)) !=
1644 (IFF_UP | IFF_RUNNING))
1645 return (0);
1646
1647 /* Do it in a process context. */
1648 cmd.ni = (ni != NULL) ? ieee80211_ref_node(ni) : NULL;
1649 cmd.key = k;
1650 athn_usb_do_async(usc, athn_usb_set_key_cb, &cmd, sizeof(cmd));
1651 usc->sc_key_tasks++;
1652 return EBUSY;
1653 }
1654
1655 void
athn_usb_set_key_cb(struct athn_usb_softc * usc,void * arg)1656 athn_usb_set_key_cb(struct athn_usb_softc *usc, void *arg)
1657 {
1658 struct ieee80211com *ic = &usc->sc_sc.sc_ic;
1659 struct athn_usb_cmd_key *cmd = arg;
1660 int s;
1661
1662 usc->sc_key_tasks--;
1663
1664 s = splnet();
1665 athn_usb_write_barrier(&usc->sc_sc);
1666 athn_set_key(ic, cmd->ni, cmd->key);
1667 if (usc->sc_key_tasks == 0) {
1668 DPRINTF(("marking port %s valid\n",
1669 ether_sprintf(cmd->ni->ni_macaddr)));
1670 cmd->ni->ni_port_valid = 1;
1671 ieee80211_set_link_state(ic, LINK_STATE_UP);
1672 }
1673 if (cmd->ni != NULL)
1674 ieee80211_release_node(ic, cmd->ni);
1675 splx(s);
1676 }
1677
1678 void
athn_usb_delete_key(struct ieee80211com * ic,struct ieee80211_node * ni,struct ieee80211_key * k)1679 athn_usb_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
1680 struct ieee80211_key *k)
1681 {
1682 struct athn_usb_softc *usc = ic->ic_softc;
1683 struct athn_usb_cmd_key cmd;
1684
1685 if (!(ic->ic_if.if_flags & IFF_RUNNING) ||
1686 ic->ic_state != IEEE80211_S_RUN)
1687 return; /* Nothing to do. */
1688
1689 /* Do it in a process context. */
1690 cmd.ni = (ni != NULL) ? ieee80211_ref_node(ni) : NULL;
1691 cmd.key = k;
1692 athn_usb_do_async(usc, athn_usb_delete_key_cb, &cmd, sizeof(cmd));
1693 }
1694
1695 void
athn_usb_delete_key_cb(struct athn_usb_softc * usc,void * arg)1696 athn_usb_delete_key_cb(struct athn_usb_softc *usc, void *arg)
1697 {
1698 struct ieee80211com *ic = &usc->sc_sc.sc_ic;
1699 struct athn_usb_cmd_key *cmd = arg;
1700 int s;
1701
1702 s = splnet();
1703 athn_delete_key(ic, cmd->ni, cmd->key);
1704 if (cmd->ni != NULL)
1705 ieee80211_release_node(ic, cmd->ni);
1706 splx(s);
1707 }
1708
1709 #ifndef IEEE80211_STA_ONLY
1710 void
athn_usb_bcneof(struct usbd_xfer * xfer,void * priv,usbd_status status)1711 athn_usb_bcneof(struct usbd_xfer *xfer, void *priv,
1712 usbd_status status)
1713 {
1714 struct athn_usb_tx_data *data = priv;
1715 struct athn_usb_softc *usc = data->sc;
1716
1717 if (__predict_false(status == USBD_STALLED))
1718 usbd_clear_endpoint_stall_async(usc->tx_data_pipe);
1719 usc->tx_bcn = data;
1720 }
1721
1722 /*
1723 * Process Software Beacon Alert interrupts.
1724 */
1725 void
athn_usb_swba(struct athn_usb_softc * usc)1726 athn_usb_swba(struct athn_usb_softc *usc)
1727 {
1728 struct athn_softc *sc = &usc->sc_sc;
1729 struct ieee80211com *ic = &sc->sc_ic;
1730 struct athn_usb_tx_data *data;
1731 struct ieee80211_frame *wh;
1732 struct ar_stream_hdr *hdr;
1733 struct ar_htc_frame_hdr *htc;
1734 struct ar_tx_bcn *bcn;
1735 struct mbuf *m;
1736 int error;
1737
1738 if (ic->ic_dtim_count == 0)
1739 ic->ic_dtim_count = ic->ic_dtim_period - 1;
1740 else
1741 ic->ic_dtim_count--;
1742
1743 /* Make sure previous beacon has been sent. */
1744 if (usc->tx_bcn == NULL)
1745 return;
1746 data = usc->tx_bcn;
1747
1748 /* Get new beacon. */
1749 m = ieee80211_beacon_alloc(ic, ic->ic_bss);
1750 if (__predict_false(m == NULL))
1751 return;
1752 /* Assign sequence number. */
1753 wh = mtod(m, struct ieee80211_frame *);
1754 *(uint16_t *)&wh->i_seq[0] =
1755 htole16(ic->ic_bss->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);
1756 ic->ic_bss->ni_txseq++;
1757
1758 hdr = (struct ar_stream_hdr *)data->buf;
1759 hdr->tag = htole16(AR_USB_TX_STREAM_TAG);
1760 hdr->len = htole16(sizeof(*htc) + sizeof(*bcn) + m->m_pkthdr.len);
1761
1762 htc = (struct ar_htc_frame_hdr *)&hdr[1];
1763 memset(htc, 0, sizeof(*htc));
1764 htc->endpoint_id = usc->ep_bcn;
1765 htc->payload_len = htobe16(sizeof(*bcn) + m->m_pkthdr.len);
1766
1767 bcn = (struct ar_tx_bcn *)&htc[1];
1768 memset(bcn, 0, sizeof(*bcn));
1769 bcn->vif_idx = 0;
1770
1771 m_copydata(m, 0, m->m_pkthdr.len, &bcn[1]);
1772
1773 usbd_setup_xfer(data->xfer, usc->tx_data_pipe, data, data->buf,
1774 sizeof(*hdr) + sizeof(*htc) + sizeof(*bcn) + m->m_pkthdr.len,
1775 USBD_SHORT_XFER_OK | USBD_NO_COPY, ATHN_USB_TX_TIMEOUT,
1776 athn_usb_bcneof);
1777
1778 m_freem(m);
1779 usc->tx_bcn = NULL;
1780 error = usbd_transfer(data->xfer);
1781 if (__predict_false(error != USBD_IN_PROGRESS && error != 0))
1782 usc->tx_bcn = data;
1783 }
1784 #endif
1785
1786 /* Update current transmit rate for a node based on firmware Tx status. */
1787 void
athn_usb_tx_status(void * arg,struct ieee80211_node * ni)1788 athn_usb_tx_status(void *arg, struct ieee80211_node *ni)
1789 {
1790 struct ar_wmi_evt_txstatus *ts = arg;
1791 struct athn_node *an = (struct athn_node *)ni;
1792 uint8_t rate_index = (ts->rate & AR_HTC_TXSTAT_RATE);
1793
1794 if (an->sta_index != ts->cookie) /* Tx report for a different node */
1795 return;
1796
1797 if (ts->flags & AR_HTC_TXSTAT_MCS) {
1798 if (isset(ni->ni_rxmcs, rate_index))
1799 ni->ni_txmcs = rate_index;
1800 } else if (rate_index < ni->ni_rates.rs_nrates)
1801 ni->ni_txrate = rate_index;
1802 }
1803
1804 void
athn_usb_rx_wmi_ctrl(struct athn_usb_softc * usc,uint8_t * buf,int len)1805 athn_usb_rx_wmi_ctrl(struct athn_usb_softc *usc, uint8_t *buf, int len)
1806 {
1807 struct ar_wmi_cmd_hdr *wmi;
1808 uint16_t cmd_id;
1809
1810 if (__predict_false(len < sizeof(*wmi)))
1811 return;
1812 wmi = (struct ar_wmi_cmd_hdr *)buf;
1813 cmd_id = betoh16(wmi->cmd_id);
1814
1815 if (!(cmd_id & AR_WMI_EVT_FLAG)) {
1816 if (usc->wait_cmd_id != cmd_id)
1817 return; /* Unexpected reply. */
1818 if (usc->obuf != NULL) {
1819 /* Copy answer into caller supplied buffer. */
1820 memcpy(usc->obuf, &wmi[1], len - sizeof(*wmi));
1821 }
1822 /* Notify caller of completion. */
1823 wakeup(&usc->wait_cmd_id);
1824 return;
1825 }
1826 switch (cmd_id & 0xfff) {
1827 #ifndef IEEE80211_STA_ONLY
1828 case AR_WMI_EVT_SWBA:
1829 athn_usb_swba(usc);
1830 break;
1831 #endif
1832 case AR_WMI_EVT_TXSTATUS: {
1833 struct ar_wmi_evt_txstatus_list *tsl;
1834 int i;
1835
1836 tsl = (struct ar_wmi_evt_txstatus_list *)&wmi[1];
1837 for (i = 0; i < tsl->count && i < nitems(tsl->ts); i++) {
1838 struct ieee80211com *ic = &usc->sc_sc.sc_ic;
1839 struct athn_node *an = (struct athn_node *)ic->ic_bss;
1840 struct ar_wmi_evt_txstatus *ts = &tsl->ts[i];
1841 uint8_t qid;
1842
1843 /* Skip the node we use to send management frames. */
1844 if (ts->cookie == 0)
1845 continue;
1846
1847 /* Skip Tx reports for non-data frame endpoints. */
1848 qid = (ts->rate & AR_HTC_TXSTAT_EPID) >>
1849 AR_HTC_TXSTAT_EPID_SHIFT;
1850 if (qid != usc->ep_data[EDCA_AC_BE] &&
1851 qid != usc->ep_data[EDCA_AC_BK] &&
1852 qid != usc->ep_data[EDCA_AC_VI] &&
1853 qid != usc->ep_data[EDCA_AC_VO])
1854 continue;
1855
1856 if (ts->cookie == an->sta_index)
1857 athn_usb_tx_status(ts, ic->ic_bss);
1858 else
1859 ieee80211_iterate_nodes(ic, athn_usb_tx_status,
1860 ts);
1861 }
1862 break;
1863 }
1864 case AR_WMI_EVT_FATAL:
1865 printf("%s: fatal firmware error\n", usc->usb_dev.dv_xname);
1866 break;
1867 default:
1868 DPRINTF(("WMI event %d ignored\n", cmd_id));
1869 break;
1870 }
1871 }
1872
1873 void
athn_usb_intr(struct usbd_xfer * xfer,void * priv,usbd_status status)1874 athn_usb_intr(struct usbd_xfer *xfer, void *priv,
1875 usbd_status status)
1876 {
1877 struct athn_usb_softc *usc = priv;
1878 struct ar_htc_frame_hdr *htc;
1879 struct ar_htc_msg_hdr *msg;
1880 uint8_t *buf = usc->ibuf;
1881 uint16_t msg_id;
1882 int len;
1883
1884 if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
1885 DPRINTF(("intr status=%d\n", status));
1886 if (status == USBD_STALLED)
1887 usbd_clear_endpoint_stall_async(usc->rx_intr_pipe);
1888 else if (status == USBD_IOERROR) {
1889 /*
1890 * The device has gone away. If async commands are
1891 * pending or running ensure the device dies ASAP
1892 * and any blocked processes are woken up.
1893 */
1894 if (usc->cmdq.queued > 0)
1895 usbd_deactivate(usc->sc_udev);
1896 }
1897 return;
1898 }
1899 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
1900
1901 /* Skip watchdog pattern if present. */
1902 if (len >= 4 && *(uint32_t *)buf == htobe32(0x00c60000)) {
1903 buf += 4;
1904 len -= 4;
1905 }
1906 if (__predict_false(len < sizeof(*htc)))
1907 return;
1908 htc = (struct ar_htc_frame_hdr *)buf;
1909 /* Skip HTC header. */
1910 buf += sizeof(*htc);
1911 len -= sizeof(*htc);
1912
1913 if (htc->endpoint_id != 0) {
1914 if (__predict_false(htc->endpoint_id != usc->ep_ctrl))
1915 return;
1916 /* Remove trailer if present. */
1917 if (htc->flags & AR_HTC_FLAG_TRAILER) {
1918 if (__predict_false(len < htc->control[0]))
1919 return;
1920 len -= htc->control[0];
1921 }
1922 athn_usb_rx_wmi_ctrl(usc, buf, len);
1923 return;
1924 }
1925 /* Endpoint 0 carries HTC messages. */
1926 if (__predict_false(len < sizeof(*msg)))
1927 return;
1928 msg = (struct ar_htc_msg_hdr *)buf;
1929 msg_id = betoh16(msg->msg_id);
1930 DPRINTF(("Rx HTC message %d\n", msg_id));
1931 switch (msg_id) {
1932 case AR_HTC_MSG_READY:
1933 if (usc->wait_msg_id != msg_id)
1934 break;
1935 usc->wait_msg_id = 0;
1936 wakeup(&usc->wait_msg_id);
1937 break;
1938 case AR_HTC_MSG_CONN_SVC_RSP:
1939 if (usc->wait_msg_id != msg_id)
1940 break;
1941 if (usc->msg_conn_svc_rsp != NULL) {
1942 memcpy(usc->msg_conn_svc_rsp, &msg[1],
1943 sizeof(struct ar_htc_msg_conn_svc_rsp));
1944 }
1945 usc->wait_msg_id = 0;
1946 wakeup(&usc->wait_msg_id);
1947 break;
1948 case AR_HTC_MSG_CONF_PIPE_RSP:
1949 if (usc->wait_msg_id != msg_id)
1950 break;
1951 usc->wait_msg_id = 0;
1952 wakeup(&usc->wait_msg_id);
1953 break;
1954 default:
1955 DPRINTF(("HTC message %d ignored\n", msg_id));
1956 break;
1957 }
1958 }
1959
1960 #if NBPFILTER > 0
1961 void
athn_usb_rx_radiotap(struct athn_softc * sc,struct mbuf * m,struct ar_rx_status * rs)1962 athn_usb_rx_radiotap(struct athn_softc *sc, struct mbuf *m,
1963 struct ar_rx_status *rs)
1964 {
1965 #define IEEE80211_RADIOTAP_F_SHORTGI 0x80 /* XXX from FBSD */
1966
1967 struct athn_rx_radiotap_header *tap = &sc->sc_rxtap;
1968 struct ieee80211com *ic = &sc->sc_ic;
1969 struct mbuf mb;
1970 uint8_t rate;
1971
1972 tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
1973 tap->wr_tsft = htole64(betoh64(rs->rs_tstamp));
1974 tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
1975 tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
1976 tap->wr_dbm_antsignal = rs->rs_rssi;
1977 /* XXX noise. */
1978 tap->wr_antenna = rs->rs_antenna;
1979 tap->wr_rate = 0; /* In case it can't be found below. */
1980 rate = rs->rs_rate;
1981 if (rate & 0x80) { /* HT. */
1982 /* Bit 7 set means HT MCS instead of rate. */
1983 tap->wr_rate = rate;
1984 if (!(rs->rs_flags & AR_RXS_FLAG_GI))
1985 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI;
1986
1987 } else if (rate & 0x10) { /* CCK. */
1988 if (rate & 0x04)
1989 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
1990 switch (rate & ~0x14) {
1991 case 0xb: tap->wr_rate = 2; break;
1992 case 0xa: tap->wr_rate = 4; break;
1993 case 0x9: tap->wr_rate = 11; break;
1994 case 0x8: tap->wr_rate = 22; break;
1995 }
1996 } else { /* OFDM. */
1997 switch (rate) {
1998 case 0xb: tap->wr_rate = 12; break;
1999 case 0xf: tap->wr_rate = 18; break;
2000 case 0xa: tap->wr_rate = 24; break;
2001 case 0xe: tap->wr_rate = 36; break;
2002 case 0x9: tap->wr_rate = 48; break;
2003 case 0xd: tap->wr_rate = 72; break;
2004 case 0x8: tap->wr_rate = 96; break;
2005 case 0xc: tap->wr_rate = 108; break;
2006 }
2007 }
2008 mb.m_data = (caddr_t)tap;
2009 mb.m_len = sc->sc_rxtap_len;
2010 mb.m_next = m;
2011 mb.m_nextpkt = NULL;
2012 mb.m_type = 0;
2013 mb.m_flags = 0;
2014 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
2015 }
2016 #endif
2017
2018 void
athn_usb_rx_frame(struct athn_usb_softc * usc,struct mbuf * m,struct mbuf_list * ml)2019 athn_usb_rx_frame(struct athn_usb_softc *usc, struct mbuf *m,
2020 struct mbuf_list *ml)
2021 {
2022 struct athn_softc *sc = &usc->sc_sc;
2023 struct ieee80211com *ic = &sc->sc_ic;
2024 struct ifnet *ifp = &ic->ic_if;
2025 struct ieee80211_frame *wh;
2026 struct ieee80211_node *ni;
2027 struct ieee80211_rxinfo rxi;
2028 struct ar_htc_frame_hdr *htc;
2029 struct ar_rx_status *rs;
2030 uint16_t datalen;
2031 int s;
2032
2033 if (__predict_false(m->m_len < sizeof(*htc)))
2034 goto skip;
2035 htc = mtod(m, struct ar_htc_frame_hdr *);
2036 if (__predict_false(htc->endpoint_id == 0)) {
2037 DPRINTF(("bad endpoint %d\n", htc->endpoint_id));
2038 goto skip;
2039 }
2040 if (htc->flags & AR_HTC_FLAG_TRAILER) {
2041 if (m->m_len < htc->control[0])
2042 goto skip;
2043 m_adj(m, -(int)htc->control[0]);
2044 }
2045 m_adj(m, sizeof(*htc)); /* Strip HTC header. */
2046
2047 if (__predict_false(m->m_len < sizeof(*rs)))
2048 goto skip;
2049 rs = mtod(m, struct ar_rx_status *);
2050
2051 /* Make sure that payload fits. */
2052 datalen = betoh16(rs->rs_datalen);
2053 if (__predict_false(m->m_len < sizeof(*rs) + datalen))
2054 goto skip;
2055
2056 if (__predict_false(datalen < sizeof(*wh) + IEEE80211_CRC_LEN))
2057 goto skip;
2058
2059 if (rs->rs_status != 0) {
2060 if (rs->rs_status & AR_RXS_RXERR_DECRYPT)
2061 ic->ic_stats.is_ccmp_dec_errs++;
2062 ifp->if_ierrors++;
2063 goto skip;
2064 }
2065 m_adj(m, sizeof(*rs)); /* Strip Rx status. */
2066
2067 s = splnet();
2068
2069 /* Grab a reference to the source node. */
2070 wh = mtod(m, struct ieee80211_frame *);
2071 ni = ieee80211_find_rxnode(ic, wh);
2072
2073 /* Remove any HW padding after the 802.11 header. */
2074 if (!(wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL)) {
2075 u_int hdrlen = ieee80211_get_hdrlen(wh);
2076 if (hdrlen & 3) {
2077 memmove((caddr_t)wh + 2, wh, hdrlen);
2078 m_adj(m, 2);
2079 }
2080 wh = mtod(m, struct ieee80211_frame *);
2081 }
2082 #if NBPFILTER > 0
2083 if (__predict_false(sc->sc_drvbpf != NULL))
2084 athn_usb_rx_radiotap(sc, m, rs);
2085 #endif
2086 /* Trim 802.11 FCS after radiotap. */
2087 m_adj(m, -IEEE80211_CRC_LEN);
2088
2089 /* Send the frame to the 802.11 layer. */
2090 memset(&rxi, 0, sizeof(rxi));
2091 rxi.rxi_rssi = rs->rs_rssi + AR_USB_DEFAULT_NF;
2092 rxi.rxi_tstamp = betoh64(rs->rs_tstamp);
2093 if (!(wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL) &&
2094 (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
2095 (ic->ic_flags & IEEE80211_F_RSNON) &&
2096 (ni->ni_flags & IEEE80211_NODE_RXPROT) &&
2097 (ni->ni_rsncipher == IEEE80211_CIPHER_CCMP ||
2098 (IEEE80211_IS_MULTICAST(wh->i_addr1) &&
2099 ni->ni_rsngroupcipher == IEEE80211_CIPHER_CCMP))) {
2100 if (ar5008_ccmp_decap(sc, m, ni) != 0) {
2101 ifp->if_ierrors++;
2102 ieee80211_release_node(ic, ni);
2103 splx(s);
2104 goto skip;
2105 }
2106 rxi.rxi_flags |= IEEE80211_RXI_HWDEC;
2107 }
2108 ieee80211_inputm(ifp, m, ni, &rxi, ml);
2109
2110 /* Node is no longer needed. */
2111 ieee80211_release_node(ic, ni);
2112 splx(s);
2113 return;
2114 skip:
2115 m_freem(m);
2116 }
2117
2118 void
athn_usb_rxeof(struct usbd_xfer * xfer,void * priv,usbd_status status)2119 athn_usb_rxeof(struct usbd_xfer *xfer, void *priv,
2120 usbd_status status)
2121 {
2122 struct mbuf_list ml = MBUF_LIST_INITIALIZER();
2123 struct athn_usb_rx_data *data = priv;
2124 struct athn_usb_softc *usc = data->sc;
2125 struct athn_softc *sc = &usc->sc_sc;
2126 struct ifnet *ifp = &sc->sc_ic.ic_if;
2127 struct athn_usb_rx_stream *stream = &usc->rx_stream;
2128 uint8_t *buf = data->buf;
2129 struct ar_stream_hdr *hdr;
2130 struct mbuf *m;
2131 uint16_t pktlen;
2132 int off, len;
2133
2134 if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
2135 DPRINTF(("RX status=%d\n", status));
2136 if (status == USBD_STALLED)
2137 usbd_clear_endpoint_stall_async(usc->rx_data_pipe);
2138 if (status != USBD_CANCELLED)
2139 goto resubmit;
2140 return;
2141 }
2142 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
2143
2144 if (stream->left > 0) {
2145 if (len >= stream->left) {
2146 /* We have all our pktlen bytes now. */
2147 if (__predict_true(stream->m != NULL)) {
2148 memcpy(mtod(stream->m, uint8_t *) +
2149 stream->moff, buf, stream->left);
2150 athn_usb_rx_frame(usc, stream->m, &ml);
2151 stream->m = NULL;
2152 }
2153 /* Next header is 32-bit aligned. */
2154 off = (stream->left + 3) & ~3;
2155 buf += off;
2156 len -= off;
2157 stream->left = 0;
2158 } else {
2159 /* Still need more bytes, save what we have. */
2160 if (__predict_true(stream->m != NULL)) {
2161 memcpy(mtod(stream->m, uint8_t *) +
2162 stream->moff, buf, len);
2163 stream->moff += len;
2164 }
2165 stream->left -= len;
2166 goto resubmit;
2167 }
2168 }
2169 KASSERT(stream->left == 0);
2170 while (len >= sizeof(*hdr)) {
2171 hdr = (struct ar_stream_hdr *)buf;
2172 if (hdr->tag != htole16(AR_USB_RX_STREAM_TAG)) {
2173 DPRINTF(("invalid tag 0x%x\n", hdr->tag));
2174 break;
2175 }
2176 pktlen = letoh16(hdr->len);
2177 buf += sizeof(*hdr);
2178 len -= sizeof(*hdr);
2179
2180 if (__predict_true(pktlen <= MCLBYTES)) {
2181 /* Allocate an mbuf to store the next pktlen bytes. */
2182 MGETHDR(m, M_DONTWAIT, MT_DATA);
2183 if (__predict_true(m != NULL)) {
2184 m->m_pkthdr.len = m->m_len = pktlen;
2185 if (pktlen > MHLEN) {
2186 MCLGET(m, M_DONTWAIT);
2187 if (!(m->m_flags & M_EXT)) {
2188 m_free(m);
2189 m = NULL;
2190 }
2191 }
2192 }
2193 } else /* Drop frames larger than MCLBYTES. */
2194 m = NULL;
2195
2196 if (m == NULL)
2197 ifp->if_ierrors++;
2198
2199 /*
2200 * NB: m can be NULL, in which case the next pktlen bytes
2201 * will be discarded from the Rx stream.
2202 */
2203 if (pktlen > len) {
2204 /* Need more bytes, save what we have. */
2205 stream->m = m; /* NB: m can be NULL. */
2206 if (__predict_true(stream->m != NULL)) {
2207 memcpy(mtod(stream->m, uint8_t *), buf, len);
2208 stream->moff = len;
2209 }
2210 stream->left = pktlen - len;
2211 goto resubmit;
2212 }
2213 if (__predict_true(m != NULL)) {
2214 /* We have all the pktlen bytes in this xfer. */
2215 memcpy(mtod(m, uint8_t *), buf, pktlen);
2216 athn_usb_rx_frame(usc, m, &ml);
2217 }
2218
2219 /* Next header is 32-bit aligned. */
2220 off = (pktlen + 3) & ~3;
2221 buf += off;
2222 len -= off;
2223 }
2224 if_input(ifp, &ml);
2225
2226 resubmit:
2227 /* Setup a new transfer. */
2228 usbd_setup_xfer(xfer, usc->rx_data_pipe, data, data->buf,
2229 ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
2230 USBD_NO_TIMEOUT, athn_usb_rxeof);
2231 (void)usbd_transfer(xfer);
2232 }
2233
2234 void
athn_usb_txeof(struct usbd_xfer * xfer,void * priv,usbd_status status)2235 athn_usb_txeof(struct usbd_xfer *xfer, void *priv,
2236 usbd_status status)
2237 {
2238 struct athn_usb_tx_data *data = priv;
2239 struct athn_usb_softc *usc = data->sc;
2240 struct athn_softc *sc = &usc->sc_sc;
2241 struct ifnet *ifp = &sc->sc_ic.ic_if;
2242 int s;
2243
2244 s = splnet();
2245 /* Put this Tx buffer back to our free list. */
2246 TAILQ_INSERT_TAIL(&usc->tx_free_list, data, next);
2247
2248 if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
2249 DPRINTF(("TX status=%d\n", status));
2250 if (status == USBD_STALLED)
2251 usbd_clear_endpoint_stall_async(usc->tx_data_pipe);
2252 ifp->if_oerrors++;
2253 splx(s);
2254 /* XXX Why return? */
2255 return;
2256 }
2257 sc->sc_tx_timer = 0;
2258
2259 /* We just released a Tx buffer, notify Tx. */
2260 if (ifq_is_oactive(&ifp->if_snd)) {
2261 ifq_clr_oactive(&ifp->if_snd);
2262 ifp->if_start(ifp);
2263 }
2264 splx(s);
2265 }
2266
2267 int
athn_usb_tx(struct athn_softc * sc,struct mbuf * m,struct ieee80211_node * ni)2268 athn_usb_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
2269 {
2270 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
2271 struct athn_node *an = (struct athn_node *)ni;
2272 struct ieee80211com *ic = &sc->sc_ic;
2273 struct ieee80211_frame *wh;
2274 struct ieee80211_key *k = NULL;
2275 struct athn_usb_tx_data *data;
2276 struct ar_stream_hdr *hdr;
2277 struct ar_htc_frame_hdr *htc;
2278 struct ar_tx_frame *txf;
2279 struct ar_tx_mgmt *txm;
2280 uint8_t *frm;
2281 uint16_t qos;
2282 uint8_t qid, tid = 0;
2283 int hasqos, xferlen, error;
2284
2285 wh = mtod(m, struct ieee80211_frame *);
2286 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
2287 k = ieee80211_get_txkey(ic, wh, ni);
2288 if (k->k_cipher == IEEE80211_CIPHER_CCMP) {
2289 u_int hdrlen = ieee80211_get_hdrlen(wh);
2290 if (ar5008_ccmp_encap(m, hdrlen, k) != 0)
2291 return (ENOBUFS);
2292 } else {
2293 if ((m = ieee80211_encrypt(ic, m, k)) == NULL)
2294 return (ENOBUFS);
2295 k = NULL; /* skip hardware crypto further below */
2296 }
2297 wh = mtod(m, struct ieee80211_frame *);
2298 }
2299 if ((hasqos = ieee80211_has_qos(wh))) {
2300 qos = ieee80211_get_qos(wh);
2301 tid = qos & IEEE80211_QOS_TID;
2302 qid = ieee80211_up_to_ac(ic, tid);
2303 } else
2304 qid = EDCA_AC_BE;
2305
2306 /* Grab a Tx buffer from our free list. */
2307 data = TAILQ_FIRST(&usc->tx_free_list);
2308 TAILQ_REMOVE(&usc->tx_free_list, data, next);
2309
2310 #if NBPFILTER > 0
2311 /* XXX Change radiotap Tx header for USB (no txrate). */
2312 if (__predict_false(sc->sc_drvbpf != NULL)) {
2313 struct athn_tx_radiotap_header *tap = &sc->sc_txtap;
2314 struct mbuf mb;
2315
2316 tap->wt_flags = 0;
2317 tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
2318 tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
2319 mb.m_data = (caddr_t)tap;
2320 mb.m_len = sc->sc_txtap_len;
2321 mb.m_next = m;
2322 mb.m_nextpkt = NULL;
2323 mb.m_type = 0;
2324 mb.m_flags = 0;
2325 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
2326 }
2327 #endif
2328
2329 /* NB: We don't take advantage of USB Tx stream mode for now. */
2330 hdr = (struct ar_stream_hdr *)data->buf;
2331 hdr->tag = htole16(AR_USB_TX_STREAM_TAG);
2332
2333 htc = (struct ar_htc_frame_hdr *)&hdr[1];
2334 memset(htc, 0, sizeof(*htc));
2335 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
2336 IEEE80211_FC0_TYPE_DATA) {
2337 htc->endpoint_id = usc->ep_data[qid];
2338
2339 txf = (struct ar_tx_frame *)&htc[1];
2340 memset(txf, 0, sizeof(*txf));
2341 txf->data_type = AR_HTC_NORMAL;
2342 txf->node_idx = an->sta_index;
2343 txf->vif_idx = 0;
2344 txf->tid = tid;
2345 if (m->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold)
2346 txf->flags |= htobe32(AR_HTC_TX_RTSCTS);
2347 else if (ic->ic_flags & IEEE80211_F_USEPROT) {
2348 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
2349 txf->flags |= htobe32(AR_HTC_TX_CTSONLY);
2350 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
2351 txf->flags |= htobe32(AR_HTC_TX_RTSCTS);
2352 }
2353
2354 if (k != NULL) {
2355 /* Map 802.11 cipher to hardware encryption type. */
2356 if (k->k_cipher == IEEE80211_CIPHER_CCMP) {
2357 txf->key_type = AR_ENCR_TYPE_AES;
2358 } else
2359 panic("unsupported cipher");
2360 /*
2361 * NB: The key cache entry index is stored in the key
2362 * private field when the key is installed.
2363 */
2364 txf->key_idx = (uintptr_t)k->k_priv;
2365 } else
2366 txf->key_idx = 0xff;
2367
2368 txf->cookie = an->sta_index;
2369 frm = (uint8_t *)&txf[1];
2370 } else {
2371 htc->endpoint_id = usc->ep_mgmt;
2372
2373 txm = (struct ar_tx_mgmt *)&htc[1];
2374 memset(txm, 0, sizeof(*txm));
2375 txm->node_idx = an->sta_index;
2376 txm->vif_idx = 0;
2377 txm->key_idx = 0xff;
2378 txm->cookie = an->sta_index;
2379 frm = (uint8_t *)&txm[1];
2380 }
2381 /* Copy payload. */
2382 m_copydata(m, 0, m->m_pkthdr.len, frm);
2383 frm += m->m_pkthdr.len;
2384 m_freem(m);
2385
2386 /* Finalize headers. */
2387 htc->payload_len = htobe16(frm - (uint8_t *)&htc[1]);
2388 hdr->len = htole16(frm - (uint8_t *)&hdr[1]);
2389 xferlen = frm - data->buf;
2390
2391 usbd_setup_xfer(data->xfer, usc->tx_data_pipe, data, data->buf,
2392 xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, ATHN_USB_TX_TIMEOUT,
2393 athn_usb_txeof);
2394 error = usbd_transfer(data->xfer);
2395 if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) {
2396 /* Put this Tx buffer back to our free list. */
2397 TAILQ_INSERT_TAIL(&usc->tx_free_list, data, next);
2398 return (error);
2399 }
2400 ieee80211_release_node(ic, ni);
2401 return (0);
2402 }
2403
2404 void
athn_usb_start(struct ifnet * ifp)2405 athn_usb_start(struct ifnet *ifp)
2406 {
2407 struct athn_softc *sc = ifp->if_softc;
2408 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
2409 struct ieee80211com *ic = &sc->sc_ic;
2410 struct ieee80211_node *ni;
2411 struct mbuf *m;
2412
2413 if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
2414 return;
2415
2416 for (;;) {
2417 if (TAILQ_EMPTY(&usc->tx_free_list)) {
2418 ifq_set_oactive(&ifp->if_snd);
2419 break;
2420 }
2421 /* Send pending management frames first. */
2422 m = mq_dequeue(&ic->ic_mgtq);
2423 if (m != NULL) {
2424 ni = m->m_pkthdr.ph_cookie;
2425 goto sendit;
2426 }
2427 if (ic->ic_state != IEEE80211_S_RUN)
2428 break;
2429
2430 /* Encapsulate and send data frames. */
2431 m = ifq_dequeue(&ifp->if_snd);
2432 if (m == NULL)
2433 break;
2434 #if NBPFILTER > 0
2435 if (ifp->if_bpf != NULL)
2436 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
2437 #endif
2438 if ((m = ieee80211_encap(ifp, m, &ni)) == NULL)
2439 continue;
2440 sendit:
2441 #if NBPFILTER > 0
2442 if (ic->ic_rawbpf != NULL)
2443 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT);
2444 #endif
2445 if (athn_usb_tx(sc, m, ni) != 0) {
2446 ieee80211_release_node(ic, ni);
2447 ifp->if_oerrors++;
2448 continue;
2449 }
2450
2451 sc->sc_tx_timer = 5;
2452 ifp->if_timer = 1;
2453 }
2454 }
2455
2456 void
athn_usb_watchdog(struct ifnet * ifp)2457 athn_usb_watchdog(struct ifnet *ifp)
2458 {
2459 struct athn_softc *sc = ifp->if_softc;
2460
2461 ifp->if_timer = 0;
2462
2463 if (sc->sc_tx_timer > 0) {
2464 if (--sc->sc_tx_timer == 0) {
2465 printf("%s: device timeout\n", sc->sc_dev.dv_xname);
2466 /* athn_usb_init(ifp); XXX needs a process context! */
2467 ifp->if_oerrors++;
2468 return;
2469 }
2470 ifp->if_timer = 1;
2471 }
2472 ieee80211_watchdog(ifp);
2473 }
2474
2475 int
athn_usb_ioctl(struct ifnet * ifp,u_long cmd,caddr_t data)2476 athn_usb_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2477 {
2478 struct athn_softc *sc = ifp->if_softc;
2479 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
2480 struct ieee80211com *ic = &sc->sc_ic;
2481 int s, error = 0;
2482
2483 if (usbd_is_dying(usc->sc_udev))
2484 return ENXIO;
2485
2486 usbd_ref_incr(usc->sc_udev);
2487
2488 s = splnet();
2489
2490 switch (cmd) {
2491 case SIOCSIFADDR:
2492 ifp->if_flags |= IFF_UP;
2493 /* FALLTHROUGH */
2494 case SIOCSIFFLAGS:
2495 if (ifp->if_flags & IFF_UP) {
2496 if (!(ifp->if_flags & IFF_RUNNING))
2497 error = athn_usb_init(ifp);
2498 } else {
2499 if (ifp->if_flags & IFF_RUNNING)
2500 athn_usb_stop(ifp);
2501 }
2502 break;
2503 case SIOCS80211CHANNEL:
2504 error = ieee80211_ioctl(ifp, cmd, data);
2505 if (error == ENETRESET &&
2506 ic->ic_opmode == IEEE80211_M_MONITOR) {
2507 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
2508 (IFF_UP | IFF_RUNNING)) {
2509 athn_usb_switch_chan(sc, ic->ic_ibss_chan,
2510 NULL);
2511 }
2512 error = 0;
2513 }
2514 break;
2515 default:
2516 error = ieee80211_ioctl(ifp, cmd, data);
2517 }
2518
2519 if (error == ENETRESET) {
2520 error = 0;
2521 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
2522 (IFF_UP | IFF_RUNNING)) {
2523 athn_usb_stop(ifp);
2524 error = athn_usb_init(ifp);
2525 }
2526 }
2527 splx(s);
2528
2529 usbd_ref_decr(usc->sc_udev);
2530
2531 return (error);
2532 }
2533
2534 int
athn_usb_init(struct ifnet * ifp)2535 athn_usb_init(struct ifnet *ifp)
2536 {
2537 struct athn_softc *sc = ifp->if_softc;
2538 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
2539 struct athn_ops *ops = &sc->ops;
2540 struct ieee80211com *ic = &sc->sc_ic;
2541 struct ieee80211_channel *c, *extc;
2542 struct athn_usb_rx_data *data;
2543 struct ar_htc_target_vif hvif;
2544 struct ar_htc_target_sta sta;
2545 struct ar_htc_cap_target hic;
2546 uint16_t mode;
2547 int i, error;
2548
2549 /* Init host async commands ring. */
2550 usc->cmdq.cur = usc->cmdq.next = usc->cmdq.queued = 0;
2551
2552 /* Allocate Tx/Rx buffers. */
2553 error = athn_usb_alloc_rx_list(usc);
2554 if (error != 0)
2555 goto fail;
2556 error = athn_usb_alloc_tx_list(usc);
2557 if (error != 0)
2558 goto fail;
2559 /* Steal one buffer for beacons. */
2560 usc->tx_bcn = TAILQ_FIRST(&usc->tx_free_list);
2561 TAILQ_REMOVE(&usc->tx_free_list, usc->tx_bcn, next);
2562
2563 c = ic->ic_bss->ni_chan = ic->ic_ibss_chan;
2564 extc = NULL;
2565
2566 /* In case a new MAC address has been configured. */
2567 IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
2568
2569 error = athn_set_power_awake(sc);
2570 if (error != 0)
2571 goto fail;
2572
2573 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_FLUSH_RECV);
2574 if (error != 0)
2575 goto fail;
2576
2577 error = athn_hw_reset(sc, c, extc, 1);
2578 if (error != 0)
2579 goto fail;
2580
2581 ops->set_txpower(sc, c, extc);
2582
2583 mode = htobe16(IEEE80211_IS_CHAN_2GHZ(c) ?
2584 AR_HTC_MODE_11NG : AR_HTC_MODE_11NA);
2585 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_SET_MODE,
2586 &mode, sizeof(mode), NULL);
2587 if (error != 0)
2588 goto fail;
2589
2590 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_ATH_INIT);
2591 if (error != 0)
2592 goto fail;
2593
2594 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV);
2595 if (error != 0)
2596 goto fail;
2597
2598 athn_rx_start(sc);
2599
2600 /* Create main interface on target. */
2601 memset(&hvif, 0, sizeof(hvif));
2602 hvif.index = 0;
2603 IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_myaddr);
2604 switch (ic->ic_opmode) {
2605 case IEEE80211_M_STA:
2606 hvif.opmode = htobe32(AR_HTC_M_STA);
2607 break;
2608 case IEEE80211_M_MONITOR:
2609 hvif.opmode = htobe32(AR_HTC_M_MONITOR);
2610 break;
2611 #ifndef IEEE80211_STA_ONLY
2612 case IEEE80211_M_IBSS:
2613 hvif.opmode = htobe32(AR_HTC_M_IBSS);
2614 break;
2615 case IEEE80211_M_AHDEMO:
2616 hvif.opmode = htobe32(AR_HTC_M_AHDEMO);
2617 break;
2618 case IEEE80211_M_HOSTAP:
2619 hvif.opmode = htobe32(AR_HTC_M_HOSTAP);
2620 break;
2621 #endif
2622 }
2623 hvif.rtsthreshold = htobe16(ic->ic_rtsthreshold);
2624 DPRINTF(("creating VAP\n"));
2625 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_VAP_CREATE,
2626 &hvif, sizeof(hvif), NULL);
2627 if (error != 0)
2628 goto fail;
2629
2630 /* Create a fake node to send management frames before assoc. */
2631 memset(&sta, 0, sizeof(sta));
2632 IEEE80211_ADDR_COPY(sta.macaddr, ic->ic_myaddr);
2633 sta.sta_index = 0;
2634 sta.is_vif_sta = 1;
2635 sta.vif_index = hvif.index;
2636 sta.maxampdu = 0xffff;
2637 DPRINTF(("creating default node\n"));
2638 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_CREATE,
2639 &sta, sizeof(sta), NULL);
2640 if (error != 0)
2641 goto fail;
2642 usc->free_node_slots = ~(1 << sta.sta_index);
2643
2644 /* Update target capabilities. */
2645 memset(&hic, 0, sizeof(hic));
2646 hic.ampdu_limit = htobe32(0x0000ffff);
2647 hic.ampdu_subframes = 20;
2648 hic.txchainmask = sc->txchainmask;
2649 DPRINTF(("updating target configuration\n"));
2650 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TARGET_IC_UPDATE,
2651 &hic, sizeof(hic), NULL);
2652 if (error != 0)
2653 goto fail;
2654
2655 /* Queue Rx xfers. */
2656 for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) {
2657 data = &usc->rx_data[i];
2658
2659 usbd_setup_xfer(data->xfer, usc->rx_data_pipe, data, data->buf,
2660 ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
2661 USBD_NO_TIMEOUT, athn_usb_rxeof);
2662 error = usbd_transfer(data->xfer);
2663 if (error != 0 && error != USBD_IN_PROGRESS)
2664 goto fail;
2665 }
2666 /* We're ready to go. */
2667 ifp->if_flags |= IFF_RUNNING;
2668 ifq_clr_oactive(&ifp->if_snd);
2669
2670 #ifdef notyet
2671 if (ic->ic_flags & IEEE80211_F_WEPON) {
2672 /* Install WEP keys. */
2673 for (i = 0; i < IEEE80211_WEP_NKID; i++)
2674 athn_usb_set_key(ic, NULL, &ic->ic_nw_keys[i]);
2675 }
2676 #endif
2677 if (ic->ic_opmode == IEEE80211_M_MONITOR)
2678 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
2679 else
2680 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2681 athn_usb_wait_async(usc);
2682 return (0);
2683 fail:
2684 athn_usb_stop(ifp);
2685 return (error);
2686 }
2687
2688 void
athn_usb_stop(struct ifnet * ifp)2689 athn_usb_stop(struct ifnet *ifp)
2690 {
2691 struct athn_softc *sc = ifp->if_softc;
2692 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc;
2693 struct ieee80211com *ic = &sc->sc_ic;
2694 struct ar_htc_target_vif hvif;
2695 uint8_t sta_index;
2696 int s;
2697
2698 sc->sc_tx_timer = 0;
2699 ifp->if_timer = 0;
2700 ifp->if_flags &= ~IFF_RUNNING;
2701 ifq_clr_oactive(&ifp->if_snd);
2702
2703 s = splusb();
2704 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2705
2706 /* Wait for all async commands to complete. */
2707 athn_usb_wait_async(usc);
2708
2709 timeout_del(&sc->scan_to);
2710 timeout_del(&sc->calib_to);
2711
2712 /* Remove all non-default nodes. */
2713 for (sta_index = 1; sta_index < AR_USB_MAX_STA; sta_index++) {
2714 if (usc->free_node_slots & (1 << sta_index))
2715 continue;
2716 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE,
2717 &sta_index, sizeof(sta_index), NULL);
2718 }
2719
2720 /* Remove main interface. This also invalidates our default node. */
2721 memset(&hvif, 0, sizeof(hvif));
2722 hvif.index = 0;
2723 IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_myaddr);
2724 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_VAP_REMOVE,
2725 &hvif, sizeof(hvif), NULL);
2726
2727 usc->free_node_slots = 0xff;
2728
2729 (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR);
2730 (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_DRAIN_TXQ_ALL);
2731 (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_STOP_RECV);
2732
2733 athn_reset(sc, 0);
2734 athn_init_pll(sc, NULL);
2735 athn_set_power_awake(sc);
2736 athn_reset(sc, 1);
2737 athn_init_pll(sc, NULL);
2738 athn_set_power_sleep(sc);
2739
2740 /* Abort Tx/Rx. */
2741 usbd_abort_pipe(usc->tx_data_pipe);
2742 usbd_abort_pipe(usc->rx_data_pipe);
2743
2744 /* Free Tx/Rx buffers. */
2745 athn_usb_free_tx_list(usc);
2746 athn_usb_free_rx_list(usc);
2747 splx(s);
2748
2749 /* Flush Rx stream. */
2750 m_freem(usc->rx_stream.m);
2751 usc->rx_stream.m = NULL;
2752 usc->rx_stream.left = 0;
2753 }
2754