• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/staging/rtl8192e/ieee80211/
1/*******************************************************************************
2
3  Copyright(c) 2004 Intel Corporation. All rights reserved.
4
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>
10
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.
14
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.
19
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.
23
24  The full GNU General Public License is included in this distribution in the
25  file called LICENSE.
26
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
30
31*******************************************************************************/
32
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/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/version.h>
49#include <linux/wireless.h>
50#include <linux/etherdevice.h>
51#include <asm/uaccess.h>
52#include <net/arp.h>
53
54#include "ieee80211.h"
55
56MODULE_DESCRIPTION("802.11 data/management/control stack");
57MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
58MODULE_LICENSE("GPL");
59
60#define DRV_NAME "ieee80211"
61
62static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
63{
64	if (ieee->networks)
65		return 0;
66
67	ieee->networks = kcalloc(
68		MAX_NETWORK_COUNT, sizeof(struct ieee80211_network),
69		GFP_KERNEL);
70	if (!ieee->networks) {
71		printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
72		       ieee->dev->name);
73		return -ENOMEM;
74	}
75
76	return 0;
77}
78
79static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
80{
81	if (!ieee->networks)
82		return;
83	kfree(ieee->networks);
84	ieee->networks = NULL;
85}
86
87static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
88{
89	int i;
90
91	INIT_LIST_HEAD(&ieee->network_free_list);
92	INIT_LIST_HEAD(&ieee->network_list);
93	for (i = 0; i < MAX_NETWORK_COUNT; i++)
94		list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
95}
96
97
98struct net_device *alloc_ieee80211(int sizeof_priv)
99{
100	struct ieee80211_device *ieee;
101	struct net_device *dev;
102	int i,err;
103
104	IEEE80211_DEBUG_INFO("Initializing...\n");
105
106	dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
107	if (!dev) {
108		IEEE80211_ERROR("Unable to network device.\n");
109		goto failed;
110	}
111
112	ieee = netdev_priv(dev);
113
114	memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv);
115	ieee->dev = dev;
116
117	err = ieee80211_networks_allocate(ieee);
118	if (err) {
119		IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
120				err);
121		goto failed;
122	}
123	ieee80211_networks_initialize(ieee);
124
125
126	/* Default fragmentation threshold is maximum payload size */
127	ieee->fts = DEFAULT_FTS;
128	ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
129	ieee->open_wep = 1;
130
131	/* Default to enabling full open WEP with host based encrypt/decrypt */
132	ieee->host_encrypt = 1;
133	ieee->host_decrypt = 1;
134	ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
135
136	INIT_LIST_HEAD(&ieee->crypt_deinit_list);
137	init_timer(&ieee->crypt_deinit_timer);
138	ieee->crypt_deinit_timer.data = (unsigned long)ieee;
139	ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
140
141	spin_lock_init(&ieee->lock);
142	spin_lock_init(&ieee->wpax_suitlist_lock);
143	spin_lock_init(&ieee->bw_spinlock);
144	spin_lock_init(&ieee->reorder_spinlock);
145	//added by WB
146	atomic_set(&(ieee->atm_chnlop), 0);
147	atomic_set(&(ieee->atm_swbw), 0);
148
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;
155	ieee->raw_tx = 0;
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.
158
159	ieee80211_softmac_init(ieee);
160
161	ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
162	if (ieee->pHTInfo == NULL)
163	{
164		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
165		return NULL;
166	}
167	HTUpdateDefaultSetting(ieee);
168	HTInitializeHTInfo(ieee); //may move to other place.
169	TSInitialize(ieee);
170	for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
171		INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
172
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;
177	}
178
179//These function were added to load crypte module autoly
180	ieee80211_tkip_null();
181	ieee80211_wep_null();
182	ieee80211_ccmp_null();
183
184	return dev;
185
186 failed:
187	if (dev)
188		free_netdev(dev);
189	return NULL;
190}
191
192
193void free_ieee80211(struct net_device *dev)
194{
195	struct ieee80211_device *ieee = netdev_priv(dev);
196	int i;
197	if (ieee->pHTInfo != NULL)
198	{
199		kfree(ieee->pHTInfo);
200		ieee->pHTInfo = NULL;
201	}
202	RemoveAllTS(ieee);
203	ieee80211_softmac_free(ieee);
204	del_timer_sync(&ieee->crypt_deinit_timer);
205	ieee80211_crypt_deinit_entries(ieee, 1);
206
207	for (i = 0; i < WEP_KEYS; i++) {
208		struct ieee80211_crypt_data *crypt = ieee->crypt[i];
209		if (crypt) {
210			if (crypt->ops)
211				crypt->ops->deinit(crypt->priv);
212			kfree(crypt);
213			ieee->crypt[i] = NULL;
214		}
215	}
216
217	ieee80211_networks_free(ieee);
218	free_netdev(dev);
219}
220
221#ifdef CONFIG_IEEE80211_DEBUG
222
223u32 ieee80211_debug_level = 0;
224static int debug = \
225	//		    IEEE80211_DL_INFO	|
226	//		    IEEE80211_DL_WX	|
227	//		    IEEE80211_DL_SCAN	|
228	//		    IEEE80211_DL_STATE	|
229	//		    IEEE80211_DL_MGMT	|
230	//		    IEEE80211_DL_FRAG	|
231	//		    IEEE80211_DL_EAP	|
232	//		    IEEE80211_DL_DROP	|
233	//		    IEEE80211_DL_TX	|
234	//		    IEEE80211_DL_RX	|
235			    //IEEE80211_DL_QOS    |
236	//		    IEEE80211_DL_HT 	|
237	//		    IEEE80211_DL_TS	|
238//			    IEEE80211_DL_BA 	|
239	//		    IEEE80211_DL_REORDER|
240//			    IEEE80211_DL_TRACE  |
241			    //IEEE80211_DL_DATA	|
242			    IEEE80211_DL_ERR	  //awayls open this flags to show error out
243			    ;
244struct proc_dir_entry *ieee80211_proc = NULL;
245
246static int show_debug_level(char *page, char **start, off_t offset,
247			    int count, int *eof, void *data)
248{
249	return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
250}
251
252static int store_debug_level(struct file *file, const char *buffer,
253			     unsigned long count, void *data)
254{
255	char buf[] = "0x00000000";
256	unsigned long len = min(sizeof(buf) - 1, (u32)count);
257	char *p = (char *)buf;
258	unsigned long val;
259
260	if (copy_from_user(buf, buffer, len))
261		return count;
262	buf[len] = 0;
263	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
264		p++;
265		if (p[0] == 'x' || p[0] == 'X')
266			p++;
267		val = simple_strtoul(p, &p, 16);
268	} else
269		val = simple_strtoul(p, &p, 10);
270	if (p == buf)
271		printk(KERN_INFO DRV_NAME
272		       ": %s is not in hex or decimal form.\n", buf);
273	else
274		ieee80211_debug_level = val;
275
276	return strnlen(buf, count);
277}
278
279extern int ieee80211_crypto_init(void);
280extern void ieee80211_crypto_deinit(void);
281extern int ieee80211_crypto_tkip_init(void);
282extern void ieee80211_crypto_tkip_exit(void);
283extern int ieee80211_crypto_ccmp_init(void);
284extern void ieee80211_crypto_ccmp_exit(void);
285extern int ieee80211_crypto_wep_init(void);
286extern void ieee80211_crypto_wep_exit(void);
287
288int __init ieee80211_rtl_init(void)
289{
290	struct proc_dir_entry *e;
291	int retval;
292
293	retval = ieee80211_crypto_init();
294	if (retval)
295		return retval;
296	retval = ieee80211_crypto_tkip_init();
297	if (retval) {
298		ieee80211_crypto_deinit();
299		return retval;
300	}
301	retval = ieee80211_crypto_ccmp_init();
302	if (retval) {
303		ieee80211_crypto_tkip_exit();
304		ieee80211_crypto_deinit();
305		return retval;
306	}
307	retval = ieee80211_crypto_wep_init();
308	if (retval) {
309		ieee80211_crypto_ccmp_exit();
310		ieee80211_crypto_tkip_exit();
311		ieee80211_crypto_deinit();
312		return retval;
313	}
314
315	ieee80211_debug_level = debug;
316	ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
317	if (ieee80211_proc == NULL) {
318		IEEE80211_ERROR("Unable to create " DRV_NAME
319				" proc directory\n");
320		return -EIO;
321	}
322	e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
323			      ieee80211_proc);
324	if (!e) {
325		remove_proc_entry(DRV_NAME, init_net.proc_net);
326		ieee80211_proc = NULL;
327		return -EIO;
328	}
329	e->read_proc = show_debug_level;
330	e->write_proc = store_debug_level;
331	e->data = NULL;
332
333	return 0;
334}
335
336void __exit ieee80211_rtl_exit(void)
337{
338	if (ieee80211_proc) {
339		remove_proc_entry("debug_level", ieee80211_proc);
340		remove_proc_entry(DRV_NAME, init_net.proc_net);
341		ieee80211_proc = NULL;
342	}
343	ieee80211_crypto_wep_exit();
344	ieee80211_crypto_ccmp_exit();
345	ieee80211_crypto_tkip_exit();
346	ieee80211_crypto_deinit();
347}
348
349#include <linux/moduleparam.h>
350module_param(debug, int, 0444);
351MODULE_PARM_DESC(debug, "debug output mask");
352
353
354#endif
355