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/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/pci.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 "ieee80211.h"
55 MODULE_DESCRIPTION("802.11 data/management/control stack");
56 MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
57 MODULE_LICENSE("GPL");
59 #define DRV_NAME "ieee80211"
61 static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
66 ieee->networks = kcalloc(
67 MAX_NETWORK_COUNT, sizeof(struct ieee80211_network),
69 if (!ieee->networks) {
70 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
78 static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
82 kfree(ieee->networks);
83 ieee->networks = NULL;
86 static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
90 INIT_LIST_HEAD(&ieee->network_free_list);
91 INIT_LIST_HEAD(&ieee->network_list);
92 for (i = 0; i < MAX_NETWORK_COUNT; i++)
93 list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
97 struct net_device *alloc_ieee80211(int sizeof_priv)
99 struct ieee80211_device *ieee;
100 struct net_device *dev;
103 IEEE80211_DEBUG_INFO("Initializing...\n");
105 dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
107 IEEE80211_ERROR("Unable to network device.\n");
111 ieee = netdev_priv(dev);
113 memset(ieee, 0, sizeof(struct ieee80211_device) + sizeof_priv);
116 err = ieee80211_networks_allocate(ieee);
118 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
122 ieee80211_networks_initialize(ieee);
125 /* Default fragmentation threshold is maximum payload size */
126 ieee->fts = DEFAULT_FTS;
127 ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
130 /* Default to enabling full open WEP with host based encrypt/decrypt */
131 ieee->host_encrypt = 1;
132 ieee->host_decrypt = 1;
133 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
135 INIT_LIST_HEAD(&ieee->crypt_deinit_list);
136 init_timer(&ieee->crypt_deinit_timer);
137 ieee->crypt_deinit_timer.data = (unsigned long)ieee;
138 ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
140 spin_lock_init(&ieee->lock);
141 spin_lock_init(&ieee->wpax_suitlist_lock);
142 spin_lock_init(&ieee->bw_spinlock);
143 spin_lock_init(&ieee->reorder_spinlock);
146 atomic_set(&(ieee->atm_chnlop), 0);
147 atomic_set(&(ieee->atm_swbw), 0);
149 ieee->wpax_type_set = 0;
150 ieee->wpa_enabled = 0;
151 ieee->tkip_countermeasures = 0;
152 ieee->drop_unencrypted = 0;
153 ieee->privacy_invoked = 0;
154 ieee->ieee802_1x = 1;
156 /* ieee->hwsec_support = 1; default support hw security: use module_param instead */
157 ieee->hwsec_active = 0; /* disable hwsec, switch it on when necessary */
159 ieee80211_softmac_init(ieee);
161 ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
162 if (ieee->pHTInfo == NULL)
164 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
167 HTUpdateDefaultSetting(ieee);
168 HTInitializeHTInfo(ieee); /* may move to other place */
170 for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
171 INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
173 for (i = 0; i < 17; i++) {
174 ieee->last_rxseq_num[i] = -1;
175 ieee->last_rxfrag_num[i] = -1;
176 ieee->last_packet_time[i] = 0;
179 /* Functions to load crypt module automatically */
180 ieee80211_tkip_null();
181 ieee80211_wep_null();
182 ieee80211_ccmp_null();
193 void free_ieee80211(struct net_device *dev)
195 struct ieee80211_device *ieee = netdev_priv(dev);
197 kfree(ieee->pHTInfo);
198 ieee->pHTInfo = NULL;
200 ieee80211_softmac_free(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);
210 ieee->crypt[i] = NULL;
214 ieee80211_networks_free(ieee);
218 #ifdef CONFIG_IEEE80211_DEBUG
220 u32 ieee80211_debug_level = 0;
222 /* IEEE80211_DL_INFO | */
223 /* IEEE80211_DL_WX | */
224 /* IEEE80211_DL_SCAN | */
225 /* IEEE80211_DL_STATE | */
226 /* IEEE80211_DL_MGMT | */
227 /* IEEE80211_DL_FRAG | */
228 /* IEEE80211_DL_EAP | */
229 /* IEEE80211_DL_DROP | */
230 /* IEEE80211_DL_TX | */
231 /* IEEE80211_DL_RX | */
232 /* IEEE80211_DL_QOS | */
233 /* IEEE80211_DL_HT | */
234 /* IEEE80211_DL_TS | */
235 /* IEEE80211_DL_BA | */
236 /* IEEE80211_DL_REORDER | */
237 /* IEEE80211_DL_TRACE | */
238 /* IEEE80211_DL_DATA | */
239 IEEE80211_DL_ERR /* always open this flag to show error out */
241 struct proc_dir_entry *ieee80211_proc = NULL;
243 static int show_debug_level(char *page, char **start, off_t offset,
244 int count, int *eof, void *data)
246 return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
249 static int store_debug_level(struct file *file, const char *buffer,
250 unsigned long count, void *data)
252 char buf[] = "0x00000000";
253 unsigned long len = min(sizeof(buf) - 1, (u32)count);
254 char *p = (char *)buf;
257 if (copy_from_user(buf, buffer, len))
260 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
262 if (p[0] == 'x' || p[0] == 'X')
264 val = simple_strtoul(p, &p, 16);
266 val = simple_strtoul(p, &p, 10);
268 printk(KERN_INFO DRV_NAME
269 ": %s is not in hex or decimal form.\n", buf);
271 ieee80211_debug_level = val;
273 return strnlen(buf, count);
276 extern int ieee80211_crypto_init(void);
277 extern void ieee80211_crypto_deinit(void);
278 extern int ieee80211_crypto_tkip_init(void);
279 extern void ieee80211_crypto_tkip_exit(void);
280 extern int ieee80211_crypto_ccmp_init(void);
281 extern void ieee80211_crypto_ccmp_exit(void);
282 extern int ieee80211_crypto_wep_init(void);
283 extern void ieee80211_crypto_wep_exit(void);
285 int __init ieee80211_rtl_init(void)
287 struct proc_dir_entry *e;
290 retval = ieee80211_crypto_init();
293 retval = ieee80211_crypto_tkip_init();
295 ieee80211_crypto_deinit();
298 retval = ieee80211_crypto_ccmp_init();
300 ieee80211_crypto_tkip_exit();
301 ieee80211_crypto_deinit();
304 retval = ieee80211_crypto_wep_init();
306 ieee80211_crypto_ccmp_exit();
307 ieee80211_crypto_tkip_exit();
308 ieee80211_crypto_deinit();
312 ieee80211_debug_level = debug;
313 ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
314 if (ieee80211_proc == NULL) {
315 IEEE80211_ERROR("Unable to create " DRV_NAME
316 " proc directory\n");
319 e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
322 remove_proc_entry(DRV_NAME, init_net.proc_net);
323 ieee80211_proc = NULL;
326 e->read_proc = show_debug_level;
327 e->write_proc = store_debug_level;
333 void __exit ieee80211_rtl_exit(void)
335 if (ieee80211_proc) {
336 remove_proc_entry("debug_level", ieee80211_proc);
337 remove_proc_entry(DRV_NAME, init_net.proc_net);
338 ieee80211_proc = NULL;
340 ieee80211_crypto_wep_exit();
341 ieee80211_crypto_ccmp_exit();
342 ieee80211_crypto_tkip_exit();
343 ieee80211_crypto_deinit();
346 #include <linux/moduleparam.h>
347 module_param(debug, int, 0444);
348 MODULE_PARM_DESC(debug, "debug output mask");