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 <linux/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        setup_timer(&ieee->crypt_deinit_timer,
 137                    ieee80211_crypt_deinit_handler, (unsigned long)ieee);
 138
 139        spin_lock_init(&ieee->lock);
 140        spin_lock_init(&ieee->wpax_suitlist_lock);
 141        spin_lock_init(&ieee->bw_spinlock);
 142        spin_lock_init(&ieee->reorder_spinlock);
 143        /* added by WB */
 144        atomic_set(&(ieee->atm_chnlop), 0);
 145        atomic_set(&(ieee->atm_swbw), 0);
 146
 147        ieee->wpax_type_set = 0;
 148        ieee->wpa_enabled = 0;
 149        ieee->tkip_countermeasures = 0;
 150        ieee->drop_unencrypted = 0;
 151        ieee->privacy_invoked = 0;
 152        ieee->ieee802_1x = 1;
 153        ieee->raw_tx = 0;
 154        //ieee->hwsec_support = 1; //defalt support hw security. //use module_param instead.
 155        ieee->hwsec_active = 0; /* disable hwsec, switch it on when necessary. */
 156
 157        ieee80211_softmac_init(ieee);
 158
 159        ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
 160        if (ieee->pHTInfo == NULL)
 161        {
 162                IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
 163                goto failed;
 164        }
 165        HTUpdateDefaultSetting(ieee);
 166        HTInitializeHTInfo(ieee); /* may move to other place. */
 167        TSInitialize(ieee);
 168
 169        for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
 170                INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
 171
 172        for (i = 0; i < 17; i++) {
 173          ieee->last_rxseq_num[i] = -1;
 174          ieee->last_rxfrag_num[i] = -1;
 175          ieee->last_packet_time[i] = 0;
 176        }
 177
 178/* These function were added to load crypte module autoly */
 179        ieee80211_tkip_null();
 180        ieee80211_ccmp_null();
 181
 182        return dev;
 183
 184 failed:
 185        if (dev)
 186                free_netdev(dev);
 187
 188        return NULL;
 189}
 190
 191
 192void free_ieee80211(struct net_device *dev)
 193{
 194        struct ieee80211_device *ieee = netdev_priv(dev);
 195        int i;
 196        /* struct list_head *p, *q; */
 197//      del_timer_sync(&ieee->SwBwTimer);
 198        kfree(ieee->pHTInfo);
 199        ieee->pHTInfo = NULL;
 200        RemoveAllTS(ieee);
 201        ieee80211_softmac_free(ieee);
 202        del_timer_sync(&ieee->crypt_deinit_timer);
 203        ieee80211_crypt_deinit_entries(ieee, 1);
 204
 205        for (i = 0; i < WEP_KEYS; i++) {
 206                struct ieee80211_crypt_data *crypt = ieee->crypt[i];
 207                if (crypt) {
 208                        if (crypt->ops)
 209                                crypt->ops->deinit(crypt->priv);
 210                        kfree(crypt);
 211                        ieee->crypt[i] = NULL;
 212                }
 213        }
 214
 215        ieee80211_networks_free(ieee);
 216        free_netdev(dev);
 217}
 218
 219#ifdef CONFIG_IEEE80211_DEBUG
 220
 221u32 ieee80211_debug_level;
 222static int debug = \
 223        //                  IEEE80211_DL_INFO   |
 224        //                  IEEE80211_DL_WX     |
 225        //                  IEEE80211_DL_SCAN   |
 226        //                  IEEE80211_DL_STATE  |
 227        //                  IEEE80211_DL_MGMT   |
 228        //                  IEEE80211_DL_FRAG   |
 229        //                  IEEE80211_DL_EAP    |
 230        //                  IEEE80211_DL_DROP   |
 231        //                  IEEE80211_DL_TX     |
 232        //                  IEEE80211_DL_RX     |
 233                            //IEEE80211_DL_QOS    |
 234        //                  IEEE80211_DL_HT     |
 235        //                  IEEE80211_DL_TS     |
 236//                          IEEE80211_DL_BA     |
 237        //                  IEEE80211_DL_REORDER|
 238//                          IEEE80211_DL_TRACE  |
 239                            //IEEE80211_DL_DATA |
 240                            IEEE80211_DL_ERR      /* awayls open this flags to show error out */
 241                            ;
 242static struct proc_dir_entry *ieee80211_proc;
 243
 244static int show_debug_level(struct seq_file *m, void *v)
 245{
 246        seq_printf(m, "0x%08X\n", ieee80211_debug_level);
 247
 248        return 0;
 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        .release = single_release,
 273};
 274
 275int __init ieee80211_debug_init(void)
 276{
 277        struct proc_dir_entry *e;
 278
 279        ieee80211_debug_level = debug;
 280
 281        ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
 282        if (ieee80211_proc == NULL) {
 283                IEEE80211_ERROR("Unable to create " DRV_NAME
 284                                " proc directory\n");
 285                return -EIO;
 286        }
 287        e = proc_create("debug_level", S_IRUGO | S_IWUSR,
 288                              ieee80211_proc, &fops);
 289        if (!e) {
 290                remove_proc_entry(DRV_NAME, init_net.proc_net);
 291                ieee80211_proc = NULL;
 292                return -EIO;
 293        }
 294        return 0;
 295}
 296
 297void __exit ieee80211_debug_exit(void)
 298{
 299        if (ieee80211_proc) {
 300                remove_proc_entry("debug_level", ieee80211_proc);
 301                remove_proc_entry(DRV_NAME, init_net.proc_net);
 302                ieee80211_proc = NULL;
 303        }
 304}
 305
 306module_param(debug, int, 0444);
 307MODULE_PARM_DESC(debug, "debug output mask");
 308#endif
 309