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