Replace <asm/uaccess.h> with <linux/uaccess.h> globally
[linux-block.git] / drivers / net / wireless / intel / ipw2x00 / libipw_module.c
CommitLineData
b453872c
JG
1/*******************************************************************************
2
ebeaddcc 3 Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
b453872c
JG
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
85d32e7b
JM
8 <j@w1.fi>
9 Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
b453872c
JG
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:
c1eb2c82 28 Intel Linux Wireless <ilw@linux.intel.com>
b453872c
JG
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31*******************************************************************************/
32
33#include <linux/compiler.h>
b453872c
JG
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>
b453872c
JG
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>
b453872c
JG
47#include <linux/wireless.h>
48#include <linux/etherdevice.h>
7c0f6ba6 49#include <linux/uaccess.h>
457c4cbc 50#include <net/net_namespace.h>
b453872c
JG
51#include <net/arp.h>
52
b0a4e7d8 53#include "libipw.h"
b453872c 54
31696160 55#define DRV_DESCRIPTION "802.11 data/management/control stack"
27ae60f8 56#define DRV_NAME "libipw"
151f52f0 57#define DRV_PROCNAME "ieee80211"
b0a4e7d8 58#define DRV_VERSION LIBIPW_VERSION
31696160
JK
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);
b453872c
JG
64MODULE_LICENSE("GPL");
65
cc40cc56
JL
66static struct cfg80211_ops libipw_config_ops = { };
67static void *libipw_wiphy_privid = &libipw_wiphy_privid;
a3caa99e 68
b0a4e7d8 69static int libipw_networks_allocate(struct libipw_device *ieee)
b453872c 70{
8e59340e
ZY
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 }
b453872c
JG
82 }
83
b453872c
JG
84 return 0;
85}
86
b0a4e7d8 87static inline void libipw_networks_free(struct libipw_device *ieee)
b453872c 88{
15f38598
ZY
89 int i;
90
2aa01652 91 for (i = 0; i < MAX_NETWORK_COUNT; i++)
8e59340e 92 kfree(ieee->networks[i]);
b453872c
JG
93}
94
b0a4e7d8 95void libipw_networks_age(struct libipw_device *ieee,
c3d72b96
DW
96 unsigned long age_secs)
97{
b0a4e7d8 98 struct libipw_network *network = NULL;
c3d72b96
DW
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}
b0a4e7d8 108EXPORT_SYMBOL(libipw_networks_age);
c3d72b96 109
b0a4e7d8 110static void libipw_networks_initialize(struct libipw_device *ieee)
b453872c
JG
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++)
8e59340e 117 list_add_tail(&ieee->networks[i]->list,
0edd5b44 118 &ieee->network_free_list);
b453872c
JG
119}
120
27ae60f8 121struct net_device *alloc_libipw(int sizeof_priv, int monitor)
b453872c 122{
b0a4e7d8 123 struct libipw_device *ieee;
b453872c
JG
124 struct net_device *dev;
125 int err;
126
b0a4e7d8 127 LIBIPW_DEBUG_INFO("Initializing...\n");
b453872c 128
b0a4e7d8 129 dev = alloc_etherdev(sizeof(struct libipw_device) + sizeof_priv);
41de8d4c 130 if (!dev)
b453872c 131 goto failed;
41de8d4c 132
b453872c 133 ieee = netdev_priv(dev);
b453872c
JG
134
135 ieee->dev = dev;
136
a3caa99e
JL
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
b0a4e7d8 158 err = libipw_networks_allocate(ieee);
b453872c 159 if (err) {
b0a4e7d8 160 LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
a3caa99e 161 goto failed_free_wiphy;
b453872c 162 }
b0a4e7d8 163 libipw_networks_initialize(ieee);
b453872c
JG
164
165 /* Default fragmentation threshold is maximum payload size */
166 ieee->fts = DEFAULT_FTS;
3cdd00c5 167 ieee->rts = DEFAULT_FTS;
b453872c
JG
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;
ccd0fda3
JK
174 ieee->host_mc_decrypt = 1;
175
af901ca1 176 /* Host fragmentation in Open mode. Default is enabled.
1264fc04
JK
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;
0edd5b44 182 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
b453872c 183
b453872c
JG
184 spin_lock_init(&ieee->lock);
185
2ba4b32e 186 lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
274bfb8d 187
0edd5b44 188 ieee->wpa_enabled = 0;
0edd5b44
JG
189 ieee->drop_unencrypted = 0;
190 ieee->privacy_invoked = 0;
b453872c
JG
191
192 return dev;
193
a3caa99e
JL
194failed_free_wiphy:
195 if (!monitor)
196 wiphy_free(ieee->wdev.wiphy);
d92a8e81
JL
197failed_free_netdev:
198 free_netdev(dev);
199failed:
b453872c
JG
200 return NULL;
201}
27ae60f8 202EXPORT_SYMBOL(alloc_libipw);
b453872c 203
27ae60f8 204void free_libipw(struct net_device *dev, int monitor)
b453872c 205{
b0a4e7d8 206 struct libipw_device *ieee = netdev_priv(dev);
b453872c 207
2ba4b32e 208 lib80211_crypt_info_free(&ieee->crypt_info);
b453872c 209
b0a4e7d8 210 libipw_networks_free(ieee);
a3caa99e
JL
211
212 /* free cfg80211 resources */
213 if (!monitor)
214 wiphy_free(ieee->wdev.wiphy);
215
b453872c
JG
216 free_netdev(dev);
217}
27ae60f8 218EXPORT_SYMBOL(free_libipw);
b453872c 219
3756162b 220#ifdef CONFIG_LIBIPW_DEBUG
b453872c
JG
221
222static int debug = 0;
b0a4e7d8
JL
223u32 libipw_debug_level = 0;
224EXPORT_SYMBOL_GPL(libipw_debug_level);
225static struct proc_dir_entry *libipw_proc = NULL;
b453872c 226
b8d83392 227static int debug_level_proc_show(struct seq_file *m, void *v)
b453872c 228{
b8d83392
AD
229 seq_printf(m, "0x%08X\n", libipw_debug_level);
230 return 0;
b453872c
JG
231}
232
b8d83392
AD
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)
b453872c 240{
262d8e46 241 char buf[] = "0x00000000\n";
b8d83392 242 size_t len = min(sizeof(buf) - 1, count);
b453872c
JG
243 unsigned long val;
244
262d8e46 245 if (copy_from_user(buf, buffer, len))
b453872c 246 return count;
262d8e46
JK
247 buf[len] = 0;
248 if (sscanf(buf, "%li", &val) != 1)
b453872c
JG
249 printk(KERN_INFO DRV_NAME
250 ": %s is not in hex or decimal form.\n", buf);
251 else
b0a4e7d8 252 libipw_debug_level = val;
b453872c 253
262d8e46 254 return strnlen(buf, len);
b453872c 255}
b8d83392
AD
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};
3756162b 265#endif /* CONFIG_LIBIPW_DEBUG */
b453872c 266
b0a4e7d8 267static int __init libipw_init(void)
b453872c 268{
3756162b 269#ifdef CONFIG_LIBIPW_DEBUG
b453872c
JG
270 struct proc_dir_entry *e;
271
b0a4e7d8 272 libipw_debug_level = debug;
151f52f0 273 libipw_proc = proc_mkdir(DRV_PROCNAME, init_net.proc_net);
b0a4e7d8 274 if (libipw_proc == NULL) {
151f52f0 275 LIBIPW_ERROR("Unable to create " DRV_PROCNAME
b453872c
JG
276 " proc directory\n");
277 return -EIO;
278 }
b8d83392
AD
279 e = proc_create("debug_level", S_IRUGO | S_IWUSR, libipw_proc,
280 &debug_level_proc_fops);
b453872c 281 if (!e) {
151f52f0 282 remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
b0a4e7d8 283 libipw_proc = NULL;
b453872c
JG
284 return -EIO;
285 }
3756162b 286#endif /* CONFIG_LIBIPW_DEBUG */
31696160
JK
287
288 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
289 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
b453872c
JG
290
291 return 0;
292}
293
b0a4e7d8 294static void __exit libipw_exit(void)
b453872c 295{
3756162b 296#ifdef CONFIG_LIBIPW_DEBUG
b0a4e7d8
JL
297 if (libipw_proc) {
298 remove_proc_entry("debug_level", libipw_proc);
151f52f0 299 remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
b0a4e7d8 300 libipw_proc = NULL;
b453872c 301 }
3756162b 302#endif /* CONFIG_LIBIPW_DEBUG */
b453872c
JG
303}
304
3756162b 305#ifdef CONFIG_LIBIPW_DEBUG
b453872c
JG
306#include <linux/moduleparam.h>
307module_param(debug, int, 0444);
308MODULE_PARM_DESC(debug, "debug output mask");
3756162b 309#endif /* CONFIG_LIBIPW_DEBUG */
b453872c 310
b0a4e7d8
JL
311module_exit(libipw_exit);
312module_init(libipw_init);