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 return -ENOMEM;
77
78 return 0;
79 }
80
rtllib_networks_free(struct rtllib_device * ieee)81 static inline void rtllib_networks_free(struct rtllib_device *ieee)
82 {
83 if (!ieee->networks)
84 return;
85 kfree(ieee->networks);
86 ieee->networks = NULL;
87 }
88
rtllib_networks_initialize(struct rtllib_device * ieee)89 static inline void rtllib_networks_initialize(struct rtllib_device *ieee)
90 {
91 int i;
92
93 INIT_LIST_HEAD(&ieee->network_free_list);
94 INIT_LIST_HEAD(&ieee->network_list);
95 for (i = 0; i < MAX_NETWORK_COUNT; i++)
96 list_add_tail(&ieee->networks[i].list,
97 &ieee->network_free_list);
98 }
99
alloc_rtllib(int sizeof_priv)100 struct net_device *alloc_rtllib(int sizeof_priv)
101 {
102 struct rtllib_device *ieee = NULL;
103 struct net_device *dev;
104 int i, err;
105
106 RTLLIB_DEBUG_INFO("Initializing...\n");
107
108 dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv);
109 if (!dev) {
110 RTLLIB_ERROR("Unable to network device.\n");
111 return NULL;
112 }
113 ieee = (struct rtllib_device *)netdev_priv_rsl(dev);
114 memset(ieee, 0, sizeof(struct rtllib_device)+sizeof_priv);
115 ieee->dev = dev;
116
117 err = rtllib_networks_allocate(ieee);
118 if (err) {
119 RTLLIB_ERROR("Unable to allocate beacon storage: %d\n",
120 err);
121 goto failed;
122 }
123 rtllib_networks_initialize(ieee);
124
125
126 /* Default fragmentation threshold is maximum payload size */
127 ieee->fts = DEFAULT_FTS;
128 ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
129 ieee->open_wep = 1;
130
131 /* Default to enabling full open WEP with host based encrypt/decrypt */
132 ieee->host_encrypt = 1;
133 ieee->host_decrypt = 1;
134 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
135
136 ieee->rtllib_ap_sec_type = rtllib_ap_sec_type;
137
138 spin_lock_init(&ieee->lock);
139 spin_lock_init(&ieee->wpax_suitlist_lock);
140 spin_lock_init(&ieee->bw_spinlock);
141 spin_lock_init(&ieee->reorder_spinlock);
142 atomic_set(&(ieee->atm_chnlop), 0);
143 atomic_set(&(ieee->atm_swbw), 0);
144
145 /* SAM FIXME */
146 lib80211_crypt_info_init(&ieee->crypt_info, "RTLLIB", &ieee->lock);
147
148 ieee->bHalfNMode = false;
149 ieee->wpa_enabled = 0;
150 ieee->tkip_countermeasures = 0;
151 ieee->drop_unencrypted = 0;
152 ieee->privacy_invoked = 0;
153 ieee->ieee802_1x = 1;
154 ieee->raw_tx = 0;
155 ieee->hwsec_active = 0;
156
157 memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32);
158 rtllib_softmac_init(ieee);
159
160 ieee->pHTInfo = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL);
161 if (ieee->pHTInfo == NULL)
162 return NULL;
163
164 HTUpdateDefaultSetting(ieee);
165 HTInitializeHTInfo(ieee);
166 TSInitialize(ieee);
167 for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
168 INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
169
170 for (i = 0; i < 17; i++) {
171 ieee->last_rxseq_num[i] = -1;
172 ieee->last_rxfrag_num[i] = -1;
173 ieee->last_packet_time[i] = 0;
174 }
175
176 return dev;
177
178 failed:
179 free_netdev(dev);
180 return NULL;
181 }
182 EXPORT_SYMBOL(alloc_rtllib);
183
free_rtllib(struct net_device * dev)184 void free_rtllib(struct net_device *dev)
185 {
186 struct rtllib_device *ieee = (struct rtllib_device *)
187 netdev_priv_rsl(dev);
188
189 kfree(ieee->pHTInfo);
190 ieee->pHTInfo = NULL;
191 rtllib_softmac_free(ieee);
192
193 lib80211_crypt_info_free(&ieee->crypt_info);
194
195 rtllib_networks_free(ieee);
196 free_netdev(dev);
197 }
198 EXPORT_SYMBOL(free_rtllib);
199
200 u32 rtllib_debug_level;
201 static int debug = RTLLIB_DL_ERR;
202 static struct proc_dir_entry *rtllib_proc;
203
show_debug_level(struct seq_file * m,void * v)204 static int show_debug_level(struct seq_file *m, void *v)
205 {
206 seq_printf(m, "0x%08X\n", rtllib_debug_level);
207
208 return 0;
209 }
210
write_debug_level(struct file * file,const char __user * buffer,size_t count,loff_t * ppos)211 static ssize_t write_debug_level(struct file *file, const char __user *buffer,
212 size_t count, loff_t *ppos)
213 {
214 unsigned long val;
215 int err = kstrtoul_from_user(buffer, count, 0, &val);
216
217 if (err)
218 return err;
219 rtllib_debug_level = val;
220 return count;
221 }
222
open_debug_level(struct inode * inode,struct file * file)223 static int open_debug_level(struct inode *inode, struct file *file)
224 {
225 return single_open(file, show_debug_level, NULL);
226 }
227
228 static const struct file_operations fops = {
229 .open = open_debug_level,
230 .read = seq_read,
231 .llseek = seq_lseek,
232 .write = write_debug_level,
233 .release = single_release,
234 };
235
rtllib_init(void)236 static int __init rtllib_init(void)
237 {
238 struct proc_dir_entry *e;
239
240 rtllib_debug_level = debug;
241 rtllib_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
242 if (rtllib_proc == NULL) {
243 RTLLIB_ERROR("Unable to create " DRV_NAME
244 " proc directory\n");
245 return -EIO;
246 }
247 e = proc_create("debug_level", S_IRUGO | S_IWUSR, rtllib_proc, &fops);
248 if (!e) {
249 remove_proc_entry(DRV_NAME, init_net.proc_net);
250 rtllib_proc = NULL;
251 return -EIO;
252 }
253 return 0;
254 }
255
rtllib_exit(void)256 static void __exit rtllib_exit(void)
257 {
258 if (rtllib_proc) {
259 remove_proc_entry("debug_level", rtllib_proc);
260 remove_proc_entry(DRV_NAME, init_net.proc_net);
261 rtllib_proc = NULL;
262 }
263 }
264
265 module_init(rtllib_init);
266 module_exit(rtllib_exit);
267
268 MODULE_LICENSE("GPL");
269