Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
[linux-2.6-microblaze.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/wireless.h>
49 #include <linux/etherdevice.h>
50 #include <linux/uaccess.h>
51 #include <net/arp.h>
52
53 #include "rtllib.h"
54
55
56 u32 rt_global_debug_component = COMP_ERR;
57 EXPORT_SYMBOL(rt_global_debug_component);
58
59
60 void _setup_timer(struct timer_list *ptimer, void *fun, unsigned long data)
61 {
62         ptimer->function = fun;
63         ptimer->data = data;
64         init_timer(ptimer);
65 }
66
67 static inline int rtllib_networks_allocate(struct rtllib_device *ieee)
68 {
69         if (ieee->networks)
70                 return 0;
71
72         ieee->networks = kzalloc(
73                 MAX_NETWORK_COUNT * sizeof(struct rtllib_network),
74                 GFP_KERNEL);
75         if (!ieee->networks) {
76                 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
77                        ieee->dev->name);
78                 return -ENOMEM;
79         }
80
81         return 0;
82 }
83
84 static inline void rtllib_networks_free(struct rtllib_device *ieee)
85 {
86         if (!ieee->networks)
87                 return;
88         kfree(ieee->networks);
89         ieee->networks = NULL;
90 }
91
92 static inline void rtllib_networks_initialize(struct rtllib_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,
100                               &ieee->network_free_list);
101 }
102
103 struct net_device *alloc_rtllib(int sizeof_priv)
104 {
105         struct rtllib_device *ieee = NULL;
106         struct net_device *dev;
107         int i, err;
108
109         RTLLIB_DEBUG_INFO("Initializing...\n");
110
111         dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv);
112         if (!dev) {
113                 RTLLIB_ERROR("Unable to network device.\n");
114                 goto failed;
115         }
116         ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
117         memset(ieee, 0, sizeof(struct rtllib_device)+sizeof_priv);
118         ieee->dev = dev;
119
120         err = rtllib_networks_allocate(ieee);
121         if (err) {
122                 RTLLIB_ERROR("Unable to allocate beacon storage: %d\n",
123                                 err);
124                 goto failed;
125         }
126         rtllib_networks_initialize(ieee);
127
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         ieee->rtllib_ap_sec_type = rtllib_ap_sec_type;
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         atomic_set(&(ieee->atm_chnlop), 0);
146         atomic_set(&(ieee->atm_swbw), 0);
147
148         /* SAM FIXME */
149         lib80211_crypt_info_init(&ieee->crypt_info, "RTLLIB", &ieee->lock);
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         return dev;
181
182  failed:
183         if (dev)
184                 free_netdev(dev);
185         return NULL;
186 }
187 EXPORT_SYMBOL(alloc_rtllib);
188
189 void free_rtllib(struct net_device *dev)
190 {
191         struct rtllib_device *ieee = (struct rtllib_device *)
192                                       netdev_priv_rsl(dev);
193
194         kfree(ieee->pHTInfo);
195         ieee->pHTInfo = NULL;
196         rtllib_softmac_free(ieee);
197
198         lib80211_crypt_info_free(&ieee->crypt_info);
199
200         rtllib_networks_free(ieee);
201         free_netdev(dev);
202 }
203 EXPORT_SYMBOL(free_rtllib);
204
205 u32 rtllib_debug_level;
206 static int debug = \
207                             RTLLIB_DL_ERR
208                             ;
209 static struct proc_dir_entry *rtllib_proc;
210
211 static int show_debug_level(char *page, char **start, off_t offset,
212                             int count, int *eof, void *data)
213 {
214         return snprintf(page, count, "0x%08X\n", rtllib_debug_level);
215 }
216
217 static int store_debug_level(struct file *file, const char __user *buffer,
218                              unsigned long count, void *data)
219 {
220         char buf[] = "0x00000000";
221         unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
222         char *p = (char *)buf;
223         unsigned long val;
224
225         if (copy_from_user(buf, buffer, len))
226                 return count;
227         buf[len] = 0;
228         if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
229                 p++;
230                 if (p[0] == 'x' || p[0] == 'X')
231                         p++;
232                 val = simple_strtoul(p, &p, 16);
233         } else
234                 val = simple_strtoul(p, &p, 10);
235         if (p == buf)
236                 printk(KERN_INFO DRV_NAME
237                        ": %s is not in hex or decimal form.\n", buf);
238         else
239                 rtllib_debug_level = val;
240
241         return strnlen(buf, count);
242 }
243
244 int __init rtllib_init(void)
245 {
246         struct proc_dir_entry *e;
247
248         rtllib_debug_level = debug;
249         rtllib_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
250         if (rtllib_proc == NULL) {
251                 RTLLIB_ERROR("Unable to create " DRV_NAME
252                                 " proc directory\n");
253                 return -EIO;
254         }
255         e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
256                               rtllib_proc);
257         if (!e) {
258                 remove_proc_entry(DRV_NAME, init_net.proc_net);
259                 rtllib_proc = NULL;
260                 return -EIO;
261         }
262         e->read_proc = show_debug_level;
263         e->write_proc = store_debug_level;
264         e->data = NULL;
265
266         return 0;
267 }
268
269 void __exit rtllib_exit(void)
270 {
271         if (rtllib_proc) {
272                 remove_proc_entry("debug_level", rtllib_proc);
273                 remove_proc_entry(DRV_NAME, init_net.proc_net);
274                 rtllib_proc = NULL;
275         }
276 }
277
278 module_init(rtllib_init);
279 module_exit(rtllib_exit);
280
281 MODULE_LICENSE("GPL");