xref: /openbsd/sys/dev/usb/if_athn_usb.c (revision 77574026)
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