From: wlanfae <wlanfae@realtek.com>
[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 #ifdef CONFIG_CFG_80211
60 #ifdef CONFIG_RTL_RFKILL
61 static inline void rtllib_rfkill_poll(struct wiphy *wiphy)
62 {
63         struct rtllib_device *rtllib = NULL;
64
65         rtllib = (struct rtllib_device *)wiphy_priv(wiphy);
66
67         rtllib = (struct rtllib_device *)netdev_priv_rsl(rtllib->dev);
68
69         if (rtllib->rtllib_rfkill_poll)
70                 rtllib->rtllib_rfkill_poll(rtllib->dev);
71 }
72 #else
73 static inline void rtllib_rfkill_poll(struct wiphy *wiphy) {}
74 #endif
75 struct cfg80211_ops rtllib_config_ops = {.rfkill_poll = rtllib_rfkill_poll };
76 void *rtllib_wiphy_privid = &rtllib_wiphy_privid;
77 #endif
78
79 void _setup_timer( struct timer_list* ptimer, void* fun, unsigned long data )
80 {
81    ptimer->function = fun;
82    ptimer->data = data;
83    init_timer( ptimer );
84 }
85
86 static inline int rtllib_networks_allocate(struct rtllib_device *ieee)
87 {
88         if (ieee->networks)
89                 return 0;
90
91 #ifndef RTK_DMP_PLATFORM
92         ieee->networks = kmalloc(
93                 MAX_NETWORK_COUNT * sizeof(struct rtllib_network),
94                 GFP_KERNEL);
95 #else
96         ieee->networks = dvr_malloc(MAX_NETWORK_COUNT * sizeof(struct rtllib_network));
97 #endif
98         if (!ieee->networks) {
99                 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
100                        ieee->dev->name);
101                 return -ENOMEM;
102         }
103
104         memset(ieee->networks, 0,
105                MAX_NETWORK_COUNT * sizeof(struct rtllib_network));
106
107         return 0;
108 }
109
110 static inline void rtllib_networks_free(struct rtllib_device *ieee)
111 {
112         if (!ieee->networks)
113                 return;
114 #ifndef RTK_DMP_PLATFORM
115         kfree(ieee->networks);
116 #else
117         dvr_free(ieee->networks);
118 #endif
119         ieee->networks = NULL;
120 }
121
122 static inline void rtllib_networks_initialize(struct rtllib_device *ieee)
123 {
124         int i;
125
126         INIT_LIST_HEAD(&ieee->network_free_list);
127         INIT_LIST_HEAD(&ieee->network_list);
128         for (i = 0; i < MAX_NETWORK_COUNT; i++)
129                 list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
130 }
131
132 #if defined CONFIG_CFG_80211
133 static bool rtllib_wdev_alloc(struct rtllib_device *ieee, int sizeof_priv)
134 {
135         int priv_size;
136         struct rtllib_device *rtllib = NULL;
137
138         priv_size = ALIGN(sizeof(struct rtllib_device),NETDEV_ALIGN) + sizeof_priv;
139
140         ieee->wdev.wiphy = wiphy_new(&rtllib_config_ops, priv_size);
141         if (!ieee->wdev.wiphy) {
142                 RTLLIB_ERROR("Unable to allocate wiphy.\n");
143                 goto out_err_new;
144         }
145
146         rtllib = (struct rtllib_device *)wiphy_priv(ieee->wdev.wiphy);
147         rtllib->dev = ieee->dev;
148
149         ieee->dev->ieee80211_ptr = &ieee->wdev;
150         ieee->wdev.iftype = NL80211_IFTYPE_STATION;
151
152         /* Fill-out wiphy structure bits we know...  Not enough info
153          *            here to call set_wiphy_dev or set MAC address or channel info
154          *                       -- have to do that in ->ndo_init... */
155         ieee->wdev.wiphy->privid = rtllib_wiphy_privid;
156
157         ieee->wdev.wiphy->max_scan_ssids = 1;
158         ieee->wdev.wiphy->max_scan_ie_len = 0;
159         ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
160
161         return true;
162
163 out_err_new:
164         wiphy_free(ieee->wdev.wiphy);
165         return false;
166 }
167 #endif
168
169 struct net_device *alloc_rtllib(int sizeof_priv)
170 {
171         struct rtllib_device *ieee = NULL;
172         struct net_device *dev;
173         int i,err;
174
175         RTLLIB_DEBUG_INFO("Initializing...\n");
176
177         dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv);
178         if (!dev) {
179                 RTLLIB_ERROR("Unable to network device.\n");
180                 goto failed;
181         }
182         ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
183         memset(ieee, 0, sizeof(struct rtllib_device)+sizeof_priv);
184         ieee->dev = dev;
185
186 #ifdef CONFIG_CFG_80211
187         if (!rtllib_wdev_alloc(ieee, sizeof_priv))
188                 goto failed;
189 #endif
190         err = rtllib_networks_allocate(ieee);
191         if (err) {
192                 RTLLIB_ERROR("Unable to allocate beacon storage: %d\n",
193                                 err);
194                 goto failed;
195         }
196         rtllib_networks_initialize(ieee);
197
198
199         /* Default fragmentation threshold is maximum payload size */
200         ieee->fts = DEFAULT_FTS;
201         ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
202         ieee->open_wep = 1;
203
204         /* Default to enabling full open WEP with host based encrypt/decrypt */
205         ieee->host_encrypt = 1;
206         ieee->host_decrypt = 1;
207         ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
208
209         INIT_LIST_HEAD(&ieee->crypt_deinit_list);
210         _setup_timer(&ieee->crypt_deinit_timer,
211                     rtllib_crypt_deinit_handler,
212                     (unsigned long) ieee);
213         ieee->rtllib_ap_sec_type = rtllib_ap_sec_type;
214
215         spin_lock_init(&ieee->lock);
216         spin_lock_init(&ieee->wpax_suitlist_lock);
217         spin_lock_init(&ieee->bw_spinlock);
218         spin_lock_init(&ieee->reorder_spinlock);
219         atomic_set(&(ieee->atm_chnlop), 0);
220         atomic_set(&(ieee->atm_swbw), 0);
221
222         ieee->bHalfNMode = false;
223         ieee->wpa_enabled = 0;
224         ieee->tkip_countermeasures = 0;
225         ieee->drop_unencrypted = 0;
226         ieee->privacy_invoked = 0;
227         ieee->ieee802_1x = 1;
228         ieee->raw_tx = 0;
229         ieee->hwsec_active = 0;
230
231         memset(ieee->swcamtable,0,sizeof(SW_CAM_TABLE)*32);
232         rtllib_softmac_init(ieee);
233
234         ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
235         if (ieee->pHTInfo == NULL)
236         {
237                 RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc memory for HTInfo\n");
238                 return NULL;
239         }
240         HTUpdateDefaultSetting(ieee);
241         HTInitializeHTInfo(ieee);
242         TSInitialize(ieee);
243         for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
244                 INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
245
246         for (i = 0; i < 17; i++) {
247                 ieee->last_rxseq_num[i] = -1;
248                 ieee->last_rxfrag_num[i] = -1;
249                 ieee->last_packet_time[i] = 0;
250         }
251
252         rtllib_tkip_null();
253         rtllib_wep_null();
254         rtllib_ccmp_null();
255
256         return dev;
257
258  failed:
259         if (dev)
260                 free_netdev(dev);
261         return NULL;
262 }
263
264
265 void free_rtllib(struct net_device *dev)
266 {
267         struct rtllib_device *ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
268         int i;
269         if (ieee->pHTInfo != NULL) {
270                 kfree(ieee->pHTInfo);
271                 ieee->pHTInfo = NULL;
272         }
273         rtllib_softmac_free(ieee);
274         del_timer_sync(&ieee->crypt_deinit_timer);
275         rtllib_crypt_deinit_entries(ieee, 1);
276
277         for (i = 0; i < WEP_KEYS; i++) {
278                 struct rtllib_crypt_data *crypt = ieee->crypt[i];
279                 if (crypt) {
280                         if (crypt->ops)
281                                 crypt->ops->deinit(crypt->priv);
282                         kfree(crypt);
283                         ieee->crypt[i] = NULL;
284                 }
285         }
286
287         rtllib_networks_free(ieee);
288 #ifdef CONFIG_CFG_80211
289         wiphy_unregister(ieee->wdev.wiphy);
290         wiphy_free(ieee->wdev.wiphy);
291 #endif
292         free_netdev(dev);
293 }
294
295 #ifdef CONFIG_RTLLIB_DEBUG
296
297 u32 rtllib_debug_level = 0;
298 static int debug = \
299                             RTLLIB_DL_ERR
300                             ;
301 struct proc_dir_entry *rtllib_proc = NULL;
302
303 static int show_debug_level(char *page, char **start, off_t offset,
304                             int count, int *eof, void *data)
305 {
306         return snprintf(page, count, "0x%08X\n", rtllib_debug_level);
307 }
308
309 static int store_debug_level(struct file *file, const char *buffer,
310                              unsigned long count, void *data)
311 {
312         char buf[] = "0x00000000";
313         unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
314         char *p = (char *)buf;
315         unsigned long val;
316
317         if (copy_from_user(buf, buffer, len))
318                 return count;
319         buf[len] = 0;
320         if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
321                 p++;
322                 if (p[0] == 'x' || p[0] == 'X')
323                         p++;
324                 val = simple_strtoul(p, &p, 16);
325         } else
326                 val = simple_strtoul(p, &p, 10);
327         if (p == buf)
328                 printk(KERN_INFO DRV_NAME
329                        ": %s is not in hex or decimal form.\n", buf);
330         else
331                 rtllib_debug_level = val;
332
333         return strnlen(buf, count);
334 }
335
336 int __init rtllib_init(void)
337 {
338 #ifdef CONFIG_RTLLIB_DEBUG
339         struct proc_dir_entry *e;
340
341         rtllib_debug_level = debug;
342         rtllib_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
343         if (rtllib_proc == NULL) {
344                 RTLLIB_ERROR("Unable to create " DRV_NAME
345                                 " proc directory\n");
346                 return -EIO;
347         }
348         e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
349                               rtllib_proc);
350         if (!e) {
351                 remove_proc_entry(DRV_NAME, init_net.proc_net);
352                 rtllib_proc = NULL;
353                 return -EIO;
354         }
355         e->read_proc = show_debug_level;
356         e->write_proc = store_debug_level;
357         e->data = NULL;
358 #endif
359
360         return 0;
361 }
362
363 void __exit rtllib_exit(void)
364 {
365 #ifdef CONFIG_RTLLIB_DEBUG
366         if (rtllib_proc) {
367                 remove_proc_entry("debug_level", rtllib_proc);
368                 remove_proc_entry(DRV_NAME, init_net.proc_net);
369                 rtllib_proc = NULL;
370         }
371 #endif
372 }
373
374 #endif