aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-06-12 16:22:48 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-06-15 15:05:52 -0400
commitd7129e190c3107db8ac11a9e51035641b68d2aa7 (patch)
tree5ff7d6bb71d3f37121c415ff049031dcb44e3e44
parent87e501b351ed9d837e63f6506b7e66331a69ed58 (diff)
iwlwifi: revamp bss_info_changed
My earlier patch, "mac80211: unify config_interface and bss_info_changed" introduced a bug in iwlwifi where it will do some things incorrectly now when reassociating. Revamp iwl_bss_info_changed to fix that issue and make it easier to read. Also, while at it, add comments about things that it should do but currently doesn't. Finally, also improve the locking in the function. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-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);