aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2007-11-21 21:53:22 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:05:39 -0500
commit76bb77e03f5b01fb83fb9fa79febba6e499f948b (patch)
tree77c84ccefe35be9085b9ebb3387cb53eeaa6ea34
parenta84fd3452d65bd3ec39168ff976f9316f33ab8eb (diff)
iwlwifi: cache mac80211 conf setting during a hardware scan
This patch caches mac80211 configuration setting during a hardware scan for the iwlwifi drivers. Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c50
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c50
4 files changed, 74 insertions, 28 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 462936a74c19..263b0b71c0c3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -714,6 +714,7 @@ struct iwl3945_priv {
714 struct ieee80211_hw *hw; 714 struct ieee80211_hw *hw;
715 struct ieee80211_channel *ieee_channels; 715 struct ieee80211_channel *ieee_channels;
716 struct ieee80211_rate *ieee_rates; 716 struct ieee80211_rate *ieee_rates;
717 struct ieee80211_conf *cache_conf;
717 718
718 /* temporary frame storage list */ 719 /* temporary frame storage list */
719 struct list_head free_frames; 720 struct list_head free_frames;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h
index 42ce27f2eee4..dda2bfbcb059 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.h
@@ -1044,6 +1044,7 @@ struct iwl4965_priv {
1044 struct ieee80211_hw *hw; 1044 struct ieee80211_hw *hw;
1045 struct ieee80211_channel *ieee_channels; 1045 struct ieee80211_channel *ieee_channels;
1046 struct ieee80211_rate *ieee_rates; 1046 struct ieee80211_rate *ieee_rates;
1047 struct ieee80211_conf *cache_conf;
1047 1048
1048 /* temporary frame storage list */ 1049 /* temporary frame storage list */
1049 struct list_head free_frames; 1050 struct list_head free_frames;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index ae352daeb3fb..bab42a1351ca 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -6965,6 +6965,8 @@ static void iwl3945_bg_abort_scan(struct work_struct *work)
6965 mutex_unlock(&priv->mutex); 6965 mutex_unlock(&priv->mutex);
6966} 6966}
6967 6967
6968static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
6969
6968static void iwl3945_bg_scan_completed(struct work_struct *work) 6970static void iwl3945_bg_scan_completed(struct work_struct *work)
6969{ 6971{
6970 struct iwl3945_priv *priv = 6972 struct iwl3945_priv *priv =
@@ -6975,6 +6977,9 @@ static void iwl3945_bg_scan_completed(struct work_struct *work)
6975 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 6977 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
6976 return; 6978 return;
6977 6979
6980 if (priv->cache_conf)
6981 iwl3945_mac_config(priv->hw, priv->cache_conf);
6982
6978 ieee80211_scan_completed(priv->hw); 6983 ieee80211_scan_completed(priv->hw);
6979 6984
6980 /* Since setting the TXPOWER may have been deferred while 6985 /* Since setting the TXPOWER may have been deferred while
@@ -7104,23 +7109,38 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
7104 struct iwl3945_priv *priv = hw->priv; 7109 struct iwl3945_priv *priv = hw->priv;
7105 const struct iwl3945_channel_info *ch_info; 7110 const struct iwl3945_channel_info *ch_info;
7106 unsigned long flags; 7111 unsigned long flags;
7112 int ret = 0;
7107 7113
7108 mutex_lock(&priv->mutex); 7114 mutex_lock(&priv->mutex);
7109 IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel); 7115 IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel);
7110 7116
7111 if (!iwl3945_is_ready(priv)) { 7117 if (!iwl3945_is_ready(priv)) {
7112 IWL_DEBUG_MAC80211("leave - not ready\n"); 7118 IWL_DEBUG_MAC80211("leave - not ready\n");
7113 mutex_unlock(&priv->mutex); 7119 ret = -EIO;
7114 return -EIO; 7120 goto out;
7115 } 7121 }
7116 7122
7117 /* TODO: Figure out how to get ieee80211_local->sta_scanning w/ only 7123 /* TODO: Figure out how to get ieee80211_local->sta_scanning w/ only
7118 * what is exposed through include/ declarations */ 7124 * what is exposed through include/ declarations */
7119 if (unlikely(!iwl3945_param_disable_hw_scan && 7125 if (unlikely(!iwl3945_param_disable_hw_scan &&
7120 test_bit(STATUS_SCANNING, &priv->status))) { 7126 test_bit(STATUS_SCANNING, &priv->status))) {
7121 IWL_DEBUG_MAC80211("leave - scanning\n"); 7127
7128 if (priv->cache_conf)
7129 IWL_DEBUG_MAC80211("leave - still scanning\n");
7130 else {
7131 /* Cache the configuration now so that we can
7132 * replay it after the hardware scan is finished. */
7133 priv->cache_conf = kmalloc(sizeof(*conf), GFP_KERNEL);
7134 if (priv->cache_conf) {
7135 memcpy(priv->cache_conf, conf, sizeof(*conf));
7136 IWL_DEBUG_MAC80211("leave - scanning\n");
7137 } else {
7138 IWL_DEBUG_MAC80211("leave - no memory\n");
7139 ret = -ENOMEM;
7140 }
7141 }
7122 mutex_unlock(&priv->mutex); 7142 mutex_unlock(&priv->mutex);
7123 return 0; 7143 return ret;
7124 } 7144 }
7125 7145
7126 spin_lock_irqsave(&priv->lock, flags); 7146 spin_lock_irqsave(&priv->lock, flags);
@@ -7131,8 +7151,8 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
7131 conf->channel, conf->phymode); 7151 conf->channel, conf->phymode);
7132 IWL_DEBUG_MAC80211("leave - invalid channel\n"); 7152 IWL_DEBUG_MAC80211("leave - invalid channel\n");
7133 spin_unlock_irqrestore(&priv->lock, flags); 7153 spin_unlock_irqrestore(&priv->lock, flags);
7134 mutex_unlock(&priv->mutex); 7154 ret = -EINVAL;
7135 return -EINVAL; 7155 goto out;
7136 } 7156 }
7137 7157
7138 iwl3945_set_rxon_channel(priv, conf->phymode, conf->channel); 7158 iwl3945_set_rxon_channel(priv, conf->phymode, conf->channel);
@@ -7149,8 +7169,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
7149#ifdef IEEE80211_CONF_CHANNEL_SWITCH 7169#ifdef IEEE80211_CONF_CHANNEL_SWITCH
7150 if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) { 7170 if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) {
7151 iwl3945_hw_channel_switch(priv, conf->channel); 7171 iwl3945_hw_channel_switch(priv, conf->channel);
7152 mutex_unlock(&priv->mutex); 7172 goto out;
7153 return 0;
7154 } 7173 }
7155#endif 7174#endif
7156 7175
@@ -7158,14 +7177,13 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
7158 7177
7159 if (!conf->radio_enabled) { 7178 if (!conf->radio_enabled) {
7160 IWL_DEBUG_MAC80211("leave - radio disabled\n"); 7179 IWL_DEBUG_MAC80211("leave - radio disabled\n");
7161 mutex_unlock(&priv->mutex); 7180 goto out;
7162 return 0;
7163 } 7181 }
7164 7182
7165 if (iwl3945_is_rfkill(priv)) { 7183 if (iwl3945_is_rfkill(priv)) {
7166 IWL_DEBUG_MAC80211("leave - RF kill\n"); 7184 IWL_DEBUG_MAC80211("leave - RF kill\n");
7167 mutex_unlock(&priv->mutex); 7185 ret = -EIO;
7168 return -EIO; 7186 goto out;
7169 } 7187 }
7170 7188
7171 iwl3945_set_rate(priv); 7189 iwl3945_set_rate(priv);
@@ -7178,9 +7196,13 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
7178 7196
7179 IWL_DEBUG_MAC80211("leave\n"); 7197 IWL_DEBUG_MAC80211("leave\n");
7180 7198
7199out:
7200 if (priv->cache_conf) {
7201 kfree(priv->cache_conf);
7202 priv->cache_conf = NULL;
7203 }
7181 mutex_unlock(&priv->mutex); 7204 mutex_unlock(&priv->mutex);
7182 7205 return ret;
7183 return 0;
7184} 7206}
7185 7207
7186static void iwl3945_config_ap(struct iwl3945_priv *priv) 7208static void iwl3945_config_ap(struct iwl3945_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 6a8c629ce0bb..8bc2634bb407 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -7403,6 +7403,8 @@ static void iwl4965_bg_abort_scan(struct work_struct *work)
7403 mutex_unlock(&priv->mutex); 7403 mutex_unlock(&priv->mutex);
7404} 7404}
7405 7405
7406static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
7407
7406static void iwl4965_bg_scan_completed(struct work_struct *work) 7408static void iwl4965_bg_scan_completed(struct work_struct *work)
7407{ 7409{
7408 struct iwl4965_priv *priv = 7410 struct iwl4965_priv *priv =
@@ -7413,6 +7415,9 @@ static void iwl4965_bg_scan_completed(struct work_struct *work)
7413 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 7415 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
7414 return; 7416 return;
7415 7417
7418 if (priv->cache_conf)
7419 iwl4965_mac_config(priv->hw, priv->cache_conf);
7420
7416 ieee80211_scan_completed(priv->hw); 7421 ieee80211_scan_completed(priv->hw);
7417 7422
7418 /* Since setting the TXPOWER may have been deferred while 7423 /* Since setting the TXPOWER may have been deferred while
@@ -7541,23 +7546,38 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
7541 struct iwl4965_priv *priv = hw->priv; 7546 struct iwl4965_priv *priv = hw->priv;
7542 const struct iwl4965_channel_info *ch_info; 7547 const struct iwl4965_channel_info *ch_info;
7543 unsigned long flags; 7548 unsigned long flags;
7549 int ret = 0;
7544 7550
7545 mutex_lock(&priv->mutex); 7551 mutex_lock(&priv->mutex);
7546 IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel); 7552 IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel);
7547 7553
7548 if (!iwl4965_is_ready(priv)) { 7554 if (!iwl4965_is_ready(priv)) {
7549 IWL_DEBUG_MAC80211("leave - not ready\n"); 7555 IWL_DEBUG_MAC80211("leave - not ready\n");
7550 mutex_unlock(&priv->mutex); 7556 ret = -EIO;
7551 return -EIO; 7557 goto out;
7552 } 7558 }
7553 7559
7554 /* TODO: Figure out how to get ieee80211_local->sta_scanning w/ only 7560 /* TODO: Figure out how to get ieee80211_local->sta_scanning w/ only
7555 * what is exposed through include/ declarations */ 7561 * what is exposed through include/ declarations */
7556 if (unlikely(!iwl4965_param_disable_hw_scan && 7562 if (unlikely(!iwl4965_param_disable_hw_scan &&
7557 test_bit(STATUS_SCANNING, &priv->status))) { 7563 test_bit(STATUS_SCANNING, &priv->status))) {
7558 IWL_DEBUG_MAC80211("leave - scanning\n"); 7564
7565 if (unlikely(priv->cache_conf))
7566 IWL_DEBUG_MAC80211("leave - still scanning\n");
7567 else {
7568 /* Cache the configuration now so that we can
7569 * replay it after the hardware scan is finished. */
7570 priv->cache_conf = kmalloc(sizeof(*conf), GFP_KERNEL);
7571 if (priv->cache_conf) {
7572 memcpy(priv->cache_conf, conf, sizeof(*conf));
7573 IWL_DEBUG_MAC80211("leave - scanning\n");
7574 } else {
7575 IWL_DEBUG_MAC80211("leave - no memory\n");
7576 ret = -ENOMEM;
7577 }
7578 }
7559 mutex_unlock(&priv->mutex); 7579 mutex_unlock(&priv->mutex);
7560 return 0; 7580 return ret;
7561 } 7581 }
7562 7582
7563 spin_lock_irqsave(&priv->lock, flags); 7583 spin_lock_irqsave(&priv->lock, flags);
@@ -7568,8 +7588,8 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
7568 conf->channel, conf->phymode); 7588 conf->channel, conf->phymode);
7569 IWL_DEBUG_MAC80211("leave - invalid channel\n"); 7589 IWL_DEBUG_MAC80211("leave - invalid channel\n");
7570 spin_unlock_irqrestore(&priv->lock, flags); 7590 spin_unlock_irqrestore(&priv->lock, flags);
7571 mutex_unlock(&priv->mutex); 7591 ret = -EINVAL;
7572 return -EINVAL; 7592 goto out;
7573 } 7593 }
7574 7594
7575#ifdef CONFIG_IWL4965_HT 7595#ifdef CONFIG_IWL4965_HT
@@ -7598,8 +7618,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
7598#ifdef IEEE80211_CONF_CHANNEL_SWITCH 7618#ifdef IEEE80211_CONF_CHANNEL_SWITCH
7599 if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) { 7619 if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) {
7600 iwl4965_hw_channel_switch(priv, conf->channel); 7620 iwl4965_hw_channel_switch(priv, conf->channel);
7601 mutex_unlock(&priv->mutex); 7621 goto out;
7602 return 0;
7603 } 7622 }
7604#endif 7623#endif
7605 7624
@@ -7607,14 +7626,13 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
7607 7626
7608 if (!conf->radio_enabled) { 7627 if (!conf->radio_enabled) {
7609 IWL_DEBUG_MAC80211("leave - radio disabled\n"); 7628 IWL_DEBUG_MAC80211("leave - radio disabled\n");
7610 mutex_unlock(&priv->mutex); 7629 goto out;
7611 return 0;
7612 } 7630 }
7613 7631
7614 if (iwl4965_is_rfkill(priv)) { 7632 if (iwl4965_is_rfkill(priv)) {
7615 IWL_DEBUG_MAC80211("leave - RF kill\n"); 7633 IWL_DEBUG_MAC80211("leave - RF kill\n");
7616 mutex_unlock(&priv->mutex); 7634 ret = -EIO;
7617 return -EIO; 7635 goto out;
7618 } 7636 }
7619 7637
7620 iwl4965_set_rate(priv); 7638 iwl4965_set_rate(priv);
@@ -7627,9 +7645,13 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
7627 7645
7628 IWL_DEBUG_MAC80211("leave\n"); 7646 IWL_DEBUG_MAC80211("leave\n");
7629 7647
7648out:
7649 if (priv->cache_conf) {
7650 kfree(priv->cache_conf);
7651 priv->cache_conf = NULL;
7652 }
7630 mutex_unlock(&priv->mutex); 7653 mutex_unlock(&priv->mutex);
7631 7654 return ret;
7632 return 0;
7633} 7655}
7634 7656
7635static void iwl4965_config_ap(struct iwl4965_priv *priv) 7657static void iwl4965_config_ap(struct iwl4965_priv *priv)