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/wireless/iwlwifi/iwl4965-base.c | |
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/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 50 |
1 files changed, 36 insertions, 14 deletions
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) |