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