[PATCH] uml build fix
[deliverable/linux.git] / net / ieee80211 / ieee80211_module.c
CommitLineData
b453872c
JG
1/*******************************************************************************
2
ebeaddcc 3 Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
b453872c
JG
4
5 Portions of this file are based on the WEP enablement code provided by the
6 Host AP project hostap-drivers v0.1.3
7 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
8 <jkmaline@cc.hut.fi>
9 Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
10
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as
13 published by the Free Software Foundation.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 more details.
19
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 59
22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 The full GNU General Public License is included in this distribution in the
25 file called LICENSE.
26
27 Contact Information:
28 James P. Ketrenos <ipw2100-admin@linux.intel.com>
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31*******************************************************************************/
32
33#include <linux/compiler.h>
b453872c
JG
34#include <linux/errno.h>
35#include <linux/if_arp.h>
36#include <linux/in6.h>
37#include <linux/in.h>
38#include <linux/ip.h>
39#include <linux/kernel.h>
40#include <linux/module.h>
41#include <linux/netdevice.h>
b453872c
JG
42#include <linux/proc_fs.h>
43#include <linux/skbuff.h>
44#include <linux/slab.h>
45#include <linux/tcp.h>
46#include <linux/types.h>
b453872c
JG
47#include <linux/wireless.h>
48#include <linux/etherdevice.h>
49#include <asm/uaccess.h>
50#include <net/arp.h>
51
52#include <net/ieee80211.h>
53
31696160
JK
54#define DRV_DESCRIPTION "802.11 data/management/control stack"
55#define DRV_NAME "ieee80211"
56#define DRV_VERSION IEEE80211_VERSION
57#define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
58
59MODULE_VERSION(DRV_VERSION);
60MODULE_DESCRIPTION(DRV_DESCRIPTION);
61MODULE_AUTHOR(DRV_COPYRIGHT);
b453872c
JG
62MODULE_LICENSE("GPL");
63
858119e1 64static int ieee80211_networks_allocate(struct ieee80211_device *ieee)
b453872c
JG
65{
66 if (ieee->networks)
67 return 0;
68
0edd5b44
JG
69 ieee->networks =
70 kmalloc(MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
71 GFP_KERNEL);
b453872c
JG
72 if (!ieee->networks) {
73 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
74 ieee->dev->name);
75 return -ENOMEM;
76 }
77
78 memset(ieee->networks, 0,
79 MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
80
81 return 0;
82}
83
15f38598
ZY
84void ieee80211_network_reset(struct ieee80211_network *network)
85{
86 if (!network)
87 return;
88
89 if (network->ibss_dfs) {
90 kfree(network->ibss_dfs);
91 network->ibss_dfs = NULL;
92 }
93}
94
b453872c
JG
95static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
96{
15f38598
ZY
97 int i;
98
b453872c
JG
99 if (!ieee->networks)
100 return;
15f38598
ZY
101
102 for (i = 0; i < MAX_NETWORK_COUNT; i++)
103 if (ieee->networks[i].ibss_dfs)
104 kfree(ieee->networks[i].ibss_dfs);
105
b453872c
JG
106 kfree(ieee->networks);
107 ieee->networks = NULL;
108}
109
858119e1 110static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
b453872c
JG
111{
112 int i;
113
114 INIT_LIST_HEAD(&ieee->network_free_list);
115 INIT_LIST_HEAD(&ieee->network_list);
116 for (i = 0; i < MAX_NETWORK_COUNT; i++)
0edd5b44
JG
117 list_add_tail(&ieee->networks[i].list,
118 &ieee->network_free_list);
b453872c
JG
119}
120
b453872c
JG
121struct net_device *alloc_ieee80211(int sizeof_priv)
122{
123 struct ieee80211_device *ieee;
124 struct net_device *dev;
125 int err;
126
127 IEEE80211_DEBUG_INFO("Initializing...\n");
128
129 dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
130 if (!dev) {
131 IEEE80211_ERROR("Unable to network device.\n");
132 goto failed;
133 }
134 ieee = netdev_priv(dev);
135 dev->hard_start_xmit = ieee80211_xmit;
136
137 ieee->dev = dev;
138
139 err = ieee80211_networks_allocate(ieee);
140 if (err) {
0edd5b44 141 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", err);
b453872c
JG
142 goto failed;
143 }
144 ieee80211_networks_initialize(ieee);
145
146 /* Default fragmentation threshold is maximum payload size */
147 ieee->fts = DEFAULT_FTS;
3cdd00c5 148 ieee->rts = DEFAULT_FTS;
b453872c
JG
149 ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
150 ieee->open_wep = 1;
151
152 /* Default to enabling full open WEP with host based encrypt/decrypt */
153 ieee->host_encrypt = 1;
154 ieee->host_decrypt = 1;
ccd0fda3
JK
155 ieee->host_mc_decrypt = 1;
156
1264fc04
JK
157 /* Host fragementation in Open mode. Default is enabled.
158 * Note: host fragmentation is always enabled if host encryption
159 * is enabled. For cards can do hardware encryption, they must do
160 * hardware fragmentation as well. So we don't need a variable
161 * like host_enc_frag. */
162 ieee->host_open_frag = 1;
0edd5b44 163 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
b453872c
JG
164
165 INIT_LIST_HEAD(&ieee->crypt_deinit_list);
166 init_timer(&ieee->crypt_deinit_timer);
167 ieee->crypt_deinit_timer.data = (unsigned long)ieee;
168 ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
0ad0c3c6 169 ieee->crypt_quiesced = 0;
b453872c
JG
170
171 spin_lock_init(&ieee->lock);
172
0edd5b44 173 ieee->wpa_enabled = 0;
0edd5b44
JG
174 ieee->drop_unencrypted = 0;
175 ieee->privacy_invoked = 0;
b453872c
JG
176
177 return dev;
178
0edd5b44 179 failed:
b453872c
JG
180 if (dev)
181 free_netdev(dev);
182 return NULL;
183}
184
b453872c
JG
185void free_ieee80211(struct net_device *dev)
186{
187 struct ieee80211_device *ieee = netdev_priv(dev);
188
189 int i;
190
0ad0c3c6 191 ieee80211_crypt_quiescing(ieee);
b453872c
JG
192 del_timer_sync(&ieee->crypt_deinit_timer);
193 ieee80211_crypt_deinit_entries(ieee, 1);
194
195 for (i = 0; i < WEP_KEYS; i++) {
196 struct ieee80211_crypt_data *crypt = ieee->crypt[i];
197 if (crypt) {
198 if (crypt->ops) {
199 crypt->ops->deinit(crypt->priv);
200 module_put(crypt->ops->owner);
201 }
202 kfree(crypt);
203 ieee->crypt[i] = NULL;
204 }
205 }
206
207 ieee80211_networks_free(ieee);
208 free_netdev(dev);
209}
210
211#ifdef CONFIG_IEEE80211_DEBUG
212
213static int debug = 0;
214u32 ieee80211_debug_level = 0;
b7cffb02 215static struct proc_dir_entry *ieee80211_proc = NULL;
b453872c
JG
216
217static int show_debug_level(char *page, char **start, off_t offset,
218 int count, int *eof, void *data)
219{
220 return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
221}
222
0edd5b44 223static int store_debug_level(struct file *file, const char __user * buffer,
b453872c
JG
224 unsigned long count, void *data)
225{
262d8e46
JK
226 char buf[] = "0x00000000\n";
227 unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
b453872c
JG
228 unsigned long val;
229
262d8e46 230 if (copy_from_user(buf, buffer, len))
b453872c 231 return count;
262d8e46
JK
232 buf[len] = 0;
233 if (sscanf(buf, "%li", &val) != 1)
b453872c
JG
234 printk(KERN_INFO DRV_NAME
235 ": %s is not in hex or decimal form.\n", buf);
236 else
237 ieee80211_debug_level = val;
238
262d8e46 239 return strnlen(buf, len);
b453872c 240}
31696160 241#endif /* CONFIG_IEEE80211_DEBUG */
b453872c
JG
242
243static int __init ieee80211_init(void)
244{
31696160 245#ifdef CONFIG_IEEE80211_DEBUG
b453872c
JG
246 struct proc_dir_entry *e;
247
248 ieee80211_debug_level = debug;
66600221 249 ieee80211_proc = proc_mkdir(DRV_NAME, proc_net);
b453872c
JG
250 if (ieee80211_proc == NULL) {
251 IEEE80211_ERROR("Unable to create " DRV_NAME
252 " proc directory\n");
253 return -EIO;
254 }
255 e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
256 ieee80211_proc);
257 if (!e) {
258 remove_proc_entry(DRV_NAME, proc_net);
259 ieee80211_proc = NULL;
260 return -EIO;
261 }
262 e->read_proc = show_debug_level;
263 e->write_proc = store_debug_level;
264 e->data = NULL;
31696160
JK
265#endif /* CONFIG_IEEE80211_DEBUG */
266
267 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
268 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
b453872c
JG
269
270 return 0;
271}
272
273static void __exit ieee80211_exit(void)
274{
31696160 275#ifdef CONFIG_IEEE80211_DEBUG
b453872c
JG
276 if (ieee80211_proc) {
277 remove_proc_entry("debug_level", ieee80211_proc);
278 remove_proc_entry(DRV_NAME, proc_net);
279 ieee80211_proc = NULL;
280 }
31696160 281#endif /* CONFIG_IEEE80211_DEBUG */
b453872c
JG
282}
283
31696160 284#ifdef CONFIG_IEEE80211_DEBUG
b453872c
JG
285#include <linux/moduleparam.h>
286module_param(debug, int, 0444);
287MODULE_PARM_DESC(debug, "debug output mask");
31696160 288#endif /* CONFIG_IEEE80211_DEBUG */
b453872c 289
b453872c
JG
290module_exit(ieee80211_exit);
291module_init(ieee80211_init);
b453872c 292
0edd5b44
JG
293const char *escape_essid(const char *essid, u8 essid_len)
294{
e88187ee
JB
295 static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
296 const char *s = essid;
297 char *d = escaped;
298
299 if (ieee80211_is_empty_essid(essid, essid_len)) {
300 memcpy(escaped, "<hidden>", sizeof("<hidden>"));
301 return escaped;
302 }
303
0edd5b44 304 essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
e88187ee
JB
305 while (essid_len--) {
306 if (*s == '\0') {
307 *d++ = '\\';
308 *d++ = '0';
309 s++;
310 } else {
311 *d++ = *s++;
312 }
313 }
314 *d = '\0';
315 return escaped;
316}
317
b453872c
JG
318EXPORT_SYMBOL(alloc_ieee80211);
319EXPORT_SYMBOL(free_ieee80211);
e88187ee 320EXPORT_SYMBOL(escape_essid);
This page took 0.239005 seconds and 5 git commands to generate.