iwmc3200wifi: cache keys when interface is down
authorSamuel Ortiz <samuel.ortiz@intel.com>
Mon, 15 Jun 2009 19:59:54 +0000 (21:59 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 10 Jul 2009 18:57:52 +0000 (14:57 -0400)
When the interface is down and one sets a WEP key from userspace, we should
be able to simply cache it.
Since that implies setting part of the profile's security settings, we now
alloc/free the umac_profile at probe/remove time, and no longer at interface
bring up/down time. Simply resetting it during the latter is enough.

Signed-off-by: Samuel Ortiz <samuel.ortiz@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwmc3200wifi/cfg80211.c
drivers/net/wireless/iwmc3200wifi/main.c
drivers/net/wireless/iwmc3200wifi/netdev.c

index 739bd9b0ddea15ac63c55ec147ae3a50eee7cbae..0cdd7ef68b78e5daa8b2194e79e4b2e950a3d208 100644 (file)
@@ -271,6 +271,10 @@ static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
        if (key_index == iwm->default_key)
                iwm->default_key = -1;
 
+       /* If the interface is down, we just cache this */
+       if (!test_bit(IWM_STATUS_READY, &iwm->status))
+               return 0;
+
        return iwm_set_key(iwm, 1, key);
 }
 
@@ -288,12 +292,16 @@ static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
                return -EINVAL;
        }
 
+       iwm->default_key = key_index;
+
+       /* If the interface is down, we just cache this */
+       if (!test_bit(IWM_STATUS_READY, &iwm->status))
+               return 0;
+
        ret = iwm_set_tx_key(iwm, key_index);
        if (ret < 0)
                return ret;
 
-       iwm->default_key = key_index;
-
        return iwm_reset_profile(iwm);
 }
 
index 7f56c06a53db84787bde98e3111e8aa67a4f3cfb..930056b013f3818cd7c88c799d809469fc2b8d5c 100644 (file)
@@ -643,19 +643,10 @@ int __iwm_up(struct iwm_priv *iwm)
                }
        }
 
-       iwm->umac_profile = kmalloc(sizeof(struct iwm_umac_profile),
-                                   GFP_KERNEL);
-       if (!iwm->umac_profile) {
-               IWM_ERR(iwm, "Couldn't alloc memory for profile\n");
-               goto err_fw;
-       }
-
-       iwm_init_default_profile(iwm, iwm->umac_profile);
-
        ret = iwm_channels_init(iwm);
        if (ret < 0) {
                IWM_ERR(iwm, "Couldn't init channels\n");
-               goto err_profile;
+               goto err_fw;
        }
 
        /* Set the READY bit to indicate interface is brought up successfully */
@@ -663,10 +654,6 @@ int __iwm_up(struct iwm_priv *iwm)
 
        return 0;
 
- err_profile:
-       kfree(iwm->umac_profile);
-       iwm->umac_profile = NULL;
-
  err_fw:
        iwm_eeprom_exit(iwm);
 
@@ -705,10 +692,9 @@ int __iwm_down(struct iwm_priv *iwm)
        clear_bit(IWM_STATUS_READY, &iwm->status);
 
        iwm_eeprom_exit(iwm);
-       kfree(iwm->umac_profile);
-       iwm->umac_profile = NULL;
        iwm_bss_list_clean(iwm);
-
+       iwm_init_default_profile(iwm, iwm->umac_profile);
+       iwm->umac_profile_active = false;
        iwm->default_key = -1;
        iwm->core_enabled = 0;
 
index aaa20c6885c8774c4e2af9e30164034456fb16f4..d4deb4b471e529f208f64b21904de47c0a5cf549 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/netdevice.h>
 
 #include "iwm.h"
+#include "commands.h"
 #include "cfg80211.h"
 #include "debug.h"
 
@@ -135,8 +136,20 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
        SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
        wdev->netdev = ndev;
 
+       iwm->umac_profile = kmalloc(sizeof(struct iwm_umac_profile),
+                                   GFP_KERNEL);
+       if (!iwm->umac_profile) {
+               dev_err(dev, "Couldn't alloc memory for profile\n");
+               goto out_profile;
+       }
+
+       iwm_init_default_profile(iwm, iwm->umac_profile);
+
        return iwm;
 
+ out_profile:
+       free_netdev(ndev);
+
  out_priv:
        iwm_priv_deinit(iwm);
 
@@ -153,6 +166,8 @@ void iwm_if_free(struct iwm_priv *iwm)
        free_netdev(iwm_to_ndev(iwm));
        iwm_wdev_free(iwm);
        iwm_priv_deinit(iwm);
+       kfree(iwm->umac_profile);
+       iwm->umac_profile = NULL;
 }
 
 int iwm_if_add(struct iwm_priv *iwm)