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