IB/mad: Add support for dual-sided RMPP transfers.
[linux-2.6/x86.git] / net / ieee80211 / ieee80211_module.c
blob13b1e5fff7e4741de39c232ba35931ef84129b92
1 /*******************************************************************************
3 Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
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>
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.
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.
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.
24 The full GNU General Public License is included in this distribution in the
25 file called LICENSE.
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
31 *******************************************************************************/
33 #include <linux/compiler.h>
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>
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>
47 #include <linux/wireless.h>
48 #include <linux/etherdevice.h>
49 #include <asm/uaccess.h>
50 #include <net/arp.h>
52 #include <net/ieee80211.h>
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>"
59 MODULE_VERSION(DRV_VERSION);
60 MODULE_DESCRIPTION(DRV_DESCRIPTION);
61 MODULE_AUTHOR(DRV_COPYRIGHT);
62 MODULE_LICENSE("GPL");
64 static int ieee80211_networks_allocate(struct ieee80211_device *ieee)
66 if (ieee->networks)
67 return 0;
69 ieee->networks =
70 kmalloc(MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
71 GFP_KERNEL);
72 if (!ieee->networks) {
73 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
74 ieee->dev->name);
75 return -ENOMEM;
78 memset(ieee->networks, 0,
79 MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
81 return 0;
84 void ieee80211_network_reset(struct ieee80211_network *network)
86 if (!network)
87 return;
89 if (network->ibss_dfs) {
90 kfree(network->ibss_dfs);
91 network->ibss_dfs = NULL;
95 static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
97 int i;
99 if (!ieee->networks)
100 return;
102 for (i = 0; i < MAX_NETWORK_COUNT; i++)
103 if (ieee->networks[i].ibss_dfs)
104 kfree(ieee->networks[i].ibss_dfs);
106 kfree(ieee->networks);
107 ieee->networks = NULL;
110 static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
112 int i;
114 INIT_LIST_HEAD(&ieee->network_free_list);
115 INIT_LIST_HEAD(&ieee->network_list);
116 for (i = 0; i < MAX_NETWORK_COUNT; i++)
117 list_add_tail(&ieee->networks[i].list,
118 &ieee->network_free_list);
121 struct net_device *alloc_ieee80211(int sizeof_priv)
123 struct ieee80211_device *ieee;
124 struct net_device *dev;
125 int err;
127 IEEE80211_DEBUG_INFO("Initializing...\n");
129 dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
130 if (!dev) {
131 IEEE80211_ERROR("Unable to network device.\n");
132 goto failed;
134 ieee = netdev_priv(dev);
135 dev->hard_start_xmit = ieee80211_xmit;
137 ieee->dev = dev;
139 err = ieee80211_networks_allocate(ieee);
140 if (err) {
141 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", err);
142 goto failed;
144 ieee80211_networks_initialize(ieee);
146 /* Default fragmentation threshold is maximum payload size */
147 ieee->fts = DEFAULT_FTS;
148 ieee->rts = DEFAULT_FTS;
149 ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
150 ieee->open_wep = 1;
152 /* Default to enabling full open WEP with host based encrypt/decrypt */
153 ieee->host_encrypt = 1;
154 ieee->host_decrypt = 1;
155 ieee->host_mc_decrypt = 1;
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;
163 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
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;
169 ieee->crypt_quiesced = 0;
171 spin_lock_init(&ieee->lock);
173 ieee->wpa_enabled = 0;
174 ieee->drop_unencrypted = 0;
175 ieee->privacy_invoked = 0;
177 return dev;
179 failed:
180 if (dev)
181 free_netdev(dev);
182 return NULL;
185 void free_ieee80211(struct net_device *dev)
187 struct ieee80211_device *ieee = netdev_priv(dev);
189 int i;
191 ieee80211_crypt_quiescing(ieee);
192 del_timer_sync(&ieee->crypt_deinit_timer);
193 ieee80211_crypt_deinit_entries(ieee, 1);
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);
202 kfree(crypt);
203 ieee->crypt[i] = NULL;
207 ieee80211_networks_free(ieee);
208 free_netdev(dev);
211 #ifdef CONFIG_IEEE80211_DEBUG
213 static int debug = 0;
214 u32 ieee80211_debug_level = 0;
215 static struct proc_dir_entry *ieee80211_proc = NULL;
217 static int show_debug_level(char *page, char **start, off_t offset,
218 int count, int *eof, void *data)
220 return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
223 static int store_debug_level(struct file *file, const char __user * buffer,
224 unsigned long count, void *data)
226 char buf[] = "0x00000000\n";
227 unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
228 unsigned long val;
230 if (copy_from_user(buf, buffer, len))
231 return count;
232 buf[len] = 0;
233 if (sscanf(buf, "%li", &val) != 1)
234 printk(KERN_INFO DRV_NAME
235 ": %s is not in hex or decimal form.\n", buf);
236 else
237 ieee80211_debug_level = val;
239 return strnlen(buf, len);
241 #endif /* CONFIG_IEEE80211_DEBUG */
243 static int __init ieee80211_init(void)
245 #ifdef CONFIG_IEEE80211_DEBUG
246 struct proc_dir_entry *e;
248 ieee80211_debug_level = debug;
249 ieee80211_proc = proc_mkdir(DRV_NAME, proc_net);
250 if (ieee80211_proc == NULL) {
251 IEEE80211_ERROR("Unable to create " DRV_NAME
252 " proc directory\n");
253 return -EIO;
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;
262 e->read_proc = show_debug_level;
263 e->write_proc = store_debug_level;
264 e->data = NULL;
265 #endif /* CONFIG_IEEE80211_DEBUG */
267 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
268 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
270 return 0;
273 static void __exit ieee80211_exit(void)
275 #ifdef CONFIG_IEEE80211_DEBUG
276 if (ieee80211_proc) {
277 remove_proc_entry("debug_level", ieee80211_proc);
278 remove_proc_entry(DRV_NAME, proc_net);
279 ieee80211_proc = NULL;
281 #endif /* CONFIG_IEEE80211_DEBUG */
284 #ifdef CONFIG_IEEE80211_DEBUG
285 #include <linux/moduleparam.h>
286 module_param(debug, int, 0444);
287 MODULE_PARM_DESC(debug, "debug output mask");
288 #endif /* CONFIG_IEEE80211_DEBUG */
290 module_exit(ieee80211_exit);
291 module_init(ieee80211_init);
293 const char *escape_essid(const char *essid, u8 essid_len)
295 static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
296 const char *s = essid;
297 char *d = escaped;
299 if (ieee80211_is_empty_essid(essid, essid_len)) {
300 memcpy(escaped, "<hidden>", sizeof("<hidden>"));
301 return escaped;
304 essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
305 while (essid_len--) {
306 if (*s == '\0') {
307 *d++ = '\\';
308 *d++ = '0';
309 s++;
310 } else {
311 *d++ = *s++;
314 *d = '\0';
315 return escaped;
318 EXPORT_SYMBOL(alloc_ieee80211);
319 EXPORT_SYMBOL(free_ieee80211);
320 EXPORT_SYMBOL(escape_essid);