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} |
|