1 /*******************************************************************************
3 * Wireless device driver for Linux (wlags49).
5 * Copyright (c) 1998-2003 Agere Systems Inc.
9 * Initially developed by TriplePoint, Inc.
10 * http://www.triplepoint.com
12 *------------------------------------------------------------------------------
14 * This file contains the main driver entry points and other adapter
17 *------------------------------------------------------------------------------
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.
26 * Copyright © 2003 Agere Systems Inc.
27 * All rights reserved.
29 * Redistribution and use in source or binary forms, with or without
30 * modifications, are permitted provided that the following conditions are met:
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
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.
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.
47 * THIS SOFTWARE IS PROVIDED
\93AS IS
\94 AND ANY EXPRESS OR IMPLIED WARRANTIES,
48 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
49 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
50 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
51 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
52 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
60 ******************************************************************************/
62 /*******************************************************************************
63 * constant definitions
64 ******************************************************************************/
66 /* Allow support for calling system fcns to access F/W image file */
67 #define __KERNEL_SYSCALLS__
69 /*******************************************************************************
71 ******************************************************************************/
72 #include <wl_version.h>
74 #include <linux/module.h>
75 #include <linux/proc_fs.h>
76 #include <linux/seq_file.h>
77 #include <linux/types.h>
78 #include <linux/kernel.h>
79 // #include <linux/sched.h>
80 // #include <linux/ptrace.h>
81 // #include <linux/slab.h>
82 // #include <linux/ctype.h>
83 // #include <linux/string.h>
84 // #include <linux/timer.h>
85 //#include <linux/interrupt.h>
86 // #include <linux/tqueue.h>
87 // #include <linux/in.h>
88 // #include <linux/delay.h>
89 // #include <asm/io.h>
90 // // #include <asm/bitops.h>
91 #include <linux/unistd.h>
92 #include <asm/uaccess.h>
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>
102 #include <linux/vmalloc.h>
110 //in order to get around:: wl_main.c:2229: `HREG_EV_RDMAD' undeclared (first use in this function)
114 #include <wl_internal.h>
117 #include <wl_netdev.h>
121 #include <wl_profile.h>
122 #endif /* USE_PROFILE */
126 #endif /* BUS_PCMCIA */
131 /*******************************************************************************
133 ******************************************************************************/
134 #define VALID_PARAM(C) \
138 printk(KERN_INFO "Wireless, parameter error: \"%s\"\n", #C); \
142 /*******************************************************************************
144 ******************************************************************************/
145 void wl_isr_handler( unsigned long p );
147 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
148 static int scull_read_procmem(struct seq_file *m, void *v);
149 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data);
152 * seq_file wrappers for procfile show routines.
154 static int scull_read_procmem_open(struct inode *inode, struct file *file)
156 return single_open(file, scull_read_procmem, PDE_DATA(inode));
159 static const struct file_operations scull_read_procmem_fops = {
160 .open = scull_read_procmem_open,
163 .release = single_release,
166 #endif /* SCULL_USE_PROC */
168 /*******************************************************************************
169 * module parameter definitions - set with 'insmod'
170 ******************************************************************************/
171 static p_u16 irq_mask = 0xdeb8; // IRQ3,4,5,7,9,10,11,12,14,15
172 static p_s8 irq_list[4] = { -1 };
175 MODULE_PARM(irq_mask, "h");
176 MODULE_PARM_DESC(irq_mask, "IRQ mask [0xdeb8]");
177 MODULE_PARM(irq_list, "1-4b");
178 MODULE_PARM_DESC(irq_list, "IRQ list [<irq_mask>]");
181 static p_u8 PARM_AUTHENTICATION = PARM_DEFAULT_AUTHENTICATION;
182 static p_u16 PARM_AUTH_KEY_MGMT_SUITE = PARM_DEFAULT_AUTH_KEY_MGMT_SUITE;
183 static p_u16 PARM_BRSC_2GHZ = PARM_DEFAULT_BRSC_2GHZ;
184 static p_u16 PARM_BRSC_5GHZ = PARM_DEFAULT_BRSC_5GHZ;
185 static p_u16 PARM_COEXISTENCE = PARM_DEFAULT_COEXISTENCE;
186 static p_u16 PARM_CONNECTION_CONTROL = PARM_DEFAULT_CONNECTION_CONTROL; //;?rename and move
187 static p_char *PARM_CREATE_IBSS = PARM_DEFAULT_CREATE_IBSS_STR;
188 static p_char *PARM_DESIRED_SSID = PARM_DEFAULT_SSID;
189 static p_char *PARM_DOWNLOAD_FIRMWARE = "";
190 static p_u16 PARM_ENABLE_ENCRYPTION = PARM_DEFAULT_ENABLE_ENCRYPTION;
191 static p_char *PARM_EXCLUDE_UNENCRYPTED = PARM_DEFAULT_EXCLUDE_UNENCRYPTED_STR;
192 static p_char *PARM_INTRA_BSS_RELAY = PARM_DEFAULT_INTRA_BSS_RELAY_STR;
193 static p_char *PARM_KEY1 = "";
194 static p_char *PARM_KEY2 = "";
195 static p_char *PARM_KEY3 = "";
196 static p_char *PARM_KEY4 = "";
197 static p_char *PARM_LOAD_BALANCING = PARM_DEFAULT_LOAD_BALANCING_STR;
198 static p_u16 PARM_MAX_SLEEP = PARM_DEFAULT_MAX_PM_SLEEP;
199 static p_char *PARM_MEDIUM_DISTRIBUTION = PARM_DEFAULT_MEDIUM_DISTRIBUTION_STR;
200 static p_char *PARM_MICROWAVE_ROBUSTNESS = PARM_DEFAULT_MICROWAVE_ROBUSTNESS_STR;
201 static p_char *PARM_MULTICAST_PM_BUFFERING = PARM_DEFAULT_MULTICAST_PM_BUFFERING_STR;
202 static p_u16 PARM_MULTICAST_RATE = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
203 static p_char *PARM_MULTICAST_RX = PARM_DEFAULT_MULTICAST_RX_STR;
204 static p_u8 PARM_NETWORK_ADDR[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
205 static p_u16 PARM_OWN_ATIM_WINDOW = PARM_DEFAULT_OWN_ATIM_WINDOW;
206 static p_u16 PARM_OWN_BEACON_INTERVAL = PARM_DEFAULT_OWN_BEACON_INTERVAL;
207 static p_u8 PARM_OWN_CHANNEL = PARM_DEFAULT_OWN_CHANNEL;
208 static p_u8 PARM_OWN_DTIM_PERIOD = PARM_DEFAULT_OWN_DTIM_PERIOD;
209 static p_char *PARM_OWN_NAME = PARM_DEFAULT_OWN_NAME;
210 static p_char *PARM_OWN_SSID = PARM_DEFAULT_SSID;
211 static p_u16 PARM_PM_ENABLED = WVLAN_PM_STATE_DISABLED;
212 static p_u16 PARM_PM_HOLDOVER_DURATION = PARM_DEFAULT_PM_HOLDOVER_DURATION;
213 static p_u8 PARM_PORT_TYPE = PARM_DEFAULT_PORT_TYPE;
214 static p_char *PARM_PROMISCUOUS_MODE = PARM_DEFAULT_PROMISCUOUS_MODE_STR;
215 static p_char *PARM_REJECT_ANY = PARM_DEFAULT_REJECT_ANY_STR;
217 static p_u16 PARM_RTS_THRESHOLD1 = PARM_DEFAULT_RTS_THRESHOLD;
218 static p_u16 PARM_RTS_THRESHOLD2 = PARM_DEFAULT_RTS_THRESHOLD;
219 static p_u16 PARM_RTS_THRESHOLD3 = PARM_DEFAULT_RTS_THRESHOLD;
220 static p_u16 PARM_RTS_THRESHOLD4 = PARM_DEFAULT_RTS_THRESHOLD;
221 static p_u16 PARM_RTS_THRESHOLD5 = PARM_DEFAULT_RTS_THRESHOLD;
222 static p_u16 PARM_RTS_THRESHOLD6 = PARM_DEFAULT_RTS_THRESHOLD;
224 static p_u16 PARM_RTS_THRESHOLD = PARM_DEFAULT_RTS_THRESHOLD;
225 static p_u16 PARM_SRSC_2GHZ = PARM_DEFAULT_SRSC_2GHZ;
226 static p_u16 PARM_SRSC_5GHZ = PARM_DEFAULT_SRSC_5GHZ;
227 static p_u8 PARM_SYSTEM_SCALE = PARM_DEFAULT_SYSTEM_SCALE;
228 static p_u8 PARM_TX_KEY = PARM_DEFAULT_TX_KEY;
229 static p_u16 PARM_TX_POW_LEVEL = PARM_DEFAULT_TX_POW_LEVEL;
231 static p_u16 PARM_TX_RATE1 = PARM_DEFAULT_TX_RATE_2GHZ;
232 static p_u16 PARM_TX_RATE2 = PARM_DEFAULT_TX_RATE_2GHZ;
233 static p_u16 PARM_TX_RATE3 = PARM_DEFAULT_TX_RATE_2GHZ;
234 static p_u16 PARM_TX_RATE4 = PARM_DEFAULT_TX_RATE_2GHZ;
235 static p_u16 PARM_TX_RATE5 = PARM_DEFAULT_TX_RATE_2GHZ;
236 static p_u16 PARM_TX_RATE6 = PARM_DEFAULT_TX_RATE_2GHZ;
238 static p_u16 PARM_TX_RATE = PARM_DEFAULT_TX_RATE_2GHZ;
240 static p_u8 PARM_WDS_ADDRESS1[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
241 static p_u8 PARM_WDS_ADDRESS2[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
242 static p_u8 PARM_WDS_ADDRESS3[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
243 static p_u8 PARM_WDS_ADDRESS4[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
244 static p_u8 PARM_WDS_ADDRESS5[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
245 static p_u8 PARM_WDS_ADDRESS6[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
250 MODULE_PARM(PARM_DESIRED_SSID, "s");
251 MODULE_PARM_DESC(PARM_DESIRED_SSID, "Network Name (<string>) [ANY]");
252 MODULE_PARM(PARM_OWN_SSID, "s");
253 MODULE_PARM_DESC(PARM_OWN_SSID, "Network Name (<string>) [ANY]");
254 MODULE_PARM(PARM_OWN_CHANNEL, "b");
255 MODULE_PARM_DESC(PARM_OWN_CHANNEL, "Channel (0 - 14) [0]");
256 MODULE_PARM(PARM_SYSTEM_SCALE, "b");
257 MODULE_PARM_DESC(PARM_SYSTEM_SCALE, "Distance Between APs (1 - 3) [1]");
258 MODULE_PARM(PARM_TX_RATE, "b");
259 MODULE_PARM_DESC(PARM_TX_RATE, "Transmit Rate Control");
260 MODULE_PARM(PARM_RTS_THRESHOLD, "h");
261 MODULE_PARM_DESC(PARM_RTS_THRESHOLD, "Medium Reservation (RTS/CTS Fragment Length) (256 - 2347) [2347]");
262 MODULE_PARM(PARM_MICROWAVE_ROBUSTNESS, "s");
263 MODULE_PARM_DESC(PARM_MICROWAVE_ROBUSTNESS, "Microwave Oven Robustness Enabled (<string> N or Y) [N]");
264 MODULE_PARM(PARM_OWN_NAME, "s");
265 MODULE_PARM_DESC(PARM_OWN_NAME, "Station Name (<string>) [Linux]");
267 MODULE_PARM(PARM_ENABLE_ENCRYPTION, "b");
268 MODULE_PARM_DESC(PARM_ENABLE_ENCRYPTION, "Encryption Mode (0 - 7) [0]");
270 MODULE_PARM(PARM_KEY1, "s");
271 MODULE_PARM_DESC(PARM_KEY1, "Data Encryption Key 1 (<string>) []");
272 MODULE_PARM(PARM_KEY2, "s");
273 MODULE_PARM_DESC(PARM_KEY2, "Data Encryption Key 2 (<string>) []");
274 MODULE_PARM(PARM_KEY3, "s");
275 MODULE_PARM_DESC(PARM_KEY3, "Data Encryption Key 3 (<string>) []");
276 MODULE_PARM(PARM_KEY4, "s");
277 MODULE_PARM_DESC(PARM_KEY4, "Data Encryption Key 4 (<string>) []");
278 MODULE_PARM(PARM_TX_KEY, "b");
279 MODULE_PARM_DESC(PARM_TX_KEY, "Transmit Key ID (1 - 4) [1]");
280 MODULE_PARM(PARM_MULTICAST_RATE, "b");
281 MODULE_PARM_DESC(PARM_MULTICAST_RATE, "Multicast Rate");
282 MODULE_PARM(PARM_DOWNLOAD_FIRMWARE, "s");
283 MODULE_PARM_DESC(PARM_DOWNLOAD_FIRMWARE, "filename of firmware image");
285 MODULE_PARM(PARM_AUTH_KEY_MGMT_SUITE, "b");
286 MODULE_PARM_DESC(PARM_AUTH_KEY_MGMT_SUITE, "Authentication Key Management suite (0-4) [0]");
288 MODULE_PARM(PARM_LOAD_BALANCING, "s");
289 MODULE_PARM_DESC(PARM_LOAD_BALANCING, "Load Balancing Enabled (<string> N or Y) [Y]");
290 MODULE_PARM(PARM_MEDIUM_DISTRIBUTION, "s");
291 MODULE_PARM_DESC(PARM_MEDIUM_DISTRIBUTION, "Medium Distribution Enabled (<string> N or Y) [Y]");
292 MODULE_PARM(PARM_TX_POW_LEVEL, "b");
293 MODULE_PARM_DESC(PARM_TX_POW_LEVEL, "Transmit Power (0 - 6) [3]");
294 MODULE_PARM(PARM_SRSC_2GHZ, "b");
295 MODULE_PARM_DESC(PARM_SRSC_2GHZ, "Supported Rate Set Control 2.4 GHz");
296 MODULE_PARM(PARM_SRSC_5GHZ, "b");
297 MODULE_PARM_DESC(PARM_SRSC_5GHZ, "Supported Rate Set Control 5.0 GHz");
298 MODULE_PARM(PARM_BRSC_2GHZ, "b");
299 MODULE_PARM_DESC(PARM_BRSC_2GHZ, "Basic Rate Set Control 2.4 GHz");
300 MODULE_PARM(PARM_BRSC_5GHZ, "b");
301 MODULE_PARM_DESC(PARM_BRSC_5GHZ, "Basic Rate Set Control 5.0 GHz");
302 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
303 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
304 MODULE_PARM(PARM_PM_ENABLED, "h");
305 MODULE_PARM_DESC(PARM_PM_ENABLED, "Power Management State (0 - 2, 8001 - 8002) [0]");
306 MODULE_PARM(PARM_PORT_TYPE, "b");
307 MODULE_PARM_DESC(PARM_PORT_TYPE, "Port Type (1 - 3) [1]");
308 //;?MODULE_PARM(PARM_CREATE_IBSS, "s");
309 //;?MODULE_PARM_DESC(PARM_CREATE_IBSS, "Create IBSS (<string> N or Y) [N]");
310 //;?MODULE_PARM(PARM_MULTICAST_RX, "s");
311 //;?MODULE_PARM_DESC(PARM_MULTICAST_RX, "Multicast Receive Enable (<string> N or Y) [Y]");
312 //;?MODULE_PARM(PARM_MAX_SLEEP, "h");
313 //;?MODULE_PARM_DESC(PARM_MAX_SLEEP, "Maximum Power Management Sleep Duration (0 - 65535) [100]");
314 //;?MODULE_PARM(PARM_NETWORK_ADDR, "6b");
315 //;?MODULE_PARM_DESC(PARM_NETWORK_ADDR, "Hardware Ethernet Address ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [<factory value>]");
316 //;?MODULE_PARM(PARM_AUTHENTICATION, "b");
319 //;?MODULE_PARM_DESC(PARM_AUTHENTICATION, "Authentication Type (0-2) [0] 0=Open 1=SharedKey 2=LEAP");
320 //;?MODULE_PARM_DESC(authentication, "Authentication Type (1-2) [1] 1=Open 2=SharedKey");
323 //;?MODULE_PARM(PARM_OWN_ATIM_WINDOW, "b");
324 //;?MODULE_PARM_DESC(PARM_OWN_ATIM_WINDOW, "ATIM Window time in TU for IBSS creation (0-100) [0]");
325 //;?MODULE_PARM(PARM_PM_HOLDOVER_DURATION, "b");
326 //;?MODULE_PARM_DESC(PARM_PM_HOLDOVER_DURATION, "Time station remains awake after MAC frame transfer when PM is on (0-65535) [100]");
327 //;?MODULE_PARM(PARM_PROMISCUOUS_MODE, "s");
328 //;?MODULE_PARM_DESC(PARM_PROMISCUOUS_MODE, "Promiscuous Mode Enable (<string> Y or N ) [N]" );
330 MODULE_PARM(PARM_CONNECTION_CONTROL, "b");
331 MODULE_PARM_DESC(PARM_CONNECTION_CONTROL, "Connection Control (0 - 3) [2]");
333 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
334 //;?should we restore this to allow smaller memory footprint
335 MODULE_PARM(PARM_OWN_DTIM_PERIOD, "b");
336 MODULE_PARM_DESC(PARM_OWN_DTIM_PERIOD, "DTIM Period (0 - 255) [1]");
337 MODULE_PARM(PARM_REJECT_ANY, "s");
338 MODULE_PARM_DESC(PARM_REJECT_ANY, "Closed System (<string> N or Y) [N]");
339 MODULE_PARM(PARM_EXCLUDE_UNENCRYPTED, "s");
340 MODULE_PARM_DESC(PARM_EXCLUDE_UNENCRYPTED, "Deny non-encrypted (<string> N or Y) [Y]");
341 MODULE_PARM(PARM_MULTICAST_PM_BUFFERING,"s");
342 MODULE_PARM_DESC(PARM_MULTICAST_PM_BUFFERING, "Buffer MAC frames for Tx after DTIM (<string> Y or N) [Y]");
343 MODULE_PARM(PARM_INTRA_BSS_RELAY, "s");
344 MODULE_PARM_DESC(PARM_INTRA_BSS_RELAY, "IntraBSS Relay (<string> N or Y) [Y]");
345 MODULE_PARM(PARM_RTS_THRESHOLD1, "h");
346 MODULE_PARM_DESC(PARM_RTS_THRESHOLD1, "RTS Threshold, WDS Port 1 (256 - 2347) [2347]");
347 MODULE_PARM(PARM_RTS_THRESHOLD2, "h");
348 MODULE_PARM_DESC(PARM_RTS_THRESHOLD2, "RTS Threshold, WDS Port 2 (256 - 2347) [2347]");
349 MODULE_PARM(PARM_RTS_THRESHOLD3, "h");
350 MODULE_PARM_DESC(PARM_RTS_THRESHOLD3, "RTS Threshold, WDS Port 3 (256 - 2347) [2347]");
351 MODULE_PARM(PARM_RTS_THRESHOLD4, "h");
352 MODULE_PARM_DESC(PARM_RTS_THRESHOLD4, "RTS Threshold, WDS Port 4 (256 - 2347) [2347]");
353 MODULE_PARM(PARM_RTS_THRESHOLD5, "h");
354 MODULE_PARM_DESC(PARM_RTS_THRESHOLD5, "RTS Threshold, WDS Port 5 (256 - 2347) [2347]");
355 MODULE_PARM(PARM_RTS_THRESHOLD6, "h");
356 MODULE_PARM_DESC(PARM_RTS_THRESHOLD6, "RTS Threshold, WDS Port 6 (256 - 2347) [2347]");
357 MODULE_PARM(PARM_TX_RATE1, "b");
358 MODULE_PARM_DESC(PARM_TX_RATE1, "Transmit Rate Control, WDS Port 1 (1 - 7) [3]");
359 MODULE_PARM(PARM_TX_RATE2, "b");
360 MODULE_PARM_DESC(PARM_TX_RATE2, "Transmit Rate Control, WDS Port 2 (1 - 7) [3]");
361 MODULE_PARM(PARM_TX_RATE3, "b");
362 MODULE_PARM_DESC(PARM_TX_RATE3, "Transmit Rate Control, WDS Port 3 (1 - 7) [3]");
363 MODULE_PARM(PARM_TX_RATE4, "b");
364 MODULE_PARM_DESC(PARM_TX_RATE4, "Transmit Rate Control, WDS Port 4 (1 - 7) [3]");
365 MODULE_PARM(PARM_TX_RATE5, "b");
366 MODULE_PARM_DESC(PARM_TX_RATE5, "Transmit Rate Control, WDS Port 5 (1 - 7) [3]");
367 MODULE_PARM(PARM_TX_RATE6, "b");
368 MODULE_PARM_DESC(PARM_TX_RATE6, "Transmit Rate Control, WDS Port 6 (1 - 7) [3]");
369 MODULE_PARM(PARM_WDS_ADDRESS1, "6b");
370 MODULE_PARM_DESC(PARM_WDS_ADDRESS1, "MAC Address, WDS Port 1 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
371 MODULE_PARM(PARM_WDS_ADDRESS2, "6b");
372 MODULE_PARM_DESC(PARM_WDS_ADDRESS2, "MAC Address, WDS Port 2 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
373 MODULE_PARM(PARM_WDS_ADDRESS3, "6b");
374 MODULE_PARM_DESC(PARM_WDS_ADDRESS3, "MAC Address, WDS Port 3 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
375 MODULE_PARM(PARM_WDS_ADDRESS4, "6b");
376 MODULE_PARM_DESC(PARM_WDS_ADDRESS4, "MAC Address, WDS Port 4 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
377 MODULE_PARM(PARM_WDS_ADDRESS5, "6b");
378 MODULE_PARM_DESC(PARM_WDS_ADDRESS5, "MAC Address, WDS Port 5 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
379 MODULE_PARM(PARM_WDS_ADDRESS6, "6b");
380 MODULE_PARM_DESC(PARM_WDS_ADDRESS6, "MAC Address, WDS Port 6 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
382 MODULE_PARM(PARM_OWN_BEACON_INTERVAL, "b");
383 MODULE_PARM_DESC(PARM_OWN_BEACON_INTERVAL, "Own Beacon Interval (20 - 200) [100]");
384 MODULE_PARM(PARM_COEXISTENCE, "b");
385 MODULE_PARM_DESC(PARM_COEXISTENCE, "Coexistence (0-7) [0]");
390 /* END NEW PARAMETERS */
391 /*******************************************************************************
392 * debugging specifics
393 ******************************************************************************/
396 static p_u32 pc_debug = DBG_LVL;
397 //MODULE_PARM(pc_debug, "i");
398 /*static ;?conflicts with my understanding of CL parameters and breaks now I moved
399 * the correspondig logic to wl_profile
400 */ p_u32 DebugFlag = ~0; //recognizable "undefined value" rather then DBG_DEFAULTS;
401 //MODULE_PARM(DebugFlag, "l");
403 dbg_info_t wl_info = { DBG_MOD_NAME, 0, 0 };
404 dbg_info_t *DbgInfo = &wl_info;
409 static p_char *useRTS = "N";
410 MODULE_PARM( useRTS, "s" );
411 MODULE_PARM_DESC( useRTS, "Use RTS test interface (<string> N or Y) [N]" );
414 /*******************************************************************************
415 * firmware download specifics
416 ******************************************************************************/
417 extern struct CFG_RANGE2_STRCT BASED
418 cfg_drv_act_ranges_pri; // describes primary-actor range of HCF
420 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
421 extern memimage ap; // AP firmware image to be downloaded
424 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
425 //extern memimage station; // STA firmware image to be downloaded
426 extern memimage fw_image; // firmware image to be downloaded
430 int wl_insert( struct net_device *dev )
433 int hcf_status = HCF_SUCCESS;
435 unsigned long flags = 0;
436 struct wl_private *lp = wl_priv(dev);
438 /* Initialize the adapter hardware. */
439 memset( &( lp->hcfCtx ), 0, sizeof( IFB_STRCT ));
441 /* Initialize the adapter parameters. */
442 spin_lock_init( &( lp->slock ));
444 /* Initialize states */
445 //lp->lockcount = 0; //PE1DNN
446 lp->is_handling_int = WL_NOT_HANDLING_INT;
447 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
451 DBG_PARAM( DbgInfo, "irq_mask", "0x%04x", irq_mask & 0x0FFFF );
452 DBG_PARAM( DbgInfo, "irq_list", "0x%02x 0x%02x 0x%02x 0x%02x",
453 irq_list[0] & 0x0FF, irq_list[1] & 0x0FF,
454 irq_list[2] & 0x0FF, irq_list[3] & 0x0FF );
455 DBG_PARAM( DbgInfo, PARM_NAME_DESIRED_SSID, "\"%s\"", PARM_DESIRED_SSID );
456 DBG_PARAM( DbgInfo, PARM_NAME_OWN_SSID, "\"%s\"", PARM_OWN_SSID );
457 DBG_PARAM( DbgInfo, PARM_NAME_OWN_CHANNEL, "%d", PARM_OWN_CHANNEL);
458 DBG_PARAM( DbgInfo, PARM_NAME_SYSTEM_SCALE, "%d", PARM_SYSTEM_SCALE );
459 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE, "%d", PARM_TX_RATE );
460 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD, "%d", PARM_RTS_THRESHOLD );
461 DBG_PARAM( DbgInfo, PARM_NAME_MICROWAVE_ROBUSTNESS, "\"%s\"", PARM_MICROWAVE_ROBUSTNESS );
462 DBG_PARAM( DbgInfo, PARM_NAME_OWN_NAME, "\"%s\"", PARM_OWN_NAME );
463 //;? DBG_PARAM( DbgInfo, PARM_NAME_ENABLE_ENCRYPTION, "\"%s\"", PARM_ENABLE_ENCRYPTION );
464 DBG_PARAM( DbgInfo, PARM_NAME_KEY1, "\"%s\"", PARM_KEY1 );
465 DBG_PARAM( DbgInfo, PARM_NAME_KEY2, "\"%s\"", PARM_KEY2 );
466 DBG_PARAM( DbgInfo, PARM_NAME_KEY3, "\"%s\"", PARM_KEY3 );
467 DBG_PARAM( DbgInfo, PARM_NAME_KEY4, "\"%s\"", PARM_KEY4 );
468 DBG_PARAM( DbgInfo, PARM_NAME_TX_KEY, "%d", PARM_TX_KEY );
469 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RATE, "%d", PARM_MULTICAST_RATE );
470 DBG_PARAM( DbgInfo, PARM_NAME_DOWNLOAD_FIRMWARE, "\"%s\"", PARM_DOWNLOAD_FIRMWARE );
471 DBG_PARAM( DbgInfo, PARM_NAME_AUTH_KEY_MGMT_SUITE, "%d", PARM_AUTH_KEY_MGMT_SUITE );
472 //;?#if (HCF_TYPE) & HCF_TYPE_STA
473 //;?should we make this code conditional depending on in STA mode
474 //;? DBG_PARAM( DbgInfo, PARM_NAME_PORT_TYPE, "%d", PARM_PORT_TYPE );
475 DBG_PARAM( DbgInfo, PARM_NAME_PM_ENABLED, "%04x", PARM_PM_ENABLED );
476 //;? DBG_PARAM( DbgInfo, PARM_NAME_CREATE_IBSS, "\"%s\"", PARM_CREATE_IBSS );
477 //;? DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RX, "\"%s\"", PARM_MULTICAST_RX );
478 //;? DBG_PARAM( DbgInfo, PARM_NAME_MAX_SLEEP, "%d", PARM_MAX_SLEEP );
480 DBG_PARAM(DbgInfo, PARM_NAME_NETWORK_ADDR, "\"%pM\"",
483 //;? DBG_PARAM( DbgInfo, PARM_NAME_AUTHENTICATION, "%d", PARM_AUTHENTICATION );
484 //;? DBG_PARAM( DbgInfo, PARM_NAME_OWN_ATIM_WINDOW, "%d", PARM_OWN_ATIM_WINDOW );
485 //;? DBG_PARAM( DbgInfo, PARM_NAME_PM_HOLDOVER_DURATION, "%d", PARM_PM_HOLDOVER_DURATION );
486 //;? DBG_PARAM( DbgInfo, PARM_NAME_PROMISCUOUS_MODE, "\"%s\"", PARM_PROMISCUOUS_MODE );
487 //;?#endif /* HCF_STA */
488 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
489 //;?should we restore this to allow smaller memory footprint
490 //;?I guess: no, since this is Debug mode only
491 DBG_PARAM( DbgInfo, PARM_NAME_OWN_DTIM_PERIOD, "%d", PARM_OWN_DTIM_PERIOD );
492 DBG_PARAM( DbgInfo, PARM_NAME_REJECT_ANY, "\"%s\"", PARM_REJECT_ANY );
493 DBG_PARAM( DbgInfo, PARM_NAME_EXCLUDE_UNENCRYPTED, "\"%s\"", PARM_EXCLUDE_UNENCRYPTED );
494 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_PM_BUFFERING, "\"%s\"", PARM_MULTICAST_PM_BUFFERING );
495 DBG_PARAM( DbgInfo, PARM_NAME_INTRA_BSS_RELAY, "\"%s\"", PARM_INTRA_BSS_RELAY );
497 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD1, "%d", PARM_RTS_THRESHOLD1 );
498 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD2, "%d", PARM_RTS_THRESHOLD2 );
499 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD3, "%d", PARM_RTS_THRESHOLD3 );
500 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD4, "%d", PARM_RTS_THRESHOLD4 );
501 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD5, "%d", PARM_RTS_THRESHOLD5 );
502 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD6, "%d", PARM_RTS_THRESHOLD6 );
503 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE1, "%d", PARM_TX_RATE1 );
504 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE2, "%d", PARM_TX_RATE2 );
505 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE3, "%d", PARM_TX_RATE3 );
506 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE4, "%d", PARM_TX_RATE4 );
507 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE5, "%d", PARM_TX_RATE5 );
508 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE6, "%d", PARM_TX_RATE6 );
509 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS1, "\"%pM\"",
511 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS2, "\"%pM\"",
513 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS3, "\"%pM\"",
515 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS4, "\"%pM\"",
517 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS5, "\"%pM\"",
519 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS6, "\"%pM\"",
524 VALID_PARAM( !PARM_DESIRED_SSID || ( strlen( PARM_DESIRED_SSID ) <= PARM_MAX_NAME_LEN ));
525 VALID_PARAM( !PARM_OWN_SSID || ( strlen( PARM_OWN_SSID ) <= PARM_MAX_NAME_LEN ));
526 VALID_PARAM(( PARM_OWN_CHANNEL <= PARM_MAX_OWN_CHANNEL ));
527 VALID_PARAM(( PARM_SYSTEM_SCALE >= PARM_MIN_SYSTEM_SCALE ) && ( PARM_SYSTEM_SCALE <= PARM_MAX_SYSTEM_SCALE ));
528 VALID_PARAM(( PARM_TX_RATE >= PARM_MIN_TX_RATE ) && ( PARM_TX_RATE <= PARM_MAX_TX_RATE ));
529 VALID_PARAM(( PARM_RTS_THRESHOLD <= PARM_MAX_RTS_THRESHOLD ));
530 VALID_PARAM( !PARM_MICROWAVE_ROBUSTNESS || strchr( "NnYy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL );
531 VALID_PARAM( !PARM_OWN_NAME || ( strlen( PARM_NAME_OWN_NAME ) <= PARM_MAX_NAME_LEN ));
532 VALID_PARAM(( PARM_ENABLE_ENCRYPTION <= PARM_MAX_ENABLE_ENCRYPTION ));
533 VALID_PARAM( is_valid_key_string( PARM_KEY1 ));
534 VALID_PARAM( is_valid_key_string( PARM_KEY2 ));
535 VALID_PARAM( is_valid_key_string( PARM_KEY3 ));
536 VALID_PARAM( is_valid_key_string( PARM_KEY4 ));
537 VALID_PARAM(( PARM_TX_KEY >= PARM_MIN_TX_KEY ) && ( PARM_TX_KEY <= PARM_MAX_TX_KEY ));
539 VALID_PARAM(( PARM_MULTICAST_RATE >= PARM_MIN_MULTICAST_RATE ) &&
540 ( PARM_MULTICAST_RATE <= PARM_MAX_MULTICAST_RATE ));
542 VALID_PARAM( !PARM_DOWNLOAD_FIRMWARE || ( strlen( PARM_DOWNLOAD_FIRMWARE ) <= 255 /*;?*/ ));
543 VALID_PARAM(( PARM_AUTH_KEY_MGMT_SUITE < PARM_MAX_AUTH_KEY_MGMT_SUITE ));
545 VALID_PARAM( !PARM_LOAD_BALANCING || strchr( "NnYy", PARM_LOAD_BALANCING[0] ) != NULL );
546 VALID_PARAM( !PARM_MEDIUM_DISTRIBUTION || strchr( "NnYy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL );
547 VALID_PARAM(( PARM_TX_POW_LEVEL <= PARM_MAX_TX_POW_LEVEL ));
549 VALID_PARAM(( PARM_PORT_TYPE >= PARM_MIN_PORT_TYPE ) && ( PARM_PORT_TYPE <= PARM_MAX_PORT_TYPE ));
550 VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
551 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
552 VALID_PARAM( !PARM_CREATE_IBSS || strchr( "NnYy", PARM_CREATE_IBSS[0] ) != NULL );
553 VALID_PARAM( !PARM_MULTICAST_RX || strchr( "NnYy", PARM_MULTICAST_RX[0] ) != NULL );
554 VALID_PARAM(( PARM_MAX_SLEEP <= PARM_MAX_MAX_PM_SLEEP ));
555 VALID_PARAM(( PARM_AUTHENTICATION <= PARM_MAX_AUTHENTICATION ));
556 VALID_PARAM(( PARM_OWN_ATIM_WINDOW <= PARM_MAX_OWN_ATIM_WINDOW ));
557 VALID_PARAM(( PARM_PM_HOLDOVER_DURATION <= PARM_MAX_PM_HOLDOVER_DURATION ));
558 VALID_PARAM( !PARM_PROMISCUOUS_MODE || strchr( "NnYy", PARM_PROMISCUOUS_MODE[0] ) != NULL );
559 VALID_PARAM(( PARM_CONNECTION_CONTROL <= PARM_MAX_CONNECTION_CONTROL ));
561 VALID_PARAM(( PARM_OWN_DTIM_PERIOD >= PARM_MIN_OWN_DTIM_PERIOD ));
562 VALID_PARAM( !PARM_REJECT_ANY || strchr( "NnYy", PARM_REJECT_ANY[0] ) != NULL );
563 VALID_PARAM( !PARM_EXCLUDE_UNENCRYPTED || strchr( "NnYy", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL );
564 VALID_PARAM( !PARM_MULTICAST_PM_BUFFERING || strchr( "NnYy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL );
565 VALID_PARAM( !PARM_INTRA_BSS_RELAY || strchr( "NnYy", PARM_INTRA_BSS_RELAY[0] ) != NULL );
567 VALID_PARAM(( PARM_RTS_THRESHOLD1 <= PARM_MAX_RTS_THRESHOLD ));
568 VALID_PARAM(( PARM_RTS_THRESHOLD2 <= PARM_MAX_RTS_THRESHOLD ));
569 VALID_PARAM(( PARM_RTS_THRESHOLD3 <= PARM_MAX_RTS_THRESHOLD ));
570 VALID_PARAM(( PARM_RTS_THRESHOLD4 <= PARM_MAX_RTS_THRESHOLD ));
571 VALID_PARAM(( PARM_RTS_THRESHOLD5 <= PARM_MAX_RTS_THRESHOLD ));
572 VALID_PARAM(( PARM_RTS_THRESHOLD6 <= PARM_MAX_RTS_THRESHOLD ));
573 VALID_PARAM(( PARM_TX_RATE1 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE1 <= PARM_MAX_TX_RATE ));
574 VALID_PARAM(( PARM_TX_RATE2 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE2 <= PARM_MAX_TX_RATE ));
575 VALID_PARAM(( PARM_TX_RATE3 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE3 <= PARM_MAX_TX_RATE ));
576 VALID_PARAM(( PARM_TX_RATE4 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE4 <= PARM_MAX_TX_RATE ));
577 VALID_PARAM(( PARM_TX_RATE5 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE5 <= PARM_MAX_TX_RATE ));
578 VALID_PARAM(( PARM_TX_RATE6 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE6 <= PARM_MAX_TX_RATE ));
581 VALID_PARAM(( PARM_OWN_BEACON_INTERVAL >= PARM_MIN_OWN_BEACON_INTERVAL ) && ( PARM_OWN_BEACON_INTERVAL <= PARM_MAX_OWN_BEACON_INTERVAL ));
582 VALID_PARAM(( PARM_COEXISTENCE <= PARM_COEXISTENCE ));
584 /* Set the driver parameters from the passed in parameters. */
586 /* THESE MODULE PARAMETERS ARE TO BE DEPRECATED IN FAVOR OF A NAMING CONVENTION
587 WHICH IS INLINE WITH THE FORTHCOMING WAVELAN API */
589 /* START NEW PARAMETERS */
591 lp->Channel = PARM_OWN_CHANNEL;
592 lp->DistanceBetweenAPs = PARM_SYSTEM_SCALE;
594 /* Need to determine how to handle the new bands for 5GHz */
595 lp->TxRateControl[0] = PARM_DEFAULT_TX_RATE_2GHZ;
596 lp->TxRateControl[1] = PARM_DEFAULT_TX_RATE_5GHZ;
598 lp->RTSThreshold = PARM_RTS_THRESHOLD;
600 /* Need to determine how to handle the new bands for 5GHz */
601 lp->MulticastRate[0] = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
602 lp->MulticastRate[1] = PARM_DEFAULT_MULTICAST_RATE_5GHZ;
604 if ( strchr( "Yy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL ) {
605 lp->MicrowaveRobustness = 1;
607 lp->MicrowaveRobustness = 0;
609 if ( PARM_DESIRED_SSID && ( strlen( PARM_DESIRED_SSID ) <= HCF_MAX_NAME_LEN )) {
610 strcpy( lp->NetworkName, PARM_DESIRED_SSID );
612 if ( PARM_OWN_SSID && ( strlen( PARM_OWN_SSID ) <= HCF_MAX_NAME_LEN )) {
613 strcpy( lp->NetworkName, PARM_OWN_SSID );
615 if ( PARM_OWN_NAME && ( strlen( PARM_OWN_NAME ) <= HCF_MAX_NAME_LEN )) {
616 strcpy( lp->StationName, PARM_OWN_NAME );
618 lp->EnableEncryption = PARM_ENABLE_ENCRYPTION;
619 if ( PARM_KEY1 && ( strlen( PARM_KEY1 ) <= MAX_KEY_LEN )) {
620 strcpy( lp->Key1, PARM_KEY1 );
622 if ( PARM_KEY2 && ( strlen( PARM_KEY2 ) <= MAX_KEY_LEN )) {
623 strcpy( lp->Key2, PARM_KEY2 );
625 if ( PARM_KEY3 && ( strlen( PARM_KEY3 ) <= MAX_KEY_LEN )) {
626 strcpy( lp->Key3, PARM_KEY3 );
628 if ( PARM_KEY4 && ( strlen( PARM_KEY4 ) <= MAX_KEY_LEN )) {
629 strcpy( lp->Key4, PARM_KEY4 );
632 lp->TransmitKeyID = PARM_TX_KEY;
634 key_string2key( lp->Key1, &(lp->DefaultKeys.key[0] ));
635 key_string2key( lp->Key2, &(lp->DefaultKeys.key[1] ));
636 key_string2key( lp->Key3, &(lp->DefaultKeys.key[2] ));
637 key_string2key( lp->Key4, &(lp->DefaultKeys.key[3] ));
639 lp->DownloadFirmware = 1 ; //;?to be upgraded PARM_DOWNLOAD_FIRMWARE;
640 lp->AuthKeyMgmtSuite = PARM_AUTH_KEY_MGMT_SUITE;
642 if ( strchr( "Yy", PARM_LOAD_BALANCING[0] ) != NULL ) {
643 lp->loadBalancing = 1;
645 lp->loadBalancing = 0;
648 if ( strchr( "Yy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL ) {
649 lp->mediumDistribution = 1;
651 lp->mediumDistribution = 0;
654 lp->txPowLevel = PARM_TX_POW_LEVEL;
656 lp->srsc[0] = PARM_SRSC_2GHZ;
657 lp->srsc[1] = PARM_SRSC_5GHZ;
658 lp->brsc[0] = PARM_BRSC_2GHZ;
659 lp->brsc[1] = PARM_BRSC_5GHZ;
660 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
661 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
662 lp->PortType = PARM_PORT_TYPE;
663 lp->MaxSleepDuration = PARM_MAX_SLEEP;
664 lp->authentication = PARM_AUTHENTICATION;
665 lp->atimWindow = PARM_OWN_ATIM_WINDOW;
666 lp->holdoverDuration = PARM_PM_HOLDOVER_DURATION;
667 lp->PMEnabled = PARM_PM_ENABLED; //;?
668 if ( strchr( "Yy", PARM_CREATE_IBSS[0] ) != NULL ) {
673 if ( strchr( "Nn", PARM_MULTICAST_RX[0] ) != NULL ) {
674 lp->MulticastReceive = 0;
676 lp->MulticastReceive = 1;
678 if ( strchr( "Yy", PARM_PROMISCUOUS_MODE[0] ) != NULL ) {
679 lp->promiscuousMode = 1;
681 lp->promiscuousMode = 0;
683 for( i = 0; i < ETH_ALEN; i++ ) {
684 lp->MACAddress[i] = PARM_NETWORK_ADDR[i];
687 lp->connectionControl = PARM_CONNECTION_CONTROL;
690 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
691 //;?should we restore this to allow smaller memory footprint
692 lp->DTIMPeriod = PARM_OWN_DTIM_PERIOD;
694 if ( strchr( "Yy", PARM_REJECT_ANY[0] ) != NULL ) {
699 if ( strchr( "Nn", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL ) {
700 lp->ExcludeUnencrypted = 0;
702 lp->ExcludeUnencrypted = 1;
704 if ( strchr( "Yy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL ) {
705 lp->multicastPMBuffering = 1;
707 lp->multicastPMBuffering = 0;
709 if ( strchr( "Yy", PARM_INTRA_BSS_RELAY[0] ) != NULL ) {
710 lp->intraBSSRelay = 1;
712 lp->intraBSSRelay = 0;
715 lp->ownBeaconInterval = PARM_OWN_BEACON_INTERVAL;
716 lp->coexistence = PARM_COEXISTENCE;
719 lp->wds_port[0].rtsThreshold = PARM_RTS_THRESHOLD1;
720 lp->wds_port[1].rtsThreshold = PARM_RTS_THRESHOLD2;
721 lp->wds_port[2].rtsThreshold = PARM_RTS_THRESHOLD3;
722 lp->wds_port[3].rtsThreshold = PARM_RTS_THRESHOLD4;
723 lp->wds_port[4].rtsThreshold = PARM_RTS_THRESHOLD5;
724 lp->wds_port[5].rtsThreshold = PARM_RTS_THRESHOLD6;
725 lp->wds_port[0].txRateCntl = PARM_TX_RATE1;
726 lp->wds_port[1].txRateCntl = PARM_TX_RATE2;
727 lp->wds_port[2].txRateCntl = PARM_TX_RATE3;
728 lp->wds_port[3].txRateCntl = PARM_TX_RATE4;
729 lp->wds_port[4].txRateCntl = PARM_TX_RATE5;
730 lp->wds_port[5].txRateCntl = PARM_TX_RATE6;
732 for( i = 0; i < ETH_ALEN; i++ ) {
733 lp->wds_port[0].wdsAddress[i] = PARM_WDS_ADDRESS1[i];
735 for( i = 0; i < ETH_ALEN; i++ ) {
736 lp->wds_port[1].wdsAddress[i] = PARM_WDS_ADDRESS2[i];
738 for( i = 0; i < ETH_ALEN; i++ ) {
739 lp->wds_port[2].wdsAddress[i] = PARM_WDS_ADDRESS3[i];
741 for( i = 0; i < ETH_ALEN; i++ ) {
742 lp->wds_port[3].wdsAddress[i] = PARM_WDS_ADDRESS4[i];
744 for( i = 0; i < ETH_ALEN; i++ ) {
745 lp->wds_port[4].wdsAddress[i] = PARM_WDS_ADDRESS5[i];
747 for( i = 0; i < ETH_ALEN; i++ ) {
748 lp->wds_port[5].wdsAddress[i] = PARM_WDS_ADDRESS6[i];
753 if ( strchr( "Yy", useRTS[0] ) != NULL ) {
761 /* END NEW PARAMETERS */
764 wl_lock( lp, &flags );
766 /* Initialize the portState variable */
767 lp->portState = WVLAN_PORT_STATE_DISABLED;
769 /* Initialize the ScanResult struct */
770 memset( &( lp->scan_results ), 0, sizeof( lp->scan_results ));
771 lp->scan_results.scan_complete = FALSE;
773 /* Initialize the ProbeResult struct */
774 memset( &( lp->probe_results ), 0, sizeof( lp->probe_results ));
775 lp->probe_results.scan_complete = FALSE;
776 lp->probe_num_aps = 0;
779 /* Initialize Tx queue stuff */
780 memset( lp->txList, 0, sizeof( lp->txList ));
782 INIT_LIST_HEAD( &( lp->txFree ));
788 for( i = 0; i < DEFAULT_NUM_TX_FRAMES; i++ ) {
789 list_add_tail( &( lp->txList[i].node ), &( lp->txFree ));
793 for( i = 0; i < WVLAN_MAX_TX_QUEUES; i++ ) {
794 INIT_LIST_HEAD( &( lp->txQ[i] ));
797 lp->netif_queue_on = TRUE;
799 /* Initialize the use_dma element in the adapter structure. Not sure if
800 this should be a compile-time or run-time configurable. So for now,
801 implement as run-time and just define here */
804 DBG_TRACE( DbgInfo, "HERMES 2.5 BUSMASTER DMA MODE\n" );
807 DBG_TRACE( DbgInfo, "HERMES 2.5 PORT I/O MODE\n" );
812 /* Register the ISR handler information here, so that it's not done
813 repeatedly in the ISR */
814 tasklet_init(&lp->task, wl_isr_handler, (unsigned long)lp);
816 /* Connect to the adapter */
817 DBG_TRACE( DbgInfo, "Calling hcf_connect()...\n" );
818 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
819 //HCF_ERR_INCOMP_FW is acceptable, because download must still take place
820 //HCF_ERR_INCOMP_PRI is not acceptable
821 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
822 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
823 wl_unlock( lp, &flags );
827 //;?should set HCF_version and how about driver_stat
828 lp->driverInfo.IO_address = dev->base_addr;
829 lp->driverInfo.IO_range = HCF_NUM_IO_PORTS; //;?conditionally 0x40 or 0x80 seems better
830 lp->driverInfo.IRQ_number = dev->irq;
831 lp->driverInfo.card_stat = lp->hcfCtx.IFB_CardStat;
832 //;? what happened to frame_type
834 /* Fill in the driver identity structure */
835 lp->driverIdentity.len = ( sizeof( lp->driverIdentity ) / sizeof( hcf_16 )) - 1;
836 lp->driverIdentity.typ = CFG_DRV_IDENTITY;
837 lp->driverIdentity.comp_id = DRV_IDENTITY;
838 lp->driverIdentity.variant = DRV_VARIANT;
839 lp->driverIdentity.version_major = DRV_MAJOR_VERSION;
840 lp->driverIdentity.version_minor = DRV_MINOR_VERSION;
843 /* Start the card here - This needs to be done in order to get the
844 MAC address for the network layer */
845 DBG_TRACE( DbgInfo, "Calling wvlan_go() to perform a card reset...\n" );
846 hcf_status = wl_go( lp );
848 if ( hcf_status != HCF_SUCCESS ) {
849 DBG_ERROR( DbgInfo, "wl_go() failed\n" );
850 wl_unlock( lp, &flags );
854 /* Certain RIDs must be set before enabling the ports */
855 wl_put_ltv_init( lp );
857 #if 0 //;?why was this already commented out in wl_lkm_720
858 /* Enable the ports */
859 if ( wl_adapter_is_open( lp->dev )) {
860 /* Enable the ports */
861 DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
862 hcf_status = wl_enable( lp );
864 if ( hcf_status != HCF_SUCCESS ) {
865 DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", hcf_status );
868 #if (HCF_TYPE) & HCF_TYPE_AP
869 DBG_TRACE( DbgInfo, "Enabling WDS Ports\n" );
870 //wl_enable_wds_ports( lp );
871 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
876 /* Fill out the MAC address information in the net_device struct */
877 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN );
878 dev->addr_len = ETH_ALEN;
880 lp->is_registered = TRUE;
883 /* Parse the config file for the sake of creating WDS ports if WDS is
884 configured there but not in the module options */
886 #endif /* USE_PROFILE */
888 /* If we're going into AP Mode, register the "virtual" ethernet devices
890 WL_WDS_NETDEV_REGISTER( lp );
892 /* Reset the DownloadFirmware variable in the private struct. If the
893 config file is not used, this will not matter; if it is used, it
894 will be reparsed in wl_open(). This is done because logic in wl_open
895 used to check if a firmware download is needed is broken by parsing
896 the file here; however, this parsing is needed to register WDS ports
897 in AP mode, if they are configured */
898 lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //;?download_firmware;
901 if ( lp->useRTS == 1 ) {
902 DBG_TRACE( DbgInfo, "ENTERING RTS MODE...\n" );
903 wl_act_int_off( lp );
904 lp->is_handling_int = WL_NOT_HANDLING_INT; // Not handling interrupts anymore
908 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT);
912 wl_unlock( lp, &flags );
914 DBG_TRACE( DbgInfo, "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
915 dev->name, dev->base_addr, dev->irq );
917 for( i = 0; i < ETH_ALEN; i++ ) {
918 printk( "%02X%c", dev->dev_addr[i], (( i < ( ETH_ALEN-1 )) ? ':' : '\n' ));
921 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
922 proc_create_data( "wlags", 0, NULL, &scull_read_procmem_fops, dev );
923 proc_mkdir("driver/wlags49", 0);
924 #endif /* SCULL_USE_PROC */
926 DBG_LEAVE( DbgInfo );
930 wl_hcf_error( dev, hcf_status );
934 DBG_ERROR( DbgInfo, "wl_insert() FAILED\n" );
936 if ( lp->is_registered == TRUE ) {
937 lp->is_registered = FALSE;
940 WL_WDS_NETDEV_DEREGISTER( lp );
945 DBG_LEAVE( DbgInfo );
948 /*============================================================================*/
951 /*******************************************************************************
953 *******************************************************************************
961 * dev - a pointer to the net_device struct of the wireless device
967 ******************************************************************************/
968 int wl_reset(struct net_device *dev)
970 struct wl_private *lp = wl_priv(dev);
971 int hcf_status = HCF_SUCCESS;
973 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
974 DBG_PARAM( DbgInfo, "dev->base_addr", "(%#03lx)", dev->base_addr );
977 * The caller should already have a lock and
978 * disable the interrupts, we do not lock here,
979 * nor do we enable/disable interrupts!
982 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", dev->base_addr );
983 if ( dev->base_addr ) {
984 /* Shutdown the adapter. */
985 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
987 /* Reset the driver information. */
990 /* Connect to the adapter. */
991 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
992 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
993 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
997 /* Check if firmware is present, if not change state */
998 if ( hcf_status == HCF_ERR_INCOMP_FW ) {
999 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1002 /* Initialize the portState variable */
1003 lp->portState = WVLAN_PORT_STATE_DISABLED;
1005 /* Restart the adapter. */
1006 hcf_status = wl_go( lp );
1007 if ( hcf_status != HCF_SUCCESS ) {
1008 DBG_ERROR( DbgInfo, "wl_go() failed, status: 0x%x\n", hcf_status );
1012 /* Certain RIDs must be set before enabling the ports */
1013 wl_put_ltv_init( lp );
1015 DBG_ERROR( DbgInfo, "Device Base Address INVALID!!!\n" );
1019 DBG_LEAVE( DbgInfo );
1022 /*============================================================================*/
1025 /*******************************************************************************
1027 *******************************************************************************
1031 * Reset the adapter.
1035 * dev - a pointer to the net_device struct of the wireless device
1039 * an HCF status code
1041 ******************************************************************************/
1042 int wl_go( struct wl_private *lp )
1044 int hcf_status = HCF_SUCCESS;
1045 char *cp = NULL; //fw_image
1048 hcf_status = wl_disable( lp );
1049 if ( hcf_status != HCF_SUCCESS ) {
1050 DBG_TRACE( DbgInfo, "Disable port 0 failed: 0x%x\n", hcf_status );
1052 while (( hcf_status != HCF_SUCCESS ) && (retries < 10)) {
1054 hcf_status = wl_disable( lp );
1056 if ( hcf_status == HCF_SUCCESS ) {
1057 DBG_TRACE( DbgInfo, "Disable port 0 succes : %d retries\n", retries );
1059 DBG_TRACE( DbgInfo, "Disable port 0 failed after: %d retries\n", retries );
1063 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
1064 //DBG_TRACE( DbgInfo, "Disabling WDS Ports\n" );
1065 //wl_disable_wds_ports( lp );
1066 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1068 //;?what was the purpose of this
1069 // /* load the appropriate firmware image, depending on driver mode */
1070 // lp->ltvRecord.len = ( sizeof( CFG_RANGE20_STRCT ) / sizeof( hcf_16 )) - 1;
1071 // lp->ltvRecord.typ = CFG_DRV_ACT_RANGES_PRI;
1072 // hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1075 if ( strlen( lp->fw_image_filename ) ) {
1080 DBG_TRACE( DbgInfo, "F/W image:%s:\n", lp->fw_image_filename );
1081 /* Obtain a user-space process context, storing the original context */
1084 file_desc = open( lp->fw_image_filename, O_RDONLY, 0 );
1085 if ( file_desc == -1 ) {
1086 DBG_ERROR( DbgInfo, "No image file found\n" );
1088 DBG_TRACE( DbgInfo, "F/W image file found\n" );
1089 #define DHF_ALLOC_SIZE 96000 //just below 96K, let's hope it suffices for now and for the future
1090 cp = (char*)vmalloc( DHF_ALLOC_SIZE );
1092 DBG_ERROR( DbgInfo, "error in vmalloc\n" );
1094 rc = read( file_desc, cp, DHF_ALLOC_SIZE );
1095 if ( rc == DHF_ALLOC_SIZE ) {
1096 DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE );
1097 } else if ( rc > 0 ) {
1098 DBG_TRACE( DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp );
1099 rc = read( file_desc, &cp[rc], 1 );
1100 if ( rc == 0 ) { //;/change to an until-loop at rc<=0
1101 DBG_TRACE( DbgInfo, "no more to read\n" );
1105 DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\
1106 ", give up, too complicated, rc = %0X\n", rc );
1107 DBG_ERROR( DbgInfo, "still have to change code to get a real download now !!!!!!!!\n" );
1109 DBG_TRACE( DbgInfo, "before dhf_download_binary\n" );
1110 hcf_status = dhf_download_binary( (memimage *)cp );
1111 DBG_TRACE( DbgInfo, "after dhf_download_binary, before dhf_download_fw\n" );
1112 //;?improve error flow/handling
1113 hcf_status = dhf_download_fw( &lp->hcfCtx, (memimage *)cp );
1114 DBG_TRACE( DbgInfo, "after dhf_download_fw\n" );
1120 set_fs( fs ); /* Return to the original context */
1124 /* If firmware is present but the type is unknown then download anyway */
1125 if ( (lp->firmware_present == WL_FRIMWARE_PRESENT)
1127 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_STA )
1129 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_AP ) ) {
1130 /* Unknown type, download needed. */
1131 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1134 if(lp->firmware_present == WL_FRIMWARE_NOT_PRESENT)
1137 DBG_TRACE( DbgInfo, "Downloading STA firmware...\n" );
1138 // hcf_status = dhf_download_fw( &lp->hcfCtx, &station );
1139 hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image );
1141 if ( hcf_status != HCF_SUCCESS ) {
1142 DBG_ERROR( DbgInfo, "Firmware Download failed\n" );
1143 DBG_LEAVE( DbgInfo );
1147 /* Report the FW versions */
1148 //;?obsolete, use the available IFB info:: wl_get_pri_records( lp );
1149 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1150 DBG_TRACE( DbgInfo, "downloaded station F/W\n" );
1151 } else if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1152 DBG_TRACE( DbgInfo, "downloaded AP F/W\n" );
1154 DBG_ERROR( DbgInfo, "unknown F/W type\n" );
1158 * Downloaded, no need to repeat this next time, assume the
1159 * contents stays in the card until it is powered off. Note we
1160 * do not switch firmware on the fly, the firmware is fixed in
1161 * the driver for now.
1163 lp->firmware_present = WL_FRIMWARE_PRESENT;
1165 DBG_TRACE( DbgInfo, "ComponentID:%04x variant:%04x major:%04x minor:%04x\n",
1166 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ),
1167 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.variant ),
1168 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_major ),
1169 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_minor ));
1171 /* now we will get the MAC address of the card */
1172 lp->ltvRecord.len = 4;
1173 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1174 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1177 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1179 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1180 if ( hcf_status != HCF_SUCCESS ) {
1181 DBG_ERROR( DbgInfo, "Could not retrieve MAC address\n" );
1182 DBG_LEAVE( DbgInfo );
1185 memcpy( lp->MACAddress, &lp->ltvRecord.u.u8[0], ETH_ALEN );
1186 DBG_TRACE(DbgInfo, "Card MAC Address: %pM\n", lp->MACAddress);
1188 /* Write out configuration to the device, enable, and reconnect. However,
1189 only reconnect if in AP mode. For STA mode, need to wait for passive scan
1190 completion before a connect can be issued */
1192 /* Enable the ports */
1193 hcf_status = wl_enable( lp );
1195 if ( lp->DownloadFirmware == WVLAN_DRV_MODE_AP ) {
1197 wl_enable_wds_ports( lp );
1199 hcf_status = wl_connect( lp );
1201 DBG_LEAVE( DbgInfo );
1204 /*============================================================================*/
1207 /*******************************************************************************
1209 *******************************************************************************
1213 * Write TxKeyID and WEP keys to the adapter. This is separated from
1214 * wl_apply() to allow dynamic WEP key updates through the wireless
1219 * lp - a pointer to the wireless adapter's private structure
1225 ******************************************************************************/
1226 void wl_set_wep_keys( struct wl_private *lp )
1230 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1231 if ( lp->EnableEncryption ) {
1232 /* NOTE: CFG_CNF_ENCRYPTION is set in wl_put_ltv() as it's a static
1236 lp->ltvRecord.len = 2;
1237 lp->ltvRecord.typ = CFG_TX_KEY_ID;
1238 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE(lp->TransmitKeyID - 1);
1240 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1242 DBG_TRACE( DbgInfo, "Key 1 len: %d\n", lp->DefaultKeys.key[0].len );
1243 DBG_TRACE( DbgInfo, "Key 2 len: %d\n", lp->DefaultKeys.key[1].len );
1244 DBG_TRACE( DbgInfo, "Key 3 len: %d\n", lp->DefaultKeys.key[2].len );
1245 DBG_TRACE( DbgInfo, "Key 4 len: %d\n", lp->DefaultKeys.key[3].len );
1248 lp->DefaultKeys.len = sizeof( lp->DefaultKeys ) / sizeof( hcf_16 ) - 1;
1249 lp->DefaultKeys.typ = CFG_DEFAULT_KEYS;
1251 /* endian translate the appropriate key information */
1252 for( count = 0; count < MAX_KEYS; count++ ) {
1253 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1256 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->DefaultKeys ));
1258 /* Reverse the above endian translation, since these keys are accessed
1260 for( count = 0; count < MAX_KEYS; count++ ) {
1261 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1264 DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption, lp->TransmitKeyID );
1265 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 );
1268 DBG_LEAVE( DbgInfo );
1269 } // wl_set_wep_keys
1270 /*============================================================================*/
1273 /*******************************************************************************
1275 *******************************************************************************
1279 * Write the parameters to the adapter. (re-)enables the card if device is
1280 * open. Returns hcf_status of hcf_enable().
1284 * lp - a pointer to the wireless adapter's private structure
1288 * an HCF status code
1290 ******************************************************************************/
1291 int wl_apply(struct wl_private *lp)
1293 int hcf_status = HCF_SUCCESS;
1295 DBG_ASSERT( lp != NULL);
1296 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1298 if ( !( lp->flags & WVLAN2_UIL_BUSY )) {
1299 /* The adapter parameters have changed:
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 );
1313 hcf_status = wl_disable( lp );
1314 if ( hcf_status != HCF_SUCCESS ) {
1315 DBG_ERROR( DbgInfo, "Disable failed\n" );
1316 DBG_LEAVE( DbgInfo );
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
1323 hcf_status = wl_put_ltv( lp );
1325 if ( hcf_status == HCF_SUCCESS ) {
1326 hcf_status = wl_enable( lp );
1328 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1329 hcf_status = wl_connect( lp );
1332 DBG_WARNING( DbgInfo, "wl_put_ltv() failed\n" );
1338 DBG_LEAVE( DbgInfo );
1341 /*============================================================================*/
1344 /*******************************************************************************
1346 *******************************************************************************
1350 * Used to set basic parameters for card initialization.
1354 * lp - a pointer to the wireless adapter's private structure
1358 * an HCF status code
1360 ******************************************************************************/
1361 int wl_put_ltv_init( struct wl_private *lp )
1365 CFG_RID_LOG_STRCT *RidLog;
1368 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1369 DBG_LEAVE( DbgInfo );
1373 lp->ltvRecord.len = 2;
1374 lp->ltvRecord.typ = CFG_CNTL_OPT;
1376 /* The Card Services build must ALWAYS be configured for 16-bit I/O. PCI or
1377 CardBus can be set to either 16/32 bit I/O, or Bus Master DMA, but only
1380 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_16BIT );
1382 if ( lp->use_dma ) {
1383 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_DMA );
1385 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1389 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1390 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT : 0x%04x\n",
1391 lp->ltvRecord.u.u16[0] );
1392 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT result : 0x%04x\n",
1395 /* Register the list of RIDs on which asynchronous notification is
1396 required. Note that this mechanism replaces the mailbox, so the mailbox
1397 can be queried by the host (if desired) without contention from us */
1400 lp->RidList[i].len = sizeof( lp->ProbeResp );
1401 lp->RidList[i].typ = CFG_ACS_SCAN;
1402 lp->RidList[i].bufp = (wci_recordp)&lp->ProbeResp;
1403 //lp->ProbeResp.infoType = 0xFFFF;
1406 lp->RidList[i].len = sizeof( lp->assoc_stat );
1407 lp->RidList[i].typ = CFG_ASSOC_STAT;
1408 lp->RidList[i].bufp = (wci_recordp)&lp->assoc_stat;
1409 lp->assoc_stat.len = 0xFFFF;
1412 lp->RidList[i].len = 4;
1413 lp->RidList[i].typ = CFG_UPDATED_INFO_RECORD;
1414 lp->RidList[i].bufp = (wci_recordp)&lp->updatedRecord;
1415 lp->updatedRecord.len = 0xFFFF;
1418 lp->RidList[i].len = sizeof( lp->sec_stat );
1419 lp->RidList[i].typ = CFG_SECURITY_STAT;
1420 lp->RidList[i].bufp = (wci_recordp)&lp->sec_stat;
1421 lp->sec_stat.len = 0xFFFF;
1424 lp->RidList[i].typ = 0; // Terminate List
1426 RidLog = (CFG_RID_LOG_STRCT *)&lp->ltvRecord;
1428 RidLog->typ = CFG_REG_INFO_LOG;
1429 RidLog->recordp = (RID_LOGP)&lp->RidList[0];
1431 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1432 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG\n" );
1433 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG result : 0x%04x\n",
1435 DBG_LEAVE( DbgInfo );
1437 } // wl_put_ltv_init
1438 /*============================================================================*/
1441 /*******************************************************************************
1443 *******************************************************************************
1447 * Used by wvlan_apply() and wvlan_go to set the card's configuration.
1451 * lp - a pointer to the wireless adapter's private structure
1455 * an HCF status code
1457 ******************************************************************************/
1458 int wl_put_ltv( struct wl_private *lp )
1464 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1467 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1468 lp->maxPort = 6; //;?why set this here and not as part of download process
1473 /* Send our configuration to the card. Perform any endian translation
1475 /* Register the Mailbox; VxWorks does this elsewhere; why;? */
1476 lp->ltvRecord.len = 4;
1477 lp->ltvRecord.typ = CFG_REG_MB;
1478 lp->ltvRecord.u.u32[0] = (u_long)&( lp->mailbox );
1479 lp->ltvRecord.u.u16[2] = ( MB_SIZE / sizeof( hcf_16 ));
1480 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1482 /* Max Data Length */
1483 lp->ltvRecord.len = 2;
1484 lp->ltvRecord.typ = CFG_CNF_MAX_DATA_LEN;
1485 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( HCF_MAX_PACKET_SIZE );
1486 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1488 /* System Scale / Distance between APs */
1489 lp->ltvRecord.len = 2;
1490 lp->ltvRecord.typ = CFG_CNF_SYSTEM_SCALE;
1491 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DistanceBetweenAPs );
1492 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1495 if ( lp->CreateIBSS && ( lp->Channel == 0 )) {
1496 DBG_TRACE( DbgInfo, "Create IBSS" );
1499 lp->ltvRecord.len = 2;
1500 lp->ltvRecord.typ = CFG_CNF_OWN_CHANNEL;
1501 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->Channel );
1502 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1504 /* Microwave Robustness */
1505 lp->ltvRecord.len = 2;
1506 lp->ltvRecord.typ = CFG_CNF_MICRO_WAVE;
1507 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MicrowaveRobustness );
1508 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1510 /* Load Balancing */
1511 lp->ltvRecord.len = 2;
1512 lp->ltvRecord.typ = CFG_CNF_LOAD_BALANCING;
1513 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->loadBalancing );
1514 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1516 /* Medium Distribution */
1517 lp->ltvRecord.len = 2;
1518 lp->ltvRecord.typ = CFG_CNF_MEDIUM_DISTRIBUTION;
1519 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->mediumDistribution );
1520 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1524 /* Tx Power Level (for supported cards) */
1525 lp->ltvRecord.len = 2;
1526 lp->ltvRecord.typ = CFG_CNF_TX_POW_LVL;
1527 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->txPowLevel );
1528 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1530 /* Short Retry Limit */
1531 /*lp->ltvRecord.len = 2;
1532 lp->ltvRecord.typ = 0xFC32;
1533 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->shortRetryLimit );
1534 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1537 /* Long Retry Limit */
1538 /*lp->ltvRecord.len = 2;
1539 lp->ltvRecord.typ = 0xFC33;
1540 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->longRetryLimit );
1541 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1544 /* Supported Rate Set Control */
1545 lp->ltvRecord.len = 3;
1546 lp->ltvRecord.typ = CFG_SUPPORTED_RATE_SET_CNTL; //0xFC88;
1547 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->srsc[0] );
1548 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->srsc[1] );
1549 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1551 /* Basic Rate Set Control */
1552 lp->ltvRecord.len = 3;
1553 lp->ltvRecord.typ = CFG_BASIC_RATE_SET_CNTL; //0xFC89;
1554 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->brsc[0] );
1555 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->brsc[1] );
1556 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1558 /* Frame Burst Limit */
1559 /* Defined, but not currently available in Firmware */
1564 /* Multicast Rate */
1565 lp->ltvRecord.len = 3;
1566 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1567 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1568 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->MulticastRate[1] );
1570 lp->ltvRecord.len = 2;
1571 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1572 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1574 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1576 /* Own Name (Station Nickname) */
1577 if (( len = ( strlen( lp->StationName ) + 1 ) & ~0x01 ) != 0 ) {
1578 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : %s\n",
1579 // lp->StationName );
1581 lp->ltvRecord.len = 2 + ( len / sizeof( hcf_16 ));
1582 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1583 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->StationName ));
1585 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->StationName, len );
1587 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : EMPTY\n" );
1589 lp->ltvRecord.len = 2;
1590 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1591 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1594 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1596 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME result : 0x%04x\n",
1599 /* The following are set in STA mode only */
1600 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1603 lp->ltvRecord.len = 2;
1604 lp->ltvRecord.typ = CFG_RTS_THRH;
1605 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1606 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1609 lp->ltvRecord.len = 2;
1610 lp->ltvRecord.typ = CFG_CNF_PORT_TYPE;
1611 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PortType );
1612 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1614 /* Tx Rate Control */
1616 lp->ltvRecord.len = 3;
1617 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1618 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1619 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1621 lp->ltvRecord.len = 2;
1622 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1623 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1626 //;?skip temporarily to see whether the RID or something else is the problem hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1628 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 2.4GHz : 0x%04x\n",
1629 lp->TxRateControl[0] );
1630 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 5.0GHz : 0x%04x\n",
1631 lp->TxRateControl[1] );
1632 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL result : 0x%04x\n",
1634 /* Power Management */
1635 lp->ltvRecord.len = 2;
1636 lp->ltvRecord.typ = CFG_CNF_PM_ENABLED;
1637 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PMEnabled );
1638 // lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0x8001 );
1639 DBG_TRACE( DbgInfo, "CFG_CNF_PM_ENABLED : 0x%04x\n", lp->PMEnabled );
1640 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1641 /* Multicast Receive */
1642 lp->ltvRecord.len = 2;
1643 lp->ltvRecord.typ = CFG_CNF_MCAST_RX;
1644 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastReceive );
1645 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1647 /* Max Sleep Duration */
1648 lp->ltvRecord.len = 2;
1649 lp->ltvRecord.typ = CFG_CNF_MAX_SLEEP_DURATION;
1650 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MaxSleepDuration );
1651 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1654 lp->ltvRecord.len = 2;
1655 lp->ltvRecord.typ = CFG_CREATE_IBSS;
1656 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->CreateIBSS );
1657 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1660 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1661 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1662 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1663 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : %s\n",
1664 // lp->NetworkName );
1666 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1667 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1668 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1670 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1672 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : ANY\n" );
1674 lp->ltvRecord.len = 2;
1675 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1676 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1679 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1681 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID result : 0x%04x\n",
1683 /* Own ATIM window */
1684 lp->ltvRecord.len = 2;
1685 lp->ltvRecord.typ = CFG_CNF_OWN_ATIM_WINDOW;
1686 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->atimWindow );
1687 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1690 /* Holdover Duration */
1691 lp->ltvRecord.len = 2;
1692 lp->ltvRecord.typ = CFG_CNF_HOLDOVER_DURATION;
1693 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->holdoverDuration );
1694 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1696 /* Promiscuous Mode */
1697 lp->ltvRecord.len = 2;
1698 lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
1699 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->promiscuousMode );
1700 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1702 /* Authentication */
1703 lp->ltvRecord.len = 2;
1704 lp->ltvRecord.typ = CFG_CNF_AUTHENTICATION;
1705 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->authentication );
1706 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1708 /* Connection Control */
1709 lp->ltvRecord.len = 2;
1710 lp->ltvRecord.typ = CFG_CNF_CONNECTION_CNTL;
1711 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->connectionControl );
1712 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1716 /* Probe data rate */
1717 /*lp->ltvRecord.len = 3;
1718 lp->ltvRecord.typ = CFG_PROBE_DATA_RATE;
1719 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->probeDataRates[0] );
1720 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->probeDataRates[1] );
1721 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1723 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 2.4GHz : 0x%04x\n",
1724 lp->probeDataRates[0] );
1725 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 5.0GHz : 0x%04x\n",
1726 lp->probeDataRates[1] );
1727 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE result : 0x%04x\n",
1731 /* The following are set in AP mode only */
1732 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
1733 //;?should we restore this to allow smaller memory footprint
1736 lp->ltvRecord.len = 2;
1737 lp->ltvRecord.typ = CFG_CNF_OWN_DTIM_PERIOD;
1738 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DTIMPeriod );
1739 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1741 /* Multicast PM Buffering */
1742 lp->ltvRecord.len = 2;
1743 lp->ltvRecord.typ = CFG_CNF_MCAST_PM_BUF;
1744 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->multicastPMBuffering );
1745 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1747 /* Reject ANY - Closed System */
1748 lp->ltvRecord.len = 2;
1749 lp->ltvRecord.typ = CFG_CNF_REJECT_ANY;
1750 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RejectAny );
1752 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1754 /* Exclude Unencrypted */
1755 lp->ltvRecord.len = 2;
1756 lp->ltvRecord.typ = CFG_CNF_EXCL_UNENCRYPTED;
1757 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ExcludeUnencrypted );
1759 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1761 /* IntraBSS Relay */
1762 lp->ltvRecord.len = 2;
1763 lp->ltvRecord.typ = CFG_CNF_INTRA_BSS_RELAY;
1764 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->intraBSSRelay );
1765 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1767 /* RTS Threshold 0 */
1768 lp->ltvRecord.len = 2;
1769 lp->ltvRecord.typ = CFG_RTS_THRH0;
1770 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1772 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1774 /* Tx Rate Control 0 */
1776 lp->ltvRecord.len = 3;
1777 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1778 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1779 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1781 lp->ltvRecord.len = 2;
1782 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1783 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1786 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1788 /* Own Beacon Interval */
1789 lp->ltvRecord.len = 2;
1790 lp->ltvRecord.typ = 0xFC31;
1791 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ownBeaconInterval );
1792 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1794 /* Co-Existence Behavior */
1795 lp->ltvRecord.len = 2;
1796 lp->ltvRecord.typ = 0xFCC7;
1797 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->coexistence );
1798 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1802 /* RTS Threshold 1 */
1803 lp->ltvRecord.len = 2;
1804 lp->ltvRecord.typ = CFG_RTS_THRH1;
1805 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].rtsThreshold );
1806 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1808 /* RTS Threshold 2 */
1809 lp->ltvRecord.len = 2;
1810 lp->ltvRecord.typ = CFG_RTS_THRH2;
1811 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].rtsThreshold );
1812 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1815 /* RTS Threshold 3 */
1816 lp->ltvRecord.len = 2;
1817 lp->ltvRecord.typ = CFG_RTS_THRH3;
1818 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].rtsThreshold );
1819 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1822 /* RTS Threshold 4 */
1823 lp->ltvRecord.len = 2;
1824 lp->ltvRecord.typ = CFG_RTS_THRH4;
1825 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].rtsThreshold );
1826 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1829 /* RTS Threshold 5 */
1830 lp->ltvRecord.len = 2;
1831 lp->ltvRecord.typ = CFG_RTS_THRH5;
1832 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].rtsThreshold );
1833 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1835 /* RTS Threshold 6 */
1836 lp->ltvRecord.len = 2;
1837 lp->ltvRecord.typ = CFG_RTS_THRH6;
1838 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].rtsThreshold );
1839 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1841 /* TX Rate Control 1 */
1842 lp->ltvRecord.len = 2;
1843 lp->ltvRecord.typ = CFG_TX_RATE_CNTL1;
1844 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].txRateCntl );
1845 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1847 /* TX Rate Control 2 */
1848 lp->ltvRecord.len = 2;
1849 lp->ltvRecord.typ = CFG_TX_RATE_CNTL2;
1850 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].txRateCntl );
1851 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1853 /* TX Rate Control 3 */
1854 lp->ltvRecord.len = 2;
1855 lp->ltvRecord.typ = CFG_TX_RATE_CNTL3;
1856 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].txRateCntl );
1857 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1859 /* TX Rate Control 4 */
1860 lp->ltvRecord.len = 2;
1861 lp->ltvRecord.typ = CFG_TX_RATE_CNTL4;
1862 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].txRateCntl );
1863 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1865 /* TX Rate Control 5 */
1866 lp->ltvRecord.len = 2;
1867 lp->ltvRecord.typ = CFG_TX_RATE_CNTL5;
1868 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].txRateCntl );
1869 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1871 /* TX Rate Control 6 */
1872 lp->ltvRecord.len = 2;
1873 lp->ltvRecord.typ = CFG_TX_RATE_CNTL6;
1874 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].txRateCntl );
1875 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1879 /* WDS addresses. It's okay to blindly send these parameters, because
1880 the port needs to be enabled, before anything is done with it. */
1883 lp->ltvRecord.len = 4;
1884 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR1;
1886 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[0].wdsAddress, ETH_ALEN );
1887 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1890 lp->ltvRecord.len = 4;
1891 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR2;
1893 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[1].wdsAddress, ETH_ALEN );
1894 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1897 lp->ltvRecord.len = 4;
1898 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR3;
1900 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[2].wdsAddress, ETH_ALEN );
1901 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1904 lp->ltvRecord.len = 4;
1905 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR4;
1907 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[3].wdsAddress, ETH_ALEN );
1908 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1911 lp->ltvRecord.len = 4;
1912 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR5;
1914 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[4].wdsAddress, ETH_ALEN );
1915 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1918 lp->ltvRecord.len = 4;
1919 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR6;
1921 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[5].wdsAddress, ETH_ALEN );
1922 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1923 #endif /* USE_WDS */
1924 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1927 /* Own MAC Address */
1929 DBG_TRACE(DbgInfo, "MAC Address : %pM\n",
1933 if ( WVLAN_VALID_MAC_ADDRESS( lp->MACAddress )) {
1934 /* Make the MAC address valid by:
1935 Clearing the multicast bit
1936 Setting the local MAC address bit
1938 //lp->MACAddress[0] &= ~0x03; //;?why is this commented out already in 720
1939 //lp->MACAddress[0] |= 0x02;
1941 lp->ltvRecord.len = 1 + ( ETH_ALEN / sizeof( hcf_16 ));
1942 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1943 //DBG_TRACE( DbgInfo, "CFG_NIC_MAC_ADDR\n" );
1944 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1946 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_MAC_ADDR\n" );
1947 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1949 /* MAC address is byte aligned, no endian conversion needed */
1950 memcpy( &( lp->ltvRecord.u.u8[0] ), lp->MACAddress, ETH_ALEN );
1951 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1952 //DBG_TRACE( DbgInfo, "CFG_XXX_MAC_ADDR result : 0x%04x\n",
1955 /* Update the MAC address in the netdevice struct */
1956 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN ); //;?what is the purpose of this seemingly complex logic
1959 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1960 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1961 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1962 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : %s\n",
1963 // lp->NetworkName );
1964 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1965 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1966 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1968 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1970 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : ANY\n" );
1971 lp->ltvRecord.len = 2;
1972 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1973 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1976 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1978 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID result : 0x%04x\n",
1980 /* enable/disable encryption */
1981 lp->ltvRecord.len = 2;
1982 lp->ltvRecord.typ = CFG_CNF_ENCRYPTION;
1983 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->EnableEncryption );
1984 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1986 /* Set the Authentication Key Management Suite */
1987 lp->ltvRecord.len = 2;
1988 lp->ltvRecord.typ = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
1989 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->AuthKeyMgmtSuite );
1990 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1992 /* If WEP (or no) keys are being used, write (or clear) them */
1993 if (lp->wext_enc != IW_ENCODE_ALG_TKIP)
1994 wl_set_wep_keys(lp);
1997 /* countryInfo, ltvCountryInfo, CFG_CNF_COUNTRY_INFO */
1999 DBG_LEAVE( DbgInfo );
2002 /*============================================================================*/
2005 /*******************************************************************************
2007 *******************************************************************************
2011 * Load the kernel module.
2020 * an errno value otherwise
2022 ******************************************************************************/
2023 static int __init wl_module_init( void )
2026 /*------------------------------------------------------------------------*/
2030 /* Convert "standard" PCMCIA parameter pc_debug to a reasonable DebugFlag value.
2031 * NOTE: The values all fall through to the lower values. */
2032 DbgInfo->DebugFlag = 0;
2033 DbgInfo->DebugFlag = DBG_TRACE_ON; //;?get this mess resolved one day
2034 if ( pc_debug ) switch( pc_debug ) {
2036 DbgInfo->DebugFlag |= DBG_DS_ON;
2038 DbgInfo->DebugFlag |= DBG_RX_ON | DBG_TX_ON;
2040 DbgInfo->DebugFlag |= DBG_PARAM_ON;
2042 DbgInfo->DebugFlag |= DBG_TRACE_ON;
2044 DbgInfo->DebugFlag |= DBG_VERBOSE_ON;
2046 DbgInfo->DebugFlag |= DBG_DEFAULTS;
2052 printk(KERN_INFO "%s\n", VERSION_INFO);
2053 printk(KERN_INFO "*** Modified for kernel 2.6 by Henk de Groot <pe1dnn@amsat.org>\n");
2054 printk(KERN_INFO "*** Based on 7.18 version by Andrey Borzenkov <arvidjaar@mail.ru> $Revision: 39 $\n");
2057 // ;?#if (HCF_TYPE) & HCF_TYPE_AP
2058 // DBG_PRINT( "Access Point Mode (AP) Support: YES\n" );
2060 // DBG_PRINT( "Access Point Mode (AP) Support: NO\n" );
2061 // #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2063 result = wl_adapter_init_module( );
2064 DBG_LEAVE( DbgInfo );
2067 /*============================================================================*/
2070 /*******************************************************************************
2072 *******************************************************************************
2076 * Unload the kernel module.
2086 ******************************************************************************/
2087 static void __exit wl_module_exit( void )
2089 wl_adapter_cleanup_module( );
2090 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
2091 remove_proc_entry( "wlags", NULL ); //;?why so a-symmetric compared to location of proc_create_data
2094 DBG_LEAVE( DbgInfo );
2097 /*============================================================================*/
2099 module_init(wl_module_init);
2100 module_exit(wl_module_exit);
2102 /*******************************************************************************
2104 *******************************************************************************
2108 * The Interrupt Service Routine for the driver.
2112 * irq - the irq the interrupt came in on
2113 * dev_id - a buffer containing information about the request
2120 ******************************************************************************/
2121 irqreturn_t wl_isr( int irq, void *dev_id, struct pt_regs *regs )
2124 struct net_device *dev = (struct net_device *) dev_id;
2125 struct wl_private *lp = NULL;
2126 /*------------------------------------------------------------------------*/
2127 if (( dev == NULL ) || ( !netif_device_present( dev ))) {
2131 /* Set the wl_private pointer (lp), now that we know that dev is non-null */
2135 if ( lp->useRTS == 1 ) {
2136 DBG_PRINT( "EXITING ISR, IN RTS MODE...\n" );
2139 #endif /* USE_RTS */
2141 /* If we have interrupts pending, then put them on a system task
2142 queue. Otherwise turn interrupts back on */
2143 events = hcf_action( &lp->hcfCtx, HCF_ACT_INT_OFF );
2145 if ( events == HCF_INT_PENDING ) {
2146 /* Schedule the ISR handler as a bottom-half task in the
2147 tq_immediate queue */
2148 tasklet_schedule(&lp->task);
2150 //DBG_PRINT( "NOT OUR INTERRUPT\n" );
2151 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2154 return IRQ_RETVAL(events == HCF_INT_PENDING);
2156 /*============================================================================*/
2159 /*******************************************************************************
2161 *******************************************************************************
2165 * The ISR handler, scheduled to run in a deferred context by the ISR. This
2166 * is where the ISR's work actually gets done.
2170 * lp - a pointer to the device's private adapter structure
2176 ******************************************************************************/
2177 #define WVLAN_MAX_INT_SERVICES 50
2179 void wl_isr_handler( unsigned long p )
2181 struct net_device *dev;
2182 unsigned long flags;
2186 struct wl_private *lp = (struct wl_private *)p;
2187 /*------------------------------------------------------------------------*/
2190 DBG_PRINT( "wl_isr_handler lp adapter pointer is NULL!!!\n" );
2192 wl_lock( lp, &flags );
2194 dev = (struct net_device *)lp->dev;
2195 if ( dev != NULL && netif_device_present( dev ) ) stop = FALSE;
2196 for( count = 0; stop == FALSE && count < WVLAN_MAX_INT_SERVICES; count++ ) {
2198 result = hcf_service_nic( &lp->hcfCtx,
2199 (wci_bufp)lp->lookAheadBuf,
2200 sizeof( lp->lookAheadBuf ));
2201 if ( result == HCF_ERR_MIC ) {
2202 wl_wext_event_mic_failed( dev ); /* Send an event that MIC failed */
2203 //;?this seems wrong if HCF_ERR_MIC coincides with another event, stop gets FALSE
2204 //so why not do it always ;?
2207 #ifndef USE_MBOX_SYNC
2208 if ( lp->hcfCtx.IFB_MBInfoLen != 0 ) { /* anything in the mailbox */
2213 /* Check for a Link status event */
2214 if ( ( lp->hcfCtx.IFB_LinkStat & CFG_LINK_STAT_FW ) != 0 ) {
2215 wl_process_link_status( lp );
2218 /* Check for probe response events */
2219 if ( lp->ProbeResp.infoType != 0 &&
2220 lp->ProbeResp.infoType != 0xFFFF ) {
2221 wl_process_probe_response( lp );
2222 memset( &lp->ProbeResp, 0, sizeof( lp->ProbeResp ));
2223 lp->ProbeResp.infoType = 0xFFFF;
2226 /* Check for updated record events */
2227 if ( lp->updatedRecord.len != 0xFFFF ) {
2228 wl_process_updated_record( lp );
2229 lp->updatedRecord.len = 0xFFFF;
2232 /* Check for association status events */
2233 if ( lp->assoc_stat.len != 0xFFFF ) {
2234 wl_process_assoc_status( lp );
2235 lp->assoc_stat.len = 0xFFFF;
2238 /* Check for security status events */
2239 if ( lp->sec_stat.len != 0xFFFF ) {
2240 wl_process_security_status( lp );
2241 lp->sec_stat.len = 0xFFFF;
2246 if ( lp->use_dma ) {
2247 /* Check for DMA Rx packets */
2248 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_RDMAD ) {
2252 /* Return Tx DMA descriptors to host */
2253 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_TDMAD ) {
2254 wl_pci_dma_hcf_reclaim_tx( lp );
2259 #endif // ENABLE_DMA
2261 /* Check for Rx packets */
2262 if ( lp->hcfCtx.IFB_RxLen != 0 ) {
2266 /* Make sure that queued frames get sent */
2267 if ( wl_send( lp )) {
2272 /* We're done, so turn interrupts which were turned off in wl_isr, back on */
2273 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2274 wl_unlock( lp, &flags );
2278 /*============================================================================*/
2281 /*******************************************************************************
2283 *******************************************************************************
2287 * Notify the adapter that it has been removed. Since the adapter is gone,
2288 * we should no longer try to talk to it.
2292 * dev - a pointer to the device's net_device structure
2298 ******************************************************************************/
2299 void wl_remove( struct net_device *dev )
2301 struct wl_private *lp = wl_priv(dev);
2302 unsigned long flags;
2304 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2306 wl_lock( lp, &flags );
2308 /* stop handling interrupts */
2309 wl_act_int_off( lp );
2310 lp->is_handling_int = WL_NOT_HANDLING_INT;
2313 * Disable the ports: just change state: since the
2314 * card is gone it is useless to talk to it and at
2315 * disconnect all state information is lost anyway.
2317 /* Reset portState */
2318 lp->portState = WVLAN_PORT_STATE_DISABLED;
2320 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
2322 //wl_disable_wds_ports( lp );
2324 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2326 /* Mark the device as unregistered */
2327 lp->is_registered = FALSE;
2329 /* Deregister the WDS ports as well */
2330 WL_WDS_NETDEV_DEREGISTER( lp );
2332 if ( lp->useRTS == 1 ) {
2333 wl_unlock( lp, &flags );
2335 DBG_LEAVE( DbgInfo );
2338 #endif /* USE_RTS */
2340 /* Inform the HCF that the card has been removed */
2341 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2343 wl_unlock( lp, &flags );
2345 DBG_LEAVE( DbgInfo );
2348 /*============================================================================*/
2351 /*******************************************************************************
2353 *******************************************************************************
2357 * Power-down and halt the adapter.
2361 * dev - a pointer to the device's net_device structure
2367 ******************************************************************************/
2368 void wl_suspend( struct net_device *dev )
2370 struct wl_private *lp = wl_priv(dev);
2371 unsigned long flags;
2373 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2375 /* The adapter is suspended:
2379 wl_lock( lp, &flags );
2381 /* Disable interrupt handling */
2382 wl_act_int_off( lp );
2385 wl_disconnect( lp );
2390 /* Disconnect from the adapter */
2391 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2393 /* Reset portState to be sure (should have been done by wl_disable */
2394 lp->portState = WVLAN_PORT_STATE_DISABLED;
2396 wl_unlock( lp, &flags );
2398 DBG_LEAVE( DbgInfo );
2401 /*============================================================================*/
2404 /*******************************************************************************
2406 *******************************************************************************
2410 * Resume a previously suspended adapter.
2414 * dev - a pointer to the device's net_device structure
2420 ******************************************************************************/
2421 void wl_resume(struct net_device *dev)
2423 struct wl_private *lp = wl_priv(dev);
2424 unsigned long flags;
2426 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2428 wl_lock( lp, &flags );
2430 /* Connect to the adapter */
2431 hcf_connect( &lp->hcfCtx, dev->base_addr );
2433 /* Reset portState */
2434 lp->portState = WVLAN_PORT_STATE_DISABLED;
2436 /* Power might have been off, assume the card lost the firmware*/
2437 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
2439 /* Reload the firmware and restart */
2442 /* Resume interrupt handling */
2443 wl_act_int_on( lp );
2445 wl_unlock( lp, &flags );
2447 DBG_LEAVE( DbgInfo );
2450 /*============================================================================*/
2453 /*******************************************************************************
2455 *******************************************************************************
2459 * This function performs a check on the device and calls wl_remove() if
2460 * necessary. This function can be used for all bus types, but exists mostly
2461 * for the benefit of the Card Services driver, as there are times when
2462 * wl_remove() does not get called.
2466 * dev - a pointer to the device's net_device structure
2472 ******************************************************************************/
2473 void wl_release( struct net_device *dev )
2475 struct wl_private *lp = wl_priv(dev);
2477 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2478 /* If wl_remove() hasn't been called (i.e. when Card Services is shut
2479 down with the card in the slot), then call it */
2480 if ( lp->is_registered == TRUE ) {
2481 DBG_TRACE( DbgInfo, "Calling unregister_netdev(), as it wasn't called yet\n" );
2484 lp->is_registered = FALSE;
2487 DBG_LEAVE( DbgInfo );
2490 /*============================================================================*/
2493 /*******************************************************************************
2495 *******************************************************************************
2499 * Accessor function to retrieve the irq_mask module parameter
2507 * The irq_mask module parameter
2509 ******************************************************************************/
2510 p_u16 wl_get_irq_mask( void )
2513 } // wl_get_irq_mask
2514 /*============================================================================*/
2517 /*******************************************************************************
2519 *******************************************************************************
2523 * Accessor function to retrieve the irq_list module parameter
2531 * The irq_list module parameter
2533 ******************************************************************************/
2534 p_s8 * wl_get_irq_list( void )
2537 } // wl_get_irq_list
2538 /*============================================================================*/
2542 /*******************************************************************************
2544 *******************************************************************************
2548 * Used to enable MAC ports
2552 * lp - pointer to the device's private adapter structure
2558 ******************************************************************************/
2559 int wl_enable( struct wl_private *lp )
2561 int hcf_status = HCF_SUCCESS;
2563 if ( lp->portState == WVLAN_PORT_STATE_ENABLED ) {
2564 DBG_TRACE( DbgInfo, "No action: Card already enabled\n" );
2565 } else if ( lp->portState == WVLAN_PORT_STATE_CONNECTED ) {
2566 //;?suspicuous logic, how can you be connected without being enabled so this is probably dead code
2567 DBG_TRACE( DbgInfo, "No action: Card already connected\n" );
2569 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_ENABLE );
2570 if ( hcf_status == HCF_SUCCESS ) {
2571 /* Set the status of the NIC to enabled */
2572 lp->portState = WVLAN_PORT_STATE_ENABLED; //;?bad mnemonic, NIC iso PORT
2574 if ( lp->use_dma ) {
2575 wl_pci_dma_hcf_supply( lp ); //;?always successful?
2580 if ( hcf_status != HCF_SUCCESS ) { //;?make this an assert
2581 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2583 DBG_LEAVE( DbgInfo );
2586 /*============================================================================*/
2590 /*******************************************************************************
2591 * wl_enable_wds_ports()
2592 *******************************************************************************
2596 * Used to enable the WDS MAC ports 1-6
2600 * lp - pointer to the device's private adapter structure
2606 ******************************************************************************/
2607 void wl_enable_wds_ports( struct wl_private * lp )
2609 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2610 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2612 DBG_LEAVE( DbgInfo );
2614 } // wl_enable_wds_ports
2615 #endif /* USE_WDS */
2616 /*============================================================================*/
2619 /*******************************************************************************
2621 *******************************************************************************
2625 * Used to connect a MAC port
2629 * lp - pointer to the device's private adapter structure
2635 ******************************************************************************/
2636 int wl_connect( struct wl_private *lp )
2640 if ( lp->portState != WVLAN_PORT_STATE_ENABLED ) {
2641 DBG_TRACE( DbgInfo, "No action: Not in enabled state\n" );
2642 DBG_LEAVE( DbgInfo );
2645 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_CONNECT );
2646 if ( hcf_status == HCF_SUCCESS ) {
2647 lp->portState = WVLAN_PORT_STATE_CONNECTED;
2649 DBG_LEAVE( DbgInfo );
2652 /*============================================================================*/
2655 /*******************************************************************************
2657 *******************************************************************************
2661 * Used to disconnect a MAC port
2665 * lp - pointer to the device's private adapter structure
2671 ******************************************************************************/
2672 int wl_disconnect( struct wl_private *lp )
2676 if ( lp->portState != WVLAN_PORT_STATE_CONNECTED ) {
2677 DBG_TRACE( DbgInfo, "No action: Not in connected state\n" );
2678 DBG_LEAVE( DbgInfo );
2681 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISCONNECT );
2682 if ( hcf_status == HCF_SUCCESS ) {
2683 lp->portState = WVLAN_PORT_STATE_ENABLED;
2685 DBG_LEAVE( DbgInfo );
2688 /*============================================================================*/
2691 /*******************************************************************************
2693 *******************************************************************************
2697 * Used to disable MAC ports
2701 * lp - pointer to the device's private adapter structure
2702 * port - the MAC port to disable
2708 ******************************************************************************/
2709 int wl_disable( struct wl_private *lp )
2711 int hcf_status = HCF_SUCCESS;
2713 if ( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
2714 DBG_TRACE( DbgInfo, "No action: Port state is disabled\n" );
2716 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISABLE );
2717 if ( hcf_status == HCF_SUCCESS ) {
2718 /* Set the status of the port to disabled */ //;?bad mnemonic use NIC iso PORT
2719 lp->portState = WVLAN_PORT_STATE_DISABLED;
2722 if ( lp->use_dma ) {
2723 wl_pci_dma_hcf_reclaim( lp );
2728 if ( hcf_status != HCF_SUCCESS ) {
2729 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2731 DBG_LEAVE( DbgInfo );
2734 /*============================================================================*/
2738 /*******************************************************************************
2739 * wl_disable_wds_ports()
2740 *******************************************************************************
2744 * Used to disable the WDS MAC ports 1-6
2748 * lp - pointer to the device's private adapter structure
2754 ******************************************************************************/
2755 void wl_disable_wds_ports( struct wl_private * lp )
2757 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2758 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2760 // if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
2761 // wl_disable( lp, HCF_PORT_1 );
2762 // wl_disable( lp, HCF_PORT_2 );
2763 // wl_disable( lp, HCF_PORT_3 );
2764 // wl_disable( lp, HCF_PORT_4 );
2765 // wl_disable( lp, HCF_PORT_5 );
2766 // wl_disable( lp, HCF_PORT_6 );
2768 DBG_LEAVE( DbgInfo );
2770 } // wl_disable_wds_ports
2772 /*============================================================================*/
2775 #ifndef USE_MBOX_SYNC
2776 /*******************************************************************************
2778 *******************************************************************************
2781 * This function is used to read and process a mailbox message.
2786 * lp - pointer to the device's private adapter structure
2790 * an HCF status code
2792 ******************************************************************************/
2793 int wl_mbx( struct wl_private *lp )
2795 int hcf_status = HCF_SUCCESS;
2797 DBG_TRACE( DbgInfo, "Mailbox Info: IFB_MBInfoLen: %d\n",
2798 lp->hcfCtx.IFB_MBInfoLen );
2800 memset( &( lp->ltvRecord ), 0, sizeof( ltv_t ));
2802 lp->ltvRecord.len = MB_SIZE;
2803 lp->ltvRecord.typ = CFG_MB_INFO;
2804 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2806 if ( hcf_status != HCF_SUCCESS ) {
2807 DBG_ERROR( DbgInfo, "hcf_get_info returned 0x%x\n", hcf_status );
2809 DBG_LEAVE( DbgInfo );
2813 if ( lp->ltvRecord.typ == CFG_MB_INFO ) {
2814 DBG_LEAVE( DbgInfo );
2817 /* Endian translate the mailbox data, then process the message */
2818 wl_endian_translate_mailbox( &( lp->ltvRecord ));
2819 wl_process_mailbox( lp );
2820 DBG_LEAVE( DbgInfo );
2823 /*============================================================================*/
2826 /*******************************************************************************
2827 * wl_endian_translate_mailbox()
2828 *******************************************************************************
2832 * This function will perform the tedious task of endian translating all
2833 * fields within a mailbox message which need translating.
2837 * ltv - pointer to the LTV to endian translate
2843 ******************************************************************************/
2844 void wl_endian_translate_mailbox( ltv_t *ltv )
2846 switch( ltv->typ ) {
2853 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
2855 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2856 ( sizeof( SCAN_RS_STRCT )));
2858 while( num_aps >= 1 ) {
2861 aps[num_aps].channel_id =
2862 CNV_LITTLE_TO_INT( aps[num_aps].channel_id );
2864 aps[num_aps].noise_level =
2865 CNV_LITTLE_TO_INT( aps[num_aps].noise_level );
2867 aps[num_aps].signal_level =
2868 CNV_LITTLE_TO_INT( aps[num_aps].signal_level );
2870 aps[num_aps].beacon_interval_time =
2871 CNV_LITTLE_TO_INT( aps[num_aps].beacon_interval_time );
2873 aps[num_aps].capability =
2874 CNV_LITTLE_TO_INT( aps[num_aps].capability );
2876 aps[num_aps].ssid_len =
2877 CNV_LITTLE_TO_INT( aps[num_aps].ssid_len );
2879 aps[num_aps].ssid_val[aps[num_aps].ssid_len] = 0;
2886 PROBE_RESP *probe_resp = (PROBE_RESP *)ltv;
2888 probe_resp->frameControl = CNV_LITTLE_TO_INT( probe_resp->frameControl );
2889 probe_resp->durID = CNV_LITTLE_TO_INT( probe_resp->durID );
2890 probe_resp->sequence = CNV_LITTLE_TO_INT( probe_resp->sequence );
2891 probe_resp->dataLength = CNV_LITTLE_TO_INT( probe_resp->dataLength );
2893 probe_resp->lenType = CNV_LITTLE_TO_INT( probe_resp->lenType );
2895 probe_resp->beaconInterval = CNV_LITTLE_TO_INT( probe_resp->beaconInterval );
2896 probe_resp->capability = CNV_LITTLE_TO_INT( probe_resp->capability );
2897 probe_resp->flags = CNV_LITTLE_TO_INT( probe_resp->flags );
2902 #define ls ((LINK_STATUS_STRCT *)ltv)
2903 ls->linkStatus = CNV_LITTLE_TO_INT( ls->linkStatus );
2907 case CFG_ASSOC_STAT:
2909 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
2911 as->assocStatus = CNV_LITTLE_TO_INT( as->assocStatus );
2915 case CFG_SECURITY_STAT:
2917 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
2919 ss->securityStatus = CNV_LITTLE_TO_INT( ss->securityStatus );
2920 ss->reason = CNV_LITTLE_TO_INT( ss->reason );
2934 DBG_LEAVE( DbgInfo );
2936 } // wl_endian_translate_mailbox
2937 /*============================================================================*/
2939 /*******************************************************************************
2940 * wl_process_mailbox()
2941 *******************************************************************************
2945 * This function processes the mailbox data.
2949 * ltv - pointer to the LTV to be processed.
2955 ******************************************************************************/
2956 void wl_process_mailbox( struct wl_private *lp )
2959 hcf_16 ltv_val = 0xFFFF;
2961 ltv = &( lp->ltvRecord );
2963 switch( ltv->typ ) {
2966 DBG_TRACE( DbgInfo, "CFG_TALLIES\n" );
2969 DBG_TRACE( DbgInfo, "CFG_SCAN\n" );
2973 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
2975 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2976 ( sizeof( SCAN_RS_STRCT )));
2978 lp->scan_results.num_aps = num_aps;
2980 DBG_TRACE( DbgInfo, "Number of APs: %d\n", num_aps );
2982 while( num_aps >= 1 ) {
2985 DBG_TRACE( DbgInfo, "AP : %d\n", num_aps );
2986 DBG_TRACE( DbgInfo, "=========================\n" );
2987 DBG_TRACE( DbgInfo, "Channel ID : 0x%04x\n",
2988 aps[num_aps].channel_id );
2989 DBG_TRACE( DbgInfo, "Noise Level : 0x%04x\n",
2990 aps[num_aps].noise_level );
2991 DBG_TRACE( DbgInfo, "Signal Level : 0x%04x\n",
2992 aps[num_aps].signal_level );
2993 DBG_TRACE( DbgInfo, "Beacon Interval : 0x%04x\n",
2994 aps[num_aps].beacon_interval_time );
2995 DBG_TRACE( DbgInfo, "Capability : 0x%04x\n",
2996 aps[num_aps].capability );
2997 DBG_TRACE( DbgInfo, "SSID Length : 0x%04x\n",
2998 aps[num_aps].ssid_len );
2999 DBG_TRACE(DbgInfo, "BSSID : %pM\n",
3000 aps[num_aps].bssid);
3002 if ( aps[num_aps].ssid_len != 0 ) {
3003 DBG_TRACE( DbgInfo, "SSID : %s.\n",
3004 aps[num_aps].ssid_val );
3006 DBG_TRACE( DbgInfo, "SSID : %s.\n", "ANY" );
3009 DBG_TRACE( DbgInfo, "\n" );
3011 /* Copy the info to the ScanResult structure in the private
3013 memcpy( &( lp->scan_results.APTable[num_aps]), &( aps[num_aps] ),
3014 sizeof( SCAN_RS_STRCT ));
3017 /* Set scan result to true so that any scan requests will
3019 lp->scan_results.scan_complete = TRUE;
3024 DBG_TRACE( DbgInfo, "CFG_ACS_SCAN\n" );
3027 PROBE_RESP *probe_rsp = (PROBE_RESP *)ltv;
3028 hcf_8 *wpa_ie = NULL;
3029 hcf_16 wpa_ie_len = 0;
3031 DBG_TRACE( DbgInfo, "(%s) =========================\n",
3034 DBG_TRACE( DbgInfo, "(%s) length : 0x%04x.\n",
3035 lp->dev->name, probe_rsp->length );
3037 if ( probe_rsp->length > 1 ) {
3038 DBG_TRACE( DbgInfo, "(%s) infoType : 0x%04x.\n",
3039 lp->dev->name, probe_rsp->infoType );
3041 DBG_TRACE( DbgInfo, "(%s) signal : 0x%02x.\n",
3042 lp->dev->name, probe_rsp->signal );
3044 DBG_TRACE( DbgInfo, "(%s) silence : 0x%02x.\n",
3045 lp->dev->name, probe_rsp->silence );
3047 DBG_TRACE( DbgInfo, "(%s) rxFlow : 0x%02x.\n",
3048 lp->dev->name, probe_rsp->rxFlow );
3050 DBG_TRACE( DbgInfo, "(%s) rate : 0x%02x.\n",
3051 lp->dev->name, probe_rsp->rate );
3053 DBG_TRACE( DbgInfo, "(%s) frame cntl : 0x%04x.\n",
3054 lp->dev->name, probe_rsp->frameControl );
3056 DBG_TRACE( DbgInfo, "(%s) durID : 0x%04x.\n",
3057 lp->dev->name, probe_rsp->durID );
3059 DBG_TRACE(DbgInfo, "(%s) address1 : %pM\n",
3060 lp->dev->name, probe_rsp->address1);
3062 DBG_TRACE(DbgInfo, "(%s) address2 : %pM\n",
3063 lp->dev->name, probe_rsp->address2);
3065 DBG_TRACE(DbgInfo, "(%s) BSSID : %pM\n",
3066 lp->dev->name, probe_rsp->BSSID);
3068 DBG_TRACE( DbgInfo, "(%s) sequence : 0x%04x.\n",
3069 lp->dev->name, probe_rsp->sequence );
3071 DBG_TRACE(DbgInfo, "(%s) address4 : %pM\n",
3072 lp->dev->name, probe_rsp->address4);
3074 DBG_TRACE( DbgInfo, "(%s) datalength : 0x%04x.\n",
3075 lp->dev->name, probe_rsp->dataLength );
3077 DBG_TRACE(DbgInfo, "(%s) DA : %pM\n",
3078 lp->dev->name, probe_rsp->DA);
3080 DBG_TRACE(DbgInfo, "(%s) SA : %pM\n",
3081 lp->dev->name, probe_rsp->SA);
3083 //DBG_TRACE( DbgInfo, "(%s) lenType : 0x%04x.\n",
3084 // lp->dev->name, probe_rsp->lenType );
3086 DBG_TRACE(DbgInfo, "(%s) timeStamp : "
3087 "%d.%d.%d.%d.%d.%d.%d.%d\n",
3089 probe_rsp->timeStamp[0],
3090 probe_rsp->timeStamp[1],
3091 probe_rsp->timeStamp[2],
3092 probe_rsp->timeStamp[3],
3093 probe_rsp->timeStamp[4],
3094 probe_rsp->timeStamp[5],
3095 probe_rsp->timeStamp[6],
3096 probe_rsp->timeStamp[7]);
3098 DBG_TRACE( DbgInfo, "(%s) beaconInt : 0x%04x.\n",
3099 lp->dev->name, probe_rsp->beaconInterval );
3101 DBG_TRACE( DbgInfo, "(%s) capability : 0x%04x.\n",
3102 lp->dev->name, probe_rsp->capability );
3104 DBG_TRACE( DbgInfo, "(%s) SSID len : 0x%04x.\n",
3105 lp->dev->name, probe_rsp->rawData[1] );
3107 if ( probe_rsp->rawData[1] > 0 ) {
3108 char ssid[HCF_MAX_NAME_LEN];
3110 memset( ssid, 0, sizeof( ssid ));
3111 strncpy( ssid, &probe_rsp->rawData[2],
3113 probe_rsp->rawData[1],
3114 HCF_MAX_NAME_LEN - 1));
3116 DBG_TRACE( DbgInfo, "(%s) SSID : %s\n",
3117 lp->dev->name, ssid );
3120 /* Parse out the WPA-IE, if one exists */
3121 wpa_ie = wl_parse_wpa_ie( probe_rsp, &wpa_ie_len );
3122 if ( wpa_ie != NULL ) {
3123 DBG_TRACE( DbgInfo, "(%s) WPA-IE : %s\n",
3124 lp->dev->name, wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
3127 DBG_TRACE( DbgInfo, "(%s) flags : 0x%04x.\n",
3128 lp->dev->name, probe_rsp->flags );
3131 DBG_TRACE( DbgInfo, "\n\n" );
3132 /* If probe response length is 1, then the scan is complete */
3133 if ( probe_rsp->length == 1 ) {
3134 DBG_TRACE( DbgInfo, "SCAN COMPLETE\n" );
3135 lp->probe_results.num_aps = lp->probe_num_aps;
3136 lp->probe_results.scan_complete = TRUE;
3138 /* Reset the counter for the next scan request */
3139 lp->probe_num_aps = 0;
3141 /* Send a wireless extensions event that the scan completed */
3142 wl_wext_event_scan_complete( lp->dev );
3144 /* Only copy to the table if the entry is unique; APs sometimes
3145 respond more than once to a probe */
3146 if ( lp->probe_num_aps == 0 ) {
3147 /* Copy the info to the ScanResult structure in the private
3149 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3150 probe_rsp, sizeof( PROBE_RESP ));
3152 /* Increment the number of APs detected */
3153 lp->probe_num_aps++;
3158 for( count = 0; count < lp->probe_num_aps; count++ ) {
3159 if ( memcmp( &( probe_rsp->BSSID ),
3160 lp->probe_results.ProbeTable[count].BSSID,
3167 /* Copy the info to the ScanResult structure in the
3168 private adapter struct. Only copy if there's room in the
3170 if ( lp->probe_num_aps < MAX_NAPS )
3172 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3173 probe_rsp, sizeof( PROBE_RESP ));
3177 DBG_WARNING( DbgInfo, "Num of scan results exceeds storage, truncating\n" );
3180 /* Increment the number of APs detected. Note I do this
3181 here even when I don't copy the probe response to the
3182 buffer in order to detect the overflow condition */
3183 lp->probe_num_aps++;
3192 #define ls ((LINK_STATUS_STRCT *)ltv)
3193 DBG_TRACE( DbgInfo, "CFG_LINK_STAT\n" );
3195 switch( ls->linkStatus ) {
3197 DBG_TRACE( DbgInfo, "Link Status : Connected\n" );
3198 wl_wext_event_ap( lp->dev );
3202 DBG_TRACE( DbgInfo, "Link Status : Disconnected\n" );
3206 DBG_TRACE( DbgInfo, "Link Status : Access Point Change\n" );
3210 DBG_TRACE( DbgInfo, "Link Status : Access Point Out of Range\n" );
3214 DBG_TRACE( DbgInfo, "Link Status : Access Point In Range\n" );
3218 DBG_TRACE( DbgInfo, "Link Status : UNKNOWN (0x%04x)\n",
3226 case CFG_ASSOC_STAT:
3227 DBG_TRACE( DbgInfo, "CFG_ASSOC_STAT\n" );
3230 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
3232 switch( as->assocStatus ) {
3234 DBG_TRACE( DbgInfo, "Association Status : STA Associated\n" );
3238 DBG_TRACE( DbgInfo, "Association Status : STA Reassociated\n" );
3242 DBG_TRACE( DbgInfo, "Association Status : STA Disassociated\n" );
3246 DBG_TRACE( DbgInfo, "Association Status : UNKNOWN (0x%04x)\n",
3251 DBG_TRACE(DbgInfo, "STA Address : %pM\n",
3254 if (( as->assocStatus == 2 ) && ( as->len == 8 )) {
3255 DBG_TRACE(DbgInfo, "Old AP Address : %pM\n",
3262 case CFG_SECURITY_STAT:
3263 DBG_TRACE( DbgInfo, "CFG_SECURITY_STAT\n" );
3266 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
3268 switch( ss->securityStatus ) {
3270 DBG_TRACE( DbgInfo, "Security Status : Dissassociate [AP]\n" );
3274 DBG_TRACE( DbgInfo, "Security Status : Deauthenticate [AP]\n" );
3278 DBG_TRACE( DbgInfo, "Security Status : Authenticate Fail [STA] or [AP]\n" );
3282 DBG_TRACE( DbgInfo, "Security Status : MIC Fail\n" );
3286 DBG_TRACE( DbgInfo, "Security Status : Associate Fail\n" );
3290 DBG_TRACE( DbgInfo, "Security Status : UNKNOWN %d\n",
3291 ss->securityStatus );
3295 DBG_TRACE(DbgInfo, "STA Address : %pM\n",
3298 DBG_TRACE(DbgInfo, "Reason : 0x%04x\n",
3305 DBG_TRACE( DbgInfo, "CFG_WMP, size is %d bytes\n", ltv->len );
3307 WMP_RSP_STRCT *wmp_rsp = (WMP_RSP_STRCT *)ltv;
3309 DBG_TRACE( DbgInfo, "CFG_WMP, pdu type is 0x%x\n",
3310 wmp_rsp->wmpRsp.wmpHdr.type );
3312 switch( wmp_rsp->wmpRsp.wmpHdr.type ) {
3313 case WVLAN_WMP_PDU_TYPE_LT_RSP:
3316 LINKTEST_RSP_STRCT *lt_rsp = (LINKTEST_RSP_STRCT *)ltv;
3318 DBG_TRACE( DbgInfo, "LINK TEST RESULT\n" );
3319 DBG_TRACE( DbgInfo, "================\n" );
3320 DBG_TRACE( DbgInfo, "Length : %d.\n", lt_rsp->len );
3322 DBG_TRACE( DbgInfo, "Name : %s.\n", lt_rsp->ltRsp.ltRsp.name );
3323 DBG_TRACE( DbgInfo, "Signal Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.signal );
3324 DBG_TRACE( DbgInfo, "Noise Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.noise );
3325 DBG_TRACE( DbgInfo, "Receive Flow : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.rxFlow );
3326 DBG_TRACE( DbgInfo, "Data Rate : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRate );
3327 DBG_TRACE( DbgInfo, "Protocol : 0x%04x.\n", lt_rsp->ltRsp.ltRsp.protocol );
3328 DBG_TRACE( DbgInfo, "Station : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.station );
3329 DBG_TRACE( DbgInfo, "Data Rate Cap : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRateCap );
3331 DBG_TRACE( DbgInfo, "Power Mgmt : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3332 lt_rsp->ltRsp.ltRsp.powerMgmt[0],
3333 lt_rsp->ltRsp.ltRsp.powerMgmt[1],
3334 lt_rsp->ltRsp.ltRsp.powerMgmt[2],
3335 lt_rsp->ltRsp.ltRsp.powerMgmt[3] );
3337 DBG_TRACE( DbgInfo, "Robustness : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3338 lt_rsp->ltRsp.ltRsp.robustness[0],
3339 lt_rsp->ltRsp.ltRsp.robustness[1],
3340 lt_rsp->ltRsp.ltRsp.robustness[2],
3341 lt_rsp->ltRsp.ltRsp.robustness[3] );
3343 DBG_TRACE( DbgInfo, "Scaling : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.scaling );
3356 DBG_TRACE( DbgInfo, "CFG_NULL\n" );
3359 case CFG_UPDATED_INFO_RECORD: // Updated Information Record
3360 DBG_TRACE( DbgInfo, "UPDATED INFORMATION RECORD\n" );
3362 ltv_val = CNV_INT_TO_LITTLE( ltv->u.u16[0] );
3364 /* Check and see which RID was updated */
3366 case CFG_CUR_COUNTRY_INFO: // Indicate Passive Scan Completion
3367 DBG_TRACE( DbgInfo, "Updated country info\n" );
3369 /* Do I need to hold off on updating RIDs until the process is
3374 case CFG_PORT_STAT: // Wait for Connect Event
3380 DBG_WARNING( DbgInfo, "Unknown RID: 0x%04x\n", ltv_val );
3386 DBG_TRACE( DbgInfo, "UNKNOWN MESSAGE: 0x%04x\n", ltv->typ );
3389 DBG_LEAVE( DbgInfo );
3391 } // wl_process_mailbox
3392 /*============================================================================*/
3393 #endif /* ifndef USE_MBOX_SYNC */
3396 /*******************************************************************************
3397 * wl_wds_netdev_register()
3398 *******************************************************************************
3402 * This function registers net_device structures with the system's network
3403 * layer for use with the WDS ports.
3408 * lp - pointer to the device's private adapter structure
3414 ******************************************************************************/
3415 void wl_wds_netdev_register( struct wl_private *lp )
3419 //;?why is there no USE_WDS clause like in wl_enable_wds_ports
3420 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3421 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3422 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3423 if ( register_netdev( lp->wds_port[count].dev ) != 0 ) {
3424 DBG_WARNING( DbgInfo, "net device for WDS port %d could not be registered\n",
3427 lp->wds_port[count].is_registered = TRUE;
3429 /* Fill out the net_device structs with the MAC addr */
3430 memcpy( lp->wds_port[count].dev->dev_addr, lp->MACAddress, ETH_ALEN );
3431 lp->wds_port[count].dev->addr_len = ETH_ALEN;
3435 DBG_LEAVE( DbgInfo );
3437 } // wl_wds_netdev_register
3438 /*============================================================================*/
3441 /*******************************************************************************
3442 * wl_wds_netdev_deregister()
3443 *******************************************************************************
3447 * This function deregisters the WDS net_device structures used by the
3448 * system's network layer.
3453 * lp - pointer to the device's private adapter structure
3459 ******************************************************************************/
3460 void wl_wds_netdev_deregister( struct wl_private *lp )
3464 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3465 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3466 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3467 unregister_netdev( lp->wds_port[count].dev );
3469 lp->wds_port[count].is_registered = FALSE;
3472 DBG_LEAVE( DbgInfo );
3474 } // wl_wds_netdev_deregister
3475 /*============================================================================*/
3476 #endif /* USE_WDS */
3479 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
3481 * The proc filesystem: function to read and entry
3483 static void printf_hcf_16(struct seq_file *m, const char *s, hcf_16 *p, int n)
3487 seq_printf(m, "%-20.20s: ", s);
3490 for (i = 0; i < n; i++) {
3493 seq_printf(m, "%04X ", p[i]);
3498 static void printf_hcf_8(struct seq_file *m, const char *s, hcf_8 *p, int n)
3502 seq_printf(m, "%-20.20s: ", s);
3505 for (i = 0; i <= n; i++) {
3508 seq_printf(m, "%02X ", p[i]);
3513 static void printf_strct(struct seq_file *m, const char *s, hcf_16 *p)
3517 seq_printf(m, "%-20.20s: ", s);
3520 for ( i = 0; i <= *p; i++ ) {
3523 seq_printf(m,"%04X ", p[i]);
3528 int scull_read_procmem(struct seq_file *m, void *v)
3530 struct wl_private *lp = m->private;
3532 CFG_HERMES_TALLIES_STRCT *p;
3535 seq_puts(m, "No wl_private in scull_read_procmem\n" );
3536 } else if ( lp->wlags49_type == 0 ){
3538 seq_printf(m, "Magic: 0x%04X\n", ifbp->IFB_Magic );
3539 seq_printf(m, "IOBase: 0x%04X\n", ifbp->IFB_IOBase );
3540 seq_printf(m, "LinkStat: 0x%04X\n", ifbp->IFB_LinkStat );
3541 seq_printf(m, "DSLinkStat: 0x%04X\n", ifbp->IFB_DSLinkStat );
3542 seq_printf(m, "TickIni: 0x%08lX\n", ifbp->IFB_TickIni );
3543 seq_printf(m, "TickCnt: 0x%04X\n", ifbp->IFB_TickCnt );
3544 seq_printf(m, "IntOffCnt: 0x%04X\n", ifbp->IFB_IntOffCnt );
3545 printf_hcf_16(m, "IFB_FWIdentity",
3546 &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
3547 } else if ( lp->wlags49_type == 1 ) {
3548 seq_printf(m, "Channel: 0x%04X\n", lp->Channel );
3549 /****** seq_printf(m, "slock: %d\n", lp->slock ); */
3550 //x struct tq_struct "task: 0x%04X\n", lp->task );
3551 //x struct net_device_stats "stats: 0x%04X\n", lp->stats );
3553 //x struct iw_statistics "wstats: 0x%04X\n", lp->wstats );
3554 //x seq_printf(m, "spy_number: 0x%04X\n", lp->spy_number );
3555 //x u_char spy_address[IW_MAX_SPY][ETH_ALEN];
3556 //x struct iw_quality spy_stat[IW_MAX_SPY];
3557 #endif // WIRELESS_EXT
3558 seq_printf(m, "IFB: 0x%p\n", &lp->hcfCtx );
3559 seq_printf(m, "flags: %#.8lX\n", lp->flags ); //;?use this format from now on
3560 seq_printf(m, "DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
3562 seq_printf(m, "DebugFlag (DbgInfo): 0x%08lX\n", DbgInfo->DebugFlag );
3564 seq_printf(m, "is_registered: 0x%04X\n", lp->is_registered );
3565 //x CFG_DRV_INFO_STRCT "driverInfo: 0x%04X\n", lp->driverInfo );
3566 printf_strct( m, "driverInfo", (hcf_16*)&lp->driverInfo );
3567 //x CFG_IDENTITY_STRCT "driverIdentity: 0x%04X\n", lp->driverIdentity );
3568 printf_strct( m, "driverIdentity", (hcf_16*)&lp->driverIdentity );
3569 //x CFG_FW_IDENTITY_STRCT "StationIdentity: 0x%04X\n", lp->StationIdentity );
3570 printf_strct( m, "StationIdentity", (hcf_16*)&lp->StationIdentity );
3571 //x CFG_PRI_IDENTITY_STRCT "PrimaryIdentity: 0x%04X\n", lp->PrimaryIdentity );
3572 printf_strct( m, "PrimaryIdentity", (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
3573 printf_strct( m, "PrimarySupplier", (hcf_16*)&lp->hcfCtx.IFB_PRISup );
3574 //x CFG_PRI_IDENTITY_STRCT "NICIdentity: 0x%04X\n", lp->NICIdentity );
3575 printf_strct( m, "NICIdentity", (hcf_16*)&lp->NICIdentity );
3576 //x ltv_t "ltvRecord: 0x%04X\n", lp->ltvRecord );
3577 seq_printf(m, "txBytes: 0x%08lX\n", lp->txBytes );
3578 seq_printf(m, "maxPort: 0x%04X\n", lp->maxPort ); /* 0 for STA, 6 for AP */
3579 /* Elements used for async notification from hardware */
3580 //x RID_LOG_STRCT RidList[10];
3581 //x ltv_t "updatedRecord: 0x%04X\n", lp->updatedRecord );
3582 //x PROBE_RESP "ProbeResp: 0x%04X\n", lp->ProbeResp );
3583 //x ASSOC_STATUS_STRCT "assoc_stat: 0x%04X\n", lp->assoc_stat );
3584 //x SECURITY_STATUS_STRCT "sec_stat: 0x%04X\n", lp->sec_stat );
3585 //x u_char lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
3586 seq_printf(m, "PortType: 0x%04X\n", lp->PortType ); // 1 - 3 (1 [Normal] | 3 [AdHoc])
3587 seq_printf(m, "Channel: 0x%04X\n", lp->Channel ); // 0 - 14 (0)
3588 //x hcf_16 TxRateControl[2];
3589 seq_printf(m, "TxRateControl[2]: 0x%04X 0x%04X\n",
3590 lp->TxRateControl[0], lp->TxRateControl[1] );
3591 seq_printf(m, "DistanceBetweenAPs: 0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
3592 seq_printf(m, "RTSThreshold: 0x%04X\n", lp->RTSThreshold ); // 0 - 2347 (2347)
3593 seq_printf(m, "PMEnabled: 0x%04X\n", lp->PMEnabled ); // 0 - 2, 8001 - 8002 (0)
3594 seq_printf(m, "MicrowaveRobustness: 0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
3595 seq_printf(m, "CreateIBSS: 0x%04X\n", lp->CreateIBSS ); // 0 - 1 (0)
3596 seq_printf(m, "MulticastReceive: 0x%04X\n", lp->MulticastReceive ); // 0 - 1 (1)
3597 seq_printf(m, "MaxSleepDuration: 0x%04X\n", lp->MaxSleepDuration ); // 0 - 65535 (100)
3598 //x hcf_8 MACAddress[ETH_ALEN];
3599 printf_hcf_8(m, "MACAddress", lp->MACAddress, ETH_ALEN );
3600 //x char NetworkName[HCF_MAX_NAME_LEN+1];
3601 seq_printf(m, "NetworkName: %.32s\n", lp->NetworkName );
3602 //x char StationName[HCF_MAX_NAME_LEN+1];
3603 seq_printf(m, "EnableEncryption: 0x%04X\n", lp->EnableEncryption ); // 0 - 1 (0)
3604 //x char Key1[MAX_KEY_LEN+1];
3605 printf_hcf_8( m, "Key1", lp->Key1, MAX_KEY_LEN );
3606 //x char Key2[MAX_KEY_LEN+1];
3607 //x char Key3[MAX_KEY_LEN+1];
3608 //x char Key4[MAX_KEY_LEN+1];
3609 seq_printf(m, "TransmitKeyID: 0x%04X\n", lp->TransmitKeyID ); // 1 - 4 (1)
3610 //x CFG_DEFAULT_KEYS_STRCT "DefaultKeys: 0x%04X\n", lp->DefaultKeys );
3611 //x u_char mailbox[MB_SIZE];
3612 //x char szEncryption[MAX_ENC_LEN];
3613 seq_printf(m, "driverEnable: 0x%04X\n", lp->driverEnable );
3614 seq_printf(m, "wolasEnable: 0x%04X\n", lp->wolasEnable );
3615 seq_printf(m, "atimWindow: 0x%04X\n", lp->atimWindow );
3616 seq_printf(m, "holdoverDuration: 0x%04X\n", lp->holdoverDuration );
3617 //x hcf_16 MulticastRate[2];
3618 seq_printf(m, "authentication: 0x%04X\n", lp->authentication ); // is this AP specific?
3619 seq_printf(m, "promiscuousMode: 0x%04X\n", lp->promiscuousMode );
3620 seq_printf(m, "DownloadFirmware: 0x%04X\n", lp->DownloadFirmware ); // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
3621 seq_printf(m, "AuthKeyMgmtSuite: 0x%04X\n", lp->AuthKeyMgmtSuite );
3622 seq_printf(m, "loadBalancing: 0x%04X\n", lp->loadBalancing );
3623 seq_printf(m, "mediumDistribution: 0x%04X\n", lp->mediumDistribution );
3624 seq_printf(m, "txPowLevel: 0x%04X\n", lp->txPowLevel );
3625 // seq_printf(m, "shortRetryLimit: 0x%04X\n", lp->shortRetryLimit );
3626 // seq_printf(m, "longRetryLimit: 0x%04X\n", lp->longRetryLimit );
3629 seq_printf(m, "connectionControl: 0x%04X\n", lp->connectionControl );
3630 //x //hcf_16 probeDataRates[2];
3631 seq_printf(m, "ownBeaconInterval: 0x%04X\n", lp->ownBeaconInterval );
3632 seq_printf(m, "coexistence: 0x%04X\n", lp->coexistence );
3633 //x WVLAN_FRAME "txF: 0x%04X\n", lp->txF );
3634 //x WVLAN_LFRAME txList[DEFAULT_NUM_TX_FRAMES];
3635 //x struct list_head "txFree: 0x%04X\n", lp->txFree );
3636 //x struct list_head txQ[WVLAN_MAX_TX_QUEUES];
3637 seq_printf(m, "netif_queue_on: 0x%04X\n", lp->netif_queue_on );
3638 seq_printf(m, "txQ_count: 0x%04X\n", lp->txQ_count );
3639 //x DESC_STRCT "desc_rx: 0x%04X\n", lp->desc_rx );
3640 //x DESC_STRCT "desc_tx: 0x%04X\n", lp->desc_tx );
3641 //x WVLAN_PORT_STATE "portState: 0x%04X\n", lp->portState );
3642 //x ScanResult "scan_results: 0x%04X\n", lp->scan_results );
3643 //x ProbeResult "probe_results: 0x%04X\n", lp->probe_results );
3644 seq_printf(m, "probe_num_aps: 0x%04X\n", lp->probe_num_aps );
3645 seq_printf(m, "use_dma: 0x%04X\n", lp->use_dma );
3646 //x DMA_STRCT "dma: 0x%04X\n", lp->dma );
3648 seq_printf(m, "useRTS: 0x%04X\n", lp->useRTS );
3650 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
3651 //;?should we restore this to allow smaller memory footprint
3652 //;?I guess not. This should be brought under Debug mode only
3653 seq_printf(m, "DTIMPeriod: 0x%04X\n", lp->DTIMPeriod ); // 1 - 255 (1)
3654 seq_printf(m, "multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
3655 seq_printf(m, "RejectAny: 0x%04X\n", lp->RejectAny ); // 0 - 1 (0)
3656 seq_printf(m, "ExcludeUnencrypted: 0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
3657 seq_printf(m, "intraBSSRelay: 0x%04X\n", lp->intraBSSRelay );
3658 seq_printf(m, "wlags49_type: 0x%08lX\n", lp->wlags49_type );
3660 //x WVLAN_WDS_IF wds_port[NUM_WDS_PORTS];
3663 } else if ( lp->wlags49_type == 2 ){
3664 seq_printf(m, "tallies to be added\n" );
3665 //Hermes Tallies (IFB substructure) {
3666 p = &lp->hcfCtx.IFB_NIC_Tallies;
3667 seq_printf(m, "TxUnicastFrames: %08lX\n", p->TxUnicastFrames );
3668 seq_printf(m, "TxMulticastFrames: %08lX\n", p->TxMulticastFrames );
3669 seq_printf(m, "TxFragments: %08lX\n", p->TxFragments );
3670 seq_printf(m, "TxUnicastOctets: %08lX\n", p->TxUnicastOctets );
3671 seq_printf(m, "TxMulticastOctets: %08lX\n", p->TxMulticastOctets );
3672 seq_printf(m, "TxDeferredTransmissions: %08lX\n", p->TxDeferredTransmissions );
3673 seq_printf(m, "TxSingleRetryFrames: %08lX\n", p->TxSingleRetryFrames );
3674 seq_printf(m, "TxMultipleRetryFrames: %08lX\n", p->TxMultipleRetryFrames );
3675 seq_printf(m, "TxRetryLimitExceeded: %08lX\n", p->TxRetryLimitExceeded );
3676 seq_printf(m, "TxDiscards: %08lX\n", p->TxDiscards );
3677 seq_printf(m, "RxUnicastFrames: %08lX\n", p->RxUnicastFrames );
3678 seq_printf(m, "RxMulticastFrames: %08lX\n", p->RxMulticastFrames );
3679 seq_printf(m, "RxFragments: %08lX\n", p->RxFragments );
3680 seq_printf(m, "RxUnicastOctets: %08lX\n", p->RxUnicastOctets );
3681 seq_printf(m, "RxMulticastOctets: %08lX\n", p->RxMulticastOctets );
3682 seq_printf(m, "RxFCSErrors: %08lX\n", p->RxFCSErrors );
3683 seq_printf(m, "RxDiscardsNoBuffer: %08lX\n", p->RxDiscardsNoBuffer );
3684 seq_printf(m, "TxDiscardsWrongSA: %08lX\n", p->TxDiscardsWrongSA );
3685 seq_printf(m, "RxWEPUndecryptable: %08lX\n", p->RxWEPUndecryptable );
3686 seq_printf(m, "RxMsgInMsgFragments: %08lX\n", p->RxMsgInMsgFragments );
3687 seq_printf(m, "RxMsgInBadMsgFragments: %08lX\n", p->RxMsgInBadMsgFragments );
3688 seq_printf(m, "RxDiscardsWEPICVError: %08lX\n", p->RxDiscardsWEPICVError );
3689 seq_printf(m, "RxDiscardsWEPExcluded: %08lX\n", p->RxDiscardsWEPExcluded );
3690 #if (HCF_EXT) & HCF_EXT_TALLIES_FW
3692 #endif // HCF_EXT_TALLIES_FW
3693 } else if ( lp->wlags49_type & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3695 DbgInfo->DebugFlag = lp->wlags49_type & 0x7FFF;
3697 lp->wlags49_type = 0; //default to IFB again ;?
3699 seq_printf(m, "unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
3702 "0x0001 - wl_private\n"
3703 "0x0002 - Tallies\n"
3704 "0x8xxx - Change debufflag\n"
3705 "ERROR 0001\nWARNING 0002\nNOTICE 0004\nTRACE 0008\n"
3706 "VERBOSE 0010\nPARAM 0020\nBREAK 0040\nRX 0100\n"
3707 "TX 0200\nDS 0400\n");
3710 } // scull_read_procmem
3712 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
3714 static char proc_number[11];
3715 unsigned int nr = 0;
3719 } else if ( copy_from_user(proc_number, buffer, count) ) {
3723 proc_number[count] = 0;
3724 nr = simple_strtoul(proc_number , NULL, 0);
3725 *(unsigned int *)data = nr;
3726 if ( nr & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3728 DbgInfo->DebugFlag = nr & 0x7FFF;
3732 DBG_PRINT( "value: %08X\n", nr );
3733 DBG_LEAVE( DbgInfo );
3737 #endif /* SCULL_USE_PROC */
3740 #define RUN_AT(x) (jiffies+(x)) //"borrowed" from include/pcmcia/k_compat.h
3741 #define DS_OOR 0x8000 //Deepsleep OutOfRange Status
3743 lp->timer_oor_cnt = DS_OOR;
3744 init_timer( &lp->timer_oor );
3745 lp->timer_oor.function = timer_oor;
3746 lp->timer_oor.data = (unsigned long)lp;
3747 lp->timer_oor.expires = RUN_AT( 3 * HZ );
3748 add_timer( &lp->timer_oor );
3749 printk(KERN_NOTICE "wl_enable: %ld\n", jiffies ); //;?remove me 1 day
3752 /*******************************************************************************
3754 *******************************************************************************
3761 * arg - a u_long representing a pointer to a dev_link_t structure for the
3762 * device to be released.
3768 ******************************************************************************/
3769 void timer_oor( u_long arg )
3771 struct wl_private *lp = (struct wl_private *)arg;
3773 DBG_PARAM( DbgInfo, "arg", "0x%08lx", arg );
3775 printk(KERN_NOTICE "timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt ); //;?remove me 1 day
3776 lp->timer_oor_cnt += 10;
3777 if ( (lp->timer_oor_cnt & ~DS_OOR) > 300 ) {
3778 lp->timer_oor_cnt = 300;
3780 lp->timer_oor_cnt |= DS_OOR;
3781 init_timer( &lp->timer_oor );
3782 lp->timer_oor.function = timer_oor;
3783 lp->timer_oor.data = (unsigned long)lp;
3784 lp->timer_oor.expires = RUN_AT( (lp->timer_oor_cnt & ~DS_OOR) * HZ );
3785 add_timer( &lp->timer_oor );
3787 DBG_LEAVE( DbgInfo );
3791 MODULE_LICENSE("Dual BSD/GPL");