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