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 <asm/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 int libipw_change_mtu(struct net_device *dev, int new_mtu) 122 { 123 if ((new_mtu < 68) || (new_mtu > LIBIPW_DATA_LEN)) 124 return -EINVAL; 125 dev->mtu = new_mtu; 126 return 0; 127 } 128 EXPORT_SYMBOL(libipw_change_mtu); 129 130 struct net_device *alloc_libipw(int sizeof_priv, int monitor) 131 { 132 struct libipw_device *ieee; 133 struct net_device *dev; 134 int err; 135 136 LIBIPW_DEBUG_INFO("Initializing...\n"); 137 138 dev = alloc_etherdev(sizeof(struct libipw_device) + sizeof_priv); 139 if (!dev) 140 goto failed; 141 142 ieee = netdev_priv(dev); 143 144 ieee->dev = dev; 145 146 if (!monitor) { 147 ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0); 148 if (!ieee->wdev.wiphy) { 149 LIBIPW_ERROR("Unable to allocate wiphy.\n"); 150 goto failed_free_netdev; 151 } 152 153 ieee->dev->ieee80211_ptr = &ieee->wdev; 154 ieee->wdev.iftype = NL80211_IFTYPE_STATION; 155 156 /* Fill-out wiphy structure bits we know... Not enough info 157 here to call set_wiphy_dev or set MAC address or channel info 158 -- have to do that in ->ndo_init... */ 159 ieee->wdev.wiphy->privid = libipw_wiphy_privid; 160 161 ieee->wdev.wiphy->max_scan_ssids = 1; 162 ieee->wdev.wiphy->max_scan_ie_len = 0; 163 ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) 164 | BIT(NL80211_IFTYPE_ADHOC); 165 } 166 167 err = libipw_networks_allocate(ieee); 168 if (err) { 169 LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err); 170 goto failed_free_wiphy; 171 } 172 libipw_networks_initialize(ieee); 173 174 /* Default fragmentation threshold is maximum payload size */ 175 ieee->fts = DEFAULT_FTS; 176 ieee->rts = DEFAULT_FTS; 177 ieee->scan_age = DEFAULT_MAX_SCAN_AGE; 178 ieee->open_wep = 1; 179 180 /* Default to enabling full open WEP with host based encrypt/decrypt */ 181 ieee->host_encrypt = 1; 182 ieee->host_decrypt = 1; 183 ieee->host_mc_decrypt = 1; 184 185 /* Host fragmentation in Open mode. Default is enabled. 186 * Note: host fragmentation is always enabled if host encryption 187 * is enabled. For cards can do hardware encryption, they must do 188 * hardware fragmentation as well. So we don't need a variable 189 * like host_enc_frag. */ 190 ieee->host_open_frag = 1; 191 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ 192 193 spin_lock_init(&ieee->lock); 194 195 lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock); 196 197 ieee->wpa_enabled = 0; 198 ieee->drop_unencrypted = 0; 199 ieee->privacy_invoked = 0; 200 201 return dev; 202 203 failed_free_wiphy: 204 if (!monitor) 205 wiphy_free(ieee->wdev.wiphy); 206 failed_free_netdev: 207 free_netdev(dev); 208 failed: 209 return NULL; 210 } 211 EXPORT_SYMBOL(alloc_libipw); 212 213 void free_libipw(struct net_device *dev, int monitor) 214 { 215 struct libipw_device *ieee = netdev_priv(dev); 216 217 lib80211_crypt_info_free(&ieee->crypt_info); 218 219 libipw_networks_free(ieee); 220 221 /* free cfg80211 resources */ 222 if (!monitor) 223 wiphy_free(ieee->wdev.wiphy); 224 225 free_netdev(dev); 226 } 227 EXPORT_SYMBOL(free_libipw); 228 229 #ifdef CONFIG_LIBIPW_DEBUG 230 231 static int debug = 0; 232 u32 libipw_debug_level = 0; 233 EXPORT_SYMBOL_GPL(libipw_debug_level); 234 static struct proc_dir_entry *libipw_proc = NULL; 235 236 static int debug_level_proc_show(struct seq_file *m, void *v) 237 { 238 seq_printf(m, "0x%08X\n", libipw_debug_level); 239 return 0; 240 } 241 242 static int debug_level_proc_open(struct inode *inode, struct file *file) 243 { 244 return single_open(file, debug_level_proc_show, NULL); 245 } 246 247 static ssize_t debug_level_proc_write(struct file *file, 248 const char __user *buffer, size_t count, loff_t *pos) 249 { 250 char buf[] = "0x00000000\n"; 251 size_t len = min(sizeof(buf) - 1, count); 252 unsigned long val; 253 254 if (copy_from_user(buf, buffer, len)) 255 return count; 256 buf[len] = 0; 257 if (sscanf(buf, "%li", &val) != 1) 258 printk(KERN_INFO DRV_NAME 259 ": %s is not in hex or decimal form.\n", buf); 260 else 261 libipw_debug_level = val; 262 263 return strnlen(buf, len); 264 } 265 266 static const struct file_operations debug_level_proc_fops = { 267 .owner = THIS_MODULE, 268 .open = debug_level_proc_open, 269 .read = seq_read, 270 .llseek = seq_lseek, 271 .release = single_release, 272 .write = debug_level_proc_write, 273 }; 274 #endif /* CONFIG_LIBIPW_DEBUG */ 275 276 static int __init libipw_init(void) 277 { 278 #ifdef CONFIG_LIBIPW_DEBUG 279 struct proc_dir_entry *e; 280 281 libipw_debug_level = debug; 282 libipw_proc = proc_mkdir(DRV_PROCNAME, init_net.proc_net); 283 if (libipw_proc == NULL) { 284 LIBIPW_ERROR("Unable to create " DRV_PROCNAME 285 " proc directory\n"); 286 return -EIO; 287 } 288 e = proc_create("debug_level", S_IRUGO | S_IWUSR, libipw_proc, 289 &debug_level_proc_fops); 290 if (!e) { 291 remove_proc_entry(DRV_PROCNAME, init_net.proc_net); 292 libipw_proc = NULL; 293 return -EIO; 294 } 295 #endif /* CONFIG_LIBIPW_DEBUG */ 296 297 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); 298 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); 299 300 return 0; 301 } 302 303 static void __exit libipw_exit(void) 304 { 305 #ifdef CONFIG_LIBIPW_DEBUG 306 if (libipw_proc) { 307 remove_proc_entry("debug_level", libipw_proc); 308 remove_proc_entry(DRV_PROCNAME, init_net.proc_net); 309 libipw_proc = NULL; 310 } 311 #endif /* CONFIG_LIBIPW_DEBUG */ 312 } 313 314 #ifdef CONFIG_LIBIPW_DEBUG 315 #include <linux/moduleparam.h> 316 module_param(debug, int, 0444); 317 MODULE_PARM_DESC(debug, "debug output mask"); 318 #endif /* CONFIG_LIBIPW_DEBUG */ 319 320 module_exit(libipw_exit); 321 module_init(libipw_init); 322