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