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 return -ENOMEM; 77 78 return 0; 79} 80 81static inline void rtllib_networks_free(struct rtllib_device *ieee) 82{ 83 if (!ieee->networks) 84 return; 85 kfree(ieee->networks); 86 ieee->networks = NULL; 87} 88 89static inline void rtllib_networks_initialize(struct rtllib_device *ieee) 90{ 91 int i; 92 93 INIT_LIST_HEAD(&ieee->network_free_list); 94 INIT_LIST_HEAD(&ieee->network_list); 95 for (i = 0; i < MAX_NETWORK_COUNT; i++) 96 list_add_tail(&ieee->networks[i].list, 97 &ieee->network_free_list); 98} 99 100struct net_device *alloc_rtllib(int sizeof_priv) 101{ 102 struct rtllib_device *ieee = NULL; 103 struct net_device *dev; 104 int i, err; 105 106 RTLLIB_DEBUG_INFO("Initializing...\n"); 107 108 dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv); 109 if (!dev) { 110 RTLLIB_ERROR("Unable to network device.\n"); 111 return NULL; 112 } 113 ieee = (struct rtllib_device *)netdev_priv_rsl(dev); 114 memset(ieee, 0, sizeof(struct rtllib_device)+sizeof_priv); 115 ieee->dev = dev; 116 117 err = rtllib_networks_allocate(ieee); 118 if (err) { 119 RTLLIB_ERROR("Unable to allocate beacon storage: %d\n", 120 err); 121 goto failed; 122 } 123 rtllib_networks_initialize(ieee); 124 125 126 /* Default fragmentation threshold is maximum payload size */ 127 ieee->fts = DEFAULT_FTS; 128 ieee->scan_age = DEFAULT_MAX_SCAN_AGE; 129 ieee->open_wep = 1; 130 131 /* Default to enabling full open WEP with host based encrypt/decrypt */ 132 ieee->host_encrypt = 1; 133 ieee->host_decrypt = 1; 134 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ 135 136 ieee->rtllib_ap_sec_type = rtllib_ap_sec_type; 137 138 spin_lock_init(&ieee->lock); 139 spin_lock_init(&ieee->wpax_suitlist_lock); 140 spin_lock_init(&ieee->bw_spinlock); 141 spin_lock_init(&ieee->reorder_spinlock); 142 atomic_set(&(ieee->atm_chnlop), 0); 143 atomic_set(&(ieee->atm_swbw), 0); 144 145 /* SAM FIXME */ 146 lib80211_crypt_info_init(&ieee->crypt_info, "RTLLIB", &ieee->lock); 147 148 ieee->bHalfNMode = false; 149 ieee->wpa_enabled = 0; 150 ieee->tkip_countermeasures = 0; 151 ieee->drop_unencrypted = 0; 152 ieee->privacy_invoked = 0; 153 ieee->ieee802_1x = 1; 154 ieee->raw_tx = 0; 155 ieee->hwsec_active = 0; 156 157 memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32); 158 rtllib_softmac_init(ieee); 159 160 ieee->pHTInfo = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL); 161 if (ieee->pHTInfo == NULL) 162 return NULL; 163 164 HTUpdateDefaultSetting(ieee); 165 HTInitializeHTInfo(ieee); 166 TSInitialize(ieee); 167 for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) 168 INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]); 169 170 for (i = 0; i < 17; i++) { 171 ieee->last_rxseq_num[i] = -1; 172 ieee->last_rxfrag_num[i] = -1; 173 ieee->last_packet_time[i] = 0; 174 } 175 176 return dev; 177 178 failed: 179 free_netdev(dev); 180 return NULL; 181} 182EXPORT_SYMBOL(alloc_rtllib); 183 184void free_rtllib(struct net_device *dev) 185{ 186 struct rtllib_device *ieee = (struct rtllib_device *) 187 netdev_priv_rsl(dev); 188 189 kfree(ieee->pHTInfo); 190 ieee->pHTInfo = NULL; 191 rtllib_softmac_free(ieee); 192 193 lib80211_crypt_info_free(&ieee->crypt_info); 194 195 rtllib_networks_free(ieee); 196 free_netdev(dev); 197} 198EXPORT_SYMBOL(free_rtllib); 199 200u32 rtllib_debug_level; 201static int debug = RTLLIB_DL_ERR; 202static struct proc_dir_entry *rtllib_proc; 203 204static int show_debug_level(struct seq_file *m, void *v) 205{ 206 seq_printf(m, "0x%08X\n", rtllib_debug_level); 207 208 return 0; 209} 210 211static ssize_t write_debug_level(struct file *file, const char __user *buffer, 212 size_t count, loff_t *ppos) 213{ 214 unsigned long val; 215 int err = kstrtoul_from_user(buffer, count, 0, &val); 216 217 if (err) 218 return err; 219 rtllib_debug_level = val; 220 return count; 221} 222 223static int open_debug_level(struct inode *inode, struct file *file) 224{ 225 return single_open(file, show_debug_level, NULL); 226} 227 228static const struct file_operations fops = { 229 .open = open_debug_level, 230 .read = seq_read, 231 .llseek = seq_lseek, 232 .write = write_debug_level, 233 .release = single_release, 234}; 235 236static int __init rtllib_init(void) 237{ 238 struct proc_dir_entry *e; 239 240 rtllib_debug_level = debug; 241 rtllib_proc = proc_mkdir(DRV_NAME, init_net.proc_net); 242 if (rtllib_proc == NULL) { 243 RTLLIB_ERROR("Unable to create " DRV_NAME 244 " proc directory\n"); 245 return -EIO; 246 } 247 e = proc_create("debug_level", S_IRUGO | S_IWUSR, rtllib_proc, &fops); 248 if (!e) { 249 remove_proc_entry(DRV_NAME, init_net.proc_net); 250 rtllib_proc = NULL; 251 return -EIO; 252 } 253 return 0; 254} 255 256static void __exit rtllib_exit(void) 257{ 258 if (rtllib_proc) { 259 remove_proc_entry("debug_level", rtllib_proc); 260 remove_proc_entry(DRV_NAME, init_net.proc_net); 261 rtllib_proc = NULL; 262 } 263} 264 265module_init(rtllib_init); 266module_exit(rtllib_exit); 267 268MODULE_LICENSE("GPL"); 269