diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 51b90309ce5a5f6440eae626e5ddbf17b1f3d218..1b81545b94eadd94ec6e4fc595f883524ebb3416 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -285,6 +285,8 @@ static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data, rxb->skb = NULL; } +#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) + static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb) { @@ -442,6 +444,13 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, case IEEE80211_STYPE_REASSOC_RESP:{ struct ieee80211_mgmt *mgnt = (struct ieee80211_mgmt *)header; + + /* We have just associated, give some + * time for the 4-way handshake if + * any. Don't start scan too early. */ + priv->next_scan_jiffies = jiffies + + IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; + priv->assoc_id = (~((1 << 15) | (1 << 14)) & le16_to_cpu(mgnt->u. assoc_resp.aid)); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 75cef3ed9511d62bae710073599abc73a22488d8..1f82061221a16388de3246aa4636ff6d366dc800 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -752,6 +752,7 @@ struct iwl3945_priv { /* Scan related variables */ unsigned long last_scan_jiffies; + unsigned long next_scan_jiffies; unsigned long scan_start; unsigned long scan_pass_start; unsigned long scan_start_tsf; diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 40c795eaabacbea01442b70e68a5590f3598beb3..c8e7adfe414a0ae211c64ddf472e95517f3d35b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -3802,6 +3802,8 @@ static void iwl4965_update_ps_mode(struct iwl4965_priv *priv, u16 ps_bit, u8 *ad } } +#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) + /* Called for REPLY_4965_RX (legacy ABG frames), or * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv, @@ -3973,6 +3975,12 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv, struct ieee80211_mgmt *mgnt = (struct ieee80211_mgmt *)header; + /* We have just associated, give some + * time for the 4-way handshake if + * any. Don't start scan too early. */ + priv->next_scan_jiffies = jiffies + + IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; + priv->assoc_id = (~((1 << 15) | (1 << 14)) & le16_to_cpu(mgnt->u.assoc_resp.aid)); priv->assoc_capability = diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 2930c10b5ed86852fc7c5b0ff9fa558d4c4d8e14..c0627386122369be196ffc45b2d372e407ac5eb6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h @@ -1082,6 +1082,7 @@ struct iwl4965_priv { /* Scan related variables */ unsigned long last_scan_jiffies; + unsigned long next_scan_jiffies; unsigned long scan_start; unsigned long scan_pass_start; unsigned long scan_start_tsf; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 71e9b7c52d57af7e2fff1e3a878a675aeabcf69c..82c1e0d45cf28c1a9d9974fdaf242b35781d816d 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2800,7 +2800,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, IWL_DEBUG_TX("Sending REASSOC frame\n"); #endif - if (!iwl3945_is_associated(priv) && + /* drop all data frame if we are not associated */ + if (!iwl3945_is_associated(priv) && !priv->assoc_id && ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); goto drop_unlock; @@ -3737,6 +3738,7 @@ static void iwl3945_rx_scan_results_notif(struct iwl3945_priv *priv, (priv->last_scan_jiffies, jiffies))); priv->last_scan_jiffies = jiffies; + priv->next_scan_jiffies = 0; } /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ @@ -3779,6 +3781,7 @@ static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv, } priv->last_scan_jiffies = jiffies; + priv->next_scan_jiffies = 0; IWL_DEBUG_INFO("Setting scan to off\n"); clear_bit(STATUS_SCANNING, &priv->status); @@ -6806,6 +6809,8 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data) mutex_unlock(&priv->mutex); } +#define IWL_DELAY_NEXT_SCAN (HZ*2) + static void iwl3945_bg_post_associate(struct work_struct *data) { struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, @@ -6906,6 +6911,8 @@ static void iwl3945_bg_post_associate(struct work_struct *data) #ifdef CONFIG_IWL3945_QOS iwl3945_activate_qos(priv, 0); #endif /* CONFIG_IWL3945_QOS */ + /* we have just associated, don't start scan too early */ + priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; mutex_unlock(&priv->mutex); } @@ -7338,7 +7345,6 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, } -#define IWL_DELAY_NEXT_SCAN (HZ*2) static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) { int rc = 0; @@ -7362,16 +7368,20 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) goto out_unlock; } + /* we don't schedule scan within next_scan_jiffies period */ + if (priv->next_scan_jiffies && + time_after(priv->next_scan_jiffies, jiffies)) { + rc = -EAGAIN; + goto out_unlock; + } /* if we just finished scan ask for delay */ - if (priv->last_scan_jiffies && - time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, - jiffies)) { + if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies + + IWL_DELAY_NEXT_SCAN, jiffies)) { rc = -EAGAIN; goto out_unlock; } if (len) { - IWL_DEBUG_SCAN("direct scan for " - "%s [%d]\n ", + IWL_DEBUG_SCAN("direct scan for %s [%d]\n ", iwl3945_escape_essid(ssid, len), (int)len); priv->one_direct_scan = 1; diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index e15986c33d0be901db55f018124f6a8d9cb2d022..670f611adf9f986b5b25efff9ee944394934d24a 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -2905,7 +2905,8 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, IWL_DEBUG_TX("Sending REASSOC frame\n"); #endif - if (!iwl4965_is_associated(priv) && + /* drop all data frame if we are not associated */ + if (!iwl4965_is_associated(priv) && !priv->assoc_id && ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n"); goto drop_unlock; @@ -4055,6 +4056,7 @@ static void iwl4965_rx_scan_results_notif(struct iwl4965_priv *priv, (priv->last_scan_jiffies, jiffies))); priv->last_scan_jiffies = jiffies; + priv->next_scan_jiffies = 0; } /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ @@ -4097,6 +4099,7 @@ static void iwl4965_rx_scan_complete_notif(struct iwl4965_priv *priv, } priv->last_scan_jiffies = jiffies; + priv->next_scan_jiffies = 0; IWL_DEBUG_INFO("Setting scan to off\n"); clear_bit(STATUS_SCANNING, &priv->status); @@ -7228,6 +7231,8 @@ static void iwl4965_bg_rx_replenish(struct work_struct *data) mutex_unlock(&priv->mutex); } +#define IWL_DELAY_NEXT_SCAN (HZ*2) + static void iwl4965_bg_post_associate(struct work_struct *data) { struct iwl4965_priv *priv = container_of(data, struct iwl4965_priv, @@ -7343,6 +7348,8 @@ static void iwl4965_bg_post_associate(struct work_struct *data) #ifdef CONFIG_IWL4965_QOS iwl4965_activate_qos(priv, 0); #endif /* CONFIG_IWL4965_QOS */ + /* we have just associated, don't start scan too early */ + priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; mutex_unlock(&priv->mutex); } @@ -7811,7 +7818,6 @@ static void iwl4965_mac_erp_ie_changed(struct ieee80211_hw *hw, iwl4965_send_rxon_assoc(priv); } -#define IWL_DELAY_NEXT_SCAN (HZ*2) static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) { int rc = 0; @@ -7835,16 +7841,20 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) goto out_unlock; } + /* we don't schedule scan within next_scan_jiffies period */ + if (priv->next_scan_jiffies && + time_after(priv->next_scan_jiffies, jiffies)) { + rc = -EAGAIN; + goto out_unlock; + } /* if we just finished scan ask for delay */ - if (priv->last_scan_jiffies && - time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, - jiffies)) { + if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies + + IWL_DELAY_NEXT_SCAN, jiffies)) { rc = -EAGAIN; goto out_unlock; } if (len) { - IWL_DEBUG_SCAN("direct scan for " - "%s [%d]\n ", + IWL_DEBUG_SCAN("direct scan for %s [%d]\n ", iwl4965_escape_essid(ssid, len), (int)len); priv->one_direct_scan = 1;