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