diff options
Diffstat (limited to 'net/ieee80211/ieee80211_crypt.c')
| -rw-r--r-- | net/ieee80211/ieee80211_crypt.c | 59 |
1 files changed, 40 insertions, 19 deletions
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c index 61a9d92e455b..f3b6aa3be638 100644 --- a/net/ieee80211/ieee80211_crypt.c +++ b/net/ieee80211/ieee80211_crypt.c | |||
| @@ -41,6 +41,12 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force) | |||
| 41 | { | 41 | { |
| 42 | struct list_head *ptr, *n; | 42 | struct list_head *ptr, *n; |
| 43 | struct ieee80211_crypt_data *entry; | 43 | struct ieee80211_crypt_data *entry; |
| 44 | unsigned long flags; | ||
| 45 | |||
| 46 | spin_lock_irqsave(&ieee->lock, flags); | ||
| 47 | |||
| 48 | if (list_empty(&ieee->crypt_deinit_list)) | ||
| 49 | goto unlock; | ||
| 44 | 50 | ||
| 45 | for (ptr = ieee->crypt_deinit_list.next, n = ptr->next; | 51 | for (ptr = ieee->crypt_deinit_list.next, n = ptr->next; |
| 46 | ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) { | 52 | ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) { |
| @@ -57,6 +63,18 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force) | |||
| 57 | } | 63 | } |
| 58 | kfree(entry); | 64 | kfree(entry); |
| 59 | } | 65 | } |
| 66 | unlock: | ||
| 67 | spin_unlock_irqrestore(&ieee->lock, flags); | ||
| 68 | } | ||
| 69 | |||
| 70 | /* After this, crypt_deinit_list won't accept new members */ | ||
| 71 | void ieee80211_crypt_quiescing(struct ieee80211_device *ieee) | ||
| 72 | { | ||
| 73 | unsigned long flags; | ||
| 74 | |||
| 75 | spin_lock_irqsave(&ieee->lock, flags); | ||
| 76 | ieee->crypt_quiesced = 1; | ||
| 77 | spin_unlock_irqrestore(&ieee->lock, flags); | ||
| 60 | } | 78 | } |
| 61 | 79 | ||
| 62 | void ieee80211_crypt_deinit_handler(unsigned long data) | 80 | void ieee80211_crypt_deinit_handler(unsigned long data) |
| @@ -64,16 +82,16 @@ void ieee80211_crypt_deinit_handler(unsigned long data) | |||
| 64 | struct ieee80211_device *ieee = (struct ieee80211_device *)data; | 82 | struct ieee80211_device *ieee = (struct ieee80211_device *)data; |
| 65 | unsigned long flags; | 83 | unsigned long flags; |
| 66 | 84 | ||
| 67 | spin_lock_irqsave(&ieee->lock, flags); | ||
| 68 | ieee80211_crypt_deinit_entries(ieee, 0); | 85 | ieee80211_crypt_deinit_entries(ieee, 0); |
| 69 | if (!list_empty(&ieee->crypt_deinit_list)) { | 86 | |
| 87 | spin_lock_irqsave(&ieee->lock, flags); | ||
| 88 | if (!list_empty(&ieee->crypt_deinit_list) && !ieee->crypt_quiesced) { | ||
| 70 | printk(KERN_DEBUG "%s: entries remaining in delayed crypt " | 89 | printk(KERN_DEBUG "%s: entries remaining in delayed crypt " |
| 71 | "deletion list\n", ieee->dev->name); | 90 | "deletion list\n", ieee->dev->name); |
| 72 | ieee->crypt_deinit_timer.expires = jiffies + HZ; | 91 | ieee->crypt_deinit_timer.expires = jiffies + HZ; |
| 73 | add_timer(&ieee->crypt_deinit_timer); | 92 | add_timer(&ieee->crypt_deinit_timer); |
| 74 | } | 93 | } |
| 75 | spin_unlock_irqrestore(&ieee->lock, flags); | 94 | spin_unlock_irqrestore(&ieee->lock, flags); |
| 76 | |||
| 77 | } | 95 | } |
| 78 | 96 | ||
| 79 | void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, | 97 | void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, |
| @@ -93,10 +111,12 @@ void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, | |||
| 93 | * locking. */ | 111 | * locking. */ |
| 94 | 112 | ||
| 95 | spin_lock_irqsave(&ieee->lock, flags); | 113 | spin_lock_irqsave(&ieee->lock, flags); |
| 96 | list_add(&tmp->list, &ieee->crypt_deinit_list); | 114 | if (!ieee->crypt_quiesced) { |
| 97 | if (!timer_pending(&ieee->crypt_deinit_timer)) { | 115 | list_add(&tmp->list, &ieee->crypt_deinit_list); |
| 98 | ieee->crypt_deinit_timer.expires = jiffies + HZ; | 116 | if (!timer_pending(&ieee->crypt_deinit_timer)) { |
| 99 | add_timer(&ieee->crypt_deinit_timer); | 117 | ieee->crypt_deinit_timer.expires = jiffies + HZ; |
| 118 | add_timer(&ieee->crypt_deinit_timer); | ||
| 119 | } | ||
| 100 | } | 120 | } |
| 101 | spin_unlock_irqrestore(&ieee->lock, flags); | 121 | spin_unlock_irqrestore(&ieee->lock, flags); |
| 102 | } | 122 | } |
| @@ -191,18 +211,18 @@ static void ieee80211_crypt_null_deinit(void *priv) | |||
| 191 | } | 211 | } |
| 192 | 212 | ||
| 193 | static struct ieee80211_crypto_ops ieee80211_crypt_null = { | 213 | static struct ieee80211_crypto_ops ieee80211_crypt_null = { |
| 194 | .name = "NULL", | 214 | .name = "NULL", |
| 195 | .init = ieee80211_crypt_null_init, | 215 | .init = ieee80211_crypt_null_init, |
| 196 | .deinit = ieee80211_crypt_null_deinit, | 216 | .deinit = ieee80211_crypt_null_deinit, |
| 197 | .encrypt_mpdu = NULL, | 217 | .encrypt_mpdu = NULL, |
| 198 | .decrypt_mpdu = NULL, | 218 | .decrypt_mpdu = NULL, |
| 199 | .encrypt_msdu = NULL, | 219 | .encrypt_msdu = NULL, |
| 200 | .decrypt_msdu = NULL, | 220 | .decrypt_msdu = NULL, |
| 201 | .set_key = NULL, | 221 | .set_key = NULL, |
| 202 | .get_key = NULL, | 222 | .get_key = NULL, |
| 203 | .extra_prefix_len = 0, | 223 | .extra_mpdu_prefix_len = 0, |
| 204 | .extra_postfix_len = 0, | 224 | .extra_mpdu_postfix_len = 0, |
| 205 | .owner = THIS_MODULE, | 225 | .owner = THIS_MODULE, |
| 206 | }; | 226 | }; |
| 207 | 227 | ||
| 208 | static int __init ieee80211_crypto_init(void) | 228 | static int __init ieee80211_crypto_init(void) |
| @@ -249,6 +269,7 @@ static void __exit ieee80211_crypto_deinit(void) | |||
| 249 | EXPORT_SYMBOL(ieee80211_crypt_deinit_entries); | 269 | EXPORT_SYMBOL(ieee80211_crypt_deinit_entries); |
| 250 | EXPORT_SYMBOL(ieee80211_crypt_deinit_handler); | 270 | EXPORT_SYMBOL(ieee80211_crypt_deinit_handler); |
| 251 | EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit); | 271 | EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit); |
| 272 | EXPORT_SYMBOL(ieee80211_crypt_quiescing); | ||
| 252 | 273 | ||
| 253 | EXPORT_SYMBOL(ieee80211_register_crypto_ops); | 274 | EXPORT_SYMBOL(ieee80211_register_crypto_ops); |
| 254 | EXPORT_SYMBOL(ieee80211_unregister_crypto_ops); | 275 | EXPORT_SYMBOL(ieee80211_unregister_crypto_ops); |
