Merge tag 'staging-3.7-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / rtl8192e / rtllib_module.c
CommitLineData
94a79942
LF
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>
94a79942
LF
48#include <linux/wireless.h>
49#include <linux/etherdevice.h>
8567829a 50#include <linux/uaccess.h>
94a79942
LF
51#include <net/arp.h>
52
53#include "rtllib.h"
54
55
d37e0208
SM
56u32 rt_global_debug_component = COMP_ERR;
57EXPORT_SYMBOL(rt_global_debug_component);
58
59
db8971b6 60void _setup_timer(struct timer_list *ptimer, void *fun, unsigned long data)
94a79942 61{
8567829a
LF
62 ptimer->function = fun;
63 ptimer->data = data;
64 init_timer(ptimer);
94a79942
LF
65}
66
67static inline int rtllib_networks_allocate(struct rtllib_device *ieee)
68{
69 if (ieee->networks)
70 return 0;
71
ec0dc6be 72 ieee->networks = kzalloc(
94a79942
LF
73 MAX_NETWORK_COUNT * sizeof(struct rtllib_network),
74 GFP_KERNEL);
94a79942
LF
75 if (!ieee->networks) {
76 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
77 ieee->dev->name);
78 return -ENOMEM;
79 }
80
94a79942
LF
81 return 0;
82}
83
84static inline void rtllib_networks_free(struct rtllib_device *ieee)
85{
86 if (!ieee->networks)
87 return;
94a79942 88 kfree(ieee->networks);
94a79942
LF
89 ieee->networks = NULL;
90}
91
92static 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++)
8567829a
LF
99 list_add_tail(&ieee->networks[i].list,
100 &ieee->network_free_list);
94a79942
LF
101}
102
94a79942
LF
103struct net_device *alloc_rtllib(int sizeof_priv)
104{
105 struct rtllib_device *ieee = NULL;
106 struct net_device *dev;
8567829a 107 int i, err;
94a79942
LF
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
94a79942
LF
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
94a79942
LF
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
3b148be0
SM
148 /* SAM FIXME */
149 lib80211_crypt_info_init(&ieee->crypt_info, "RTLLIB", &ieee->lock);
150
94a79942
LF
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
8567829a 160 memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
94a79942
LF
161 rtllib_softmac_init(ieee);
162
8567829a
LF
163 ieee->pHTInfo = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL);
164 if (ieee->pHTInfo == NULL) {
94a79942
LF
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
94a79942
LF
180 return dev;
181
182 failed:
183 if (dev)
184 free_netdev(dev);
185 return NULL;
186}
3b28499c 187EXPORT_SYMBOL(alloc_rtllib);
94a79942 188
94a79942
LF
189void free_rtllib(struct net_device *dev)
190{
8567829a
LF
191 struct rtllib_device *ieee = (struct rtllib_device *)
192 netdev_priv_rsl(dev);
d7613e53
LF
193
194 kfree(ieee->pHTInfo);
195 ieee->pHTInfo = NULL;
94a79942 196 rtllib_softmac_free(ieee);
0ddcf5fd 197
3b148be0 198 lib80211_crypt_info_free(&ieee->crypt_info);
94a79942
LF
199
200 rtllib_networks_free(ieee);
94a79942
LF
201 free_netdev(dev);
202}
3b28499c 203EXPORT_SYMBOL(free_rtllib);
94a79942 204
8567829a 205u32 rtllib_debug_level;
94a79942
LF
206static int debug = \
207 RTLLIB_DL_ERR
208 ;
ec0dc6be 209static struct proc_dir_entry *rtllib_proc;
94a79942
LF
210
211static 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
ec0dc6be 217static int store_debug_level(struct file *file, const char __user *buffer,
94a79942
LF
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
244int __init rtllib_init(void)
245{
94a79942
LF
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;
94a79942
LF
265
266 return 0;
267}
268
269void __exit rtllib_exit(void)
270{
94a79942
LF
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 }
94a79942 276}
d37e0208
SM
277
278module_init(rtllib_init);
279module_exit(rtllib_exit);
280
281MODULE_LICENSE("GPL");