aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c114
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}
2496EXPORT_SYMBOL(iwl_bss_info_changed); 2522EXPORT_SYMBOL(iwl_bss_info_changed);