linux/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
<<
>>
Prefs
   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/config.h>
  35#include <linux/errno.h>
  36#include <linux/if_arp.h>
  37#include <linux/in6.h>
  38#include <linux/in.h>
  39#include <linux/ip.h>
  40#include <linux/kernel.h>
  41#include <linux/module.h>
  42#include <linux/netdevice.h>
  43#include <linux/pci.h>
  44#include <linux/proc_fs.h>
  45#include <linux/skbuff.h>
  46#include <linux/slab.h>
  47#include <linux/tcp.h>
  48#include <linux/types.h>
  49#include <linux/wireless.h>
  50#include <linux/etherdevice.h>
  51#include <asm/uaccess.h>
  52#include <net/arp.h>
  53
  54#include "ieee80211.h"
  55
  56MODULE_DESCRIPTION("802.11 data/management/control stack");
  57MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
  58MODULE_LICENSE("GPL");
  59
  60#define DRV_NAME "ieee80211"
  61
  62static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
  63{
  64        if (ieee->networks)
  65                return 0;
  66
  67        ieee->networks = kcalloc(
  68                MAX_NETWORK_COUNT, sizeof(struct ieee80211_network),
  69                GFP_KERNEL);
  70        if (!ieee->networks) {
  71                printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
  72                       ieee->dev->name);
  73                return -ENOMEM;
  74        }
  75
  76        return 0;
  77}
  78
  79static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
  80{
  81        if (!ieee->networks)
  82                return;
  83        kfree(ieee->networks);
  84        ieee->networks = NULL;
  85}
  86
  87static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
  88{
  89        int i;
  90
  91        INIT_LIST_HEAD(&ieee->network_free_list);
  92        INIT_LIST_HEAD(&ieee->network_list);
  93        for (i = 0; i < MAX_NETWORK_COUNT; i++)
  94                list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
  95}
  96
  97
  98struct net_device *alloc_ieee80211(int sizeof_priv)
  99{
 100        struct ieee80211_device *ieee;
 101        struct net_device *dev;
 102        int i,err;
 103
 104        IEEE80211_DEBUG_INFO("Initializing...\n");
 105
 106        dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
 107        if (!dev) {
 108                IEEE80211_ERROR("Unable to network device.\n");
 109                goto failed;
 110        }
 111
 112        ieee = netdev_priv(dev);
 113        memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv);
 114        ieee->dev = dev;
 115
 116        err = ieee80211_networks_allocate(ieee);
 117        if (err) {
 118                IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
 119                                err);
 120                goto failed;
 121        }
 122        ieee80211_networks_initialize(ieee);
 123
 124
 125        /* Default fragmentation threshold is maximum payload size */
 126        ieee->fts = DEFAULT_FTS;
 127        ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
 128        ieee->open_wep = 1;
 129
 130        /* Default to enabling full open WEP with host based encrypt/decrypt */
 131        ieee->host_encrypt = 1;
 132        ieee->host_decrypt = 1;
 133        ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
 134
 135        INIT_LIST_HEAD(&ieee->crypt_deinit_list);
 136        init_timer(&ieee->crypt_deinit_timer);
 137        ieee->crypt_deinit_timer.data = (unsigned long)ieee;
 138        ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
 139
 140        spin_lock_init(&ieee->lock);
 141        spin_lock_init(&ieee->wpax_suitlist_lock);
 142        spin_lock_init(&ieee->bw_spinlock);
 143        spin_lock_init(&ieee->reorder_spinlock);
 144        //added by WB
 145        atomic_set(&(ieee->atm_chnlop), 0);
 146        atomic_set(&(ieee->atm_swbw), 0);
 147
 148        ieee->wpax_type_set = 0;
 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_support = 1; //defalt support hw security. //use module_param instead.
 156        ieee->hwsec_active = 0; //disable hwsec, switch it on when necessary.
 157
 158        ieee80211_softmac_init(ieee);
 159
 160        ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
 161        if (ieee->pHTInfo == NULL)
 162        {
 163                IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
 164                goto failed;
 165        }
 166        HTUpdateDefaultSetting(ieee);
 167        HTInitializeHTInfo(ieee); //may move to other place.
 168        TSInitialize(ieee);
 169
 170        for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
 171                INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
 172
 173        for (i = 0; i < 17; i++) {
 174          ieee->last_rxseq_num[i] = -1;
 175          ieee->last_rxfrag_num[i] = -1;
 176          ieee->last_packet_time[i] = 0;
 177        }
 178
 179//These function were added to load crypte module autoly
 180        ieee80211_tkip_null();
 181        ieee80211_wep_null();
 182        ieee80211_ccmp_null();
 183
 184        return dev;
 185
 186 failed:
 187        if (dev)
 188                free_netdev(dev);
 189
 190        return NULL;
 191}
 192
 193
 194void free_ieee80211(struct net_device *dev)
 195{
 196        struct ieee80211_device *ieee = netdev_priv(dev);
 197        int i;
 198        //struct list_head *p, *q;
 199//      del_timer_sync(&ieee->SwBwTimer);
 200        kfree(ieee->pHTInfo);
 201        ieee->pHTInfo = NULL;
 202        RemoveAllTS(ieee);
 203        ieee80211_softmac_free(ieee);
 204        del_timer_sync(&ieee->crypt_deinit_timer);
 205        ieee80211_crypt_deinit_entries(ieee, 1);
 206
 207        for (i = 0; i < WEP_KEYS; i++) {
 208                struct ieee80211_crypt_data *crypt = ieee->crypt[i];
 209                if (crypt) {
 210                        if (crypt->ops)
 211                                crypt->ops->deinit(crypt->priv);
 212                        kfree(crypt);
 213                        ieee->crypt[i] = NULL;
 214                }
 215        }
 216
 217        ieee80211_networks_free(ieee);
 218        free_netdev(dev);
 219}
 220
 221#ifdef CONFIG_IEEE80211_DEBUG
 222
 223u32 ieee80211_debug_level;
 224static int debug = \
 225        //                  IEEE80211_DL_INFO   |
 226        //                  IEEE80211_DL_WX     |
 227        //                  IEEE80211_DL_SCAN   |
 228        //                  IEEE80211_DL_STATE  |
 229        //                  IEEE80211_DL_MGMT   |
 230        //                  IEEE80211_DL_FRAG   |
 231        //                  IEEE80211_DL_EAP    |
 232        //                  IEEE80211_DL_DROP   |
 233        //                  IEEE80211_DL_TX     |
 234        //                  IEEE80211_DL_RX     |
 235                            //IEEE80211_DL_QOS    |
 236        //                  IEEE80211_DL_HT     |
 237        //                  IEEE80211_DL_TS     |
 238//                          IEEE80211_DL_BA     |
 239        //                  IEEE80211_DL_REORDER|
 240//                          IEEE80211_DL_TRACE  |
 241                            //IEEE80211_DL_DATA |
 242                            IEEE80211_DL_ERR      //awayls open this flags to show error out
 243                            ;
 244struct proc_dir_entry *ieee80211_proc;
 245
 246static int show_debug_level(struct seq_file *m, void *v)
 247{
 248        return seq_printf(m, "0x%08X\n", ieee80211_debug_level);
 249}
 250
 251static ssize_t write_debug_level(struct file *file, const char __user *buffer,
 252                             size_t count, loff_t *ppos)
 253{
 254        unsigned long val;
 255        int err = kstrtoul_from_user(buffer, count, 0, &val);
 256        if (err)
 257                return err;
 258        ieee80211_debug_level = val;
 259        return count;
 260}
 261
 262static int open_debug_level(struct inode *inode, struct file *file)
 263{
 264        return single_open(file, show_debug_level, NULL);
 265}
 266
 267static const struct file_operations fops = {
 268        .open = open_debug_level,
 269        .read = seq_read,
 270        .llseek = seq_lseek,
 271        .write = write_debug_level
 272};
 273
 274int __init ieee80211_debug_init(void)
 275{
 276        struct proc_dir_entry *e;
 277
 278        ieee80211_debug_level = debug;
 279
 280        ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
 281        if (ieee80211_proc == NULL) {
 282                IEEE80211_ERROR("Unable to create " DRV_NAME
 283                                " proc directory\n");
 284                return -EIO;
 285        }
 286        e = proc_create("debug_level", S_IRUGO | S_IWUSR, 
 287                              ieee80211_proc, &fops);
 288        if (!e) {
 289                remove_proc_entry(DRV_NAME, init_net.proc_net);
 290                ieee80211_proc = NULL;
 291                return -EIO;
 292        }
 293        return 0;
 294}
 295
 296void __exit ieee80211_debug_exit(void)
 297{
 298        if (ieee80211_proc) {
 299                remove_proc_entry("debug_level", ieee80211_proc);
 300                remove_proc_entry(DRV_NAME, init_net.proc_net);
 301                ieee80211_proc = NULL;
 302        }
 303}
 304
 305#include <linux/moduleparam.h>
 306module_param(debug, int, 0444);
 307MODULE_PARM_DESC(debug, "debug output mask");
 308#endif
 309