Commit 7878a5a4 authored by Mohamed Abbas's avatar Mohamed Abbas Committed by David S. Miller

iwlwifi: enhance WPA authenication stability

This patch enhanced WPA authenication stability by avoiding scan
immediately followed by association. We don't do any scanning right
after association in next several seconds. This will allow WPA
authentication to take place without any interruption.
Signed-off-by: default avatarMohamed Abbas <mabbas@linux.intel.com>
Signed-off-by: default avatarZhu Yi <yi.zhu@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 2bdc7031
...@@ -285,6 +285,8 @@ static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data, ...@@ -285,6 +285,8 @@ static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data,
rxb->skb = NULL; rxb->skb = NULL;
} }
#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
struct iwl3945_rx_mem_buffer *rxb) struct iwl3945_rx_mem_buffer *rxb)
{ {
...@@ -442,6 +444,13 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, ...@@ -442,6 +444,13 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
case IEEE80211_STYPE_REASSOC_RESP:{ case IEEE80211_STYPE_REASSOC_RESP:{
struct ieee80211_mgmt *mgnt = struct ieee80211_mgmt *mgnt =
(struct ieee80211_mgmt *)header; (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)) & priv->assoc_id = (~((1 << 15) | (1 << 14)) &
le16_to_cpu(mgnt->u. le16_to_cpu(mgnt->u.
assoc_resp.aid)); assoc_resp.aid));
......
...@@ -752,6 +752,7 @@ struct iwl3945_priv { ...@@ -752,6 +752,7 @@ struct iwl3945_priv {
/* Scan related variables */ /* Scan related variables */
unsigned long last_scan_jiffies; unsigned long last_scan_jiffies;
unsigned long next_scan_jiffies;
unsigned long scan_start; unsigned long scan_start;
unsigned long scan_pass_start; unsigned long scan_pass_start;
unsigned long scan_start_tsf; unsigned long scan_start_tsf;
......
...@@ -3802,6 +3802,8 @@ static void iwl4965_update_ps_mode(struct iwl4965_priv *priv, u16 ps_bit, u8 *ad ...@@ -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 /* Called for REPLY_4965_RX (legacy ABG frames), or
* REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv, static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
...@@ -3973,6 +3975,12 @@ 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 *mgnt =
(struct ieee80211_mgmt *)header; (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)) priv->assoc_id = (~((1 << 15) | (1 << 14))
& le16_to_cpu(mgnt->u.assoc_resp.aid)); & le16_to_cpu(mgnt->u.assoc_resp.aid));
priv->assoc_capability = priv->assoc_capability =
......
...@@ -1082,6 +1082,7 @@ struct iwl4965_priv { ...@@ -1082,6 +1082,7 @@ struct iwl4965_priv {
/* Scan related variables */ /* Scan related variables */
unsigned long last_scan_jiffies; unsigned long last_scan_jiffies;
unsigned long next_scan_jiffies;
unsigned long scan_start; unsigned long scan_start;
unsigned long scan_pass_start; unsigned long scan_pass_start;
unsigned long scan_start_tsf; unsigned long scan_start_tsf;
......
...@@ -2800,7 +2800,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, ...@@ -2800,7 +2800,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
IWL_DEBUG_TX("Sending REASSOC frame\n"); IWL_DEBUG_TX("Sending REASSOC frame\n");
#endif #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)) { ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
goto drop_unlock; goto drop_unlock;
...@@ -3737,6 +3738,7 @@ static void iwl3945_rx_scan_results_notif(struct iwl3945_priv *priv, ...@@ -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->last_scan_jiffies = jiffies; priv->last_scan_jiffies = jiffies;
priv->next_scan_jiffies = 0;
} }
/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
...@@ -3779,6 +3781,7 @@ static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv, ...@@ -3779,6 +3781,7 @@ static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv,
} }
priv->last_scan_jiffies = jiffies; priv->last_scan_jiffies = jiffies;
priv->next_scan_jiffies = 0;
IWL_DEBUG_INFO("Setting scan to off\n"); IWL_DEBUG_INFO("Setting scan to off\n");
clear_bit(STATUS_SCANNING, &priv->status); clear_bit(STATUS_SCANNING, &priv->status);
...@@ -6806,6 +6809,8 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data) ...@@ -6806,6 +6809,8 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
} }
#define IWL_DELAY_NEXT_SCAN (HZ*2)
static void iwl3945_bg_post_associate(struct work_struct *data) static void iwl3945_bg_post_associate(struct work_struct *data)
{ {
struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv,
...@@ -6906,6 +6911,8 @@ static void iwl3945_bg_post_associate(struct work_struct *data) ...@@ -6906,6 +6911,8 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
#ifdef CONFIG_IWL3945_QOS #ifdef CONFIG_IWL3945_QOS
iwl3945_activate_qos(priv, 0); iwl3945_activate_qos(priv, 0);
#endif /* CONFIG_IWL3945_QOS */ #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); mutex_unlock(&priv->mutex);
} }
...@@ -7338,7 +7345,6 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, ...@@ -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) static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
{ {
int rc = 0; int rc = 0;
...@@ -7362,16 +7368,20 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) ...@@ -7362,16 +7368,20 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
goto out_unlock; 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 we just finished scan ask for delay */
if (priv->last_scan_jiffies && if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies +
time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, IWL_DELAY_NEXT_SCAN, jiffies)) {
jiffies)) {
rc = -EAGAIN; rc = -EAGAIN;
goto out_unlock; goto out_unlock;
} }
if (len) { if (len) {
IWL_DEBUG_SCAN("direct scan for " IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
"%s [%d]\n ",
iwl3945_escape_essid(ssid, len), (int)len); iwl3945_escape_essid(ssid, len), (int)len);
priv->one_direct_scan = 1; priv->one_direct_scan = 1;
......
...@@ -2905,7 +2905,8 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, ...@@ -2905,7 +2905,8 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv,
IWL_DEBUG_TX("Sending REASSOC frame\n"); IWL_DEBUG_TX("Sending REASSOC frame\n");
#endif #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)) { ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n"); IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n");
goto drop_unlock; goto drop_unlock;
...@@ -4055,6 +4056,7 @@ static void iwl4965_rx_scan_results_notif(struct iwl4965_priv *priv, ...@@ -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->last_scan_jiffies = jiffies; priv->last_scan_jiffies = jiffies;
priv->next_scan_jiffies = 0;
} }
/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
...@@ -4097,6 +4099,7 @@ static void iwl4965_rx_scan_complete_notif(struct iwl4965_priv *priv, ...@@ -4097,6 +4099,7 @@ static void iwl4965_rx_scan_complete_notif(struct iwl4965_priv *priv,
} }
priv->last_scan_jiffies = jiffies; priv->last_scan_jiffies = jiffies;
priv->next_scan_jiffies = 0;
IWL_DEBUG_INFO("Setting scan to off\n"); IWL_DEBUG_INFO("Setting scan to off\n");
clear_bit(STATUS_SCANNING, &priv->status); clear_bit(STATUS_SCANNING, &priv->status);
...@@ -7228,6 +7231,8 @@ static void iwl4965_bg_rx_replenish(struct work_struct *data) ...@@ -7228,6 +7231,8 @@ static void iwl4965_bg_rx_replenish(struct work_struct *data)
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
} }
#define IWL_DELAY_NEXT_SCAN (HZ*2)
static void iwl4965_bg_post_associate(struct work_struct *data) static void iwl4965_bg_post_associate(struct work_struct *data)
{ {
struct iwl4965_priv *priv = container_of(data, struct iwl4965_priv, struct iwl4965_priv *priv = container_of(data, struct iwl4965_priv,
...@@ -7343,6 +7348,8 @@ static void iwl4965_bg_post_associate(struct work_struct *data) ...@@ -7343,6 +7348,8 @@ static void iwl4965_bg_post_associate(struct work_struct *data)
#ifdef CONFIG_IWL4965_QOS #ifdef CONFIG_IWL4965_QOS
iwl4965_activate_qos(priv, 0); iwl4965_activate_qos(priv, 0);
#endif /* CONFIG_IWL4965_QOS */ #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); mutex_unlock(&priv->mutex);
} }
...@@ -7811,7 +7818,6 @@ static void iwl4965_mac_erp_ie_changed(struct ieee80211_hw *hw, ...@@ -7811,7 +7818,6 @@ static void iwl4965_mac_erp_ie_changed(struct ieee80211_hw *hw,
iwl4965_send_rxon_assoc(priv); 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) static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
{ {
int rc = 0; int rc = 0;
...@@ -7835,16 +7841,20 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) ...@@ -7835,16 +7841,20 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
goto out_unlock; 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 we just finished scan ask for delay */
if (priv->last_scan_jiffies && if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies +
time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, IWL_DELAY_NEXT_SCAN, jiffies)) {
jiffies)) {
rc = -EAGAIN; rc = -EAGAIN;
goto out_unlock; goto out_unlock;
} }
if (len) { if (len) {
IWL_DEBUG_SCAN("direct scan for " IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
"%s [%d]\n ",
iwl4965_escape_essid(ssid, len), (int)len); iwl4965_escape_essid(ssid, len), (int)len);
priv->one_direct_scan = 1; priv->one_direct_scan = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment