diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 114 |
1 files changed, 70 insertions, 44 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index f9d16ca5b3d9..e05faa004dae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -2390,39 +2390,46 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
2390 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); | 2390 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); |
2391 | } | 2391 | } |
2392 | 2392 | ||
2393 | if ((changes & BSS_CHANGED_BSSID) && !iwl_is_rfkill(priv)) { | 2393 | if (changes & BSS_CHANGED_BEACON_INT) { |
2394 | /* If there is currently a HW scan going on in the background | 2394 | priv->beacon_int = bss_conf->beacon_int; |
2395 | * then we need to cancel it else the RXON below will fail. */ | 2395 | /* TODO: in AP mode, do something to make this take effect */ |
2396 | } | ||
2397 | |||
2398 | if (changes & BSS_CHANGED_BSSID) { | ||
2399 | IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid); | ||
2400 | |||
2401 | /* | ||
2402 | * If there is currently a HW scan going on in the | ||
2403 | * background then we need to cancel it else the RXON | ||
2404 | * below/in post_associate will fail. | ||
2405 | */ | ||
2396 | if (iwl_scan_cancel_timeout(priv, 100)) { | 2406 | if (iwl_scan_cancel_timeout(priv, 100)) { |
2397 | IWL_WARN(priv, "Aborted scan still in progress " | 2407 | IWL_WARN(priv, "Aborted scan still in progress after 100ms\n"); |
2398 | "after 100ms\n"); | ||
2399 | IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); | 2408 | IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); |
2400 | mutex_unlock(&priv->mutex); | 2409 | mutex_unlock(&priv->mutex); |
2401 | return; | 2410 | return; |
2402 | } | 2411 | } |
2403 | memcpy(priv->staging_rxon.bssid_addr, | ||
2404 | bss_conf->bssid, ETH_ALEN); | ||
2405 | 2412 | ||
2406 | /* TODO: Audit driver for usage of these members and see | 2413 | /* mac80211 only sets assoc when in STATION mode */ |
2407 | * if mac80211 deprecates them (priv->bssid looks like it | 2414 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC || |
2408 | * shouldn't be there, but I haven't scanned the IBSS code | 2415 | bss_conf->assoc) { |
2409 | * to verify) - jpk */ | 2416 | memcpy(priv->staging_rxon.bssid_addr, |
2410 | memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); | 2417 | bss_conf->bssid, ETH_ALEN); |
2411 | 2418 | ||
2412 | if (priv->iw_mode == NL80211_IFTYPE_AP) | 2419 | /* currently needed in a few places */ |
2413 | iwlcore_config_ap(priv); | 2420 | memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); |
2414 | else { | 2421 | } else { |
2415 | int rc = iwlcore_commit_rxon(priv); | 2422 | priv->staging_rxon.filter_flags &= |
2416 | if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) | 2423 | ~RXON_FILTER_ASSOC_MSK; |
2417 | iwl_rxon_add_station( | ||
2418 | priv, priv->active_rxon.bssid_addr, 1); | ||
2419 | } | 2424 | } |
2420 | } else if (!iwl_is_rfkill(priv)) { | 2425 | |
2421 | iwl_scan_cancel_timeout(priv, 100); | ||
2422 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
2423 | iwlcore_commit_rxon(priv); | ||
2424 | } | 2426 | } |
2425 | 2427 | ||
2428 | /* | ||
2429 | * This needs to be after setting the BSSID in case | ||
2430 | * mac80211 decides to do both changes at once because | ||
2431 | * it will invoke post_associate. | ||
2432 | */ | ||
2426 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && | 2433 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && |
2427 | changes & BSS_CHANGED_BEACON) { | 2434 | changes & BSS_CHANGED_BEACON) { |
2428 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); | 2435 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); |
@@ -2431,8 +2438,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
2431 | iwl_mac_beacon_update(hw, beacon); | 2438 | iwl_mac_beacon_update(hw, beacon); |
2432 | } | 2439 | } |
2433 | 2440 | ||
2434 | mutex_unlock(&priv->mutex); | ||
2435 | |||
2436 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { | 2441 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { |
2437 | IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", | 2442 | IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", |
2438 | bss_conf->use_short_preamble); | 2443 | bss_conf->use_short_preamble); |
@@ -2450,6 +2455,23 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
2450 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; | 2455 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; |
2451 | } | 2456 | } |
2452 | 2457 | ||
2458 | if (changes & BSS_CHANGED_BASIC_RATES) { | ||
2459 | /* XXX use this information | ||
2460 | * | ||
2461 | * To do that, remove code from iwl_set_rate() and put something | ||
2462 | * like this here: | ||
2463 | * | ||
2464 | if (A-band) | ||
2465 | priv->staging_rxon.ofdm_basic_rates = | ||
2466 | bss_conf->basic_rates; | ||
2467 | else | ||
2468 | priv->staging_rxon.ofdm_basic_rates = | ||
2469 | bss_conf->basic_rates >> 4; | ||
2470 | priv->staging_rxon.cck_basic_rates = | ||
2471 | bss_conf->basic_rates & 0xF; | ||
2472 | */ | ||
2473 | } | ||
2474 | |||
2453 | if (changes & BSS_CHANGED_HT) { | 2475 | if (changes & BSS_CHANGED_HT) { |
2454 | iwl_ht_conf(priv, bss_conf); | 2476 | iwl_ht_conf(priv, bss_conf); |
2455 | 2477 | ||
@@ -2459,10 +2481,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
2459 | 2481 | ||
2460 | if (changes & BSS_CHANGED_ASSOC) { | 2482 | if (changes & BSS_CHANGED_ASSOC) { |
2461 | IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); | 2483 | IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); |
2462 | /* This should never happen as this function should | ||
2463 | * never be called from interrupt context. */ | ||
2464 | if (WARN_ON_ONCE(in_interrupt())) | ||
2465 | return; | ||
2466 | if (bss_conf->assoc) { | 2484 | if (bss_conf->assoc) { |
2467 | priv->assoc_id = bss_conf->aid; | 2485 | priv->assoc_id = bss_conf->aid; |
2468 | priv->beacon_int = bss_conf->beacon_int; | 2486 | priv->beacon_int = bss_conf->beacon_int; |
@@ -2470,27 +2488,35 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
2470 | priv->timestamp = bss_conf->timestamp; | 2488 | priv->timestamp = bss_conf->timestamp; |
2471 | priv->assoc_capability = bss_conf->assoc_capability; | 2489 | priv->assoc_capability = bss_conf->assoc_capability; |
2472 | 2490 | ||
2473 | /* we have just associated, don't start scan too early | 2491 | /* |
2474 | * leave time for EAPOL exchange to complete | 2492 | * We have just associated, don't start scan too early |
2493 | * leave time for EAPOL exchange to complete. | ||
2494 | * | ||
2495 | * XXX: do this in mac80211 | ||
2475 | */ | 2496 | */ |
2476 | priv->next_scan_jiffies = jiffies + | 2497 | priv->next_scan_jiffies = jiffies + |
2477 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; | 2498 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; |
2478 | mutex_lock(&priv->mutex); | 2499 | if (!iwl_is_rfkill(priv)) |
2479 | priv->cfg->ops->lib->post_associate(priv); | 2500 | priv->cfg->ops->lib->post_associate(priv); |
2480 | mutex_unlock(&priv->mutex); | 2501 | } else |
2481 | } else { | ||
2482 | priv->assoc_id = 0; | 2502 | priv->assoc_id = 0; |
2483 | IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc); | 2503 | |
2504 | } | ||
2505 | |||
2506 | if (changes && iwl_is_associated(priv) && priv->assoc_id) { | ||
2507 | IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n", | ||
2508 | changes); | ||
2509 | ret = iwl_send_rxon_assoc(priv); | ||
2510 | if (!ret) { | ||
2511 | /* Sync active_rxon with latest change. */ | ||
2512 | memcpy((void *)&priv->active_rxon, | ||
2513 | &priv->staging_rxon, | ||
2514 | sizeof(struct iwl_rxon_cmd)); | ||
2484 | } | 2515 | } |
2485 | } else if (changes && iwl_is_associated(priv) && priv->assoc_id) { | ||
2486 | IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes); | ||
2487 | ret = iwl_send_rxon_assoc(priv); | ||
2488 | if (!ret) | ||
2489 | /* Sync active_rxon with latest change. */ | ||
2490 | memcpy((void *)&priv->active_rxon, | ||
2491 | &priv->staging_rxon, | ||
2492 | sizeof(struct iwl_rxon_cmd)); | ||
2493 | } | 2516 | } |
2517 | |||
2518 | mutex_unlock(&priv->mutex); | ||
2519 | |||
2494 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2520 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
2495 | } | 2521 | } |
2496 | EXPORT_SYMBOL(iwl_bss_info_changed); | 2522 | EXPORT_SYMBOL(iwl_bss_info_changed); |