diff options
author | Zhu Yi <yi.zhu@intel.com> | 2007-11-21 21:53:22 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:05:39 -0500 |
commit | 76bb77e03f5b01fb83fb9fa79febba6e499f948b (patch) | |
tree | 77c84ccefe35be9085b9ebb3387cb53eeaa6ea34 /drivers/net | |
parent | a84fd3452d65bd3ec39168ff976f9316f33ab8eb (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>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 50 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 50 |
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 | ||
6968 | static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); | ||
6969 | |||
6968 | static void iwl3945_bg_scan_completed(struct work_struct *work) | 6970 | static 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 | ||
7199 | out: | ||
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 | ||
7186 | static void iwl3945_config_ap(struct iwl3945_priv *priv) | 7208 | static 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 | ||
7406 | static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); | ||
7407 | |||
7406 | static void iwl4965_bg_scan_completed(struct work_struct *work) | 7408 | static 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 | ||
7648 | out: | ||
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 | ||
7635 | static void iwl4965_config_ap(struct iwl4965_priv *priv) | 7657 | static void iwl4965_config_ap(struct iwl4965_priv *priv) |