Deleted Added
full compact
if_iwi.c (167776) if_iwi.c (170530)
1/*-
2 * Copyright (c) 2004, 2005
3 * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
4 * Copyright (c) 2005-2006 Sam Leffler, Errno Consulting
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 13 unchanged lines hidden (view full) ---

22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2004, 2005
3 * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
4 * Copyright (c) 2005-2006 Sam Leffler, Errno Consulting
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 13 unchanged lines hidden (view full) ---

22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/dev/iwi/if_iwi.c 167776 2007-03-21 18:40:31Z jhb $");
30__FBSDID("$FreeBSD: head/sys/dev/iwi/if_iwi.c 170530 2007-06-11 03:36:55Z sam $");
31
32/*-
33 * Intel(R) PRO/Wireless 2200BG/2225BG/2915ABG driver
34 * http://www.intel.com/network/connectivity/products/wireless/prowireless_mobile.htm
35 */
36
37#include <sys/param.h>
38#include <sys/sysctl.h>

--- 28 unchanged lines hidden (view full) ---

67#include <net/if_arp.h>
68#include <net/ethernet.h>
69#include <net/if_dl.h>
70#include <net/if_media.h>
71#include <net/if_types.h>
72
73#include <net80211/ieee80211_var.h>
74#include <net80211/ieee80211_radiotap.h>
31
32/*-
33 * Intel(R) PRO/Wireless 2200BG/2225BG/2915ABG driver
34 * http://www.intel.com/network/connectivity/products/wireless/prowireless_mobile.htm
35 */
36
37#include <sys/param.h>
38#include <sys/sysctl.h>

--- 28 unchanged lines hidden (view full) ---

67#include <net/if_arp.h>
68#include <net/ethernet.h>
69#include <net/if_dl.h>
70#include <net/if_media.h>
71#include <net/if_types.h>
72
73#include <net80211/ieee80211_var.h>
74#include <net80211/ieee80211_radiotap.h>
75#include <net80211/ieee80211_regdomain.h>
75
76#include <netinet/in.h>
77#include <netinet/in_systm.h>
78#include <netinet/in_var.h>
79#include <netinet/ip.h>
80#include <netinet/if_ether.h>
81
82#include <dev/iwi/if_iwireg.h>

--- 49 unchanged lines hidden (view full) ---

132static void iwi_reset_rx_ring(struct iwi_softc *, struct iwi_rx_ring *);
133static void iwi_free_rx_ring(struct iwi_softc *, struct iwi_rx_ring *);
134static struct ieee80211_node *iwi_node_alloc(struct ieee80211_node_table *);
135static void iwi_node_free(struct ieee80211_node *);
136static int iwi_media_change(struct ifnet *);
137static void iwi_media_status(struct ifnet *, struct ifmediareq *);
138static int iwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
139static void iwi_wme_init(struct iwi_softc *);
76
77#include <netinet/in.h>
78#include <netinet/in_systm.h>
79#include <netinet/in_var.h>
80#include <netinet/ip.h>
81#include <netinet/if_ether.h>
82
83#include <dev/iwi/if_iwireg.h>

--- 49 unchanged lines hidden (view full) ---

133static void iwi_reset_rx_ring(struct iwi_softc *, struct iwi_rx_ring *);
134static void iwi_free_rx_ring(struct iwi_softc *, struct iwi_rx_ring *);
135static struct ieee80211_node *iwi_node_alloc(struct ieee80211_node_table *);
136static void iwi_node_free(struct ieee80211_node *);
137static int iwi_media_change(struct ifnet *);
138static void iwi_media_status(struct ifnet *, struct ifmediareq *);
139static int iwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
140static void iwi_wme_init(struct iwi_softc *);
140static void iwi_wme_setparams(void *, int);
141static int iwi_wme_setparams(struct iwi_softc *);
141static int iwi_wme_update(struct ieee80211com *);
142static uint16_t iwi_read_prom_word(struct iwi_softc *, uint8_t);
143static void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int,
144 struct iwi_frame *);
145static void iwi_notification_intr(struct iwi_softc *, struct iwi_notif *);
146static void iwi_rx_intr(struct iwi_softc *);
147static void iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *);
148static void iwi_intr(void *);
149static int iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t);
150static void iwi_write_ibssnode(struct iwi_softc *, const u_int8_t [], int);
151static int iwi_tx_start(struct ifnet *, struct mbuf *,
152 struct ieee80211_node *, int);
153static void iwi_start(struct ifnet *);
142static int iwi_wme_update(struct ieee80211com *);
143static uint16_t iwi_read_prom_word(struct iwi_softc *, uint8_t);
144static void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int,
145 struct iwi_frame *);
146static void iwi_notification_intr(struct iwi_softc *, struct iwi_notif *);
147static void iwi_rx_intr(struct iwi_softc *);
148static void iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *);
149static void iwi_intr(void *);
150static int iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t);
151static void iwi_write_ibssnode(struct iwi_softc *, const u_int8_t [], int);
152static int iwi_tx_start(struct ifnet *, struct mbuf *,
153 struct ieee80211_node *, int);
154static void iwi_start(struct ifnet *);
154static void iwi_watchdog(struct ifnet *);
155static void iwi_watchdog(void *);
155static int iwi_ioctl(struct ifnet *, u_long, caddr_t);
156static void iwi_stop_master(struct iwi_softc *);
157static int iwi_reset(struct iwi_softc *);
158static int iwi_load_ucode(struct iwi_softc *, const struct iwi_fw *);
159static int iwi_load_firmware(struct iwi_softc *, const struct iwi_fw *);
160static void iwi_release_fw_dma(struct iwi_softc *sc);
161static int iwi_config(struct iwi_softc *);
162static int iwi_get_firmware(struct iwi_softc *);
163static void iwi_put_firmware(struct iwi_softc *);
156static int iwi_ioctl(struct ifnet *, u_long, caddr_t);
157static void iwi_stop_master(struct iwi_softc *);
158static int iwi_reset(struct iwi_softc *);
159static int iwi_load_ucode(struct iwi_softc *, const struct iwi_fw *);
160static int iwi_load_firmware(struct iwi_softc *, const struct iwi_fw *);
161static void iwi_release_fw_dma(struct iwi_softc *sc);
162static int iwi_config(struct iwi_softc *);
163static int iwi_get_firmware(struct iwi_softc *);
164static void iwi_put_firmware(struct iwi_softc *);
165static int iwi_scanchan(struct iwi_softc *, unsigned long, int);
166static void iwi_scan_start(struct ieee80211com *);
167static void iwi_scan_end(struct ieee80211com *);
164static void iwi_scanabort(void *, int);
168static void iwi_scanabort(void *, int);
165static void iwi_scandone(void *, int);
166static void iwi_scanstart(void *, int);
167static void iwi_scanchan(void *, int);
169static void iwi_set_channel(struct ieee80211com *);
170static void iwi_scan_curchan(struct ieee80211com *, unsigned long maxdwell);
171#if 0
172static void iwi_scan_allchan(struct ieee80211com *, unsigned long maxdwell);
173#endif
174static void iwi_scan_mindwell(struct ieee80211com *);
175static void iwi_assoc(struct ieee80211com *ic);
176static void iwi_disassoc(struct ieee80211com *);
177static void iwi_ops(void *, int);
178static int iwi_queue_cmd(struct iwi_softc *, int);
168static int iwi_auth_and_assoc(struct iwi_softc *);
169static int iwi_disassociate(struct iwi_softc *, int quiet);
179static int iwi_auth_and_assoc(struct iwi_softc *);
180static int iwi_disassociate(struct iwi_softc *, int quiet);
170static void iwi_down(void *, int);
171static void iwi_init(void *);
172static void iwi_init_locked(void *, int);
173static void iwi_stop(void *);
174static void iwi_restart(void *, int);
175static int iwi_getrfkill(struct iwi_softc *);
176static void iwi_radio_on(void *, int);
177static void iwi_radio_off(void *, int);
178static void iwi_sysctlattach(struct iwi_softc *);

--- 63 unchanged lines hidden (view full) ---

242
243static int
244iwi_attach(device_t dev)
245{
246 struct iwi_softc *sc = device_get_softc(dev);
247 struct ifnet *ifp;
248 struct ieee80211com *ic = &sc->sc_ic;
249 uint16_t val;
181static void iwi_init(void *);
182static void iwi_init_locked(void *, int);
183static void iwi_stop(void *);
184static void iwi_restart(void *, int);
185static int iwi_getrfkill(struct iwi_softc *);
186static void iwi_radio_on(void *, int);
187static void iwi_radio_off(void *, int);
188static void iwi_sysctlattach(struct iwi_softc *);

--- 63 unchanged lines hidden (view full) ---

252
253static int
254iwi_attach(device_t dev)
255{
256 struct iwi_softc *sc = device_get_softc(dev);
257 struct ifnet *ifp;
258 struct ieee80211com *ic = &sc->sc_ic;
259 uint16_t val;
250 int error, i;
260 int i, error, bands;
251
252 sc->sc_dev = dev;
253
261
262 sc->sc_dev = dev;
263
254 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
255 MTX_DEF);
264 IWI_LOCK_INIT(sc);
265 IWI_CMD_LOCK_INIT(sc);
256
257 sc->sc_unr = new_unrhdr(1, IWI_MAX_IBSSNODE-1, &sc->sc_mtx);
258
259#if __FreeBSD_version >= 700000
266
267 sc->sc_unr = new_unrhdr(1, IWI_MAX_IBSSNODE-1, &sc->sc_mtx);
268
269#if __FreeBSD_version >= 700000
260 sc->sc_tq = taskqueue_create("iwi_taskq", M_NOWAIT,
270 sc->sc_tq = taskqueue_create("iwi_taskq", M_NOWAIT | M_ZERO,
261 taskqueue_thread_enqueue, &sc->sc_tq);
262 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
263 device_get_nameunit(dev));
264#else
271 taskqueue_thread_enqueue, &sc->sc_tq);
272 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
273 device_get_nameunit(dev));
274#else
265 sc->sc_tq = taskqueue_create("iwi_taskq", M_NOWAIT,
275 sc->sc_tq = taskqueue_create("iwi_taskq", M_NOWAIT | M_ZERO,
266 taskqueue_thread_enqueue, &sc->sc_tq, &sc->sc_tqproc);
267 kthread_create(taskqueue_thread_loop, &sc->sc_tq, &sc->sc_tqproc,
268 0, 0, "%s taskq", device_get_nameunit(dev));
269#endif
270 TASK_INIT(&sc->sc_radiontask, 0, iwi_radio_on, sc);
271 TASK_INIT(&sc->sc_radiofftask, 0, iwi_radio_off, sc);
276 taskqueue_thread_enqueue, &sc->sc_tq, &sc->sc_tqproc);
277 kthread_create(taskqueue_thread_loop, &sc->sc_tq, &sc->sc_tqproc,
278 0, 0, "%s taskq", device_get_nameunit(dev));
279#endif
280 TASK_INIT(&sc->sc_radiontask, 0, iwi_radio_on, sc);
281 TASK_INIT(&sc->sc_radiofftask, 0, iwi_radio_off, sc);
272 TASK_INIT(&sc->sc_scanstarttask, 0, iwi_scanstart, sc);
273 TASK_INIT(&sc->sc_scanaborttask, 0, iwi_scanabort, sc);
274 TASK_INIT(&sc->sc_scandonetask, 0, iwi_scandone, sc);
275 TASK_INIT(&sc->sc_scantask, 0, iwi_scanchan, sc);
276 TASK_INIT(&sc->sc_setwmetask, 0, iwi_wme_setparams, sc);
277 TASK_INIT(&sc->sc_downtask, 0, iwi_down, sc);
278 TASK_INIT(&sc->sc_restarttask, 0, iwi_restart, sc);
282 TASK_INIT(&sc->sc_restarttask, 0, iwi_restart, sc);
283 TASK_INIT(&sc->sc_opstask, 0, iwi_ops, sc);
284 TASK_INIT(&sc->sc_scanaborttask, 0, iwi_scanabort, sc);
285 callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0);
279
280 if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
281 device_printf(dev, "chip is in D%d power mode "
282 "-- setting to D0\n", pci_get_powerstate(dev));
283 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
284 }
285
286 pci_write_config(dev, 0x41, 0, 1);

--- 51 unchanged lines hidden (view full) ---

338
339 iwi_wme_init(sc);
340
341 ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
342 if (ifp == NULL) {
343 device_printf(dev, "can not if_alloc()\n");
344 goto fail;
345 }
286
287 if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
288 device_printf(dev, "chip is in D%d power mode "
289 "-- setting to D0\n", pci_get_powerstate(dev));
290 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
291 }
292
293 pci_write_config(dev, 0x41, 0, 1);

--- 51 unchanged lines hidden (view full) ---

