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
_setup_timer(struct timer_list * ptimer,void * fun,unsigned long data)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
rtllib_networks_allocate(struct rtllib_device * ieee)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
rtllib_networks_free(struct rtllib_device * ieee)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
rtllib_networks_initialize(struct rtllib_device * ieee)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
alloc_rtllib(int sizeof_priv)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
free_rtllib(struct net_device * dev)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
show_debug_level(struct seq_file * m,void * v)211 static int show_debug_level(struct seq_file *m, void *v)
212 {
213 return seq_printf(m, "0x%08X\n", rtllib_debug_level);
214 }
215
write_debug_level(struct file * file,const char __user * buffer,size_t count,loff_t * ppos)216 static ssize_t write_debug_level(struct file *file, const char __user *buffer,
217 size_t count, loff_t *ppos)
218 {
219 unsigned long val;
220 int err = kstrtoul_from_user(buffer, count, 0, &val);
221 if (err)
222 return err;
223 rtllib_debug_level = val;
224 return count;
225 }
226
open_debug_level(struct inode * inode,struct file * file)227 static int open_debug_level(struct inode *inode, struct file *file)
228 {
229 return single_open(file, show_debug_level, NULL);
230 }
231
232 static const struct file_operations fops = {
233 .open = open_debug_level,
234 .read = seq_read,
235 .llseek = seq_lseek,
236 .write = write_debug_level
237 };
238
rtllib_init(void)239 int __init rtllib_init(void)
240 {
241 struct proc_dir_entry *e;
242
243 rtllib_debug_level = debug;
244 rtllib_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
245 if (rtllib_proc == NULL) {
246 RTLLIB_ERROR("Unable to create " DRV_NAME
247 " proc directory\n");
248 return -EIO;
249 }
250 e = proc_create("debug_level", S_IRUGO | S_IWUSR, rtllib_proc, &fops);
251 if (!e) {
252 remove_proc_entry(DRV_NAME, init_net.proc_net);
253 rtllib_proc = NULL;
254 return -EIO;
255 }
256 return 0;
257 }
258
rtllib_exit(void)259 void __exit rtllib_exit(void)
260 {
261 if (rtllib_proc) {
262 remove_proc_entry("debug_level", rtllib_proc);
263 remove_proc_entry(DRV_NAME, init_net.proc_net);
264 rtllib_proc = NULL;
265 }
266 }
267
268 module_init(rtllib_init);
269 module_exit(rtllib_exit);
270
271 MODULE_LICENSE("GPL");
272