Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=76bb77e03f5b01fb83fb9fa79febba6e499f948b
Commit:     76bb77e03f5b01fb83fb9fa79febba6e499f948b
Parent:     a84fd3452d65bd3ec39168ff976f9316f33ab8eb
Author:     Zhu Yi <[EMAIL PROTECTED]>
AuthorDate: Thu Nov 22 10:53:22 2007 +0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Mon Jan 28 15:05:39 2008 -0800

    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 <[EMAIL PROTECTED]>
    Signed-off-by: John W. Linville <[EMAIL PROTECTED]>
---
 drivers/net/wireless/iwlwifi/iwl-3945.h     |    1 +
 drivers/net/wireless/iwlwifi/iwl-4965.h     |    1 +
 drivers/net/wireless/iwlwifi/iwl3945-base.c |   50 +++++++++++++++++++-------
 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 462936a..263b0b7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -714,6 +714,7 @@ struct iwl3945_priv {
        struct ieee80211_hw *hw;
        struct ieee80211_channel *ieee_channels;
        struct ieee80211_rate *ieee_rates;
+       struct ieee80211_conf *cache_conf;
 
        /* temporary frame storage list */
        struct list_head free_frames;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h 
b/drivers/net/wireless/iwlwifi/iwl-4965.h
index 42ce27f..dda2bfb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.h
@@ -1044,6 +1044,7 @@ struct iwl4965_priv {
        struct ieee80211_hw *hw;
        struct ieee80211_channel *ieee_channels;
        struct ieee80211_rate *ieee_rates;
+       struct ieee80211_conf *cache_conf;
 
        /* temporary frame storage list */
        struct list_head free_frames;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c 
b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index ae352da..bab42a1 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)
        mutex_unlock(&priv->mutex);
 }
 
+static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf 
*conf);
+
 static void iwl3945_bg_scan_completed(struct work_struct *work)
 {
        struct iwl3945_priv *priv =
@@ -6975,6 +6977,9 @@ static void iwl3945_bg_scan_completed(struct work_struct 
*work)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
+       if (priv->cache_conf)
+               iwl3945_mac_config(priv->hw, priv->cache_conf);
+
        ieee80211_scan_completed(priv->hw);
 
        /* 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
        struct iwl3945_priv *priv = hw->priv;
        const struct iwl3945_channel_info *ch_info;
        unsigned long flags;
+       int ret = 0;
 
        mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel);
 
        if (!iwl3945_is_ready(priv)) {
                IWL_DEBUG_MAC80211("leave - not ready\n");
-               mutex_unlock(&priv->mutex);
-               return -EIO;
+               ret = -EIO;
+               goto out;
        }
 
        /* TODO: Figure out how to get ieee80211_local->sta_scanning w/ only
         * what is exposed through include/ declarations */
        if (unlikely(!iwl3945_param_disable_hw_scan &&
                     test_bit(STATUS_SCANNING, &priv->status))) {
-               IWL_DEBUG_MAC80211("leave - scanning\n");
+
+               if (priv->cache_conf)
+                       IWL_DEBUG_MAC80211("leave - still scanning\n");
+               else {
+                       /* Cache the configuration now so that we can
+                        * replay it after the hardware scan is finished. */
+                       priv->cache_conf = kmalloc(sizeof(*conf), GFP_KERNEL);
+                       if (priv->cache_conf) {
+                               memcpy(priv->cache_conf, conf, sizeof(*conf));
+                               IWL_DEBUG_MAC80211("leave - scanning\n");
+                       } else {
+                               IWL_DEBUG_MAC80211("leave - no memory\n");
+                               ret = -ENOMEM;
+                       }
+               }
                mutex_unlock(&priv->mutex);
-               return 0;
+               return ret;
        }
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -7131,8 +7151,8 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, 
struct ieee80211_conf *co
                               conf->channel, conf->phymode);
                IWL_DEBUG_MAC80211("leave - invalid channel\n");
                spin_unlock_irqrestore(&priv->lock, flags);
-               mutex_unlock(&priv->mutex);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
        }
 
        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
 #ifdef IEEE80211_CONF_CHANNEL_SWITCH
        if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) {
                iwl3945_hw_channel_switch(priv, conf->channel);
-               mutex_unlock(&priv->mutex);
-               return 0;
+               goto out;
        }
 #endif
 
