1 /*******************************************************************************
3 Copyright(c) 2004 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/pci.h>
44 #include <linux/proc_fs.h>
45 #include <linux/skbuff.h>
46 #include <linux/slab.h>
47 #include <linux/tcp.h>
48 #include <linux/types.h>
49 #include <linux/version.h>
50 #include <linux/wireless.h>
51 #include <linux/etherdevice.h>
52 #include <asm/uaccess.h>
54 #include <net/net_namespace.h>
56 #include "ieee80211.h"
58 MODULE_DESCRIPTION("802.11 data/management/control stack");
59 MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
60 MODULE_LICENSE("GPL");
62 #define DRV_NAME "ieee80211"
64 static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
69 ieee->networks = kmalloc(
70 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 static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
88 kfree(ieee->networks);
89 ieee->networks = NULL;
92 static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
96 INIT_LIST_HEAD(&ieee->network_free_list);
97 INIT_LIST_HEAD(&ieee->network_list);
98 for (i = 0; i < MAX_NETWORK_COUNT; i++)
99 list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
103 struct net_device *alloc_ieee80211(int sizeof_priv)
105 struct ieee80211_device *ieee;
106 struct net_device *dev;
109 IEEE80211_DEBUG_INFO("Initializing...\n");
111 dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
113 IEEE80211_ERROR("Unable to network device.\n");
116 ieee = netdev_priv(dev);
117 dev->hard_start_xmit = ieee80211_xmit;
121 err = ieee80211_networks_allocate(ieee);
123 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
127 ieee80211_networks_initialize(ieee);
129 /* Default fragmentation threshold is maximum payload size */
130 ieee->fts = DEFAULT_FTS;
131 ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
134 /* Default to enabling full open WEP with host based encrypt/decrypt */
135 ieee->host_encrypt = 1;
136 ieee->host_decrypt = 1;
137 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
139 INIT_LIST_HEAD(&ieee->crypt_deinit_list);
140 init_timer(&ieee->crypt_deinit_timer);
141 ieee->crypt_deinit_timer.data = (unsigned long)ieee;
142 ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
144 spin_lock_init(&ieee->lock);
145 spin_lock_init(&ieee->wpax_suitlist_lock);
147 ieee->wpax_type_set = 0;
148 ieee->wpa_enabled = 0;
149 ieee->tkip_countermeasures = 0;
150 ieee->drop_unencrypted = 0;
151 ieee->privacy_invoked = 0;
152 ieee->ieee802_1x = 1;
155 ieee80211_softmac_init(ieee);
157 for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
158 INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
160 for (i = 0; i < 17; i++) {
161 ieee->last_rxseq_num[i] = -1;
162 ieee->last_rxfrag_num[i] = -1;
163 ieee->last_packet_time[i] = 0;
165 //These function were added to load crypte module autoly
166 ieee80211_tkip_null();
167 ieee80211_wep_null();
168 ieee80211_ccmp_null();
178 void free_ieee80211(struct net_device *dev)
180 struct ieee80211_device *ieee = netdev_priv(dev);
183 struct list_head *p, *q;
186 ieee80211_softmac_free(ieee);
187 del_timer_sync(&ieee->crypt_deinit_timer);
188 ieee80211_crypt_deinit_entries(ieee, 1);
190 for (i = 0; i < WEP_KEYS; i++) {
191 struct ieee80211_crypt_data *crypt = ieee->crypt[i];
194 crypt->ops->deinit(crypt->priv);
195 module_put(crypt->ops->owner);
198 ieee->crypt[i] = NULL;
202 ieee80211_networks_free(ieee);
204 for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
205 list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
206 kfree(list_entry(p, struct ieee_ibss_seq, list));
215 //#ifdef CONFIG_IEEE80211_DEBUG
218 static int debug = 0;
219 u32 ieee80211_debug_level = 0;
220 struct proc_dir_entry *ieee80211_proc = NULL;
222 static int show_debug_level(char *page, char **start, off_t offset,
223 int count, int *eof, void *data)
225 return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
228 static int store_debug_level(struct file *file, const char *buffer,
229 unsigned long count, void *data)
231 char buf[] = "0x00000000";
232 unsigned long len = min(sizeof(buf) - 1, (u32)count);
233 char *p = (char *)buf;
236 if (copy_from_user(buf, buffer, len))
239 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
241 if (p[0] == 'x' || p[0] == 'X')
243 val = simple_strtoul(p, &p, 16);
245 val = simple_strtoul(p, &p, 10);
247 printk(KERN_INFO DRV_NAME
248 ": %s is not in hex or decimal form.\n", buf);
250 ieee80211_debug_level = val;
252 return strnlen(buf, count);
255 static int __init ieee80211_init(void)
257 struct proc_dir_entry *e;
259 ieee80211_debug_level = debug;
260 ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
261 if (ieee80211_proc == NULL) {
262 IEEE80211_ERROR("Unable to create " DRV_NAME
263 " proc directory\n");
266 e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
269 remove_proc_entry(DRV_NAME, proc_net);
270 ieee80211_proc = NULL;
273 e->read_proc = show_debug_level;
274 e->write_proc = store_debug_level;
280 static void __exit ieee80211_exit(void)
282 if (ieee80211_proc) {
283 remove_proc_entry("debug_level", ieee80211_proc);
284 remove_proc_entry(DRV_NAME, proc_net);
285 ieee80211_proc = NULL;
289 #include <linux/moduleparam.h>
290 module_param(debug, int, 0444);
291 MODULE_PARM_DESC(debug, "debug output mask");
294 module_exit(ieee80211_exit);
295 module_init(ieee80211_init);
299 EXPORT_SYMBOL(alloc_ieee80211);
300 EXPORT_SYMBOL(free_ieee80211);