aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211/ieee80211_crypt.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2008-10-29 11:35:05 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-11-21 11:08:17 -0500
commit274bfb8dc5ffa16cb073801bebe76ab7f4e2e73d (patch)
tree04cd3f6a062496911b56737daa6a0858b769ccd6 /net/ieee80211/ieee80211_crypt.c
parentdfe1bafdbac1c7b48b636fb7ace799e78170e0d6 (diff)
lib80211: absorb crypto bits from net/ieee80211
These bits are shared already between ipw2x00 and hostap, and could probably be shared both more cleanly and with other drivers. This commit simply relocates the code to lib80211 and adjusts the drivers appropriately. Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/ieee80211/ieee80211_crypt.c')
-rw-r--r--net/ieee80211/ieee80211_crypt.c206
1 files changed, 0 insertions, 206 deletions
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
deleted file mode 100644
index df5592c9339f..000000000000
--- a/net/ieee80211/ieee80211_crypt.c
+++ /dev/null
@@ -1,206 +0,0 @@
1/*
2 * Host AP crypto routines
3 *
4 * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
5 * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. See README and COPYING for
10 * more details.
11 *
12 */
13
14#include <linux/errno.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/string.h>
19#include <net/ieee80211.h>
20
21MODULE_AUTHOR("Jouni Malinen");
22MODULE_DESCRIPTION("HostAP crypto");
23MODULE_LICENSE("GPL");
24
25struct ieee80211_crypto_alg {
26 struct list_head list;
27 struct ieee80211_crypto_ops *ops;
28};
29
30static LIST_HEAD(ieee80211_crypto_algs);
31static DEFINE_SPINLOCK(ieee80211_crypto_lock);
32
33void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
34{
35 struct ieee80211_crypt_data *entry, *next;
36 unsigned long flags;
37
38 spin_lock_irqsave(&ieee->lock, flags);
39 list_for_each_entry_safe(entry, next, &ieee->crypt_deinit_list, list) {
40 if (atomic_read(&entry->refcnt) != 0 && !force)
41 continue;
42
43 list_del(&entry->list);
44
45 if (entry->ops) {
46 entry->ops->deinit(entry->priv);
47 module_put(entry->ops->owner);
48 }
49 kfree(entry);
50 }
51 spin_unlock_irqrestore(&ieee->lock, flags);
52}
53
54/* After this, crypt_deinit_list won't accept new members */
55void ieee80211_crypt_quiescing(struct ieee80211_device *ieee)
56{
57 unsigned long flags;
58
59 spin_lock_irqsave(&ieee->lock, flags);
60 ieee->crypt_quiesced = 1;
61 spin_unlock_irqrestore(&ieee->lock, flags);
62}
63
64void ieee80211_crypt_deinit_handler(unsigned long data)
65{
66 struct ieee80211_device *ieee = (struct ieee80211_device *)data;
67 unsigned long flags;
68
69 ieee80211_crypt_deinit_entries(ieee, 0);
70
71 spin_lock_irqsave(&ieee->lock, flags);
72 if (!list_empty(&ieee->crypt_deinit_list) && !ieee->crypt_quiesced) {
73 printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
74 "deletion list\n", ieee->dev->name);
75 ieee->crypt_deinit_timer.expires = jiffies + HZ;
76 add_timer(&ieee->crypt_deinit_timer);
77 }
78 spin_unlock_irqrestore(&ieee->lock, flags);
79}
80
81void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
82 struct ieee80211_crypt_data **crypt)
83{
84 struct ieee80211_crypt_data *tmp;
85 unsigned long flags;
86
87 if (*crypt == NULL)
88 return;
89
90 tmp = *crypt;
91 *crypt = NULL;
92
93 /* must not run ops->deinit() while there may be pending encrypt or
94 * decrypt operations. Use a list of delayed deinits to avoid needing
95 * locking. */
96
97 spin_lock_irqsave(&ieee->lock, flags);
98 if (!ieee->crypt_quiesced) {
99 list_add(&tmp->list, &ieee->crypt_deinit_list);
100 if (!timer_pending(&ieee->crypt_deinit_timer)) {
101 ieee->crypt_deinit_timer.expires = jiffies + HZ;
102 add_timer(&ieee->crypt_deinit_timer);
103 }
104 }
105 spin_unlock_irqrestore(&ieee->lock, flags);
106}
107
108int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
109{
110 unsigned long flags;
111 struct ieee80211_crypto_alg *alg;
112
113 alg = kzalloc(sizeof(*alg), GFP_KERNEL);
114 if (alg == NULL)
115 return -ENOMEM;
116
117 alg->ops = ops;
118
119 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
120 list_add(&alg->list, &ieee80211_crypto_algs);
121 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
122
123 printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
124 ops->name);
125
126 return 0;
127}
128
129int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
130{
131 struct ieee80211_crypto_alg *alg;
132 unsigned long flags;
133
134 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
135 list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
136 if (alg->ops == ops)
137 goto found;
138 }
139 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
140 return -EINVAL;
141
142 found:
143 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
144 "'%s'\n", ops->name);
145 list_del(&alg->list);
146 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
147 kfree(alg);
148 return 0;
149}
150
151struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
152{
153 struct ieee80211_crypto_alg *alg;
154 unsigned long flags;
155
156 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
157 list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
158 if (strcmp(alg->ops->name, name) == 0)
159 goto found;
160 }
161 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
162 return NULL;
163
164 found:
165 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
166 return alg->ops;
167}
168
169static void *ieee80211_crypt_null_init(int keyidx)
170{
171 return (void *)1;
172}
173
174static void ieee80211_crypt_null_deinit(void *priv)
175{
176}
177
178static struct ieee80211_crypto_ops ieee80211_crypt_null = {
179 .name = "NULL",
180 .init = ieee80211_crypt_null_init,
181 .deinit = ieee80211_crypt_null_deinit,
182 .owner = THIS_MODULE,
183};
184
185static int __init ieee80211_crypto_init(void)
186{
187 return ieee80211_register_crypto_ops(&ieee80211_crypt_null);
188}
189
190static void __exit ieee80211_crypto_deinit(void)
191{
192 ieee80211_unregister_crypto_ops(&ieee80211_crypt_null);
193 BUG_ON(!list_empty(&ieee80211_crypto_algs));
194}
195
196EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
197EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
198EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
199EXPORT_SYMBOL(ieee80211_crypt_quiescing);
200
201EXPORT_SYMBOL(ieee80211_register_crypto_ops);
202EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
203EXPORT_SYMBOL(ieee80211_get_crypto_ops);
204
205module_init(ieee80211_crypto_init);
206module_exit(ieee80211_crypto_deinit);