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