345
346 iwi_wme_init(sc);
347
348 ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
349 if (ifp == NULL) {
350 device_printf(dev, "can not if_alloc()\n");
351 goto fail;
352 }
353 ic->ic_ifp = ifp;
346 ifp->if_softc = sc;
347 if_initname(ifp, device_get_name(dev), device_get_unit(dev));
348 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
349 ifp->if_init = iwi_init;
350 ifp->if_ioctl = iwi_ioctl;
351 ifp->if_start = iwi_start;
354 ifp->if_softc = sc;
355 if_initname(ifp, device_get_name(dev), device_get_unit(dev));
356 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
357 ifp->if_init = iwi_init;
358 ifp->if_ioctl = iwi_ioctl;
359 ifp->if_start = iwi_start;
352 ifp->if_watchdog = iwi_watchdog;
353 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
354 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
355 IFQ_SET_READY(&ifp->if_snd);
356
360 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
361 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
362 IFQ_SET_READY(&ifp->if_snd);
363
357 ic->ic_ifp = ifp;
358 ic->ic_wme.wme_update = iwi_wme_update;
359 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
360 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
361 ic->ic_state = IEEE80211_S_INIT;
362
363 /* set device capabilities */
364 ic->ic_caps =
364 ic->ic_wme.wme_update = iwi_wme_update;
365 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
366 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
367 ic->ic_state = IEEE80211_S_INIT;
368
369 /* set device capabilities */
370 ic->ic_caps =
365 IEEE80211_C_IBSS | /* IBSS mode supported */
366 IEEE80211_C_MONITOR | /* monitor mode supported */
367 IEEE80211_C_PMGT | /* power save supported */
368 IEEE80211_C_SHPREAMBLE | /* short preamble supported */
369 IEEE80211_C_WPA | /* 802.11i */
370 IEEE80211_C_WME; /* 802.11e */
371 IEEE80211_C_IBSS /* IBSS mode supported */
372 | IEEE80211_C_MONITOR /* monitor mode supported */
373 | IEEE80211_C_PMGT /* power save supported */
374 | IEEE80211_C_SHPREAMBLE /* short preamble supported */
375 | IEEE80211_C_WPA /* 802.11i */
376 | IEEE80211_C_WME /* 802.11e */
377 | IEEE80211_C_BGSCAN /* capable of bg scanning */
378 ;
371
372 /* read MAC address from EEPROM */
373 val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 0);
374 ic->ic_myaddr[0] = val & 0xff;
375 ic->ic_myaddr[1] = val >> 8;
376 val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 1);
377 ic->ic_myaddr[2] = val & 0xff;
378 ic->ic_myaddr[3] = val >> 8;
379 val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 2);
380 ic->ic_myaddr[4] = val & 0xff;
381 ic->ic_myaddr[5] = val >> 8;
379
380 /* read MAC address from EEPROM */
381 val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 0);
382 ic->ic_myaddr[0] = val & 0xff;
383 ic->ic_myaddr[1] = val >> 8;
384 val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 1);
385 ic->ic_myaddr[2] = val & 0xff;
386 ic->ic_myaddr[3] = val >> 8;
387 val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 2);
388 ic->ic_myaddr[4] = val & 0xff;
389 ic->ic_myaddr[5] = val >> 8;
390
391 bands = 0;
392 setbit(&bands, IEEE80211_MODE_11B);
393 setbit(&bands, IEEE80211_MODE_11G);
394 if (pci_get_device(dev) >= 0x4223)
395 setbit(&bands, IEEE80211_MODE_11A);
396 ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1);
382
397
383 if (pci_get_device(dev) >= 0x4223) {
384 /* set supported .11a channels */
385 for (i = 36; i <= 64; i += 4) {
386 ic->ic_channels[i].ic_freq =
387 ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
388 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
389 }
390 for (i = 149; i <= 165; i += 4) {
391 ic->ic_channels[i].ic_freq =
392 ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
393 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
394 }
395 }
396
397 /* set supported .11b and .11g channels (1 through 14) */
398 for (i = 1; i <= 14; i++) {
399 ic->ic_channels[i].ic_freq =
400 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
401 ic->ic_channels[i].ic_flags =
402 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
403 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
404 }
405
406 ieee80211_ifattach(ic);
407 ic->ic_bmissthreshold = 10; /* override default */
408 /* override default methods */
409 ic->ic_node_alloc = iwi_node_alloc;
410 sc->sc_node_free = ic->ic_node_free;
411 ic->ic_node_free = iwi_node_free;
398 ieee80211_ifattach(ic);
399 ic->ic_bmissthreshold = 10; /* override default */
400 /* override default methods */
401 ic->ic_node_alloc = iwi_node_alloc;
402 sc->sc_node_free = ic->ic_node_free;
403 ic->ic_node_free = iwi_node_free;
404 ic->ic_scan_start = iwi_scan_start;
405 ic->ic_scan_end = iwi_scan_end;
406 ic->ic_set_channel = iwi_set_channel;
407 ic->ic_scan_curchan = iwi_scan_curchan;
408 ic->ic_scan_mindwell = iwi_scan_mindwell;
409
412 /* override state transition machine */
413 sc->sc_newstate = ic->ic_newstate;
414 ic->ic_newstate = iwi_newstate;
415 ieee80211_media_init(ic, iwi_media_change, iwi_media_status);
416
417 bpfattach2(ifp, DLT_IEEE802_11_RADIO,
418 sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap),
419 &sc->sc_drvbpf);

--- 29 unchanged lines hidden (view full) ---

449}
450
451static int
452iwi_detach(device_t dev)
453{
454 struct iwi_softc *sc = device_get_softc(dev);
455 struct ieee80211com *ic = &sc->sc_ic;
456 struct ifnet *ifp = ic->ic_ifp;
410 /* override state transition machine */
411 sc->sc_newstate = ic->ic_newstate;
412 ic->ic_newstate = iwi_newstate;
413 ieee80211_media_init(ic, iwi_media_change, iwi_media_status);
414
415 bpfattach2(ifp, DLT_IEEE802_11_RADIO,
416 sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap),
417 &sc->sc_drvbpf);

--- 29 unchanged lines hidden (view full) ---

447}
448
449static int
450iwi_detach(device_t dev)
451{
452 struct iwi_softc *sc = device_get_softc(dev);
453 struct ieee80211com *ic = &sc->sc_ic;
454 struct ifnet *ifp = ic->ic_ifp;
455 IWI_LOCK_DECL;
457
458 if (ifp != NULL) {
456
457 if (ifp != NULL) {
458 IWI_LOCK(sc);
459 iwi_stop(sc);
459 iwi_stop(sc);
460 IWI_UNLOCK(sc);
460 bpfdetach(ifp);
461 ieee80211_ifdetach(ic);
462 }
461 bpfdetach(ifp);
462 ieee80211_ifdetach(ic);
463 }
464
465 callout_drain(&sc->sc_wdtimer);
463 iwi_put_firmware(sc);
464 iwi_release_fw_dma(sc);
465
466 iwi_free_cmd_ring(sc, &sc->cmdq);
467 iwi_free_tx_ring(sc, &sc->txq[0]);
468 iwi_free_tx_ring(sc, &sc->txq[1]);
469 iwi_free_tx_ring(sc, &sc->txq[2]);
470 iwi_free_tx_ring(sc, &sc->txq[3]);

--- 10 unchanged lines hidden (view full) ---

481 if (ifp != NULL)
482 if_free(ifp);
483
484 taskqueue_free(sc->sc_tq);
485
486 if (sc->sc_unr != NULL)
487 delete_unrhdr(sc->sc_unr);
488
466 iwi_put_firmware(sc);
467 iwi_release_fw_dma(sc);
468
469 iwi_free_cmd_ring(sc, &sc->cmdq);
470 iwi_free_tx_ring(sc, &sc->txq[0]);
471 iwi_free_tx_ring(sc, &sc->txq[1]);
472 iwi_free_tx_ring(sc, &sc->txq[2]);
473 iwi_free_tx_ring(sc, &sc->txq[3]);

--- 10 unchanged lines hidden (view full) ---

484 if (ifp != NULL)
485 if_free(ifp);
486
487 taskqueue_free(sc->sc_tq);
488
489 if (sc->sc_unr != NULL)
490 delete_unrhdr(sc->sc_unr);
491
489 mtx_destroy(&sc->sc_mtx);
492 IWI_LOCK_DESTROY(sc);
493 IWI_CMD_LOCK_DESTROY(sc);
490
491 return 0;
492}
493
494static void
495iwi_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
496{
497 if (error != 0)

--- 290 unchanged lines hidden (view full) ---

788 if (ring->data_dmat != NULL)
789 bus_dma_tag_destroy(ring->data_dmat);
790}
791
792static int
793iwi_shutdown(device_t dev)
794{
795 struct iwi_softc *sc = device_get_softc(dev);
494
495 return 0;
496}
497
498static void
499iwi_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
500{
501 if (error != 0)

--- 290 unchanged lines hidden (view full) ---

792 if (ring->data_dmat != NULL)
793 bus_dma_tag_destroy(ring->data_dmat);
794}
795
796static int
797iwi_shutdown(device_t dev)
798{
799 struct iwi_softc *sc = device_get_softc(dev);
800 IWI_LOCK_DECL;
796
801
802 IWI_LOCK(sc);
797 iwi_stop(sc);
803 iwi_stop(sc);
804 IWI_UNLOCK(sc);
798 iwi_put_firmware(sc); /* ??? XXX */
799
800 return 0;
801}
802
803static int
804iwi_suspend(device_t dev)
805{
806 struct iwi_softc *sc = device_get_softc(dev);
805 iwi_put_firmware(sc); /* ??? XXX */
806
807 return 0;
808}
809
810static int
811iwi_suspend(device_t dev)
812{
813 struct iwi_softc *sc = device_get_softc(dev);
814 IWI_LOCK_DECL;
807
815
816 IWI_LOCK(sc);
808 iwi_stop(sc);
817 iwi_stop(sc);
818 IWI_UNLOCK(sc);
809
810 return 0;
811}
812
813static int
814iwi_resume(device_t dev)
815{
816 struct iwi_softc *sc = device_get_softc(dev);

--- 113 unchanged lines hidden (view full) ---

930 imr->ifm_active |= IFM_IEEE80211_MONITOR;
931}
932
933static int
934iwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
935{
936 struct ifnet *ifp = ic->ic_ifp;
937 struct iwi_softc *sc = ifp->if_softc;
819
820 return 0;
821}
822
823static int
824iwi_resume(device_t dev)
825{
826 struct iwi_softc *sc = device_get_softc(dev);

--- 113 unchanged lines hidden (view full) ---

940 imr->ifm_active |= IFM_IEEE80211_MONITOR;
941}
942
943static int
944iwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
945{
946 struct ifnet *ifp = ic->ic_ifp;
947 struct iwi_softc *sc = ifp->if_softc;
948 int error = 0;
938
949
939 IWI_LOCK_CHECK(sc);
950 IWI_LOCK_ASSERT(sc);
940 DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__,
941 ieee80211_state_name[ic->ic_state],
942 ieee80211_state_name[nstate], sc->flags));
943
944 /* XXX state change race with taskqueue */
945 switch (nstate) {
951 DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__,
952 ieee80211_state_name[ic->ic_state],
953 ieee80211_state_name[nstate], sc->flags));
954
955 /* XXX state change race with taskqueue */
956 switch (nstate) {
946 case IEEE80211_S_SCAN:
947 if (ic->ic_state == IEEE80211_S_RUN) {
948 /*
949 * Beacon miss, send disassoc and wait for a reply
950 * from the card; we'll start a scan then. Note
951 * this only happens with auto roaming; otherwise
952 * just notify users and wait to be directed.
953 */
954 /* notify directly as we bypass net80211 */
955 ieee80211_sta_leave(ic, ic->ic_bss);
956 if (ic->ic_roaming == IEEE80211_ROAMING_AUTO)
957 taskqueue_enqueue(sc->sc_tq, &sc->sc_downtask);
958 break;
959 }
960 if ((sc->flags & IWI_FLAG_SCANNING) == 0) {
961 sc->flags |= IWI_FLAG_SCANNING;
962 taskqueue_enqueue(sc->sc_tq, &sc->sc_scanstarttask);
963 }
964 break;
965
966 case IEEE80211_S_AUTH:
957 case IEEE80211_S_AUTH:
967 iwi_auth_and_assoc(sc);
958 iwi_assoc(ic);
968 break;
959 break;
969
970 case IEEE80211_S_RUN:
971 if (ic->ic_opmode == IEEE80211_M_IBSS) {
972 /*
973 * XXX when joining an ibss network we are called
974 * with a SCAN -> RUN transition on scan complete.
975 * Use that to call iwi_auth_and_assoc. On completing
976 * the join we are then called again with an
977 * AUTH -> RUN transition and we want to do nothing.
978 * This is all totally bogus and needs to be redone.
979 */
980 if (ic->ic_state == IEEE80211_S_SCAN)
960 case IEEE80211_S_RUN:
961 if (ic->ic_opmode == IEEE80211_M_IBSS) {
962 /*
963 * XXX when joining an ibss network we are called
964 * with a SCAN -> RUN transition on scan complete.
965 * Use that to call iwi_auth_and_assoc. On completing
966 * the join we are then called again with an
967 * AUTH -> RUN transition and we want to do nothing.
968 * This is all totally bogus and needs to be redone.
969 */
970 if (ic->ic_state == IEEE80211_S_SCAN)
981 iwi_auth_and_assoc(sc);
982 } else if (ic->ic_opmode == IEEE80211_M_MONITOR)
983 taskqueue_enqueue(sc->sc_tq, &sc->sc_scantask);
984
985 /* XXX way wrong */
986 return sc->sc_newstate(ic, nstate,
987 IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
988
989 case IEEE80211_S_ASSOC:
971 iwi_assoc(ic);
972 }
990 break;
973 break;
991
992 case IEEE80211_S_INIT:
993 /*
994 * NB: don't try to do this if iwi_stop_master has
995 * shutdown the firmware and disabled interrupts.
996 */
997 if (ic->ic_state == IEEE80211_S_RUN &&
998 (sc->flags & IWI_FLAG_FW_INITED))
974 case IEEE80211_S_INIT:
975 /*
976 * NB: don't try to do this if iwi_stop_master has
977 * shutdown the firmware and disabled interrupts.
978 */
979 if (ic->ic_state == IEEE80211_S_RUN &&
980 (sc->flags & IWI_FLAG_FW_INITED))
999 taskqueue_enqueue(sc->sc_tq, &sc->sc_downtask);
981 iwi_disassoc(ic);
982 if (ic->ic_state == IEEE80211_S_SCAN &&
983 (sc->fw_state == IWI_FW_SCANNING))
984 ieee80211_cancel_scan(ic);
1000 break;
985 break;
986 case IEEE80211_S_ASSOC:
987 /*
988 * If we are not transitioning from AUTH the resend the
989 * association request.
990 */
991 if (ic->ic_state != IEEE80211_S_AUTH)
992 iwi_assoc(ic);
993 break;
994 default:
995 break;
1001 }
996 }
997 return (error != 0) ? error : sc->sc_newstate(ic, nstate, arg);
1002
998
1003 ic->ic_state = nstate;
1004 return 0;
1005}
1006
1007/*
1008 * WME parameters coming from IEEE 802.11e specification. These values are
1009 * already declared in ieee80211_proto.c, but they are static so they can't
1010 * be reused here.
1011 */
1012static const struct wmeParams iwi_wme_cck_params[WME_NUM_AC] = {

--- 34 unchanged lines hidden (view full) ---

1047 sc->wme[2].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
1048 sc->wme[2].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
1049 sc->wme[2].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
1050 sc->wme[2].acm[ac] = wmep->wmep_acm;
1051 }
1052}
1053
1054static int
999}
1000
1001/*
1002 * WME parameters coming from IEEE 802.11e specification. These values are
1003 * already declared in ieee80211_proto.c, but they are static so they can't
1004 * be reused here.
1005 */
1006static const struct wmeParams iwi_wme_cck_params[WME_NUM_AC] = {

--- 34 unchanged lines hidden (view full) ---

1041 sc->wme[2].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
1042 sc->wme[2].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
1043 sc->wme[2].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
1044 sc->wme[2].acm[ac] = wmep->wmep_acm;
1045 }
1046}
1047
1048static int
1055iwi_wme_setparams_locked(struct iwi_softc *sc)
1049iwi_wme_setparams(struct iwi_softc *sc)
1056{
1057 struct ieee80211com *ic = &sc->sc_ic;
1058 const struct wmeParams *wmep;
1059 int ac;
1060
1061 for (ac = 0; ac < WME_NUM_AC; ac++) {
1062 /* set WME values for current operating mode */
1063 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
1064 sc->wme[0].aifsn[ac] = wmep->wmep_aifsn;
1065 sc->wme[0].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
1066 sc->wme[0].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
1067 sc->wme[0].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
1068 sc->wme[0].acm[ac] = wmep->wmep_acm;
1069 }
1070
1071 DPRINTF(("Setting WME parameters\n"));
1072 return iwi_cmd(sc, IWI_CMD_SET_WME_PARAMS, sc->wme, sizeof sc->wme);
1073}
1050{
1051 struct ieee80211com *ic = &sc->sc_ic;
1052 const struct wmeParams *wmep;
1053 int ac;
1054
1055 for (ac = 0; ac < WME_NUM_AC; ac++) {
1056 /* set WME values for current operating mode */
1057 wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
1058 sc->wme[0].aifsn[ac] = wmep->wmep_aifsn;
1059 sc->wme[0].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
1060 sc->wme[0].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
1061 sc->wme[0].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
1062 sc->wme[0].acm[ac] = wmep->wmep_acm;
1063 }
1064
1065 DPRINTF(("Setting WME parameters\n"));
1066 return iwi_cmd(sc, IWI_CMD_SET_WME_PARAMS, sc->wme, sizeof sc->wme);
1067}
1074
1075static void
1076iwi_wme_setparams(void *arg, int npending)
1077{
1078 struct iwi_softc *sc = arg;
1079 IWI_LOCK_DECL;
1080
1081 IWI_LOCK(sc);
1082 (void) iwi_wme_setparams_locked(sc);
1083 IWI_UNLOCK(sc);
1084}
1085#undef IWI_USEC
1086#undef IWI_EXP2
1087
1088static int
1089iwi_wme_update(struct ieee80211com *ic)
1090{
1091 struct iwi_softc *sc = ic->ic_ifp->if_softc;
1092
1093 /*
1094 * We may be called to update the WME parameters in
1095 * the adapter at various places. If we're already
1096 * associated then initiate the request immediately
1097 * (via the taskqueue); otherwise we assume the params
1098 * will get sent down to the adapter as part of the
1099 * work iwi_auth_and_assoc does.
1100 */
1068#undef IWI_USEC
1069#undef IWI_EXP2
1070
1071static int
1072iwi_wme_update(struct ieee80211com *ic)
1073{
1074 struct iwi_softc *sc = ic->ic_ifp->if_softc;
1075
1076 /*
1077 * We may be called to update the WME parameters in
1078 * the adapter at various places. If we're already
1079 * associated then initiate the request immediately
1080 * (via the taskqueue); otherwise we assume the params
1081 * will get sent down to the adapter as part of the
1082 * work iwi_auth_and_assoc does.
1083 */
1101 if (ic->ic_state == IEEE80211_S_RUN)
1102 taskqueue_enqueue(sc->sc_tq, &sc->sc_setwmetask);
1103 return 0;
1084 return (iwi_queue_cmd(sc, IWI_SET_WME));
1104}
1105
1106static int
1107iwi_wme_setie(struct iwi_softc *sc)
1108{
1109 struct ieee80211_wme_info wme;
1110
1111 memset(&wme, 0, sizeof wme);

--- 66 unchanged lines hidden (view full) ---

1178 return val;
1179}
1180
1181static void
1182iwi_setcurchan(struct iwi_softc *sc, int chan)
1183{
1184 struct ieee80211com *ic = &sc->sc_ic;
1185
1085}
1086
1087static int
1088iwi_wme_setie(struct iwi_softc *sc)
1089{
1090 struct ieee80211_wme_info wme;
1091
1092 memset(&wme, 0, sizeof wme);

--- 66 unchanged lines hidden (view full) ---

1159 return val;
1160}
1161
1162static void
1163iwi_setcurchan(struct iwi_softc *sc, int chan)
1164{
1165 struct ieee80211com *ic = &sc->sc_ic;
1166
1186 IWI_LOCK_CHECK(sc);
1187 ic->ic_curchan = &ic->ic_channels[chan];
1188 sc->curchan = chan;
1189
1190 sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq =
1191 htole16(ic->ic_curchan->ic_freq);
1192 sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags =
1193 htole16(ic->ic_curchan->ic_flags);
1194}
1195

--- 87 unchanged lines hidden (view full) ---

1283
1284 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
1285 }
1286 IWI_UNLOCK(sc);
1287
1288 ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
1289
1290 /* send the frame to the 802.11 layer */
1167 sc->curchan = chan;
1168
1169 sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq =
1170 htole16(ic->ic_curchan->ic_freq);
1171 sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags =
1172 htole16(ic->ic_curchan->ic_flags);
1173}
1174

