Staging: add rtl8187se driver
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / rtl8187se / ieee80211 / ieee80211_module.c
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/config.h>
35 #include <linux/errno.h>
36 #include <linux/if_arp.h>
37 #include <linux/in6.h>
38 #include <linux/in.h>
39 #include <linux/ip.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>
53 #include <net/arp.h>
54 #include <net/net_namespace.h>
55
56 #include "ieee80211.h"
57
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");
61
62 #define DRV_NAME "ieee80211"
63
64 static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
65 {
66 if (ieee->networks)
67 return 0;
68
69 ieee->networks = kmalloc(
70 MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
71 GFP_KERNEL);
72 if (!ieee->networks) {
73 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
74 ieee->dev->name);
75 return -ENOMEM;
76 }
77
78 memset(ieee->networks, 0,
79 MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
80
81 return 0;
82 }
83
84 static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
85 {
86 if (!ieee->networks)
87 return;
88 kfree(ieee->networks);
89 ieee->networks = NULL;
90 }
91
92 static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
93 {
94 int i;
95
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);
100 }
101
102
103 struct net_device *alloc_ieee80211(int sizeof_priv)
104 {
105 struct ieee80211_device *ieee;
106 struct net_device *dev;
107 int i,err;
108
109 IEEE80211_DEBUG_INFO("Initializing...\n");
110
111 dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
112 if (!dev) {
113 IEEE80211_ERROR("Unable to network device.\n");
114 goto failed;
115 }
116 ieee = netdev_priv(dev);
117 dev->hard_start_xmit = ieee80211_xmit;
118
119 ieee->dev = dev;
120
121 err = ieee80211_networks_allocate(ieee);
122 if (err) {
123 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
124 err);
125 goto failed;
126 }
127 ieee80211_networks_initialize(ieee);
128
129 /* Default fragmentation threshold is maximum payload size */
130 ieee->fts = DEFAULT_FTS;
131 ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
132 ieee->open_wep = 1;
133
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 */
138
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;
143
144 spin_lock_init(&ieee->lock);
145 spin_lock_init(&ieee->wpax_suitlist_lock);
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
155 ieee80211_softmac_init(ieee);
156
157 for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
158 INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
159
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;
164 }
165 //These function were added to load crypte module autoly
166 ieee80211_tkip_null();
167 ieee80211_wep_null();
168 ieee80211_ccmp_null();
169 return dev;
170
171 failed:
172 if (dev)
173 free_netdev(dev);
174 return NULL;
175 }
176
177
178 void free_ieee80211(struct net_device *dev)
179 {
180 struct ieee80211_device *ieee = netdev_priv(dev);
181
182 int i;
183 struct list_head *p, *q;
184
185
186 ieee80211_softmac_free(ieee);
187 del_timer_sync(&ieee->crypt_deinit_timer);
188 ieee80211_crypt_deinit_entries(ieee, 1);
189
190 for (i = 0; i < WEP_KEYS; i++) {
191 struct ieee80211_crypt_data *crypt = ieee->crypt[i];
192 if (crypt) {
193 if (crypt->ops) {
194 crypt->ops->deinit(crypt->priv);
195 module_put(crypt->ops->owner);
196 }
197 kfree(crypt);
198 ieee->crypt[i] = NULL;
199 }
200 }
201
202 ieee80211_networks_free(ieee);
203
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));
207 list_del(p);
208 }
209 }
210
211
212 free_netdev(dev);
213 }
214
215 //#ifdef CONFIG_IEEE80211_DEBUG
216 #if 0
217
218 static int debug = 0;
219 u32 ieee80211_debug_level = 0;
220 struct proc_dir_entry *ieee80211_proc = NULL;
221
222 static int show_debug_level(char *page, char **start, off_t offset,
223 int count, int *eof, void *data)
224 {
225 return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
226 }
227
228 static int store_debug_level(struct file *file, const char *buffer,
229 unsigned long count, void *data)
230 {
231 char buf[] = "0x00000000";
232 unsigned long len = min(sizeof(buf) - 1, (u32)count);
233 char *p = (char *)buf;
234 unsigned long val;
235
236 if (copy_from_user(buf, buffer, len))
237 return count;
238 buf[len] = 0;
239 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
240 p++;
241 if (p[0] == 'x' || p[0] == 'X')
242 p++;
243 val = simple_strtoul(p, &p, 16);
244 } else
245 val = simple_strtoul(p, &p, 10);
246 if (p == buf)
247 printk(KERN_INFO DRV_NAME
248 ": %s is not in hex or decimal form.\n", buf);
249 else
250 ieee80211_debug_level = val;
251
252 return strnlen(buf, count);
253 }
254
255 static int __init ieee80211_init(void)
256 {
257 struct proc_dir_entry *e;
258
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");
264 return -EIO;
265 }
266 e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
267 ieee80211_proc);
268 if (!e) {
269 remove_proc_entry(DRV_NAME, proc_net);
270 ieee80211_proc = NULL;
271 return -EIO;
272 }
273 e->read_proc = show_debug_level;
274 e->write_proc = store_debug_level;
275 e->data = NULL;
276
277 return 0;
278 }
279
280 static void __exit ieee80211_exit(void)
281 {
282 if (ieee80211_proc) {
283 remove_proc_entry("debug_level", ieee80211_proc);
284 remove_proc_entry(DRV_NAME, proc_net);
285 ieee80211_proc = NULL;
286 }
287 }
288
289 #include <linux/moduleparam.h>
290 module_param(debug, int, 0444);
291 MODULE_PARM_DESC(debug, "debug output mask");
292
293
294 module_exit(ieee80211_exit);
295 module_init(ieee80211_init);
296 #endif
297
298 #if 0
299 EXPORT_SYMBOL(alloc_ieee80211);
300 EXPORT_SYMBOL(free_ieee80211);
301 #endif