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 	/* WEP Keys */
1997 	wl_set_wep_keys( lp );
1998 
1999 	/* Country Code */
2000 	/* countryInfo, ltvCountryInfo, CFG_CNF_COUNTRY_INFO */
2001 
2002 	DBG_LEAVE( DbgInfo );
2003 	return hcf_status;
2004 } // wl_put_ltv
2005 /*============================================================================*/
2006 
2007 
2008 /*******************************************************************************
2009  *	init_module()
2010  *******************************************************************************
2011  *
2012  *  DESCRIPTION:
2013  *
2014  *      Load the kernel module.
2015  *
2016  *  PARAMETERS:
2017  *
2018  *      N/A
2019  *
2020  *  RETURNS:
2021  *
2022  *      0 on success
2023  *      an errno value otherwise
2024  *
2025  ******************************************************************************/
wl_module_init(void)2026 static int __init wl_module_init( void )
2027 {
2028 	int result;
2029 	/*------------------------------------------------------------------------*/
2030 
2031 	DBG_FUNC( "wl_module_init" );
2032 
2033 #if DBG
2034 	/* Convert "standard" PCMCIA parameter pc_debug to a reasonable DebugFlag value.
2035 	 * NOTE: The values all fall through to the lower values. */
2036 	DbgInfo->DebugFlag = 0;
2037 	DbgInfo->DebugFlag = DBG_TRACE_ON;		//;?get this mess resolved one day
2038 	if ( pc_debug ) switch( pc_debug ) {
2039 	  case 8:
2040 		DbgInfo->DebugFlag |= DBG_DS_ON;
2041 	  case 7:
2042 		DbgInfo->DebugFlag |= DBG_RX_ON | DBG_TX_ON;
2043 	  case 6:
2044 		DbgInfo->DebugFlag |= DBG_PARAM_ON;
2045 	  case 5:
2046 		DbgInfo->DebugFlag |= DBG_TRACE_ON;
2047 	  case 4:
2048 		DbgInfo->DebugFlag |= DBG_VERBOSE_ON;
2049 	  case 1:
2050 		DbgInfo->DebugFlag |= DBG_DEFAULTS;
2051 	  default:
2052 		break;
2053 	}
2054 #endif /* DBG */
2055 
2056 	DBG_ENTER( DbgInfo );
2057 	printk(KERN_INFO "%s\n", VERSION_INFO);
2058     	printk(KERN_INFO "*** Modified for kernel 2.6 by Henk de Groot <pe1dnn@amsat.org>\n");
2059         printk(KERN_INFO "*** Based on 7.18 version by Andrey Borzenkov <arvidjaar@mail.ru> $Revision: 39 $\n");
2060 
2061 
2062 // ;?#if (HCF_TYPE) & HCF_TYPE_AP
2063 // 	DBG_PRINT( "Access Point Mode (AP) Support: YES\n" );
2064 // #else
2065 // 	DBG_PRINT( "Access Point Mode (AP) Support: NO\n" );
2066 // #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2067 
2068 	result = wl_adapter_init_module( );
2069 	DBG_LEAVE( DbgInfo );
2070 	return result;
2071 } // init_module
2072 /*============================================================================*/
2073 
2074 
2075 /*******************************************************************************
2076  *	cleanup_module()
2077  *******************************************************************************
2078  *
2079  *  DESCRIPTION:
2080  *
2081  *      Unload the kernel module.
2082  *
2083  *  PARAMETERS:
2084  *
2085  *      N/A
2086  *
2087  *  RETURNS:
2088  *
2089  *      N/A
2090  *
2091  ******************************************************************************/
wl_module_exit(void)2092 static void __exit wl_module_exit( void )
2093 {
2094 	DBG_FUNC( "wl_module_exit" );
2095 	DBG_ENTER(DbgInfo);
2096 
2097 	wl_adapter_cleanup_module( );
2098 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
2099 	remove_proc_entry( "wlags", NULL );		//;?why so a-symmetric compared to location of create_proc_read_entry
2100 #endif
2101 
2102 	DBG_LEAVE( DbgInfo );
2103 	return;
2104 } // cleanup_module
2105 /*============================================================================*/
2106 
2107 module_init(wl_module_init);
2108 module_exit(wl_module_exit);
2109 
2110 /*******************************************************************************
2111  *	wl_isr()
2112  *******************************************************************************
2113  *
2114  *  DESCRIPTION:
2115  *
2116  *      The Interrupt Service Routine for the driver.
2117  *
2118  *  PARAMETERS:
2119  *
2120  *      irq     -   the irq the interrupt came in on
2121  *      dev_id  -   a buffer containing information about the request
2122  *      regs    -
2123  *
2124  *  RETURNS:
2125  *
2126  *      N/A
2127  *
2128  ******************************************************************************/
wl_isr(int irq,void * dev_id,struct pt_regs * regs)2129 irqreturn_t wl_isr( int irq, void *dev_id, struct pt_regs *regs )
2130 {
2131 	int                 events;
2132 	struct net_device   *dev = (struct net_device *) dev_id;
2133 	struct wl_private   *lp = NULL;
2134 	/*------------------------------------------------------------------------*/
2135 	if (( dev == NULL ) || ( !netif_device_present( dev ))) {
2136 		return IRQ_NONE;
2137 	}
2138 
2139 	/* Set the wl_private pointer (lp), now that we know that dev is non-null */
2140 	lp = wl_priv(dev);
2141 
2142 #ifdef USE_RTS
2143 	if ( lp->useRTS == 1 ) {
2144 		DBG_PRINT( "EXITING ISR, IN RTS MODE...\n" );
2145 		return;
2146 		}
2147 #endif  /* USE_RTS */
2148 
2149 	/* If we have interrupts pending, then put them on a system task
2150 	   queue. Otherwise turn interrupts back on */
2151 	events = hcf_action( &lp->hcfCtx, HCF_ACT_INT_OFF );
2152 
2153 	if ( events == HCF_INT_PENDING ) {
2154 		/* Schedule the ISR handler as a bottom-half task in the
2155 		   tq_immediate queue */
2156 		tasklet_schedule(&lp->task);
2157 	} else {
2158 		//DBG_PRINT( "NOT OUR INTERRUPT\n" );
2159 		hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2160 	}
2161 
2162 	return IRQ_RETVAL(events == HCF_INT_PENDING);
2163 } // wl_isr
2164 /*============================================================================*/
2165 
2166 
2167 /*******************************************************************************
2168  *	wl_isr_handler()
2169  *******************************************************************************
2170  *
2171  *  DESCRIPTION:
2172  *
2173  *      The ISR handler, scheduled to run in a deferred context by the ISR. This
2174  *      is where the ISR's work actually gets done.
2175  *
2176  *  PARAMETERS:
2177  *
2178  *      lp  - a pointer to the device's private adapter structure
2179  *
2180  *  RETURNS:
2181  *
2182  *      N/A
2183  *
2184  ******************************************************************************/
2185 #define WVLAN_MAX_INT_SERVICES  50
2186 
wl_isr_handler(unsigned long p)2187 void wl_isr_handler( unsigned long p )
2188 {
2189 	struct net_device       *dev;
2190 	unsigned long           flags;
2191 	bool_t                  stop = TRUE;
2192 	int                     count;
2193 	int                     result;
2194         struct wl_private       *lp = (struct wl_private *)p;
2195 	/*------------------------------------------------------------------------*/
2196 
2197 	if ( lp == NULL ) {
2198 		DBG_PRINT( "wl_isr_handler  lp adapter pointer is NULL!!!\n" );
2199 	} else {
2200 		wl_lock( lp, &flags );
2201 
2202 		dev = (struct net_device *)lp->dev;
2203 		if ( dev != NULL && netif_device_present( dev ) ) stop = FALSE;
2204 		for( count = 0; stop == FALSE && count < WVLAN_MAX_INT_SERVICES; count++ ) {
2205 			stop = TRUE;
2206 			result = hcf_service_nic( &lp->hcfCtx,
2207 									  (wci_bufp)lp->lookAheadBuf,
2208 									  sizeof( lp->lookAheadBuf ));
2209 			if ( result == HCF_ERR_MIC ) {
2210 				wl_wext_event_mic_failed( dev ); 	/* Send an event that MIC failed */
2211 				//;?this seems wrong if HCF_ERR_MIC coincides with another event, stop gets FALSE
2212 				//so why not do it always ;?
2213 			}
2214 
2215 #ifndef USE_MBOX_SYNC
2216 			if ( lp->hcfCtx.IFB_MBInfoLen != 0 ) {	/* anything in the mailbox */
2217 				wl_mbx( lp );
2218 				stop = FALSE;
2219 			}
2220 #endif
2221 			/* Check for a Link status event */
2222 			if ( ( lp->hcfCtx.IFB_LinkStat & CFG_LINK_STAT_FW ) != 0 ) {
2223 				wl_process_link_status( lp );
2224 				stop = FALSE;
2225 			}
2226 			/* Check for probe response events */
2227 			if ( lp->ProbeResp.infoType != 0 &&
2228 				lp->ProbeResp.infoType != 0xFFFF ) {
2229 				wl_process_probe_response( lp );
2230 				memset( &lp->ProbeResp, 0, sizeof( lp->ProbeResp ));
2231 				lp->ProbeResp.infoType = 0xFFFF;
2232 				stop = FALSE;
2233 			}
2234 			/* Check for updated record events */
2235 			if ( lp->updatedRecord.len != 0xFFFF ) {
2236 				wl_process_updated_record( lp );
2237 				lp->updatedRecord.len = 0xFFFF;
2238 				stop = FALSE;
2239 			}
2240 			/* Check for association status events */
2241 			if ( lp->assoc_stat.len != 0xFFFF ) {
2242 				wl_process_assoc_status( lp );
2243 				lp->assoc_stat.len = 0xFFFF;
2244 				stop = FALSE;
2245 			}
2246 			/* Check for security status events */
2247 			if ( lp->sec_stat.len != 0xFFFF ) {
2248 				wl_process_security_status( lp );
2249 				lp->sec_stat.len = 0xFFFF;
2250 				stop = FALSE;
2251 			}
2252 
2253 #ifdef ENABLE_DMA
2254 			if ( lp->use_dma ) {
2255 				/* Check for DMA Rx packets */
2256 				if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_RDMAD ) {
2257 					wl_rx_dma( dev );
2258 					stop = FALSE;
2259 				}
2260 				/* Return Tx DMA descriptors to host */
2261 				if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_TDMAD ) {
2262 					wl_pci_dma_hcf_reclaim_tx( lp );
2263 					stop = FALSE;
2264 				}
2265 			}
2266 			else
2267 #endif // ENABLE_DMA
2268 			{
2269 				/* Check for Rx packets */
2270 				if ( lp->hcfCtx.IFB_RxLen != 0 ) {
2271 					wl_rx( dev );
2272 					stop = FALSE;
2273 				}
2274 				/* Make sure that queued frames get sent */
2275 				if ( wl_send( lp )) {
2276 					stop = FALSE;
2277 				}
2278 			}
2279 		}
2280 		/* We're done, so turn interrupts which were turned off in wl_isr, back on */
2281 		hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2282 		wl_unlock( lp, &flags );
2283 	}
2284 	return;
2285 } // wl_isr_handler
2286 /*============================================================================*/
2287 
2288 
2289 /*******************************************************************************
2290  *	wl_remove()
2291  *******************************************************************************
2292  *
2293  *  DESCRIPTION:
2294  *
2295  *      Notify the adapter that it has been removed. Since the adapter is gone,
2296  *  we should no longer try to talk to it.
2297  *
2298  *  PARAMETERS:
2299  *
2300  *      dev - a pointer to the device's net_device structure
2301  *
2302  *  RETURNS:
2303  *
2304  *      N/A
2305  *
2306  ******************************************************************************/
wl_remove(struct net_device * dev)2307 void wl_remove( struct net_device *dev )
2308 {
2309 	struct wl_private   *lp = wl_priv(dev);
2310 	unsigned long   flags;
2311 	/*------------------------------------------------------------------------*/
2312 	DBG_FUNC( "wl_remove" );
2313 	DBG_ENTER( DbgInfo );
2314 
2315 	DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2316 
2317 	wl_lock( lp, &flags );
2318 
2319 	/* stop handling interrupts */
2320 	wl_act_int_off( lp );
2321         lp->is_handling_int = WL_NOT_HANDLING_INT;
2322 
2323 	/*
2324          * Disable the ports: just change state: since the
2325          * card is gone it is useless to talk to it and at
2326          * disconnect all state information is lost anyway.
2327          */
2328 	/* Reset portState */
2329 	lp->portState = WVLAN_PORT_STATE_DISABLED;
2330 
2331 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
2332 #ifdef USE_WDS
2333 	//wl_disable_wds_ports( lp );
2334 #endif // USE_WDS
2335 #endif  /* (HCF_TYPE) & HCF_TYPE_AP */
2336 
2337 	/* Mark the device as unregistered */
2338 	lp->is_registered = FALSE;
2339 
2340 	/* Deregister the WDS ports as well */
2341 	WL_WDS_NETDEV_DEREGISTER( lp );
2342 #ifdef USE_RTS
2343 	if ( lp->useRTS == 1 ) {
2344 		wl_unlock( lp, &flags );
2345 
2346 		DBG_LEAVE( DbgInfo );
2347 		return;
2348 	}
2349 #endif  /* USE_RTS */
2350 
2351 	/* Inform the HCF that the card has been removed */
2352 	hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2353 
2354 	wl_unlock( lp, &flags );
2355 
2356 	DBG_LEAVE( DbgInfo );
2357 	return;
2358 } // wl_remove
2359 /*============================================================================*/
2360 
2361 
2362 /*******************************************************************************
2363  *	wl_suspend()
2364  *******************************************************************************
2365  *
2366  *  DESCRIPTION:
2367  *
2368  *      Power-down and halt the adapter.
2369  *
2370  *  PARAMETERS:
2371  *
2372  *      dev - a pointer to the device's net_device structure
2373  *
2374  *  RETURNS:
2375  *
2376  *      N/A
2377  *
2378  ******************************************************************************/
wl_suspend(struct net_device * dev)2379 void wl_suspend( struct net_device *dev )
2380 {
2381 	struct wl_private  *lp = wl_priv(dev);
2382 	unsigned long   flags;
2383 	/*------------------------------------------------------------------------*/
2384 	DBG_FUNC( "wl_suspend" );
2385 	DBG_ENTER( DbgInfo );
2386 
2387 	DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2388 
2389 	/* The adapter is suspended:
2390 			Stop the adapter
2391 			Power down
2392 	*/
2393 	wl_lock( lp, &flags );
2394 
2395 	/* Disable interrupt handling */
2396 	wl_act_int_off( lp );
2397 
2398 	/* Disconnect */
2399 	wl_disconnect( lp );
2400 
2401 	/* Disable */
2402 	wl_disable( lp );
2403 
2404         /* Disconnect from the adapter */
2405 	hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2406 
2407 	/* Reset portState to be sure (should have been done by wl_disable */
2408 	lp->portState = WVLAN_PORT_STATE_DISABLED;
2409 
2410 	wl_unlock( lp, &flags );
2411 
2412 	DBG_LEAVE( DbgInfo );
2413 	return;
2414 } // wl_suspend
2415 /*============================================================================*/
2416 
2417 
2418 /*******************************************************************************
2419  *	wl_resume()
2420  *******************************************************************************
2421  *
2422  *  DESCRIPTION:
2423  *
2424  *      Resume a previously suspended adapter.
2425  *
2426  *  PARAMETERS:
2427  *
2428  *      dev - a pointer to the device's net_device structure
2429  *
2430  *  RETURNS:
2431  *
2432  *      N/A
2433  *
2434  ******************************************************************************/
wl_resume(struct net_device * dev)2435 void wl_resume(struct net_device *dev)
2436 {
2437 	struct wl_private  *lp = wl_priv(dev);
2438 	unsigned long   flags;
2439 	/*------------------------------------------------------------------------*/
2440 	DBG_FUNC( "wl_resume" );
2441 	DBG_ENTER( DbgInfo );
2442 
2443 	DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2444 
2445 	wl_lock( lp, &flags );
2446 
2447         /* Connect to the adapter */
2448 	hcf_connect( &lp->hcfCtx, dev->base_addr );
2449 
2450 	/* Reset portState */
2451 	lp->portState = WVLAN_PORT_STATE_DISABLED;
2452 
2453 	/* Power might have been off, assume the card lost the firmware*/
2454 	lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
2455 
2456 	/* Reload the firmware and restart */
2457 	wl_reset( dev );
2458 
2459 	/* Resume interrupt handling */
2460 	wl_act_int_on( lp );
2461 
2462 	wl_unlock( lp, &flags );
2463 
2464 	DBG_LEAVE( DbgInfo );
2465 	return;
2466 } // wl_resume
2467 /*============================================================================*/
2468 
2469 
2470 /*******************************************************************************
2471  *	wl_release()
2472  *******************************************************************************
2473  *
2474  *  DESCRIPTION:
2475  *
2476  *      This function perfroms a check on the device and calls wl_remove() if
2477  *  necessary. This function can be used for all bus types, but exists mostly
2478  *  for the benefit of the Card Services driver, as there are times when
2479  *  wl_remove() does not get called.
2480  *
2481  *  PARAMETERS:
2482  *
2483  *      dev - a pointer to the device's net_device structure
2484  *
2485  *  RETURNS:
2486  *
2487  *      N/A
2488  *
2489  ******************************************************************************/
wl_release(struct net_device * dev)2490 void wl_release( struct net_device *dev )
2491 {
2492 	struct wl_private  *lp = wl_priv(dev);
2493 	/*------------------------------------------------------------------------*/
2494 	DBG_FUNC( "wl_release" );
2495 	DBG_ENTER( DbgInfo );
2496 
2497 	DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2498 	/* If wl_remove() hasn't been called (i.e. when Card Services is shut
2499 	   down with the card in the slot), then call it */
2500 	if ( lp->is_registered == TRUE ) {
2501 		DBG_TRACE( DbgInfo, "Calling unregister_netdev(), as it wasn't called yet\n" );
2502 		wl_remove( dev );
2503 
2504 		lp->is_registered = FALSE;
2505 	}
2506 
2507 	DBG_LEAVE( DbgInfo );
2508 	return;
2509 } // wl_release
2510 /*============================================================================*/
2511 
2512 
2513 /*******************************************************************************
2514  *	wl_get_irq_mask()
2515  *******************************************************************************
2516  *
2517  *  DESCRIPTION:
2518  *
2519  *      Accessor function to retrieve the irq_mask module parameter
2520  *
2521  *  PARAMETERS:
2522  *
2523  *      N/A
2524  *
2525  *  RETURNS:
2526  *
2527  *      The irq_mask module parameter
2528  *
2529  ******************************************************************************/
wl_get_irq_mask(void)2530 p_u16 wl_get_irq_mask( void )
2531 {
2532 	return irq_mask;
2533 } // wl_get_irq_mask
2534 /*============================================================================*/
2535 
2536 
2537 /*******************************************************************************
2538  *	wl_get_irq_list()
2539  *******************************************************************************
2540  *
2541  *  DESCRIPTION:
2542  *
2543  *      Accessor function to retrieve the irq_list module parameter
2544  *
2545  *  PARAMETERS:
2546  *
2547  *      N/A
2548  *
2549  *  RETURNS:
2550  *
2551  *      The irq_list module parameter
2552  *
2553  ******************************************************************************/
wl_get_irq_list(void)2554 p_s8 * wl_get_irq_list( void )
2555 {
2556 	return irq_list;
2557 } // wl_get_irq_list
2558 /*============================================================================*/
2559 
2560 
2561 
2562 /*******************************************************************************
2563  *	wl_enable()
2564  *******************************************************************************
2565  *
2566  *  DESCRIPTION:
2567  *
2568  *      Used to enable MAC ports
2569  *
2570  *  PARAMETERS:
2571  *
2572  *      lp      - pointer to the device's private adapter structure
2573  *
2574  *  RETURNS:
2575  *
2576  *      N/A
2577  *
2578  ******************************************************************************/
wl_enable(struct wl_private * lp)2579 int wl_enable( struct wl_private *lp )
2580 {
2581 	int hcf_status = HCF_SUCCESS;
2582 	/*------------------------------------------------------------------------*/
2583 	DBG_FUNC( "wl_enable" );
2584 	DBG_ENTER( DbgInfo );
2585 
2586 	if ( lp->portState == WVLAN_PORT_STATE_ENABLED ) {
2587 		DBG_TRACE( DbgInfo, "No action: Card already enabled\n" );
2588 	} else if ( lp->portState == WVLAN_PORT_STATE_CONNECTED ) {
2589 		//;?suspicuous logic, how can you be connected without being enabled so this is probably dead code
2590 		DBG_TRACE( DbgInfo, "No action: Card already connected\n" );
2591 	} else {
2592 		hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_ENABLE );
2593 		if ( hcf_status == HCF_SUCCESS ) {
2594 			/* Set the status of the NIC to enabled */
2595 			lp->portState = WVLAN_PORT_STATE_ENABLED;   //;?bad mnemonic, NIC iso PORT
2596 #ifdef ENABLE_DMA
2597 			if ( lp->use_dma ) {
2598 				wl_pci_dma_hcf_supply( lp );  //;?always succes?
2599 			}
2600 #endif
2601 		}
2602 	}
2603 	if ( hcf_status != HCF_SUCCESS ) {  //;?make this an assert
2604 		DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2605 	}
2606 	DBG_LEAVE( DbgInfo );
2607 	return hcf_status;
2608 } // wl_enable
2609 /*============================================================================*/
2610 
2611 
2612 #ifdef USE_WDS
2613 /*******************************************************************************
2614  *	wl_enable_wds_ports()
2615  *******************************************************************************
2616  *
2617  *  DESCRIPTION:
2618  *
2619  *      Used to enable the WDS MAC ports 1-6
2620  *
2621  *  PARAMETERS:
2622  *
2623  *      lp      - pointer to the device's private adapter structure
2624  *
2625  *  RETURNS:
2626  *
2627  *      N/A
2628  *
2629  ******************************************************************************/
wl_enable_wds_ports(struct wl_private * lp)2630 void wl_enable_wds_ports( struct wl_private * lp )
2631 {
2632 
2633 	DBG_FUNC( "wl_enable_wds_ports" );
2634 	DBG_ENTER( DbgInfo );
2635 	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ){
2636 		DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2637 	}
2638 	DBG_LEAVE( DbgInfo );
2639 	return;
2640 } // wl_enable_wds_ports
2641 #endif  /* USE_WDS */
2642 /*============================================================================*/
2643 
2644 
2645 /*******************************************************************************
2646  *	wl_connect()
2647  *******************************************************************************
2648  *
2649  *  DESCRIPTION:
2650  *
2651  *      Used to connect a MAC port
2652  *
2653  *  PARAMETERS:
2654  *
2655  *      lp      - pointer to the device's private adapter structure
2656  *
2657  *  RETURNS:
2658  *
2659  *      N/A
2660  *
2661  ******************************************************************************/
wl_connect(struct wl_private * lp)2662 int wl_connect( struct wl_private *lp )
2663 {
2664 	int hcf_status;
2665 	/*------------------------------------------------------------------------*/
2666 
2667 	DBG_FUNC( "wl_connect" );
2668 	DBG_ENTER( DbgInfo );
2669 
2670 	if ( lp->portState != WVLAN_PORT_STATE_ENABLED ) {
2671 		DBG_TRACE( DbgInfo, "No action: Not in enabled state\n" );
2672 		DBG_LEAVE( DbgInfo );
2673 		return HCF_SUCCESS;
2674 	}
2675 	hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_CONNECT );
2676 	if ( hcf_status == HCF_SUCCESS ) {
2677 		lp->portState = WVLAN_PORT_STATE_CONNECTED;
2678 	}
2679 	DBG_LEAVE( DbgInfo );
2680 	return hcf_status;
2681 } // wl_connect
2682 /*============================================================================*/
2683 
2684 
2685 /*******************************************************************************
2686  *	wl_disconnect()
2687  *******************************************************************************
2688  *
2689  *  DESCRIPTION:
2690  *
2691  *      Used to disconnect a MAC port
2692  *
2693  *  PARAMETERS:
2694  *
2695  *      lp      - pointer to the device's private adapter structure
2696  *
2697  *  RETURNS:
2698  *
2699  *      N/A
2700  *
2701  ******************************************************************************/
wl_disconnect(struct wl_private * lp)2702 int wl_disconnect( struct wl_private *lp )
2703 {
2704 	int hcf_status;
2705 	/*------------------------------------------------------------------------*/
2706 
2707 	DBG_FUNC( "wl_disconnect" );
2708 	DBG_ENTER( DbgInfo );
2709 
2710 	if ( lp->portState != WVLAN_PORT_STATE_CONNECTED ) {
2711 		DBG_TRACE( DbgInfo, "No action: Not in connected state\n" );
2712 		DBG_LEAVE( DbgInfo );
2713 		return HCF_SUCCESS;
2714 	}
2715 	hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISCONNECT );
2716 	if ( hcf_status == HCF_SUCCESS ) {
2717 		lp->portState = WVLAN_PORT_STATE_ENABLED;
2718 	}
2719 	DBG_LEAVE( DbgInfo );
2720 	return hcf_status;
2721 } // wl_disconnect
2722 /*============================================================================*/
2723 
2724 
2725 /*******************************************************************************
2726  *	wl_disable()
2727  *******************************************************************************
2728  *
2729  *  DESCRIPTION:
2730  *
2731  *      Used to disable MAC ports
2732  *
2733  *  PARAMETERS:
2734  *
2735  *      lp      - pointer to the device's private adapter structure
2736  *      port    - the MAC port to disable
2737  *
2738  *  RETURNS:
2739  *
2740  *      N/A
2741  *
2742  ******************************************************************************/
wl_disable(struct wl_private * lp)2743 int wl_disable( struct wl_private *lp )
2744 {
2745 	int hcf_status = HCF_SUCCESS;
2746 	/*------------------------------------------------------------------------*/
2747 	DBG_FUNC( "wl_disable" );
2748 	DBG_ENTER( DbgInfo );
2749 
2750 	if ( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
2751 		DBG_TRACE( DbgInfo, "No action: Port state is disabled\n" );
2752 	} else {
2753 		hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISABLE );
2754 		if ( hcf_status == HCF_SUCCESS ) {
2755 			/* Set the status of the port to disabled */ //;?bad mnemonic use NIC iso PORT
2756 			lp->portState = WVLAN_PORT_STATE_DISABLED;
2757 
2758 #ifdef ENABLE_DMA
2759 			if ( lp->use_dma ) {
2760 				wl_pci_dma_hcf_reclaim( lp );
2761 			}
2762 #endif
2763 		}
2764 	}
2765 	if ( hcf_status != HCF_SUCCESS ) {
2766 		DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2767 	}
2768 	DBG_LEAVE( DbgInfo );
2769 	return hcf_status;
2770 } // wl_disable
2771 /*============================================================================*/
2772 
2773 
2774 #ifdef USE_WDS
2775 /*******************************************************************************
2776  *	wl_disable_wds_ports()
2777  *******************************************************************************
2778  *
2779  *  DESCRIPTION:
2780  *
2781  *      Used to disable the WDS MAC ports 1-6
2782  *
2783  *  PARAMETERS:
2784  *
2785  *      lp      - pointer to the device's private adapter structure
2786  *
2787  *  RETURNS:
2788  *
2789  *      N/A
2790  *
2791  ******************************************************************************/
wl_disable_wds_ports(struct wl_private * lp)2792 void wl_disable_wds_ports( struct wl_private * lp )
2793 {
2794 
2795 	DBG_FUNC( "wl_disable_wds_ports" );
2796 	DBG_ENTER( DbgInfo );
2797 
2798 	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ){
2799 		DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2800 	}
2801 // 	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
2802 // 		wl_disable( lp, HCF_PORT_1 );
2803 // 		wl_disable( lp, HCF_PORT_2 );
2804 // 		wl_disable( lp, HCF_PORT_3 );
2805 // 		wl_disable( lp, HCF_PORT_4 );
2806 // 		wl_disable( lp, HCF_PORT_5 );
2807 // 		wl_disable( lp, HCF_PORT_6 );
2808 // 	}
2809 	DBG_LEAVE( DbgInfo );
2810 	return;
2811 } // wl_disable_wds_ports
2812 #endif // USE_WDS
2813 /*============================================================================*/
2814 
2815 
2816 #ifndef USE_MBOX_SYNC
2817 /*******************************************************************************
2818  *	wl_mbx()
2819  *******************************************************************************
2820  *
2821  *  DESCRIPTION:
2822  *      This function is used to read and process a mailbox message.
2823  *
2824  *
2825  *  PARAMETERS:
2826  *
2827  *      lp      - pointer to the device's private adapter structure
2828  *
2829  *  RETURNS:
2830  *
2831  *      an HCF status code
2832  *
2833  ******************************************************************************/
wl_mbx(struct wl_private * lp)2834 int wl_mbx( struct wl_private *lp )
2835 {
2836 	int hcf_status = HCF_SUCCESS;
2837 	/*------------------------------------------------------------------------*/
2838 	DBG_FUNC( "wl_mbx" );
2839 	DBG_ENTER( DbgInfo );
2840 	DBG_TRACE( DbgInfo, "Mailbox Info: IFB_MBInfoLen: %d\n",
2841 			   lp->hcfCtx.IFB_MBInfoLen );
2842 
2843 	memset( &( lp->ltvRecord ), 0, sizeof( ltv_t ));
2844 
2845 	lp->ltvRecord.len = MB_SIZE;
2846 	lp->ltvRecord.typ = CFG_MB_INFO;
2847 	hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2848 
2849 	if ( hcf_status != HCF_SUCCESS ) {
2850 		DBG_ERROR( DbgInfo, "hcf_get_info returned 0x%x\n", hcf_status );
2851 
2852 		DBG_LEAVE( DbgInfo );
2853 		return hcf_status;
2854 	}
2855 
2856 	if ( lp->ltvRecord.typ == CFG_MB_INFO ) {
2857 		DBG_LEAVE( DbgInfo );
2858 		return hcf_status;
2859 	}
2860 	/* Endian translate the mailbox data, then process the message */
2861 	wl_endian_translate_mailbox( &( lp->ltvRecord ));
2862 	wl_process_mailbox( lp );
2863 	DBG_LEAVE( DbgInfo );
2864 	return hcf_status;
2865 } // wl_mbx
2866 /*============================================================================*/
2867 
2868 
2869 /*******************************************************************************
2870  *	wl_endian_translate_mailbox()
2871  *******************************************************************************
2872  *
2873  *  DESCRIPTION:
2874  *
2875  *      This function will perform the tedious task of endian translating all
2876  *  fields withtin a mailbox message which need translating.
2877  *
2878  *  PARAMETERS:
2879  *
2880  *      ltv - pointer to the LTV to endian translate
2881  *
2882  *  RETURNS:
2883  *
2884  *      none
2885  *
2886  ******************************************************************************/
wl_endian_translate_mailbox(ltv_t * ltv)2887 void wl_endian_translate_mailbox( ltv_t *ltv )
2888 {
2889 
2890 	DBG_FUNC( "wl_endian_translate_mailbox" );
2891 	DBG_ENTER( DbgInfo );
2892 	switch( ltv->typ ) {
2893 	  case CFG_TALLIES:
2894 		break;
2895 
2896 	  case CFG_SCAN:
2897 		{
2898 			int num_aps;
2899 			SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)&ltv->u.u8[0];
2900 
2901 			num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2902 								 ( sizeof( SCAN_RS_STRCT )));
2903 
2904 			while( num_aps >= 1 ) {
2905 				num_aps--;
2906 
2907 				aps[num_aps].channel_id =
2908 					CNV_LITTLE_TO_INT( aps[num_aps].channel_id );
2909 
2910 				aps[num_aps].noise_level =
2911 					CNV_LITTLE_TO_INT( aps[num_aps].noise_level );
2912 
2913 				aps[num_aps].signal_level =
2914 					CNV_LITTLE_TO_INT( aps[num_aps].signal_level );
2915 
2916 				aps[num_aps].beacon_interval_time =
2917 					CNV_LITTLE_TO_INT( aps[num_aps].beacon_interval_time );
2918 
2919 				aps[num_aps].capability =
2920 					CNV_LITTLE_TO_INT( aps[num_aps].capability );
2921 
2922 				aps[num_aps].ssid_len =
2923 					CNV_LITTLE_TO_INT( aps[num_aps].ssid_len );
2924 
2925 				aps[num_aps].ssid_val[aps[num_aps].ssid_len] = 0;
2926 			}
2927 		}
2928 		break;
2929 
2930 	  case CFG_ACS_SCAN:
2931 		{
2932 			PROBE_RESP *probe_resp = (PROBE_RESP *)ltv;
2933 
2934 			probe_resp->frameControl   = CNV_LITTLE_TO_INT( probe_resp->frameControl );
2935 			probe_resp->durID          = CNV_LITTLE_TO_INT( probe_resp->durID );
2936 			probe_resp->sequence       = CNV_LITTLE_TO_INT( probe_resp->sequence );
2937 			probe_resp->dataLength     = CNV_LITTLE_TO_INT( probe_resp->dataLength );
2938 #ifndef WARP
2939 			probe_resp->lenType        = CNV_LITTLE_TO_INT( probe_resp->lenType );
2940 #endif // WARP
2941 			probe_resp->beaconInterval = CNV_LITTLE_TO_INT( probe_resp->beaconInterval );
2942 			probe_resp->capability     = CNV_LITTLE_TO_INT( probe_resp->capability );
2943 			probe_resp->flags          = CNV_LITTLE_TO_INT( probe_resp->flags );
2944 		}
2945 		break;
2946 
2947 	  case CFG_LINK_STAT:
2948 #define ls ((LINK_STATUS_STRCT *)ltv)
2949 			ls->linkStatus = CNV_LITTLE_TO_INT( ls->linkStatus );
2950 		break;
2951 #undef ls
2952 
2953 	  case CFG_ASSOC_STAT:
2954 		{
2955 			ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
2956 
2957 			as->assocStatus = CNV_LITTLE_TO_INT( as->assocStatus );
2958 		}
2959 		break;
2960 
2961 	  case CFG_SECURITY_STAT:
2962 		{
2963 			SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
2964 
2965 			ss->securityStatus  = CNV_LITTLE_TO_INT( ss->securityStatus );
2966 			ss->reason          = CNV_LITTLE_TO_INT( ss->reason );
2967 		}
2968 		break;
2969 
2970 	  case CFG_WMP:
2971 		break;
2972 
2973 	  case CFG_NULL:
2974 		break;
2975 
2976 	default:
2977 		break;
2978 	}
2979 
2980 	DBG_LEAVE( DbgInfo );
2981 	return;
2982 } // wl_endian_translate_mailbox
2983 /*============================================================================*/
2984 
2985 /*******************************************************************************
2986  *	wl_process_mailbox()
2987  *******************************************************************************
2988  *
2989  *  DESCRIPTION:
2990  *
2991  *      This function will process the mailbox data.
2992  *
2993  *  PARAMETERS:
2994  *
2995  *      ltv - pointer to the LTV to be processed.
2996  *
2997  *  RETURNS:
2998  *
2999  *      none
3000  *
3001  ******************************************************************************/
wl_process_mailbox(struct wl_private * lp)3002 void wl_process_mailbox( struct wl_private *lp )
3003 {
3004 	ltv_t   *ltv;
3005 	hcf_16  ltv_val = 0xFFFF;
3006 	/*------------------------------------------------------------------------*/
3007 	DBG_FUNC( "wl_process_mailbox" );
3008 	DBG_ENTER( DbgInfo );
3009 	ltv = &( lp->ltvRecord );
3010 
3011 	switch( ltv->typ ) {
3012 
3013 	  case CFG_TALLIES:
3014 		DBG_TRACE( DbgInfo, "CFG_TALLIES\n" );
3015 		break;
3016 	  case CFG_SCAN:
3017 		DBG_TRACE( DbgInfo, "CFG_SCAN\n" );
3018 
3019 		{
3020 			int num_aps;
3021 			SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)&ltv->u.u8[0];
3022 
3023 			num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
3024 								 ( sizeof( SCAN_RS_STRCT )));
3025 
3026 			lp->scan_results.num_aps = num_aps;
3027 
3028 			DBG_TRACE( DbgInfo, "Number of APs: %d\n", num_aps );
3029 
3030 			while( num_aps >= 1 ) {
3031 				num_aps--;
3032 
3033 				DBG_TRACE( DbgInfo, "AP              : %d\n", num_aps );
3034 				DBG_TRACE( DbgInfo, "=========================\n" );
3035 				DBG_TRACE( DbgInfo, "Channel ID      : 0x%04x\n",
3036 						   aps[num_aps].channel_id );
3037 				DBG_TRACE( DbgInfo, "Noise Level     : 0x%04x\n",
3038 						   aps[num_aps].noise_level );
3039 				DBG_TRACE( DbgInfo, "Signal Level    : 0x%04x\n",
3040 						   aps[num_aps].signal_level );
3041 				DBG_TRACE( DbgInfo, "Beacon Interval : 0x%04x\n",
3042 						   aps[num_aps].beacon_interval_time );
3043 				DBG_TRACE( DbgInfo, "Capability      : 0x%04x\n",
3044 						   aps[num_aps].capability );
3045 				DBG_TRACE( DbgInfo, "SSID Length     : 0x%04x\n",
3046 						   aps[num_aps].ssid_len );
3047 				DBG_TRACE(DbgInfo, "BSSID           : %pM\n",
3048 						   aps[num_aps].bssid);
3049 
3050 				if ( aps[num_aps].ssid_len != 0 ) {
3051 					DBG_TRACE( DbgInfo, "SSID            : %s.\n",
3052 							   aps[num_aps].ssid_val );
3053 				} else {
3054 					DBG_TRACE( DbgInfo, "SSID            : %s.\n", "ANY" );
3055 				}
3056 
3057 				DBG_TRACE( DbgInfo, "\n" );
3058 
3059 				/* Copy the info to the ScanResult structure in the private
3060 				   adapter struct */
3061 				memcpy( &( lp->scan_results.APTable[num_aps]), &( aps[num_aps] ),
3062 						sizeof( SCAN_RS_STRCT ));
3063 			}
3064 
3065 			/* Set scan result to true so that any scan requests will
3066 			   complete */
3067 			lp->scan_results.scan_complete = TRUE;
3068 		}
3069 
3070 		break;
3071 	  case CFG_ACS_SCAN:
3072 		DBG_TRACE( DbgInfo, "CFG_ACS_SCAN\n" );
3073 
3074 		{
3075 			PROBE_RESP  *probe_rsp = (PROBE_RESP *)ltv;
3076 			hcf_8       *wpa_ie = NULL;
3077 			hcf_16      wpa_ie_len = 0;
3078 
3079 			DBG_TRACE( DbgInfo, "(%s) =========================\n",
3080 					   lp->dev->name );
3081 
3082 			DBG_TRACE( DbgInfo, "(%s) length      : 0x%04x.\n",
3083 					   lp->dev->name, probe_rsp->length );
3084 
3085 			if ( probe_rsp->length > 1 ) {
3086 				DBG_TRACE( DbgInfo, "(%s) infoType    : 0x%04x.\n",
3087 						   lp->dev->name, probe_rsp->infoType );
3088 
3089 				DBG_TRACE( DbgInfo, "(%s) signal      : 0x%02x.\n",
3090 						   lp->dev->name, probe_rsp->signal );
3091 
3092 				DBG_TRACE( DbgInfo, "(%s) silence     : 0x%02x.\n",
3093 						   lp->dev->name, probe_rsp->silence );
3094 
3095 				DBG_TRACE( DbgInfo, "(%s) rxFlow      : 0x%02x.\n",
3096 						   lp->dev->name, probe_rsp->rxFlow );
3097 
3098 				DBG_TRACE( DbgInfo, "(%s) rate        : 0x%02x.\n",
3099 						   lp->dev->name, probe_rsp->rate );
3100 
3101 				DBG_TRACE( DbgInfo, "(%s) frame cntl  : 0x%04x.\n",
3102 						   lp->dev->name, probe_rsp->frameControl );
3103 
3104 				DBG_TRACE( DbgInfo, "(%s) durID       : 0x%04x.\n",
3105 						   lp->dev->name, probe_rsp->durID );
3106 
3107 				DBG_TRACE(DbgInfo, "(%s) address1    : %pM\n",
3108 					lp->dev->name, probe_rsp->address1);
3109 
3110 				DBG_TRACE(DbgInfo, "(%s) address2    : %pM\n",
3111 					lp->dev->name, probe_rsp->address2);
3112 
3113 				DBG_TRACE(DbgInfo, "(%s) BSSID       : %pM\n",
3114 					lp->dev->name, probe_rsp->BSSID);
3115 
3116 				DBG_TRACE( DbgInfo, "(%s) sequence    : 0x%04x.\n",
3117 						   lp->dev->name, probe_rsp->sequence );
3118 
3119 				DBG_TRACE(DbgInfo, "(%s) address4    : %pM\n",
3120 					lp->dev->name, probe_rsp->address4);
3121 
3122 				DBG_TRACE( DbgInfo, "(%s) datalength  : 0x%04x.\n",
3123 						   lp->dev->name, probe_rsp->dataLength );
3124 
3125 				DBG_TRACE(DbgInfo, "(%s) DA          : %pM\n",
3126 					lp->dev->name, probe_rsp->DA);
3127 
3128 				DBG_TRACE(DbgInfo, "(%s) SA          : %pM\n",
3129 					lp->dev->name, probe_rsp->SA);
3130 
3131 				//DBG_TRACE( DbgInfo, "(%s) lenType     : 0x%04x.\n",
3132 				//           lp->dev->name, probe_rsp->lenType );
3133 
3134 				DBG_TRACE(DbgInfo, "(%s) timeStamp   : "
3135 						"%d.%d.%d.%d.%d.%d.%d.%d\n",
3136 						lp->dev->name,
3137 						probe_rsp->timeStamp[0],
3138 						probe_rsp->timeStamp[1],
3139 						probe_rsp->timeStamp[2],
3140 						probe_rsp->timeStamp[3],
3141 						probe_rsp->timeStamp[4],
3142 						probe_rsp->timeStamp[5],
3143 						probe_rsp->timeStamp[6],
3144 						probe_rsp->timeStamp[7]);
3145 
3146 				DBG_TRACE( DbgInfo, "(%s) beaconInt   : 0x%04x.\n",
3147 						   lp->dev->name, probe_rsp->beaconInterval );
3148 
3149 				DBG_TRACE( DbgInfo, "(%s) capability  : 0x%04x.\n",
3150 						   lp->dev->name, probe_rsp->capability );
3151 
3152 				DBG_TRACE( DbgInfo, "(%s) SSID len    : 0x%04x.\n",
3153 						   lp->dev->name, probe_rsp->rawData[1] );
3154 
3155 				if ( probe_rsp->rawData[1] > 0 ) {
3156 					char ssid[HCF_MAX_NAME_LEN];
3157 
3158 					memset( ssid, 0, sizeof( ssid ));
3159 					strncpy( ssid, &probe_rsp->rawData[2],
3160 							 probe_rsp->rawData[1] );
3161 
3162 					DBG_TRACE( DbgInfo, "(%s) SSID        : %s\n",
3163 							   lp->dev->name, ssid );
3164 				}
3165 
3166 				/* Parse out the WPA-IE, if one exists */
3167 				wpa_ie = wl_parse_wpa_ie( probe_rsp, &wpa_ie_len );
3168 				if ( wpa_ie != NULL ) {
3169 					DBG_TRACE( DbgInfo, "(%s) WPA-IE      : %s\n",
3170 					lp->dev->name, wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
3171 				}
3172 
3173 				DBG_TRACE( DbgInfo, "(%s) flags       : 0x%04x.\n",
3174 						   lp->dev->name, probe_rsp->flags );
3175 			}
3176 
3177 			DBG_TRACE( DbgInfo, "\n\n" );
3178 			/* If probe response length is 1, then the scan is complete */
3179 			if ( probe_rsp->length == 1 ) {
3180 				DBG_TRACE( DbgInfo, "SCAN COMPLETE\n" );
3181 				lp->probe_results.num_aps = lp->probe_num_aps;
3182 				lp->probe_results.scan_complete = TRUE;
3183 
3184 				/* Reset the counter for the next scan request */
3185 				lp->probe_num_aps = 0;
3186 
3187 				/* Send a wireless extensions event that the scan completed */
3188 				wl_wext_event_scan_complete( lp->dev );
3189 			} else {
3190 				/* Only copy to the table if the entry is unique; APs sometimes
3191 				   respond more than once to a probe */
3192 				if ( lp->probe_num_aps == 0 ) {
3193 					/* Copy the info to the ScanResult structure in the private
3194 					adapter struct */
3195 					memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3196 							probe_rsp, sizeof( PROBE_RESP ));
3197 
3198 					/* Increment the number of APs detected */
3199 					lp->probe_num_aps++;
3200 				} else {
3201 					int count;
3202 					int unique = 1;
3203 
3204 					for( count = 0; count < lp->probe_num_aps; count++ ) {
3205 						if ( memcmp( &( probe_rsp->BSSID ),
3206 							lp->probe_results.ProbeTable[count].BSSID,
3207 							ETH_ALEN ) == 0 ) {
3208 							unique = 0;
3209 						}
3210 					}
3211 
3212 					if ( unique ) {
3213 						/* Copy the info to the ScanResult structure in the
3214 						private adapter struct. Only copy if there's room in the
3215 						table */
3216 						if ( lp->probe_num_aps < MAX_NAPS )
3217 						{
3218 							memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3219 									probe_rsp, sizeof( PROBE_RESP ));
3220 						}
3221 						else
3222 						{
3223 							DBG_WARNING( DbgInfo, "Num of scan results exceeds storage, truncating\n" );
3224 						}
3225 
3226 						/* Increment the number of APs detected. Note I do this
3227 						   here even when I don't copy the probe response to the
3228 						   buffer in order to detect the overflow condition */
3229 						lp->probe_num_aps++;
3230 					}
3231 				}
3232 			}
3233 		}
3234 
3235 		break;
3236 
3237 	  case CFG_LINK_STAT:
3238 #define ls ((LINK_STATUS_STRCT *)ltv)
3239 		DBG_TRACE( DbgInfo, "CFG_LINK_STAT\n" );
3240 
3241 		switch( ls->linkStatus ) {
3242 		  case 1:
3243 			DBG_TRACE( DbgInfo, "Link Status : Connected\n" );
3244 			wl_wext_event_ap( lp->dev );
3245 			break;
3246 
3247 		  case 2:
3248 			DBG_TRACE( DbgInfo, "Link Status : Disconnected\n"  );
3249 			break;
3250 
3251 		  case 3:
3252 			DBG_TRACE( DbgInfo, "Link Status : Access Point Change\n" );
3253 			break;
3254 
3255 		  case 4:
3256 			DBG_TRACE( DbgInfo, "Link Status : Access Point Out of Range\n" );
3257 			break;
3258 
3259 		  case 5:
3260 			DBG_TRACE( DbgInfo, "Link Status : Access Point In Range\n" );
3261 			break;
3262 
3263 		default:
3264 			DBG_TRACE( DbgInfo, "Link Status : UNKNOWN (0x%04x)\n",
3265 					   ls->linkStatus );
3266 			break;
3267 		}
3268 
3269 		break;
3270 #undef ls
3271 
3272 	  case CFG_ASSOC_STAT:
3273 		DBG_TRACE( DbgInfo, "CFG_ASSOC_STAT\n" );
3274 
3275 		{
3276 			ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
3277 
3278 			switch( as->assocStatus ) {
3279 			  case 1:
3280 				DBG_TRACE( DbgInfo, "Association Status : STA Associated\n" );
3281 				break;
3282 
3283 			  case 2:
3284 				DBG_TRACE( DbgInfo, "Association Status : STA Reassociated\n" );
3285 				break;
3286 
3287 			  case 3:
3288 				DBG_TRACE( DbgInfo, "Association Status : STA Disassociated\n" );
3289 				break;
3290 
3291 			default:
3292 				DBG_TRACE( DbgInfo, "Association Status : UNKNOWN (0x%04x)\n",
3293 						   as->assocStatus );
3294 				break;
3295 			}
3296 
3297 			DBG_TRACE(DbgInfo, "STA Address        : %pM\n",
3298 					   as->staAddr);
3299 
3300 			if (( as->assocStatus == 2 )  && ( as->len == 8 )) {
3301 				DBG_TRACE(DbgInfo, "Old AP Address     : %pM\n",
3302 						   as->oldApAddr);
3303 			}
3304 		}
3305 
3306 		break;
3307 
3308 	  case CFG_SECURITY_STAT:
3309 		DBG_TRACE( DbgInfo, "CFG_SECURITY_STAT\n" );
3310 
3311 		{
3312 			SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
3313 
3314 			switch( ss->securityStatus ) {
3315 			  case 1:
3316 				DBG_TRACE( DbgInfo, "Security Status : Dissassociate [AP]\n" );
3317 				break;
3318 
3319 			  case 2:
3320 				DBG_TRACE( DbgInfo, "Security Status : Deauthenticate [AP]\n" );
3321 				break;
3322 
3323 			  case 3:
3324 				DBG_TRACE( DbgInfo, "Security Status : Authenticate Fail [STA] or [AP]\n" );
3325 				break;
3326 
3327 			  case 4:
3328 				DBG_TRACE( DbgInfo, "Security Status : MIC Fail\n" );
3329 				break;
3330 
3331 			  case 5:
3332 				DBG_TRACE( DbgInfo, "Security Status : Associate Fail\n" );
3333 				break;
3334 
3335 			default:
3336 				DBG_TRACE( DbgInfo, "Security Status : UNKNOWN %d\n",
3337 						   ss->securityStatus );
3338 				break;
3339 			}
3340 
3341 			DBG_TRACE(DbgInfo, "STA Address     : %pM\n",
3342 					ss->staAddr);
3343 
3344 			DBG_TRACE(DbgInfo, "Reason          : 0x%04x\n",
3345 					ss->reason);
3346 		}
3347 
3348 		break;
3349 
3350 	  case CFG_WMP:
3351 		DBG_TRACE( DbgInfo, "CFG_WMP, size is %d bytes\n", ltv->len );
3352 		{
3353 			WMP_RSP_STRCT *wmp_rsp = (WMP_RSP_STRCT *)ltv;
3354 
3355 			DBG_TRACE( DbgInfo, "CFG_WMP, pdu type is 0x%x\n",
3356 					   wmp_rsp->wmpRsp.wmpHdr.type );
3357 
3358 			switch( wmp_rsp->wmpRsp.wmpHdr.type ) {
3359 			  case WVLAN_WMP_PDU_TYPE_LT_RSP:
3360 				{
3361 #if DBG
3362 					LINKTEST_RSP_STRCT  *lt_rsp = (LINKTEST_RSP_STRCT *)ltv;
3363 #endif // DBG
3364 					DBG_TRACE( DbgInfo, "LINK TEST RESULT\n" );
3365 					DBG_TRACE( DbgInfo, "================\n" );
3366 					DBG_TRACE( DbgInfo, "Length        : %d.\n",     lt_rsp->len );
3367 
3368 					DBG_TRACE( DbgInfo, "Name          : %s.\n",     lt_rsp->ltRsp.ltRsp.name );
3369 					DBG_TRACE( DbgInfo, "Signal Level  : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.signal );
3370 					DBG_TRACE( DbgInfo, "Noise  Level  : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.noise );
3371 					DBG_TRACE( DbgInfo, "Receive Flow  : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.rxFlow );
3372 					DBG_TRACE( DbgInfo, "Data Rate     : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRate );
3373 					DBG_TRACE( DbgInfo, "Protocol      : 0x%04x.\n", lt_rsp->ltRsp.ltRsp.protocol );
3374 					DBG_TRACE( DbgInfo, "Station       : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.station );
3375 					DBG_TRACE( DbgInfo, "Data Rate Cap : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRateCap );
3376 
3377 					DBG_TRACE( DbgInfo, "Power Mgmt    : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3378 								lt_rsp->ltRsp.ltRsp.powerMgmt[0],
3379 								lt_rsp->ltRsp.ltRsp.powerMgmt[1],
3380 								lt_rsp->ltRsp.ltRsp.powerMgmt[2],
3381 								lt_rsp->ltRsp.ltRsp.powerMgmt[3] );
3382 
3383 					DBG_TRACE( DbgInfo, "Robustness    : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3384 								lt_rsp->ltRsp.ltRsp.robustness[0],
3385 								lt_rsp->ltRsp.ltRsp.robustness[1],
3386 								lt_rsp->ltRsp.ltRsp.robustness[2],
3387 								lt_rsp->ltRsp.ltRsp.robustness[3] );
3388 
3389 					DBG_TRACE( DbgInfo, "Scaling       : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.scaling );
3390 				}
3391 
3392 				break;
3393 
3394 			default:
3395 				break;
3396 			}
3397 		}
3398 
3399 		break;
3400 
3401 	  case CFG_NULL:
3402 		DBG_TRACE( DbgInfo, "CFG_NULL\n" );
3403 		break;
3404 
3405 	  case CFG_UPDATED_INFO_RECORD:        // Updated Information Record
3406 		DBG_TRACE( DbgInfo, "UPDATED INFORMATION RECORD\n" );
3407 
3408 		ltv_val = CNV_INT_TO_LITTLE( ltv->u.u16[0] );
3409 
3410 		/* Check and see which RID was updated */
3411 		switch( ltv_val ) {
3412 		  case CFG_CUR_COUNTRY_INFO:  // Indicate Passive Scan Completion
3413 			DBG_TRACE( DbgInfo, "Updated country info\n" );
3414 
3415 			/* Do I need to hold off on updating RIDs until the process is
3416 			   complete? */
3417 			wl_connect( lp );
3418 			break;
3419 
3420 		  case CFG_PORT_STAT:    // Wait for Connect Event
3421 			//wl_connect( lp );
3422 
3423 			break;
3424 
3425 		default:
3426 			DBG_WARNING( DbgInfo, "Unknown RID: 0x%04x\n", ltv_val );
3427 		}
3428 
3429 		break;
3430 
3431 	default:
3432 		DBG_TRACE( DbgInfo, "UNKNOWN MESSAGE: 0x%04x\n", ltv->typ );
3433 		break;
3434 	}
3435 	DBG_LEAVE( DbgInfo );
3436 	return;
3437 } // wl_process_mailbox
3438 /*============================================================================*/
3439 #endif  /* ifndef USE_MBOX_SYNC */
3440 
3441 #ifdef USE_WDS
3442 /*******************************************************************************
3443  *	wl_wds_netdev_register()
3444  *******************************************************************************
3445  *
3446  *  DESCRIPTION:
3447  *
3448  *      This function registers net_device structures with the system's network
3449  *      layer for use with the WDS ports.
3450  *
3451  *
3452  *  PARAMETERS:
3453  *
3454  *      lp      - pointer to the device's private adapter structure
3455  *
3456  *  RETURNS:
3457  *
3458  *      N/A
3459  *
3460  ******************************************************************************/
wl_wds_netdev_register(struct wl_private * lp)3461 void wl_wds_netdev_register( struct wl_private *lp )
3462 {
3463 	int count;
3464 	/*------------------------------------------------------------------------*/
3465 	DBG_FUNC( "wl_wds_netdev_register" );
3466 	DBG_ENTER( DbgInfo );
3467 	//;?why is there no USE_WDS clause like in wl_enable_wds_ports
3468 	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
3469 		for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3470 			if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3471 				if ( register_netdev( lp->wds_port[count].dev ) != 0 ) {
3472 					DBG_WARNING( DbgInfo, "net device for WDS port %d could not be registered\n",
3473 								( count + 1 ));
3474 				}
3475 				lp->wds_port[count].is_registered = TRUE;
3476 
3477 				/* Fill out the net_device structs with the MAC addr */
3478 				memcpy( lp->wds_port[count].dev->dev_addr, lp->MACAddress, ETH_ALEN );
3479 				lp->wds_port[count].dev->addr_len = ETH_ALEN;
3480 			}
3481 		}
3482 	}
3483 	DBG_LEAVE( DbgInfo );
3484 	return;
3485 } // wl_wds_netdev_register
3486 /*============================================================================*/
3487 
3488 
3489 /*******************************************************************************
3490  *	wl_wds_netdev_deregister()
3491  *******************************************************************************
3492  *
3493  *  DESCRIPTION:
3494  *
3495  *      This function deregisters the WDS net_device structures used by the
3496  *      system's network layer.
3497  *
3498  *
3499  *  PARAMETERS:
3500  *
3501  *      lp      - pointer to the device's private adapter structure
3502  *
3503  *  RETURNS:
3504  *
3505  *      N/A
3506  *
3507  ******************************************************************************/
wl_wds_netdev_deregister(struct wl_private * lp)3508 void wl_wds_netdev_deregister( struct wl_private *lp )
3509 {
3510 	int count;
3511 	/*------------------------------------------------------------------------*/
3512 	DBG_FUNC( "wl_wds_netdev_deregister" );
3513 	DBG_ENTER( DbgInfo );
3514 	if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP  ) {
3515 		for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3516 			if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3517 				unregister_netdev( lp->wds_port[count].dev );
3518 			}
3519 			lp->wds_port[count].is_registered = FALSE;
3520 		}
3521 	}
3522 	DBG_LEAVE( DbgInfo );
3523 	return;
3524 } // wl_wds_netdev_deregister
3525 /*============================================================================*/
3526 #endif  /* USE_WDS */
3527 
3528 
3529 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
3530 /*
3531  * The proc filesystem: function to read and entry
3532  */
3533 int printf_hcf_16( char *s, char *buf, hcf_16* p, int n );
3534 int printf_hcf_16( char *s, char *buf, hcf_16* p, int n ) {
3535 
3536 int i, len;
3537 
3538 	len = sprintf(buf, "%s", s );
3539 	while ( len < 20 ) len += sprintf(buf+len, " " );
3540 	len += sprintf(buf+len,": " );
3541 	for ( i = 0; i < n; i++ ) {
3542 		if ( len % 80 > 75 ) {
3543 			len += sprintf(buf+len,"\n" );
3544 		}
3545 		len += sprintf(buf+len,"%04X ", p[i] );
3546 	}
3547 	len += sprintf(buf+len,"\n" );
3548 	return len;
3549 } // printf_hcf_16
3550 
3551 int printf_hcf_8( char *s, char *buf, hcf_8* p, int n );
3552 int printf_hcf_8( char *s, char *buf, hcf_8* p, int n ) {
3553 
3554 int i, len;
3555 
3556 	len = sprintf(buf, "%s", s );
3557 	while ( len < 20 ) len += sprintf(buf+len, " " );
3558 	len += sprintf(buf+len,": " );
3559 	for ( i = 0; i <= n; i++ ) {
3560 		if ( len % 80 > 77 ) {
3561 			len += sprintf(buf+len,"\n" );
3562 		}
3563 		len += sprintf(buf+len,"%02X ", p[i] );
3564 	}
3565 	len += sprintf(buf+len,"\n" );
3566 	return len;
3567 } // printf_hcf8
3568 
3569 int printf_strct( char *s, char *buf, hcf_16* p );
3570 int printf_strct( char *s, char *buf, hcf_16* p ) {
3571 
3572 int i, len;
3573 
3574 	len = sprintf(buf, "%s", s );
3575 	while ( len < 20 ) len += sprintf(buf+len, " " );
3576 	len += sprintf(buf+len,": " );
3577 	for ( i = 0; i <= *p; i++ ) {
3578 		if ( len % 80 > 75 ) {
3579 			len += sprintf(buf+len,"\n" );
3580 		}
3581 		len += sprintf(buf+len,"%04X ", p[i] );
3582 	}
3583 	len += sprintf(buf+len,"\n" );
3584 	return len;
3585 } // printf_strct
3586 
3587 int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data )
3588 {
3589 	struct wl_private	*lp = NULL;
3590 	IFBP				ifbp;
3591    	CFG_HERMES_TALLIES_STRCT *p;
3592 
3593     #define LIMIT (PAGE_SIZE-80) /* don't print any more after this size */
3594 
3595     len=0;
3596 
3597 	lp = ((struct net_device *)data)->priv;
3598 	if (lp == NULL) {
3599         len += sprintf(buf+len,"No wl_private in scull_read_procmem\n" );
3600 	} else if ( lp->wlags49_type == 0 ){
3601    	    ifbp = &lp->hcfCtx;
3602    	    len += sprintf(buf+len,"Magic:               0x%04X\n", ifbp->IFB_Magic );
3603    	    len += sprintf(buf+len,"IOBase:              0x%04X\n", ifbp->IFB_IOBase );
3604    	    len += sprintf(buf+len,"LinkStat:            0x%04X\n", ifbp->IFB_LinkStat );
3605    	    len += sprintf(buf+len,"DSLinkStat:          0x%04X\n", ifbp->IFB_DSLinkStat );
3606    	    len += sprintf(buf+len,"TickIni:         0x%08lX\n", ifbp->IFB_TickIni );
3607    	    len += sprintf(buf+len,"TickCnt:             0x%04X\n", ifbp->IFB_TickCnt );
3608    	    len += sprintf(buf+len,"IntOffCnt:           0x%04X\n", ifbp->IFB_IntOffCnt );
3609 		len += printf_hcf_16( "IFB_FWIdentity", &buf[len],
3610 							  &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
3611 	} else if ( lp->wlags49_type == 1 ) {
3612    	    len += sprintf(buf+len,"Channel:              0x%04X\n", lp->Channel );
3613 /****** len += sprintf(buf+len,"slock:                  %d\n", lp->slock );		*/
3614 //x		struct tq_struct            "task:               0x%04X\n", lp->task );
3615 //x		struct net_device_stats     "stats:              0x%04X\n", lp->stats );
3616 #ifdef WIRELESS_EXT
3617 //x		struct iw_statistics        "wstats:             0x%04X\n", lp->wstats );
3618 //x   	    len += sprintf(buf+len,"spy_number:           0x%04X\n", lp->spy_number );
3619 //x		u_char                      spy_address[IW_MAX_SPY][ETH_ALEN];
3620 //x		struct iw_quality           spy_stat[IW_MAX_SPY];
3621 #endif // WIRELESS_EXT
3622    	    len += sprintf(buf+len,"IFB:                  0x%p\n", &lp->hcfCtx );
3623    	    len += sprintf(buf+len,"flags:                %#.8lX\n", lp->flags );  //;?use this format from now on
3624    	    len += sprintf(buf+len,"DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
3625 #if DBG
3626    	    len += sprintf(buf+len,"DebugFlag (DbgInfo):   0x%08lX\n", DbgInfo->DebugFlag );
3627 #endif // DBG
3628    	    len += sprintf(buf+len,"is_registered:        0x%04X\n", lp->is_registered );
3629 //x		CFG_DRV_INFO_STRCT          "driverInfo:         0x%04X\n", lp->driverInfo );
3630 		len += printf_strct( "driverInfo", &buf[len], (hcf_16*)&lp->driverInfo );
3631 //x		CFG_IDENTITY_STRCT          "driverIdentity:     0x%04X\n", lp->driverIdentity );
3632 		len += printf_strct( "driverIdentity", &buf[len], (hcf_16*)&lp->driverIdentity );
3633 //x		CFG_FW_IDENTITY_STRCT       "StationIdentity:    0x%04X\n", lp->StationIdentity );
3634 		len += printf_strct( "StationIdentity", &buf[len], (hcf_16*)&lp->StationIdentity );
3635 //x		CFG_PRI_IDENTITY_STRCT      "PrimaryIdentity:    0x%04X\n", lp->PrimaryIdentity );
3636 		len += printf_strct( "PrimaryIdentity", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
3637 		len += printf_strct( "PrimarySupplier", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRISup );
3638 //x		CFG_PRI_IDENTITY_STRCT      "NICIdentity:        0x%04X\n", lp->NICIdentity );
3639 		len += printf_strct( "NICIdentity", &buf[len], (hcf_16*)&lp->NICIdentity );
3640 //x		ltv_t                       "ltvRecord:          0x%04X\n", lp->ltvRecord );
3641    	    len += sprintf(buf+len,"txBytes:              0x%08lX\n", lp->txBytes );
3642    	    len += sprintf(buf+len,"maxPort:              0x%04X\n", lp->maxPort );        /* 0 for STA, 6 for AP */
3643 	/* Elements used for async notification from hardware */
3644 //x		RID_LOG_STRCT				RidList[10];
3645 //x		ltv_t                       "updatedRecord:      0x%04X\n", lp->updatedRecord );
3646 //x		PROBE_RESP				    "ProbeResp:                    0x%04X\n", lp->ProbeResp );
3647 //x		ASSOC_STATUS_STRCT          "assoc_stat:         0x%04X\n", lp->assoc_stat );
3648 //x		SECURITY_STATUS_STRCT       "sec_stat:           0x%04X\n", lp->sec_stat );
3649 //x		u_char                      lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
3650    	    len += sprintf(buf+len,"PortType:             0x%04X\n", lp->PortType );           // 1 - 3 (1 [Normal] | 3 [AdHoc])
3651    	    len += sprintf(buf+len,"Channel:              0x%04X\n", lp->Channel );            // 0 - 14 (0)
3652 //x		hcf_16                      TxRateControl[2];
3653    	    len += sprintf(buf+len,"TxRateControl[2]:     0x%04X 0x%04X\n",
3654 						lp->TxRateControl[0], lp->TxRateControl[1] );
3655    	    len += sprintf(buf+len,"DistanceBetweenAPs:   0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
3656    	    len += sprintf(buf+len,"RTSThreshold:         0x%04X\n", lp->RTSThreshold );       // 0 - 2347 (2347)
3657    	    len += sprintf(buf+len,"PMEnabled:            0x%04X\n", lp->PMEnabled );          // 0 - 2, 8001 - 8002 (0)
3658    	    len += sprintf(buf+len,"MicrowaveRobustness:  0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
3659    	    len += sprintf(buf+len,"CreateIBSS:           0x%04X\n", lp->CreateIBSS );         // 0 - 1 (0)
3660    	    len += sprintf(buf+len,"MulticastReceive:     0x%04X\n", lp->MulticastReceive );   // 0 - 1 (1)
3661    	    len += sprintf(buf+len,"MaxSleepDuration:     0x%04X\n", lp->MaxSleepDuration );   // 0 - 65535 (100)
3662 //x		hcf_8                       MACAddress[ETH_ALEN];
3663 		len += printf_hcf_8( "MACAddress", &buf[len], lp->MACAddress, ETH_ALEN );
3664 //x		char                        NetworkName[HCF_MAX_NAME_LEN+1];
3665    	    len += sprintf(buf+len,"NetworkName:          %.32s\n", lp->NetworkName );
3666 //x		char                        StationName[HCF_MAX_NAME_LEN+1];
3667    	    len += sprintf(buf+len,"EnableEncryption:     0x%04X\n", lp->EnableEncryption );   // 0 - 1 (0)
3668 //x		char                        Key1[MAX_KEY_LEN+1];
3669 		len += printf_hcf_8( "Key1", &buf[len], lp->Key1, MAX_KEY_LEN );
3670 //x		char                        Key2[MAX_KEY_LEN+1];
3671 //x		char                        Key3[MAX_KEY_LEN+1];
3672 //x		char                        Key4[MAX_KEY_LEN+1];
3673    	    len += sprintf(buf+len,"TransmitKeyID:        0x%04X\n", lp->TransmitKeyID );      // 1 - 4 (1)
3674 //x		CFG_DEFAULT_KEYS_STRCT	    "DefaultKeys:         0x%04X\n", lp->DefaultKeys );
3675 //x		u_char                      mailbox[MB_SIZE];
3676 //x		char                        szEncryption[MAX_ENC_LEN];
3677    	    len += sprintf(buf+len,"driverEnable:         0x%04X\n", lp->driverEnable );
3678    	    len += sprintf(buf+len,"wolasEnable:          0x%04X\n", lp->wolasEnable );
3679    	    len += sprintf(buf+len,"atimWindow:           0x%04X\n", lp->atimWindow );
3680    	    len += sprintf(buf+len,"holdoverDuration:     0x%04X\n", lp->holdoverDuration );
3681 //x		hcf_16                      MulticastRate[2];
3682    	    len += sprintf(buf+len,"authentication:       0x%04X\n", lp->authentication ); // is this AP specific?
3683    	    len += sprintf(buf+len,"promiscuousMode:      0x%04X\n", lp->promiscuousMode );
3684    	    len += sprintf(buf+len,"DownloadFirmware:     0x%04X\n", lp->DownloadFirmware );   // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
3685    	    len += sprintf(buf+len,"AuthKeyMgmtSuite:     0x%04X\n", lp->AuthKeyMgmtSuite );
3686    	    len += sprintf(buf+len,"loadBalancing:        0x%04X\n", lp->loadBalancing );
3687    	    len += sprintf(buf+len,"mediumDistribution:   0x%04X\n", lp->mediumDistribution );
3688    	    len += sprintf(buf+len,"txPowLevel:           0x%04X\n", lp->txPowLevel );
3689 //   	    len += sprintf(buf+len,"shortRetryLimit:    0x%04X\n", lp->shortRetryLimit );
3690 //   	    len += sprintf(buf+len,"longRetryLimit:     0x%04X\n", lp->longRetryLimit );
3691 //x		hcf_16                      srsc[2];
3692 //x		hcf_16                      brsc[2];
3693    	    len += sprintf(buf+len,"connectionControl:    0x%04X\n", lp->connectionControl );
3694 //x		//hcf_16                      probeDataRates[2];
3695    	    len += sprintf(buf+len,"ownBeaconInterval:    0x%04X\n", lp->ownBeaconInterval );
3696    	    len += sprintf(buf+len,"coexistence:          0x%04X\n", lp->coexistence );
3697 //x		WVLAN_FRAME                 "txF:                0x%04X\n", lp->txF );
3698 //x		WVLAN_LFRAME                txList[DEFAULT_NUM_TX_FRAMES];
3699 //x		struct list_head            "txFree:             0x%04X\n", lp->txFree );
3700 //x		struct list_head            txQ[WVLAN_MAX_TX_QUEUES];
3701    	    len += sprintf(buf+len,"netif_queue_on:       0x%04X\n", lp->netif_queue_on );
3702    	    len += sprintf(buf+len,"txQ_count:            0x%04X\n", lp->txQ_count );
3703 //x		DESC_STRCT                  "desc_rx:            0x%04X\n", lp->desc_rx );
3704 //x		DESC_STRCT                  "desc_tx:            0x%04X\n", lp->desc_tx );
3705 //x		WVLAN_PORT_STATE            "portState:          0x%04X\n", lp->portState );
3706 //x		ScanResult                  "scan_results:       0x%04X\n", lp->scan_results );
3707 //x		ProbeResult                 "probe_results:      0x%04X\n", lp->probe_results );
3708    	    len += sprintf(buf+len,"probe_num_aps:        0x%04X\n", lp->probe_num_aps );
3709    	    len += sprintf(buf+len,"use_dma:              0x%04X\n", lp->use_dma );
3710 //x		DMA_STRCT                   "dma:                0x%04X\n", lp->dma );
3711 #ifdef USE_RTS
3712    	    len += sprintf(buf+len,"useRTS:               0x%04X\n", lp->useRTS );
3713 #endif  // USE_RTS
3714 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
3715 		//;?should we restore this to allow smaller memory footprint
3716 		//;?I guess not. This should be brought under Debug mode only
3717    	    len += sprintf(buf+len,"DTIMPeriod:           0x%04X\n", lp->DTIMPeriod );         // 1 - 255 (1)
3718    	    len += sprintf(buf+len,"multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
3719    	    len += sprintf(buf+len,"RejectAny:            0x%04X\n", lp->RejectAny );          // 0 - 1 (0)
3720    	    len += sprintf(buf+len,"ExcludeUnencrypted:   0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
3721    	    len += sprintf(buf+len,"intraBSSRelay:        0x%04X\n", lp->intraBSSRelay );
3722    	    len += sprintf(buf+len,"wlags49_type:             0x%08lX\n", lp->wlags49_type );
3723 #ifdef USE_WDS
3724 //x		WVLAN_WDS_IF                wds_port[NUM_WDS_PORTS];
3725 #endif // USE_WDS
3726 #endif // HCF_AP
3727 	} else if ( lp->wlags49_type == 2 ){
3728         len += sprintf(buf+len,"tallies to be added\n" );
3729 //Hermes Tallies (IFB substructure) {
3730    	    p = &lp->hcfCtx.IFB_NIC_Tallies;
3731         len += sprintf(buf+len,"TxUnicastFrames:          %08lX\n", p->TxUnicastFrames );
3732         len += sprintf(buf+len,"TxMulticastFrames:        %08lX\n", p->TxMulticastFrames );
3733         len += sprintf(buf+len,"TxFragments:              %08lX\n", p->TxFragments );
3734         len += sprintf(buf+len,"TxUnicastOctets:          %08lX\n", p->TxUnicastOctets );
3735         len += sprintf(buf+len,"TxMulticastOctets:        %08lX\n", p->TxMulticastOctets );
3736         len += sprintf(buf+len,"TxDeferredTransmissions:  %08lX\n", p->TxDeferredTransmissions );
3737         len += sprintf(buf+len,"TxSingleRetryFrames:      %08lX\n", p->TxSingleRetryFrames );
3738         len += sprintf(buf+len,"TxMultipleRetryFrames:    %08lX\n", p->TxMultipleRetryFrames );
3739         len += sprintf(buf+len,"TxRetryLimitExceeded:     %08lX\n", p->TxRetryLimitExceeded );
3740         len += sprintf(buf+len,"TxDiscards:               %08lX\n", p->TxDiscards );
3741         len += sprintf(buf+len,"RxUnicastFrames:          %08lX\n", p->RxUnicastFrames );
3742         len += sprintf(buf+len,"RxMulticastFrames:        %08lX\n", p->RxMulticastFrames );
3743         len += sprintf(buf+len,"RxFragments:              %08lX\n", p->RxFragments );
3744         len += sprintf(buf+len,"RxUnicastOctets:          %08lX\n", p->RxUnicastOctets );
3745         len += sprintf(buf+len,"RxMulticastOctets:        %08lX\n", p->RxMulticastOctets );
3746         len += sprintf(buf+len,"RxFCSErrors:              %08lX\n", p->RxFCSErrors );
3747         len += sprintf(buf+len,"RxDiscardsNoBuffer:       %08lX\n", p->RxDiscardsNoBuffer );
3748         len += sprintf(buf+len,"TxDiscardsWrongSA:        %08lX\n", p->TxDiscardsWrongSA );
3749         len += sprintf(buf+len,"RxWEPUndecryptable:       %08lX\n", p->RxWEPUndecryptable );
3750         len += sprintf(buf+len,"RxMsgInMsgFragments:      %08lX\n", p->RxMsgInMsgFragments );
3751         len += sprintf(buf+len,"RxMsgInBadMsgFragments:   %08lX\n", p->RxMsgInBadMsgFragments );
3752         len += sprintf(buf+len,"RxDiscardsWEPICVError:    %08lX\n", p->RxDiscardsWEPICVError );
3753         len += sprintf(buf+len,"RxDiscardsWEPExcluded:    %08lX\n", p->RxDiscardsWEPExcluded );
3754 #if (HCF_EXT) & HCF_EXT_TALLIES_FW
3755         //to be added ;?
3756 #endif // HCF_EXT_TALLIES_FW
3757 	} else if ( lp->wlags49_type & 0x8000 ) {	//;?kludgy but it is unclear to me were else to place this
3758 #if DBG
3759 		DbgInfo->DebugFlag = lp->wlags49_type & 0x7FFF;
3760 #endif // DBG
3761 		lp->wlags49_type = 0;				//default to IFB again ;?
3762 	} else {
3763         len += sprintf(buf+len,"unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
3764         len += sprintf(buf+len,"0x0000 - IFB\n" );
3765         len += sprintf(buf+len,"0x0001 - wl_private\n" );
3766         len += sprintf(buf+len,"0x0002 - Tallies\n" );
3767         len += sprintf(buf+len,"0x8xxx - Change debufflag\n" );
3768         len += sprintf(buf+len,"ERROR    0001\nWARNING  0002\nNOTICE   0004\nTRACE    0008\n" );
3769         len += sprintf(buf+len,"VERBOSE  0010\nPARAM    0020\nBREAK    0040\nRX       0100\n" );
3770         len += sprintf(buf+len,"TX       0200\nDS       0400\n" );
3771 	}
3772     return len;
3773 } // scull_read_procmem
3774 
3775 static void proc_write(const char *name, write_proc_t *w, void *data)
3776 {
3777 	struct proc_dir_entry * entry = create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
3778 	if (entry) {
3779 		entry->write_proc = w;
3780 		entry->data = data;
3781 	}
3782 } // proc_write
3783 
3784 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
3785 {
3786 	static char		proc_number[11];
3787 	unsigned int	nr = 0;
3788 
3789 	DBG_FUNC( "write_int" );
3790 	DBG_ENTER( DbgInfo );
3791 
3792 	if (count > 9) {
3793 		count = -EINVAL;
3794 	} else if ( copy_from_user(proc_number, buffer, count) ) {
3795 		count = -EFAULT;
3796 	}
3797 	if  (count > 0 ) {
3798 		proc_number[count] = 0;
3799 		nr = simple_strtoul(proc_number , NULL, 0);
3800  		*(unsigned int *)data = nr;
3801 		if ( nr & 0x8000 ) {	//;?kludgy but it is unclear to me were else to place this
3802 #if DBG
3803 			DbgInfo->DebugFlag = nr & 0x7FFF;
3804 #endif // DBG
3805 		}
3806 	}
3807 	DBG_PRINT( "value: %08X\n", nr );
3808 	DBG_LEAVE( DbgInfo );
3809 	return count;
3810 } // write_int
3811 
3812 #endif /* SCULL_USE_PROC */
3813 
3814 #ifdef DN554
3815 #define RUN_AT(x)		(jiffies+(x))		//"borrowed" from include/pcmcia/k_compat.h
3816 #define DS_OOR	0x8000		//Deepsleep OutOfRange Status
3817 
3818 		lp->timer_oor_cnt = DS_OOR;
3819 		init_timer( &lp->timer_oor );
3820 		lp->timer_oor.function = timer_oor;
3821 		lp->timer_oor.data = (unsigned long)lp;
3822 		lp->timer_oor.expires = RUN_AT( 3 * HZ );
3823 		add_timer( &lp->timer_oor );
3824 		printk( "<5>wl_enable: %ld\n", jiffies );		//;?remove me 1 day
3825 #endif //DN554
3826 #ifdef DN554
3827 /*******************************************************************************
3828  *	timer_oor()
3829  *******************************************************************************
3830  *
3831  *  DESCRIPTION:
3832  *
3833  *
3834  *  PARAMETERS:
3835  *
3836  *      arg - a u_long representing a pointer to a dev_link_t structure for the
3837  *            device to be released.
3838  *
3839  *  RETURNS:
3840  *
3841  *      N/A
3842  *
3843  ******************************************************************************/
timer_oor(u_long arg)3844 void timer_oor( u_long arg )
3845 {
3846 	struct wl_private       *lp = (struct wl_private *)arg;
3847 
3848     /*------------------------------------------------------------------------*/
3849 
3850     DBG_FUNC( "timer_oor" );
3851     DBG_ENTER( DbgInfo );
3852     DBG_PARAM( DbgInfo, "arg", "0x%08lx", arg );
3853 
3854 	printk( "<5>timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt );		//;?remove me 1 day
3855 	lp->timer_oor_cnt += 10;
3856     if ( (lp->timer_oor_cnt & ~DS_OOR) > 300 ) {
3857 		lp->timer_oor_cnt = 300;
3858 	}
3859 	lp->timer_oor_cnt |= DS_OOR;
3860 	init_timer( &lp->timer_oor );
3861 	lp->timer_oor.function = timer_oor;
3862 	lp->timer_oor.data = (unsigned long)lp;
3863 	lp->timer_oor.expires = RUN_AT( (lp->timer_oor_cnt & ~DS_OOR) * HZ );
3864 	add_timer( &lp->timer_oor );
3865 
3866     DBG_LEAVE( DbgInfo );
3867 } // timer_oor
3868 #endif //DN554
3869 
3870 MODULE_LICENSE("Dual BSD/GPL");
3871