--- 87 unchanged lines hidden (view full) ---

1262
1263 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
1264 }
1265 IWI_UNLOCK(sc);
1266
1267 ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
1268
1269 /* send the frame to the 802.11 layer */
1291 type = ieee80211_input(ic, m, ni, frame->rssi_dbm, 0);
1270 type = ieee80211_input(ic, m, ni, frame->rssi_dbm, 0, 0);
1292
1293 /* node is no longer needed */
1294 ieee80211_free_node(ni);
1295
1296 IWI_LOCK(sc);
1297 if (sc->sc_softled) {
1298 /*
1299 * Blink for any data frame. Otherwise do a

--- 42 unchanged lines hidden (view full) ---

1342 * done in the driver.
1343 */
1344static void
1345iwi_checkforqos(struct iwi_softc *sc, const struct ieee80211_frame *wh, int len)
1346{
1347#define SUBTYPE(wh) ((wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK)
1348 const uint8_t *frm, *efrm, *wme;
1349 struct ieee80211_node *ni;
1271
1272 /* node is no longer needed */
1273 ieee80211_free_node(ni);
1274
1275 IWI_LOCK(sc);
1276 if (sc->sc_softled) {
1277 /*
1278 * Blink for any data frame. Otherwise do a

--- 42 unchanged lines hidden (view full) ---

1321 * done in the driver.
1322 */
1323static void
1324iwi_checkforqos(struct iwi_softc *sc, const struct ieee80211_frame *wh, int len)
1325{
1326#define SUBTYPE(wh) ((wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK)
1327 const uint8_t *frm, *efrm, *wme;
1328 struct ieee80211_node *ni;
1329 uint16_t capinfo, status, associd;
1350
1351 /* NB: +8 for capinfo, status, associd, and first ie */
1352 if (!(sizeof(*wh)+8 < len && len < IEEE80211_MAX_LEN) ||
1353 SUBTYPE(wh) != IEEE80211_FC0_SUBTYPE_ASSOC_RESP)
1354 return;
1355 /*
1356 * asresp frame format
1357 * [2] capability information
1358 * [2] status
1359 * [2] association ID
1360 * [tlv] supported rates
1361 * [tlv] extended supported rates
1362 * [tlv] WME
1363 */
1364 frm = (const uint8_t *)&wh[1];
1365 efrm = ((const uint8_t *) wh) + len;
1330
1331 /* NB: +8 for capinfo, status, associd, and first ie */
1332 if (!(sizeof(*wh)+8 < len && len < IEEE80211_MAX_LEN) ||
1333 SUBTYPE(wh) != IEEE80211_FC0_SUBTYPE_ASSOC_RESP)
1334 return;
1335 /*
1336 * asresp frame format
1337 * [2] capability information
1338 * [2] status
1339 * [2] association ID
1340 * [tlv] supported rates
1341 * [tlv] extended supported rates
1342 * [tlv] WME
1343 */
1344 frm = (const uint8_t *)&wh[1];
1345 efrm = ((const uint8_t *) wh) + len;
1366 frm += 6;
1367
1346
1347 capinfo = le16toh(*(const uint16_t *)frm);
1348 frm += 2;
1349 status = le16toh(*(const uint16_t *)frm);
1350 frm += 2;
1351 associd = le16toh(*(const uint16_t *)frm);
1352 frm += 2;
1353
1368 wme = NULL;
1369 while (frm < efrm) {
1370 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1]);
1371 switch (*frm) {
1372 case IEEE80211_ELEMID_VENDOR:
1373 if (iswmeoui(frm))
1374 wme = frm;
1375 break;
1376 }
1377 frm += frm[1] + 2;
1378 }
1379
1380 ni = sc->sc_ic.ic_bss;
1354 wme = NULL;
1355 while (frm < efrm) {
1356 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1]);
1357 switch (*frm) {
1358 case IEEE80211_ELEMID_VENDOR:
1359 if (iswmeoui(frm))
1360 wme = frm;
1361 break;
1362 }
1363 frm += frm[1] + 2;
1364 }
1365
1366 ni = sc->sc_ic.ic_bss;
1367 ni->ni_capinfo = capinfo;
1368 ni->ni_associd = associd;
1381 if (wme != NULL)
1382 ni->ni_flags |= IEEE80211_NODE_QOS;
1383 else
1384 ni->ni_flags &= ~IEEE80211_NODE_QOS;
1385#undef SUBTYPE
1386}
1387
1388static void

--- 6 unchanged lines hidden (view full) ---

1395 struct iwi_notif_association *assoc;
1396 struct iwi_notif_beacon_state *beacon;
1397
1398 switch (notif->type) {
1399 case IWI_NOTIF_TYPE_SCAN_CHANNEL:
1400 chan = (struct iwi_notif_scan_channel *)(notif + 1);
1401
1402 DPRINTFN(3, ("Scan of channel %u complete (%u)\n",
1369 if (wme != NULL)
1370 ni->ni_flags |= IEEE80211_NODE_QOS;
1371 else
1372 ni->ni_flags &= ~IEEE80211_NODE_QOS;
1373#undef SUBTYPE
1374}
1375
1376static void

--- 6 unchanged lines hidden (view full) ---

1383 struct iwi_notif_association *assoc;
1384 struct iwi_notif_beacon_state *beacon;
1385
1386 switch (notif->type) {
1387 case IWI_NOTIF_TYPE_SCAN_CHANNEL:
1388 chan = (struct iwi_notif_scan_channel *)(notif + 1);
1389
1390 DPRINTFN(3, ("Scan of channel %u complete (%u)\n",
1403 ic->ic_channels[chan->nchan].ic_freq, chan->nchan));
1391 ieee80211_ieee2mhz(chan->nchan, 0), chan->nchan));
1392
1393 /* Reset the timer, the scan is still going */
1394 sc->sc_state_timer = 3;
1404 break;
1405
1406 case IWI_NOTIF_TYPE_SCAN_COMPLETE:
1407 scan = (struct iwi_notif_scan_complete *)(notif + 1);
1408
1409 DPRINTFN(2, ("Scan completed (%u, %u)\n", scan->nchan,
1410 scan->status));
1411
1395 break;
1396
1397 case IWI_NOTIF_TYPE_SCAN_COMPLETE:
1398 scan = (struct iwi_notif_scan_complete *)(notif + 1);
1399
1400 DPRINTFN(2, ("Scan completed (%u, %u)\n", scan->nchan,
1401 scan->status));
1402
1412 sc->sc_scan_timer = 0;
1403 IWI_STATE_END(sc, IWI_FW_SCANNING);
1413
1404
1414 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
1415 /*
1416 * Monitor mode works by doing a passive scan to set
1417 * the channel and enable rx. Because we don't want
1418 * to abort a scan lest the firmware crash we scan
1419 * for a short period of time and automatically restart
1420 * the scan when notified the sweep has completed.
1421 */
1422 taskqueue_enqueue(sc->sc_tq, &sc->sc_scantask);
1423 } else {
1424 sc->flags &= ~IWI_FLAG_SCANNING;
1425 taskqueue_enqueue(sc->sc_tq, &sc->sc_scandonetask);
1426 }
1405 if (scan->status == IWI_SCAN_COMPLETED)
1406 ieee80211_scan_next(ic);
1407
1427 break;
1428
1429 case IWI_NOTIF_TYPE_AUTHENTICATION:
1430 auth = (struct iwi_notif_authentication *)(notif + 1);
1431
1432 switch (auth->state) {
1433 case IWI_AUTH_SUCCESS:
1434 DPRINTFN(2, ("Authentication succeeeded\n"));
1435 ieee80211_node_authorize(ic->ic_bss);
1436 ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1);
1437 break;
1438
1439 case IWI_AUTH_FAIL:
1440 DPRINTFN(2, ("Authentication failed\n"));
1441 sc->flags &= ~IWI_FLAG_ASSOCIATED;
1408 break;
1409
1410 case IWI_NOTIF_TYPE_AUTHENTICATION:
1411 auth = (struct iwi_notif_authentication *)(notif + 1);
1412
1413 switch (auth->state) {
1414 case IWI_AUTH_SUCCESS:
1415 DPRINTFN(2, ("Authentication succeeeded\n"));
1416 ieee80211_node_authorize(ic->ic_bss);
1417 ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1);
1418 break;
1419
1420 case IWI_AUTH_FAIL:
1421 DPRINTFN(2, ("Authentication failed\n"));
1422 sc->flags &= ~IWI_FLAG_ASSOCIATED;
1423 IWI_STATE_END(sc, IWI_FW_ASSOCIATING);
1442 /* XXX */
1443 break;
1444
1445 case IWI_AUTH_SENT_1:
1446 case IWI_AUTH_RECV_2:
1447 case IWI_AUTH_SEQ1_PASS:
1448 break;
1449
1450 case IWI_AUTH_SEQ1_FAIL:
1451 DPRINTFN(2, ("Initial authentication handshake failed; "
1452 "you probably need shared key\n"));
1424 /* XXX */
1425 break;
1426
1427 case IWI_AUTH_SENT_1:
1428 case IWI_AUTH_RECV_2:
1429 case IWI_AUTH_SEQ1_PASS:
1430 break;
1431
1432 case IWI_AUTH_SEQ1_FAIL:
1433 DPRINTFN(2, ("Initial authentication handshake failed; "
1434 "you probably need shared key\n"));
1435 IWI_STATE_END(sc, IWI_FW_ASSOCIATING);
1453 /* XXX retry shared key when in auto */
1454 break;
1455
1456 default:
1457 device_printf(sc->sc_dev,
1458 "unknown authentication state %u\n", auth->state);
1459 }
1460 break;

--- 4 unchanged lines hidden (view full) ---

