Blame view
net/wireless/lib80211.c
6.55 KB
7e272fcff wireless: consoli... |
1 2 3 4 5 |
/* * lib80211 -- common bits for IEEE802.11 drivers * * Copyright(c) 2008 John W. Linville <linville@tuxdriver.com> * |
274bfb8dc lib80211: absorb ... |
6 7 8 9 10 11 12 13 |
* Portions copied from old ieee80211 component, w/ original copyright * notices below: * * Host AP crypto routines * * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi> * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com> * |
7e272fcff wireless: consoli... |
14 |
*/ |
e9c0268f0 net/wireless: Use... |
15 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
7e272fcff wireless: consoli... |
16 |
#include <linux/module.h> |
2819f8ad6 wireless: escape_... |
17 |
#include <linux/ctype.h> |
7e272fcff wireless: consoli... |
18 |
#include <linux/ieee80211.h> |
274bfb8dc lib80211: absorb ... |
19 20 21 22 |
#include <linux/errno.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/string.h> |
7e272fcff wireless: consoli... |
23 24 25 26 27 28 29 30 31 32 |
#include <net/lib80211.h> #define DRV_NAME "lib80211" #define DRV_DESCRIPTION "common routines for IEEE802.11 drivers" MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_AUTHOR("John W. Linville <linville@tuxdriver.com>"); MODULE_LICENSE("GPL"); |
274bfb8dc lib80211: absorb ... |
33 34 35 36 37 38 39 |
struct lib80211_crypto_alg { struct list_head list; struct lib80211_crypto_ops *ops; }; static LIST_HEAD(lib80211_crypto_algs); static DEFINE_SPINLOCK(lib80211_crypto_lock); |
9d630c779 lib80211: remove ... |
40 41 42 43 |
static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force); static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info); static void lib80211_crypt_deinit_handler(unsigned long data); |
2ba4b32ec lib80211: consoli... |
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
int lib80211_crypt_info_init(struct lib80211_crypt_info *info, char *name, spinlock_t *lock) { memset(info, 0, sizeof(*info)); info->name = name; info->lock = lock; INIT_LIST_HEAD(&info->crypt_deinit_list); setup_timer(&info->crypt_deinit_timer, lib80211_crypt_deinit_handler, (unsigned long)info); return 0; } EXPORT_SYMBOL(lib80211_crypt_info_init); void lib80211_crypt_info_free(struct lib80211_crypt_info *info) { int i; lib80211_crypt_quiescing(info); del_timer_sync(&info->crypt_deinit_timer); lib80211_crypt_deinit_entries(info, 1); for (i = 0; i < NUM_WEP_KEYS; i++) { struct lib80211_crypt_data *crypt = info->crypt[i]; if (crypt) { if (crypt->ops) { crypt->ops->deinit(crypt->priv); module_put(crypt->ops->owner); } kfree(crypt); info->crypt[i] = NULL; } } } EXPORT_SYMBOL(lib80211_crypt_info_free); |
9d630c779 lib80211: remove ... |
81 82 |
static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force) |
7e272fcff wireless: consoli... |
83 |
{ |
274bfb8dc lib80211: absorb ... |
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
struct lib80211_crypt_data *entry, *next; unsigned long flags; spin_lock_irqsave(info->lock, flags); list_for_each_entry_safe(entry, next, &info->crypt_deinit_list, list) { if (atomic_read(&entry->refcnt) != 0 && !force) continue; list_del(&entry->list); if (entry->ops) { entry->ops->deinit(entry->priv); module_put(entry->ops->owner); } kfree(entry); } spin_unlock_irqrestore(info->lock, flags); } |
274bfb8dc lib80211: absorb ... |
102 103 |
/* After this, crypt_deinit_list won't accept new members */ |
9d630c779 lib80211: remove ... |
104 |
static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info) |
274bfb8dc lib80211: absorb ... |
105 106 107 108 109 110 111 |
{ unsigned long flags; spin_lock_irqsave(info->lock, flags); info->crypt_quiesced = 1; spin_unlock_irqrestore(info->lock, flags); } |
274bfb8dc lib80211: absorb ... |
112 |
|
9d630c779 lib80211: remove ... |
113 |
static void lib80211_crypt_deinit_handler(unsigned long data) |
274bfb8dc lib80211: absorb ... |
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
{ struct lib80211_crypt_info *info = (struct lib80211_crypt_info *)data; unsigned long flags; lib80211_crypt_deinit_entries(info, 0); spin_lock_irqsave(info->lock, flags); if (!list_empty(&info->crypt_deinit_list) && !info->crypt_quiesced) { printk(KERN_DEBUG "%s: entries remaining in delayed crypt " "deletion list ", info->name); info->crypt_deinit_timer.expires = jiffies + HZ; add_timer(&info->crypt_deinit_timer); } spin_unlock_irqrestore(info->lock, flags); } |
274bfb8dc lib80211: absorb ... |
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info, struct lib80211_crypt_data **crypt) { struct lib80211_crypt_data *tmp; unsigned long flags; if (*crypt == NULL) return; tmp = *crypt; *crypt = NULL; /* must not run ops->deinit() while there may be pending encrypt or * decrypt operations. Use a list of delayed deinits to avoid needing * locking. */ spin_lock_irqsave(info->lock, flags); if (!info->crypt_quiesced) { list_add(&tmp->list, &info->crypt_deinit_list); if (!timer_pending(&info->crypt_deinit_timer)) { info->crypt_deinit_timer.expires = jiffies + HZ; add_timer(&info->crypt_deinit_timer); } } spin_unlock_irqrestore(info->lock, flags); } EXPORT_SYMBOL(lib80211_crypt_delayed_deinit); int lib80211_register_crypto_ops(struct lib80211_crypto_ops *ops) { unsigned long flags; struct lib80211_crypto_alg *alg; alg = kzalloc(sizeof(*alg), GFP_KERNEL); if (alg == NULL) return -ENOMEM; alg->ops = ops; spin_lock_irqsave(&lib80211_crypto_lock, flags); list_add(&alg->list, &lib80211_crypto_algs); spin_unlock_irqrestore(&lib80211_crypto_lock, flags); printk(KERN_DEBUG "lib80211_crypt: registered algorithm '%s' ", ops->name); return 0; } EXPORT_SYMBOL(lib80211_register_crypto_ops); int lib80211_unregister_crypto_ops(struct lib80211_crypto_ops *ops) { struct lib80211_crypto_alg *alg; unsigned long flags; spin_lock_irqsave(&lib80211_crypto_lock, flags); list_for_each_entry(alg, &lib80211_crypto_algs, list) { if (alg->ops == ops) goto found; } spin_unlock_irqrestore(&lib80211_crypto_lock, flags); return -EINVAL; found: |
e9c0268f0 net/wireless: Use... |
196 197 198 |
printk(KERN_DEBUG "lib80211_crypt: unregistered algorithm '%s' ", ops->name); |
274bfb8dc lib80211: absorb ... |
199 200 201 |
list_del(&alg->list); spin_unlock_irqrestore(&lib80211_crypto_lock, flags); kfree(alg); |
7e272fcff wireless: consoli... |
202 203 |
return 0; } |
274bfb8dc lib80211: absorb ... |
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
EXPORT_SYMBOL(lib80211_unregister_crypto_ops); struct lib80211_crypto_ops *lib80211_get_crypto_ops(const char *name) { struct lib80211_crypto_alg *alg; unsigned long flags; spin_lock_irqsave(&lib80211_crypto_lock, flags); list_for_each_entry(alg, &lib80211_crypto_algs, list) { if (strcmp(alg->ops->name, name) == 0) goto found; } spin_unlock_irqrestore(&lib80211_crypto_lock, flags); return NULL; found: spin_unlock_irqrestore(&lib80211_crypto_lock, flags); return alg->ops; } EXPORT_SYMBOL(lib80211_get_crypto_ops); static void *lib80211_crypt_null_init(int keyidx) { return (void *)1; } static void lib80211_crypt_null_deinit(void *priv) { } static struct lib80211_crypto_ops lib80211_crypt_null = { .name = "NULL", .init = lib80211_crypt_null_init, .deinit = lib80211_crypt_null_deinit, .owner = THIS_MODULE, }; static int __init lib80211_init(void) { |
e9c0268f0 net/wireless: Use... |
243 244 |
pr_info(DRV_DESCRIPTION " "); |
274bfb8dc lib80211: absorb ... |
245 246 |
return lib80211_register_crypto_ops(&lib80211_crypt_null); } |
7e272fcff wireless: consoli... |
247 |
|
274bfb8dc lib80211: absorb ... |
248 |
static void __exit lib80211_exit(void) |
7e272fcff wireless: consoli... |
249 |
{ |
274bfb8dc lib80211: absorb ... |
250 251 |
lib80211_unregister_crypto_ops(&lib80211_crypt_null); BUG_ON(!list_empty(&lib80211_crypto_algs)); |
7e272fcff wireless: consoli... |
252 |
} |
274bfb8dc lib80211: absorb ... |
253 254 |
module_init(lib80211_init); module_exit(lib80211_exit); |