wl1251: experimental PS hacks
[pandora-kernel.git] / drivers / staging / rtl8192e / rtllib_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/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 <linux/uaccess.h>
52 #include <net/arp.h>
53
54 #include "rtllib.h"
55
56
57 #define DRV_NAME "rtllib_92e"
58
59 void _setup_timer(struct timer_list *ptimer, void *fun, unsigned long data)
60 {
61         ptimer->function = fun;
62         ptimer->data = data;
63         init_timer(ptimer);
64 }
65
66 static inline int rtllib_networks_allocate(struct rtllib_device *ieee)
67 {
68         if (ieee->networks)
69                 return 0;
70
71         ieee->networks = kzalloc(
72                 MAX_NETWORK_COUNT * sizeof(struct rtllib_network),
73                 GFP_KERNEL);
74         if (!ieee->networks) {
75                 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
76                        ieee->dev->name);
77                 return -ENOMEM;
78         }
79
80         return 0;
81 }
82
83 static inline void rtllib_networks_free(struct rtllib_device *ieee)
84 {
85         if (!ieee->networks)
86                 return;
87         kfree(ieee->networks);
88         ieee->networks = NULL;
89 }
90
91 static inline void rtllib_networks_initialize(struct rtllib_device *ieee)
92 {
93         int i;
94
95         INIT_LIST_HEAD(&ieee->network_free_list);
96         INIT_LIST_HEAD(&ieee->network_list);
97         for (i = 0; i < MAX_NETWORK_COUNT; i++)
98                 list_add_tail(&ieee->networks[i].list,
99                               &ieee->network_free_list);
100 }
101
102 struct net_device *alloc_rtllib(int sizeof_priv)
103 {
104         struct rtllib_device *ieee = NULL;
105         struct net_device *dev;
106         int i, err;
107
108         RTLLIB_DEBUG_INFO("Initializing...\n");
109
110         dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv);
111         if (!dev) {
112                 RTLLIB_ERROR("Unable to network device.\n");
113                 goto failed;
114         }
115         ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
116         memset(ieee, 0, sizeof(struct rtllib_device)+sizeof_priv);
117         ieee->dev = dev;
118
119         err = rtllib_networks_allocate(ieee);
120         if (err) {
121                 RTLLIB_ERROR("Unable to allocate beacon storage: %d\n",
122                                 err);
123                 goto failed;
124         }
125         rtllib_networks_initialize(ieee);
126
127
128         /* Default fragmentation threshold is maximum payload size */
129         ieee->fts = DEFAULT_FTS;
130         ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
131         ieee->open_wep = 1;
132
133         /* Default to enabling full open WEP with host based encrypt/decrypt */
134         ieee->host_encrypt = 1;
135         ieee->host_decrypt = 1;
136         ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
137
138         INIT_LIST_HEAD(&ieee->crypt_deinit_list);
139         _setup_timer(&ieee->crypt_deinit_timer,
140                     rtllib_crypt_deinit_handler,
141                     (unsigned long) ieee);
142         ieee->rtllib_ap_sec_type = rtllib_ap_sec_type;
143
144         spin_lock_init(&ieee->lock);
145         spin_lock_init(&ieee->wpax_suitlist_lock);
146         spin_lock_init(&ieee->bw_spinlock);
147         spin_lock_init(&ieee->reorder_spinlock);
148         atomic_set(&(ieee->atm_chnlop), 0);
149         atomic_set(&(ieee->atm_swbw), 0);
150
151         ieee->bHalfNMode = false;
152         ieee->wpa_enabled = 0;
153         ieee->tkip_countermeasures = 0;
154         ieee->drop_unencrypted = 0;
155         ieee->privacy_invoked = 0;
156         ieee->ieee802_1x = 1;
157         ieee->raw_tx = 0;
158         ieee->hwsec_active = 0;
159
160         memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
161         rtllib_softmac_init(ieee);
162
163         ieee->pHTInfo = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL);
164         if (ieee->pHTInfo == NULL) {
165                 RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc memory for HTInfo\n");
166                 return NULL;
167         }
168         HTUpdateDefaultSetting(ieee);
169         HTInitializeHTInfo(ieee);
170         TSInitialize(ieee);
171         for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
172                 INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
173
174         for (i = 0; i < 17; i++) {
175                 ieee->last_rxseq_num[i] = -1;
176                 ieee->last_rxfrag_num[i] = -1;
177                 ieee->last_packet_time[i] = 0;
178         }
179
180         rtllib_tkip_null();
181         rtllib_wep_null();
182         rtllib_ccmp_null();
183
184         return dev;
185
186  failed:
187         if (dev)
188                 free_netdev(dev);
189         return NULL;
190 }
191
192 void free_rtllib(struct net_device *dev)
193 {
194         struct rtllib_device *ieee = (struct rtllib_device *)
195                                       netdev_priv_rsl(dev);
196         int i;
197
198         kfree(ieee->pHTInfo);
199         ieee->pHTInfo = NULL;
200         rtllib_softmac_free(ieee);
201         del_timer_sync(&ieee->crypt_deinit_timer);
202         rtllib_crypt_deinit_entries(ieee, 1);
203
204         for (i = 0; i < WEP_KEYS; i++) {
205                 struct rtllib_crypt_data *crypt = ieee->crypt[i];
206                 if (crypt) {
207                         if (crypt->ops)
208                                 crypt->ops->deinit(crypt->priv);
209                         kfree(crypt);
210                         ieee->crypt[i] = NULL;
211                 }
212         }
213
214         rtllib_networks_free(ieee);
215         free_netdev(dev);
216 }
217
218 u32 rtllib_debug_level;
219 static int debug = \
220                             RTLLIB_DL_ERR
221                             ;
222 static struct proc_dir_entry *rtllib_proc;
223
224 static int show_debug_level(char *page, char **start, off_t offset,
225                             int count, int *eof, void *data)
226 {
227         return snprintf(page, count, "0x%08X\n", rtllib_debug_level);
228 }
229
230 static int store_debug_level(struct file *file, const char __user *buffer,
231                              unsigned long count, void *data)
232 {
233         char buf[] = "0x00000000";
234         unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
235         char *p = (char *)buf;
236         unsigned long val;
237
238         if (copy_from_user(buf, buffer, len))
239                 return count;
240         buf[len] = 0;
241         if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
242                 p++;
243                 if (p[0] == 'x' || p[0] == 'X')
244                         p++;
245                 val = simple_strtoul(p, &p, 16);
246         } else
247                 val = simple_strtoul(p, &p, 10);
248         if (p == buf)
249                 printk(KERN_INFO DRV_NAME
250                        ": %s is not in hex or decimal form.\n", buf);
251         else
252                 rtllib_debug_level = val;
253
254         return strnlen(buf, count);
255 }
256
257 int __init rtllib_init(void)
258 {
259         struct proc_dir_entry *e;
260
261         rtllib_debug_level = debug;
262         rtllib_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
263         if (rtllib_proc == NULL) {
264                 RTLLIB_ERROR("Unable to create " DRV_NAME
265                                 " proc directory\n");
266                 return -EIO;
267         }
268         e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
269                               rtllib_proc);
270         if (!e) {
271                 remove_proc_entry(DRV_NAME, init_net.proc_net);
272                 rtllib_proc = NULL;
273                 return -EIO;
274         }
275         e->read_proc = show_debug_level;
276         e->write_proc = store_debug_level;
277         e->data = NULL;
278
279         return 0;
280 }
281
282 void __exit rtllib_exit(void)
283 {
284         if (rtllib_proc) {
285                 remove_proc_entry("debug_level", rtllib_proc);
286                 remove_proc_entry(DRV_NAME, init_net.proc_net);
287                 rtllib_proc = NULL;
288         }
289 }