1465 switch (assoc->state) {
1466 case IWI_AUTH_SUCCESS:
1467 /* re-association, do nothing */
1468 break;
1469
1470 case IWI_ASSOC_SUCCESS:
1471 DPRINTFN(2, ("Association succeeded\n"));
1472 sc->flags |= IWI_FLAG_ASSOCIATED;
1436 /* XXX retry shared key when in auto */
1437 break;
1438
1439 default:
1440 device_printf(sc->sc_dev,
1441 "unknown authentication state %u\n", auth->state);
1442 }
1443 break;

--- 4 unchanged lines hidden (view full) ---

1448 switch (assoc->state) {
1449 case IWI_AUTH_SUCCESS:
1450 /* re-association, do nothing */
1451 break;
1452
1453 case IWI_ASSOC_SUCCESS:
1454 DPRINTFN(2, ("Association succeeded\n"));
1455 sc->flags |= IWI_FLAG_ASSOCIATED;
1456 IWI_STATE_END(sc, IWI_FW_ASSOCIATING);
1473 iwi_checkforqos(sc,
1474 (const struct ieee80211_frame *)(assoc+1),
1475 le16toh(notif->len) - sizeof(*assoc));
1476 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
1477 break;
1478
1457 iwi_checkforqos(sc,
1458 (const struct ieee80211_frame *)(assoc+1),
1459 le16toh(notif->len) - sizeof(*assoc));
1460 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
1461 break;
1462
1479 case IWI_ASSOC_FAIL:
1480 DPRINTFN(2, ("Association failed\n"));
1463 case IWI_ASSOC_INIT:
1464 switch (sc->fw_state) {
1465 case IWI_FW_ASSOCIATING:
1466 DPRINTFN(2, ("Association failed\n"));
1467 IWI_STATE_END(sc, IWI_FW_ASSOCIATING);
1468 ieee80211_new_state(ic,
1469 IEEE80211_S_SCAN, -1);
1470 break;
1471
1472 case IWI_FW_DISASSOCIATING:
1473 DPRINTFN(2, ("Dissassociated\n"));
1474 IWI_STATE_END(sc,
1475 IWI_FW_DISASSOCIATING);
1476 break;
1477 }
1481 sc->flags &= ~IWI_FLAG_ASSOCIATED;
1478 sc->flags &= ~IWI_FLAG_ASSOCIATED;
1482 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
1483 break;
1484
1485 default:
1486 device_printf(sc->sc_dev,
1487 "unknown association state %u\n", assoc->state);
1488 }
1489 break;
1490
1491 case IWI_NOTIF_TYPE_BEACON:
1492 /* XXX check struct length */
1493 beacon = (struct iwi_notif_beacon_state *)(notif + 1);
1494
1495 DPRINTFN(5, ("Beacon state (%u, %u)\n",
1496 beacon->state, le32toh(beacon->number)));
1497
1498 if (beacon->state == IWI_BEACON_MISS) {
1479 break;
1480
1481 default:
1482 device_printf(sc->sc_dev,
1483 "unknown association state %u\n", assoc->state);
1484 }
1485 break;
1486
1487 case IWI_NOTIF_TYPE_BEACON:
1488 /* XXX check struct length */
1489 beacon = (struct iwi_notif_beacon_state *)(notif + 1);
1490
1491 DPRINTFN(5, ("Beacon state (%u, %u)\n",
1492 beacon->state, le32toh(beacon->number)));
1493
1494 if (beacon->state == IWI_BEACON_MISS) {
1499#if 0
1500 if (sc->flags & IWI_FLAG_SCANNING) {
1501 /* XXX terminate scan, linux driver
1502 says fw can get stuck */
1503 /* XXX should be handled in iwi_newstate */
1504 taskqueue_enqueue(sc->sc_tq,
1505 &sc->sc_scanaborttask);
1506 }
1507#endif
1508 /*
1509 * The firmware notifies us of every beacon miss
1510 * so we need to track the count against the
1511 * configured threshold before notifying the
1512 * 802.11 layer.
1513 * XXX try to roam, drop assoc only on much higher count
1514 */
1515 if (le32toh(beacon->number) >= ic->ic_bmissthreshold) {

--- 71 unchanged lines hidden (view full) ---

1587 hw = CSR_READ_4(sc, txq->csr_ridx);
1588
1589 for (; txq->next != hw;) {
1590 data = &txq->data[txq->next];
1591
1592 bus_dmamap_sync(txq->data_dmat, data->map,
1593 BUS_DMASYNC_POSTWRITE);
1594 bus_dmamap_unload(txq->data_dmat, data->map);
1495 /*
1496 * The firmware notifies us of every beacon miss
1497 * so we need to track the count against the
1498 * configured threshold before notifying the
1499 * 802.11 layer.
1500 * XXX try to roam, drop assoc only on much higher count
1501 */
1502 if (le32toh(beacon->number) >= ic->ic_bmissthreshold) {

--- 71 unchanged lines hidden (view full) ---

1574 hw = CSR_READ_4(sc, txq->csr_ridx);
1575
1576 for (; txq->next != hw;) {
1577 data = &txq->data[txq->next];
1578
1579 bus_dmamap_sync(txq->data_dmat, data->map,
1580 BUS_DMASYNC_POSTWRITE);
1581 bus_dmamap_unload(txq->data_dmat, data->map);
1582 if (data->m->m_flags & M_TXCB)
1583 ieee80211_process_callback(data->ni, data->m, 0/*XXX*/);
1595 m_freem(data->m);
1596 data->m = NULL;
1597 ieee80211_free_node(data->ni);
1598 data->ni = NULL;
1599
1600 DPRINTFN(15, ("tx done idx=%u\n", txq->next));
1601
1602 ifp->if_opackets++;

--- 25 unchanged lines hidden (view full) ---

1628 return;
1629 }
1630
1631 /* acknowledge interrupts */
1632 CSR_WRITE_4(sc, IWI_CSR_INTR, r);
1633
1634 if (r & IWI_INTR_FATAL_ERROR) {
1635 device_printf(sc->sc_dev, "firmware error\n");
1584 m_freem(data->m);
1585 data->m = NULL;
1586 ieee80211_free_node(data->ni);
1587 data->ni = NULL;
1588
1589 DPRINTFN(15, ("tx done idx=%u\n", txq->next));
1590
1591 ifp->if_opackets++;

--- 25 unchanged lines hidden (view full) ---

1617 return;
1618 }
1619
1620 /* acknowledge interrupts */
1621 CSR_WRITE_4(sc, IWI_CSR_INTR, r);
1622
1623 if (r & IWI_INTR_FATAL_ERROR) {
1624 device_printf(sc->sc_dev, "firmware error\n");
1636 taskqueue_enqueue(sc->sc_tq, &sc->sc_restarttask);
1625 /* don't restart if the interface isn't up */
1626 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
1627 taskqueue_enqueue(sc->sc_tq, &sc->sc_restarttask);
1628
1629 sc->flags &= ~IWI_FLAG_BUSY;
1630 sc->sc_busy_timer = 0;
1631 wakeup(sc);
1637 }
1638
1639 if (r & IWI_INTR_FW_INITED) {
1640 if (!(r & (IWI_INTR_FATAL_ERROR | IWI_INTR_PARITY_ERROR)))
1641 wakeup(sc);
1642 }
1643
1644 if (r & IWI_INTR_RADIO_OFF)
1645 taskqueue_enqueue(sc->sc_tq, &sc->sc_radiofftask);
1646
1647 if (r & IWI_INTR_CMD_DONE) {
1648 sc->flags &= ~IWI_FLAG_BUSY;
1632 }
1633
1634 if (r & IWI_INTR_FW_INITED) {
1635 if (!(r & (IWI_INTR_FATAL_ERROR | IWI_INTR_PARITY_ERROR)))
1636 wakeup(sc);
1637 }
1638
1639 if (r & IWI_INTR_RADIO_OFF)
1640 taskqueue_enqueue(sc->sc_tq, &sc->sc_radiofftask);
1641
1642 if (r & IWI_INTR_CMD_DONE) {
1643 sc->flags &= ~IWI_FLAG_BUSY;
1644 sc->sc_busy_timer = 0;
1649 wakeup(sc);
1650 }
1651
1652 if (r & IWI_INTR_TX1_DONE)
1653 iwi_tx_intr(sc, &sc->txq[0]);
1654
1655 if (r & IWI_INTR_TX2_DONE)
1656 iwi_tx_intr(sc, &sc->txq[1]);

--- 15 unchanged lines hidden (view full) ---

1672 IWI_UNLOCK(sc);
1673}
1674
1675static int
1676iwi_cmd(struct iwi_softc *sc, uint8_t type, void *data, uint8_t len)
1677{
1678 struct iwi_cmd_desc *desc;
1679
1645 wakeup(sc);
1646 }
1647
1648 if (r & IWI_INTR_TX1_DONE)
1649 iwi_tx_intr(sc, &sc->txq[0]);
1650
1651 if (r & IWI_INTR_TX2_DONE)
1652 iwi_tx_intr(sc, &sc->txq[1]);

--- 15 unchanged lines hidden (view full) ---

1668 IWI_UNLOCK(sc);
1669}
1670
1671static int
1672iwi_cmd(struct iwi_softc *sc, uint8_t type, void *data, uint8_t len)
1673{
1674 struct iwi_cmd_desc *desc;
1675
1680 IWI_LOCK_CHECK(sc);
1676 IWI_LOCK_ASSERT(sc);
1681
1682 if (sc->flags & IWI_FLAG_BUSY) {
1683 device_printf(sc->sc_dev, "%s: cmd %d not sent, busy\n",
1684 __func__, type);
1685 return EAGAIN;
1686 }
1687 sc->flags |= IWI_FLAG_BUSY;
1677
1678 if (sc->flags & IWI_FLAG_BUSY) {
1679 device_printf(sc->sc_dev, "%s: cmd %d not sent, busy\n",
1680 __func__, type);
1681 return EAGAIN;
1682 }
1683 sc->flags |= IWI_FLAG_BUSY;
1684 sc->sc_busy_timer = 2;
1688
1689 desc = &sc->cmdq.desc[sc->cmdq.cur];
1690
1691 desc->hdr.type = IWI_HDR_TYPE_COMMAND;
1692 desc->hdr.flags = IWI_HDR_FLAG_IRQ;
1693 desc->type = type;
1694 desc->len = len;
1695 memcpy(desc->data, data, len);

--- 40 unchanged lines hidden (view full) ---

1736 struct iwi_tx_ring *txq = &sc->txq[ac];
1737 struct iwi_tx_data *data;
1738 struct iwi_tx_desc *desc;
1739 struct mbuf *mnew;
1740 bus_dma_segment_t segs[IWI_MAX_NSEG];
1741 int error, nsegs, hdrlen, i;
1742 int ismcast, flags, xflags, staid;
1743
1685
1686 desc = &sc->cmdq.desc[sc->cmdq.cur];
1687
1688 desc->hdr.type = IWI_HDR_TYPE_COMMAND;
1689 desc->hdr.flags = IWI_HDR_FLAG_IRQ;
1690 desc->type = type;
1691 desc->len = len;
1692 memcpy(desc->data, data, len);

--- 40 unchanged lines hidden (view full) ---

1733 struct iwi_tx_ring *txq = &sc->txq[ac];
1734 struct iwi_tx_data *data;
1735 struct iwi_tx_desc *desc;
1736 struct mbuf *mnew;
1737 bus_dma_segment_t segs[IWI_MAX_NSEG];
1738 int error, nsegs, hdrlen, i;
1739 int ismcast, flags, xflags, staid;
1740
1744 IWI_LOCK_CHECK(sc);
1741 IWI_LOCK_ASSERT(sc);
1745 wh = mtod(m0, const struct ieee80211_frame *);
1746 /* NB: only data frames use this path */
1747 hdrlen = ieee80211_hdrsize(wh);
1748 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
1749 flags = xflags = 0;
1750
1751 if (!ismcast)
1752 flags |= IWI_DATA_FLAG_NEED_ACK;

--- 214 unchanged lines hidden (view full) ---

1967
1968 if (iwi_tx_start(ifp, m0, ni, ac) != 0) {
1969 ieee80211_free_node(ni);
1970 ifp->if_oerrors++;
1971 break;
1972 }
1973
1974 sc->sc_tx_timer = 5;
1742 wh = mtod(m0, const struct ieee80211_frame *);
1743 /* NB: only data frames use this path */
1744 hdrlen = ieee80211_hdrsize(wh);
1745 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
1746 flags = xflags = 0;
1747
1748 if (!ismcast)
1749 flags |= IWI_DATA_FLAG_NEED_ACK;

--- 214 unchanged lines hidden (view full) ---

1964
1965 if (iwi_tx_start(ifp, m0, ni, ac) != 0) {
1966 ieee80211_free_node(ni);
1967 ifp->if_oerrors++;
1968 break;
1969 }
1970
1971 sc->sc_tx_timer = 5;
1975 ifp->if_timer = 1;
1976 }
1977
1978 IWI_UNLOCK(sc);
1979}
1980
1981static void
1972 }
1973
1974 IWI_UNLOCK(sc);
1975}
1976
1977static void
1982iwi_watchdog(struct ifnet *ifp)
1978iwi_watchdog(void *arg)
1983{
1979{
1984 struct iwi_softc *sc = ifp->if_softc;
1985 struct ieee80211com *ic = &sc->sc_ic;
1986 IWI_LOCK_DECL;
1980 struct iwi_softc *sc = arg;
1981 struct ifnet *ifp = sc->sc_ifp;
1987
1982
1988 IWI_LOCK(sc);
1983 IWI_LOCK_ASSERT(sc);
1989
1990 if (sc->sc_tx_timer > 0) {
1991 if (--sc->sc_tx_timer == 0) {
1992 if_printf(ifp, "device timeout\n");
1993 ifp->if_oerrors++;
1994 taskqueue_enqueue(sc->sc_tq, &sc->sc_restarttask);
1995 }
1996 }

--- 5 unchanged lines hidden (view full) ---

2002 * it is enabled so we must poll for the latter.
2003 */
2004 if (!iwi_getrfkill(sc))
2005 taskqueue_enqueue(sc->sc_tq, &sc->sc_radiontask);
2006 else
2007 sc->sc_rfkill_timer = 2;
2008 }
2009 }
1984
1985 if (sc->sc_tx_timer > 0) {
1986 if (--sc->sc_tx_timer == 0) {
1987 if_printf(ifp, "device timeout\n");
1988 ifp->if_oerrors++;
1989 taskqueue_enqueue(sc->sc_tq, &sc->sc_restarttask);
1990 }
1991 }

--- 5 unchanged lines hidden (view full) ---

