GNU Linux-libre 4.14.251-gnu1
[releases.git] / drivers / net / wireless / intel / ipw2x00 / libipw_module.c
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
61 MODULE_VERSION(DRV_VERSION);
62 MODULE_DESCRIPTION(DRV_DESCRIPTION);
63 MODULE_AUTHOR(DRV_COPYRIGHT);
64 MODULE_LICENSE("GPL");
65
66 static struct cfg80211_ops libipw_config_ops = { };
67 static void *libipw_wiphy_privid = &libipw_wiphy_privid;
68
69 static 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
87 static 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
95 void 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 }
108 EXPORT_SYMBOL(libipw_networks_age);
109
110 static 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
121 struct 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
194 failed_free_wiphy:
195         if (!monitor)
196                 wiphy_free(ieee->wdev.wiphy);
197 failed_free_netdev:
198         free_netdev(dev);
199 failed:
200         return NULL;
201 }
202 EXPORT_SYMBOL(alloc_libipw);
203
204 void 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 }
218 EXPORT_SYMBOL(free_libipw);
219
220 #ifdef CONFIG_LIBIPW_DEBUG
221
222 static int debug = 0;
223 u32 libipw_debug_level = 0;
224 EXPORT_SYMBOL_GPL(libipw_debug_level);
225 static struct proc_dir_entry *libipw_proc = NULL;
226
227 static 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
233 static int debug_level_proc_open(struct inode *inode, struct file *file)
234 {
235         return single_open(file, debug_level_proc_show, NULL);
236 }
237
238 static 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
257 static 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
267 static 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", S_IRUGO | S_IWUSR, 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
294 static 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>
307 module_param(debug, int, 0444);
308 MODULE_PARM_DESC(debug, "debug output mask");
309 #endif                          /* CONFIG_LIBIPW_DEBUG */
310
311 module_exit(libipw_exit);
312 module_init(libipw_init);