staging: rtl8192e: Convert typedef SW_CAM_TABLE to struct sw_cam_table
[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 <asm/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 = kmalloc(
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         memset(ieee->networks, 0,
81                MAX_NETWORK_COUNT * sizeof(struct rtllib_network));
82
83         return 0;
84 }
85
86 static inline void rtllib_networks_free(struct rtllib_device *ieee)
87 {
88         if (!ieee->networks)
89                 return;
90         kfree(ieee->networks);
91         ieee->networks = NULL;
92 }
93
94 static inline void rtllib_networks_initialize(struct rtllib_device *ieee)
95 {
96         int i;
97
98         INIT_LIST_HEAD(&ieee->network_free_list);
99         INIT_LIST_HEAD(&ieee->network_list);
100         for (i = 0; i < MAX_NETWORK_COUNT; i++)
101                 list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
102 }
103
104 struct net_device *alloc_rtllib(int sizeof_priv)
105 {
106         struct rtllib_device *ieee = NULL;
107         struct net_device *dev;
108         int i,err;
109
110         RTLLIB_DEBUG_INFO("Initializing...\n");
111
112         dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv);
113         if (!dev) {
114                 RTLLIB_ERROR("Unable to network device.\n");
115                 goto failed;
116         }
117         ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
118         memset(ieee, 0, sizeof(struct rtllib_device)+sizeof_priv);
119         ieee->dev = dev;
120
121         err = rtllib_networks_allocate(ieee);
122         if (err) {
123                 RTLLIB_ERROR("Unable to allocate beacon storage: %d\n",
124                                 err);
125                 goto failed;
126         }
127         rtllib_networks_initialize(ieee);
128
129
130         /* Default fragmentation threshold is maximum payload size */
131         ieee->fts = DEFAULT_FTS;
132         ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
133         ieee->open_wep = 1;
134
135         /* Default to enabling full open WEP with host based encrypt/decrypt */
136         ieee->host_encrypt = 1;
137         ieee->host_decrypt = 1;
138         ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
139
140         INIT_LIST_HEAD(&ieee->crypt_deinit_list);
141         _setup_timer(&ieee->crypt_deinit_timer,
142                     rtllib_crypt_deinit_handler,
143                     (unsigned long) ieee);
144         ieee->rtllib_ap_sec_type = rtllib_ap_sec_type;
145
146         spin_lock_init(&ieee->lock);
147         spin_lock_init(&ieee->wpax_suitlist_lock);
148         spin_lock_init(&ieee->bw_spinlock);
149         spin_lock_init(&ieee->reorder_spinlock);
150         atomic_set(&(ieee->atm_chnlop), 0);
151         atomic_set(&(ieee->atm_swbw), 0);
152
153         ieee->bHalfNMode = false;
154         ieee->wpa_enabled = 0;
155         ieee->tkip_countermeasures = 0;
156         ieee->drop_unencrypted = 0;
157         ieee->privacy_invoked = 0;
158         ieee->ieee802_1x = 1;
159         ieee->raw_tx = 0;
160         ieee->hwsec_active = 0;
161
162         memset(ieee->swcamtable,0,sizeof(struct sw_cam_table)*32);
163         rtllib_softmac_init(ieee);
164
165         ieee->pHTInfo = (struct rt_hi_throughput*)kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL);
166         if (ieee->pHTInfo == NULL)
167         {
168                 RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc memory for HTInfo\n");
169                 return NULL;
170         }
171         HTUpdateDefaultSetting(ieee);
172         HTInitializeHTInfo(ieee);
173         TSInitialize(ieee);
174         for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
175                 INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
176
177         for (i = 0; i < 17; i++) {
178                 ieee->last_rxseq_num[i] = -1;
179                 ieee->last_rxfrag_num[i] = -1;
180                 ieee->last_packet_time[i] = 0;
181         }
182
183         rtllib_tkip_null();
184         rtllib_wep_null();
185         rtllib_ccmp_null();
186
187         return dev;
188
189  failed:
190         if (dev)
191                 free_netdev(dev);
192         return NULL;
193 }
194
195
196 void free_rtllib(struct net_device *dev)
197 {
198         struct rtllib_device *ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
199         int i;
200         if (ieee->pHTInfo != NULL) {
201                 kfree(ieee->pHTInfo);
202                 ieee->pHTInfo = NULL;
203         }
204         rtllib_softmac_free(ieee);
205         del_timer_sync(&ieee->crypt_deinit_timer);
206         rtllib_crypt_deinit_entries(ieee, 1);
207
208         for (i = 0; i < WEP_KEYS; i++) {
209                 struct rtllib_crypt_data *crypt = ieee->crypt[i];
210                 if (crypt) {
211                         if (crypt->ops)
212                                 crypt->ops->deinit(crypt->priv);
213                         kfree(crypt);
214                         ieee->crypt[i] = NULL;
215                 }
216         }
217
218         rtllib_networks_free(ieee);
219         free_netdev(dev);
220 }
221
222 u32 rtllib_debug_level = 0;
223 static int debug = \
224                             RTLLIB_DL_ERR
225                             ;
226 struct proc_dir_entry *rtllib_proc = NULL;
227
228 static 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", rtllib_debug_level);
232 }
233
234 static 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((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                 rtllib_debug_level = val;
257
258         return strnlen(buf, count);
259 }
260
261 int __init rtllib_init(void)
262 {
263         struct proc_dir_entry *e;
264
265         rtllib_debug_level = debug;
266         rtllib_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
267         if (rtllib_proc == NULL) {
268                 RTLLIB_ERROR("Unable to create " DRV_NAME
269                                 " proc directory\n");
270                 return -EIO;
271         }
272         e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
273                               rtllib_proc);
274         if (!e) {
275                 remove_proc_entry(DRV_NAME, init_net.proc_net);
276                 rtllib_proc = NULL;
277                 return -EIO;
278         }
279         e->read_proc = show_debug_level;
280         e->write_proc = store_debug_level;
281         e->data = NULL;
282
283         return 0;
284 }
285
286 void __exit rtllib_exit(void)
287 {
288         if (rtllib_proc) {
289                 remove_proc_entry("debug_level", rtllib_proc);
290                 remove_proc_entry(DRV_NAME, init_net.proc_net);
291                 rtllib_proc = NULL;
292         }
293 }