~ubuntu-branches/ubuntu/precise/linux-ti-omap/precise

« back to all changes in this revision

Viewing changes to ubuntu/rtl8192se/rtllib/rtllib_crypt.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bader, Amit Kucheria
  • Date: 2010-03-23 18:05:12 UTC
  • Revision ID: james.westby@ubuntu.com-20100323180512-iavj906ocnphdubp
Tags: 2.6.33-500.3
[ Amit Kucheria ]

* [Config] Fix the debug package name to end in -dbgsym
* SAUCE: Add the ubuntu/ drivers to omap
* SAUCE: Re-export the symbols for aufs
* [Config] Enable AUFS and COMPCACHE

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Host AP crypto routines
 
3
 *
 
4
 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.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/version.h>
 
15
#include <linux/module.h>
 
16
#include <linux/init.h>
 
17
#include <linux/slab.h>
 
18
#include <asm/string.h>
 
19
#include <asm/errno.h>
 
20
 
 
21
#include "rtllib.h"
 
22
 
 
23
#ifndef BUILT_IN_RTLLIB
 
24
MODULE_AUTHOR("Jouni Malinen");
 
25
MODULE_DESCRIPTION("HostAP crypto");
 
26
MODULE_LICENSE("GPL");
 
27
#endif
 
28
 
 
29
struct rtllib_crypto_alg {
 
30
        struct list_head list;
 
31
        struct rtllib_crypto_ops *ops;
 
32
};
 
33
 
 
34
 
 
35
struct rtllib_crypto {
 
36
        struct list_head algs;
 
37
        spinlock_t lock;
 
38
};
 
39
 
 
40
static struct rtllib_crypto *hcrypt;
 
41
 
 
42
void rtllib_crypt_deinit_entries(struct rtllib_device *ieee,
 
43
                                           int force)
 
44
{
 
45
        struct list_head *ptr, *n;
 
46
        struct rtllib_crypt_data *entry;
 
47
 
 
48
        for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
 
49
             ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
 
50
                entry = list_entry(ptr, struct rtllib_crypt_data, list);
 
51
 
 
52
                if (atomic_read(&entry->refcnt) != 0 && !force)
 
53
                        continue;
 
54
 
 
55
                list_del(ptr);
 
56
 
 
57
                if (entry->ops) {
 
58
                        entry->ops->deinit(entry->priv);
 
59
#ifndef BUILT_IN_RTLLIB
 
60
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)         
 
61
                        module_put(entry->ops->owner);
 
62
#else
 
63
                        __MOD_DEC_USE_COUNT(entry->ops->owner); 
 
64
#endif                  
 
65
#endif
 
66
                }
 
67
                kfree(entry);
 
68
        }
 
69
}
 
70
 
 
71
void rtllib_crypt_deinit_handler(unsigned long data)
 
72
{
 
73
        struct rtllib_device *ieee = (struct rtllib_device *)data;
 
74
        unsigned long flags;
 
75
 
 
76
        spin_lock_irqsave(&ieee->lock, flags);
 
77
        rtllib_crypt_deinit_entries(ieee, 0);
 
78
        if (!list_empty(&ieee->crypt_deinit_list)) {
 
79
                printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
 
80
                       "deletion list\n", ieee->dev->name);
 
81
                ieee->crypt_deinit_timer.expires = jiffies + HZ;
 
82
                add_timer(&ieee->crypt_deinit_timer);
 
83
        }
 
84
        spin_unlock_irqrestore(&ieee->lock, flags);
 
85
 
 
86
}
 
87
 
 
88
void rtllib_crypt_delayed_deinit(struct rtllib_device *ieee,
 
89
                                    struct rtllib_crypt_data **crypt)
 
90
{
 
91
        struct rtllib_crypt_data *tmp;
 
92
        unsigned long flags;
 
93
 
 
94
        if (*crypt == NULL)
 
95
                return;
 
96
 
 
97
        tmp = *crypt;
 
98
        *crypt = NULL;
 
99
 
 
100
        /* must not run ops->deinit() while there may be pending encrypt or
 
101
         * decrypt operations. Use a list of delayed deinits to avoid needing
 
102
         * locking. */
 
103
 
 
104
        spin_lock_irqsave(&ieee->lock, flags);
 
105
        list_add(&tmp->list, &ieee->crypt_deinit_list);
 
106
        if (!timer_pending(&ieee->crypt_deinit_timer)) {
 
107
                ieee->crypt_deinit_timer.expires = jiffies + HZ;
 
108
                add_timer(&ieee->crypt_deinit_timer);
 
109
        }
 
110
        spin_unlock_irqrestore(&ieee->lock, flags);
 
111
}
 
112
 
 
113
int rtllib_register_crypto_ops(struct rtllib_crypto_ops *ops)
 
114
{
 
115
        unsigned long flags;
 
116
        struct rtllib_crypto_alg *alg;
 
117
 
 
118
        if (hcrypt == NULL)
 
119
                return -1;
 
120
 
 
121
        alg = kmalloc(sizeof(*alg), GFP_KERNEL);
 
122
        if (alg == NULL)
 
123
                return -ENOMEM;
 
124
 
 
125
        memset(alg, 0, sizeof(*alg));
 
126
        alg->ops = ops;
 
127
 
 
128
        spin_lock_irqsave(&hcrypt->lock, flags);
 
129
        list_add(&alg->list, &hcrypt->algs);
 
130
        spin_unlock_irqrestore(&hcrypt->lock, flags);
 
131
 
 
132
        printk(KERN_DEBUG "rtllib_crypt: registered algorithm '%s'\n",
 
133
               ops->name);
 
134
 
 
135
        return 0;
 
136
}
 
