• 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/rtl8192su/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	memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv);
114	ieee->dev = dev;
115
116	err = ieee80211_networks_allocate(ieee);
117	if (err) {
118		IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
119				err);
120		goto failed;
121	}
122	ieee80211_networks_initialize(ieee);
123
124
125	/* Default fragmentation threshold is maximum payload size */
126	ieee->fts = DEFAULT_FTS;
127	ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
128	ieee->open_wep = 1;
129
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 */
134
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;
139
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);
144	atomic_set(&(ieee->atm_chnlop), 0);
145	atomic_set(&(ieee->atm_swbw), 0);
146
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;
153	ieee->raw_tx = 0;
154	ieee->hwsec_active = 0; //disable hwsec, switch it on when necessary.
155
156	ieee80211_softmac_init(ieee);
157
158	ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
159	if (ieee->pHTInfo == NULL)
160	{
161		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
162		return NULL;
163	}
164	HTUpdateDefaultSetting(ieee);
165	HTInitializeHTInfo(ieee); //may move to other place.
166	TSInitialize(ieee);
167
168	for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
169		INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
170
171	for (i = 0; i < 17; i++) {
172	  ieee->last_rxseq_num[i] = -1;
173	  ieee->last_rxfrag_num[i] = -1;
174	  ieee->last_packet_time[i] = 0;
175	}
176
177//These function were added to load crypte module autoly
178	ieee80211_tkip_null();
179	ieee80211_wep_null();
180	ieee80211_ccmp_null();
181
182	return dev;
183
184 failed:
185	if (dev)
186		free_netdev(dev);
187
188	return NULL;
189}
190
191
192void free_ieee80211(struct net_device *dev)
193{
194	struct ieee80211_device *ieee = netdev_priv(dev);
195	int i;
196	if (ieee->pHTInfo != NULL)
197	{
198		kfree(ieee->pHTInfo);
199		ieee->pHTInfo = NULL;
200	}
201	RemoveAllTS(ieee);
202	ieee80211_softmac_free(ieee);
203	del_timer_sync(&ieee->crypt_deinit_timer);
204	ieee80211_crypt_deinit_entries(ieee, 1);
205
206	for (i = 0; i < WEP_KEYS; i++) {
207		struct ieee80211_crypt_data *crypt = ieee->crypt[i];
208		if (crypt) {
209			if (crypt->ops)
210				crypt->ops->deinit(crypt->priv);
211			kfree(crypt);
212			ieee->crypt[i] = NULL;
213		}
214	}
215
216	ieee80211_networks_free(ieee);
217	free_netdev(dev);
218}
219
220#ifdef CONFIG_IEEE80211_DEBUG
221
222u32 ieee80211_debug_level = 0;
223static int debug = \
224			    IEEE80211_DL_ERR	  //awayls open this flags to show error out
225			    ;
226struct proc_dir_entry *ieee80211_proc = NULL;
227
228static int show_debug_level(char *page, char **start, off_t offset,
229			    int count, int *eof, void *data)
230{
231	return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
232}
233
234static int store_debug_level(struct file *file, const char *buffer,
235			     unsigned long count, void *data)
236{
237	char buf[] = "0x00000000";
238	unsigned long len = min_t(unsigned long, sizeof(buf) - 1, count);
239	char *p = (char *)buf;
240	unsigned long val;
241
242	if (copy_from_user(buf, buffer, len))
243		return count;
244	buf[len] = 0;
245	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
246		p++;
247		if (p[0] == 'x' || p[0] == 'X')
248			p++;
249		val = simple_strtoul(p, &p, 16);
250	} else
251		val = simple_strtoul(p, &p, 10);
252	if (p == buf)
253		printk(KERN_INFO DRV_NAME
254		       ": %s is not in hex or decimal form.\n", buf);
255	else
256		ieee80211_debug_level = val;
257
258	return strnlen(buf, count);
259}
260
261int ieee80211_debug_init(void)
262{
263	struct proc_dir_entry *e;
264
265	ieee80211_debug_level = debug;
266
267	ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
268	if (ieee80211_proc == NULL) {
269		IEEE80211_ERROR("Unable to create " DRV_NAME
270				" proc directory\n");
271		return -EIO;
272	}
273	e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
274			      ieee80211_proc);
275	if (!e) {
276		remove_proc_entry(DRV_NAME, init_net.proc_net);
277		ieee80211_proc = NULL;
278		return -EIO;
279	}
280	e->read_proc = show_debug_level;
281	e->write_proc = store_debug_level;
282	e->data = NULL;
283
284	return 0;
285}
286
287void ieee80211_debug_exit(void)
288{
289	if (ieee80211_proc) {
290		remove_proc_entry("debug_level", ieee80211_proc);
291		remove_proc_entry(DRV_NAME, init_net.proc_net);
292		ieee80211_proc = NULL;
293	}
294}
295
296#include <linux/moduleparam.h>
297module_param(debug, int, 0444);
298MODULE_PARM_DESC(debug, "debug output mask");
299#endif
300