]> err.no Git - linux-2.6/blobdiff - net/ieee80211/ieee80211_crypt.c
Merge branch 'master'
[linux-2.6] / net / ieee80211 / ieee80211_crypt.c
index 0c366299db0f7c72ec3e95bf71af86d875b48f59..20cc580a07e0dcec958aeaf22387e6fe008f7800 100644 (file)
@@ -12,7 +12,6 @@
  */
 
 #include <linux/config.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -44,6 +43,10 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
        unsigned long flags;
 
        spin_lock_irqsave(&ieee->lock, flags);
+
+       if (list_empty(&ieee->crypt_deinit_list))
+               goto unlock;
+
        for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
             ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
                entry = list_entry(ptr, struct ieee80211_crypt_data, list);
@@ -59,21 +62,35 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
                }
                kfree(entry);
        }
+      unlock:
+       spin_unlock_irqrestore(&ieee->lock, flags);
+}
+
+/* After this, crypt_deinit_list won't accept new members */
+void ieee80211_crypt_quiescing(struct ieee80211_device *ieee)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&ieee->lock, flags);
+       ieee->crypt_quiesced = 1;
        spin_unlock_irqrestore(&ieee->lock, flags);
 }
 
 void ieee80211_crypt_deinit_handler(unsigned long data)
 {
        struct ieee80211_device *ieee = (struct ieee80211_device *)data;
+       unsigned long flags;
 
        ieee80211_crypt_deinit_entries(ieee, 0);
-       if (!list_empty(&ieee->crypt_deinit_list)) {
+
+       spin_lock_irqsave(&ieee->lock, flags);
+       if (!list_empty(&ieee->crypt_deinit_list) && !ieee->crypt_quiesced) {
                printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
                       "deletion list\n", ieee->dev->name);
                ieee->crypt_deinit_timer.expires = jiffies + HZ;
                add_timer(&ieee->crypt_deinit_timer);
        }
-
+       spin_unlock_irqrestore(&ieee->lock, flags);
 }
 
 void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
@@ -93,10 +110,12 @@ void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
         * locking. */
 
        spin_lock_irqsave(&ieee->lock, flags);
-       list_add(&tmp->list, &ieee->crypt_deinit_list);
-       if (!timer_pending(&ieee->crypt_deinit_timer)) {
-               ieee->crypt_deinit_timer.expires = jiffies + HZ;
-               add_timer(&ieee->crypt_deinit_timer);
+       if (!ieee->crypt_quiesced) {
+               list_add(&tmp->list, &ieee->crypt_deinit_list);
+               if (!timer_pending(&ieee->crypt_deinit_timer)) {
+                       ieee->crypt_deinit_timer.expires = jiffies + HZ;
+                       add_timer(&ieee->crypt_deinit_timer);
+               }
        }
        spin_unlock_irqrestore(&ieee->lock, flags);
 }
@@ -182,8 +201,7 @@ struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
                return NULL;
 }
 
-static void *ieee80211_crypt_null_init(struct ieee80211_device *ieee,
-                                      int keyidx)
+static void *ieee80211_crypt_null_init(int keyidx)
 {
        return (void *)1;
 }
@@ -201,8 +219,8 @@ static struct ieee80211_crypto_ops ieee80211_crypt_null = {
        .decrypt_msdu = NULL,
        .set_key = NULL,
        .get_key = NULL,
-       .extra_prefix_len = 0,
-       .extra_postfix_len = 0,
+       .extra_mpdu_prefix_len = 0,
+       .extra_mpdu_postfix_len = 0,
        .owner = THIS_MODULE,
 };
 
@@ -250,6 +268,7 @@ static void __exit ieee80211_crypto_deinit(void)
 EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
 EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
 EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
+EXPORT_SYMBOL(ieee80211_crypt_quiescing);
 
 EXPORT_SYMBOL(ieee80211_register_crypto_ops);
 EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);