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