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