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
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
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
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>
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>
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)
70 kmalloc(MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
72 if (!ieee->networks) {
73 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
78 memset(ieee->networks, 0,
79 MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
84 void ieee80211_network_reset(struct ieee80211_network *network)
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)
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)
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 static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
123 if ((new_mtu < 68) || (new_mtu > IEEE80211_DATA_LEN))
129 struct net_device *alloc_ieee80211(int sizeof_priv)
131 struct ieee80211_device *ieee;
132 struct net_device *dev;
135 IEEE80211_DEBUG_INFO("Initializing...\n");
137 dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
139 IEEE80211_ERROR("Unable to network device.\n");
142 ieee = netdev_priv(dev);
143 dev->hard_start_xmit = ieee80211_xmit;
144 dev->change_mtu = ieee80211_change_mtu;
148 err = ieee80211_networks_allocate(ieee);
150 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", err);
153 ieee80211_networks_initialize(ieee);
155 /* Default fragmentation threshold is maximum payload size */
156 ieee->fts = DEFAULT_FTS;
157 ieee->rts = DEFAULT_FTS;
158 ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
161 /* Default to enabling full open WEP with host based encrypt/decrypt */
162 ieee->host_encrypt = 1;
163 ieee->host_decrypt = 1;
164 ieee->host_mc_decrypt = 1;
166 /* Host fragementation in Open mode. Default is enabled.
167 * Note: host fragmentation is always enabled if host encryption
168 * is enabled. For cards can do hardware encryption, they must do
169 * hardware fragmentation as well. So we don't need a variable
170 * like host_enc_frag. */
171 ieee->host_open_frag = 1;
172 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
174 INIT_LIST_HEAD(&ieee->crypt_deinit_list);
175 init_timer(&ieee->crypt_deinit_timer);
176 ieee->crypt_deinit_timer.data = (unsigned long)ieee;
177 ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
178 ieee->crypt_quiesced = 0;
180 spin_lock_init(&ieee->lock);
182 ieee->wpa_enabled = 0;
183 ieee->drop_unencrypted = 0;
184 ieee->privacy_invoked = 0;
194 void free_ieee80211(struct net_device *dev)
196 struct ieee80211_device *ieee = netdev_priv(dev);
200 ieee80211_crypt_quiescing(ieee);
201 del_timer_sync(&ieee->crypt_deinit_timer);
202 ieee80211_crypt_deinit_entries(ieee, 1);
204 for (i = 0; i < WEP_KEYS; i++) {
205 struct ieee80211_crypt_data *crypt = ieee->crypt[i];
208 crypt->ops->deinit(crypt->priv);
209 module_put(crypt->ops->owner);
212 ieee->crypt[i] = NULL;
216 ieee80211_networks_free(ieee);
220 #ifdef CONFIG_IEEE80211_DEBUG
222 static int debug = 0;
223 u32 ieee80211_debug_level = 0;
224 static struct proc_dir_entry *ieee80211_proc = NULL;
226 static int show_debug_level(char *page, char **start, off_t offset,
227 int count, int *eof, void *data)
229 return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
232 static int store_debug_level(struct file *file, const char __user * buffer,
233 unsigned long count, void *data)
235 char buf[] = "0x00000000\n";
236 unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
239 if (copy_from_user(buf, buffer, len))
242 if (sscanf(buf, "%li", &val) != 1)
243 printk(KERN_INFO DRV_NAME
244 ": %s is not in hex or decimal form.\n", buf);
246 ieee80211_debug_level = val;
248 return strnlen(buf, len);
250 #endif /* CONFIG_IEEE80211_DEBUG */
252 static int __init ieee80211_init(void)
254 #ifdef CONFIG_IEEE80211_DEBUG
255 struct proc_dir_entry *e;
257 ieee80211_debug_level = debug;
258 ieee80211_proc = proc_mkdir(DRV_NAME, proc_net);
259 if (ieee80211_proc == NULL) {
260 IEEE80211_ERROR("Unable to create " DRV_NAME
261 " proc directory\n");
264 e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
267 remove_proc_entry(DRV_NAME, proc_net);
268 ieee80211_proc = NULL;
271 e->read_proc = show_debug_level;
272 e->write_proc = store_debug_level;
274 #endif /* CONFIG_IEEE80211_DEBUG */
276 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
277 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
282 static void __exit ieee80211_exit(void)
284 #ifdef CONFIG_IEEE80211_DEBUG
285 if (ieee80211_proc) {
286 remove_proc_entry("debug_level", ieee80211_proc);
287 remove_proc_entry(DRV_NAME, proc_net);
288 ieee80211_proc = NULL;
290 #endif /* CONFIG_IEEE80211_DEBUG */
293 #ifdef CONFIG_IEEE80211_DEBUG
294 #include <linux/moduleparam.h>
295 module_param(debug, int, 0444);
296 MODULE_PARM_DESC(debug, "debug output mask");
297 #endif /* CONFIG_IEEE80211_DEBUG */
299 module_exit(ieee80211_exit);
300 module_init(ieee80211_init);
302 const char *escape_essid(const char *essid, u8 essid_len)
304 static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
305 const char *s = essid;
308 if (ieee80211_is_empty_essid(essid, essid_len)) {
309 memcpy(escaped, "<hidden>", sizeof("<hidden>"));
313 essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
314 while (essid_len--) {
327 EXPORT_SYMBOL(alloc_ieee80211);
328 EXPORT_SYMBOL(free_ieee80211);
329 EXPORT_SYMBOL(escape_essid);