Linux Audio

Check our new training course

Loading...
  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
 56u32 rt_global_debug_component = COMP_ERR;
 57EXPORT_SYMBOL(rt_global_debug_component);
 58
 59
 60void _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
 67static 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
 84static 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
 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++)
 99		list_add_tail(&ieee->networks[i].list,
100			      &ieee->network_free_list);
101}
102
103struct 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}
187EXPORT_SYMBOL(alloc_rtllib);
188
189void 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}
203EXPORT_SYMBOL(free_rtllib);
204
205u32 rtllib_debug_level;
206static int debug = \
207			    RTLLIB_DL_ERR
208			    ;
209static struct proc_dir_entry *rtllib_proc;
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
217static int store_debug_level(struct file *file, const char __user *buffer,
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{
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;
265
266	return 0;
267}
268
269void __exit rtllib_exit(void)
270{
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	}
276}
277
278module_init(rtllib_init);
279module_exit(rtllib_exit);
280
281MODULE_LICENSE("GPL");