1 // SPDX-License-Identifier: GPL-2.0 2 /******************************************************************************* 3 * 4 * Copyright(c) 2004 Intel Corporation. All rights reserved. 5 * 6 * Portions of this file are based on the WEP enablement code provided by the 7 * Host AP project hostap-drivers v0.1.3 8 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen 9 * <jkmaline@cc.hut.fi> 10 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> 11 * 12 * Contact Information: 13 * James P. Ketrenos <ipw2100-admin@linux.intel.com> 14 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 15 * 16 ******************************************************************************/ 17 18 #include <linux/compiler.h> 19 #include <linux/errno.h> 20 #include <linux/if_arp.h> 21 #include <linux/in6.h> 22 #include <linux/in.h> 23 #include <linux/ip.h> 24 #include <linux/kernel.h> 25 #include <linux/module.h> 26 #include <linux/netdevice.h> 27 #include <linux/pci.h> 28 #include <linux/proc_fs.h> 29 #include <linux/skbuff.h> 30 #include <linux/slab.h> 31 #include <linux/tcp.h> 32 #include <linux/types.h> 33 #include <linux/wireless.h> 34 #include <linux/etherdevice.h> 35 #include <linux/uaccess.h> 36 #include <net/arp.h> 37 38 #include "ieee80211.h" 39 40 MODULE_DESCRIPTION("802.11 data/management/control stack"); 41 MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>"); 42 MODULE_LICENSE("GPL"); 43 44 #define DRV_NAME "ieee80211" 45 46 static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) 47 { 48 if (ieee->networks) 49 return 0; 50 51 ieee->networks = kcalloc(MAX_NETWORK_COUNT, 52 sizeof(struct ieee80211_network), 53 GFP_KERNEL); 54 if (!ieee->networks) { 55 netdev_warn(ieee->dev, "Out of memory allocating beacons\n"); 56 return -ENOMEM; 57 } 58 59 return 0; 60 } 61 62 static inline void ieee80211_networks_free(struct ieee80211_device *ieee) 63 { 64 if (!ieee->networks) 65 return; 66 kfree(ieee->networks); 67 ieee->networks = NULL; 68 } 69 70 static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee) 71 { 72 int i; 73 74 INIT_LIST_HEAD(&ieee->network_free_list); 75 INIT_LIST_HEAD(&ieee->network_list); 76 for (i = 0; i < MAX_NETWORK_COUNT; i++) 77 list_add_tail(&ieee->networks[i].list, &ieee->network_free_list); 78 } 79 80 struct net_device *alloc_ieee80211(int sizeof_priv) 81 { 82 struct ieee80211_device *ieee; 83 struct net_device *dev; 84 int i, err; 85 86 IEEE80211_DEBUG_INFO("Initializing...\n"); 87 88 dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv); 89 if (!dev) { 90 IEEE80211_ERROR("Unable to network device.\n"); 91 goto failed; 92 } 93 94 ieee = netdev_priv(dev); 95 ieee->dev = dev; 96 97 err = ieee80211_networks_allocate(ieee); 98 if (err) { 99 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", 100 err); 101 goto failed; 102 } 103 ieee80211_networks_initialize(ieee); 104 105 /* Default fragmentation threshold is maximum payload size */ 106 ieee->fts = DEFAULT_FTS; 107 ieee->scan_age = DEFAULT_MAX_SCAN_AGE; 108 ieee->open_wep = 1; 109 110 /* Default to enabling full open WEP with host based encrypt/decrypt */ 111 ieee->host_encrypt = 1; 112 ieee->host_decrypt = 1; 113 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ 114 115 INIT_LIST_HEAD(&ieee->crypt_deinit_list); 116 timer_setup(&ieee->crypt_deinit_timer, ieee80211_crypt_deinit_handler, 117 0); 118 119 spin_lock_init(&ieee->lock); 120 spin_lock_init(&ieee->wpax_suitlist_lock); 121 spin_lock_init(&ieee->bw_spinlock); 122 spin_lock_init(&ieee->reorder_spinlock); 123 /* added by WB */ 124 atomic_set(&ieee->atm_chnlop, 0); 125 atomic_set(&ieee->atm_swbw, 0); 126 127 ieee->wpax_type_set = 0; 128 ieee->wpa_enabled = 0; 129 ieee->tkip_countermeasures = 0; 130 ieee->drop_unencrypted = 0; 131 ieee->privacy_invoked = 0; 132 ieee->ieee802_1x = 1; 133 ieee->raw_tx = 0; 134 //ieee->hwsec_support = 1; //defalt support hw security. //use module_param instead. 135 ieee->hwsec_active = 0; /* disable hwsec, switch it on when necessary. */ 136 137 ieee80211_softmac_init(ieee); 138 139 ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL); 140 if (!ieee->pHTInfo) { 141 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n"); 142 143 /* By this point in code ieee80211_networks_allocate() has been 144 * successfully called so the memory allocated should be freed 145 */ 146 ieee80211_networks_free(ieee); 147 goto failed; 148 } 149 HTUpdateDefaultSetting(ieee); 150 HTInitializeHTInfo(ieee); /* may move to other place. */ 151 TSInitialize(ieee); 152 153 for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) 154 INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]); 155 156 for (i = 0; i < 17; i++) { 157 ieee->last_rxseq_num[i] = -1; 158 ieee->last_rxfrag_num[i] = -1; 159 ieee->last_packet_time[i] = 0; 160 } 161 162 return dev; 163 164 failed: 165 if (dev) 166 free_netdev(dev); 167 168 return NULL; 169 } 170 171 void free_ieee80211(struct net_device *dev) 172 { 173 struct ieee80211_device *ieee = netdev_priv(dev); 174 int i; 175 /* struct list_head *p, *q; */ 176 // del_timer_sync(&ieee->SwBwTimer); 177 kfree(ieee->pHTInfo); 178 ieee->pHTInfo = NULL; 179 RemoveAllTS(ieee); 180 ieee80211_softmac_free(ieee); 181 del_timer_sync(&ieee->crypt_deinit_timer); 182 ieee80211_crypt_deinit_entries(ieee, 1); 183 184 for (i = 0; i < WEP_KEYS; i++) { 185 struct ieee80211_crypt_data *crypt = ieee->crypt[i]; 186 187 if (crypt) { 188 if (crypt->ops) 189 crypt->ops->deinit(crypt->priv); 190 kfree(crypt); 191 ieee->crypt[i] = NULL; 192 } 193 } 194 195 ieee80211_networks_free(ieee); 196 free_netdev(dev); 197 } 198 199 #ifdef CONFIG_IEEE80211_DEBUG 200 201 u32 ieee80211_debug_level; 202 static int debug = // IEEE80211_DL_INFO | 203 // IEEE80211_DL_WX | 204 // IEEE80211_DL_SCAN | 205 // IEEE80211_DL_STATE | 206 // IEEE80211_DL_MGMT | 207 // IEEE80211_DL_FRAG | 208 // IEEE80211_DL_EAP | 209 // IEEE80211_DL_DROP | 210 // IEEE80211_DL_TX | 211 // IEEE80211_DL_RX | 212 //IEEE80211_DL_QOS | 213 // IEEE80211_DL_HT | 214 // IEEE80211_DL_TS | 215 // IEEE80211_DL_BA | 216 // IEEE80211_DL_REORDER| 217 // IEEE80211_DL_TRACE | 218 //IEEE80211_DL_DATA | 219 IEEE80211_DL_ERR /* awayls open this flags to show error out */ 220 ; 221 static struct proc_dir_entry *ieee80211_proc; 222 223 static int show_debug_level(struct seq_file *m, void *v) 224 { 225 seq_printf(m, "0x%08X\n", ieee80211_debug_level); 226 227 return 0; 228 } 229 230 static ssize_t write_debug_level(struct file *file, const char __user *buffer, 231 size_t count, loff_t *ppos) 232 { 233 unsigned long val; 234 int err = kstrtoul_from_user(buffer, count, 0, &val); 235 236 if (err) 237 return err; 238 ieee80211_debug_level = val; 239 return count; 240 } 241 242 static int open_debug_level(struct inode *inode, struct file *file) 243 { 244 return single_open(file, show_debug_level, NULL); 245 } 246 247 static const struct proc_ops debug_level_proc_ops = { 248 .proc_open = open_debug_level, 249 .proc_read = seq_read, 250 .proc_lseek = seq_lseek, 251 .proc_write = write_debug_level, 252 .proc_release = single_release, 253 }; 254 255 int __init ieee80211_debug_init(void) 256 { 257 struct proc_dir_entry *e; 258 259 ieee80211_debug_level = debug; 260 261 ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net); 262 if (!ieee80211_proc) { 263 IEEE80211_ERROR("Unable to create " DRV_NAME 264 " proc directory\n"); 265 return -EIO; 266 } 267 e = proc_create("debug_level", 0644, ieee80211_proc, &debug_level_proc_ops); 268 if (!e) { 269 remove_proc_entry(DRV_NAME, init_net.proc_net); 270 ieee80211_proc = NULL; 271 return -EIO; 272 } 273 return 0; 274 } 275 276 void ieee80211_debug_exit(void) 277 { 278 if (ieee80211_proc) { 279 remove_proc_entry("debug_level", ieee80211_proc); 280 remove_proc_entry(DRV_NAME, init_net.proc_net); 281 ieee80211_proc = NULL; 282 } 283 } 284 285 module_param(debug, int, 0444); 286 MODULE_PARM_DESC(debug, "debug output mask"); 287 #endif 288