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