137
 
 
138
int rtllib_unregister_crypto_ops(struct rtllib_crypto_ops *ops)
 
139
{
 
140
        unsigned long flags;
 
141
        struct list_head *ptr;
 
142
        struct rtllib_crypto_alg *del_alg = NULL;
 
143
 
 
144
        if (hcrypt == NULL)
 
145
                return -1;
 
146
 
 
147
        spin_lock_irqsave(&hcrypt->lock, flags);
 
148
        for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
 
149
                struct rtllib_crypto_alg *alg =
 
150
                        (struct rtllib_crypto_alg *) ptr;
 
151
                if (alg->ops == ops) {
 
152
                        list_del(&alg->list);
 
153
                        del_alg = alg;
 
154
                        break;
 
155
                }
 
156
        }
 
157
        spin_unlock_irqrestore(&hcrypt->lock, flags);
 
158
 
 
159
        if (del_alg) {
 
160
                printk(KERN_DEBUG "rtllib_crypt: unregistered algorithm "
 
161
                       "'%s'\n", ops->name);
 
162
                kfree(del_alg);
 
163
        }
 
164
 
 
165
        return del_alg ? 0 : -1;
 
166
}
 
167
 
 
168
 
 
169
struct rtllib_crypto_ops * rtllib_get_crypto_ops(const char *name)
 
170
{
 
171
        unsigned long flags;
 
172
        struct list_head *ptr;
 
173
        struct rtllib_crypto_alg *found_alg = NULL;
 
174
 
 
175
        if (hcrypt == NULL)
 
176
                return NULL;
 
177
 
 
178
        spin_lock_irqsave(&hcrypt->lock, flags);
 
179
        for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
 
180
                struct rtllib_crypto_alg *alg =
 
181
                        (struct rtllib_crypto_alg *) ptr;
 
182
                if (strcmp(alg->ops->name, name) == 0) {
 
183
                        found_alg = alg;
 
184
                        break;
 
185
                }
 
186
        }
 
187
        spin_unlock_irqrestore(&hcrypt->lock, flags);
 
188
 
 
189
        if (found_alg)
 
190
                return found_alg->ops;
 
191
        else
 
192
                return NULL;
 
193
}
 
194
 
 
195
 
 
196
static void * rtllib_crypt_null_init(int keyidx) { return (void *) 1; }
 
197
static void rtllib_crypt_null_deinit(void *priv) {}
 
198
 
 
199
static struct rtllib_crypto_ops rtllib_crypt_null = {
 
200
        .name                   = "NULL",
 
201
        .init                   = rtllib_crypt_null_init,
 
202
        .deinit                 = rtllib_crypt_null_deinit,
 
203
        .encrypt_mpdu           = NULL,
 
204
        .decrypt_mpdu           = NULL,
 
205
        .encrypt_msdu           = NULL,
 
206
        .decrypt_msdu           = NULL,
 
207
        .set_key                = NULL,
 
208
        .get_key                = NULL,
 
209
        .extra_prefix_len       = 0,
 
210
        .extra_postfix_len      = 0,
 
211
        .owner                  = THIS_MODULE,
 
212
};
 
213
 
 
214
 
 
215
int __init rtllib_crypto_init(void)
 
216
{
 
217
        int ret = -ENOMEM;
 
218
 
 
219
        hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
 
220
        if (!hcrypt)
 
221
                goto out;
 
222
 
 
223
        memset(hcrypt, 0, sizeof(*hcrypt));
 
224
        INIT_LIST_HEAD(&hcrypt->algs);
 
225
        spin_lock_init(&hcrypt->lock);
 
226
 
 
227
        ret = rtllib_register_crypto_ops(&rtllib_crypt_null);
 
228
        if (ret < 0) {
 
229
                kfree(hcrypt);
 
230
                hcrypt = NULL;
 
231
        }
 
232
out:
 
233
        return ret;
 
234
}
 
235
 
 
236
 
 
237
void __exit rtllib_crypto_deinit(void)
 
238
{
 
239
        struct list_head *ptr, *n;
 
240
 
 
241
        if (hcrypt == NULL)
 
242
                return;
 
243
 
 
244
        for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
 
245
             ptr = n, n = ptr->next) {
 
246
                struct rtllib_crypto_alg *alg =
 
247
                        (struct rtllib_crypto_alg *) ptr;
 
248
                list_del(ptr);
 
249
                printk(KERN_DEBUG "rtllib_crypt: unregistered algorithm "
 
250
                       "'%s' (deinit)\n", alg->ops->name);
 
251
                kfree(alg);
 
252
        }
 
253
 
 
254
        kfree(hcrypt);
 
255
}
 
256
 
 
257
#ifndef BUILT_IN_RTLLIB
 
258
EXPORT_SYMBOL_RSL(rtllib_crypt_deinit_entries);
 
259
EXPORT_SYMBOL_RSL(rtllib_crypt_deinit_handler);
 
260
EXPORT_SYMBOL_RSL(rtllib_crypt_delayed_deinit);
 
261
 
 
262
EXPORT_SYMBOL_RSL(rtllib_register_crypto_ops);
 
263
EXPORT_SYMBOL_RSL(rtllib_unregister_crypto_ops);
 
264
EXPORT_SYMBOL_RSL(rtllib_get_crypto_ops);
 
265
 
 
266
module_init(rtllib_crypto_init);
 
267
module_exit(rtllib_crypto_deinit);
 
268
#endif