]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/staging/rtl8192e/rtllib_module.c
35ea93de3682cb5935066bc2337c63c80d2cd302
[mirror_ubuntu-artful-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/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 /* SAM Init here */
140 INIT_LIST_HEAD(&ieee->crypt_info.crypt_deinit_list);
141 _setup_timer(&ieee->crypt_info.crypt_deinit_timer,
142 rtllib_crypt_deinit_handler,
143 (unsigned long)&ieee->crypt_info);
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 = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL);
166 if (ieee->pHTInfo == NULL) {
167 RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc memory for HTInfo\n");
168 return NULL;
169 }
170 HTUpdateDefaultSetting(ieee);
171 HTInitializeHTInfo(ieee);
172 TSInitialize(ieee);
173 for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
174 INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
175
176 for (i = 0; i < 17; i++) {
177 ieee->last_rxseq_num[i] = -1;
178 ieee->last_rxfrag_num[i] = -1;
179 ieee->last_packet_time[i] = 0;
180 }
181
182 return dev;
183
184 failed:
185 if (dev)
186 free_netdev(dev);
187 return NULL;
188 }
189 EXPORT_SYMBOL(alloc_rtllib);
190
191 void free_rtllib(struct net_device *dev)
192 {
193 struct rtllib_device *ieee = (struct rtllib_device *)
194 netdev_priv_rsl(dev);
195 int i;
196
197 kfree(ieee->pHTInfo);
198 ieee->pHTInfo = NULL;
199 rtllib_softmac_free(ieee);
200
201 /* SAM cleanup */
202 del_timer_sync(&ieee->crypt_info.crypt_deinit_timer);
203 rtllib_crypt_deinit_entries(&ieee->crypt_info, 1);
204
205 for (i = 0; i < NUM_WEP_KEYS; i++) {
206 struct lib80211_crypt_data *crypt = ieee->crypt_info.crypt[i];
207 if (crypt) {
208 if (crypt->ops)
209 crypt->ops->deinit(crypt->priv);
210 kfree(crypt);
211 ieee->crypt_info.crypt[i] = NULL;
212 }
213 }
214
215 rtllib_networks_free(ieee);
216 free_netdev(dev);
217 }
218 EXPORT_SYMBOL(free_rtllib);
219
220 u32 rtllib_debug_level;
221 static int debug = \
222 RTLLIB_DL_ERR
223 ;
224 static struct proc_dir_entry *rtllib_proc;
225
226 static int show_debug_level(char *page, char **start, off_t offset,
227 int count, int *eof, void *data)
228 {
229 return snprintf(page, count, "0x%08X\n", rtllib_debug_level);
230 }
231
232 static int store_debug_level(struct file *file, const char __user *buffer,
233 unsigned long count, void *data)
234 {
235 char buf[] = "0x00000000";
236 unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
237 char *p = (char *)buf;
238 unsigned long val;
239
240 if (copy_from_user(buf, buffer, len))
241 return count;
242 buf[len] = 0;
243 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
244 p++;
245 if (p[0] == 'x' || p[0] == 'X')
246 p++;
247 val = simple_strtoul(p, &p, 16);
248 } else
249 val = simple_strtoul(p, &p, 10);
250 if (p == buf)
251 printk(KERN_INFO DRV_NAME
252 ": %s is not in hex or decimal form.\n", buf);
253 else
254 rtllib_debug_level = val;
255
256 return strnlen(buf, count);
257 }
258
259 int __init rtllib_init(void)
260 {
261 struct proc_dir_entry *e;
262
263 rtllib_debug_level = debug;
264 rtllib_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
265 if (rtllib_proc == NULL) {
266 RTLLIB_ERROR("Unable to create " DRV_NAME
267 " proc directory\n");
268 return -EIO;
269 }
270 e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
271 rtllib_proc);
272 if (!e) {
273 remove_proc_entry(DRV_NAME, init_net.proc_net);
274 rtllib_proc = NULL;
275 return -EIO;
276 }
277 e->read_proc = show_debug_level;
278 e->write_proc = store_debug_level;
279 e->data = NULL;
280
281 return 0;
282 }
283
284 void __exit rtllib_exit(void)
285 {
286 if (rtllib_proc) {
287 remove_proc_entry("debug_level", rtllib_proc);
288 remove_proc_entry(DRV_NAME, init_net.proc_net);
289 rtllib_proc = NULL;
290 }
291 }
292
293 module_init(rtllib_init);
294 module_exit(rtllib_exit);
295
296 MODULE_LICENSE("GPL");