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