@@ -7158,14 +7177,13 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, 
struct ieee80211_conf *co
 
        if (!conf->radio_enabled) {
                IWL_DEBUG_MAC80211("leave - radio disabled\n");
-               mutex_unlock(&priv->mutex);
-               return 0;
+               goto out;
        }
 
        if (iwl3945_is_rfkill(priv)) {
                IWL_DEBUG_MAC80211("leave - RF kill\n");
-               mutex_unlock(&priv->mutex);
-               return -EIO;
+               ret = -EIO;
+               goto out;
        }
 
        iwl3945_set_rate(priv);
@@ -7178,9 +7196,13 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, 
struct ieee80211_conf *co
 
        IWL_DEBUG_MAC80211("leave\n");
 
+out:
+       if (priv->cache_conf) {
+               kfree(priv->cache_conf);
+               priv->cache_conf = NULL;
+       }
        mutex_unlock(&priv->mutex);
-
-       return 0;
+       return ret;
 }
 
 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 6a8c629..8bc2634 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)
        mutex_unlock(&priv->mutex);
 }
 
+static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf 
*conf);
+
 static void iwl4965_bg_scan_completed(struct work_struct *work)
 {
        struct iwl4965_priv *priv =
@@ -7413,6 +7415,9 @@ static void iwl4965_bg_scan_completed(struct work_struct 
*work)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
+       if (priv->cache_conf)
+               iwl4965_mac_config(priv->hw, priv->cache_conf);
+
        ieee80211_scan_completed(priv->hw);
 
        /* 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
        struct iwl4965_priv *priv = hw->priv;
        const struct iwl4965_channel_info *ch_info;
        unsigned long flags;
+       int ret = 0;
 
        mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel);
 
        if (!iwl4965_is_ready(priv)) {
                IWL_DEBUG_MAC80211("leave - not ready\n");
-               mutex_unlock(&priv->mutex);
-               return -EIO;
+               ret = -EIO;
+               goto out;
        }
 
        /* TODO: Figure out how to get ieee80211_local->sta_scanning w/ only
         * what is exposed through include/ declarations */
        if (unlikely(!iwl4965_param_disable_hw_scan &&
                     test_bit(STATUS_SCANNING, &priv->status))) {
-               IWL_DEBUG_MAC80211("leave - scanning\n");
+
+               if (unlikely(priv->cache_conf))
+                       IWL_DEBUG_MAC80211("leave - still scanning\n");
+               else {
+                       /* Cache the configuration now so that we can
+                        * replay it after the hardware scan is finished. */
+                       priv->cache_conf = kmalloc(sizeof(*conf), GFP_KERNEL);
+                       if (priv->cache_conf) {
+                               memcpy(priv->cache_conf, conf, sizeof(*conf));
+                               IWL_DEBUG_MAC80211("leave - scanning\n");
+                       } else {
+                               IWL_DEBUG_MAC80211("leave - no memory\n");
+                               ret = -ENOMEM;
+                       }
+               }
                mutex_unlock(&priv->mutex);
-               return 0;
+               return ret;
        }
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -7568,8 +7588,8 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, 
struct ieee80211_conf *co
                               conf->channel, conf->phymode);
                IWL_DEBUG_MAC80211("leave - invalid channel\n");
                spin_unlock_irqrestore(&priv->lock, flags);
-               mutex_unlock(&priv->mutex);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
        }
 
 #ifdef CONFIG_IWL4965_HT
@@ -7598,8 +7618,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, 
struct ieee80211_conf *co
 #ifdef IEEE80211_CONF_CHANNEL_SWITCH
        if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) {
                iwl4965_hw_channel_switch(priv, conf->channel);
-               mutex_unlock(&priv->mutex);
-               return 0;
+               goto out;
        }
 #endif
 
@@ -7607,14 +7626,13 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, 
struct ieee80211_conf *co
 
        if (!conf->radio_enabled) {
                IWL_DEBUG_MAC80211("leave - radio disabled\n");
-               mutex_unlock(&priv->mutex);
-               return 0;
+               goto out;
        }
 
        if (iwl4965_is_rfkill(priv)) {
                IWL_DEBUG_MAC80211("leave - RF kill\n");
-               mutex_unlock(&priv->mutex);
-               return -EIO;
+               ret = -EIO;
+               goto out;
        }
 
        iwl4965_set_rate(priv);
@@ -7627,9 +7645,13 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, 
struct ieee80211_conf *co
 
        IWL_DEBUG_MAC80211("leave\n");
 
+out:
+       if (priv->cache_conf) {
+               kfree(priv->cache_conf);
+               priv->cache_conf = NULL;
+       }
        mutex_unlock(&priv->mutex);
-
-       return 0;
+       return ret;
 }
 
 static void iwl4965_config_ap(struct iwl4965_priv *priv)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to