1997 * it is enabled so we must poll for the latter.
1998 */
1999 if (!iwi_getrfkill(sc))
2000 taskqueue_enqueue(sc->sc_tq, &sc->sc_radiontask);
2001 else
2002 sc->sc_rfkill_timer = 2;
2003 }
2004 }
2010 if (sc->sc_scan_timer > 0) {
2011 if (--sc->sc_scan_timer == 0) {
2012 if (sc->flags & IWI_FLAG_SCANNING) {
2013 if_printf(ifp, "scan stuck\n");
2014 taskqueue_enqueue(sc->sc_tq, &sc->sc_restarttask);
2015 }
2005 if (sc->sc_state_timer > 0) {
2006 if (--sc->sc_state_timer == 0) {
2007 if_printf(ifp, "firmware stuck in state %d, resetting\n",
2008 sc->fw_state);
2009 taskqueue_enqueue(sc->sc_tq, &sc->sc_restarttask);
2010 if (sc->fw_state == IWI_FW_SCANNING)
2011 ieee80211_cancel_scan(&sc->sc_ic);
2012 sc->sc_state_timer = 3;
2016 }
2017 }
2013 }
2014 }
2018 if (sc->sc_tx_timer || sc->sc_rfkill_timer || sc->sc_scan_timer)
2019 ifp->if_timer = 1;
2020 else
2021 ifp->if_timer = 0;
2015 if (sc->sc_busy_timer > 0) {
2016 if (--sc->sc_busy_timer == 0) {
2017 if_printf(ifp, "firmware command timeout, resetting\n");
2018 taskqueue_enqueue(sc->sc_tq, &sc->sc_restarttask);
2019 }
2020 }
2022
2021
2023 ieee80211_watchdog(ic);
2024
2025 IWI_UNLOCK(sc);
2022 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
2023 callout_reset(&sc->sc_wdtimer, hz, iwi_watchdog, sc);
2026}
2027
2028static int
2029iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2030{
2031 struct iwi_softc *sc = ifp->if_softc;
2032 struct ieee80211com *ic = &sc->sc_ic;
2033 int error = 0;

--- 45 unchanged lines hidden (view full) ---

2079}
2080
2081static void
2082iwi_stop_master(struct iwi_softc *sc)
2083{
2084 uint32_t tmp;
2085 int ntries;
2086
2024}
2025
2026static int
2027iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2028{
2029 struct iwi_softc *sc = ifp->if_softc;
2030 struct ieee80211com *ic = &sc->sc_ic;
2031 int error = 0;

--- 45 unchanged lines hidden (view full) ---

2077}
2078
2079static void
2080iwi_stop_master(struct iwi_softc *sc)
2081{
2082 uint32_t tmp;
2083 int ntries;
2084
2087 IWI_LOCK_CHECK(sc);
2088
2089 /* disable interrupts */
2090 CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, 0);
2091
2092 CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_STOP_MASTER);
2093 for (ntries = 0; ntries < 5; ntries++) {
2094 if (CSR_READ_4(sc, IWI_CSR_RST) & IWI_RST_MASTER_DISABLED)
2095 break;
2096 DELAY(10);

--- 250 unchanged lines hidden (view full) ---

2347iwi_load_ucode(struct iwi_softc *sc, const struct iwi_fw *fw)
2348{
2349 uint32_t tmp;
2350 const uint16_t *w;
2351 const char *uc = fw->data;
2352 size_t size = fw->size;
2353 int i, ntries, error;
2354
2085 /* disable interrupts */
2086 CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, 0);
2087
2088 CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_STOP_MASTER);
2089 for (ntries = 0; ntries < 5; ntries++) {
2090 if (CSR_READ_4(sc, IWI_CSR_RST) & IWI_RST_MASTER_DISABLED)
2091 break;
2092 DELAY(10);

--- 250 unchanged lines hidden (view full) ---

2343iwi_load_ucode(struct iwi_softc *sc, const struct iwi_fw *fw)
2344{
2345 uint32_t tmp;
2346 const uint16_t *w;
2347 const char *uc = fw->data;
2348 size_t size = fw->size;
2349 int i, ntries, error;
2350
2355 IWI_LOCK_CHECK(sc);
2351 IWI_LOCK_ASSERT(sc);
2356 error = 0;
2357 CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) |
2358 IWI_RST_STOP_MASTER);
2359 for (ntries = 0; ntries < 5; ntries++) {
2360 if (CSR_READ_4(sc, IWI_CSR_RST) & IWI_RST_MASTER_DISABLED)
2361 break;
2362 DELAY(10);
2363 }

--- 56 unchanged lines hidden (view full) ---

2420
2421static int
2422iwi_load_firmware(struct iwi_softc *sc, const struct iwi_fw *fw)
2423{
2424 u_char *p, *end;
2425 uint32_t sentinel, ctl, src, dst, sum, len, mlen, tmp;
2426 int ntries, error;
2427
2352 error = 0;
2353 CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) |
2354 IWI_RST_STOP_MASTER);
2355 for (ntries = 0; ntries < 5; ntries++) {
2356 if (CSR_READ_4(sc, IWI_CSR_RST) & IWI_RST_MASTER_DISABLED)
2357 break;
2358 DELAY(10);
2359 }

--- 56 unchanged lines hidden (view full) ---

2416
2417static int
2418iwi_load_firmware(struct iwi_softc *sc, const struct iwi_fw *fw)
2419{
2420 u_char *p, *end;
2421 uint32_t sentinel, ctl, src, dst, sum, len, mlen, tmp;
2422 int ntries, error;
2423
2428 IWI_LOCK_CHECK(sc);
2424 IWI_LOCK_ASSERT(sc);
2429 /* copy firmware image to DMA memory */
2430 memcpy(sc->fw_virtaddr, fw->data, fw->size);
2431
2432 /* make sure the adapter will get up-to-date values */
2433 bus_dmamap_sync(sc->fw_dmat, sc->fw_map, BUS_DMASYNC_PREWRITE);
2434
2435 /* tell the adapter where the command blocks are stored */
2436 MEM_WRITE_4(sc, 0x3000a0, 0x27000);

--- 125 unchanged lines hidden (view full) ---

2562{
2563 struct ieee80211com *ic = &sc->sc_ic;
2564 struct ifnet *ifp = ic->ic_ifp;
2565 struct iwi_configuration config;
2566 struct iwi_rateset rs;
2567 struct iwi_txpower power;
2568 uint32_t data;
2569 int error, i;
2425 /* copy firmware image to DMA memory */
2426 memcpy(sc->fw_virtaddr, fw->data, fw->size);
2427
2428 /* make sure the adapter will get up-to-date values */
2429 bus_dmamap_sync(sc->fw_dmat, sc->fw_map, BUS_DMASYNC_PREWRITE);
2430
2431 /* tell the adapter where the command blocks are stored */
2432 MEM_WRITE_4(sc, 0x3000a0, 0x27000);

--- 125 unchanged lines hidden (view full) ---

2558{
2559 struct ieee80211com *ic = &sc->sc_ic;
2560 struct ifnet *ifp = ic->ic_ifp;
2561 struct iwi_configuration config;
2562 struct iwi_rateset rs;
2563 struct iwi_txpower power;
2564 uint32_t data;
2565 int error, i;
2570 IWI_LOCK_CHECK(sc);
2566 IWI_LOCK_ASSERT(sc);
2571
2572 IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
2573 DPRINTF(("Setting MAC address to %6D\n", ic->ic_myaddr, ":"));
2574 error = iwi_cmd(sc, IWI_CMD_SET_MAC_ADDRESS, ic->ic_myaddr,
2575 IEEE80211_ADDR_LEN);
2576 if (error != 0)
2577 return error;
2578

--- 61 unchanged lines hidden (view full) ---

2640 memcpy(rs.rates, ic->ic_sup_rates[IEEE80211_MODE_11A].rs_rates,
2641 rs.nrates);
2642 DPRINTF(("Setting .11a supported rates (%u)\n", rs.nrates));
2643 error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs);
2644 if (error != 0)
2645 return error;
2646
2647 /* if we have a desired ESSID, set it now */
2567
2568 IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
2569 DPRINTF(("Setting MAC address to %6D\n", ic->ic_myaddr, ":"));
2570 error = iwi_cmd(sc, IWI_CMD_SET_MAC_ADDRESS, ic->ic_myaddr,
2571 IEEE80211_ADDR_LEN);
2572 if (error != 0)
2573 return error;
2574

--- 61 unchanged lines hidden (view full) ---

2636 memcpy(rs.rates, ic->ic_sup_rates[IEEE80211_MODE_11A].rs_rates,
2637 rs.nrates);
2638 DPRINTF(("Setting .11a supported rates (%u)\n", rs.nrates));
2639 error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs);
2640 if (error != 0)
2641 return error;
2642
2643 /* if we have a desired ESSID, set it now */
2648 if (ic->ic_des_esslen != 0) {
2644 if (ic->ic_des_ssid[0].len != 0) {
2649#ifdef IWI_DEBUG
2650 if (iwi_debug > 0) {
2651 printf("Setting desired ESSID to ");
2645#ifdef IWI_DEBUG
2646 if (iwi_debug > 0) {
2647 printf("Setting desired ESSID to ");
2652 ieee80211_print_essid(ic->ic_des_essid,
2653 ic->ic_des_esslen);
2648 ieee80211_print_essid(ic->ic_des_ssid[0].ssid,
2649 ic->ic_des_ssid[0].len);
2654 printf("\n");
2655 }
2656#endif
2650 printf("\n");
2651 }
2652#endif
2657 error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ic->ic_des_essid,
2658 ic->ic_des_esslen);
2653 error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ic->ic_des_ssid[0].ssid,
2654 ic->ic_des_ssid[0].len);
2659 if (error != 0)
2660 return error;
2661 }
2662
2663 data = htole32(arc4random());
2664 DPRINTF(("Setting initialization vector to %u\n", le32toh(data)));
2665 error = iwi_cmd(sc, IWI_CMD_SET_IV, &data, sizeof data);
2666 if (error != 0)

--- 14 unchanged lines hidden (view full) ---

2681 uint8_t *st = &scan->scan_type[ix / 2];
2682 if (ix % 2)
2683 *st = (*st & 0xf0) | ((scan_type & 0xf) << 0);
2684 else
2685 *st = (*st & 0x0f) | ((scan_type & 0xf) << 4);
2686}
2687
2688static int
2655 if (error != 0)
2656 return error;
2657 }
2658
2659 data = htole32(arc4random());
2660 DPRINTF(("Setting initialization vector to %u\n", le32toh(data)));
2661 error = iwi_cmd(sc, IWI_CMD_SET_IV, &data, sizeof data);
2662 if (error != 0)

--- 14 unchanged lines hidden (view full) ---

