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/config.h>
35 #include <linux/errno.h>
36 #include <linux/if_arp.h>
37 #include <linux/in6.h>
40 #include <linux/kernel.h>
41 #include <linux/module.h>
42 #include <linux/netdevice.h>
43 #include <linux/proc_fs.h>
44 #include <linux/skbuff.h>
45 #include <linux/slab.h>
46 #include <linux/tcp.h>
47 #include <linux/types.h>
48 #include <linux/wireless.h>
49 #include <linux/etherdevice.h>
50 #include <asm/uaccess.h>
53 #include <net/ieee80211.h>
55 #define DRV_DESCRIPTION "802.11 data/management/control stack"
56 #define DRV_NAME "ieee80211"
57 #define DRV_VERSION IEEE80211_VERSION
58 #define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
60 MODULE_VERSION(DRV_VERSION);
61 MODULE_DESCRIPTION(DRV_DESCRIPTION);
62 MODULE_AUTHOR(DRV_COPYRIGHT);
63 MODULE_LICENSE("GPL");
65 static int ieee80211_networks_allocate(struct ieee80211_device *ieee)
71 kmalloc(MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
73 if (!ieee->networks) {
74 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
79 memset(ieee->networks, 0,
80 MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
85 void ieee80211_network_reset(struct ieee80211_network *network)
90 if (network->ibss_dfs) {
91 kfree(network->ibss_dfs);
92 network->ibss_dfs = NULL;
96 static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
103 for (i = 0; i < MAX_NETWORK_COUNT; i++)
104 if (ieee->networks[i].ibss_dfs)
105 kfree(ieee->networks[i].ibss_dfs);
107 kfree(ieee->networks);
108 ieee->networks = NULL;
111 static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
115 INIT_LIST_HEAD(&ieee->network_free_list);
116 INIT_LIST_HEAD(&ieee->network_list);
117 for (i = 0; i < MAX_NETWORK_COUNT; i++)
118 list_add_tail(&ieee->networks[i].list,
119 &ieee->network_free_list);
122 struct net_device *alloc_ieee80211(int sizeof_priv)
124 struct ieee80211_device *ieee;
125 struct net_device *dev;
128 IEEE80211_DEBUG_INFO("Initializing...\n");
130 dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
132 IEEE80211_ERROR("Unable to network device.\n");
135 ieee = netdev_priv(dev);
136 dev->hard_start_xmit = ieee80211_xmit;
140 err = ieee80211_networks_allocate(ieee);
142 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", err);
145 ieee80211_networks_initialize(ieee);
147 /* Default fragmentation threshold is maximum payload size */
148 ieee->fts = DEFAULT_FTS;
149 ieee->rts = DEFAULT_FTS;
150 ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
153 /* Default to enabling full open WEP with host based encrypt/decrypt */
154 ieee->host_encrypt = 1;
155 ieee->host_decrypt = 1;
156 ieee->host_mc_decrypt = 1;
158 /* Host fragementation in Open mode. Default is enabled.
159 * Note: host fragmentation is always enabled if host encryption
160 * is enabled. For cards can do hardware encryption, they must do
161 * hardware fragmentation as well. So we don't need a variable
162 * like host_enc_frag. */
163 ieee->host_open_frag = 1;
164 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
166 INIT_LIST_HEAD(&ieee->crypt_deinit_list);
167 init_timer(&ieee->crypt_deinit_timer);
168 ieee->crypt_deinit_timer.data = (unsigned long)ieee;
169 ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
170 ieee->crypt_quiesced = 0;
172 spin_lock_init(&ieee->lock);
174 ieee->wpa_enabled = 0;
175 ieee->drop_unencrypted = 0;
176 ieee->privacy_invoked = 0;
186 void free_ieee80211(struct net_device *dev)
188 struct ieee80211_device *ieee = netdev_priv(dev);
192 ieee80211_crypt_quiescing(ieee);
193 del_timer_sync(&ieee->crypt_deinit_timer);
194 ieee80211_crypt_deinit_entries(ieee, 1);
196 for (i = 0; i < WEP_KEYS; i++) {
197 struct ieee80211_crypt_data *crypt = ieee->crypt[i];
200 crypt->ops->deinit(crypt->priv);
201 module_put(crypt->ops->owner);
204 ieee->crypt[i] = NULL;
208 ieee80211_networks_free(ieee);
212 #ifdef CONFIG_IEEE80211_DEBUG
214 static int debug = 0;
215 u32 ieee80211_debug_level = 0;
216 static struct proc_dir_entry *ieee80211_proc = NULL;
218 static int show_debug_level(char *page, char **start, off_t offset,
219 int count, int *eof, void *data)
221 return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
224 static int store_debug_level(struct file *file, const char __user * buffer,
225 unsigned long count, void *data)
227 char buf[] = "0x00000000\n";
228 unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
231 if (copy_from_user(buf, buffer, len))
234 if (sscanf(buf, "%li", &val) != 1)
235 printk(KERN_INFO DRV_NAME
236 ": %s is not in hex or decimal form.\n", buf);
238 ieee80211_debug_level = val;
240 return strnlen(buf, len);
242 #endif /* CONFIG_IEEE80211_DEBUG */
244 static int __init ieee80211_init(void)
246 #ifdef CONFIG_IEEE80211_DEBUG
247 struct proc_dir_entry *e;
249 ieee80211_debug_level = debug;
250 ieee80211_proc = proc_mkdir(DRV_NAME, proc_net);
251 if (ieee80211_proc == NULL) {
252 IEEE80211_ERROR("Unable to create " DRV_NAME
253 " proc directory\n");
256 e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
259 remove_proc_entry(DRV_NAME, proc_net);
260 ieee80211_proc = NULL;
263 e->read_proc = show_debug_level;
264 e->write_proc = store_debug_level;
266 #endif /* CONFIG_IEEE80211_DEBUG */
268 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
269 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
274 static void __exit ieee80211_exit(void)
276 #ifdef CONFIG_IEEE80211_DEBUG
277 if (ieee80211_proc) {
278 remove_proc_entry("debug_level", ieee80211_proc);
279 remove_proc_entry(DRV_NAME, proc_net);
280 ieee80211_proc = NULL;
282 #endif /* CONFIG_IEEE80211_DEBUG */
285 #ifdef CONFIG_IEEE80211_DEBUG
286 #include <linux/moduleparam.h>
287 module_param(debug, int, 0444);
288 MODULE_PARM_DESC(debug, "debug output mask");
289 #endif /* CONFIG_IEEE80211_DEBUG */
291 module_exit(ieee80211_exit);
292 module_init(ieee80211_init);
294 const char *escape_essid(const char *essid, u8 essid_len)
296 static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
297 const char *s = essid;
300 if (ieee80211_is_empty_essid(essid, essid_len)) {
301 memcpy(escaped, "<hidden>", sizeof("<hidden>"));
305 essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
306 while (essid_len--) {
319 EXPORT_SYMBOL(alloc_ieee80211);
320 EXPORT_SYMBOL(free_ieee80211);
321 EXPORT_SYMBOL(escape_essid);