linux/drivers/staging/wlags49_h2/wl_main.c
<<
>>
Prefs
   1/*******************************************************************************
   2 * Agere Systems Inc.
   3 * Wireless device driver for Linux (wlags49).
   4 *
   5 * Copyright (c) 1998-2003 Agere Systems Inc.
   6 * All rights reserved.
   7 *   http://www.agere.com
   8 *
   9 * Initially developed by TriplePoint, Inc.
  10 *   http://www.triplepoint.com
  11 *
  12 *------------------------------------------------------------------------------
  13 *
  14 *   This file contains the main driver entry points and other adapter
  15 *   specific routines.
  16 *
  17 *------------------------------------------------------------------------------
  18 *
  19 * SOFTWARE LICENSE
  20 *
  21 * This software is provided subject to the following terms and conditions,
  22 * which you should read carefully before using the software.  Using this
  23 * software indicates your acceptance of these terms and conditions.  If you do
  24 * not agree with these terms and conditions, do not use the software.
  25 *
  26 * Copyright © 2003 Agere Systems Inc.
  27 * All rights reserved.
  28 *
  29 * Redistribution and use in source or binary forms, with or without
  30 * modifications, are permitted provided that the following conditions are met:
  31 *
  32 * . Redistributions of source code must retain the above copyright notice, this
  33 *    list of conditions and the following Disclaimer as comments in the code as
  34 *    well as in the documentation and/or other materials provided with the
  35 *    distribution.
  36 *
  37 * . Redistributions in binary form must reproduce the above copyright notice,
  38 *    this list of conditions and the following Disclaimer in the documentation
  39 *    and/or other materials provided with the distribution.
  40 *
  41 * . Neither the name of Agere Systems Inc. nor the names of the contributors
  42 *    may be used to endorse or promote products derived from this software
  43 *    without specific prior written permission.
  44 *
  45 * Disclaimer
  46 *
  47 * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
  48 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  49 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  50 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
  51 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
  52 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  54 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  55 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
  56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  58 * DAMAGE.
  59 *
  60 ******************************************************************************/
  61
  62/*******************************************************************************
  63 *  constant definitions
  64 ******************************************************************************/
  65
  66/* Allow support for calling system fcns to access F/W image file */
  67#define __KERNEL_SYSCALLS__
  68
  69/*******************************************************************************
  70 *  include files
  71 ******************************************************************************/
  72#include <wl_version.h>
  73
  74#include <linux/module.h>
  75#include <linux/proc_fs.h>
  76#include <linux/seq_file.h>
  77#include <linux/types.h>
  78#include <linux/kernel.h>
  79// #include <linux/sched.h>
  80// #include <linux/ptrace.h>
  81// #include <linux/slab.h>
  82// #include <linux/ctype.h>
  83// #include <linux/string.h>
  84// #include <linux/timer.h>
  85//#include <linux/interrupt.h>
  86// #include <linux/tqueue.h>
  87// #include <linux/in.h>
  88// #include <linux/delay.h>
  89// #include <asm/io.h>
  90// // #include <asm/bitops.h>
  91#include <linux/unistd.h>
  92#include <asm/uaccess.h>
  93
  94#include <linux/netdevice.h>
  95#include <linux/etherdevice.h>
  96// #include <linux/skbuff.h>
  97// #include <linux/if_arp.h>
  98// #include <linux/ioport.h>
  99
 100#define BIN_DL 0
 101#if BIN_DL
 102#include <linux/vmalloc.h>
 103#endif // BIN_DL
 104
 105
 106#include <debug.h>
 107
 108#include <hcf.h>
 109#include <dhf.h>
 110//in order to get around:: wl_main.c:2229: `HREG_EV_RDMAD' undeclared (first use in this function)
 111#include <hcfdef.h>
 112
 113#include <wl_if.h>
 114#include <wl_internal.h>
 115#include <wl_util.h>
 116#include <wl_main.h>
 117#include <wl_netdev.h>
 118#include <wl_wext.h>
 119
 120#ifdef USE_PROFILE
 121#include <wl_profile.h>
 122#endif  /* USE_PROFILE */
 123
 124#ifdef BUS_PCMCIA
 125#include <wl_cs.h>
 126#endif  /* BUS_PCMCIA */
 127
 128#ifdef BUS_PCI
 129#include <wl_pci.h>
 130#endif  /* BUS_PCI */
 131/*******************************************************************************
 132 *      macro definitions
 133 ******************************************************************************/
 134#define VALID_PARAM(C) \
 135        { \
 136                if (!(C)) \
 137                { \
 138                        printk(KERN_INFO "Wireless, parameter error: \"%s\"\n", #C); \
 139                        goto failed; \
 140                } \
 141        }
 142/*******************************************************************************
 143 *      local functions
 144 ******************************************************************************/
 145void wl_isr_handler( unsigned long p );
 146
 147#if 0 //SCULL_USE_PROC /* don't waste space if unused */
 148static int scull_read_procmem(struct seq_file *m, void *v);
 149static int write_int(struct file *file, const char *buffer, unsigned long count, void *data);
 150
 151/*
 152 * seq_file wrappers for procfile show routines.
 153 */
 154static int scull_read_procmem_open(struct inode *inode, struct file *file)
 155{
 156        return single_open(file, scull_read_procmem, PDE_DATA(inode));
 157}
 158
 159static const struct file_operations scull_read_procmem_fops = {
 160        .open           = scull_read_procmem_open,
 161        .read           = seq_read,
 162        .llseek         = seq_lseek,
 163        .release        = single_release,
 164};
 165
 166#endif /* SCULL_USE_PROC */
 167
 168/*******************************************************************************
 169 * module parameter definitions - set with 'insmod'
 170 ******************************************************************************/
 171static p_u16    irq_mask                = 0xdeb8; // IRQ3,4,5,7,9,10,11,12,14,15
 172static p_s8     irq_list[4]             = { -1 };
 173
 174#if 0
 175MODULE_PARM(irq_mask,               "h");
 176MODULE_PARM_DESC(irq_mask,               "IRQ mask [0xdeb8]");
 177MODULE_PARM(irq_list,               "1-4b");
 178MODULE_PARM_DESC(irq_list,               "IRQ list [<irq_mask>]");
 179#endif
 180
 181static p_u8     PARM_AUTHENTICATION             = PARM_DEFAULT_AUTHENTICATION;
 182static p_u16    PARM_AUTH_KEY_MGMT_SUITE        = PARM_DEFAULT_AUTH_KEY_MGMT_SUITE;
 183static p_u16    PARM_BRSC_2GHZ                  = PARM_DEFAULT_BRSC_2GHZ;
 184static p_u16    PARM_BRSC_5GHZ                  = PARM_DEFAULT_BRSC_5GHZ;
 185static p_u16    PARM_COEXISTENCE                = PARM_DEFAULT_COEXISTENCE;
 186static p_u16    PARM_CONNECTION_CONTROL         = PARM_DEFAULT_CONNECTION_CONTROL;  //;?rename and move
 187static p_char  *PARM_CREATE_IBSS                = PARM_DEFAULT_CREATE_IBSS_STR;
 188static p_char  *PARM_DESIRED_SSID               = PARM_DEFAULT_SSID;
 189static p_char  *PARM_DOWNLOAD_FIRMWARE      = "";
 190static p_u16    PARM_ENABLE_ENCRYPTION          = PARM_DEFAULT_ENABLE_ENCRYPTION;
 191static p_char  *PARM_EXCLUDE_UNENCRYPTED        = PARM_DEFAULT_EXCLUDE_UNENCRYPTED_STR;
 192static p_char  *PARM_INTRA_BSS_RELAY            = PARM_DEFAULT_INTRA_BSS_RELAY_STR;
 193static p_char  *PARM_KEY1                       = "";
 194static p_char  *PARM_KEY2                       = "";
 195static p_char  *PARM_KEY3                       = "";
 196static p_char  *PARM_KEY4                       = "";
 197static p_char  *PARM_LOAD_BALANCING             = PARM_DEFAULT_LOAD_BALANCING_STR;
 198static p_u16    PARM_MAX_SLEEP                  = PARM_DEFAULT_MAX_PM_SLEEP;
 199static p_char  *PARM_MEDIUM_DISTRIBUTION        = PARM_DEFAULT_MEDIUM_DISTRIBUTION_STR;
 200static p_char  *PARM_MICROWAVE_ROBUSTNESS       = PARM_DEFAULT_MICROWAVE_ROBUSTNESS_STR;
 201static p_char  *PARM_MULTICAST_PM_BUFFERING     = PARM_DEFAULT_MULTICAST_PM_BUFFERING_STR;
 202static p_u16    PARM_MULTICAST_RATE             = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
 203static p_char  *PARM_MULTICAST_RX               = PARM_DEFAULT_MULTICAST_RX_STR;
 204static p_u8     PARM_NETWORK_ADDR[ETH_ALEN]     = PARM_DEFAULT_NETWORK_ADDR;
 205static p_u16    PARM_OWN_ATIM_WINDOW            = PARM_DEFAULT_OWN_ATIM_WINDOW;
 206static p_u16    PARM_OWN_BEACON_INTERVAL        = PARM_DEFAULT_OWN_BEACON_INTERVAL;
 207static p_u8     PARM_OWN_CHANNEL                = PARM_DEFAULT_OWN_CHANNEL;
 208static p_u8     PARM_OWN_DTIM_PERIOD            = PARM_DEFAULT_OWN_DTIM_PERIOD;
 209static p_char  *PARM_OWN_NAME                   = PARM_DEFAULT_OWN_NAME;
 210static p_char  *PARM_OWN_SSID                   = PARM_DEFAULT_SSID;
 211static p_u16    PARM_PM_ENABLED                 = WVLAN_PM_STATE_DISABLED;
 212static p_u16    PARM_PM_HOLDOVER_DURATION       = PARM_DEFAULT_PM_HOLDOVER_DURATION;
 213static p_u8     PARM_PORT_TYPE                  = PARM_DEFAULT_PORT_TYPE;
 214static p_char  *PARM_PROMISCUOUS_MODE           = PARM_DEFAULT_PROMISCUOUS_MODE_STR;
 215static p_char  *PARM_REJECT_ANY                 = PARM_DEFAULT_REJECT_ANY_STR;
 216#ifdef USE_WDS
 217static p_u16    PARM_RTS_THRESHOLD1             = PARM_DEFAULT_RTS_THRESHOLD;
 218static p_u16    PARM_RTS_THRESHOLD2             = PARM_DEFAULT_RTS_THRESHOLD;
 219static p_u16    PARM_RTS_THRESHOLD3             = PARM_DEFAULT_RTS_THRESHOLD;
 220static p_u16    PARM_RTS_THRESHOLD4             = PARM_DEFAULT_RTS_THRESHOLD;
 221static p_u16    PARM_RTS_THRESHOLD5             = PARM_DEFAULT_RTS_THRESHOLD;
 222static p_u16    PARM_RTS_THRESHOLD6             = PARM_DEFAULT_RTS_THRESHOLD;
 223#endif // USE_WDS
 224static p_u16    PARM_RTS_THRESHOLD              = PARM_DEFAULT_RTS_THRESHOLD;
 225static p_u16    PARM_SRSC_2GHZ                  = PARM_DEFAULT_SRSC_2GHZ;
 226static p_u16    PARM_SRSC_5GHZ                  = PARM_DEFAULT_SRSC_5GHZ;
 227static p_u8     PARM_SYSTEM_SCALE               = PARM_DEFAULT_SYSTEM_SCALE;
 228static p_u8     PARM_TX_KEY                     = PARM_DEFAULT_TX_KEY;
 229static p_u16    PARM_TX_POW_LEVEL               = PARM_DEFAULT_TX_POW_LEVEL;
 230#ifdef USE_WDS
 231static p_u16    PARM_TX_RATE1                   = PARM_DEFAULT_TX_RATE_2GHZ;
 232static p_u16    PARM_TX_RATE2                   = PARM_DEFAULT_TX_RATE_2GHZ;
 233static p_u16    PARM_TX_RATE3                   = PARM_DEFAULT_TX_RATE_2GHZ;
 234static p_u16    PARM_TX_RATE4                   = PARM_DEFAULT_TX_RATE_2GHZ;
 235static p_u16    PARM_TX_RATE5                   = PARM_DEFAULT_TX_RATE_2GHZ;
 236static p_u16    PARM_TX_RATE6                   = PARM_DEFAULT_TX_RATE_2GHZ;
 237#endif // USE_WDS
 238static p_u16    PARM_TX_RATE                    = PARM_DEFAULT_TX_RATE_2GHZ;
 239#ifdef USE_WDS
 240static p_u8     PARM_WDS_ADDRESS1[ETH_ALEN]     = PARM_DEFAULT_NETWORK_ADDR;
 241static p_u8     PARM_WDS_ADDRESS2[ETH_ALEN]     = PARM_DEFAULT_NETWORK_ADDR;
 242static p_u8     PARM_WDS_ADDRESS3[ETH_ALEN]     = PARM_DEFAULT_NETWORK_ADDR;
 243static p_u8     PARM_WDS_ADDRESS4[ETH_ALEN]     = PARM_DEFAULT_NETWORK_ADDR;
 244static p_u8     PARM_WDS_ADDRESS5[ETH_ALEN]     = PARM_DEFAULT_NETWORK_ADDR;
 245static p_u8     PARM_WDS_ADDRESS6[ETH_ALEN]     = PARM_DEFAULT_NETWORK_ADDR;
 246#endif // USE_WDS
 247
 248
 249#if 0
 250MODULE_PARM(PARM_DESIRED_SSID,          "s");
 251MODULE_PARM_DESC(PARM_DESIRED_SSID,             "Network Name (<string>) [ANY]");
 252MODULE_PARM(PARM_OWN_SSID,              "s");
 253MODULE_PARM_DESC(PARM_OWN_SSID,                 "Network Name (<string>) [ANY]");
 254MODULE_PARM(PARM_OWN_CHANNEL,           "b");
 255MODULE_PARM_DESC(PARM_OWN_CHANNEL,              "Channel (0 - 14) [0]");
 256MODULE_PARM(PARM_SYSTEM_SCALE,          "b");
 257MODULE_PARM_DESC(PARM_SYSTEM_SCALE,             "Distance Between APs (1 - 3) [1]");
 258MODULE_PARM(PARM_TX_RATE,               "b");
 259MODULE_PARM_DESC(PARM_TX_RATE,                  "Transmit Rate Control");
 260MODULE_PARM(PARM_RTS_THRESHOLD,         "h");
 261MODULE_PARM_DESC(PARM_RTS_THRESHOLD,            "Medium Reservation (RTS/CTS Fragment Length) (256 - 2347) [2347]");
 262MODULE_PARM(PARM_MICROWAVE_ROBUSTNESS,  "s");
 263MODULE_PARM_DESC(PARM_MICROWAVE_ROBUSTNESS,     "Microwave Oven Robustness Enabled (<string> N or Y) [N]");
 264MODULE_PARM(PARM_OWN_NAME,              "s");
 265MODULE_PARM_DESC(PARM_OWN_NAME,                 "Station Name (<string>) [Linux]");
 266
 267MODULE_PARM(PARM_ENABLE_ENCRYPTION,     "b");
 268MODULE_PARM_DESC(PARM_ENABLE_ENCRYPTION,        "Encryption Mode (0 - 7) [0]");
 269
 270MODULE_PARM(PARM_KEY1,                  "s");
 271MODULE_PARM_DESC(PARM_KEY1,                     "Data Encryption Key 1 (<string>) []");
 272MODULE_PARM(PARM_KEY2,                  "s");
 273MODULE_PARM_DESC(PARM_KEY2,                     "Data Encryption Key 2 (<string>) []");
 274MODULE_PARM(PARM_KEY3,                  "s");
 275MODULE_PARM_DESC(PARM_KEY3,                     "Data Encryption Key 3 (<string>) []");
 276MODULE_PARM(PARM_KEY4,                  "s");
 277MODULE_PARM_DESC(PARM_KEY4,                     "Data Encryption Key 4 (<string>) []");
 278MODULE_PARM(PARM_TX_KEY,                "b");
 279MODULE_PARM_DESC(PARM_TX_KEY,                   "Transmit Key ID (1 - 4) [1]");
 280MODULE_PARM(PARM_MULTICAST_RATE,        "b");
 281MODULE_PARM_DESC(PARM_MULTICAST_RATE,           "Multicast Rate");
 282MODULE_PARM(PARM_DOWNLOAD_FIRMWARE,     "s");
 283MODULE_PARM_DESC(PARM_DOWNLOAD_FIRMWARE,        "filename of firmware image");
 284
 285MODULE_PARM(PARM_AUTH_KEY_MGMT_SUITE,   "b");
 286MODULE_PARM_DESC(PARM_AUTH_KEY_MGMT_SUITE,      "Authentication Key Management suite (0-4) [0]");
 287
 288MODULE_PARM(PARM_LOAD_BALANCING,        "s");
 289MODULE_PARM_DESC(PARM_LOAD_BALANCING,           "Load Balancing Enabled (<string> N or Y) [Y]");
 290MODULE_PARM(PARM_MEDIUM_DISTRIBUTION,   "s");
 291MODULE_PARM_DESC(PARM_MEDIUM_DISTRIBUTION,      "Medium Distribution Enabled (<string> N or Y) [Y]");
 292MODULE_PARM(PARM_TX_POW_LEVEL,          "b");
 293MODULE_PARM_DESC(PARM_TX_POW_LEVEL,             "Transmit Power (0 - 6) [3]");
 294MODULE_PARM(PARM_SRSC_2GHZ,             "b");
 295MODULE_PARM_DESC(PARM_SRSC_2GHZ,                "Supported Rate Set Control 2.4 GHz");
 296MODULE_PARM(PARM_SRSC_5GHZ,             "b");
 297MODULE_PARM_DESC(PARM_SRSC_5GHZ,                "Supported Rate Set Control 5.0 GHz");
 298MODULE_PARM(PARM_BRSC_2GHZ,             "b");
 299MODULE_PARM_DESC(PARM_BRSC_2GHZ,                "Basic Rate Set Control 2.4 GHz");
 300MODULE_PARM(PARM_BRSC_5GHZ,             "b");
 301MODULE_PARM_DESC(PARM_BRSC_5GHZ,                "Basic Rate Set Control 5.0 GHz");
 302#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
 303//;?seems reasonable that even an AP-only driver could afford this small additional footprint
 304MODULE_PARM(PARM_PM_ENABLED,            "h");
 305MODULE_PARM_DESC(PARM_PM_ENABLED,               "Power Management State (0 - 2, 8001 - 8002) [0]");
 306MODULE_PARM(PARM_PORT_TYPE,             "b");
 307MODULE_PARM_DESC(PARM_PORT_TYPE,                "Port Type (1 - 3) [1]");
 308//;?MODULE_PARM(PARM_CREATE_IBSS,           "s");
 309//;?MODULE_PARM_DESC(PARM_CREATE_IBSS,              "Create IBSS (<string> N or Y) [N]");
 310//;?MODULE_PARM(PARM_MULTICAST_RX,          "s");
 311//;?MODULE_PARM_DESC(PARM_MULTICAST_RX,             "Multicast Receive Enable (<string> N or Y) [Y]");
 312//;?MODULE_PARM(PARM_MAX_SLEEP,             "h");
 313//;?MODULE_PARM_DESC(PARM_MAX_SLEEP,                "Maximum Power Management Sleep Duration (0 - 65535) [100]");
 314//;?MODULE_PARM(PARM_NETWORK_ADDR,          "6b");
 315//;?MODULE_PARM_DESC(PARM_NETWORK_ADDR,             "Hardware Ethernet Address ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [<factory value>]");
 316//;?MODULE_PARM(PARM_AUTHENTICATION,        "b");
 317//
 318//tracker 12448
 319//;?MODULE_PARM_DESC(PARM_AUTHENTICATION,           "Authentication Type (0-2) [0] 0=Open 1=SharedKey 2=LEAP");
 320//;?MODULE_PARM_DESC(authentication,         "Authentication Type (1-2) [1] 1=Open 2=SharedKey");
 321//tracker 12448
 322//
 323//;?MODULE_PARM(PARM_OWN_ATIM_WINDOW,       "b");
 324//;?MODULE_PARM_DESC(PARM_OWN_ATIM_WINDOW,          "ATIM Window time in TU for IBSS creation (0-100) [0]");
 325//;?MODULE_PARM(PARM_PM_HOLDOVER_DURATION,  "b");
 326//;?MODULE_PARM_DESC(PARM_PM_HOLDOVER_DURATION,     "Time station remains awake after MAC frame transfer when PM is on (0-65535) [100]");
 327//;?MODULE_PARM(PARM_PROMISCUOUS_MODE,      "s");
 328//;?MODULE_PARM_DESC(PARM_PROMISCUOUS_MODE,         "Promiscuous Mode Enable (<string> Y or N ) [N]" );
 329//;?
 330MODULE_PARM(PARM_CONNECTION_CONTROL,    "b");
 331MODULE_PARM_DESC(PARM_CONNECTION_CONTROL,       "Connection Control (0 - 3) [2]");
 332#endif /* HCF_STA */
 333#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
 334                                        //;?should we restore this to allow smaller memory footprint
 335MODULE_PARM(PARM_OWN_DTIM_PERIOD,       "b");
 336MODULE_PARM_DESC(PARM_OWN_DTIM_PERIOD,          "DTIM Period (0 - 255) [1]");
 337MODULE_PARM(PARM_REJECT_ANY,            "s");
 338MODULE_PARM_DESC(PARM_REJECT_ANY,               "Closed System (<string> N or Y) [N]");
 339MODULE_PARM(PARM_EXCLUDE_UNENCRYPTED,   "s");
 340MODULE_PARM_DESC(PARM_EXCLUDE_UNENCRYPTED,      "Deny non-encrypted (<string> N or Y) [Y]");
 341MODULE_PARM(PARM_MULTICAST_PM_BUFFERING,"s");
 342MODULE_PARM_DESC(PARM_MULTICAST_PM_BUFFERING,   "Buffer MAC frames for Tx after DTIM (<string> Y or N) [Y]");
 343MODULE_PARM(PARM_INTRA_BSS_RELAY,       "s");
 344MODULE_PARM_DESC(PARM_INTRA_BSS_RELAY,          "IntraBSS Relay (<string> N or Y) [Y]");
 345MODULE_PARM(PARM_RTS_THRESHOLD1,        "h");
 346MODULE_PARM_DESC(PARM_RTS_THRESHOLD1,           "RTS Threshold, WDS Port 1 (256 - 2347) [2347]");
 347MODULE_PARM(PARM_RTS_THRESHOLD2,        "h");
 348MODULE_PARM_DESC(PARM_RTS_THRESHOLD2,           "RTS Threshold, WDS Port 2 (256 - 2347) [2347]");
 349MODULE_PARM(PARM_RTS_THRESHOLD3,        "h");
 350MODULE_PARM_DESC(PARM_RTS_THRESHOLD3,           "RTS Threshold, WDS Port 3 (256 - 2347) [2347]");
 351MODULE_PARM(PARM_RTS_THRESHOLD4,        "h");
 352MODULE_PARM_DESC(PARM_RTS_THRESHOLD4,           "RTS Threshold, WDS Port 4 (256 - 2347) [2347]");
 353MODULE_PARM(PARM_RTS_THRESHOLD5,        "h");
 354MODULE_PARM_DESC(PARM_RTS_THRESHOLD5,           "RTS Threshold, WDS Port 5 (256 - 2347) [2347]");
 355MODULE_PARM(PARM_RTS_THRESHOLD6,        "h");
 356MODULE_PARM_DESC(PARM_RTS_THRESHOLD6,           "RTS Threshold, WDS Port 6 (256 - 2347) [2347]");
 357MODULE_PARM(PARM_TX_RATE1,              "b");
 358MODULE_PARM_DESC(PARM_TX_RATE1,                 "Transmit Rate Control, WDS Port 1 (1 - 7) [3]");
 359MODULE_PARM(PARM_TX_RATE2,              "b");
 360MODULE_PARM_DESC(PARM_TX_RATE2,                 "Transmit Rate Control, WDS Port 2 (1 - 7) [3]");
 361MODULE_PARM(PARM_TX_RATE3,              "b");
 362MODULE_PARM_DESC(PARM_TX_RATE3,                 "Transmit Rate Control, WDS Port 3 (1 - 7) [3]");
 363MODULE_PARM(PARM_TX_RATE4,              "b");
 364MODULE_PARM_DESC(PARM_TX_RATE4,                 "Transmit Rate Control, WDS Port 4 (1 - 7) [3]");
 365MODULE_PARM(PARM_TX_RATE5,              "b");
 366MODULE_PARM_DESC(PARM_TX_RATE5,                 "Transmit Rate Control, WDS Port 5 (1 - 7) [3]");
 367MODULE_PARM(PARM_TX_RATE6,              "b");
 368MODULE_PARM_DESC(PARM_TX_RATE6,                 "Transmit Rate Control, WDS Port 6 (1 - 7) [3]");
 369MODULE_PARM(PARM_WDS_ADDRESS1,          "6b");
 370MODULE_PARM_DESC(PARM_WDS_ADDRESS1,             "MAC Address, WDS Port 1 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
 371MODULE_PARM(PARM_WDS_ADDRESS2,          "6b");
 372MODULE_PARM_DESC(PARM_WDS_ADDRESS2,             "MAC Address, WDS Port 2 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
 373MODULE_PARM(PARM_WDS_ADDRESS3,          "6b");
 374MODULE_PARM_DESC(PARM_WDS_ADDRESS3,             "MAC Address, WDS Port 3 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
 375MODULE_PARM(PARM_WDS_ADDRESS4,          "6b");
 376MODULE_PARM_DESC(PARM_WDS_ADDRESS4,             "MAC Address, WDS Port 4 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
 377MODULE_PARM(PARM_WDS_ADDRESS5,          "6b");
 378MODULE_PARM_DESC(PARM_WDS_ADDRESS5,             "MAC Address, WDS Port 5 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
 379MODULE_PARM(PARM_WDS_ADDRESS6,          "6b");
 380MODULE_PARM_DESC(PARM_WDS_ADDRESS6,             "MAC Address, WDS Port 6 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
 381
 382MODULE_PARM(PARM_OWN_BEACON_INTERVAL,   "b");
 383MODULE_PARM_DESC(PARM_OWN_BEACON_INTERVAL,      "Own Beacon Interval (20 - 200) [100]");
 384MODULE_PARM(PARM_COEXISTENCE,   "b");
 385MODULE_PARM_DESC(PARM_COEXISTENCE,      "Coexistence (0-7) [0]");
 386
 387#endif /* HCF_AP */
 388#endif
 389
 390/* END NEW PARAMETERS */
 391/*******************************************************************************
 392 * debugging specifics
 393 ******************************************************************************/
 394#if DBG
 395
 396static p_u32    pc_debug = DBG_LVL;
 397//MODULE_PARM(pc_debug, "i");
 398/*static ;?conflicts with my understanding of CL parameters and breaks now I moved
 399 * the correspondig logic to wl_profile
 400 */ p_u32    DebugFlag = ~0; //recognizable "undefined value" rather then DBG_DEFAULTS;
 401//MODULE_PARM(DebugFlag, "l");
 402
 403dbg_info_t   wl_info = { DBG_MOD_NAME, 0, 0 };
 404dbg_info_t  *DbgInfo = &wl_info;
 405
 406#endif /* DBG */
 407#ifdef USE_RTS
 408
 409static p_char  *useRTS = "N";
 410MODULE_PARM( useRTS, "s" );
 411MODULE_PARM_DESC( useRTS, "Use RTS test interface (<string> N or Y) [N]" );
 412
 413#endif  /* USE_RTS */
 414/*******************************************************************************
 415 * firmware download specifics
 416 ******************************************************************************/
 417extern struct CFG_RANGE2_STRCT BASED
 418        cfg_drv_act_ranges_pri;             // describes primary-actor range of HCF
 419
 420#if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
 421extern memimage ap;                 // AP firmware image to be downloaded
 422#endif /* HCF_AP */
 423
 424#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
 425//extern memimage station;            // STA firmware image to be downloaded
 426extern memimage fw_image;            // firmware image to be downloaded
 427#endif /* HCF_STA */
 428
 429
 430int wl_insert( struct net_device *dev )
 431{
 432        int                     result = 0;
 433        int                     hcf_status = HCF_SUCCESS;
 434        int                     i;
 435        unsigned long           flags = 0;
 436        struct wl_private       *lp = wl_priv(dev);
 437        /*------------------------------------------------------------------------*/
 438        DBG_FUNC( "wl_insert" );
 439        DBG_ENTER( DbgInfo );
 440
 441        /* Initialize the adapter hardware. */
 442        memset( &( lp->hcfCtx ), 0, sizeof( IFB_STRCT ));
 443
 444        /* Initialize the adapter parameters. */
 445        spin_lock_init( &( lp->slock ));
 446
 447        /* Initialize states */
 448        //lp->lockcount = 0; //PE1DNN
 449        lp->is_handling_int = WL_NOT_HANDLING_INT;
 450        lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
 451
 452        lp->dev = dev;
 453
 454        DBG_PARAM( DbgInfo, "irq_mask", "0x%04x", irq_mask & 0x0FFFF );
 455        DBG_PARAM( DbgInfo, "irq_list", "0x%02x 0x%02x 0x%02x 0x%02x",
 456                           irq_list[0] & 0x0FF, irq_list[1] & 0x0FF,
 457                           irq_list[2] & 0x0FF, irq_list[3] & 0x0FF );
 458        DBG_PARAM( DbgInfo, PARM_NAME_DESIRED_SSID, "\"%s\"", PARM_DESIRED_SSID );
 459        DBG_PARAM( DbgInfo, PARM_NAME_OWN_SSID, "\"%s\"", PARM_OWN_SSID );
 460        DBG_PARAM( DbgInfo, PARM_NAME_OWN_CHANNEL, "%d", PARM_OWN_CHANNEL);
 461        DBG_PARAM( DbgInfo, PARM_NAME_SYSTEM_SCALE, "%d", PARM_SYSTEM_SCALE );
 462        DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE, "%d", PARM_TX_RATE );
 463        DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD, "%d", PARM_RTS_THRESHOLD );
 464        DBG_PARAM( DbgInfo, PARM_NAME_MICROWAVE_ROBUSTNESS, "\"%s\"", PARM_MICROWAVE_ROBUSTNESS );
 465        DBG_PARAM( DbgInfo, PARM_NAME_OWN_NAME, "\"%s\"", PARM_OWN_NAME );
 466//;?            DBG_PARAM( DbgInfo, PARM_NAME_ENABLE_ENCRYPTION, "\"%s\"", PARM_ENABLE_ENCRYPTION );
 467        DBG_PARAM( DbgInfo, PARM_NAME_KEY1, "\"%s\"", PARM_KEY1 );
 468        DBG_PARAM( DbgInfo, PARM_NAME_KEY2, "\"%s\"", PARM_KEY2 );
 469        DBG_PARAM( DbgInfo, PARM_NAME_KEY3, "\"%s\"", PARM_KEY3 );
 470        DBG_PARAM( DbgInfo, PARM_NAME_KEY4, "\"%s\"", PARM_KEY4 );
 471        DBG_PARAM( DbgInfo, PARM_NAME_TX_KEY, "%d", PARM_TX_KEY );
 472        DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RATE, "%d", PARM_MULTICAST_RATE );
 473        DBG_PARAM( DbgInfo, PARM_NAME_DOWNLOAD_FIRMWARE, "\"%s\"", PARM_DOWNLOAD_FIRMWARE );
 474        DBG_PARAM( DbgInfo, PARM_NAME_AUTH_KEY_MGMT_SUITE, "%d", PARM_AUTH_KEY_MGMT_SUITE );
 475//;?#if (HCF_TYPE) & HCF_TYPE_STA
 476                                        //;?should we make this code conditional depending on in STA mode
 477//;?        DBG_PARAM( DbgInfo, PARM_NAME_PORT_TYPE, "%d", PARM_PORT_TYPE );
 478                DBG_PARAM( DbgInfo, PARM_NAME_PM_ENABLED, "%04x", PARM_PM_ENABLED );
 479//;?        DBG_PARAM( DbgInfo, PARM_NAME_CREATE_IBSS, "\"%s\"", PARM_CREATE_IBSS );
 480//;?        DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RX, "\"%s\"", PARM_MULTICAST_RX );
 481//;?        DBG_PARAM( DbgInfo, PARM_NAME_MAX_SLEEP, "%d", PARM_MAX_SLEEP );
 482/*
 483        DBG_PARAM(DbgInfo, PARM_NAME_NETWORK_ADDR, "\"%pM\"",
 484                        PARM_NETWORK_ADDR);
 485 */
 486//;?        DBG_PARAM( DbgInfo, PARM_NAME_AUTHENTICATION, "%d", PARM_AUTHENTICATION );
 487//;?        DBG_PARAM( DbgInfo, PARM_NAME_OWN_ATIM_WINDOW, "%d", PARM_OWN_ATIM_WINDOW );
 488//;?        DBG_PARAM( DbgInfo, PARM_NAME_PM_HOLDOVER_DURATION, "%d", PARM_PM_HOLDOVER_DURATION );
 489//;?        DBG_PARAM( DbgInfo, PARM_NAME_PROMISCUOUS_MODE, "\"%s\"", PARM_PROMISCUOUS_MODE );
 490//;?#endif /* HCF_STA */
 491#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
 492                //;?should we restore this to allow smaller memory footprint
 493                //;?I guess: no, since this is Debug mode only
 494        DBG_PARAM( DbgInfo, PARM_NAME_OWN_DTIM_PERIOD, "%d", PARM_OWN_DTIM_PERIOD );
 495        DBG_PARAM( DbgInfo, PARM_NAME_REJECT_ANY, "\"%s\"", PARM_REJECT_ANY );
 496        DBG_PARAM( DbgInfo, PARM_NAME_EXCLUDE_UNENCRYPTED, "\"%s\"", PARM_EXCLUDE_UNENCRYPTED );
 497        DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_PM_BUFFERING, "\"%s\"", PARM_MULTICAST_PM_BUFFERING );
 498        DBG_PARAM( DbgInfo, PARM_NAME_INTRA_BSS_RELAY, "\"%s\"", PARM_INTRA_BSS_RELAY );
 499#ifdef USE_WDS
 500        DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD1, "%d", PARM_RTS_THRESHOLD1 );
 501        DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD2, "%d", PARM_RTS_THRESHOLD2 );
 502        DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD3, "%d", PARM_RTS_THRESHOLD3 );
 503        DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD4, "%d", PARM_RTS_THRESHOLD4 );
 504        DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD5, "%d", PARM_RTS_THRESHOLD5 );
 505        DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD6, "%d", PARM_RTS_THRESHOLD6 );
 506        DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE1, "%d", PARM_TX_RATE1 );
 507        DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE2, "%d", PARM_TX_RATE2 );
 508        DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE3, "%d", PARM_TX_RATE3 );
 509        DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE4, "%d", PARM_TX_RATE4 );
 510        DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE5, "%d", PARM_TX_RATE5 );
 511        DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE6, "%d", PARM_TX_RATE6 );
 512        DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS1, "\"%pM\"",
 513                        PARM_WDS_ADDRESS1);
 514        DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS2, "\"%pM\"",
 515                        PARM_WDS_ADDRESS2);
 516        DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS3, "\"%pM\"",
 517                        PARM_WDS_ADDRESS3);
 518        DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS4, "\"%pM\"",
 519                        PARM_WDS_ADDRESS4);
 520        DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS5, "\"%pM\"",
 521                        PARM_WDS_ADDRESS5);
 522        DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS6, "\"%pM\"",
 523                        PARM_WDS_ADDRESS6);
 524#endif /* USE_WDS */
 525#endif /* HCF_AP */
 526
 527        VALID_PARAM( !PARM_DESIRED_SSID || ( strlen( PARM_DESIRED_SSID ) <= PARM_MAX_NAME_LEN ));
 528        VALID_PARAM( !PARM_OWN_SSID || ( strlen( PARM_OWN_SSID ) <= PARM_MAX_NAME_LEN ));
 529        VALID_PARAM(( PARM_OWN_CHANNEL <= PARM_MAX_OWN_CHANNEL ));
 530        VALID_PARAM(( PARM_SYSTEM_SCALE >= PARM_MIN_SYSTEM_SCALE ) && ( PARM_SYSTEM_SCALE <= PARM_MAX_SYSTEM_SCALE ));
 531        VALID_PARAM(( PARM_TX_RATE >= PARM_MIN_TX_RATE ) && ( PARM_TX_RATE <= PARM_MAX_TX_RATE ));
 532        VALID_PARAM(( PARM_RTS_THRESHOLD <= PARM_MAX_RTS_THRESHOLD ));
 533        VALID_PARAM( !PARM_MICROWAVE_ROBUSTNESS || strchr( "NnYy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL );
 534        VALID_PARAM( !PARM_OWN_NAME || ( strlen( PARM_NAME_OWN_NAME ) <= PARM_MAX_NAME_LEN ));
 535        VALID_PARAM(( PARM_ENABLE_ENCRYPTION <= PARM_MAX_ENABLE_ENCRYPTION ));
 536        VALID_PARAM( is_valid_key_string( PARM_KEY1 ));
 537        VALID_PARAM( is_valid_key_string( PARM_KEY2 ));
 538        VALID_PARAM( is_valid_key_string( PARM_KEY3 ));
 539        VALID_PARAM( is_valid_key_string( PARM_KEY4 ));
 540        VALID_PARAM(( PARM_TX_KEY >= PARM_MIN_TX_KEY ) && ( PARM_TX_KEY <= PARM_MAX_TX_KEY ));
 541
 542        VALID_PARAM(( PARM_MULTICAST_RATE >= PARM_MIN_MULTICAST_RATE ) &&
 543                                        ( PARM_MULTICAST_RATE <= PARM_MAX_MULTICAST_RATE ));
 544
 545        VALID_PARAM( !PARM_DOWNLOAD_FIRMWARE || ( strlen( PARM_DOWNLOAD_FIRMWARE ) <= 255 /*;?*/ ));
 546        VALID_PARAM(( PARM_AUTH_KEY_MGMT_SUITE < PARM_MAX_AUTH_KEY_MGMT_SUITE ));
 547
 548        VALID_PARAM( !PARM_LOAD_BALANCING || strchr( "NnYy", PARM_LOAD_BALANCING[0] ) != NULL );
 549        VALID_PARAM( !PARM_MEDIUM_DISTRIBUTION || strchr( "NnYy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL );
 550        VALID_PARAM(( PARM_TX_POW_LEVEL <= PARM_MAX_TX_POW_LEVEL ));
 551
 552        VALID_PARAM(( PARM_PORT_TYPE >= PARM_MIN_PORT_TYPE ) && ( PARM_PORT_TYPE <= PARM_MAX_PORT_TYPE ));
 553        VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
 554                                 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
 555        VALID_PARAM( !PARM_CREATE_IBSS || strchr( "NnYy", PARM_CREATE_IBSS[0] ) != NULL );
 556        VALID_PARAM( !PARM_MULTICAST_RX || strchr( "NnYy", PARM_MULTICAST_RX[0] ) != NULL );
 557        VALID_PARAM(( PARM_MAX_SLEEP <= PARM_MAX_MAX_PM_SLEEP ));
 558        VALID_PARAM(( PARM_AUTHENTICATION <= PARM_MAX_AUTHENTICATION ));
 559        VALID_PARAM(( PARM_OWN_ATIM_WINDOW <= PARM_MAX_OWN_ATIM_WINDOW ));
 560        VALID_PARAM(( PARM_PM_HOLDOVER_DURATION <= PARM_MAX_PM_HOLDOVER_DURATION ));
 561        VALID_PARAM( !PARM_PROMISCUOUS_MODE || strchr( "NnYy", PARM_PROMISCUOUS_MODE[0] ) != NULL );
 562        VALID_PARAM(( PARM_CONNECTION_CONTROL <= PARM_MAX_CONNECTION_CONTROL ));
 563
 564        VALID_PARAM(( PARM_OWN_DTIM_PERIOD >= PARM_MIN_OWN_DTIM_PERIOD ));
 565        VALID_PARAM( !PARM_REJECT_ANY || strchr( "NnYy", PARM_REJECT_ANY[0] ) != NULL );
 566        VALID_PARAM( !PARM_EXCLUDE_UNENCRYPTED || strchr( "NnYy", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL );
 567        VALID_PARAM( !PARM_MULTICAST_PM_BUFFERING || strchr( "NnYy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL );
 568        VALID_PARAM( !PARM_INTRA_BSS_RELAY || strchr( "NnYy", PARM_INTRA_BSS_RELAY[0] ) != NULL );
 569#ifdef USE_WDS
 570        VALID_PARAM(( PARM_RTS_THRESHOLD1 <= PARM_MAX_RTS_THRESHOLD ));
 571        VALID_PARAM(( PARM_RTS_THRESHOLD2 <= PARM_MAX_RTS_THRESHOLD ));
 572        VALID_PARAM(( PARM_RTS_THRESHOLD3 <= PARM_MAX_RTS_THRESHOLD ));
 573        VALID_PARAM(( PARM_RTS_THRESHOLD4 <= PARM_MAX_RTS_THRESHOLD ));
 574        VALID_PARAM(( PARM_RTS_THRESHOLD5 <= PARM_MAX_RTS_THRESHOLD ));
 575        VALID_PARAM(( PARM_RTS_THRESHOLD6 <= PARM_MAX_RTS_THRESHOLD ));
 576        VALID_PARAM(( PARM_TX_RATE1 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE1 <= PARM_MAX_TX_RATE ));
 577        VALID_PARAM(( PARM_TX_RATE2 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE2 <= PARM_MAX_TX_RATE ));
 578        VALID_PARAM(( PARM_TX_RATE3 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE3 <= PARM_MAX_TX_RATE ));
 579        VALID_PARAM(( PARM_TX_RATE4 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE4 <= PARM_MAX_TX_RATE ));
 580        VALID_PARAM(( PARM_TX_RATE5 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE5 <= PARM_MAX_TX_RATE ));
 581        VALID_PARAM(( PARM_TX_RATE6 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE6 <= PARM_MAX_TX_RATE ));
 582#endif /* USE_WDS */
 583
 584        VALID_PARAM(( PARM_OWN_BEACON_INTERVAL >= PARM_MIN_OWN_BEACON_INTERVAL ) && ( PARM_OWN_BEACON_INTERVAL <= PARM_MAX_OWN_BEACON_INTERVAL ));
 585        VALID_PARAM(( PARM_COEXISTENCE <= PARM_COEXISTENCE ));
 586
 587        /* Set the driver parameters from the passed in parameters. */
 588
 589        /* THESE MODULE PARAMETERS ARE TO BE DEPRECATED IN FAVOR OF A NAMING CONVENTION
 590           WHICH IS INLINE WITH THE FORTHCOMING WAVELAN API */
 591
 592        /* START NEW PARAMETERS */
 593
 594        lp->Channel             = PARM_OWN_CHANNEL;
 595        lp->DistanceBetweenAPs  = PARM_SYSTEM_SCALE;
 596
 597        /* Need to determine how to handle the new bands for 5GHz */
 598        lp->TxRateControl[0]    = PARM_DEFAULT_TX_RATE_2GHZ;
 599        lp->TxRateControl[1]    = PARM_DEFAULT_TX_RATE_5GHZ;
 600
 601        lp->RTSThreshold        = PARM_RTS_THRESHOLD;
 602
 603        /* Need to determine how to handle the new bands for 5GHz */
 604        lp->MulticastRate[0]    = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
 605        lp->MulticastRate[1]    = PARM_DEFAULT_MULTICAST_RATE_5GHZ;
 606
 607        if ( strchr( "Yy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL ) {
 608                lp->MicrowaveRobustness = 1;
 609        } else {
 610                lp->MicrowaveRobustness = 0;
 611        }
 612        if ( PARM_DESIRED_SSID && ( strlen( PARM_DESIRED_SSID ) <= HCF_MAX_NAME_LEN )) {
 613                strcpy( lp->NetworkName, PARM_DESIRED_SSID );
 614        }
 615        if ( PARM_OWN_SSID && ( strlen( PARM_OWN_SSID ) <= HCF_MAX_NAME_LEN )) {
 616                strcpy( lp->NetworkName, PARM_OWN_SSID );
 617        }
 618        if ( PARM_OWN_NAME && ( strlen( PARM_OWN_NAME ) <= HCF_MAX_NAME_LEN )) {
 619                strcpy( lp->StationName, PARM_OWN_NAME );
 620        }
 621        lp->EnableEncryption = PARM_ENABLE_ENCRYPTION;
 622        if ( PARM_KEY1 && ( strlen( PARM_KEY1 ) <= MAX_KEY_LEN )) {
 623                strcpy( lp->Key1, PARM_KEY1 );
 624        }
 625        if ( PARM_KEY2 && ( strlen( PARM_KEY2 ) <= MAX_KEY_LEN )) {
 626                strcpy( lp->Key2, PARM_KEY2 );
 627        }
 628        if ( PARM_KEY3 && ( strlen( PARM_KEY3 ) <= MAX_KEY_LEN )) {
 629                strcpy( lp->Key3, PARM_KEY3 );
 630        }
 631        if ( PARM_KEY4 && ( strlen( PARM_KEY4 ) <= MAX_KEY_LEN )) {
 632                strcpy( lp->Key4, PARM_KEY4 );
 633        }
 634
 635        lp->TransmitKeyID = PARM_TX_KEY;
 636
 637        key_string2key( lp->Key1, &(lp->DefaultKeys.key[0] ));
 638        key_string2key( lp->Key2, &(lp->DefaultKeys.key[1] ));
 639        key_string2key( lp->Key3, &(lp->DefaultKeys.key[2] ));
 640        key_string2key( lp->Key4, &(lp->DefaultKeys.key[3] ));
 641
 642        lp->DownloadFirmware = 1 ; //;?to be upgraded PARM_DOWNLOAD_FIRMWARE;
 643        lp->AuthKeyMgmtSuite = PARM_AUTH_KEY_MGMT_SUITE;
 644
 645        if ( strchr( "Yy", PARM_LOAD_BALANCING[0] ) != NULL ) {
 646                lp->loadBalancing = 1;
 647        } else {
 648                lp->loadBalancing = 0;
 649        }
 650
 651        if ( strchr( "Yy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL ) {
 652                lp->mediumDistribution = 1;
 653        } else {
 654                lp->mediumDistribution = 0;
 655        }
 656
 657        lp->txPowLevel = PARM_TX_POW_LEVEL;
 658
 659        lp->srsc[0] = PARM_SRSC_2GHZ;
 660        lp->srsc[1] = PARM_SRSC_5GHZ;
 661        lp->brsc[0] = PARM_BRSC_2GHZ;
 662        lp->brsc[1] = PARM_BRSC_5GHZ;
 663#if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
 664//;?seems reasonable that even an AP-only driver could afford this small additional footprint
 665        lp->PortType            = PARM_PORT_TYPE;
 666        lp->MaxSleepDuration    = PARM_MAX_SLEEP;
 667        lp->authentication      = PARM_AUTHENTICATION;
 668        lp->atimWindow          = PARM_OWN_ATIM_WINDOW;
 669        lp->holdoverDuration    = PARM_PM_HOLDOVER_DURATION;
 670        lp->PMEnabled           = PARM_PM_ENABLED;  //;?
 671        if ( strchr( "Yy", PARM_CREATE_IBSS[0] ) != NULL ) {
 672                lp->CreateIBSS = 1;
 673        } else {
 674                lp->CreateIBSS = 0;
 675        }
 676        if ( strchr( "Nn", PARM_MULTICAST_RX[0] ) != NULL ) {
 677                lp->MulticastReceive = 0;
 678        } else {
 679                lp->MulticastReceive = 1;
 680        }
 681        if ( strchr( "Yy", PARM_PROMISCUOUS_MODE[0] ) != NULL ) {
 682                lp->promiscuousMode = 1;
 683        } else {
 684                lp->promiscuousMode = 0;
 685        }
 686        for( i = 0; i < ETH_ALEN; i++ ) {
 687           lp->MACAddress[i] = PARM_NETWORK_ADDR[i];
 688        }
 689
 690        lp->connectionControl = PARM_CONNECTION_CONTROL;
 691
 692#endif /* HCF_STA */
 693#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
 694        //;?should we restore this to allow smaller memory footprint
 695        lp->DTIMPeriod = PARM_OWN_DTIM_PERIOD;
 696
 697        if ( strchr( "Yy", PARM_REJECT_ANY[0] ) != NULL ) {
 698                lp->RejectAny = 1;
 699        } else {
 700                lp->RejectAny = 0;
 701        }
 702        if ( strchr( "Nn", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL ) {
 703                lp->ExcludeUnencrypted = 0;
 704        } else {
 705                lp->ExcludeUnencrypted = 1;
 706        }
 707        if ( strchr( "Yy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL ) {
 708                lp->multicastPMBuffering = 1;
 709        } else {
 710                lp->multicastPMBuffering = 0;
 711        }
 712        if ( strchr( "Yy", PARM_INTRA_BSS_RELAY[0] ) != NULL ) {
 713                lp->intraBSSRelay = 1;
 714        } else {
 715                lp->intraBSSRelay = 0;
 716        }
 717
 718        lp->ownBeaconInterval = PARM_OWN_BEACON_INTERVAL;
 719        lp->coexistence       = PARM_COEXISTENCE;
 720
 721#ifdef USE_WDS
 722        lp->wds_port[0].rtsThreshold    = PARM_RTS_THRESHOLD1;
 723        lp->wds_port[1].rtsThreshold    = PARM_RTS_THRESHOLD2;
 724        lp->wds_port[2].rtsThreshold    = PARM_RTS_THRESHOLD3;
 725        lp->wds_port[3].rtsThreshold    = PARM_RTS_THRESHOLD4;
 726        lp->wds_port[4].rtsThreshold    = PARM_RTS_THRESHOLD5;
 727        lp->wds_port[5].rtsThreshold    = PARM_RTS_THRESHOLD6;
 728        lp->wds_port[0].txRateCntl      = PARM_TX_RATE1;
 729        lp->wds_port[1].txRateCntl      = PARM_TX_RATE2;
 730        lp->wds_port[2].txRateCntl      = PARM_TX_RATE3;
 731        lp->wds_port[3].txRateCntl      = PARM_TX_RATE4;
 732        lp->wds_port[4].txRateCntl      = PARM_TX_RATE5;
 733        lp->wds_port[5].txRateCntl      = PARM_TX_RATE6;
 734
 735        for( i = 0; i < ETH_ALEN; i++ ) {
 736                lp->wds_port[0].wdsAddress[i] = PARM_WDS_ADDRESS1[i];
 737        }
 738        for( i = 0; i < ETH_ALEN; i++ ) {
 739                lp->wds_port[1].wdsAddress[i] = PARM_WDS_ADDRESS2[i];
 740        }
 741        for( i = 0; i < ETH_ALEN; i++ ) {
 742                lp->wds_port[2].wdsAddress[i] = PARM_WDS_ADDRESS3[i];
 743        }
 744        for( i = 0; i < ETH_ALEN; i++ ) {
 745                lp->wds_port[3].wdsAddress[i] = PARM_WDS_ADDRESS4[i];
 746        }
 747        for( i = 0; i < ETH_ALEN; i++ ) {
 748                lp->wds_port[4].wdsAddress[i] = PARM_WDS_ADDRESS5[i];
 749        }
 750        for( i = 0; i < ETH_ALEN; i++ ) {
 751                lp->wds_port[5].wdsAddress[i] = PARM_WDS_ADDRESS6[i];
 752        }
 753#endif  /* USE_WDS */
 754#endif  /* HCF_AP */
 755#ifdef USE_RTS
 756        if ( strchr( "Yy", useRTS[0] ) != NULL ) {
 757                lp->useRTS = 1;
 758        } else {
 759                lp->useRTS = 0;
 760        }
 761#endif  /* USE_RTS */
 762
 763
 764        /* END NEW PARAMETERS */
 765
 766
 767        wl_lock( lp, &flags );
 768
 769        /* Initialize the portState variable */
 770        lp->portState = WVLAN_PORT_STATE_DISABLED;
 771
 772        /* Initialize the ScanResult struct */
 773        memset( &( lp->scan_results ), 0, sizeof( lp->scan_results ));
 774        lp->scan_results.scan_complete = FALSE;
 775
 776        /* Initialize the ProbeResult struct */
 777        memset( &( lp->probe_results ), 0, sizeof( lp->probe_results ));
 778        lp->probe_results.scan_complete = FALSE;
 779        lp->probe_num_aps = 0;
 780
 781
 782        /* Initialize Tx queue stuff */
 783        memset( lp->txList, 0, sizeof( lp->txList ));
 784
 785        INIT_LIST_HEAD( &( lp->txFree ));
 786
 787        lp->txF.skb  = NULL;
 788        lp->txF.port = 0;
 789
 790
 791        for( i = 0; i < DEFAULT_NUM_TX_FRAMES; i++ ) {
 792                list_add_tail( &( lp->txList[i].node ), &( lp->txFree ));
 793        }
 794
 795
 796        for( i = 0; i < WVLAN_MAX_TX_QUEUES; i++ ) {
 797                INIT_LIST_HEAD( &( lp->txQ[i] ));
 798        }
 799
 800        lp->netif_queue_on = TRUE;
 801        lp->txQ_count = 0;
 802        /* Initialize the use_dma element in the adapter structure. Not sure if
 803           this should be a compile-time or run-time configurable. So for now,
 804           implement as run-time and just define here */
 805#ifdef WARP
 806#ifdef ENABLE_DMA
 807        DBG_TRACE( DbgInfo, "HERMES 2.5 BUSMASTER DMA MODE\n" );
 808        lp->use_dma = 1;
 809#else
 810        DBG_TRACE( DbgInfo, "HERMES 2.5 PORT I/O MODE\n" );
 811        lp->use_dma = 0;
 812#endif // ENABLE_DMA
 813#endif // WARP
 814
 815        /* Register the ISR handler information here, so that it's not done
 816           repeatedly in the ISR */
 817        tasklet_init(&lp->task, wl_isr_handler, (unsigned long)lp);
 818
 819        /* Connect to the adapter */
 820        DBG_TRACE( DbgInfo, "Calling hcf_connect()...\n" );
 821        hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
 822        //HCF_ERR_INCOMP_FW is acceptable, because download must still take place
 823        //HCF_ERR_INCOMP_PRI is not acceptable
 824        if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
 825                DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
 826                wl_unlock( lp, &flags );
 827                goto hcf_failed;
 828        }
 829
 830        //;?should set HCF_version and how about driver_stat
 831        lp->driverInfo.IO_address       = dev->base_addr;
 832        lp->driverInfo.IO_range         = HCF_NUM_IO_PORTS;     //;?conditionally 0x40 or 0x80 seems better
 833        lp->driverInfo.IRQ_number       = dev->irq;
 834        lp->driverInfo.card_stat        = lp->hcfCtx.IFB_CardStat;
 835        //;? what happened to frame_type
 836
 837        /* Fill in the driver identity structure */
 838        lp->driverIdentity.len              = ( sizeof( lp->driverIdentity ) / sizeof( hcf_16 )) - 1;
 839        lp->driverIdentity.typ              = CFG_DRV_IDENTITY;
 840        lp->driverIdentity.comp_id          = DRV_IDENTITY;
 841        lp->driverIdentity.variant          = DRV_VARIANT;
 842        lp->driverIdentity.version_major    = DRV_MAJOR_VERSION;
 843        lp->driverIdentity.version_minor    = DRV_MINOR_VERSION;
 844
 845
 846        /* Start the card here - This needs to be done in order to get the
 847           MAC address for the network layer */
 848        DBG_TRACE( DbgInfo, "Calling wvlan_go() to perform a card reset...\n" );
 849        hcf_status = wl_go( lp );
 850
 851        if ( hcf_status != HCF_SUCCESS ) {
 852                DBG_ERROR( DbgInfo, "wl_go() failed\n" );
 853                wl_unlock( lp, &flags );
 854                goto hcf_failed;
 855        }
 856
 857        /* Certain RIDs must be set before enabling the ports */
 858        wl_put_ltv_init( lp );
 859
 860#if 0 //;?why was this already commented out in wl_lkm_720
 861        /* Enable the ports */
 862        if ( wl_adapter_is_open( lp->dev )) {
 863                /* Enable the ports */
 864                DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
 865                hcf_status = wl_enable( lp );
 866
 867                if ( hcf_status != HCF_SUCCESS ) {
 868                        DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", hcf_status );
 869                }
 870
 871#if (HCF_TYPE) & HCF_TYPE_AP
 872                DBG_TRACE( DbgInfo, "Enabling WDS Ports\n" );
 873                //wl_enable_wds_ports( lp );
 874#endif  /* (HCF_TYPE) & HCF_TYPE_AP */
 875
 876        }
 877#endif
 878
 879        /* Fill out the MAC address information in the net_device struct */
 880        memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN );
 881        dev->addr_len = ETH_ALEN;
 882
 883        lp->is_registered = TRUE;
 884
 885#ifdef USE_PROFILE
 886        /* Parse the config file for the sake of creating WDS ports if WDS is
 887           configured there but not in the module options */
 888        parse_config( dev );
 889#endif  /* USE_PROFILE */
 890
 891        /* If we're going into AP Mode, register the "virtual" ethernet devices
 892           needed for WDS */
 893        WL_WDS_NETDEV_REGISTER( lp );
 894
 895        /* Reset the DownloadFirmware variable in the private struct. If the
 896           config file is not used, this will not matter; if it is used, it
 897           will be reparsed in wl_open(). This is done because logic in wl_open
 898           used to check if a firmware download is needed is broken by parsing
 899           the file here; however, this parsing is needed to register WDS ports
 900           in AP mode, if they are configured */
 901        lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //;?download_firmware;
 902
 903#ifdef USE_RTS
 904        if ( lp->useRTS == 1 ) {
 905                DBG_TRACE( DbgInfo, "ENTERING RTS MODE...\n" );
 906                wl_act_int_off( lp );
 907                lp->is_handling_int = WL_NOT_HANDLING_INT; // Not handling interrupts anymore
 908
 909                wl_disable( lp );
 910
 911                hcf_connect( &lp->hcfCtx, HCF_DISCONNECT);
 912        }
 913#endif  /* USE_RTS */
 914
 915        wl_unlock( lp, &flags );
 916
 917        DBG_TRACE( DbgInfo, "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
 918                           dev->name, dev->base_addr, dev->irq );
 919
 920        for( i = 0; i < ETH_ALEN; i++ ) {
 921                printk( "%02X%c", dev->dev_addr[i], (( i < ( ETH_ALEN-1 )) ? ':' : '\n' ));
 922        }
 923
 924#if 0 //SCULL_USE_PROC /* don't waste space if unused */
 925        proc_create_data( "wlags", 0, NULL, &scull_read_procmem_fops, dev );
 926        proc_mkdir("driver/wlags49", 0);
 927#endif /* SCULL_USE_PROC */
 928
 929        DBG_LEAVE( DbgInfo );
 930        return result;
 931
 932hcf_failed:
 933        wl_hcf_error( dev, hcf_status );
 934
 935failed:
 936
 937        DBG_ERROR( DbgInfo, "wl_insert() FAILED\n" );
 938
 939        if ( lp->is_registered == TRUE ) {
 940                lp->is_registered = FALSE;
 941        }
 942
 943        WL_WDS_NETDEV_DEREGISTER( lp );
 944
 945        result = -EFAULT;
 946
 947
 948        DBG_LEAVE( DbgInfo );
 949        return result;
 950} // wl_insert
 951/*============================================================================*/
 952
 953
 954/*******************************************************************************
 955 *      wl_reset()
 956 *******************************************************************************
 957 *
 958 *  DESCRIPTION:
 959 *
 960 *      Reset the adapter.
 961 *
 962 *  PARAMETERS:
 963 *
 964 *      dev - a pointer to the net_device struct of the wireless device
 965 *
 966 *  RETURNS:
 967 *
 968 *      an HCF status code
 969 *
 970 ******************************************************************************/
 971int wl_reset(struct net_device *dev)
 972{
 973        struct wl_private  *lp = wl_priv(dev);
 974        int                 hcf_status = HCF_SUCCESS;
 975        /*------------------------------------------------------------------------*/
 976        DBG_FUNC( "wl_reset" );
 977        DBG_ENTER( DbgInfo );
 978        DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
 979        DBG_PARAM( DbgInfo, "dev->base_addr", "(%#03lx)", dev->base_addr );
 980
 981        /*
 982         * The caller should already have a lock and
 983         * disable the interrupts, we do not lock here,
 984         * nor do we enable/disable interrupts!
 985         */
 986
 987        DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", dev->base_addr );
 988        if ( dev->base_addr ) {
 989                /* Shutdown the adapter. */
 990                hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
 991
 992                /* Reset the driver information. */
 993                lp->txBytes = 0;
 994
 995                /* Connect to the adapter. */
 996                hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
 997                if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
 998                        DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
 999                        goto out;
1000                }
1001
1002                /* Check if firmware is present, if not change state */
1003                if ( hcf_status == HCF_ERR_INCOMP_FW ) {
1004                        lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1005                }
1006
1007                /* Initialize the portState variable */
1008                lp->portState = WVLAN_PORT_STATE_DISABLED;
1009
1010                /* Restart the adapter. */
1011                hcf_status = wl_go( lp );
1012                if ( hcf_status != HCF_SUCCESS ) {
1013                        DBG_ERROR( DbgInfo, "wl_go() failed, status: 0x%x\n", hcf_status );
1014                        goto out;
1015                }
1016
1017                /* Certain RIDs must be set before enabling the ports */
1018                wl_put_ltv_init( lp );
1019        } else {
1020                DBG_ERROR( DbgInfo, "Device Base Address INVALID!!!\n" );
1021        }
1022
1023out:
1024        DBG_LEAVE( DbgInfo );
1025        return hcf_status;
1026} // wl_reset
1027/*============================================================================*/
1028
1029
1030/*******************************************************************************
1031 *      wl_go()
1032 *******************************************************************************
1033 *
1034 *  DESCRIPTION:
1035 *
1036 *      Reset the adapter.
1037 *
1038 *  PARAMETERS:
1039 *
1040 *      dev - a pointer to the net_device struct of the wireless device
1041 *
1042 *  RETURNS:
1043 *
1044 *      an HCF status code
1045 *
1046 ******************************************************************************/
1047int wl_go( struct wl_private *lp )
1048{
1049        int     hcf_status = HCF_SUCCESS;
1050        char    *cp = NULL;                     //fw_image
1051        int     retries = 0;
1052        /*------------------------------------------------------------------------*/
1053        DBG_FUNC( "wl_go" );
1054        DBG_ENTER( DbgInfo );
1055
1056        hcf_status = wl_disable( lp );
1057        if ( hcf_status != HCF_SUCCESS ) {
1058                DBG_TRACE( DbgInfo, "Disable port 0 failed: 0x%x\n", hcf_status );
1059
1060                while (( hcf_status != HCF_SUCCESS ) && (retries < 10)) {
1061                        retries++;
1062                        hcf_status = wl_disable( lp );
1063                }
1064                if ( hcf_status == HCF_SUCCESS ) {
1065                        DBG_TRACE( DbgInfo, "Disable port 0 succes : %d retries\n", retries );
1066                } else {
1067                        DBG_TRACE( DbgInfo, "Disable port 0 failed after: %d retries\n", retries );
1068                }
1069        }
1070
1071#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
1072        //DBG_TRACE( DbgInfo, "Disabling WDS Ports\n" );
1073        //wl_disable_wds_ports( lp );
1074#endif  /* (HCF_TYPE) & HCF_TYPE_AP */
1075
1076//;?what was the purpose of this
1077//      /* load the appropriate firmware image, depending on driver mode */
1078//      lp->ltvRecord.len   = ( sizeof( CFG_RANGE20_STRCT ) / sizeof( hcf_16 )) - 1;
1079//      lp->ltvRecord.typ   = CFG_DRV_ACT_RANGES_PRI;
1080//      hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1081
1082#if BIN_DL
1083        if ( strlen( lp->fw_image_filename ) ) {
1084mm_segment_t    fs;
1085int                     file_desc;
1086int                     rc;
1087
1088                DBG_TRACE( DbgInfo, "F/W image:%s:\n", lp->fw_image_filename );
1089                /* Obtain a user-space process context, storing the original context */
1090                fs = get_fs( );
1091                set_fs( get_ds( ));
1092                file_desc = open( lp->fw_image_filename, O_RDONLY, 0 );
1093                if ( file_desc == -1 ) {
1094                        DBG_ERROR( DbgInfo, "No image file found\n" );
1095                } else {
1096                        DBG_TRACE( DbgInfo, "F/W image file found\n" );
1097#define DHF_ALLOC_SIZE 96000                    //just below 96K, let's hope it suffices for now and for the future
1098                        cp = (char*)vmalloc( DHF_ALLOC_SIZE );
1099                        if ( cp == NULL ) {
1100                                DBG_ERROR( DbgInfo, "error in vmalloc\n" );
1101                        } else {
1102                                rc = read( file_desc, cp, DHF_ALLOC_SIZE );
1103                                if ( rc == DHF_ALLOC_SIZE ) {
1104                                        DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE );
1105                                } else if ( rc > 0 ) {
1106                                        DBG_TRACE( DbgInfo, "read O.K.: %d bytes  %.12s\n", rc, cp );
1107                                        rc = read( file_desc, &cp[rc], 1 );
1108                                        if ( rc == 0 ) { //;/change to an until-loop at rc<=0
1109                                                DBG_TRACE( DbgInfo, "no more to read\n" );
1110                                        }
1111                                }
1112                                if ( rc != 0 ) {
1113                                        DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\
1114                                                                                ", give up, too complicated, rc = %0X\n", rc );
1115                                        DBG_ERROR( DbgInfo, "still have to change code to get a real download now !!!!!!!!\n" );
1116                                } else {
1117                                        DBG_TRACE( DbgInfo, "before dhf_download_binary\n" );
1118                                        hcf_status = dhf_download_binary( (memimage *)cp );
1119                                        DBG_TRACE( DbgInfo, "after dhf_download_binary, before dhf_download_fw\n" );
1120                                        //;?improve error flow/handling
1121                                        hcf_status = dhf_download_fw( &lp->hcfCtx, (memimage *)cp );
1122                                        DBG_TRACE( DbgInfo, "after dhf_download_fw\n" );
1123                                }
1124                                vfree( cp );
1125                        }
1126                        close( file_desc );
1127                }
1128                set_fs( fs );                   /* Return to the original context */
1129        }
1130#endif // BIN_DL
1131
1132        /* If firmware is present but the type is unknown then download anyway */
1133        if ( (lp->firmware_present == WL_FRIMWARE_PRESENT)
1134             &&
1135             ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_STA )
1136             &&
1137             ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_AP ) ) {
1138                /* Unknown type, download needed.  */
1139                lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1140        }
1141
1142        if(lp->firmware_present == WL_FRIMWARE_NOT_PRESENT)
1143        {
1144                if ( cp == NULL ) {
1145                        DBG_TRACE( DbgInfo, "Downloading STA firmware...\n" );
1146//                      hcf_status = dhf_download_fw( &lp->hcfCtx, &station );
1147                        hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image );
1148                }
1149                if ( hcf_status != HCF_SUCCESS ) {
1150                        DBG_ERROR( DbgInfo, "Firmware Download failed\n" );
1151                        DBG_LEAVE( DbgInfo );
1152                        return hcf_status;
1153                }
1154        }
1155        /* Report the FW versions */
1156        //;?obsolete, use the available IFB info:: wl_get_pri_records( lp );
1157        if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA  ) {
1158                DBG_TRACE( DbgInfo, "downloaded station F/W\n" );
1159        } else if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
1160                DBG_TRACE( DbgInfo, "downloaded AP F/W\n" );
1161        } else {
1162                DBG_ERROR( DbgInfo, "unknown F/W type\n" );
1163        }
1164
1165        /*
1166         * Downloaded, no need to repeat this next time, assume the
1167         * contents stays in the card until it is powered off. Note we
1168         * do not switch firmware on the fly, the firmware is fixed in
1169         * the driver for now.
1170         */
1171        lp->firmware_present = WL_FRIMWARE_PRESENT;
1172
1173        DBG_TRACE( DbgInfo, "ComponentID:%04x variant:%04x major:%04x minor:%04x\n",
1174                                CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ),
1175                                CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.variant ),
1176                                CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_major ),
1177                                CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_minor ));
1178
1179        /* now we will get the MAC address of the card */
1180        lp->ltvRecord.len = 4;
1181        if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
1182                lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1183        } else
1184        {
1185                lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1186        }
1187        hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1188        if ( hcf_status != HCF_SUCCESS ) {
1189                DBG_ERROR( DbgInfo, "Could not retrieve MAC address\n" );
1190                DBG_LEAVE( DbgInfo );
1191                return hcf_status;
1192        }
1193        memcpy( lp->MACAddress, &lp->ltvRecord.u.u8[0], ETH_ALEN );
1194        DBG_TRACE(DbgInfo, "Card MAC Address: %pM\n", lp->MACAddress);
1195
1196        /* Write out configuration to the device, enable, and reconnect. However,
1197           only reconnect if in AP mode. For STA mode, need to wait for passive scan
1198           completion before a connect can be issued */
1199        wl_put_ltv( lp );
1200        /* Enable the ports */
1201        hcf_status = wl_enable( lp );
1202
1203        if ( lp->DownloadFirmware == WVLAN_DRV_MODE_AP ) {
1204#ifdef USE_WDS
1205                wl_enable_wds_ports( lp );
1206#endif // USE_WDS
1207                hcf_status = wl_connect( lp );
1208        }
1209        DBG_LEAVE( DbgInfo );
1210        return hcf_status;
1211} // wl_go
1212/*============================================================================*/
1213
1214
1215/*******************************************************************************
1216 *      wl_set_wep_keys()
1217 *******************************************************************************
1218 *
1219 *  DESCRIPTION:
1220 *
1221 *      Write TxKeyID and WEP keys to the adapter. This is separated from
1222 *  wl_apply() to allow dynamic WEP key updates through the wireless
1223 *  extensions.
1224 *
1225 *  PARAMETERS:
1226 *
1227 *      lp  - a pointer to the wireless adapter's private structure
1228 *
1229 *  RETURNS:
1230 *
1231 *      N/A
1232 *
1233 ******************************************************************************/
1234void wl_set_wep_keys( struct wl_private *lp )
1235{
1236        int count = 0;
1237        /*------------------------------------------------------------------------*/
1238        DBG_FUNC( "wl_set_wep_keys" );
1239        DBG_ENTER( DbgInfo );
1240        DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1241        if ( lp->EnableEncryption ) {
1242                /* NOTE: CFG_CNF_ENCRYPTION is set in wl_put_ltv() as it's a static
1243                                 RID */
1244
1245                /* set TxKeyID */
1246                lp->ltvRecord.len = 2;
1247                lp->ltvRecord.typ       = CFG_TX_KEY_ID;
1248                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE(lp->TransmitKeyID - 1);
1249
1250                hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1251
1252                DBG_TRACE( DbgInfo, "Key 1 len: %d\n", lp->DefaultKeys.key[0].len );
1253                DBG_TRACE( DbgInfo, "Key 2 len: %d\n", lp->DefaultKeys.key[1].len );
1254                DBG_TRACE( DbgInfo, "Key 3 len: %d\n", lp->DefaultKeys.key[2].len );
1255                DBG_TRACE( DbgInfo, "Key 4 len: %d\n", lp->DefaultKeys.key[3].len );
1256
1257                /* write keys */
1258                lp->DefaultKeys.len = sizeof( lp->DefaultKeys ) / sizeof( hcf_16 ) - 1;
1259                lp->DefaultKeys.typ = CFG_DEFAULT_KEYS;
1260
1261                /* endian translate the appropriate key information */
1262                for( count = 0; count < MAX_KEYS; count++ ) {
1263                        lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1264                }
1265
1266                hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->DefaultKeys ));
1267
1268                /* Reverse the above endian translation, since these keys are accessed
1269                   elsewhere */
1270                for( count = 0; count < MAX_KEYS; count++ ) {
1271                        lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1272                }
1273
1274                DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption, lp->TransmitKeyID );
1275                DBG_NOTICE( DbgInfo, "set key: %s(%d) [%d]\n", lp->DefaultKeys.key[lp->TransmitKeyID-1].key, lp->DefaultKeys.key[lp->TransmitKeyID-1].len, lp->TransmitKeyID-1 );
1276        }
1277
1278        DBG_LEAVE( DbgInfo );
1279} // wl_set_wep_keys
1280/*============================================================================*/
1281
1282
1283/*******************************************************************************
1284 *      wl_apply()
1285 *******************************************************************************
1286 *
1287 *  DESCRIPTION:
1288 *
1289 *      Write the parameters to the adapter. (re-)enables the card if device is
1290 *  open. Returns hcf_status of hcf_enable().
1291 *
1292 *  PARAMETERS:
1293 *
1294 *      lp  - a pointer to the wireless adapter's private structure
1295 *
1296 *  RETURNS:
1297 *
1298 *      an HCF status code
1299 *
1300 ******************************************************************************/
1301int wl_apply(struct wl_private *lp)
1302{
1303        int hcf_status = HCF_SUCCESS;
1304        /*------------------------------------------------------------------------*/
1305        DBG_FUNC( "wl_apply" );
1306        DBG_ENTER( DbgInfo );
1307        DBG_ASSERT( lp != NULL);
1308        DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1309
1310        if ( !( lp->flags & WVLAN2_UIL_BUSY )) {
1311                /* The adapter parameters have changed:
1312                                disable card
1313                                reload parameters
1314                                enable card
1315                */
1316
1317                if ( wl_adapter_is_open( lp->dev )) {
1318                        /* Disconnect and disable if necessary */
1319                        hcf_status = wl_disconnect( lp );
1320                        if ( hcf_status != HCF_SUCCESS ) {
1321                                DBG_ERROR( DbgInfo, "Disconnect failed\n" );
1322                                DBG_LEAVE( DbgInfo );
1323                                return -1;
1324                        }
1325                        hcf_status = wl_disable( lp );
1326                        if ( hcf_status != HCF_SUCCESS ) {
1327                                DBG_ERROR( DbgInfo, "Disable failed\n" );
1328                                DBG_LEAVE( DbgInfo );
1329                                return -1;
1330                        } else {
1331                                /* Write out configuration to the device, enable, and reconnect.
1332                                   However, only reconnect if in AP mode. For STA mode, need to
1333                                   wait for passive scan completion before a connect can be
1334                                   issued */
1335                                hcf_status = wl_put_ltv( lp );
1336
1337                                if ( hcf_status == HCF_SUCCESS ) {
1338                                        hcf_status = wl_enable( lp );
1339
1340                                        if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
1341                                                hcf_status = wl_connect( lp );
1342                                        }
1343                                } else {
1344                                        DBG_WARNING( DbgInfo, "wl_put_ltv() failed\n" );
1345                                }
1346                        }
1347                }
1348        }
1349
1350        DBG_LEAVE( DbgInfo );
1351        return hcf_status;
1352} // wl_apply
1353/*============================================================================*/
1354
1355
1356/*******************************************************************************
1357 *      wl_put_ltv_init()
1358 *******************************************************************************
1359 *
1360 *  DESCRIPTION:
1361 *
1362 *      Used to set basic parameters for card initialization.
1363 *
1364 *  PARAMETERS:
1365 *
1366 *      lp  - a pointer to the wireless adapter's private structure
1367 *
1368 *  RETURNS:
1369 *
1370 *      an HCF status code
1371 *
1372 ******************************************************************************/
1373int wl_put_ltv_init( struct wl_private *lp )
1374{
1375        int i;
1376        int hcf_status;
1377        CFG_RID_LOG_STRCT *RidLog;
1378        /*------------------------------------------------------------------------*/
1379        DBG_FUNC( "wl_put_ltv_init" );
1380        DBG_ENTER( DbgInfo );
1381        if ( lp == NULL ) {
1382                DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1383                DBG_LEAVE( DbgInfo );
1384                return -1;
1385        }
1386        /* DMA/IO */
1387        lp->ltvRecord.len = 2;
1388        lp->ltvRecord.typ = CFG_CNTL_OPT;
1389
1390        /* The Card Services build must ALWAYS be configured for 16-bit I/O. PCI or
1391           CardBus can be set to either 16/32 bit I/O, or Bus Master DMA, but only
1392           for Hermes-2.5 */
1393#ifdef BUS_PCMCIA
1394        lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_16BIT );
1395#else
1396        if ( lp->use_dma ) {
1397                lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_DMA );
1398        } else {
1399                lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1400        }
1401
1402#endif
1403        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1404        DBG_TRACE( DbgInfo, "CFG_CNTL_OPT                      : 0x%04x\n",
1405                           lp->ltvRecord.u.u16[0] );
1406        DBG_TRACE( DbgInfo, "CFG_CNTL_OPT result               : 0x%04x\n",
1407                           hcf_status );
1408
1409        /* Register the list of RIDs on which asynchronous notification is
1410           required. Note that this mechanism replaces the mailbox, so the mailbox
1411           can be queried by the host (if desired) without contention from us */
1412        i=0;
1413
1414        lp->RidList[i].len     = sizeof( lp->ProbeResp );
1415        lp->RidList[i].typ     = CFG_ACS_SCAN;
1416        lp->RidList[i].bufp    = (wci_recordp)&lp->ProbeResp;
1417        //lp->ProbeResp.infoType = 0xFFFF;
1418        i++;
1419
1420        lp->RidList[i].len     = sizeof( lp->assoc_stat );
1421        lp->RidList[i].typ     = CFG_ASSOC_STAT;
1422        lp->RidList[i].bufp    = (wci_recordp)&lp->assoc_stat;
1423        lp->assoc_stat.len     = 0xFFFF;
1424        i++;
1425
1426        lp->RidList[i].len     = 4;
1427        lp->RidList[i].typ     = CFG_UPDATED_INFO_RECORD;
1428        lp->RidList[i].bufp    = (wci_recordp)&lp->updatedRecord;
1429        lp->updatedRecord.len  = 0xFFFF;
1430        i++;
1431
1432        lp->RidList[i].len     = sizeof( lp->sec_stat );
1433        lp->RidList[i].typ     = CFG_SECURITY_STAT;
1434        lp->RidList[i].bufp    = (wci_recordp)&lp->sec_stat;
1435        lp->sec_stat.len       = 0xFFFF;
1436        i++;
1437
1438        lp->RidList[i].typ     = 0;    // Terminate List
1439
1440        RidLog = (CFG_RID_LOG_STRCT *)&lp->ltvRecord;
1441        RidLog->len     = 3;
1442        RidLog->typ     = CFG_REG_INFO_LOG;
1443        RidLog->recordp = (RID_LOGP)&lp->RidList[0];
1444
1445        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1446        DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG\n" );
1447        DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG result           : 0x%04x\n",
1448                           hcf_status );
1449        DBG_LEAVE( DbgInfo );
1450        return hcf_status;
1451} // wl_put_ltv_init
1452/*============================================================================*/
1453
1454
1455/*******************************************************************************
1456 *      wl_put_ltv()
1457 *******************************************************************************
1458 *
1459 *  DESCRIPTION:
1460 *
1461 *      Used by wvlan_apply() and wvlan_go to set the card's configuration.
1462 *
1463 *  PARAMETERS:
1464 *
1465 *      lp  - a pointer to the wireless adapter's private structure
1466 *
1467 *  RETURNS:
1468 *
1469 *      an HCF status code
1470 *
1471 ******************************************************************************/
1472int wl_put_ltv( struct wl_private *lp )
1473{
1474        int len;
1475        int hcf_status;
1476        /*------------------------------------------------------------------------*/
1477        DBG_FUNC( "wl_put_ltv" );
1478        DBG_ENTER( DbgInfo );
1479
1480        if ( lp == NULL ) {
1481                DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1482                return -1;
1483        }
1484        if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
1485                lp->maxPort = 6;                        //;?why set this here and not as part of download process
1486        } else {
1487                lp->maxPort = 0;
1488        }
1489
1490        /* Send our configuration to the card. Perform any endian translation
1491           necessary */
1492        /* Register the Mailbox; VxWorks does this elsewhere; why;? */
1493        lp->ltvRecord.len       = 4;
1494        lp->ltvRecord.typ       = CFG_REG_MB;
1495        lp->ltvRecord.u.u32[0]  = (u_long)&( lp->mailbox );
1496        lp->ltvRecord.u.u16[2]  = ( MB_SIZE / sizeof( hcf_16 ));
1497        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1498
1499        /* Max Data Length */
1500        lp->ltvRecord.len       = 2;
1501        lp->ltvRecord.typ       = CFG_CNF_MAX_DATA_LEN;
1502        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( HCF_MAX_PACKET_SIZE );
1503        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1504
1505        /* System Scale / Distance between APs */
1506        lp->ltvRecord.len       = 2;
1507        lp->ltvRecord.typ       = CFG_CNF_SYSTEM_SCALE;
1508        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->DistanceBetweenAPs );
1509        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1510
1511        /* Channel */
1512        if ( lp->CreateIBSS && ( lp->Channel == 0 )) {
1513                DBG_TRACE( DbgInfo, "Create IBSS" );
1514                lp->Channel = 10;
1515        }
1516        lp->ltvRecord.len       = 2;
1517        lp->ltvRecord.typ       = CFG_CNF_OWN_CHANNEL;
1518        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->Channel );
1519        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1520
1521        /* Microwave Robustness */
1522        lp->ltvRecord.len       = 2;
1523        lp->ltvRecord.typ       = CFG_CNF_MICRO_WAVE;
1524        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->MicrowaveRobustness );
1525        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1526
1527        /* Load Balancing */
1528        lp->ltvRecord.len       = 2;
1529        lp->ltvRecord.typ       = CFG_CNF_LOAD_BALANCING;
1530        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->loadBalancing );
1531        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1532
1533        /* Medium Distribution */
1534        lp->ltvRecord.len       = 2;
1535        lp->ltvRecord.typ       = CFG_CNF_MEDIUM_DISTRIBUTION;
1536        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->mediumDistribution );
1537        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1538        /* Country Code */
1539
1540#ifdef WARP
1541        /* Tx Power Level (for supported cards) */
1542        lp->ltvRecord.len       = 2;
1543        lp->ltvRecord.typ       = CFG_CNF_TX_POW_LVL;
1544        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->txPowLevel );
1545        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1546
1547        /* Short Retry Limit */
1548        /*lp->ltvRecord.len       = 2;
1549        lp->ltvRecord.typ       = 0xFC32;
1550        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->shortRetryLimit );
1551        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1552        */
1553
1554        /* Long Retry Limit */
1555        /*lp->ltvRecord.len       = 2;
1556        lp->ltvRecord.typ       = 0xFC33;
1557        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->longRetryLimit );
1558        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1559        */
1560
1561        /* Supported Rate Set Control */
1562        lp->ltvRecord.len       = 3;
1563        lp->ltvRecord.typ       = CFG_SUPPORTED_RATE_SET_CNTL; //0xFC88;
1564        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->srsc[0] );
1565        lp->ltvRecord.u.u16[1]  = CNV_INT_TO_LITTLE( lp->srsc[1] );
1566        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1567
1568        /* Basic Rate Set Control */
1569        lp->ltvRecord.len       = 3;
1570        lp->ltvRecord.typ       = CFG_BASIC_RATE_SET_CNTL; //0xFC89;
1571        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->brsc[0] );
1572        lp->ltvRecord.u.u16[1]  = CNV_INT_TO_LITTLE( lp->brsc[1] );
1573        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1574
1575        /* Frame Burst Limit */
1576        /* Defined, but not currently available in Firmware */
1577
1578#endif // WARP
1579
1580#ifdef WARP
1581        /* Multicast Rate */
1582        lp->ltvRecord.len       = 3;
1583        lp->ltvRecord.typ       = CFG_CNF_MCAST_RATE;
1584        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1585        lp->ltvRecord.u.u16[1]  = CNV_INT_TO_LITTLE( lp->MulticastRate[1] );
1586#else
1587        lp->ltvRecord.len       = 2;
1588        lp->ltvRecord.typ       = CFG_CNF_MCAST_RATE;
1589        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1590#endif // WARP
1591        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1592
1593        /* Own Name (Station Nickname) */
1594        if (( len = ( strlen( lp->StationName ) + 1 ) & ~0x01 ) != 0 ) {
1595                //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME                  : %s\n",
1596                //           lp->StationName );
1597
1598                lp->ltvRecord.len       = 2 + ( len / sizeof( hcf_16 ));
1599                lp->ltvRecord.typ       = CFG_CNF_OWN_NAME;
1600                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( strlen( lp->StationName ));
1601
1602                memcpy( &( lp->ltvRecord.u.u8[2] ), lp->StationName, len );
1603        } else {
1604                //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME                  : EMPTY\n" );
1605
1606                lp->ltvRecord.len       = 2;
1607                lp->ltvRecord.typ       = CFG_CNF_OWN_NAME;
1608                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0 );
1609        }
1610
1611        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1612
1613        //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME result           : 0x%04x\n",
1614        //           hcf_status );
1615
1616        /* The following are set in STA mode only */
1617        if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA  ) {
1618
1619                /* RTS Threshold */
1620                lp->ltvRecord.len       = 2;
1621                lp->ltvRecord.typ       = CFG_RTS_THRH;
1622                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1623                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1624
1625                /* Port Type */
1626                lp->ltvRecord.len       = 2;
1627                lp->ltvRecord.typ       = CFG_CNF_PORT_TYPE;
1628                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->PortType );
1629                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1630
1631                /* Tx Rate Control */
1632#ifdef WARP
1633                lp->ltvRecord.len       = 3;
1634                lp->ltvRecord.typ       = CFG_TX_RATE_CNTL;
1635                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1636                lp->ltvRecord.u.u16[1]  = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1637#else
1638                lp->ltvRecord.len       = 2;
1639                lp->ltvRecord.typ       = CFG_TX_RATE_CNTL;
1640                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1641#endif  // WARP
1642
1643//;?skip temporarily to see whether the RID or something else is the problem hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1644
1645                DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 2.4GHz           : 0x%04x\n",
1646                                   lp->TxRateControl[0] );
1647                DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 5.0GHz           : 0x%04x\n",
1648                                   lp->TxRateControl[1] );
1649                DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL result           : 0x%04x\n",
1650                                   hcf_status );
1651                /* Power Management */
1652                lp->ltvRecord.len       = 2;
1653                lp->ltvRecord.typ       = CFG_CNF_PM_ENABLED;
1654                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->PMEnabled );
1655//              lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0x8001 );
1656                DBG_TRACE( DbgInfo, "CFG_CNF_PM_ENABLED                : 0x%04x\n", lp->PMEnabled );
1657                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1658                /* Multicast Receive */
1659                lp->ltvRecord.len       = 2;
1660                lp->ltvRecord.typ       = CFG_CNF_MCAST_RX;
1661                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->MulticastReceive );
1662                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1663
1664                /* Max Sleep Duration */
1665                lp->ltvRecord.len       = 2;
1666                lp->ltvRecord.typ       = CFG_CNF_MAX_SLEEP_DURATION;
1667                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->MaxSleepDuration );
1668                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1669
1670                /* Create IBSS */
1671                lp->ltvRecord.len       = 2;
1672                lp->ltvRecord.typ       = CFG_CREATE_IBSS;
1673                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->CreateIBSS );
1674                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1675
1676                /* Desired SSID */
1677                if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1678                         ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1679                         ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1680                        //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID                  : %s\n",
1681                        //           lp->NetworkName );
1682
1683                        lp->ltvRecord.len       = 2 + (len / sizeof(hcf_16));
1684                        lp->ltvRecord.typ       = CFG_DESIRED_SSID;
1685                        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1686
1687                        memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1688                } else {
1689                        //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID                  : ANY\n" );
1690
1691                        lp->ltvRecord.len       = 2;
1692                        lp->ltvRecord.typ       = CFG_DESIRED_SSID;
1693                        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0 );
1694                }
1695
1696                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1697
1698                //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID result           : 0x%04x\n",
1699                //           hcf_status );
1700                /* Own ATIM window */
1701                lp->ltvRecord.len       = 2;
1702                lp->ltvRecord.typ       = CFG_CNF_OWN_ATIM_WINDOW;
1703                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->atimWindow );
1704                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1705
1706
1707                /* Holdover Duration */
1708                lp->ltvRecord.len       = 2;
1709                lp->ltvRecord.typ       = CFG_CNF_HOLDOVER_DURATION;
1710                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->holdoverDuration );
1711                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1712
1713                /* Promiscuous Mode */
1714                lp->ltvRecord.len       = 2;
1715                lp->ltvRecord.typ       = CFG_PROMISCUOUS_MODE;
1716                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->promiscuousMode );
1717                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1718
1719                /* Authentication */
1720                lp->ltvRecord.len       = 2;
1721                lp->ltvRecord.typ       = CFG_CNF_AUTHENTICATION;
1722                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->authentication );
1723                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1724#ifdef WARP
1725                /* Connection Control */
1726                lp->ltvRecord.len       = 2;
1727                lp->ltvRecord.typ       = CFG_CNF_CONNECTION_CNTL;
1728                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->connectionControl );
1729                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1730
1731
1732
1733                /* Probe data rate */
1734                /*lp->ltvRecord.len       = 3;
1735                lp->ltvRecord.typ       = CFG_PROBE_DATA_RATE;
1736                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->probeDataRates[0] );
1737                lp->ltvRecord.u.u16[1]  = CNV_INT_TO_LITTLE( lp->probeDataRates[1] );
1738                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1739
1740                DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 2.4GHz        : 0x%04x\n",
1741                                   lp->probeDataRates[0] );
1742                DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 5.0GHz        : 0x%04x\n",
1743                                   lp->probeDataRates[1] );
1744                DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE result        : 0x%04x\n",
1745                                   hcf_status );*/
1746#endif // WARP
1747        } else {
1748                /* The following are set in AP mode only */
1749#if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
1750                //;?should we restore this to allow smaller memory footprint
1751
1752                /* DTIM Period */
1753                lp->ltvRecord.len       = 2;
1754                lp->ltvRecord.typ       = CFG_CNF_OWN_DTIM_PERIOD;
1755                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->DTIMPeriod );
1756                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1757
1758                /* Multicast PM Buffering */
1759                lp->ltvRecord.len       = 2;
1760                lp->ltvRecord.typ       = CFG_CNF_MCAST_PM_BUF;
1761                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->multicastPMBuffering );
1762                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1763
1764                /* Reject ANY - Closed System */
1765                lp->ltvRecord.len       = 2;
1766                lp->ltvRecord.typ       = CFG_CNF_REJECT_ANY;
1767                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->RejectAny );
1768
1769                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1770
1771                /* Exclude Unencrypted */
1772                lp->ltvRecord.len       = 2;
1773                lp->ltvRecord.typ       = CFG_CNF_EXCL_UNENCRYPTED;
1774                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->ExcludeUnencrypted );
1775
1776                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1777
1778                /* IntraBSS Relay */
1779                lp->ltvRecord.len       = 2;
1780                lp->ltvRecord.typ       = CFG_CNF_INTRA_BSS_RELAY;
1781                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->intraBSSRelay );
1782                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1783
1784                /* RTS Threshold 0 */
1785                lp->ltvRecord.len       = 2;
1786                lp->ltvRecord.typ       = CFG_RTS_THRH0;
1787                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1788
1789                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1790
1791                /* Tx Rate Control 0 */
1792#ifdef WARP
1793                lp->ltvRecord.len       = 3;
1794                lp->ltvRecord.typ       = CFG_TX_RATE_CNTL0;
1795                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1796                lp->ltvRecord.u.u16[1]  = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1797#else
1798                lp->ltvRecord.len       = 2;
1799                lp->ltvRecord.typ       = CFG_TX_RATE_CNTL0;
1800                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1801#endif  // WARP
1802
1803                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1804
1805                /* Own Beacon Interval */
1806                lp->ltvRecord.len       = 2;
1807                lp->ltvRecord.typ       = 0xFC31;
1808                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->ownBeaconInterval );
1809                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1810
1811                /* Co-Existence Behavior */
1812                lp->ltvRecord.len       = 2;
1813                lp->ltvRecord.typ       = 0xFCC7;
1814                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->coexistence );
1815                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1816
1817#ifdef USE_WDS
1818
1819                /* RTS Threshold 1 */
1820                lp->ltvRecord.len       = 2;
1821                lp->ltvRecord.typ       = CFG_RTS_THRH1;
1822                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[0].rtsThreshold );
1823                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1824
1825                /* RTS Threshold 2 */
1826                lp->ltvRecord.len       = 2;
1827                lp->ltvRecord.typ       = CFG_RTS_THRH2;
1828                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[1].rtsThreshold );
1829                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1830
1831
1832                /* RTS Threshold 3 */
1833                lp->ltvRecord.len       = 2;
1834                lp->ltvRecord.typ       = CFG_RTS_THRH3;
1835                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[2].rtsThreshold );
1836                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1837
1838
1839                /* RTS Threshold 4 */
1840                lp->ltvRecord.len       = 2;
1841                lp->ltvRecord.typ       = CFG_RTS_THRH4;
1842                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[3].rtsThreshold );
1843                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1844
1845
1846                /* RTS Threshold 5 */
1847                lp->ltvRecord.len       = 2;
1848                lp->ltvRecord.typ       = CFG_RTS_THRH5;
1849                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[4].rtsThreshold );
1850                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1851
1852                /* RTS Threshold 6 */
1853                lp->ltvRecord.len       = 2;
1854                lp->ltvRecord.typ       = CFG_RTS_THRH6;
1855                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[5].rtsThreshold );
1856                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1857#if 0
1858                /* TX Rate Control 1 */
1859                lp->ltvRecord.len       = 2;
1860                lp->ltvRecord.typ       = CFG_TX_RATE_CNTL1;
1861                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[0].txRateCntl );
1862                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1863
1864                /* TX Rate Control 2 */
1865                lp->ltvRecord.len       = 2;
1866                lp->ltvRecord.typ       = CFG_TX_RATE_CNTL2;
1867                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[1].txRateCntl );
1868                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1869
1870                /* TX Rate Control 3 */
1871                lp->ltvRecord.len       = 2;
1872                lp->ltvRecord.typ       = CFG_TX_RATE_CNTL3;
1873                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[2].txRateCntl );
1874                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1875
1876                /* TX Rate Control 4 */
1877                lp->ltvRecord.len       = 2;
1878                lp->ltvRecord.typ       = CFG_TX_RATE_CNTL4;
1879                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[3].txRateCntl );
1880                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1881
1882                /* TX Rate Control 5 */
1883                lp->ltvRecord.len       = 2;
1884                lp->ltvRecord.typ       = CFG_TX_RATE_CNTL5;
1885                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[4].txRateCntl );
1886                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1887
1888                /* TX Rate Control 6 */
1889                lp->ltvRecord.len       = 2;
1890                lp->ltvRecord.typ       = CFG_TX_RATE_CNTL6;
1891                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->wds_port[5].txRateCntl );
1892                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1893
1894#endif
1895
1896                /* WDS addresses.  It's okay to blindly send these parameters, because
1897                   the port needs to be enabled, before anything is done with it. */
1898
1899                /* WDS Address 1 */
1900                lp->ltvRecord.len      = 4;
1901                lp->ltvRecord.typ      = CFG_CNF_WDS_ADDR1;
1902
1903                memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[0].wdsAddress, ETH_ALEN );
1904                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1905
1906                /* WDS Address 2 */
1907                lp->ltvRecord.len      = 4;
1908                lp->ltvRecord.typ      = CFG_CNF_WDS_ADDR2;
1909
1910                memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[1].wdsAddress, ETH_ALEN );
1911                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1912
1913                /* WDS Address 3 */
1914                lp->ltvRecord.len      = 4;
1915                lp->ltvRecord.typ      = CFG_CNF_WDS_ADDR3;
1916
1917                memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[2].wdsAddress, ETH_ALEN );
1918                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1919
1920                /* WDS Address 4 */
1921                lp->ltvRecord.len      = 4;
1922                lp->ltvRecord.typ      = CFG_CNF_WDS_ADDR4;
1923
1924                memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[3].wdsAddress, ETH_ALEN );
1925                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1926
1927                /* WDS Address 5 */
1928                lp->ltvRecord.len      = 4;
1929                lp->ltvRecord.typ      = CFG_CNF_WDS_ADDR5;
1930
1931                memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[4].wdsAddress, ETH_ALEN );
1932                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1933
1934                /* WDS Address 6 */
1935                lp->ltvRecord.len      = 4;
1936                lp->ltvRecord.typ      = CFG_CNF_WDS_ADDR6;
1937
1938                memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[5].wdsAddress, ETH_ALEN );
1939                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1940#endif  /* USE_WDS */
1941#endif  /* (HCF_TYPE) & HCF_TYPE_AP */
1942        }
1943
1944        /* Own MAC Address */
1945/*
1946        DBG_TRACE(DbgInfo, "MAC Address                       : %pM\n",
1947                        lp->MACAddress);
1948 */
1949
1950        if ( WVLAN_VALID_MAC_ADDRESS( lp->MACAddress )) {
1951                /* Make the MAC address valid by:
1952                                Clearing the multicast bit
1953                                Setting the local MAC address bit
1954                */
1955                //lp->MACAddress[0] &= ~0x03;  //;?why is this commented out already in 720
1956                //lp->MACAddress[0] |= 0x02;
1957
1958                lp->ltvRecord.len = 1 + ( ETH_ALEN / sizeof( hcf_16 ));
1959                if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
1960                        //DBG_TRACE( DbgInfo, "CFG_NIC_MAC_ADDR\n" );
1961                        lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1962                } else {
1963                        //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_MAC_ADDR\n" );
1964                        lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1965                }
1966                /* MAC address is byte aligned, no endian conversion needed */
1967                memcpy( &( lp->ltvRecord.u.u8[0] ), lp->MACAddress, ETH_ALEN );
1968                hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1969                //DBG_TRACE( DbgInfo, "CFG_XXX_MAC_ADDR result           : 0x%04x\n",
1970                //           hcf_status );
1971
1972                /* Update the MAC address in the netdevice struct */
1973                memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN ); //;?what is the purpose of this seemingly complex logic
1974        }
1975        /* Own SSID */
1976        if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1977                                 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1978                                 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1979                //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID                  : %s\n",
1980                //           lp->NetworkName );
1981                lp->ltvRecord.len       = 2 + (len / sizeof(hcf_16));
1982                lp->ltvRecord.typ       = CFG_CNF_OWN_SSID;
1983                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1984
1985                memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1986        } else {
1987                //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID                  : ANY\n" );
1988                lp->ltvRecord.len       = 2;
1989                lp->ltvRecord.typ       = CFG_CNF_OWN_SSID;
1990                lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0 );
1991        }
1992
1993        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1994
1995        //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID result           : 0x%04x\n",
1996        //           hcf_status );
1997        /* enable/disable encryption */
1998        lp->ltvRecord.len       = 2;
1999        lp->ltvRecord.typ       = CFG_CNF_ENCRYPTION;
2000        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->EnableEncryption );
2001        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2002
2003        /* Set the Authentication Key Management Suite */
2004        lp->ltvRecord.len       = 2;
2005        lp->ltvRecord.typ       = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
2006        lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( lp->AuthKeyMgmtSuite );
2007        hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2008
2009        /* If WEP (or no) keys are being used, write (or clear) them */
2010        if (lp->wext_enc != IW_ENCODE_ALG_TKIP)
2011                wl_set_wep_keys(lp);
2012
2013        /* Country Code */
2014        /* countryInfo, ltvCountryInfo, CFG_CNF_COUNTRY_INFO */
2015
2016        DBG_LEAVE( DbgInfo );
2017        return hcf_status;
2018} // wl_put_ltv
2019/*============================================================================*/
2020
2021
2022/*******************************************************************************
2023 *      init_module()
2024 *******************************************************************************
2025 *
2026 *  DESCRIPTION:
2027 *
2028 *      Load the kernel module.
2029 *
2030 *  PARAMETERS:
2031 *
2032 *      N/A
2033 *
2034 *  RETURNS:
2035 *
2036 *      0 on success
2037 *      an errno value otherwise
2038 *
2039 ******************************************************************************/
2040static int __init wl_module_init( void )
2041{
2042        int result;
2043        /*------------------------------------------------------------------------*/
2044
2045        DBG_FUNC( "wl_module_init" );
2046
2047#if DBG
2048        /* Convert "standard" PCMCIA parameter pc_debug to a reasonable DebugFlag value.
2049         * NOTE: The values all fall through to the lower values. */
2050        DbgInfo->DebugFlag = 0;
2051        DbgInfo->DebugFlag = DBG_TRACE_ON;              //;?get this mess resolved one day
2052        if ( pc_debug ) switch( pc_debug ) {
2053          case 8:
2054                DbgInfo->DebugFlag |= DBG_DS_ON;
2055          case 7:
2056                DbgInfo->DebugFlag |= DBG_RX_ON | DBG_TX_ON;
2057          case 6:
2058                DbgInfo->DebugFlag |= DBG_PARAM_ON;
2059          case 5:
2060                DbgInfo->DebugFlag |= DBG_TRACE_ON;
2061          case 4:
2062                DbgInfo->DebugFlag |= DBG_VERBOSE_ON;
2063          case 1:
2064                DbgInfo->DebugFlag |= DBG_DEFAULTS;
2065          default:
2066                break;
2067        }
2068#endif /* DBG */
2069
2070        DBG_ENTER( DbgInfo );
2071        printk(KERN_INFO "%s\n", VERSION_INFO);
2072        printk(KERN_INFO "*** Modified for kernel 2.6 by Henk de Groot <pe1dnn@amsat.org>\n");
2073        printk(KERN_INFO "*** Based on 7.18 version by Andrey Borzenkov <arvidjaar@mail.ru> $Revision: 39 $\n");
2074
2075
2076// ;?#if (HCF_TYPE) & HCF_TYPE_AP
2077//      DBG_PRINT( "Access Point Mode (AP) Support: YES\n" );
2078// #else
2079//      DBG_PRINT( "Access Point Mode (AP) Support: NO\n" );
2080// #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2081
2082        result = wl_adapter_init_module( );
2083        DBG_LEAVE( DbgInfo );
2084        return result;
2085} // init_module
2086/*============================================================================*/
2087
2088
2089/*******************************************************************************
2090 *      cleanup_module()
2091 *******************************************************************************
2092 *
2093 *  DESCRIPTION:
2094 *
2095 *      Unload the kernel module.
2096 *
2097 *  PARAMETERS:
2098 *
2099 *      N/A
2100 *
2101 *  RETURNS:
2102 *
2103 *      N/A
2104 *
2105 ******************************************************************************/
2106static void __exit wl_module_exit( void )
2107{
2108        DBG_FUNC( "wl_module_exit" );
2109        DBG_ENTER(DbgInfo);
2110
2111        wl_adapter_cleanup_module( );
2112#if 0 //SCULL_USE_PROC /* don't waste space if unused */
2113        remove_proc_entry( "wlags", NULL );             //;?why so a-symmetric compared to location of proc_create_data
2114#endif
2115
2116        DBG_LEAVE( DbgInfo );
2117        return;
2118} // cleanup_module
2119/*============================================================================*/
2120
2121module_init(wl_module_init);
2122module_exit(wl_module_exit);
2123
2124/*******************************************************************************
2125 *      wl_isr()
2126 *******************************************************************************
2127 *
2128 *  DESCRIPTION:
2129 *
2130 *      The Interrupt Service Routine for the driver.
2131 *
2132 *  PARAMETERS:
2133 *
2134 *      irq     -   the irq the interrupt came in on
2135 *      dev_id  -   a buffer containing information about the request
2136 *      regs    -
2137 *
2138 *  RETURNS:
2139 *
2140 *      N/A
2141 *
2142 ******************************************************************************/
2143irqreturn_t wl_isr( int irq, void *dev_id, struct pt_regs *regs )
2144{
2145        int                 events;
2146        struct net_device   *dev = (struct net_device *) dev_id;
2147        struct wl_private   *lp = NULL;
2148        /*------------------------------------------------------------------------*/
2149        if (( dev == NULL ) || ( !netif_device_present( dev ))) {
2150                return IRQ_NONE;
2151        }
2152
2153        /* Set the wl_private pointer (lp), now that we know that dev is non-null */
2154        lp = wl_priv(dev);
2155
2156#ifdef USE_RTS
2157        if ( lp->useRTS == 1 ) {
2158                DBG_PRINT( "EXITING ISR, IN RTS MODE...\n" );
2159                return;
2160                }
2161#endif  /* USE_RTS */
2162
2163        /* If we have interrupts pending, then put them on a system task
2164           queue. Otherwise turn interrupts back on */
2165        events = hcf_action( &lp->hcfCtx, HCF_ACT_INT_OFF );
2166
2167        if ( events == HCF_INT_PENDING ) {
2168                /* Schedule the ISR handler as a bottom-half task in the
2169                   tq_immediate queue */
2170                tasklet_schedule(&lp->task);
2171        } else {
2172                //DBG_PRINT( "NOT OUR INTERRUPT\n" );
2173                hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2174        }
2175
2176        return IRQ_RETVAL(events == HCF_INT_PENDING);
2177} // wl_isr
2178/*============================================================================*/
2179
2180
2181/*******************************************************************************
2182 *      wl_isr_handler()
2183 *******************************************************************************
2184 *
2185 *  DESCRIPTION:
2186 *
2187 *      The ISR handler, scheduled to run in a deferred context by the ISR. This
2188 *      is where the ISR's work actually gets done.
2189 *
2190 *  PARAMETERS:
2191 *
2192 *      lp  - a pointer to the device's private adapter structure
2193 *
2194 *  RETURNS:
2195 *
2196 *      N/A
2197 *
2198 ******************************************************************************/
2199#define WVLAN_MAX_INT_SERVICES  50
2200
2201void wl_isr_handler( unsigned long p )
2202{
2203        struct net_device       *dev;
2204        unsigned long           flags;
2205        bool_t                  stop = TRUE;
2206        int                     count;
2207        int                     result;
2208        struct wl_private       *lp = (struct wl_private *)p;
2209        /*------------------------------------------------------------------------*/
2210
2211        if ( lp == NULL ) {
2212                DBG_PRINT( "wl_isr_handler  lp adapter pointer is NULL!!!\n" );
2213        } else {
2214                wl_lock( lp, &flags );
2215
2216                dev = (struct net_device *)lp->dev;
2217                if ( dev != NULL && netif_device_present( dev ) ) stop = FALSE;
2218                for( count = 0; stop == FALSE && count < WVLAN_MAX_INT_SERVICES; count++ ) {
2219                        stop = TRUE;
2220                        result = hcf_service_nic( &lp->hcfCtx,
2221                                                                          (wci_bufp)lp->lookAheadBuf,
2222                                                                          sizeof( lp->lookAheadBuf ));
2223                        if ( result == HCF_ERR_MIC ) {
2224                                wl_wext_event_mic_failed( dev );        /* Send an event that MIC failed */
2225                                //;?this seems wrong if HCF_ERR_MIC coincides with another event, stop gets FALSE
2226                                //so why not do it always ;?
2227                        }
2228
2229#ifndef USE_MBOX_SYNC
2230                        if ( lp->hcfCtx.IFB_MBInfoLen != 0 ) {  /* anything in the mailbox */
2231                                wl_mbx( lp );
2232                                stop = FALSE;
2233                        }
2234#endif
2235                        /* Check for a Link status event */
2236                        if ( ( lp->hcfCtx.IFB_LinkStat & CFG_LINK_STAT_FW ) != 0 ) {
2237                                wl_process_link_status( lp );
2238                                stop = FALSE;
2239                        }
2240                        /* Check for probe response events */
2241                        if ( lp->ProbeResp.infoType != 0 &&
2242                                lp->ProbeResp.infoType != 0xFFFF ) {
2243                                wl_process_probe_response( lp );
2244                                memset( &lp->ProbeResp, 0, sizeof( lp->ProbeResp ));
2245                                lp->ProbeResp.infoType = 0xFFFF;
2246                                stop = FALSE;
2247                        }
2248                        /* Check for updated record events */
2249                        if ( lp->updatedRecord.len != 0xFFFF ) {
2250                                wl_process_updated_record( lp );
2251                                lp->updatedRecord.len = 0xFFFF;
2252                                stop = FALSE;
2253                        }
2254                        /* Check for association status events */
2255                        if ( lp->assoc_stat.len != 0xFFFF ) {
2256                                wl_process_assoc_status( lp );
2257                                lp->assoc_stat.len = 0xFFFF;
2258                                stop = FALSE;
2259                        }
2260                        /* Check for security status events */
2261                        if ( lp->sec_stat.len != 0xFFFF ) {
2262                                wl_process_security_status( lp );
2263                                lp->sec_stat.len = 0xFFFF;
2264                                stop = FALSE;
2265                        }
2266
2267#ifdef ENABLE_DMA
2268                        if ( lp->use_dma ) {
2269                                /* Check for DMA Rx packets */
2270                                if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_RDMAD ) {
2271                                        wl_rx_dma( dev );
2272                                        stop = FALSE;
2273                                }
2274                                /* Return Tx DMA descriptors to host */
2275                                if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_TDMAD ) {
2276                                        wl_pci_dma_hcf_reclaim_tx( lp );
2277                                        stop = FALSE;
2278                                }
2279                        }
2280                        else
2281#endif // ENABLE_DMA
2282                        {
2283                                /* Check for Rx packets */
2284                                if ( lp->hcfCtx.IFB_RxLen != 0 ) {
2285                                        wl_rx( dev );
2286                                        stop = FALSE;
2287                                }
2288                                /* Make sure that queued frames get sent */
2289                                if ( wl_send( lp )) {
2290                                        stop = FALSE;
2291                                }
2292                        }
2293                }
2294                /* We're done, so turn interrupts which were turned off in wl_isr, back on */
2295                hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2296                wl_unlock( lp, &flags );
2297        }
2298        return;
2299} // wl_isr_handler
2300/*============================================================================*/
2301
2302
2303/*******************************************************************************
2304 *      wl_remove()
2305 *******************************************************************************
2306 *
2307 *  DESCRIPTION:
2308 *
2309 *      Notify the adapter that it has been removed. Since the adapter is gone,
2310 *  we should no longer try to talk to it.
2311 *
2312 *  PARAMETERS:
2313 *
2314 *      dev - a pointer to the device's net_device structure
2315 *
2316 *  RETURNS:
2317 *
2318 *      N/A
2319 *
2320 ******************************************************************************/
2321void wl_remove( struct net_device *dev )
2322{
2323        struct wl_private   *lp = wl_priv(dev);
2324        unsigned long   flags;
2325        /*------------------------------------------------------------------------*/
2326        DBG_FUNC( "wl_remove" );
2327        DBG_ENTER( DbgInfo );
2328
2329        DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2330
2331        wl_lock( lp, &flags );
2332
2333        /* stop handling interrupts */
2334        wl_act_int_off( lp );
2335        lp->is_handling_int = WL_NOT_HANDLING_INT;
2336
2337        /*
2338         * Disable the ports: just change state: since the
2339         * card is gone it is useless to talk to it and at
2340         * disconnect all state information is lost anyway.
2341         */
2342        /* Reset portState */
2343        lp->portState = WVLAN_PORT_STATE_DISABLED;
2344
2345#if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
2346#ifdef USE_WDS
2347        //wl_disable_wds_ports( lp );
2348#endif // USE_WDS
2349#endif  /* (HCF_TYPE) & HCF_TYPE_AP */
2350
2351        /* Mark the device as unregistered */
2352        lp->is_registered = FALSE;
2353
2354        /* Deregister the WDS ports as well */
2355        WL_WDS_NETDEV_DEREGISTER( lp );
2356#ifdef USE_RTS
2357        if ( lp->useRTS == 1 ) {
2358                wl_unlock( lp, &flags );
2359
2360                DBG_LEAVE( DbgInfo );
2361                return;
2362        }
2363#endif  /* USE_RTS */
2364
2365        /* Inform the HCF that the card has been removed */
2366        hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2367
2368        wl_unlock( lp, &flags );
2369
2370        DBG_LEAVE( DbgInfo );
2371        return;
2372} // wl_remove
2373/*============================================================================*/
2374
2375
2376/*******************************************************************************
2377 *      wl_suspend()
2378 *******************************************************************************
2379 *
2380 *  DESCRIPTION:
2381 *
2382 *      Power-down and halt the adapter.
2383 *
2384 *  PARAMETERS:
2385 *
2386 *      dev - a pointer to the device's net_device structure
2387 *
2388 *  RETURNS:
2389 *
2390 *      N/A
2391 *
2392 ******************************************************************************/
2393void wl_suspend( struct net_device *dev )
2394{
2395        struct wl_private  *lp = wl_priv(dev);
2396        unsigned long   flags;
2397        /*------------------------------------------------------------------------*/
2398        DBG_FUNC( "wl_suspend" );
2399        DBG_ENTER( DbgInfo );
2400
2401        DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2402
2403        /* The adapter is suspended:
2404                        Stop the adapter
2405                        Power down
2406        */
2407        wl_lock( lp, &flags );
2408
2409        /* Disable interrupt handling */
2410        wl_act_int_off( lp );
2411
2412        /* Disconnect */
2413        wl_disconnect( lp );
2414
2415        /* Disable */
2416        wl_disable( lp );
2417
2418        /* Disconnect from the adapter */
2419        hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2420
2421        /* Reset portState to be sure (should have been done by wl_disable */
2422        lp->portState = WVLAN_PORT_STATE_DISABLED;
2423
2424        wl_unlock( lp, &flags );
2425
2426        DBG_LEAVE( DbgInfo );
2427        return;
2428} // wl_suspend
2429/*============================================================================*/
2430
2431
2432/*******************************************************************************
2433 *      wl_resume()
2434 *******************************************************************************
2435 *
2436 *  DESCRIPTION:
2437 *
2438 *      Resume a previously suspended adapter.
2439 *
2440 *  PARAMETERS:
2441 *
2442 *      dev - a pointer to the device's net_device structure
2443 *
2444 *  RETURNS:
2445 *
2446 *      N/A
2447 *
2448 ******************************************************************************/
2449void wl_resume(struct net_device *dev)
2450{
2451        struct wl_private  *lp = wl_priv(dev);
2452        unsigned long   flags;
2453        /*------------------------------------------------------------------------*/
2454        DBG_FUNC( "wl_resume" );
2455        DBG_ENTER( DbgInfo );
2456
2457        DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2458
2459        wl_lock( lp, &flags );
2460
2461        /* Connect to the adapter */
2462        hcf_connect( &lp->hcfCtx, dev->base_addr );
2463
2464        /* Reset portState */
2465        lp->portState = WVLAN_PORT_STATE_DISABLED;
2466
2467        /* Power might have been off, assume the card lost the firmware*/
2468        lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
2469
2470        /* Reload the firmware and restart */
2471        wl_reset( dev );
2472
2473        /* Resume interrupt handling */
2474        wl_act_int_on( lp );
2475
2476        wl_unlock( lp, &flags );
2477
2478        DBG_LEAVE( DbgInfo );
2479        return;
2480} // wl_resume
2481/*============================================================================*/
2482
2483
2484/*******************************************************************************
2485 *      wl_release()
2486 *******************************************************************************
2487 *
2488 *  DESCRIPTION:
2489 *
2490 *      This function performs a check on the device and calls wl_remove() if
2491 *  necessary. This function can be used for all bus types, but exists mostly
2492 *  for the benefit of the Card Services driver, as there are times when
2493 *  wl_remove() does not get called.
2494 *
2495 *  PARAMETERS:
2496 *
2497 *      dev - a pointer to the device's net_device structure
2498 *
2499 *  RETURNS:
2500 *
2501 *      N/A
2502 *
2503 ******************************************************************************/
2504void wl_release( struct net_device *dev )
2505{
2506        struct wl_private  *lp = wl_priv(dev);
2507        /*------------------------------------------------------------------------*/
2508        DBG_FUNC( "wl_release" );
2509        DBG_ENTER( DbgInfo );
2510
2511        DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2512        /* If wl_remove() hasn't been called (i.e. when Card Services is shut
2513           down with the card in the slot), then call it */
2514        if ( lp->is_registered == TRUE ) {
2515                DBG_TRACE( DbgInfo, "Calling unregister_netdev(), as it wasn't called yet\n" );
2516                wl_remove( dev );
2517
2518                lp->is_registered = FALSE;
2519        }
2520
2521        DBG_LEAVE( DbgInfo );
2522        return;
2523} // wl_release
2524/*============================================================================*/
2525
2526
2527/*******************************************************************************
2528 *      wl_get_irq_mask()
2529 *******************************************************************************
2530 *
2531 *  DESCRIPTION:
2532 *
2533 *      Accessor function to retrieve the irq_mask module parameter
2534 *
2535 *  PARAMETERS:
2536 *
2537 *      N/A
2538 *
2539 *  RETURNS:
2540 *
2541 *      The irq_mask module parameter
2542 *
2543 ******************************************************************************/
2544p_u16 wl_get_irq_mask( void )
2545{
2546        return irq_mask;
2547} // wl_get_irq_mask
2548/*============================================================================*/
2549
2550
2551/*******************************************************************************
2552 *      wl_get_irq_list()
2553 *******************************************************************************
2554 *
2555 *  DESCRIPTION:
2556 *
2557 *      Accessor function to retrieve the irq_list module parameter
2558 *
2559 *  PARAMETERS:
2560 *
2561 *      N/A
2562 *
2563 *  RETURNS:
2564 *
2565 *      The irq_list module parameter
2566 *
2567 ******************************************************************************/
2568p_s8 * wl_get_irq_list( void )
2569{
2570        return irq_list;
2571} // wl_get_irq_list
2572/*============================================================================*/
2573
2574
2575
2576/*******************************************************************************
2577 *      wl_enable()
2578 *******************************************************************************
2579 *
2580 *  DESCRIPTION:
2581 *
2582 *      Used to enable MAC ports
2583 *
2584 *  PARAMETERS:
2585 *
2586 *      lp      - pointer to the device's private adapter structure
2587 *
2588 *  RETURNS:
2589 *
2590 *      N/A
2591 *
2592 ******************************************************************************/
2593int wl_enable( struct wl_private *lp )
2594{
2595        int hcf_status = HCF_SUCCESS;
2596        /*------------------------------------------------------------------------*/
2597        DBG_FUNC( "wl_enable" );
2598        DBG_ENTER( DbgInfo );
2599
2600        if ( lp->portState == WVLAN_PORT_STATE_ENABLED ) {
2601                DBG_TRACE( DbgInfo, "No action: Card already enabled\n" );
2602        } else if ( lp->portState == WVLAN_PORT_STATE_CONNECTED ) {
2603                //;?suspicuous logic, how can you be connected without being enabled so this is probably dead code
2604                DBG_TRACE( DbgInfo, "No action: Card already connected\n" );
2605        } else {
2606                hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_ENABLE );
2607                if ( hcf_status == HCF_SUCCESS ) {
2608                        /* Set the status of the NIC to enabled */
2609                        lp->portState = WVLAN_PORT_STATE_ENABLED;   //;?bad mnemonic, NIC iso PORT
2610#ifdef ENABLE_DMA
2611                        if ( lp->use_dma ) {
2612                                wl_pci_dma_hcf_supply( lp );  //;?always successful?
2613                        }
2614#endif
2615                }
2616        }
2617        if ( hcf_status != HCF_SUCCESS ) {  //;?make this an assert
2618                DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2619        }
2620        DBG_LEAVE( DbgInfo );
2621        return hcf_status;
2622} // wl_enable
2623/*============================================================================*/
2624
2625
2626#ifdef USE_WDS
2627/*******************************************************************************
2628 *      wl_enable_wds_ports()
2629 *******************************************************************************
2630 *
2631 *  DESCRIPTION:
2632 *
2633 *      Used to enable the WDS MAC ports 1-6
2634 *
2635 *  PARAMETERS:
2636 *
2637 *      lp      - pointer to the device's private adapter structure
2638 *
2639 *  RETURNS:
2640 *
2641 *      N/A
2642 *
2643 ******************************************************************************/
2644void wl_enable_wds_ports( struct wl_private * lp )
2645{
2646
2647        DBG_FUNC( "wl_enable_wds_ports" );
2648        DBG_ENTER( DbgInfo );
2649        if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ){
2650                DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2651        }
2652        DBG_LEAVE( DbgInfo );
2653        return;
2654} // wl_enable_wds_ports
2655#endif  /* USE_WDS */
2656/*============================================================================*/
2657
2658
2659/*******************************************************************************
2660 *      wl_connect()
2661 *******************************************************************************
2662 *
2663 *  DESCRIPTION:
2664 *
2665 *      Used to connect a MAC port
2666 *
2667 *  PARAMETERS:
2668 *
2669 *      lp      - pointer to the device's private adapter structure
2670 *
2671 *  RETURNS:
2672 *
2673 *      N/A
2674 *
2675 ******************************************************************************/
2676int wl_connect( struct wl_private *lp )
2677{
2678        int hcf_status;
2679        /*------------------------------------------------------------------------*/
2680
2681        DBG_FUNC( "wl_connect" );
2682        DBG_ENTER( DbgInfo );
2683
2684        if ( lp->portState != WVLAN_PORT_STATE_ENABLED ) {
2685                DBG_TRACE( DbgInfo, "No action: Not in enabled state\n" );
2686                DBG_LEAVE( DbgInfo );
2687                return HCF_SUCCESS;
2688        }
2689        hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_CONNECT );
2690        if ( hcf_status == HCF_SUCCESS ) {
2691                lp->portState = WVLAN_PORT_STATE_CONNECTED;
2692        }
2693        DBG_LEAVE( DbgInfo );
2694        return hcf_status;
2695} // wl_connect
2696/*============================================================================*/
2697
2698
2699/*******************************************************************************
2700 *      wl_disconnect()
2701 *******************************************************************************
2702 *
2703 *  DESCRIPTION:
2704 *
2705 *      Used to disconnect a MAC port
2706 *
2707 *  PARAMETERS:
2708 *
2709 *      lp      - pointer to the device's private adapter structure
2710 *
2711 *  RETURNS:
2712 *
2713 *      N/A
2714 *
2715 ******************************************************************************/
2716int wl_disconnect( struct wl_private *lp )
2717{
2718        int hcf_status;
2719        /*------------------------------------------------------------------------*/
2720
2721        DBG_FUNC( "wl_disconnect" );
2722        DBG_ENTER( DbgInfo );
2723
2724        if ( lp->portState != WVLAN_PORT_STATE_CONNECTED ) {
2725                DBG_TRACE( DbgInfo, "No action: Not in connected state\n" );
2726                DBG_LEAVE( DbgInfo );
2727                return HCF_SUCCESS;
2728        }
2729        hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISCONNECT );
2730        if ( hcf_status == HCF_SUCCESS ) {
2731                lp->portState = WVLAN_PORT_STATE_ENABLED;
2732        }
2733        DBG_LEAVE( DbgInfo );
2734        return hcf_status;
2735} // wl_disconnect
2736/*============================================================================*/
2737
2738
2739/*******************************************************************************
2740 *      wl_disable()
2741 *******************************************************************************
2742 *
2743 *  DESCRIPTION:
2744 *
2745 *      Used to disable MAC ports
2746 *
2747 *  PARAMETERS:
2748 *
2749 *      lp      - pointer to the device's private adapter structure
2750 *      port    - the MAC port to disable
2751 *
2752 *  RETURNS:
2753 *
2754 *      N/A
2755 *
2756 ******************************************************************************/
2757int wl_disable( struct wl_private *lp )
2758{
2759        int hcf_status = HCF_SUCCESS;
2760        /*------------------------------------------------------------------------*/
2761        DBG_FUNC( "wl_disable" );
2762        DBG_ENTER( DbgInfo );
2763
2764        if ( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
2765                DBG_TRACE( DbgInfo, "No action: Port state is disabled\n" );
2766        } else {
2767                hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISABLE );
2768                if ( hcf_status == HCF_SUCCESS ) {
2769                        /* Set the status of the port to disabled */ //;?bad mnemonic use NIC iso PORT
2770                        lp->portState = WVLAN_PORT_STATE_DISABLED;
2771
2772#ifdef ENABLE_DMA
2773                        if ( lp->use_dma ) {
2774                                wl_pci_dma_hcf_reclaim( lp );
2775                        }
2776#endif
2777                }
2778        }
2779        if ( hcf_status != HCF_SUCCESS ) {
2780                DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2781        }
2782        DBG_LEAVE( DbgInfo );
2783        return hcf_status;
2784} // wl_disable
2785/*============================================================================*/
2786
2787
2788#ifdef USE_WDS
2789/*******************************************************************************
2790 *      wl_disable_wds_ports()
2791 *******************************************************************************
2792 *
2793 *  DESCRIPTION:
2794 *
2795 *      Used to disable the WDS MAC ports 1-6
2796 *
2797 *  PARAMETERS:
2798 *
2799 *      lp      - pointer to the device's private adapter structure
2800 *
2801 *  RETURNS:
2802 *
2803 *      N/A
2804 *
2805 ******************************************************************************/
2806void wl_disable_wds_ports( struct wl_private * lp )
2807{
2808
2809        DBG_FUNC( "wl_disable_wds_ports" );
2810        DBG_ENTER( DbgInfo );
2811
2812        if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ){
2813                DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2814        }
2815//      if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
2816//              wl_disable( lp, HCF_PORT_1 );
2817//              wl_disable( lp, HCF_PORT_2 );
2818//              wl_disable( lp, HCF_PORT_3 );
2819//              wl_disable( lp, HCF_PORT_4 );
2820//              wl_disable( lp, HCF_PORT_5 );
2821//              wl_disable( lp, HCF_PORT_6 );
2822//      }
2823        DBG_LEAVE( DbgInfo );
2824        return;
2825} // wl_disable_wds_ports
2826#endif // USE_WDS
2827/*============================================================================*/
2828
2829
2830#ifndef USE_MBOX_SYNC
2831/*******************************************************************************
2832 *      wl_mbx()
2833 *******************************************************************************
2834 *
2835 *  DESCRIPTION:
2836 *      This function is used to read and process a mailbox message.
2837 *
2838 *
2839 *  PARAMETERS:
2840 *
2841 *      lp      - pointer to the device's private adapter structure
2842 *
2843 *  RETURNS:
2844 *
2845 *      an HCF status code
2846 *
2847 ******************************************************************************/
2848int wl_mbx( struct wl_private *lp )
2849{
2850        int hcf_status = HCF_SUCCESS;
2851        /*------------------------------------------------------------------------*/
2852        DBG_FUNC( "wl_mbx" );
2853        DBG_ENTER( DbgInfo );
2854        DBG_TRACE( DbgInfo, "Mailbox Info: IFB_MBInfoLen: %d\n",
2855                           lp->hcfCtx.IFB_MBInfoLen );
2856
2857        memset( &( lp->ltvRecord ), 0, sizeof( ltv_t ));
2858
2859        lp->ltvRecord.len = MB_SIZE;
2860        lp->ltvRecord.typ = CFG_MB_INFO;
2861        hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2862
2863        if ( hcf_status != HCF_SUCCESS ) {
2864                DBG_ERROR( DbgInfo, "hcf_get_info returned 0x%x\n", hcf_status );
2865
2866                DBG_LEAVE( DbgInfo );
2867                return hcf_status;
2868        }
2869
2870        if ( lp->ltvRecord.typ == CFG_MB_INFO ) {
2871                DBG_LEAVE( DbgInfo );
2872                return hcf_status;
2873        }
2874        /* Endian translate the mailbox data, then process the message */
2875        wl_endian_translate_mailbox( &( lp->ltvRecord ));
2876        wl_process_mailbox( lp );
2877        DBG_LEAVE( DbgInfo );
2878        return hcf_status;
2879} // wl_mbx
2880/*============================================================================*/
2881
2882
2883/*******************************************************************************
2884 *      wl_endian_translate_mailbox()
2885 *******************************************************************************
2886 *
2887 *  DESCRIPTION:
2888 *
2889 *      This function will perform the tedious task of endian translating all
2890 *  fields within a mailbox message which need translating.
2891 *
2892 *  PARAMETERS:
2893 *
2894 *      ltv - pointer to the LTV to endian translate
2895 *
2896 *  RETURNS:
2897 *
2898 *      none
2899 *
2900 ******************************************************************************/
2901void wl_endian_translate_mailbox( ltv_t *ltv )
2902{
2903
2904        DBG_FUNC( "wl_endian_translate_mailbox" );
2905        DBG_ENTER( DbgInfo );
2906        switch( ltv->typ ) {
2907          case CFG_TALLIES:
2908                break;
2909
2910          case CFG_SCAN:
2911                {
2912                        int num_aps;
2913                        SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)&ltv->u.u8[0];
2914
2915                        num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2916                                                                 ( sizeof( SCAN_RS_STRCT )));
2917
2918                        while( num_aps >= 1 ) {
2919                                num_aps--;
2920
2921                                aps[num_aps].channel_id =
2922                                        CNV_LITTLE_TO_INT( aps[num_aps].channel_id );
2923
2924                                aps[num_aps].noise_level =
2925                                        CNV_LITTLE_TO_INT( aps[num_aps].noise_level );
2926
2927                                aps[num_aps].signal_level =
2928                                        CNV_LITTLE_TO_INT( aps[num_aps].signal_level );
2929
2930                                aps[num_aps].beacon_interval_time =
2931                                        CNV_LITTLE_TO_INT( aps[num_aps].beacon_interval_time );
2932
2933                                aps[num_aps].capability =
2934                                        CNV_LITTLE_TO_INT( aps[num_aps].capability );
2935
2936                                aps[num_aps].ssid_len =
2937                                        CNV_LITTLE_TO_INT( aps[num_aps].ssid_len );
2938
2939                                aps[num_aps].ssid_val[aps[num_aps].ssid_len] = 0;
2940                        }
2941                }
2942                break;
2943
2944          case CFG_ACS_SCAN:
2945                {
2946                        PROBE_RESP *probe_resp = (PROBE_RESP *)ltv;
2947
2948                        probe_resp->frameControl   = CNV_LITTLE_TO_INT( probe_resp->frameControl );
2949                        probe_resp->durID          = CNV_LITTLE_TO_INT( probe_resp->durID );
2950                        probe_resp->sequence       = CNV_LITTLE_TO_INT( probe_resp->sequence );
2951                        probe_resp->dataLength     = CNV_LITTLE_TO_INT( probe_resp->dataLength );
2952#ifndef WARP
2953                        probe_resp->lenType        = CNV_LITTLE_TO_INT( probe_resp->lenType );
2954#endif // WARP
2955                        probe_resp->beaconInterval = CNV_LITTLE_TO_INT( probe_resp->beaconInterval );
2956                        probe_resp->capability     = CNV_LITTLE_TO_INT( probe_resp->capability );
2957                        probe_resp->flags          = CNV_LITTLE_TO_INT( probe_resp->flags );
2958                }
2959                break;
2960
2961          case CFG_LINK_STAT:
2962#define ls ((LINK_STATUS_STRCT *)ltv)
2963                        ls->linkStatus = CNV_LITTLE_TO_INT( ls->linkStatus );
2964                break;
2965#undef ls
2966
2967          case CFG_ASSOC_STAT:
2968                {
2969                        ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
2970
2971                        as->assocStatus = CNV_LITTLE_TO_INT( as->assocStatus );
2972                }
2973                break;
2974
2975          case CFG_SECURITY_STAT:
2976                {
2977                        SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
2978
2979                        ss->securityStatus  = CNV_LITTLE_TO_INT( ss->securityStatus );
2980                        ss->reason          = CNV_LITTLE_TO_INT( ss->reason );
2981                }
2982                break;
2983
2984          case CFG_WMP:
2985                break;
2986
2987          case CFG_NULL:
2988                break;
2989
2990        default:
2991                break;
2992        }
2993
2994        DBG_LEAVE( DbgInfo );
2995        return;
2996} // wl_endian_translate_mailbox
2997/*============================================================================*/
2998
2999/*******************************************************************************
3000 *      wl_process_mailbox()
3001 *******************************************************************************
3002 *
3003 *  DESCRIPTION:
3004 *
3005 *      This function processes the mailbox data.
3006 *
3007 *  PARAMETERS:
3008 *
3009 *      ltv - pointer to the LTV to be processed.
3010 *
3011 *  RETURNS:
3012 *
3013 *      none
3014 *
3015 ******************************************************************************/
3016void wl_process_mailbox( struct wl_private *lp )
3017{
3018        ltv_t   *ltv;
3019        hcf_16  ltv_val = 0xFFFF;
3020        /*------------------------------------------------------------------------*/
3021        DBG_FUNC( "wl_process_mailbox" );
3022        DBG_ENTER( DbgInfo );
3023        ltv = &( lp->ltvRecord );
3024
3025        switch( ltv->typ ) {
3026
3027          case CFG_TALLIES:
3028                DBG_TRACE( DbgInfo, "CFG_TALLIES\n" );
3029                break;
3030          case CFG_SCAN:
3031                DBG_TRACE( DbgInfo, "CFG_SCAN\n" );
3032
3033                {
3034                        int num_aps;
3035                        SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)&ltv->u.u8[0];
3036
3037                        num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
3038                                                                 ( sizeof( SCAN_RS_STRCT )));
3039
3040                        lp->scan_results.num_aps = num_aps;
3041
3042                        DBG_TRACE( DbgInfo, "Number of APs: %d\n", num_aps );
3043
3044                        while( num_aps >= 1 ) {
3045                                num_aps--;
3046
3047                                DBG_TRACE( DbgInfo, "AP              : %d\n", num_aps );
3048                                DBG_TRACE( DbgInfo, "=========================\n" );
3049                                DBG_TRACE( DbgInfo, "Channel ID      : 0x%04x\n",
3050                                                   aps[num_aps].channel_id );
3051                                DBG_TRACE( DbgInfo, "Noise Level     : 0x%04x\n",
3052                                                   aps[num_aps].noise_level );
3053                                DBG_TRACE( DbgInfo, "Signal Level    : 0x%04x\n",
3054                                                   aps[num_aps].signal_level );
3055                                DBG_TRACE( DbgInfo, "Beacon Interval : 0x%04x\n",
3056                                                   aps[num_aps].beacon_interval_time );
3057                                DBG_TRACE( DbgInfo, "Capability      : 0x%04x\n",
3058                                                   aps[num_aps].capability );
3059                                DBG_TRACE( DbgInfo, "SSID Length     : 0x%04x\n",
3060                                                   aps[num_aps].ssid_len );
3061                                DBG_TRACE(DbgInfo, "BSSID           : %pM\n",
3062                                                   aps[num_aps].bssid);
3063
3064                                if ( aps[num_aps].ssid_len != 0 ) {
3065                                        DBG_TRACE( DbgInfo, "SSID            : %s.\n",
3066                                                           aps[num_aps].ssid_val );
3067                                } else {
3068                                        DBG_TRACE( DbgInfo, "SSID            : %s.\n", "ANY" );
3069                                }
3070
3071                                DBG_TRACE( DbgInfo, "\n" );
3072
3073                                /* Copy the info to the ScanResult structure in the private
3074                                   adapter struct */
3075                                memcpy( &( lp->scan_results.APTable[num_aps]), &( aps[num_aps] ),
3076                                                sizeof( SCAN_RS_STRCT ));
3077                        }
3078
3079                        /* Set scan result to true so that any scan requests will
3080                           complete */
3081                        lp->scan_results.scan_complete = TRUE;
3082                }
3083
3084                break;
3085          case CFG_ACS_SCAN:
3086                DBG_TRACE( DbgInfo, "CFG_ACS_SCAN\n" );
3087
3088                {
3089                        PROBE_RESP  *probe_rsp = (PROBE_RESP *)ltv;
3090                        hcf_8       *wpa_ie = NULL;
3091                        hcf_16      wpa_ie_len = 0;
3092
3093                        DBG_TRACE( DbgInfo, "(%s) =========================\n",
3094                                           lp->dev->name );
3095
3096                        DBG_TRACE( DbgInfo, "(%s) length      : 0x%04x.\n",
3097                                           lp->dev->name, probe_rsp->length );
3098
3099                        if ( probe_rsp->length > 1 ) {
3100                                DBG_TRACE( DbgInfo, "(%s) infoType    : 0x%04x.\n",
3101                                                   lp->dev->name, probe_rsp->infoType );
3102
3103                                DBG_TRACE( DbgInfo, "(%s) signal      : 0x%02x.\n",
3104                                                   lp->dev->name, probe_rsp->signal );
3105
3106                                DBG_TRACE( DbgInfo, "(%s) silence     : 0x%02x.\n",
3107                                                   lp->dev->name, probe_rsp->silence );
3108
3109                                DBG_TRACE( DbgInfo, "(%s) rxFlow      : 0x%02x.\n",
3110                                                   lp->dev->name, probe_rsp->rxFlow );
3111
3112                                DBG_TRACE( DbgInfo, "(%s) rate        : 0x%02x.\n",
3113                                                   lp->dev->name, probe_rsp->rate );
3114
3115                                DBG_TRACE( DbgInfo, "(%s) frame cntl  : 0x%04x.\n",
3116                                                   lp->dev->name, probe_rsp->frameControl );
3117
3118                                DBG_TRACE( DbgInfo, "(%s) durID       : 0x%04x.\n",
3119                                                   lp->dev->name, probe_rsp->durID );
3120
3121                                DBG_TRACE(DbgInfo, "(%s) address1    : %pM\n",
3122                                        lp->dev->name, probe_rsp->address1);
3123
3124                                DBG_TRACE(DbgInfo, "(%s) address2    : %pM\n",
3125                                        lp->dev->name, probe_rsp->address2);
3126
3127                                DBG_TRACE(DbgInfo, "(%s) BSSID       : %pM\n",
3128                                        lp->dev->name, probe_rsp->BSSID);
3129
3130                                DBG_TRACE( DbgInfo, "(%s) sequence    : 0x%04x.\n",
3131                                                   lp->dev->name, probe_rsp->sequence );
3132
3133                                DBG_TRACE(DbgInfo, "(%s) address4    : %pM\n",
3134                                        lp->dev->name, probe_rsp->address4);
3135
3136                                DBG_TRACE( DbgInfo, "(%s) datalength  : 0x%04x.\n",
3137                                                   lp->dev->name, probe_rsp->dataLength );
3138
3139                                DBG_TRACE(DbgInfo, "(%s) DA          : %pM\n",
3140                                        lp->dev->name, probe_rsp->DA);
3141
3142                                DBG_TRACE(DbgInfo, "(%s) SA          : %pM\n",
3143                                        lp->dev->name, probe_rsp->SA);
3144
3145                                //DBG_TRACE( DbgInfo, "(%s) lenType     : 0x%04x.\n",
3146                                //           lp->dev->name, probe_rsp->lenType );
3147
3148                                DBG_TRACE(DbgInfo, "(%s) timeStamp   : "
3149                                                "%d.%d.%d.%d.%d.%d.%d.%d\n",
3150                                                lp->dev->name,
3151                                                probe_rsp->timeStamp[0],
3152                                                probe_rsp->timeStamp[1],
3153                                                probe_rsp->timeStamp[2],
3154                                                probe_rsp->timeStamp[3],
3155                                                probe_rsp->timeStamp[4],
3156                                                probe_rsp->timeStamp[5],
3157                                                probe_rsp->timeStamp[6],
3158                                                probe_rsp->timeStamp[7]);
3159
3160                                DBG_TRACE( DbgInfo, "(%s) beaconInt   : 0x%04x.\n",
3161                                                   lp->dev->name, probe_rsp->beaconInterval );
3162
3163                                DBG_TRACE( DbgInfo, "(%s) capability  : 0x%04x.\n",
3164                                                   lp->dev->name, probe_rsp->capability );
3165
3166                                DBG_TRACE( DbgInfo, "(%s) SSID len    : 0x%04x.\n",
3167                                                   lp->dev->name, probe_rsp->rawData[1] );
3168
3169                                if ( probe_rsp->rawData[1] > 0 ) {
3170                                        char ssid[HCF_MAX_NAME_LEN];
3171
3172                                        memset( ssid, 0, sizeof( ssid ));
3173                                        strncpy( ssid, &probe_rsp->rawData[2],
3174                                                 min_t(u8,
3175                                                        probe_rsp->rawData[1],
3176                                                        HCF_MAX_NAME_LEN - 1));
3177
3178                                        DBG_TRACE( DbgInfo, "(%s) SSID        : %s\n",
3179                                                           lp->dev->name, ssid );
3180                                }
3181
3182                                /* Parse out the WPA-IE, if one exists */
3183                                wpa_ie = wl_parse_wpa_ie( probe_rsp, &wpa_ie_len );
3184                                if ( wpa_ie != NULL ) {
3185                                        DBG_TRACE( DbgInfo, "(%s) WPA-IE      : %s\n",
3186                                        lp->dev->name, wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
3187                                }
3188
3189                                DBG_TRACE( DbgInfo, "(%s) flags       : 0x%04x.\n",
3190                                                   lp->dev->name, probe_rsp->flags );
3191                        }
3192
3193                        DBG_TRACE( DbgInfo, "\n\n" );
3194                        /* If probe response length is 1, then the scan is complete */
3195                        if ( probe_rsp->length == 1 ) {
3196                                DBG_TRACE( DbgInfo, "SCAN COMPLETE\n" );
3197                                lp->probe_results.num_aps = lp->probe_num_aps;
3198                                lp->probe_results.scan_complete = TRUE;
3199
3200                                /* Reset the counter for the next scan request */
3201                                lp->probe_num_aps = 0;
3202
3203                                /* Send a wireless extensions event that the scan completed */
3204                                wl_wext_event_scan_complete( lp->dev );
3205                        } else {
3206                                /* Only copy to the table if the entry is unique; APs sometimes
3207                                   respond more than once to a probe */
3208                                if ( lp->probe_num_aps == 0 ) {
3209                                        /* Copy the info to the ScanResult structure in the private
3210                                        adapter struct */
3211                                        memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3212                                                        probe_rsp, sizeof( PROBE_RESP ));
3213
3214                                        /* Increment the number of APs detected */
3215                                        lp->probe_num_aps++;
3216                                } else {
3217                                        int count;
3218                                        int unique = 1;
3219
3220                                        for( count = 0; count < lp->probe_num_aps; count++ ) {
3221                                                if ( memcmp( &( probe_rsp->BSSID ),
3222                                                        lp->probe_results.ProbeTable[count].BSSID,
3223                                                        ETH_ALEN ) == 0 ) {
3224                                                        unique = 0;
3225                                                }
3226                                        }
3227
3228                                        if ( unique ) {
3229                                                /* Copy the info to the ScanResult structure in the
3230                                                private adapter struct. Only copy if there's room in the
3231                                                table */
3232                                                if ( lp->probe_num_aps < MAX_NAPS )
3233                                                {
3234                                                        memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3235                                                                        probe_rsp, sizeof( PROBE_RESP ));
3236                                                }
3237                                                else
3238                                                {
3239                                                        DBG_WARNING( DbgInfo, "Num of scan results exceeds storage, truncating\n" );
3240                                                }
3241
3242                                                /* Increment the number of APs detected. Note I do this
3243                                                   here even when I don't copy the probe response to the
3244                                                   buffer in order to detect the overflow condition */
3245                                                lp->probe_num_aps++;
3246                                        }
3247                                }
3248                        }
3249                }
3250
3251                break;
3252
3253          case CFG_LINK_STAT:
3254#define ls ((LINK_STATUS_STRCT *)ltv)
3255                DBG_TRACE( DbgInfo, "CFG_LINK_STAT\n" );
3256
3257                switch( ls->linkStatus ) {
3258                  case 1:
3259                        DBG_TRACE( DbgInfo, "Link Status : Connected\n" );
3260                        wl_wext_event_ap( lp->dev );
3261                        break;
3262
3263                  case 2:
3264                        DBG_TRACE( DbgInfo, "Link Status : Disconnected\n"  );
3265                        break;
3266
3267                  case 3:
3268                        DBG_TRACE( DbgInfo, "Link Status : Access Point Change\n" );
3269                        break;
3270
3271                  case 4:
3272                        DBG_TRACE( DbgInfo, "Link Status : Access Point Out of Range\n" );
3273                        break;
3274
3275                  case 5:
3276                        DBG_TRACE( DbgInfo, "Link Status : Access Point In Range\n" );
3277                        break;
3278
3279                default:
3280                        DBG_TRACE( DbgInfo, "Link Status : UNKNOWN (0x%04x)\n",
3281                                           ls->linkStatus );
3282                        break;
3283                }
3284
3285                break;
3286#undef ls
3287
3288          case CFG_ASSOC_STAT:
3289                DBG_TRACE( DbgInfo, "CFG_ASSOC_STAT\n" );
3290
3291                {
3292                        ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
3293
3294                        switch( as->assocStatus ) {
3295                          case 1:
3296                                DBG_TRACE( DbgInfo, "Association Status : STA Associated\n" );
3297                                break;
3298
3299                          case 2:
3300                                DBG_TRACE( DbgInfo, "Association Status : STA Reassociated\n" );
3301                                break;
3302
3303                          case 3:
3304                                DBG_TRACE( DbgInfo, "Association Status : STA Disassociated\n" );
3305                                break;
3306
3307                        default:
3308                                DBG_TRACE( DbgInfo, "Association Status : UNKNOWN (0x%04x)\n",
3309                                                   as->assocStatus );
3310                                break;
3311                        }
3312
3313                        DBG_TRACE(DbgInfo, "STA Address        : %pM\n",
3314                                           as->staAddr);
3315
3316                        if (( as->assocStatus == 2 )  && ( as->len == 8 )) {
3317                                DBG_TRACE(DbgInfo, "Old AP Address     : %pM\n",
3318                                                   as->oldApAddr);
3319                        }
3320                }
3321
3322                break;
3323
3324          case CFG_SECURITY_STAT:
3325                DBG_TRACE( DbgInfo, "CFG_SECURITY_STAT\n" );
3326
3327                {
3328                        SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
3329
3330                        switch( ss->securityStatus ) {
3331                          case 1:
3332                                DBG_TRACE( DbgInfo, "Security Status : Dissassociate [AP]\n" );
3333                                break;
3334
3335                          case 2:
3336                                DBG_TRACE( DbgInfo, "Security Status : Deauthenticate [AP]\n" );
3337                                break;
3338
3339                          case 3:
3340                                DBG_TRACE( DbgInfo, "Security Status : Authenticate Fail [STA] or [AP]\n" );
3341                                break;
3342
3343                          case 4:
3344                                DBG_TRACE( DbgInfo, "Security Status : MIC Fail\n" );
3345                                break;
3346
3347                          case 5:
3348                                DBG_TRACE( DbgInfo, "Security Status : Associate Fail\n" );
3349                                break;
3350
3351                        default:
3352                                DBG_TRACE( DbgInfo, "Security Status : UNKNOWN %d\n",
3353                                                   ss->securityStatus );
3354                                break;
3355                        }
3356
3357                        DBG_TRACE(DbgInfo, "STA Address     : %pM\n",
3358                                        ss->staAddr);
3359
3360                        DBG_TRACE(DbgInfo, "Reason          : 0x%04x\n",
3361                                        ss->reason);
3362                }
3363
3364                break;
3365
3366          case CFG_WMP:
3367                DBG_TRACE( DbgInfo, "CFG_WMP, size is %d bytes\n", ltv->len );
3368                {
3369                        WMP_RSP_STRCT *wmp_rsp = (WMP_RSP_STRCT *)ltv;
3370
3371                        DBG_TRACE( DbgInfo, "CFG_WMP, pdu type is 0x%x\n",
3372                                           wmp_rsp->wmpRsp.wmpHdr.type );
3373
3374                        switch( wmp_rsp->wmpRsp.wmpHdr.type ) {
3375                          case WVLAN_WMP_PDU_TYPE_LT_RSP:
3376                                {
3377#if DBG
3378                                        LINKTEST_RSP_STRCT  *lt_rsp = (LINKTEST_RSP_STRCT *)ltv;
3379#endif // DBG
3380                                        DBG_TRACE( DbgInfo, "LINK TEST RESULT\n" );
3381                                        DBG_TRACE( DbgInfo, "================\n" );
3382                                        DBG_TRACE( DbgInfo, "Length        : %d.\n",     lt_rsp->len );
3383
3384                                        DBG_TRACE( DbgInfo, "Name          : %s.\n",     lt_rsp->ltRsp.ltRsp.name );
3385                                        DBG_TRACE( DbgInfo, "Signal Level  : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.signal );
3386                                        DBG_TRACE( DbgInfo, "Noise  Level  : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.noise );
3387                                        DBG_TRACE( DbgInfo, "Receive Flow  : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.rxFlow );
3388                                        DBG_TRACE( DbgInfo, "Data Rate     : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRate );
3389                                        DBG_TRACE( DbgInfo, "Protocol      : 0x%04x.\n", lt_rsp->ltRsp.ltRsp.protocol );
3390                                        DBG_TRACE( DbgInfo, "Station       : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.station );
3391                                        DBG_TRACE( DbgInfo, "Data Rate Cap : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRateCap );
3392
3393                                        DBG_TRACE( DbgInfo, "Power Mgmt    : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3394                                                                lt_rsp->ltRsp.ltRsp.powerMgmt[0],
3395                                                                lt_rsp->ltRsp.ltRsp.powerMgmt[1],
3396                                                                lt_rsp->ltRsp.ltRsp.powerMgmt[2],
3397                                                                lt_rsp->ltRsp.ltRsp.powerMgmt[3] );
3398
3399                                        DBG_TRACE( DbgInfo, "Robustness    : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3400                                                                lt_rsp->ltRsp.ltRsp.robustness[0],
3401                                                                lt_rsp->ltRsp.ltRsp.robustness[1],
3402                                                                lt_rsp->ltRsp.ltRsp.robustness[2],
3403                                                                lt_rsp->ltRsp.ltRsp.robustness[3] );
3404
3405                                        DBG_TRACE( DbgInfo, "Scaling       : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.scaling );
3406                                }
3407
3408                                break;
3409
3410                        default:
3411                                break;
3412                        }
3413                }
3414
3415                break;
3416
3417          case CFG_NULL:
3418                DBG_TRACE( DbgInfo, "CFG_NULL\n" );
3419                break;
3420
3421          case CFG_UPDATED_INFO_RECORD:        // Updated Information Record
3422                DBG_TRACE( DbgInfo, "UPDATED INFORMATION RECORD\n" );
3423
3424                ltv_val = CNV_INT_TO_LITTLE( ltv->u.u16[0] );
3425
3426                /* Check and see which RID was updated */
3427                switch( ltv_val ) {
3428                  case CFG_CUR_COUNTRY_INFO:  // Indicate Passive Scan Completion
3429                        DBG_TRACE( DbgInfo, "Updated country info\n" );
3430
3431                        /* Do I need to hold off on updating RIDs until the process is
3432                           complete? */
3433                        wl_connect( lp );
3434                        break;
3435
3436                  case CFG_PORT_STAT:    // Wait for Connect Event
3437                        //wl_connect( lp );
3438
3439                        break;
3440
3441                default:
3442                        DBG_WARNING( DbgInfo, "Unknown RID: 0x%04x\n", ltv_val );
3443                }
3444
3445                break;
3446
3447        default:
3448                DBG_TRACE( DbgInfo, "UNKNOWN MESSAGE: 0x%04x\n", ltv->typ );
3449                break;
3450        }
3451        DBG_LEAVE( DbgInfo );
3452        return;
3453} // wl_process_mailbox
3454/*============================================================================*/
3455#endif  /* ifndef USE_MBOX_SYNC */
3456
3457#ifdef USE_WDS
3458/*******************************************************************************
3459 *      wl_wds_netdev_register()
3460 *******************************************************************************
3461 *
3462 *  DESCRIPTION:
3463 *
3464 *      This function registers net_device structures with the system's network
3465 *      layer for use with the WDS ports.
3466 *
3467 *
3468 *  PARAMETERS:
3469 *
3470 *      lp      - pointer to the device's private adapter structure
3471 *
3472 *  RETURNS:
3473 *
3474 *      N/A
3475 *
3476 ******************************************************************************/
3477void wl_wds_netdev_register( struct wl_private *lp )
3478{
3479        int count;
3480        /*------------------------------------------------------------------------*/
3481        DBG_FUNC( "wl_wds_netdev_register" );
3482        DBG_ENTER( DbgInfo );
3483        //;?why is there no USE_WDS clause like in wl_enable_wds_ports
3484        if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
3485                for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3486                        if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3487                                if ( register_netdev( lp->wds_port[count].dev ) != 0 ) {
3488                                        DBG_WARNING( DbgInfo, "net device for WDS port %d could not be registered\n",
3489                                                                ( count + 1 ));
3490                                }
3491                                lp->wds_port[count].is_registered = TRUE;
3492
3493                                /* Fill out the net_device structs with the MAC addr */
3494                                memcpy( lp->wds_port[count].dev->dev_addr, lp->MACAddress, ETH_ALEN );
3495                                lp->wds_port[count].dev->addr_len = ETH_ALEN;
3496                        }
3497                }
3498        }
3499        DBG_LEAVE( DbgInfo );
3500        return;
3501} // wl_wds_netdev_register
3502/*============================================================================*/
3503
3504
3505/*******************************************************************************
3506 *      wl_wds_netdev_deregister()
3507 *******************************************************************************
3508 *
3509 *  DESCRIPTION:
3510 *
3511 *      This function deregisters the WDS net_device structures used by the
3512 *      system's network layer.
3513 *
3514 *
3515 *  PARAMETERS:
3516 *
3517 *      lp      - pointer to the device's private adapter structure
3518 *
3519 *  RETURNS:
3520 *
3521 *      N/A
3522 *
3523 ******************************************************************************/
3524void wl_wds_netdev_deregister( struct wl_private *lp )
3525{
3526        int count;
3527        /*------------------------------------------------------------------------*/
3528        DBG_FUNC( "wl_wds_netdev_deregister" );
3529        DBG_ENTER( DbgInfo );
3530        if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
3531                for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3532                        if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3533                                unregister_netdev( lp->wds_port[count].dev );
3534                        }
3535                        lp->wds_port[count].is_registered = FALSE;
3536                }
3537        }
3538        DBG_LEAVE( DbgInfo );
3539        return;
3540} // wl_wds_netdev_deregister
3541/*============================================================================*/
3542#endif  /* USE_WDS */
3543
3544
3545#if 0 //SCULL_USE_PROC /* don't waste space if unused */
3546/*
3547 * The proc filesystem: function to read and entry
3548 */
3549static void printf_hcf_16(struct seq_file *m, const char *s, hcf_16 *p, int n)
3550{
3551        int i, len;
3552
3553        seq_printf(m, "%-20.20s: ", s);
3554        len = 22;
3555
3556        for (i = 0; i < n; i++) {
3557                if (len % 80 > 75)
3558                        seq_putc(m, '\n');
3559                seq_printf(m, "%04X ", p[i]);
3560        }
3561        seq_putc(m, '\n');
3562}
3563
3564static void printf_hcf_8(struct seq_file *m, const char *s, hcf_8 *p, int n)
3565{
3566        int i, len;
3567
3568        seq_printf(m, "%-20.20s: ", s);
3569        len = 22;
3570
3571        for (i = 0; i <= n; i++) {
3572                if (len % 80 > 77)
3573                        seq_putc(m, '\n');
3574                seq_printf(m, "%02X ", p[i]);
3575        }
3576        seq_putc(m, '\n');
3577}
3578
3579static void printf_strct(struct seq_file *m, const char *s, hcf_16 *p)
3580{
3581        int i, len;
3582
3583        seq_printf(m, "%-20.20s: ", s);
3584        len = 22;
3585
3586        for ( i = 0; i <= *p; i++ ) {
3587                if (len % 80 > 75)
3588                        seq_putc(m, '\n');
3589                seq_printf(m,"%04X ", p[i]);
3590        }
3591        seq_putc(m, '\n');
3592}
3593
3594int scull_read_procmem(struct seq_file *m, void *v)
3595{
3596        struct wl_private       *lp = m->private;
3597        IFBP                            ifbp;
3598        CFG_HERMES_TALLIES_STRCT *p;
3599
3600        if (lp == NULL) {
3601                seq_puts(m, "No wl_private in scull_read_procmem\n" );
3602        } else if ( lp->wlags49_type == 0 ){
3603                ifbp = &lp->hcfCtx;
3604                seq_printf(m, "Magic:               0x%04X\n", ifbp->IFB_Magic );
3605                seq_printf(m, "IOBase:              0x%04X\n", ifbp->IFB_IOBase );
3606                seq_printf(m, "LinkStat:            0x%04X\n", ifbp->IFB_LinkStat );
3607                seq_printf(m, "DSLinkStat:          0x%04X\n", ifbp->IFB_DSLinkStat );
3608                seq_printf(m, "TickIni:         0x%08lX\n", ifbp->IFB_TickIni );
3609                seq_printf(m, "TickCnt:             0x%04X\n", ifbp->IFB_TickCnt );
3610                seq_printf(m, "IntOffCnt:           0x%04X\n", ifbp->IFB_IntOffCnt );
3611                printf_hcf_16(m, "IFB_FWIdentity",
3612                              &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
3613        } else if ( lp->wlags49_type == 1 ) {
3614                seq_printf(m, "Channel:              0x%04X\n", lp->Channel );
3615/****** seq_printf(m, "slock:                  %d\n", lp->slock );              */
3616//x             struct tq_struct            "task:               0x%04X\n", lp->task );
3617//x             struct net_device_stats     "stats:              0x%04X\n", lp->stats );
3618#ifdef WIRELESS_EXT
3619//x             struct iw_statistics        "wstats:             0x%04X\n", lp->wstats );
3620//x         seq_printf(m, "spy_number:           0x%04X\n", lp->spy_number );
3621//x             u_char                      spy_address[IW_MAX_SPY][ETH_ALEN];
3622//x             struct iw_quality           spy_stat[IW_MAX_SPY];
3623#endif // WIRELESS_EXT
3624                seq_printf(m, "IFB:                  0x%p\n", &lp->hcfCtx );
3625                seq_printf(m, "flags:                %#.8lX\n", lp->flags );  //;?use this format from now on
3626                seq_printf(m, "DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
3627#if DBG
3628                seq_printf(m, "DebugFlag (DbgInfo):   0x%08lX\n", DbgInfo->DebugFlag );
3629#endif // DBG
3630                seq_printf(m, "is_registered:        0x%04X\n", lp->is_registered );
3631//x             CFG_DRV_INFO_STRCT          "driverInfo:         0x%04X\n", lp->driverInfo );
3632                printf_strct( m, "driverInfo", (hcf_16*)&lp->driverInfo );
3633//x             CFG_IDENTITY_STRCT          "driverIdentity:     0x%04X\n", lp->driverIdentity );
3634                printf_strct( m, "driverIdentity", (hcf_16*)&lp->driverIdentity );
3635//x             CFG_FW_IDENTITY_STRCT       "StationIdentity:    0x%04X\n", lp->StationIdentity );
3636                printf_strct( m, "StationIdentity", (hcf_16*)&lp->StationIdentity );
3637//x             CFG_PRI_IDENTITY_STRCT      "PrimaryIdentity:    0x%04X\n", lp->PrimaryIdentity );
3638                printf_strct( m, "PrimaryIdentity", (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
3639                printf_strct( m, "PrimarySupplier", (hcf_16*)&lp->hcfCtx.IFB_PRISup );
3640//x             CFG_PRI_IDENTITY_STRCT      "NICIdentity:        0x%04X\n", lp->NICIdentity );
3641                printf_strct( m, "NICIdentity", (hcf_16*)&lp->NICIdentity );
3642//x             ltv_t                       "ltvRecord:          0x%04X\n", lp->ltvRecord );
3643                seq_printf(m, "txBytes:              0x%08lX\n", lp->txBytes );
3644                seq_printf(m, "maxPort:              0x%04X\n", lp->maxPort );        /* 0 for STA, 6 for AP */
3645                /* Elements used for async notification from hardware */
3646//x             RID_LOG_STRCT                           RidList[10];
3647//x             ltv_t                       "updatedRecord:      0x%04X\n", lp->updatedRecord );
3648//x             PROBE_RESP                                  "ProbeResp:                    0x%04X\n", lp->ProbeResp );
3649//x             ASSOC_STATUS_STRCT          "assoc_stat:         0x%04X\n", lp->assoc_stat );
3650//x             SECURITY_STATUS_STRCT       "sec_stat:           0x%04X\n", lp->sec_stat );
3651//x             u_char                      lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
3652                seq_printf(m, "PortType:             0x%04X\n", lp->PortType );           // 1 - 3 (1 [Normal] | 3 [AdHoc])
3653                seq_printf(m, "Channel:              0x%04X\n", lp->Channel );            // 0 - 14 (0)
3654//x             hcf_16                      TxRateControl[2];
3655                seq_printf(m, "TxRateControl[2]:     0x%04X 0x%04X\n",
3656                               lp->TxRateControl[0], lp->TxRateControl[1] );
3657                seq_printf(m, "DistanceBetweenAPs:   0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
3658                seq_printf(m, "RTSThreshold:         0x%04X\n", lp->RTSThreshold );       // 0 - 2347 (2347)
3659                seq_printf(m, "PMEnabled:            0x%04X\n", lp->PMEnabled );          // 0 - 2, 8001 - 8002 (0)
3660                seq_printf(m, "MicrowaveRobustness:  0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
3661                seq_printf(m, "CreateIBSS:           0x%04X\n", lp->CreateIBSS );         // 0 - 1 (0)
3662                seq_printf(m, "MulticastReceive:     0x%04X\n", lp->MulticastReceive );   // 0 - 1 (1)
3663                seq_printf(m, "MaxSleepDuration:     0x%04X\n", lp->MaxSleepDuration );   // 0 - 65535 (100)
3664//x             hcf_8                       MACAddress[ETH_ALEN];
3665                printf_hcf_8(m, "MACAddress", lp->MACAddress, ETH_ALEN );
3666//x             char                        NetworkName[HCF_MAX_NAME_LEN+1];
3667                seq_printf(m, "NetworkName:          %.32s\n", lp->NetworkName );
3668//x             char                        StationName[HCF_MAX_NAME_LEN+1];
3669                seq_printf(m, "EnableEncryption:     0x%04X\n", lp->EnableEncryption );   // 0 - 1 (0)
3670//x             char                        Key1[MAX_KEY_LEN+1];
3671                printf_hcf_8( m, "Key1", lp->Key1, MAX_KEY_LEN );
3672//x             char                        Key2[MAX_KEY_LEN+1];
3673//x             char                        Key3[MAX_KEY_LEN+1];
3674//x             char                        Key4[MAX_KEY_LEN+1];
3675                seq_printf(m, "TransmitKeyID:        0x%04X\n", lp->TransmitKeyID );      // 1 - 4 (1)
3676//x             CFG_DEFAULT_KEYS_STRCT      "DefaultKeys:         0x%04X\n", lp->DefaultKeys );
3677//x             u_char                      mailbox[MB_SIZE];
3678//x             char                        szEncryption[MAX_ENC_LEN];
3679                seq_printf(m, "driverEnable:         0x%04X\n", lp->driverEnable );
3680                seq_printf(m, "wolasEnable:          0x%04X\n", lp->wolasEnable );
3681                seq_printf(m, "atimWindow:           0x%04X\n", lp->atimWindow );
3682                seq_printf(m, "holdoverDuration:     0x%04X\n", lp->holdoverDuration );
3683//x             hcf_16                      MulticastRate[2];
3684                seq_printf(m, "authentication:       0x%04X\n", lp->authentication ); // is this AP specific?
3685                seq_printf(m, "promiscuousMode:      0x%04X\n", lp->promiscuousMode );
3686                seq_printf(m, "DownloadFirmware:     0x%04X\n", lp->DownloadFirmware );   // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
3687                seq_printf(m, "AuthKeyMgmtSuite:     0x%04X\n", lp->AuthKeyMgmtSuite );
3688                seq_printf(m, "loadBalancing:        0x%04X\n", lp->loadBalancing );
3689                seq_printf(m, "mediumDistribution:   0x%04X\n", lp->mediumDistribution );
3690                seq_printf(m, "txPowLevel:           0x%04X\n", lp->txPowLevel );
3691//          seq_printf(m, "shortRetryLimit:    0x%04X\n", lp->shortRetryLimit );
3692//          seq_printf(m, "longRetryLimit:     0x%04X\n", lp->longRetryLimit );
3693//x             hcf_16                      srsc[2];
3694//x             hcf_16                      brsc[2];
3695                seq_printf(m, "connectionControl:    0x%04X\n", lp->connectionControl );
3696//x             //hcf_16                      probeDataRates[2];
3697                seq_printf(m, "ownBeaconInterval:    0x%04X\n", lp->ownBeaconInterval );
3698                seq_printf(m, "coexistence:          0x%04X\n", lp->coexistence );
3699//x             WVLAN_FRAME                 "txF:                0x%04X\n", lp->txF );
3700//x             WVLAN_LFRAME                txList[DEFAULT_NUM_TX_FRAMES];
3701//x             struct list_head            "txFree:             0x%04X\n", lp->txFree );
3702//x             struct list_head            txQ[WVLAN_MAX_TX_QUEUES];
3703                seq_printf(m, "netif_queue_on:       0x%04X\n", lp->netif_queue_on );
3704                seq_printf(m, "txQ_count:            0x%04X\n", lp->txQ_count );
3705//x             DESC_STRCT                  "desc_rx:            0x%04X\n", lp->desc_rx );
3706//x             DESC_STRCT                  "desc_tx:            0x%04X\n", lp->desc_tx );
3707//x             WVLAN_PORT_STATE            "portState:          0x%04X\n", lp->portState );
3708//x             ScanResult                  "scan_results:       0x%04X\n", lp->scan_results );
3709//x             ProbeResult                 "probe_results:      0x%04X\n", lp->probe_results );
3710                seq_printf(m, "probe_num_aps:        0x%04X\n", lp->probe_num_aps );
3711                seq_printf(m, "use_dma:              0x%04X\n", lp->use_dma );
3712//x             DMA_STRCT                   "dma:                0x%04X\n", lp->dma );
3713#ifdef USE_RTS
3714                seq_printf(m, "useRTS:               0x%04X\n", lp->useRTS );
3715#endif  // USE_RTS
3716#if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
3717                //;?should we restore this to allow smaller memory footprint
3718                //;?I guess not. This should be brought under Debug mode only
3719                seq_printf(m, "DTIMPeriod:           0x%04X\n", lp->DTIMPeriod );         // 1 - 255 (1)
3720                seq_printf(m, "multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
3721                seq_printf(m, "RejectAny:            0x%04X\n", lp->RejectAny );          // 0 - 1 (0)
3722                seq_printf(m, "ExcludeUnencrypted:   0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
3723                seq_printf(m, "intraBSSRelay:        0x%04X\n", lp->intraBSSRelay );
3724                seq_printf(m, "wlags49_type:             0x%08lX\n", lp->wlags49_type );
3725#ifdef USE_WDS
3726//x             WVLAN_WDS_IF                wds_port[NUM_WDS_PORTS];
3727#endif // USE_WDS
3728#endif // HCF_AP
3729        } else if ( lp->wlags49_type == 2 ){
3730                seq_printf(m, "tallies to be added\n" );
3731//Hermes Tallies (IFB substructure) {
3732                p = &lp->hcfCtx.IFB_NIC_Tallies;
3733                seq_printf(m, "TxUnicastFrames:          %08lX\n", p->TxUnicastFrames );
3734                seq_printf(m, "TxMulticastFrames:        %08lX\n", p->TxMulticastFrames );
3735                seq_printf(m, "TxFragments:              %08lX\n", p->TxFragments );
3736                seq_printf(m, "TxUnicastOctets:          %08lX\n", p->TxUnicastOctets );
3737                seq_printf(m, "TxMulticastOctets:        %08lX\n", p->TxMulticastOctets );
3738                seq_printf(m, "TxDeferredTransmissions:  %08lX\n", p->TxDeferredTransmissions );
3739                seq_printf(m, "TxSingleRetryFrames:      %08lX\n", p->TxSingleRetryFrames );
3740                seq_printf(m, "TxMultipleRetryFrames:    %08lX\n", p->TxMultipleRetryFrames );
3741                seq_printf(m, "TxRetryLimitExceeded:     %08lX\n", p->TxRetryLimitExceeded );
3742                seq_printf(m, "TxDiscards:               %08lX\n", p->TxDiscards );
3743                seq_printf(m, "RxUnicastFrames:          %08lX\n", p->RxUnicastFrames );
3744                seq_printf(m, "RxMulticastFrames:        %08lX\n", p->RxMulticastFrames );
3745                seq_printf(m, "RxFragments:              %08lX\n", p->RxFragments );
3746                seq_printf(m, "RxUnicastOctets:          %08lX\n", p->RxUnicastOctets );
3747                seq_printf(m, "RxMulticastOctets:        %08lX\n", p->RxMulticastOctets );
3748                seq_printf(m, "RxFCSErrors:              %08lX\n", p->RxFCSErrors );
3749                seq_printf(m, "RxDiscardsNoBuffer:       %08lX\n", p->RxDiscardsNoBuffer );
3750                seq_printf(m, "TxDiscardsWrongSA:        %08lX\n", p->TxDiscardsWrongSA );
3751                seq_printf(m, "RxWEPUndecryptable:       %08lX\n", p->RxWEPUndecryptable );
3752                seq_printf(m, "RxMsgInMsgFragments:      %08lX\n", p->RxMsgInMsgFragments );
3753                seq_printf(m, "RxMsgInBadMsgFragments:   %08lX\n", p->RxMsgInBadMsgFragments );
3754                seq_printf(m, "RxDiscardsWEPICVError:    %08lX\n", p->RxDiscardsWEPICVError );
3755                seq_printf(m, "RxDiscardsWEPExcluded:    %08lX\n", p->RxDiscardsWEPExcluded );
3756#if (HCF_EXT) & HCF_EXT_TALLIES_FW
3757                //to be added ;?
3758#endif // HCF_EXT_TALLIES_FW
3759        } else if ( lp->wlags49_type & 0x8000 ) {       //;?kludgy but it is unclear to me were else to place this
3760#if DBG
3761                DbgInfo->DebugFlag = lp->wlags49_type & 0x7FFF;
3762#endif // DBG
3763                lp->wlags49_type = 0;                           //default to IFB again ;?
3764        } else {
3765                seq_printf(m, "unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
3766                seq_puts(m,
3767                         "0x0000 - IFB\n"
3768                         "0x0001 - wl_private\n"
3769                         "0x0002 - Tallies\n"
3770                         "0x8xxx - Change debufflag\n"
3771                         "ERROR    0001\nWARNING  0002\nNOTICE   0004\nTRACE    0008\n"
3772                         "VERBOSE  0010\nPARAM    0020\nBREAK    0040\nRX       0100\n"
3773                         "TX       0200\nDS       0400\n");
3774        }
3775        return 0;
3776} // scull_read_procmem
3777
3778static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
3779{
3780        static char             proc_number[11];
3781        unsigned int    nr = 0;
3782
3783        DBG_FUNC( "write_int" );
3784        DBG_ENTER( DbgInfo );
3785
3786        if (count > 9) {
3787                count = -EINVAL;
3788        } else if ( copy_from_user(proc_number, buffer, count) ) {
3789                count = -EFAULT;
3790        }
3791        if  (count > 0 ) {
3792                proc_number[count] = 0;
3793                nr = simple_strtoul(proc_number , NULL, 0);
3794                *(unsigned int *)data = nr;
3795                if ( nr & 0x8000 ) {    //;?kludgy but it is unclear to me were else to place this
3796#if DBG
3797                        DbgInfo->DebugFlag = nr & 0x7FFF;
3798#endif // DBG
3799                }
3800        }
3801        DBG_PRINT( "value: %08X\n", nr );
3802        DBG_LEAVE( DbgInfo );
3803        return count;
3804} // write_int
3805
3806#endif /* SCULL_USE_PROC */
3807
3808#ifdef DN554
3809#define RUN_AT(x)               (jiffies+(x))           //"borrowed" from include/pcmcia/k_compat.h
3810#define DS_OOR  0x8000          //Deepsleep OutOfRange Status
3811
3812                lp->timer_oor_cnt = DS_OOR;
3813                init_timer( &lp->timer_oor );
3814                lp->timer_oor.function = timer_oor;
3815                lp->timer_oor.data = (unsigned long)lp;
3816                lp->timer_oor.expires = RUN_AT( 3 * HZ );
3817                add_timer( &lp->timer_oor );
3818                printk(KERN_NOTICE "wl_enable: %ld\n", jiffies );               //;?remove me 1 day
3819#endif //DN554
3820#ifdef DN554
3821/*******************************************************************************
3822 *      timer_oor()
3823 *******************************************************************************
3824 *
3825 *  DESCRIPTION:
3826 *
3827 *
3828 *  PARAMETERS:
3829 *
3830 *      arg - a u_long representing a pointer to a dev_link_t structure for the
3831 *            device to be released.
3832 *
3833 *  RETURNS:
3834 *
3835 *      N/A
3836 *
3837 ******************************************************************************/
3838void timer_oor( u_long arg )
3839{
3840        struct wl_private       *lp = (struct wl_private *)arg;
3841
3842    /*------------------------------------------------------------------------*/
3843
3844    DBG_FUNC( "timer_oor" );
3845    DBG_ENTER( DbgInfo );
3846    DBG_PARAM( DbgInfo, "arg", "0x%08lx", arg );
3847
3848        printk(KERN_NOTICE "timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt );             //;?remove me 1 day
3849        lp->timer_oor_cnt += 10;
3850    if ( (lp->timer_oor_cnt & ~DS_OOR) > 300 ) {
3851                lp->timer_oor_cnt = 300;
3852        }
3853        lp->timer_oor_cnt |= DS_OOR;
3854        init_timer( &lp->timer_oor );
3855        lp->timer_oor.function = timer_oor;
3856        lp->timer_oor.data = (unsigned long)lp;
3857        lp->timer_oor.expires = RUN_AT( (lp->timer_oor_cnt & ~DS_OOR) * HZ );
3858        add_timer( &lp->timer_oor );
3859
3860    DBG_LEAVE( DbgInfo );
3861} // timer_oor
3862#endif //DN554
3863
3864MODULE_LICENSE("Dual BSD/GPL");
3865