2677 uint8_t *st = &scan->scan_type[ix / 2];
2678 if (ix % 2)
2679 *st = (*st & 0xf0) | ((scan_type & 0xf) << 0);
2680 else
2681 *st = (*st & 0x0f) | ((scan_type & 0xf) << 4);
2682}
2683
2684static int
2689iwi_scan(struct iwi_softc *sc)
2685scan_type(const struct ieee80211_scan_state *ss,
2686 const struct ieee80211_channel *chan)
2690{
2687{
2691 struct ieee80211com *ic = &sc->sc_ic;
2692 const struct ieee80211_channel *c;
2688 /* We can only set one essid for a directed scan */
2689 if (ss->ss_nssid != 0)
2690 return IWI_SCAN_TYPE_BDIRECTED;
2691 if ((ss->ss_flags & IEEE80211_SCAN_ACTIVE) &&
2692 (chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0)
2693 return IWI_SCAN_TYPE_BROADCAST;
2694 return IWI_SCAN_TYPE_PASSIVE;
2695}
2696
2697static __inline int
2698scan_band(const struct ieee80211_channel *c)
2699{
2700 return IEEE80211_IS_CHAN_5GHZ(c) ? IWI_CHAN_5GHZ : IWI_CHAN_2GHZ;
2701}
2702
2703/*
2704 * Start a scan on the current channel or all channels.
2705 */
2706static int
2707iwi_scanchan(struct iwi_softc *sc, unsigned long maxdwell, int mode)
2708{
2709 struct ieee80211com *ic;
2710 struct ieee80211_channel *chan;
2711 struct ieee80211_scan_state *ss;
2693 struct iwi_scan_ext scan;
2712 struct iwi_scan_ext scan;
2694 int i, ix, start, scan_type, error;
2713 int error = 0;
2695
2714
2696 IWI_LOCK_CHECK(sc);
2715 IWI_LOCK_ASSERT(sc);
2716 if (sc->fw_state == IWI_FW_SCANNING) {
2717 /*
2718 * This should not happen as we only trigger scan_next after
2719 * completion
2720 */
2721 DPRINTF(("%s: called too early - still scanning\n", __func__));
2722 return (EBUSY);
2723 }
2724 IWI_STATE_BEGIN(sc, IWI_FW_SCANNING);
2697
2725
2726 ic = &sc->sc_ic;
2727 ss = ic->ic_scan;
2728
2698 memset(&scan, 0, sizeof scan);
2729 memset(&scan, 0, sizeof scan);
2730 scan.full_scan_index = htole32(++sc->sc_scangen);
2731 scan.dwell_time[IWI_SCAN_TYPE_PASSIVE] = htole16(maxdwell);
2732 if (ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) {
2733 /*
2734 * Use very short dwell times for when we send probe request
2735 * frames. Without this bg scans hang. Ideally this should
2736 * be handled with early-termination as done by net80211 but
2737 * that's not feasible (aborting a scan is problematic).
2738 */
2739 scan.dwell_time[IWI_SCAN_TYPE_BROADCAST] = htole16(30);
2740 scan.dwell_time[IWI_SCAN_TYPE_BDIRECTED] = htole16(30);
2741 } else {
2742 scan.dwell_time[IWI_SCAN_TYPE_BROADCAST] = htole16(maxdwell);
2743 scan.dwell_time[IWI_SCAN_TYPE_BDIRECTED] = htole16(maxdwell);
2744 }
2699
2745
2700 /* XXX different dwell times for different scan types */
2701 scan.dwell_time[IWI_SCAN_TYPE_PASSIVE] = htole16(sc->dwelltime);
2702 scan.dwell_time[IWI_SCAN_TYPE_BROADCAST] = htole16(sc->dwelltime);
2703 scan.dwell_time[IWI_SCAN_TYPE_BDIRECTED] = htole16(sc->dwelltime);
2746 /* We can only set one essid for a directed scan */
2747 if (ss->ss_nssid != 0) {
2748 error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ss->ss_ssid[0].ssid,
2749 ss->ss_ssid[0].len);
2750 if (error)
2751 return (error);
2752 }
2704
2753
2705 scan.full_scan_index = htole32(ic->ic_scan.nt_scangen);
2706
2707 if (ic->ic_des_esslen != 0) {
2708 scan_type = IWI_SCAN_TYPE_BDIRECTED;
2754 if (mode == IWI_SCAN_ALLCHAN) {
2755 int i, next, band, b, bstart;
2756 /*
2757 * Convert scan list to run-length encoded channel list
2758 * the firmware requires (preserving the order setup by
2759 * net80211). The first entry in each run specifies the
2760 * band and the count of items in the run.
2761 */
2762 next = 0; /* next open slot */
2763 bstart = 0; /* NB: not needed, silence compiler */
2764 band = -1; /* NB: impossible value */
2765 KASSERT(ss->ss_last > 0, ("no channels"));
2766 for (i = 0; i < ss->ss_last; i++) {
2767 chan = ss->ss_chans[i];
2768 b = scan_band(chan);
2769 if (b != band) {
2770 if (band != -1)
2771 scan.channels[bstart] =
2772 (next - bstart) | band;
2773 /* NB: this allocates a slot for the run-len */
2774 band = b, bstart = next++;
2775 }
2776 if (next >= IWI_SCAN_CHANNELS) {
2777 DPRINTF(("truncating scan list\n"));
2778 break;
2779 }
2780 scan.channels[next] = ieee80211_chan2ieee(ic, chan);
2781 set_scan_type(&scan, next, scan_type(ss, chan));
2782 next++;
2783 }
2784 scan.channels[bstart] = (next - bstart) | band;
2785 } else {
2786 /* Scan the current channel only */
2787 chan = ic->ic_curchan;
2788 scan.channels[0] = 1 | scan_band(chan);
2789 scan.channels[1] = ieee80211_chan2ieee(ic, chan);
2790 set_scan_type(&scan, 1, scan_type(ss, chan));
2791 }
2709#ifdef IWI_DEBUG
2792#ifdef IWI_DEBUG
2710 if (iwi_debug > 0) {
2711 printf("Setting desired ESSID to ");
2712 ieee80211_print_essid(ic->ic_des_essid,
2713 ic->ic_des_esslen);
2793 if (iwi_debug > 0) {
2794 static const char *scantype[8] =
2795 { "PSTOP", "PASV", "DIR", "BCAST", "BDIR", "5", "6", "7" };
2796 int i;
2797 printf("Scan request: index %u dwell %d/%d/%d\n"
2798 , le32toh(scan.full_scan_index)
2799 , le16toh(scan.dwell_time[IWI_SCAN_TYPE_PASSIVE])
2800 , le16toh(scan.dwell_time[IWI_SCAN_TYPE_BROADCAST])
2801 , le16toh(scan.dwell_time[IWI_SCAN_TYPE_BDIRECTED])
2802 );
2803 i = 0;
2804 do {
2805 int run = scan.channels[i];
2806 if (run == 0)
2807 break;
2808 printf("Scan %d %s channels:", run & 0x3f,
2809 run & IWI_CHAN_2GHZ ? "2.4GHz" : "5GHz");
2810 for (run &= 0x3f, i++; run > 0; run--, i++) {
2811 uint8_t type = scan.scan_type[i/2];
2812 printf(" %u/%s", scan.channels[i],
2813 scantype[(i & 1 ? type : type>>4) & 7]);
2814 }
2714 printf("\n");
2815 printf("\n");
2715 }
2816 } while (i < IWI_SCAN_CHANNELS);
2817 }
2716#endif
2818#endif
2717 error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ic->ic_des_essid,
2718 ic->ic_des_esslen);
2719 if (error != 0)
2720 return error;
2721 } else
2722 scan_type = IWI_SCAN_TYPE_BROADCAST;
2723
2819
2724 ix = 0;
2725 if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) {
2726 start = ix;
2727 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
2728 c = &ic->ic_channels[i];
2729 /*
2730 * NB: ieee80211_next_scan clears curchan from the
2731 * channel list so we must explicitly check; this
2732 * will be fixed when the new scanning support arrives.
2733 */
2734 if (!IEEE80211_IS_CHAN_5GHZ(c) ||
2735 !(isset(ic->ic_chan_scan,i) || c == ic->ic_curchan))
2736 continue;
2737 ix++;
2738 scan.channels[ix] = i;
2739 if (c->ic_flags & IEEE80211_CHAN_PASSIVE)
2740 set_scan_type(&scan, ix, IWI_SCAN_TYPE_PASSIVE);
2741 else
2742 set_scan_type(&scan, ix, scan_type);
2743 }
2744 if (start != ix) {
2745 scan.channels[start] = IWI_CHAN_5GHZ | (ix - start);
2746 ix++;
2747 }
2748 }
2749 if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) {
2750 start = ix;
2751 for (i = 0; i <= IEEE80211_CHAN_MAX; i++) {
2752 c = &ic->ic_channels[i];
2753 /* NB: see above */
2754 if (!IEEE80211_IS_CHAN_2GHZ(c) ||
2755 !(isset(ic->ic_chan_scan,i) || c == ic->ic_curchan))
2756 continue;
2757 ix++;
2758 scan.channels[ix] = i;
2759 if (c->ic_flags & IEEE80211_CHAN_PASSIVE)
2760 set_scan_type(&scan, ix, IWI_SCAN_TYPE_PASSIVE);
2761 else
2762 set_scan_type(&scan, ix, scan_type);
2763 }
2764 if (start != ix)
2765 scan.channels[start] = IWI_CHAN_2GHZ | (ix - start);
2766 }
2767
2768 DPRINTF(("Start scanning\n"));
2769 /*
2770 * With 100ms/channel dwell time and a max of ~20 channels
2771 * 5 seconds may be too tight; leave a bit more slack.
2772 */
2773 sc->sc_scan_timer = 7; /* seconds to complete */
2774 sc->sc_ifp->if_timer = 1;
2775 sc->flags |= IWI_FLAG_SCANNING;
2776 return iwi_cmd(sc, IWI_CMD_SCAN_EXT, &scan, sizeof scan);
2820 return (iwi_cmd(sc, IWI_CMD_SCAN_EXT, &scan, sizeof scan));
2777}
2778
2779static void
2780iwi_scanabort(void *arg, int npending)
2781{
2782 struct iwi_softc *sc = arg;
2783 IWI_LOCK_DECL;
2784
2785 IWI_LOCK(sc);
2821}
2822
2823static void
2824iwi_scanabort(void *arg, int npending)
2825{
2826 struct iwi_softc *sc = arg;
2827 IWI_LOCK_DECL;
2828
2829 IWI_LOCK(sc);
2830 sc->flags &= ~IWI_FLAG_CHANNEL_SCAN;
2786 /* NB: make sure we're still scanning */
2831 /* NB: make sure we're still scanning */
2787 if (sc->flags & IWI_FLAG_SCANNING)
2832 if (sc->fw_state == IWI_FW_SCANNING)
2788 iwi_cmd(sc, IWI_CMD_ABORT_SCAN, NULL, 0);
2789 IWI_UNLOCK(sc);
2790}
2791
2833 iwi_cmd(sc, IWI_CMD_ABORT_SCAN, NULL, 0);
2834 IWI_UNLOCK(sc);
2835}
2836
2792static void
2793iwi_scanstart(void *arg, int npending)
2794{
2795 struct iwi_softc *sc = arg;
2796 struct ieee80211com *ic = &sc->sc_ic;
2797 IWI_LOCK_DECL;
2798
2799 IWI_LOCK(sc);
2800 /*
2801 * Tell the card to kick off a scan. We guard this
2802 * by checking IWI_FLAG_SCANNING as otherwise we'll
2803 * do this twice because ieee80211_begin_scan will
2804 * immediately call us back to scan the first channel
2805 * in the list.
2806 */
2807 if (sc->flags & IWI_FLAG_SCANNING) {
2808 ieee80211_begin_scan(ic, 1);
2809 if (iwi_scan(sc) != 0) {
2810 /* XXX should not happen */
2811 sc->flags &= ~IWI_FLAG_SCANNING;
2812 ieee80211_new_state(ic, IEEE80211_S_INIT, 0);
2813 }
2814 }
2815 IWI_UNLOCK(sc);
2816}
2817
2818static void
2819iwi_scandone(void *arg, int npending)
2820{
2821 struct iwi_softc *sc = arg;
2822 struct ieee80211com *ic = &sc->sc_ic;
2823 IWI_LOCK_DECL;
2824
2825 IWI_LOCK(sc);
2826 if (sc->flags & IWI_FLAG_ASSOCIATED)
2827 iwi_disassociate(sc, 0);
2828 ieee80211_end_scan(ic);
2829 IWI_UNLOCK(sc);
2830}
2831
2832/*
2833 * Set the current channel by doing a passive scan. Note this
2834 * is explicitly for monitor mode operation; do not use it for
2835 * anything else (sigh).
2836 */
2837static void
2838iwi_scanchan(void *arg, int npending)
2839{
2840 struct iwi_softc *sc = arg;
2841 struct ieee80211com *ic;
2842 struct ieee80211_channel *chan;
2843 struct iwi_scan_ext scan;
2844 IWI_LOCK_DECL;
2845
2846 IWI_LOCK(sc);
2847 ic = &sc->sc_ic;
2848 KASSERT(ic->ic_opmode == IEEE80211_M_MONITOR,
2849 ("opmode %u", ic->ic_opmode));
2850 chan = ic->ic_ibss_chan;
2851
2852 memset(&scan, 0, sizeof scan);
2853 /*
2854 * Set the dwell time to a fairly small value. The firmware
2855 * is prone to crash when aborting a scan so it's better to
2856 * let a scan complete before changing channels--such as when
2857 * channel hopping in monitor mode.
2858 */
2859 scan.dwell_time[IWI_SCAN_TYPE_PASSIVE] = htole16(2000);
2860 scan.full_scan_index = htole32(ic->ic_scan.nt_scangen);
2861 if (IEEE80211_IS_CHAN_5GHZ(chan))
2862 scan.channels[0] = 1 | IWI_CHAN_5GHZ;
2863 else
2864 scan.channels[0] = 1 | IWI_CHAN_2GHZ;
2865 scan.channels[1] = ieee80211_chan2ieee(ic, chan);
2866 set_scan_type(&scan, 1, IWI_SCAN_TYPE_PASSIVE);
2867
2868 DPRINTF(("Setting channel to %u\n", ieee80211_chan2ieee(ic, chan)));
2869 sc->flags |= IWI_FLAG_SCANNING;
2870 (void) iwi_cmd(sc, IWI_CMD_SCAN_EXT, &scan, sizeof scan);
2871 IWI_UNLOCK(sc);
2872}
2873
2874static int
2875iwi_set_sensitivity(struct iwi_softc *sc, int8_t rssi_dbm)
2876{
2877 struct iwi_sensitivity sens;
2878
2879 DPRINTF(("Setting sensitivity to %d\n", rssi_dbm));
2880
2881 memset(&sens, 0, sizeof sens);

--- 7 unchanged lines hidden (view full) ---

2889 struct ieee80211com *ic = &sc->sc_ic;
2890 struct ifnet *ifp = ic->ic_ifp;
2891 struct ieee80211_node *ni = ic->ic_bss;
2892 struct iwi_configuration config;
2893 struct iwi_associate *assoc = &sc->assoc;
2894 struct iwi_rateset rs;
2895 uint16_t capinfo;
2896 int error;
2837static int
2838iwi_set_sensitivity(struct iwi_softc *sc, int8_t rssi_dbm)
2839{
2840 struct iwi_sensitivity sens;
2841
2842 DPRINTF(("Setting sensitivity to %d\n", rssi_dbm));
2843
2844 memset(&sens, 0, sizeof sens);

--- 7 unchanged lines hidden (view full) ---

2852 struct ieee80211com *ic = &sc->sc_ic;
2853 struct ifnet *ifp = ic->ic_ifp;
2854 struct ieee80211_node *ni = ic->ic_bss;
2855 struct iwi_configuration config;
2856 struct iwi_associate *assoc = &sc->assoc;
2857 struct iwi_rateset rs;
2858 uint16_t capinfo;
2859 int error;
2897
2898 IWI_LOCK_CHECK(sc);
2899 if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) {
2860
2861 IWI_LOCK_ASSERT(sc);
2862
2863 if (sc->flags & IWI_FLAG_ASSOCIATED) {
2864 DPRINTF(("Already associated\n"));
2865 return (-1);
2866 }
2867
2868 IWI_STATE_BEGIN(sc, IWI_FW_ASSOCIATING);
2869 error = 0;
2870 if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
2900 memset(&config, 0, sizeof config);
2901 config.bluetooth_coexistence = sc->bluetooth;
2902 config.antenna = sc->antenna;
2903 config.multicast_enabled = 1;
2904 config.use_protection = 1;
2905 config.answer_pbreq =
2906 (ic->ic_opmode == IEEE80211_M_IBSS) ? 1 : 0;
2907 config.disable_unicast_decryption = 1;
2908 config.disable_multicast_decryption = 1;
2909 DPRINTF(("Configuring adapter\n"));
2910 error = iwi_cmd(sc, IWI_CMD_SET_CONFIG, &config, sizeof config);
2911 if (error != 0)
2871 memset(&config, 0, sizeof config);
2872 config.bluetooth_coexistence = sc->bluetooth;
2873 config.antenna = sc->antenna;
2874 config.multicast_enabled = 1;
2875 config.use_protection = 1;
2876 config.answer_pbreq =
2877 (ic->ic_opmode == IEEE80211_M_IBSS) ? 1 : 0;
2878 config.disable_unicast_decryption = 1;
2879 config.disable_multicast_decryption = 1;
2880 DPRINTF(("Configuring adapter\n"));
2881 error = iwi_cmd(sc, IWI_CMD_SET_CONFIG, &config, sizeof config);
2882 if (error != 0)
2912 return error;
2883 goto done;
2913 }
2914
2915#ifdef IWI_DEBUG
2916 if (iwi_debug > 0) {
2917 printf("Setting ESSID to ");
2918 ieee80211_print_essid(ni->ni_essid, ni->ni_esslen);
2919 printf("\n");
2920 }
2921#endif
2922 error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ni->ni_essid, ni->ni_esslen);
2923 if (error != 0)
2884 }
2885
2886#ifdef IWI_DEBUG
2887 if (iwi_debug > 0) {
2888 printf("Setting ESSID to ");
2889 ieee80211_print_essid(ni->ni_essid, ni->ni_esslen);
2890 printf("\n");
2891 }
2892#endif
2893 error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ni->ni_essid, ni->ni_esslen);
2894 if (error != 0)
2924 return error;
2895 goto done;
2925
2926 /* the rate set has already been "negotiated" */
2896
2897 /* the rate set has already been "negotiated" */
2927 rs.mode = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? IWI_MODE_11A :
2928 IWI_MODE_11G;
2898 if (IEEE80211_IS_CHAN_A(ic->ic_curchan))
2899 rs.mode = IWI_MODE_11A;
2900 else if (IEEE80211_IS_CHAN_G(ic->ic_curchan))
2901 rs.mode = IWI_MODE_11G;
2902 if (IEEE80211_IS_CHAN_B(ic->ic_curchan))
2903 rs.mode = IWI_MODE_11B;
2904
2929 rs.type = IWI_RATESET_TYPE_NEGOTIATED;
2930 rs.nrates = ni->ni_rates.rs_nrates;
2931 if (rs.nrates > IWI_RATESET_SIZE) {
2932 DPRINTF(("Truncating negotiated rate set from %u\n",
2933 rs.nrates));
2934 rs.nrates = IWI_RATESET_SIZE;
2935 }
2936 memcpy(rs.rates, ni->ni_rates.rs_rates, rs.nrates);
2937 DPRINTF(("Setting negotiated rates (%u)\n", rs.nrates));
2938 error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs);
2939 if (error != 0)
2905 rs.type = IWI_RATESET_TYPE_NEGOTIATED;
2906 rs.nrates = ni->ni_rates.rs_nrates;
2907 if (rs.nrates > IWI_RATESET_SIZE) {
2908 DPRINTF(("Truncating negotiated rate set from %u\n",
2909 rs.nrates));
2910 rs.nrates = IWI_RATESET_SIZE;
2911 }
2912 memcpy(rs.rates, ni->ni_rates.rs_rates, rs.nrates);
2913 DPRINTF(("Setting negotiated rates (%u)\n", rs.nrates));
2914 error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs);
2915 if (error != 0)
2940 return error;
2916 goto done;
2941
2942 memset(assoc, 0, sizeof *assoc);
2943
2944 if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL) {
2945 /* NB: don't treat WME setup as failure */
2917
2918 memset(assoc, 0, sizeof *assoc);
2919
2920 if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL) {
2921 /* NB: don't treat WME setup as failure */
2946 if (iwi_wme_setparams_locked(sc) == 0 && iwi_wme_setie(sc) == 0)
2922 if (iwi_wme_setparams(sc) == 0 && iwi_wme_setie(sc) == 0)
2947 assoc->policy |= htole16(IWI_POLICY_WME);
2948 /* XXX complain on failure? */
2949 }
2950
2951 if (ic->ic_opt_ie != NULL) {
2952 DPRINTF(("Setting optional IE (len=%u)\n", ic->ic_opt_ie_len));
2953 error = iwi_cmd(sc, IWI_CMD_SET_OPTIE, ic->ic_opt_ie,
2954 ic->ic_opt_ie_len);
2955 if (error != 0)
2923 assoc->policy |= htole16(IWI_POLICY_WME);
2924 /* XXX complain on failure? */
2925 }
2926
2927 if (ic->ic_opt_ie != NULL) {
2928 DPRINTF(("Setting optional IE (len=%u)\n", ic->ic_opt_ie_len));
2929 error = iwi_cmd(sc, IWI_CMD_SET_OPTIE, ic->ic_opt_ie,
2930 ic->ic_opt_ie_len);
2931 if (error != 0)
2956 return error;
2932 goto done;
2957 }
2958
2959 error = iwi_set_sensitivity(sc, ni->ni_rssi);
2960 if (error != 0)
2933 }
2934
2935 error = iwi_set_sensitivity(sc, ni->ni_rssi);
2936 if (error != 0)
2961 return error;
2937 goto done;
2962
2938
2963 if (IEEE80211_IS_CHAN_A(ni->ni_chan))
2939 if (IEEE80211_IS_CHAN_A(ic->ic_curchan))
2964 assoc->mode = IWI_MODE_11A;
2940 assoc->mode = IWI_MODE_11A;
2965 else if (IEEE80211_IS_CHAN_G(ni->ni_chan))
2941 else if (IEEE80211_IS_CHAN_G(ic->ic_curchan))
2966 assoc->mode = IWI_MODE_11G;
2942 assoc->mode = IWI_MODE_11G;
2967 else if (IEEE80211_IS_CHAN_B(ni->ni_chan))
2943 else if (IEEE80211_IS_CHAN_B(ic->ic_curchan))
2968 assoc->mode = IWI_MODE_11B;
2944 assoc->mode = IWI_MODE_11B;
2969 /* XXX else error */
2970 assoc->chan = ieee80211_chan2ieee(ic, ni->ni_chan);
2945
2946 assoc->chan = ic->ic_curchan->ic_ieee;
2971 /*
2972 * NB: do not arrange for shared key auth w/o privacy
2973 * (i.e. a wep key); it causes a firmware error.
2974 */
2975 if ((ic->ic_flags & IEEE80211_F_PRIVACY) &&
2976 ni->ni_authmode == IEEE80211_AUTH_SHARED) {
2977 assoc->auth = IWI_AUTH_SHARED;
2978 /*
2979 * It's possible to have privacy marked but no default
2980 * key setup. This typically is due to a user app bug
2981 * but if we blindly grab the key the firmware will
2982 * barf so avoid it for now.
2983 */
2984 if (ic->ic_crypto.cs_def_txkey != IEEE80211_KEYIX_NONE)
2985 assoc->auth |= ic->ic_crypto.cs_def_txkey << 4;
2986
2987 error = iwi_setwepkeys(sc);
2988 if (error != 0)
2947 /*
2948 * NB: do not arrange for shared key auth w/o privacy
2949 * (i.e. a wep key); it causes a firmware error.
2950 */
2951 if ((ic->ic_flags & IEEE80211_F_PRIVACY) &&
2952 ni->ni_authmode == IEEE80211_AUTH_SHARED) {
2953 assoc->auth = IWI_AUTH_SHARED;
2954 /*
2955 * It's possible to have privacy marked but no default
2956 * key setup. This typically is due to a user app bug
2957 * but if we blindly grab the key the firmware will
2958 * barf so avoid it for now.
2959 */
2960 if (ic->ic_crypto.cs_def_txkey != IEEE80211_KEYIX_NONE)
2961 assoc->auth |= ic->ic_crypto.cs_def_txkey << 4;
2962
2963 error = iwi_setwepkeys(sc);
2964 if (error != 0)
2989 return error;
2965 goto done;
2990 }
2991 if (ic->ic_flags & IEEE80211_F_WPA)
2992 assoc->policy |= htole16(IWI_POLICY_WPA);
2993 if (ic->ic_opmode == IEEE80211_M_IBSS && ni->ni_tstamp.tsf == 0)
2994 assoc->type = IWI_HC_IBSS_START;
2995 else
2996 assoc->type = IWI_HC_ASSOC;
2997 memcpy(assoc->tstamp, ni->ni_tstamp.data, 8);
2998
2999 if (ic->ic_opmode == IEEE80211_M_IBSS)
3000 capinfo = IEEE80211_CAPINFO_IBSS;
3001 else
3002 capinfo = IEEE80211_CAPINFO_ESS;
3003 if (ic->ic_flags & IEEE80211_F_PRIVACY)
3004 capinfo |= IEEE80211_CAPINFO_PRIVACY;
3005 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
2966 }
2967 if (ic->ic_flags & IEEE80211_F_WPA)
2968 assoc->policy |= htole16(IWI_POLICY_WPA);
2969 if (ic->ic_opmode == IEEE80211_M_IBSS && ni->ni_tstamp.tsf == 0)
2970 assoc->type = IWI_HC_IBSS_START;
2971 else
2972 assoc->type = IWI_HC_ASSOC;
2973 memcpy(assoc->tstamp, ni->ni_tstamp.data, 8);
2974
2975 if (ic->ic_opmode == IEEE80211_M_IBSS)
2976 capinfo = IEEE80211_CAPINFO_IBSS;
2977 else
2978 capinfo = IEEE80211_CAPINFO_ESS;
2979 if (ic->ic_flags & IEEE80211_F_PRIVACY)
2980 capinfo |= IEEE80211_CAPINFO_PRIVACY;
2981 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
3006 IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
2982 IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
3007 capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
3008 if (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)
3009 capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
3010 assoc->capinfo = htole16(capinfo);
3011
3012 assoc->lintval = htole16(ic->ic_lintval);
3013 assoc->intval = htole16(ni->ni_intval);
3014 IEEE80211_ADDR_COPY(assoc->bssid, ni->ni_bssid);

