Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*******************************************************************************
  2
  3  Copyright(c) 2004-2005 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  <j@w1.fi>
  9  Copyright (c) 2002-2003, Jouni Malinen <j@w1.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  Intel Linux Wireless <ilw@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/proc_fs.h>
 43#include <linux/skbuff.h>
 44#include <linux/slab.h>
 45#include <linux/tcp.h>
 46#include <linux/types.h>
 47#include <linux/wireless.h>
 48#include <linux/etherdevice.h>
 49#include <linux/uaccess.h>
 50#include <net/net_namespace.h>
 51#include <net/arp.h>
 52
 53#include "libipw.h"
 54
 55#define DRV_DESCRIPTION "802.11 data/management/control stack"
 56#define DRV_NAME        "libipw"
 57#define DRV_PROCNAME	"ieee80211"
 58#define DRV_VERSION	LIBIPW_VERSION
 59#define DRV_COPYRIGHT   "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
 60
 61MODULE_VERSION(DRV_VERSION);
 62MODULE_DESCRIPTION(DRV_DESCRIPTION);
 63MODULE_AUTHOR(DRV_COPYRIGHT);
 64MODULE_LICENSE("GPL");
 65
 66static struct cfg80211_ops libipw_config_ops = { };
 67static void *libipw_wiphy_privid = &libipw_wiphy_privid;
 68
 69static int libipw_networks_allocate(struct libipw_device *ieee)
 70{
 71	int i, j;
 72
 73	for (i = 0; i < MAX_NETWORK_COUNT; i++) {
 74		ieee->networks[i] = kzalloc(sizeof(struct libipw_network),
 75					    GFP_KERNEL);
 76		if (!ieee->networks[i]) {
 77			LIBIPW_ERROR("Out of memory allocating beacons\n");
 78			for (j = 0; j < i; j++)
 79				kfree(ieee->networks[j]);
 80			return -ENOMEM;
 81		}
 82	}
 83
 84	return 0;
 85}
 86
 87static inline void libipw_networks_free(struct libipw_device *ieee)
 88{
 89	int i;
 90
 91	for (i = 0; i < MAX_NETWORK_COUNT; i++)
 92		kfree(ieee->networks[i]);
 93}
 94
 95void libipw_networks_age(struct libipw_device *ieee,
 96                            unsigned long age_secs)
 97{
 98	struct libipw_network *network = NULL;
 99	unsigned long flags;
100	unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
101
102	spin_lock_irqsave(&ieee->lock, flags);
103	list_for_each_entry(network, &ieee->network_list, list) {
104		network->last_scanned -= age_jiffies;
105	}
106	spin_unlock_irqrestore(&ieee->lock, flags);
107}
108EXPORT_SYMBOL(libipw_networks_age);
109
110static void libipw_networks_initialize(struct libipw_device *ieee)
111{
112	int i;
113
114	INIT_LIST_HEAD(&ieee->network_free_list);
115	INIT_LIST_HEAD(&ieee->network_list);
116	for (i = 0; i < MAX_NETWORK_COUNT; i++)
117		list_add_tail(&ieee->networks[i]->list,
118			      &ieee->network_free_list);
119}
120
121struct net_device *alloc_libipw(int sizeof_priv, int monitor)
122{
123	struct libipw_device *ieee;
124	struct net_device *dev;
125	int err;
126
127	LIBIPW_DEBUG_INFO("Initializing...\n");
128
129	dev = alloc_etherdev(sizeof(struct libipw_device) + sizeof_priv);
130	if (!dev)
131		goto failed;
132
133	ieee = netdev_priv(dev);
134
135	ieee->dev = dev;
136
137	if (!monitor) {
138		ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0);
139		if (!ieee->wdev.wiphy) {
140			LIBIPW_ERROR("Unable to allocate wiphy.\n");
141			goto failed_free_netdev;
142		}
143
144		ieee->dev->ieee80211_ptr = &ieee->wdev;
145		ieee->wdev.iftype = NL80211_IFTYPE_STATION;
146
147		/* Fill-out wiphy structure bits we know...  Not enough info
148		   here to call set_wiphy_dev or set MAC address or channel info
149		   -- have to do that in ->ndo_init... */
150		ieee->wdev.wiphy->privid = libipw_wiphy_privid;
151
152		ieee->wdev.wiphy->max_scan_ssids = 1;
153		ieee->wdev.wiphy->max_scan_ie_len = 0;
154		ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
155						| BIT(NL80211_IFTYPE_ADHOC);
156	}
157
158	err = libipw_networks_allocate(ieee);
159	if (err) {
160		LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
161		goto failed_free_wiphy;
162	}
163	libipw_networks_initialize(ieee);
164
165	/* Default fragmentation threshold is maximum payload size */
166	ieee->fts = DEFAULT_FTS;
167	ieee->rts = DEFAULT_FTS;
168	ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
169	ieee->open_wep = 1;
170
171	/* Default to enabling full open WEP with host based encrypt/decrypt */
172	ieee->host_encrypt = 1;
173	ieee->host_decrypt = 1;
174	ieee->host_mc_decrypt = 1;
175
176	/* Host fragmentation in Open mode. Default is enabled.
177	 * Note: host fragmentation is always enabled if host encryption
178	 * is enabled. For cards can do hardware encryption, they must do
179	 * hardware fragmentation as well. So we don't need a variable
180	 * like host_enc_frag. */
181	ieee->host_open_frag = 1;
182	ieee->ieee802_1x = 1;	/* Default to supporting 802.1x */
183
184	spin_lock_init(&ieee->lock);
185
186	lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
187
188	ieee->wpa_enabled = 0;
189	ieee->drop_unencrypted = 0;
190	ieee->privacy_invoked = 0;
191
192	return dev;
193
194failed_free_wiphy:
195	if (!monitor)
196		wiphy_free(ieee->wdev.wiphy);
197failed_free_netdev:
198	free_netdev(dev);
199failed:
200	return NULL;
201}
202EXPORT_SYMBOL(alloc_libipw);
203
204void free_libipw(struct net_device *dev, int monitor)
205{
206	struct libipw_device *ieee = netdev_priv(dev);
207
208	lib80211_crypt_info_free(&ieee->crypt_info);
209
210	libipw_networks_free(ieee);
211
212	/* free cfg80211 resources */
213	if (!monitor)
214		wiphy_free(ieee->wdev.wiphy);
215
216	free_netdev(dev);
217}
218EXPORT_SYMBOL(free_libipw);
219
220#ifdef CONFIG_LIBIPW_DEBUG
221
222static int debug = 0;
223u32 libipw_debug_level = 0;
224EXPORT_SYMBOL_GPL(libipw_debug_level);
225static struct proc_dir_entry *libipw_proc = NULL;
226
227static int debug_level_proc_show(struct seq_file *m, void *v)
228{
229	seq_printf(m, "0x%08X\n", libipw_debug_level);
230	return 0;
231}
232
233static int debug_level_proc_open(struct inode *inode, struct file *file)
234{
235	return single_open(file, debug_level_proc_show, NULL);
236}
237
238static ssize_t debug_level_proc_write(struct file *file,
239		const char __user *buffer, size_t count, loff_t *pos)
240{
241	char buf[] = "0x00000000\n";
242	size_t len = min(sizeof(buf) - 1, count);
243	unsigned long val;
244
245	if (copy_from_user(buf, buffer, len))
246		return count;
247	buf[len] = 0;
248	if (sscanf(buf, "%li", &val) != 1)
249		printk(KERN_INFO DRV_NAME
250		       ": %s is not in hex or decimal form.\n", buf);
251	else
252		libipw_debug_level = val;
253
254	return strnlen(buf, len);
255}
256
257static const struct file_operations debug_level_proc_fops = {
258	.owner		= THIS_MODULE,
259	.open		= debug_level_proc_open,
260	.read		= seq_read,
261	.llseek		= seq_lseek,
262	.release	= single_release,
263	.write		= debug_level_proc_write,
264};
265#endif				/* CONFIG_LIBIPW_DEBUG */
266
267static int __init libipw_init(void)
268{
269#ifdef CONFIG_LIBIPW_DEBUG
270	struct proc_dir_entry *e;
271
272	libipw_debug_level = debug;
273	libipw_proc = proc_mkdir(DRV_PROCNAME, init_net.proc_net);
274	if (libipw_proc == NULL) {
275		LIBIPW_ERROR("Unable to create " DRV_PROCNAME
276				" proc directory\n");
277		return -EIO;
278	}
279	e = proc_create("debug_level", 0644, libipw_proc,
280			&debug_level_proc_fops);
281	if (!e) {
282		remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
283		libipw_proc = NULL;
284		return -EIO;
285	}
286#endif				/* CONFIG_LIBIPW_DEBUG */
287
288	printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
289	printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
290
291	return 0;
292}
293
294static void __exit libipw_exit(void)
295{
296#ifdef CONFIG_LIBIPW_DEBUG
297	if (libipw_proc) {
298		remove_proc_entry("debug_level", libipw_proc);
299		remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
300		libipw_proc = NULL;
301	}
302#endif				/* CONFIG_LIBIPW_DEBUG */
303}
304
305#ifdef CONFIG_LIBIPW_DEBUG
306#include <linux/moduleparam.h>
307module_param(debug, int, 0444);
308MODULE_PARM_DESC(debug, "debug output mask");
309#endif				/* CONFIG_LIBIPW_DEBUG */
310
311module_exit(libipw_exit);
312module_init(libipw_init);