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