--- 4 unchanged lines hidden (view full) ---

3019
3020 DPRINTF(("%s bssid %6D dst %6D channel %u policy 0x%x "
3021 "auth %u capinfo 0x%x lintval %u bintval %u\n",
3022 assoc->type == IWI_HC_IBSS_START ? "Start" : "Join",
3023 assoc->bssid, ":", assoc->dst, ":",
3024 assoc->chan, le16toh(assoc->policy), assoc->auth,
3025 le16toh(assoc->capinfo), le16toh(assoc->lintval),
3026 le16toh(assoc->intval)));
2983 capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
2984 if (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)
2985 capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
2986 assoc->capinfo = htole16(capinfo);
2987
2988 assoc->lintval = htole16(ic->ic_lintval);
2989 assoc->intval = htole16(ni->ni_intval);
2990 IEEE80211_ADDR_COPY(assoc->bssid, ni->ni_bssid);

--- 4 unchanged lines hidden (view full) ---

2995
2996 DPRINTF(("%s bssid %6D dst %6D channel %u policy 0x%x "
2997 "auth %u capinfo 0x%x lintval %u bintval %u\n",
2998 assoc->type == IWI_HC_IBSS_START ? "Start" : "Join",
2999 assoc->bssid, ":", assoc->dst, ":",
3000 assoc->chan, le16toh(assoc->policy), assoc->auth,
3001 le16toh(assoc->capinfo), le16toh(assoc->lintval),
3002 le16toh(assoc->intval)));
3027 return iwi_cmd(sc, IWI_CMD_ASSOCIATE, assoc, sizeof *assoc);
3003 error = iwi_cmd(sc, IWI_CMD_ASSOCIATE, assoc, sizeof *assoc);
3004done:
3005 if (error)
3006 IWI_STATE_END(sc, IWI_FW_ASSOCIATING);
3007
3008 return (error);
3028}
3029
3030static int
3031iwi_disassociate(struct iwi_softc *sc, int quiet)
3032{
3033 struct iwi_associate *assoc = &sc->assoc;
3034
3009}
3010
3011static int
3012iwi_disassociate(struct iwi_softc *sc, int quiet)
3013{
3014 struct iwi_associate *assoc = &sc->assoc;
3015
3016 if ((sc->flags & IWI_FLAG_ASSOCIATED) == 0) {
3017 DPRINTF(("Not associated\n"));
3018 return (-1);
3019 }
3020
3021 IWI_STATE_BEGIN(sc, IWI_FW_DISASSOCIATING);
3022
3035 if (quiet)
3036 assoc->type = IWI_HC_DISASSOC_QUIET;
3037 else
3038 assoc->type = IWI_HC_DISASSOC;
3039
3040 DPRINTF(("Trying to disassociate from %6D channel %u\n",
3041 assoc->bssid, ":", assoc->chan));
3042 return iwi_cmd(sc, IWI_CMD_ASSOCIATE, assoc, sizeof *assoc);
3043}
3044
3045static void
3023 if (quiet)
3024 assoc->type = IWI_HC_DISASSOC_QUIET;
3025 else
3026 assoc->type = IWI_HC_DISASSOC;
3027
3028 DPRINTF(("Trying to disassociate from %6D channel %u\n",
3029 assoc->bssid, ":", assoc->chan));
3030 return iwi_cmd(sc, IWI_CMD_ASSOCIATE, assoc, sizeof *assoc);
3031}
3032
3033static void
3046iwi_down(void *arg, int npending)
3047{
3048 struct iwi_softc *sc = arg;
3049 IWI_LOCK_DECL;
3050
3051 IWI_LOCK(sc);
3052 iwi_disassociate(sc, 0);
3053 IWI_UNLOCK(sc);
3054}
3055
3056static void
3057iwi_init(void *priv)
3058{
3059 struct iwi_softc *sc = priv;
3060 IWI_LOCK_DECL;
3061
3062 IWI_LOCK(sc);
3063 iwi_init_locked(sc, 0);
3064 IWI_UNLOCK(sc);

--- 64 unchanged lines hidden (view full) ---

3129{
3130 struct iwi_softc *sc = priv;
3131 struct ieee80211com *ic = &sc->sc_ic;
3132 struct ifnet *ifp = ic->ic_ifp;
3133 struct iwi_rx_data *data;
3134 int i;
3135 IWI_LOCK_DECL;
3136
3034iwi_init(void *priv)
3035{
3036 struct iwi_softc *sc = priv;
3037 IWI_LOCK_DECL;
3038
3039 IWI_LOCK(sc);
3040 iwi_init_locked(sc, 0);
3041 IWI_UNLOCK(sc);

--- 64 unchanged lines hidden (view full) ---

3106{
3107 struct iwi_softc *sc = priv;
3108 struct ieee80211com *ic = &sc->sc_ic;
3109 struct ifnet *ifp = ic->ic_ifp;
3110 struct iwi_rx_data *data;
3111 int i;
3112 IWI_LOCK_DECL;
3113
3137 IWI_LOCK_CHECK(sc);
3138 if (sc->flags & IWI_FLAG_FW_LOADING) {
3114 IWI_LOCK_ASSERT(sc);
3115 if (sc->fw_state == IWI_FW_LOADING) {
3139 device_printf(sc->sc_dev, "%s: already loading\n", __func__);
3140 return; /* XXX: condvar? */
3141 }
3142
3143 iwi_stop(sc);
3116 device_printf(sc->sc_dev, "%s: already loading\n", __func__);
3117 return; /* XXX: condvar? */
3118 }
3119
3120 iwi_stop(sc);
3121 IWI_STATE_BEGIN(sc, IWI_FW_LOADING);
3144
3145 if (iwi_reset(sc) != 0) {
3146 device_printf(sc->sc_dev, "could not reset adapter\n");
3147 goto fail;
3148 }
3149
3122
3123 if (iwi_reset(sc) != 0) {
3124 device_printf(sc->sc_dev, "could not reset adapter\n");
3125 goto fail;
3126 }
3127
3150 sc->flags |= IWI_FLAG_FW_LOADING;
3151
3152 IWI_UNLOCK(sc);
3153 if (iwi_get_firmware(sc)) {
3154 IWI_LOCK(sc);
3155 goto fail;
3156 }
3157
3158 /* allocate DMA memory for mapping firmware image */
3159 i = sc->fw_fw.size;

--- 68 unchanged lines hidden (view full) ---

3228 * we need to notify user apps so they can manually
3229 * get us going again.
3230 */
3231 if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL || force)
3232 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
3233 } else
3234 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
3235
3128 IWI_UNLOCK(sc);
3129 if (iwi_get_firmware(sc)) {
3130 IWI_LOCK(sc);
3131 goto fail;
3132 }
3133
3134 /* allocate DMA memory for mapping firmware image */
3135 i = sc->fw_fw.size;

--- 68 unchanged lines hidden (view full) ---

3204 * we need to notify user apps so they can manually
3205 * get us going again.
3206 */
3207 if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL || force)
3208 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
3209 } else
3210 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
3211
3212 callout_reset(&sc->sc_wdtimer, hz, iwi_watchdog, sc);
3236 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
3237 ifp->if_drv_flags |= IFF_DRV_RUNNING;
3238
3213 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
3214 ifp->if_drv_flags |= IFF_DRV_RUNNING;
3215
3239 sc->flags &= ~IWI_FLAG_FW_LOADING;
3216 IWI_STATE_END(sc, IWI_FW_LOADING);
3240 return;
3241
3242fail: ifp->if_flags &= ~IFF_UP;
3217 return;
3218
3219fail: ifp->if_flags &= ~IFF_UP;
3243 sc->flags &= ~IWI_FLAG_FW_LOADING;
3220 IWI_STATE_END(sc, IWI_FW_LOADING);
3244 iwi_stop(sc);
3245 iwi_put_firmware(sc);
3246}
3247
3248static void
3249iwi_stop(void *priv)
3250{
3251 struct iwi_softc *sc = priv;
3252 struct ieee80211com *ic = &sc->sc_ic;
3253 struct ifnet *ifp = ic->ic_ifp;
3254
3221 iwi_stop(sc);
3222 iwi_put_firmware(sc);
3223}
3224
3225static void
3226iwi_stop(void *priv)
3227{
3228 struct iwi_softc *sc = priv;
3229 struct ieee80211com *ic = &sc->sc_ic;
3230 struct ifnet *ifp = ic->ic_ifp;
3231
3255 IWI_LOCK_CHECK(sc); /* XXX: pretty sure this triggers */
3232 IWI_LOCK_ASSERT(sc);
3256 if (sc->sc_softled) {
3257 callout_stop(&sc->sc_ledtimer);
3258 sc->sc_blinking = 0;
3259 }
3260
3233 if (sc->sc_softled) {
3234 callout_stop(&sc->sc_ledtimer);
3235 sc->sc_blinking = 0;
3236 }
3237
3238 callout_stop(&sc->sc_wdtimer);
3261 iwi_stop_master(sc);
3262
3263 CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_SOFT_RESET);
3264
3265 /* reset rings */
3266 iwi_reset_cmd_ring(sc, &sc->cmdq);
3267 iwi_reset_tx_ring(sc, &sc->txq[0]);
3268 iwi_reset_tx_ring(sc, &sc->txq[1]);
3269 iwi_reset_tx_ring(sc, &sc->txq[2]);
3270 iwi_reset_tx_ring(sc, &sc->txq[3]);
3271 iwi_reset_rx_ring(sc, &sc->rxq);
3272
3239 iwi_stop_master(sc);
3240
3241 CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_SOFT_RESET);
3242
3243 /* reset rings */
3244 iwi_reset_cmd_ring(sc, &sc->cmdq);
3245 iwi_reset_tx_ring(sc, &sc->txq[0]);
3246 iwi_reset_tx_ring(sc, &sc->txq[1]);
3247 iwi_reset_tx_ring(sc, &sc->txq[2]);
3248 iwi_reset_tx_ring(sc, &sc->txq[3]);
3249 iwi_reset_rx_ring(sc, &sc->rxq);
3250
3273 ifp->if_timer = 0;
3274 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3275
3276 sc->sc_tx_timer = 0;
3277 sc->sc_rfkill_timer = 0;
3251 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3252
3253 sc->sc_tx_timer = 0;
3254 sc->sc_rfkill_timer = 0;
3278 sc->sc_scan_timer = 0;
3279 sc->flags &= ~(IWI_FLAG_BUSY | IWI_FLAG_SCANNING | IWI_FLAG_ASSOCIATED);
3255 sc->sc_state_timer = 0;
3256 sc->sc_busy_timer = 0;
3257 sc->flags &= ~(IWI_FLAG_BUSY | IWI_FLAG_ASSOCIATED);
3258 sc->fw_state = IWI_FW_IDLE;
3259 wakeup(sc);
3280
3281 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
3282}
3283
3284static void
3285iwi_restart(void *arg, int npending)
3286{
3287 struct iwi_softc *sc = arg;

--- 22 unchanged lines hidden (view full) ---

3310 device_printf(sc->sc_dev, "radio turned on\n");
3311 iwi_init(sc);
3312}
3313
3314static void
3315iwi_radio_off(void *arg, int pending)
3316{
3317 struct iwi_softc *sc = arg;
3260
3261 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
3262}
3263
3264static void
3265iwi_restart(void *arg, int npending)
3266{
3267 struct iwi_softc *sc = arg;

--- 22 unchanged lines hidden (view full) ---

3290 device_printf(sc->sc_dev, "radio turned on\n");
3291 iwi_init(sc);
3292}
3293
3294static void
3295iwi_radio_off(void *arg, int pending)
3296{
3297 struct iwi_softc *sc = arg;
3298 IWI_LOCK_DECL;
3318
3319 device_printf(sc->sc_dev, "radio turned off\n");
3299
3300 device_printf(sc->sc_dev, "radio turned off\n");
3301 IWI_LOCK(sc);
3320 iwi_stop(sc);
3321 sc->sc_rfkill_timer = 2;
3302 iwi_stop(sc);
3303 sc->sc_rfkill_timer = 2;
3322 sc->sc_ifp->if_timer = 1;
3304 IWI_UNLOCK(sc);
3323}
3324
3325static int
3326iwi_sysctl_stats(SYSCTL_HANDLER_ARGS)
3327{
3328 struct iwi_softc *sc = arg1;
3329 uint32_t size, buf[128];
3330

--- 29 unchanged lines hidden (view full) ---

3360 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "radio",
3361 CTLTYPE_INT | CTLFLAG_RD, sc, 0, iwi_sysctl_radio, "I",
3362 "radio transmitter switch state (0=off, 1=on)");
3363
3364 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "stats",
3365 CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, iwi_sysctl_stats, "S",
3366 "statistics");
3367
3305}
3306
3307static int
3308iwi_sysctl_stats(SYSCTL_HANDLER_ARGS)
3309{
3310 struct iwi_softc *sc = arg1;
3311 uint32_t size, buf[128];
3312

--- 29 unchanged lines hidden (view full) ---

3342 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "radio",
3343 CTLTYPE_INT | CTLFLAG_RD, sc, 0, iwi_sysctl_radio, "I",
3344 "radio transmitter switch state (0=off, 1=on)");
3345
3346 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "stats",
3347 CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, iwi_sysctl_stats, "S",
3348 "statistics");
3349
3368 sc->dwelltime = 100;
3369 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "dwell",
3370 CTLFLAG_RW, &sc->dwelltime, 0,
3371 "channel dwell time (ms) for AP/station scanning");
3372
3373 sc->bluetooth = 0;
3374 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "bluetooth",
3375 CTLFLAG_RW, &sc->bluetooth, 0, "bluetooth coexistence");
3376
3377 sc->antenna = IWI_ANTENNA_AUTO;
3378 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "antenna",
3379 CTLFLAG_RW, &sc->antenna, 0, "antenna (0=auto)");
3380}

