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