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