--- 182 unchanged lines hidden (view full) ---

3563 sc->sc_nictype = (iwi_read_prom_word(sc, IWI_EEPROM_NIC) >> 8) & 0xff;
3564 if (sc->sc_nictype == 1) {
3565 /*
3566 * NB: led's are reversed.
3567 */
3568 sc->sc_ledpin = IWI_RST_LED_ASSOCIATED;
3569 }
3570}
3350 sc->bluetooth = 0;
3351 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "bluetooth",
3352 CTLFLAG_RW, &sc->bluetooth, 0, "bluetooth coexistence");
3353
3354 sc->antenna = IWI_ANTENNA_AUTO;
3355 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "antenna",
3356 CTLFLAG_RW, &sc->antenna, 0, "antenna (0=auto)");
3357}

--- 182 unchanged lines hidden (view full) ---

3540 sc->sc_nictype = (iwi_read_prom_word(sc, IWI_EEPROM_NIC) >> 8) & 0xff;
3541 if (sc->sc_nictype == 1) {
3542 /*
3543 * NB: led's are reversed.
3544 */
3545 sc->sc_ledpin = IWI_RST_LED_ASSOCIATED;
3546 }
3547}
3548
3549static void
3550iwi_ops(void *arg, int npending)
3551{
3552 struct iwi_softc *sc = arg;
3553 struct ieee80211com *ic = &sc->sc_ic;
3554 IWI_LOCK_DECL;
3555 int cmd;
3556
3557again:
3558 IWI_CMD_LOCK(sc);
3559 cmd = sc->sc_cmd[sc->sc_cmd_cur];
3560 if (cmd == 0) {
3561 /* No more commands to process */
3562 IWI_CMD_UNLOCK(sc);
3563 return;
3564 }
3565 sc->sc_cmd[sc->sc_cmd_cur] = 0; /* free the slot */
3566 sc->sc_cmd_cur = (sc->sc_cmd_cur + 1) % IWI_CMD_MAXOPS;
3567 IWI_CMD_UNLOCK(sc);
3568
3569 IWI_LOCK(sc);
3570 while (sc->fw_state != IWI_FW_IDLE || (sc->flags & IWI_FLAG_BUSY)) {
3571 msleep(sc, &sc->sc_mtx, 0, "iwicmd", hz/10);
3572 }
3573
3574 if (!(sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING))
3575 goto done;
3576
3577 switch (cmd) {
3578 case IWI_ASSOC:
3579 iwi_auth_and_assoc(sc);
3580 break;
3581 case IWI_DISASSOC:
3582 iwi_disassociate(sc, 0);
3583 break;
3584 case IWI_SET_WME:
3585 if (ic->ic_state == IEEE80211_S_RUN)
3586 (void) iwi_wme_setparams(sc);
3587 break;
3588 case IWI_SCAN_START:
3589 sc->flags |= IWI_FLAG_CHANNEL_SCAN;
3590 break;
3591 case IWI_SCAN_CURCHAN:
3592 case IWI_SCAN_ALLCHAN:
3593 if (!(sc->flags & IWI_FLAG_CHANNEL_SCAN)) {
3594 DPRINTF(("%s: ic_scan_curchan while not scanning\n",
3595 __func__));
3596 goto done;
3597 }
3598 if (iwi_scanchan(sc, sc->sc_maxdwell, cmd))
3599 ieee80211_cancel_scan(ic);
3600
3601 break;
3602 }
3603done:
3604 IWI_UNLOCK(sc);
3605
3606 /* Take another pass */
3607 goto again;
3608}
3609
3610static int
3611iwi_queue_cmd(struct iwi_softc *sc, int cmd)
3612{
3613 IWI_CMD_LOCK(sc);
3614 if (sc->sc_cmd[sc->sc_cmd_next] != 0) {
3615 IWI_CMD_UNLOCK(sc);
3616 DPRINTF(("%s: command %d dropped\n", __func__, cmd));
3617 return (EBUSY);
3618 }
3619
3620 sc->sc_cmd[sc->sc_cmd_next] = cmd;
3621 sc->sc_cmd_next = (sc->sc_cmd_next + 1) % IWI_CMD_MAXOPS;
3622 taskqueue_enqueue(sc->sc_tq, &sc->sc_opstask);
3623 IWI_CMD_UNLOCK(sc);
3624 return (0);
3625}
3626
3627static void
3628iwi_scan_start(struct ieee80211com *ic)
3629{
3630 struct ifnet *ifp = ic->ic_ifp;
3631 struct iwi_softc *sc = ifp->if_softc;
3632
3633 iwi_queue_cmd(sc, IWI_SCAN_START);
3634}
3635
3636static void
3637iwi_set_channel(struct ieee80211com *ic)
3638{
3639 struct ifnet *ifp = ic->ic_ifp;
3640 struct iwi_softc *sc = ifp->if_softc;
3641 if (sc->fw_state == IWI_FW_IDLE)
3642 iwi_setcurchan(sc, ic->ic_curchan->ic_ieee);
3643}
3644
3645static void
3646iwi_scan_curchan(struct ieee80211com *ic, unsigned long maxdwell)
3647{
3648 struct ifnet *ifp = ic->ic_ifp;
3649 struct iwi_softc *sc = ifp->if_softc;
3650
3651 sc->sc_maxdwell = maxdwell;
3652 iwi_queue_cmd(sc, IWI_SCAN_CURCHAN);
3653}
3654
3655#if 0
3656static void
3657iwi_scan_allchan(struct ieee80211com *ic, unsigned long maxdwell)
3658{
3659 struct ifnet *ifp = ic->ic_ifp;
3660 struct iwi_softc *sc = ifp->if_softc;
3661
3662 sc->sc_maxdwell = maxdwell;
3663 iwi_queue_cmd(sc, IWI_SCAN_ALLCHAN);
3664}
3665#endif
3666
3667static void
3668iwi_scan_mindwell(struct ieee80211com *ic)
3669{
3670 /* NB: don't try to abort scan; wait for firmware to finish */
3671}
3672
3673static void
3674iwi_scan_end(struct ieee80211com *ic)
3675{
3676 struct ifnet *ifp = ic->ic_ifp;
3677 struct iwi_softc *sc = ifp->if_softc;
3678
3679 taskqueue_enqueue(sc->sc_tq, &sc->sc_scanaborttask);
3680}
3681
3682static void
3683iwi_assoc(struct ieee80211com *ic)
3684{
3685 struct ifnet *ifp = ic->ic_ifp;
3686 struct iwi_softc *sc = ifp->if_softc;
3687
3688 iwi_queue_cmd(sc, IWI_ASSOC);
3689}
3690
3691static void
3692iwi_disassoc(struct ieee80211com *ic)
3693{
3694 struct ifnet *ifp = ic->ic_ifp;
3695 struct iwi_softc *sc = ifp->if_softc;
3696
3697 iwi_queue_cmd(sc, IWI_DISASSOC);
3698}