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 /* These function were added to load crypte module autoly */ 163 ieee80211_tkip_null(); 164 165 return dev; 166 167 failed: 168 if (dev) 169 free_netdev(dev); 170 171 return NULL; 172 } 173 174 void free_ieee80211(struct net_device *dev) 175 { 176 struct ieee80211_device *ieee = netdev_priv(dev); 177 int i; 178 /* struct list_head *p, *q; */ 179 // del_timer_sync(&ieee->SwBwTimer); 180 kfree(ieee->pHTInfo); 181 ieee->pHTInfo = NULL; 182 RemoveAllTS(ieee); 183 ieee80211_softmac_free(ieee); 184 del_timer_sync(&ieee->crypt_deinit_timer); 185 ieee80211_crypt_deinit_entries(ieee, 1); 186 187 for (i = 0; i < WEP_KEYS; i++) { 188 struct ieee80211_crypt_data *crypt = ieee->crypt[i]; 189 190 if (crypt) { 191 if (crypt->ops) 192 crypt->ops->deinit(crypt->priv); 193 kfree(crypt); 194 ieee->crypt[i] = NULL; 195 } 196 } 197 198 ieee80211_networks_free(ieee); 199 free_netdev(dev); 200 } 201 202 #ifdef CONFIG_IEEE80211_DEBUG 203 204 u32 ieee80211_debug_level; 205 static int debug = // IEEE80211_DL_INFO | 206 // IEEE80211_DL_WX | 207 // IEEE80211_DL_SCAN | 208 // IEEE80211_DL_STATE | 209 // IEEE80211_DL_MGMT | 210 // IEEE80211_DL_FRAG | 211 // IEEE80211_DL_EAP | 212 // IEEE80211_DL_DROP | 213 // IEEE80211_DL_TX | 214 // IEEE80211_DL_RX | 215 //IEEE80211_DL_QOS | 216 // IEEE80211_DL_HT | 217 // IEEE80211_DL_TS | 218 // IEEE80211_DL_BA | 219 // IEEE80211_DL_REORDER| 220 // IEEE80211_DL_TRACE | 221 //IEEE80211_DL_DATA | 222 IEEE80211_DL_ERR /* awayls open this flags to show error out */ 223 ; 224 static struct proc_dir_entry *ieee80211_proc; 225 226 static int show_debug_level(struct seq_file *m, void *v) 227 { 228 seq_printf(m, "0x%08X\n", ieee80211_debug_level); 229 230 return 0; 231 } 232 233 static ssize_t write_debug_level(struct file *file, const char __user *buffer, 234 size_t count, loff_t *ppos) 235 { 236 unsigned long val; 237 int err = kstrtoul_from_user(buffer, count, 0, &val); 238 239 if (err) 240 return err; 241 ieee80211_debug_level = val; 242 return count; 243 } 244 245 static int open_debug_level(struct inode *inode, struct file *file) 246 { 247 return single_open(file, show_debug_level, NULL); 248 } 249 250 static const struct proc_ops debug_level_proc_ops = { 251 .proc_open = open_debug_level, 252 .proc_read = seq_read, 253 .proc_lseek = seq_lseek, 254 .proc_write = write_debug_level, 255 .proc_release = single_release, 256 }; 257 258 int __init ieee80211_debug_init(void) 259 { 260 struct proc_dir_entry *e; 261 262 ieee80211_debug_level = debug; 263 264 ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net); 265 if (!ieee80211_proc) { 266 IEEE80211_ERROR("Unable to create " DRV_NAME 267 " proc directory\n"); 268 return -EIO; 269 } 270 e = proc_create("debug_level", 0644, ieee80211_proc, &debug_level_proc_ops); 271 if (!e) { 272 remove_proc_entry(DRV_NAME, init_net.proc_net); 273 ieee80211_proc = NULL; 274 return -EIO; 275 } 276 return 0; 277 } 278 279 void ieee80211_debug_exit(void) 280 { 281 if (ieee80211_proc) { 282 remove_proc_entry("debug_level", ieee80211_proc); 283 remove_proc_entry(DRV_NAME, init_net.proc_net); 284 ieee80211_proc = NULL; 285 } 286 } 287 288 module_param(debug, int, 0444); 289 MODULE_PARM_DESC(debug, "debug output mask"); 290 #endif 291