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