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 = seq_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);
437 /*------------------------------------------------------------------------*/
438 DBG_FUNC( "wl_insert" );
439 DBG_ENTER( DbgInfo );
441 /* Initialize the adapter hardware. */
442 memset( &( lp->hcfCtx ), 0, sizeof( IFB_STRCT ));
444 /* Initialize the adapter parameters. */
445 spin_lock_init( &( lp->slock ));
447 /* Initialize states */
448 //lp->lockcount = 0; //PE1DNN
449 lp->is_handling_int = WL_NOT_HANDLING_INT;
450 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
454 DBG_PARAM( DbgInfo, "irq_mask", "0x%04x", irq_mask & 0x0FFFF );
455 DBG_PARAM( DbgInfo, "irq_list", "0x%02x 0x%02x 0x%02x 0x%02x",
456 irq_list[0] & 0x0FF, irq_list[1] & 0x0FF,
457 irq_list[2] & 0x0FF, irq_list[3] & 0x0FF );
458 DBG_PARAM( DbgInfo, PARM_NAME_DESIRED_SSID, "\"%s\"", PARM_DESIRED_SSID );
459 DBG_PARAM( DbgInfo, PARM_NAME_OWN_SSID, "\"%s\"", PARM_OWN_SSID );
460 DBG_PARAM( DbgInfo, PARM_NAME_OWN_CHANNEL, "%d", PARM_OWN_CHANNEL);
461 DBG_PARAM( DbgInfo, PARM_NAME_SYSTEM_SCALE, "%d", PARM_SYSTEM_SCALE );
462 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE, "%d", PARM_TX_RATE );
463 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD, "%d", PARM_RTS_THRESHOLD );
464 DBG_PARAM( DbgInfo, PARM_NAME_MICROWAVE_ROBUSTNESS, "\"%s\"", PARM_MICROWAVE_ROBUSTNESS );
465 DBG_PARAM( DbgInfo, PARM_NAME_OWN_NAME, "\"%s\"", PARM_OWN_NAME );
466 //;? DBG_PARAM( DbgInfo, PARM_NAME_ENABLE_ENCRYPTION, "\"%s\"", PARM_ENABLE_ENCRYPTION );
467 DBG_PARAM( DbgInfo, PARM_NAME_KEY1, "\"%s\"", PARM_KEY1 );
468 DBG_PARAM( DbgInfo, PARM_NAME_KEY2, "\"%s\"", PARM_KEY2 );
469 DBG_PARAM( DbgInfo, PARM_NAME_KEY3, "\"%s\"", PARM_KEY3 );
470 DBG_PARAM( DbgInfo, PARM_NAME_KEY4, "\"%s\"", PARM_KEY4 );
471 DBG_PARAM( DbgInfo, PARM_NAME_TX_KEY, "%d", PARM_TX_KEY );
472 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RATE, "%d", PARM_MULTICAST_RATE );
473 DBG_PARAM( DbgInfo, PARM_NAME_DOWNLOAD_FIRMWARE, "\"%s\"", PARM_DOWNLOAD_FIRMWARE );
474 DBG_PARAM( DbgInfo, PARM_NAME_AUTH_KEY_MGMT_SUITE, "%d", PARM_AUTH_KEY_MGMT_SUITE );
475 //;?#if (HCF_TYPE) & HCF_TYPE_STA
476 //;?should we make this code conditional depending on in STA mode
477 //;? DBG_PARAM( DbgInfo, PARM_NAME_PORT_TYPE, "%d", PARM_PORT_TYPE );
478 DBG_PARAM( DbgInfo, PARM_NAME_PM_ENABLED, "%04x", PARM_PM_ENABLED );
479 //;? DBG_PARAM( DbgInfo, PARM_NAME_CREATE_IBSS, "\"%s\"", PARM_CREATE_IBSS );
480 //;? DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RX, "\"%s\"", PARM_MULTICAST_RX );
481 //;? DBG_PARAM( DbgInfo, PARM_NAME_MAX_SLEEP, "%d", PARM_MAX_SLEEP );
483 DBG_PARAM(DbgInfo, PARM_NAME_NETWORK_ADDR, "\"%pM\"",
486 //;? DBG_PARAM( DbgInfo, PARM_NAME_AUTHENTICATION, "%d", PARM_AUTHENTICATION );
487 //;? DBG_PARAM( DbgInfo, PARM_NAME_OWN_ATIM_WINDOW, "%d", PARM_OWN_ATIM_WINDOW );
488 //;? DBG_PARAM( DbgInfo, PARM_NAME_PM_HOLDOVER_DURATION, "%d", PARM_PM_HOLDOVER_DURATION );
489 //;? DBG_PARAM( DbgInfo, PARM_NAME_PROMISCUOUS_MODE, "\"%s\"", PARM_PROMISCUOUS_MODE );
490 //;?#endif /* HCF_STA */
491 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
492 //;?should we restore this to allow smaller memory footprint
493 //;?I guess: no, since this is Debug mode only
494 DBG_PARAM( DbgInfo, PARM_NAME_OWN_DTIM_PERIOD, "%d", PARM_OWN_DTIM_PERIOD );
495 DBG_PARAM( DbgInfo, PARM_NAME_REJECT_ANY, "\"%s\"", PARM_REJECT_ANY );
496 DBG_PARAM( DbgInfo, PARM_NAME_EXCLUDE_UNENCRYPTED, "\"%s\"", PARM_EXCLUDE_UNENCRYPTED );
497 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_PM_BUFFERING, "\"%s\"", PARM_MULTICAST_PM_BUFFERING );
498 DBG_PARAM( DbgInfo, PARM_NAME_INTRA_BSS_RELAY, "\"%s\"", PARM_INTRA_BSS_RELAY );
500 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD1, "%d", PARM_RTS_THRESHOLD1 );
501 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD2, "%d", PARM_RTS_THRESHOLD2 );
502 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD3, "%d", PARM_RTS_THRESHOLD3 );
503 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD4, "%d", PARM_RTS_THRESHOLD4 );
504 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD5, "%d", PARM_RTS_THRESHOLD5 );
505 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD6, "%d", PARM_RTS_THRESHOLD6 );
506 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE1, "%d", PARM_TX_RATE1 );
507 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE2, "%d", PARM_TX_RATE2 );
508 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE3, "%d", PARM_TX_RATE3 );
509 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE4, "%d", PARM_TX_RATE4 );
510 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE5, "%d", PARM_TX_RATE5 );
511 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE6, "%d", PARM_TX_RATE6 );
512 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS1, "\"%pM\"",
514 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS2, "\"%pM\"",
516 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS3, "\"%pM\"",
518 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS4, "\"%pM\"",
520 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS5, "\"%pM\"",
522 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS6, "\"%pM\"",
527 VALID_PARAM( !PARM_DESIRED_SSID || ( strlen( PARM_DESIRED_SSID ) <= PARM_MAX_NAME_LEN ));
528 VALID_PARAM( !PARM_OWN_SSID || ( strlen( PARM_OWN_SSID ) <= PARM_MAX_NAME_LEN ));
529 VALID_PARAM(( PARM_OWN_CHANNEL <= PARM_MAX_OWN_CHANNEL ));
530 VALID_PARAM(( PARM_SYSTEM_SCALE >= PARM_MIN_SYSTEM_SCALE ) && ( PARM_SYSTEM_SCALE <= PARM_MAX_SYSTEM_SCALE ));
531 VALID_PARAM(( PARM_TX_RATE >= PARM_MIN_TX_RATE ) && ( PARM_TX_RATE <= PARM_MAX_TX_RATE ));
532 VALID_PARAM(( PARM_RTS_THRESHOLD <= PARM_MAX_RTS_THRESHOLD ));
533 VALID_PARAM( !PARM_MICROWAVE_ROBUSTNESS || strchr( "NnYy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL );
534 VALID_PARAM( !PARM_OWN_NAME || ( strlen( PARM_NAME_OWN_NAME ) <= PARM_MAX_NAME_LEN ));
535 VALID_PARAM(( PARM_ENABLE_ENCRYPTION <= PARM_MAX_ENABLE_ENCRYPTION ));
536 VALID_PARAM( is_valid_key_string( PARM_KEY1 ));
537 VALID_PARAM( is_valid_key_string( PARM_KEY2 ));
538 VALID_PARAM( is_valid_key_string( PARM_KEY3 ));
539 VALID_PARAM( is_valid_key_string( PARM_KEY4 ));
540 VALID_PARAM(( PARM_TX_KEY >= PARM_MIN_TX_KEY ) && ( PARM_TX_KEY <= PARM_MAX_TX_KEY ));
542 VALID_PARAM(( PARM_MULTICAST_RATE >= PARM_MIN_MULTICAST_RATE ) &&
543 ( PARM_MULTICAST_RATE <= PARM_MAX_MULTICAST_RATE ));
545 VALID_PARAM( !PARM_DOWNLOAD_FIRMWARE || ( strlen( PARM_DOWNLOAD_FIRMWARE ) <= 255 /*;?*/ ));
546 VALID_PARAM(( PARM_AUTH_KEY_MGMT_SUITE < PARM_MAX_AUTH_KEY_MGMT_SUITE ));
548 VALID_PARAM( !PARM_LOAD_BALANCING || strchr( "NnYy", PARM_LOAD_BALANCING[0] ) != NULL );
549 VALID_PARAM( !PARM_MEDIUM_DISTRIBUTION || strchr( "NnYy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL );
550 VALID_PARAM(( PARM_TX_POW_LEVEL <= PARM_MAX_TX_POW_LEVEL ));
552 VALID_PARAM(( PARM_PORT_TYPE >= PARM_MIN_PORT_TYPE ) && ( PARM_PORT_TYPE <= PARM_MAX_PORT_TYPE ));
553 VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
554 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
555 VALID_PARAM( !PARM_CREATE_IBSS || strchr( "NnYy", PARM_CREATE_IBSS[0] ) != NULL );
556 VALID_PARAM( !PARM_MULTICAST_RX || strchr( "NnYy", PARM_MULTICAST_RX[0] ) != NULL );
557 VALID_PARAM(( PARM_MAX_SLEEP <= PARM_MAX_MAX_PM_SLEEP ));
558 VALID_PARAM(( PARM_AUTHENTICATION <= PARM_MAX_AUTHENTICATION ));
559 VALID_PARAM(( PARM_OWN_ATIM_WINDOW <= PARM_MAX_OWN_ATIM_WINDOW ));
560 VALID_PARAM(( PARM_PM_HOLDOVER_DURATION <= PARM_MAX_PM_HOLDOVER_DURATION ));
561 VALID_PARAM( !PARM_PROMISCUOUS_MODE || strchr( "NnYy", PARM_PROMISCUOUS_MODE[0] ) != NULL );
562 VALID_PARAM(( PARM_CONNECTION_CONTROL <= PARM_MAX_CONNECTION_CONTROL ));
564 VALID_PARAM(( PARM_OWN_DTIM_PERIOD >= PARM_MIN_OWN_DTIM_PERIOD ));
565 VALID_PARAM( !PARM_REJECT_ANY || strchr( "NnYy", PARM_REJECT_ANY[0] ) != NULL );
566 VALID_PARAM( !PARM_EXCLUDE_UNENCRYPTED || strchr( "NnYy", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL );
567 VALID_PARAM( !PARM_MULTICAST_PM_BUFFERING || strchr( "NnYy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL );
568 VALID_PARAM( !PARM_INTRA_BSS_RELAY || strchr( "NnYy", PARM_INTRA_BSS_RELAY[0] ) != NULL );
570 VALID_PARAM(( PARM_RTS_THRESHOLD1 <= PARM_MAX_RTS_THRESHOLD ));
571 VALID_PARAM(( PARM_RTS_THRESHOLD2 <= PARM_MAX_RTS_THRESHOLD ));
572 VALID_PARAM(( PARM_RTS_THRESHOLD3 <= PARM_MAX_RTS_THRESHOLD ));
573 VALID_PARAM(( PARM_RTS_THRESHOLD4 <= PARM_MAX_RTS_THRESHOLD ));
574 VALID_PARAM(( PARM_RTS_THRESHOLD5 <= PARM_MAX_RTS_THRESHOLD ));
575 VALID_PARAM(( PARM_RTS_THRESHOLD6 <= PARM_MAX_RTS_THRESHOLD ));
576 VALID_PARAM(( PARM_TX_RATE1 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE1 <= PARM_MAX_TX_RATE ));
577 VALID_PARAM(( PARM_TX_RATE2 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE2 <= PARM_MAX_TX_RATE ));
578 VALID_PARAM(( PARM_TX_RATE3 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE3 <= PARM_MAX_TX_RATE ));
579 VALID_PARAM(( PARM_TX_RATE4 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE4 <= PARM_MAX_TX_RATE ));
580 VALID_PARAM(( PARM_TX_RATE5 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE5 <= PARM_MAX_TX_RATE ));
581 VALID_PARAM(( PARM_TX_RATE6 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE6 <= PARM_MAX_TX_RATE ));
584 VALID_PARAM(( PARM_OWN_BEACON_INTERVAL >= PARM_MIN_OWN_BEACON_INTERVAL ) && ( PARM_OWN_BEACON_INTERVAL <= PARM_MAX_OWN_BEACON_INTERVAL ));
585 VALID_PARAM(( PARM_COEXISTENCE <= PARM_COEXISTENCE ));
587 /* Set the driver parameters from the passed in parameters. */
589 /* THESE MODULE PARAMETERS ARE TO BE DEPRECATED IN FAVOR OF A NAMING CONVENTION
590 WHICH IS INLINE WITH THE FORTHCOMING WAVELAN API */
592 /* START NEW PARAMETERS */
594 lp->Channel = PARM_OWN_CHANNEL;
595 lp->DistanceBetweenAPs = PARM_SYSTEM_SCALE;
597 /* Need to determine how to handle the new bands for 5GHz */
598 lp->TxRateControl[0] = PARM_DEFAULT_TX_RATE_2GHZ;
599 lp->TxRateControl[1] = PARM_DEFAULT_TX_RATE_5GHZ;
601 lp->RTSThreshold = PARM_RTS_THRESHOLD;
603 /* Need to determine how to handle the new bands for 5GHz */
604 lp->MulticastRate[0] = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
605 lp->MulticastRate[1] = PARM_DEFAULT_MULTICAST_RATE_5GHZ;
607 if ( strchr( "Yy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL ) {
608 lp->MicrowaveRobustness = 1;
610 lp->MicrowaveRobustness = 0;
612 if ( PARM_DESIRED_SSID && ( strlen( PARM_DESIRED_SSID ) <= HCF_MAX_NAME_LEN )) {
613 strcpy( lp->NetworkName, PARM_DESIRED_SSID );
615 if ( PARM_OWN_SSID && ( strlen( PARM_OWN_SSID ) <= HCF_MAX_NAME_LEN )) {
616 strcpy( lp->NetworkName, PARM_OWN_SSID );
618 if ( PARM_OWN_NAME && ( strlen( PARM_OWN_NAME ) <= HCF_MAX_NAME_LEN )) {
619 strcpy( lp->StationName, PARM_OWN_NAME );
621 lp->EnableEncryption = PARM_ENABLE_ENCRYPTION;
622 if ( PARM_KEY1 && ( strlen( PARM_KEY1 ) <= MAX_KEY_LEN )) {
623 strcpy( lp->Key1, PARM_KEY1 );
625 if ( PARM_KEY2 && ( strlen( PARM_KEY2 ) <= MAX_KEY_LEN )) {
626 strcpy( lp->Key2, PARM_KEY2 );
628 if ( PARM_KEY3 && ( strlen( PARM_KEY3 ) <= MAX_KEY_LEN )) {
629 strcpy( lp->Key3, PARM_KEY3 );
631 if ( PARM_KEY4 && ( strlen( PARM_KEY4 ) <= MAX_KEY_LEN )) {
632 strcpy( lp->Key4, PARM_KEY4 );
635 lp->TransmitKeyID = PARM_TX_KEY;
637 key_string2key( lp->Key1, &(lp->DefaultKeys.key[0] ));
638 key_string2key( lp->Key2, &(lp->DefaultKeys.key[1] ));
639 key_string2key( lp->Key3, &(lp->DefaultKeys.key[2] ));
640 key_string2key( lp->Key4, &(lp->DefaultKeys.key[3] ));
642 lp->DownloadFirmware = 1 ; //;?to be upgraded PARM_DOWNLOAD_FIRMWARE;
643 lp->AuthKeyMgmtSuite = PARM_AUTH_KEY_MGMT_SUITE;
645 if ( strchr( "Yy", PARM_LOAD_BALANCING[0] ) != NULL ) {
646 lp->loadBalancing = 1;
648 lp->loadBalancing = 0;
651 if ( strchr( "Yy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL ) {
652 lp->mediumDistribution = 1;
654 lp->mediumDistribution = 0;
657 lp->txPowLevel = PARM_TX_POW_LEVEL;
659 lp->srsc[0] = PARM_SRSC_2GHZ;
660 lp->srsc[1] = PARM_SRSC_5GHZ;
661 lp->brsc[0] = PARM_BRSC_2GHZ;
662 lp->brsc[1] = PARM_BRSC_5GHZ;
663 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
664 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
665 lp->PortType = PARM_PORT_TYPE;
666 lp->MaxSleepDuration = PARM_MAX_SLEEP;
667 lp->authentication = PARM_AUTHENTICATION;
668 lp->atimWindow = PARM_OWN_ATIM_WINDOW;
669 lp->holdoverDuration = PARM_PM_HOLDOVER_DURATION;
670 lp->PMEnabled = PARM_PM_ENABLED; //;?
671 if ( strchr( "Yy", PARM_CREATE_IBSS[0] ) != NULL ) {
676 if ( strchr( "Nn", PARM_MULTICAST_RX[0] ) != NULL ) {
677 lp->MulticastReceive = 0;
679 lp->MulticastReceive = 1;
681 if ( strchr( "Yy", PARM_PROMISCUOUS_MODE[0] ) != NULL ) {
682 lp->promiscuousMode = 1;
684 lp->promiscuousMode = 0;
686 for( i = 0; i < ETH_ALEN; i++ ) {
687 lp->MACAddress[i] = PARM_NETWORK_ADDR[i];
690 lp->connectionControl = PARM_CONNECTION_CONTROL;
693 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
694 //;?should we restore this to allow smaller memory footprint
695 lp->DTIMPeriod = PARM_OWN_DTIM_PERIOD;
697 if ( strchr( "Yy", PARM_REJECT_ANY[0] ) != NULL ) {
702 if ( strchr( "Nn", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL ) {
703 lp->ExcludeUnencrypted = 0;
705 lp->ExcludeUnencrypted = 1;
707 if ( strchr( "Yy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL ) {
708 lp->multicastPMBuffering = 1;
710 lp->multicastPMBuffering = 0;
712 if ( strchr( "Yy", PARM_INTRA_BSS_RELAY[0] ) != NULL ) {
713 lp->intraBSSRelay = 1;
715 lp->intraBSSRelay = 0;
718 lp->ownBeaconInterval = PARM_OWN_BEACON_INTERVAL;
719 lp->coexistence = PARM_COEXISTENCE;
722 lp->wds_port[0].rtsThreshold = PARM_RTS_THRESHOLD1;
723 lp->wds_port[1].rtsThreshold = PARM_RTS_THRESHOLD2;
724 lp->wds_port[2].rtsThreshold = PARM_RTS_THRESHOLD3;
725 lp->wds_port[3].rtsThreshold = PARM_RTS_THRESHOLD4;
726 lp->wds_port[4].rtsThreshold = PARM_RTS_THRESHOLD5;
727 lp->wds_port[5].rtsThreshold = PARM_RTS_THRESHOLD6;
728 lp->wds_port[0].txRateCntl = PARM_TX_RATE1;
729 lp->wds_port[1].txRateCntl = PARM_TX_RATE2;
730 lp->wds_port[2].txRateCntl = PARM_TX_RATE3;
731 lp->wds_port[3].txRateCntl = PARM_TX_RATE4;
732 lp->wds_port[4].txRateCntl = PARM_TX_RATE5;
733 lp->wds_port[5].txRateCntl = PARM_TX_RATE6;
735 for( i = 0; i < ETH_ALEN; i++ ) {
736 lp->wds_port[0].wdsAddress[i] = PARM_WDS_ADDRESS1[i];
738 for( i = 0; i < ETH_ALEN; i++ ) {
739 lp->wds_port[1].wdsAddress[i] = PARM_WDS_ADDRESS2[i];
741 for( i = 0; i < ETH_ALEN; i++ ) {
742 lp->wds_port[2].wdsAddress[i] = PARM_WDS_ADDRESS3[i];
744 for( i = 0; i < ETH_ALEN; i++ ) {
745 lp->wds_port[3].wdsAddress[i] = PARM_WDS_ADDRESS4[i];
747 for( i = 0; i < ETH_ALEN; i++ ) {
748 lp->wds_port[4].wdsAddress[i] = PARM_WDS_ADDRESS5[i];
750 for( i = 0; i < ETH_ALEN; i++ ) {
751 lp->wds_port[5].wdsAddress[i] = PARM_WDS_ADDRESS6[i];
756 if ( strchr( "Yy", useRTS[0] ) != NULL ) {
764 /* END NEW PARAMETERS */
767 wl_lock( lp, &flags );
769 /* Initialize the portState variable */
770 lp->portState = WVLAN_PORT_STATE_DISABLED;
772 /* Initialize the ScanResult struct */
773 memset( &( lp->scan_results ), 0, sizeof( lp->scan_results ));
774 lp->scan_results.scan_complete = FALSE;
776 /* Initialize the ProbeResult struct */
777 memset( &( lp->probe_results ), 0, sizeof( lp->probe_results ));
778 lp->probe_results.scan_complete = FALSE;
779 lp->probe_num_aps = 0;
782 /* Initialize Tx queue stuff */
783 memset( lp->txList, 0, sizeof( lp->txList ));
785 INIT_LIST_HEAD( &( lp->txFree ));
791 for( i = 0; i < DEFAULT_NUM_TX_FRAMES; i++ ) {
792 list_add_tail( &( lp->txList[i].node ), &( lp->txFree ));
796 for( i = 0; i < WVLAN_MAX_TX_QUEUES; i++ ) {
797 INIT_LIST_HEAD( &( lp->txQ[i] ));
800 lp->netif_queue_on = TRUE;
802 /* Initialize the use_dma element in the adapter structure. Not sure if
803 this should be a compile-time or run-time configurable. So for now,
804 implement as run-time and just define here */
807 DBG_TRACE( DbgInfo, "HERMES 2.5 BUSMASTER DMA MODE\n" );
810 DBG_TRACE( DbgInfo, "HERMES 2.5 PORT I/O MODE\n" );
815 /* Register the ISR handler information here, so that it's not done
816 repeatedly in the ISR */
817 tasklet_init(&lp->task, wl_isr_handler, (unsigned long)lp);
819 /* Connect to the adapter */
820 DBG_TRACE( DbgInfo, "Calling hcf_connect()...\n" );
821 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
822 //HCF_ERR_INCOMP_FW is acceptable, because download must still take place
823 //HCF_ERR_INCOMP_PRI is not acceptable
824 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
825 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
826 wl_unlock( lp, &flags );
830 //;?should set HCF_version and how about driver_stat
831 lp->driverInfo.IO_address = dev->base_addr;
832 lp->driverInfo.IO_range = HCF_NUM_IO_PORTS; //;?conditionally 0x40 or 0x80 seems better
833 lp->driverInfo.IRQ_number = dev->irq;
834 lp->driverInfo.card_stat = lp->hcfCtx.IFB_CardStat;
835 //;? what happened to frame_type
837 /* Fill in the driver identity structure */
838 lp->driverIdentity.len = ( sizeof( lp->driverIdentity ) / sizeof( hcf_16 )) - 1;
839 lp->driverIdentity.typ = CFG_DRV_IDENTITY;
840 lp->driverIdentity.comp_id = DRV_IDENTITY;
841 lp->driverIdentity.variant = DRV_VARIANT;
842 lp->driverIdentity.version_major = DRV_MAJOR_VERSION;
843 lp->driverIdentity.version_minor = DRV_MINOR_VERSION;
846 /* Start the card here - This needs to be done in order to get the
847 MAC address for the network layer */
848 DBG_TRACE( DbgInfo, "Calling wvlan_go() to perform a card reset...\n" );
849 hcf_status = wl_go( lp );
851 if ( hcf_status != HCF_SUCCESS ) {
852 DBG_ERROR( DbgInfo, "wl_go() failed\n" );
853 wl_unlock( lp, &flags );
857 /* Certain RIDs must be set before enabling the ports */
858 wl_put_ltv_init( lp );
860 #if 0 //;?why was this already commented out in wl_lkm_720
861 /* Enable the ports */
862 if ( wl_adapter_is_open( lp->dev )) {
863 /* Enable the ports */
864 DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
865 hcf_status = wl_enable( lp );
867 if ( hcf_status != HCF_SUCCESS ) {
868 DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", hcf_status );
871 #if (HCF_TYPE) & HCF_TYPE_AP
872 DBG_TRACE( DbgInfo, "Enabling WDS Ports\n" );
873 //wl_enable_wds_ports( lp );
874 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
879 /* Fill out the MAC address information in the net_device struct */
880 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN );
881 dev->addr_len = ETH_ALEN;
883 lp->is_registered = TRUE;
886 /* Parse the config file for the sake of creating WDS ports if WDS is
887 configured there but not in the module options */
889 #endif /* USE_PROFILE */
891 /* If we're going into AP Mode, register the "virtual" ethernet devices
893 WL_WDS_NETDEV_REGISTER( lp );
895 /* Reset the DownloadFirmware variable in the private struct. If the
896 config file is not used, this will not matter; if it is used, it
897 will be reparsed in wl_open(). This is done because logic in wl_open
898 used to check if a firmware download is needed is broken by parsing
899 the file here; however, this parsing is needed to register WDS ports
900 in AP mode, if they are configured */
901 lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //;?download_firmware;
904 if ( lp->useRTS == 1 ) {
905 DBG_TRACE( DbgInfo, "ENTERING RTS MODE...\n" );
906 wl_act_int_off( lp );
907 lp->is_handling_int = WL_NOT_HANDLING_INT; // Not handling interrupts anymore
911 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT);
915 wl_unlock( lp, &flags );
917 DBG_TRACE( DbgInfo, "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
918 dev->name, dev->base_addr, dev->irq );
920 for( i = 0; i < ETH_ALEN; i++ ) {
921 printk( "%02X%c", dev->dev_addr[i], (( i < ( ETH_ALEN-1 )) ? ':' : '\n' ));
924 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
925 proc_create_data( "wlags", 0, NULL, &scull_read_procmem_fops, dev );
926 proc_mkdir("driver/wlags49", 0);
927 #endif /* SCULL_USE_PROC */
929 DBG_LEAVE( DbgInfo );
933 wl_hcf_error( dev, hcf_status );
937 DBG_ERROR( DbgInfo, "wl_insert() FAILED\n" );
939 if ( lp->is_registered == TRUE ) {
940 lp->is_registered = FALSE;
943 WL_WDS_NETDEV_DEREGISTER( lp );
948 DBG_LEAVE( DbgInfo );
951 /*============================================================================*/
954 /*******************************************************************************
956 *******************************************************************************
964 * dev - a pointer to the net_device struct of the wireless device
970 ******************************************************************************/
971 int wl_reset(struct net_device *dev)
973 struct wl_private *lp = wl_priv(dev);
974 int hcf_status = HCF_SUCCESS;
975 /*------------------------------------------------------------------------*/
976 DBG_FUNC( "wl_reset" );
977 DBG_ENTER( DbgInfo );
978 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
979 DBG_PARAM( DbgInfo, "dev->base_addr", "(%#03lx)", dev->base_addr );
982 * The caller should already have a lock and
983 * disable the interrupts, we do not lock here,
984 * nor do we enable/disable interrupts!
987 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", dev->base_addr );
988 if ( dev->base_addr ) {
989 /* Shutdown the adapter. */
990 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
992 /* Reset the driver information. */
995 /* Connect to the adapter. */
996 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
997 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
998 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
1002 /* Check if firmware is present, if not change state */
1003 if ( hcf_status == HCF_ERR_INCOMP_FW ) {
1004 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1007 /* Initialize the portState variable */
1008 lp->portState = WVLAN_PORT_STATE_DISABLED;
1010 /* Restart the adapter. */
1011 hcf_status = wl_go( lp );
1012 if ( hcf_status != HCF_SUCCESS ) {
1013 DBG_ERROR( DbgInfo, "wl_go() failed, status: 0x%x\n", hcf_status );
1017 /* Certain RIDs must be set before enabling the ports */
1018 wl_put_ltv_init( lp );
1020 DBG_ERROR( DbgInfo, "Device Base Address INVALID!!!\n" );
1024 DBG_LEAVE( DbgInfo );
1027 /*============================================================================*/
1030 /*******************************************************************************
1032 *******************************************************************************
1036 * Reset the adapter.
1040 * dev - a pointer to the net_device struct of the wireless device
1044 * an HCF status code
1046 ******************************************************************************/
1047 int wl_go( struct wl_private *lp )
1049 int hcf_status = HCF_SUCCESS;
1050 char *cp = NULL; //fw_image
1052 /*------------------------------------------------------------------------*/
1053 DBG_FUNC( "wl_go" );
1054 DBG_ENTER( DbgInfo );
1056 hcf_status = wl_disable( lp );
1057 if ( hcf_status != HCF_SUCCESS ) {
1058 DBG_TRACE( DbgInfo, "Disable port 0 failed: 0x%x\n", hcf_status );
1060 while (( hcf_status != HCF_SUCCESS ) && (retries < 10)) {
1062 hcf_status = wl_disable( lp );
1064 if ( hcf_status == HCF_SUCCESS ) {
1065 DBG_TRACE( DbgInfo, "Disable port 0 succes : %d retries\n", retries );
1067 DBG_TRACE( DbgInfo, "Disable port 0 failed after: %d retries\n", retries );
1071 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
1072 //DBG_TRACE( DbgInfo, "Disabling WDS Ports\n" );
1073 //wl_disable_wds_ports( lp );
1074 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1076 //;?what was the purpose of this
1077 // /* load the appropriate firmware image, depending on driver mode */
1078 // lp->ltvRecord.len = ( sizeof( CFG_RANGE20_STRCT ) / sizeof( hcf_16 )) - 1;
1079 // lp->ltvRecord.typ = CFG_DRV_ACT_RANGES_PRI;
1080 // hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1083 if ( strlen( lp->fw_image_filename ) ) {
1088 DBG_TRACE( DbgInfo, "F/W image:%s:\n", lp->fw_image_filename );
1089 /* Obtain a user-space process context, storing the original context */
1092 file_desc = open( lp->fw_image_filename, O_RDONLY, 0 );
1093 if ( file_desc == -1 ) {
1094 DBG_ERROR( DbgInfo, "No image file found\n" );
1096 DBG_TRACE( DbgInfo, "F/W image file found\n" );
1097 #define DHF_ALLOC_SIZE 96000 //just below 96K, let's hope it suffices for now and for the future
1098 cp = (char*)vmalloc( DHF_ALLOC_SIZE );
1100 DBG_ERROR( DbgInfo, "error in vmalloc\n" );
1102 rc = read( file_desc, cp, DHF_ALLOC_SIZE );
1103 if ( rc == DHF_ALLOC_SIZE ) {
1104 DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE );
1105 } else if ( rc > 0 ) {
1106 DBG_TRACE( DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp );
1107 rc = read( file_desc, &cp[rc], 1 );
1108 if ( rc == 0 ) { //;/change to an until-loop at rc<=0
1109 DBG_TRACE( DbgInfo, "no more to read\n" );
1113 DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\
1114 ", give up, too complicated, rc = %0X\n", rc );
1115 DBG_ERROR( DbgInfo, "still have to change code to get a real download now !!!!!!!!\n" );
1117 DBG_TRACE( DbgInfo, "before dhf_download_binary\n" );
1118 hcf_status = dhf_download_binary( (memimage *)cp );
1119 DBG_TRACE( DbgInfo, "after dhf_download_binary, before dhf_download_fw\n" );
1120 //;?improve error flow/handling
1121 hcf_status = dhf_download_fw( &lp->hcfCtx, (memimage *)cp );
1122 DBG_TRACE( DbgInfo, "after dhf_download_fw\n" );
1128 set_fs( fs ); /* Return to the original context */
1132 /* If firmware is present but the type is unknown then download anyway */
1133 if ( (lp->firmware_present == WL_FRIMWARE_PRESENT)
1135 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_STA )
1137 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_AP ) ) {
1138 /* Unknown type, download needed. */
1139 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1142 if(lp->firmware_present == WL_FRIMWARE_NOT_PRESENT)
1145 DBG_TRACE( DbgInfo, "Downloading STA firmware...\n" );
1146 // hcf_status = dhf_download_fw( &lp->hcfCtx, &station );
1147 hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image );
1149 if ( hcf_status != HCF_SUCCESS ) {
1150 DBG_ERROR( DbgInfo, "Firmware Download failed\n" );
1151 DBG_LEAVE( DbgInfo );
1155 /* Report the FW versions */
1156 //;?obsolete, use the available IFB info:: wl_get_pri_records( lp );
1157 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1158 DBG_TRACE( DbgInfo, "downloaded station F/W\n" );
1159 } else if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1160 DBG_TRACE( DbgInfo, "downloaded AP F/W\n" );
1162 DBG_ERROR( DbgInfo, "unknown F/W type\n" );
1166 * Downloaded, no need to repeat this next time, assume the
1167 * contents stays in the card until it is powered off. Note we
1168 * do not switch firmware on the fly, the firmware is fixed in
1169 * the driver for now.
1171 lp->firmware_present = WL_FRIMWARE_PRESENT;
1173 DBG_TRACE( DbgInfo, "ComponentID:%04x variant:%04x major:%04x minor:%04x\n",
1174 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ),
1175 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.variant ),
1176 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_major ),
1177 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_minor ));
1179 /* now we will get the MAC address of the card */
1180 lp->ltvRecord.len = 4;
1181 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1182 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1185 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1187 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1188 if ( hcf_status != HCF_SUCCESS ) {
1189 DBG_ERROR( DbgInfo, "Could not retrieve MAC address\n" );
1190 DBG_LEAVE( DbgInfo );
1193 memcpy( lp->MACAddress, &lp->ltvRecord.u.u8[0], ETH_ALEN );
1194 DBG_TRACE(DbgInfo, "Card MAC Address: %pM\n", lp->MACAddress);
1196 /* Write out configuration to the device, enable, and reconnect. However,
1197 only reconnect if in AP mode. For STA mode, need to wait for passive scan
1198 completion before a connect can be issued */
1200 /* Enable the ports */
1201 hcf_status = wl_enable( lp );
1203 if ( lp->DownloadFirmware == WVLAN_DRV_MODE_AP ) {
1205 wl_enable_wds_ports( lp );
1207 hcf_status = wl_connect( lp );
1209 DBG_LEAVE( DbgInfo );
1212 /*============================================================================*/
1215 /*******************************************************************************
1217 *******************************************************************************
1221 * Write TxKeyID and WEP keys to the adapter. This is separated from
1222 * wl_apply() to allow dynamic WEP key updates through the wireless
1227 * lp - a pointer to the wireless adapter's private structure
1233 ******************************************************************************/
1234 void wl_set_wep_keys( struct wl_private *lp )
1237 /*------------------------------------------------------------------------*/
1238 DBG_FUNC( "wl_set_wep_keys" );
1239 DBG_ENTER( DbgInfo );
1240 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1241 if ( lp->EnableEncryption ) {
1242 /* NOTE: CFG_CNF_ENCRYPTION is set in wl_put_ltv() as it's a static
1246 lp->ltvRecord.len = 2;
1247 lp->ltvRecord.typ = CFG_TX_KEY_ID;
1248 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE(lp->TransmitKeyID - 1);
1250 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1252 DBG_TRACE( DbgInfo, "Key 1 len: %d\n", lp->DefaultKeys.key[0].len );
1253 DBG_TRACE( DbgInfo, "Key 2 len: %d\n", lp->DefaultKeys.key[1].len );
1254 DBG_TRACE( DbgInfo, "Key 3 len: %d\n", lp->DefaultKeys.key[2].len );
1255 DBG_TRACE( DbgInfo, "Key 4 len: %d\n", lp->DefaultKeys.key[3].len );
1258 lp->DefaultKeys.len = sizeof( lp->DefaultKeys ) / sizeof( hcf_16 ) - 1;
1259 lp->DefaultKeys.typ = CFG_DEFAULT_KEYS;
1261 /* endian translate the appropriate key information */
1262 for( count = 0; count < MAX_KEYS; count++ ) {
1263 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1266 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->DefaultKeys ));
1268 /* Reverse the above endian translation, since these keys are accessed
1270 for( count = 0; count < MAX_KEYS; count++ ) {
1271 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1274 DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption, lp->TransmitKeyID );
1275 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 );
1278 DBG_LEAVE( DbgInfo );
1279 } // wl_set_wep_keys
1280 /*============================================================================*/
1283 /*******************************************************************************
1285 *******************************************************************************
1289 * Write the parameters to the adapter. (re-)enables the card if device is
1290 * open. Returns hcf_status of hcf_enable().
1294 * lp - a pointer to the wireless adapter's private structure
1298 * an HCF status code
1300 ******************************************************************************/
1301 int wl_apply(struct wl_private *lp)
1303 int hcf_status = HCF_SUCCESS;
1304 /*------------------------------------------------------------------------*/
1305 DBG_FUNC( "wl_apply" );
1306 DBG_ENTER( DbgInfo );
1307 DBG_ASSERT( lp != NULL);
1308 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1310 if ( !( lp->flags & WVLAN2_UIL_BUSY )) {
1311 /* The adapter parameters have changed:
1317 if ( wl_adapter_is_open( lp->dev )) {
1318 /* Disconnect and disable if necessary */
1319 hcf_status = wl_disconnect( lp );
1320 if ( hcf_status != HCF_SUCCESS ) {
1321 DBG_ERROR( DbgInfo, "Disconnect failed\n" );
1322 DBG_LEAVE( DbgInfo );
1325 hcf_status = wl_disable( lp );
1326 if ( hcf_status != HCF_SUCCESS ) {
1327 DBG_ERROR( DbgInfo, "Disable failed\n" );
1328 DBG_LEAVE( DbgInfo );
1331 /* Write out configuration to the device, enable, and reconnect.
1332 However, only reconnect if in AP mode. For STA mode, need to
1333 wait for passive scan completion before a connect can be
1335 hcf_status = wl_put_ltv( lp );
1337 if ( hcf_status == HCF_SUCCESS ) {
1338 hcf_status = wl_enable( lp );
1340 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1341 hcf_status = wl_connect( lp );
1344 DBG_WARNING( DbgInfo, "wl_put_ltv() failed\n" );
1350 DBG_LEAVE( DbgInfo );
1353 /*============================================================================*/
1356 /*******************************************************************************
1358 *******************************************************************************
1362 * Used to set basic parameters for card initialization.
1366 * lp - a pointer to the wireless adapter's private structure
1370 * an HCF status code
1372 ******************************************************************************/
1373 int wl_put_ltv_init( struct wl_private *lp )
1377 CFG_RID_LOG_STRCT *RidLog;
1378 /*------------------------------------------------------------------------*/
1379 DBG_FUNC( "wl_put_ltv_init" );
1380 DBG_ENTER( DbgInfo );
1382 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1383 DBG_LEAVE( DbgInfo );
1387 lp->ltvRecord.len = 2;
1388 lp->ltvRecord.typ = CFG_CNTL_OPT;
1390 /* The Card Services build must ALWAYS be configured for 16-bit I/O. PCI or
1391 CardBus can be set to either 16/32 bit I/O, or Bus Master DMA, but only
1394 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_16BIT );
1396 if ( lp->use_dma ) {
1397 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_DMA );
1399 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1403 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1404 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT : 0x%04x\n",
1405 lp->ltvRecord.u.u16[0] );
1406 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT result : 0x%04x\n",
1409 /* Register the list of RIDs on which asynchronous notification is
1410 required. Note that this mechanism replaces the mailbox, so the mailbox
1411 can be queried by the host (if desired) without contention from us */
1414 lp->RidList[i].len = sizeof( lp->ProbeResp );
1415 lp->RidList[i].typ = CFG_ACS_SCAN;
1416 lp->RidList[i].bufp = (wci_recordp)&lp->ProbeResp;
1417 //lp->ProbeResp.infoType = 0xFFFF;
1420 lp->RidList[i].len = sizeof( lp->assoc_stat );
1421 lp->RidList[i].typ = CFG_ASSOC_STAT;
1422 lp->RidList[i].bufp = (wci_recordp)&lp->assoc_stat;
1423 lp->assoc_stat.len = 0xFFFF;
1426 lp->RidList[i].len = 4;
1427 lp->RidList[i].typ = CFG_UPDATED_INFO_RECORD;
1428 lp->RidList[i].bufp = (wci_recordp)&lp->updatedRecord;
1429 lp->updatedRecord.len = 0xFFFF;
1432 lp->RidList[i].len = sizeof( lp->sec_stat );
1433 lp->RidList[i].typ = CFG_SECURITY_STAT;
1434 lp->RidList[i].bufp = (wci_recordp)&lp->sec_stat;
1435 lp->sec_stat.len = 0xFFFF;
1438 lp->RidList[i].typ = 0; // Terminate List
1440 RidLog = (CFG_RID_LOG_STRCT *)&lp->ltvRecord;
1442 RidLog->typ = CFG_REG_INFO_LOG;
1443 RidLog->recordp = (RID_LOGP)&lp->RidList[0];
1445 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1446 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG\n" );
1447 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG result : 0x%04x\n",
1449 DBG_LEAVE( DbgInfo );
1451 } // wl_put_ltv_init
1452 /*============================================================================*/
1455 /*******************************************************************************
1457 *******************************************************************************
1461 * Used by wvlan_apply() and wvlan_go to set the card's configuration.
1465 * lp - a pointer to the wireless adapter's private structure
1469 * an HCF status code
1471 ******************************************************************************/
1472 int wl_put_ltv( struct wl_private *lp )
1476 /*------------------------------------------------------------------------*/
1477 DBG_FUNC( "wl_put_ltv" );
1478 DBG_ENTER( DbgInfo );
1481 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1484 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1485 lp->maxPort = 6; //;?why set this here and not as part of download process
1490 /* Send our configuration to the card. Perform any endian translation
1492 /* Register the Mailbox; VxWorks does this elsewhere; why;? */
1493 lp->ltvRecord.len = 4;
1494 lp->ltvRecord.typ = CFG_REG_MB;
1495 lp->ltvRecord.u.u32[0] = (u_long)&( lp->mailbox );
1496 lp->ltvRecord.u.u16[2] = ( MB_SIZE / sizeof( hcf_16 ));
1497 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1499 /* Max Data Length */
1500 lp->ltvRecord.len = 2;
1501 lp->ltvRecord.typ = CFG_CNF_MAX_DATA_LEN;
1502 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( HCF_MAX_PACKET_SIZE );
1503 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1505 /* System Scale / Distance between APs */
1506 lp->ltvRecord.len = 2;
1507 lp->ltvRecord.typ = CFG_CNF_SYSTEM_SCALE;
1508 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DistanceBetweenAPs );
1509 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1512 if ( lp->CreateIBSS && ( lp->Channel == 0 )) {
1513 DBG_TRACE( DbgInfo, "Create IBSS" );
1516 lp->ltvRecord.len = 2;
1517 lp->ltvRecord.typ = CFG_CNF_OWN_CHANNEL;
1518 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->Channel );
1519 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1521 /* Microwave Robustness */
1522 lp->ltvRecord.len = 2;
1523 lp->ltvRecord.typ = CFG_CNF_MICRO_WAVE;
1524 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MicrowaveRobustness );
1525 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1527 /* Load Balancing */
1528 lp->ltvRecord.len = 2;
1529 lp->ltvRecord.typ = CFG_CNF_LOAD_BALANCING;
1530 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->loadBalancing );
1531 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1533 /* Medium Distribution */
1534 lp->ltvRecord.len = 2;
1535 lp->ltvRecord.typ = CFG_CNF_MEDIUM_DISTRIBUTION;
1536 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->mediumDistribution );
1537 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1541 /* Tx Power Level (for supported cards) */
1542 lp->ltvRecord.len = 2;
1543 lp->ltvRecord.typ = CFG_CNF_TX_POW_LVL;
1544 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->txPowLevel );
1545 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1547 /* Short Retry Limit */
1548 /*lp->ltvRecord.len = 2;
1549 lp->ltvRecord.typ = 0xFC32;
1550 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->shortRetryLimit );
1551 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1554 /* Long Retry Limit */
1555 /*lp->ltvRecord.len = 2;
1556 lp->ltvRecord.typ = 0xFC33;
1557 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->longRetryLimit );
1558 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1561 /* Supported Rate Set Control */
1562 lp->ltvRecord.len = 3;
1563 lp->ltvRecord.typ = CFG_SUPPORTED_RATE_SET_CNTL; //0xFC88;
1564 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->srsc[0] );
1565 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->srsc[1] );
1566 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1568 /* Basic Rate Set Control */
1569 lp->ltvRecord.len = 3;
1570 lp->ltvRecord.typ = CFG_BASIC_RATE_SET_CNTL; //0xFC89;
1571 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->brsc[0] );
1572 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->brsc[1] );
1573 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1575 /* Frame Burst Limit */
1576 /* Defined, but not currently available in Firmware */
1581 /* Multicast Rate */
1582 lp->ltvRecord.len = 3;
1583 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1584 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1585 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->MulticastRate[1] );
1587 lp->ltvRecord.len = 2;
1588 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1589 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1591 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1593 /* Own Name (Station Nickname) */
1594 if (( len = ( strlen( lp->StationName ) + 1 ) & ~0x01 ) != 0 ) {
1595 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : %s\n",
1596 // lp->StationName );
1598 lp->ltvRecord.len = 2 + ( len / sizeof( hcf_16 ));
1599 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1600 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->StationName ));
1602 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->StationName, len );
1604 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : EMPTY\n" );
1606 lp->ltvRecord.len = 2;
1607 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1608 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1611 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1613 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME result : 0x%04x\n",
1616 /* The following are set in STA mode only */
1617 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1620 lp->ltvRecord.len = 2;
1621 lp->ltvRecord.typ = CFG_RTS_THRH;
1622 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1623 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1626 lp->ltvRecord.len = 2;
1627 lp->ltvRecord.typ = CFG_CNF_PORT_TYPE;
1628 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PortType );
1629 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1631 /* Tx Rate Control */
1633 lp->ltvRecord.len = 3;
1634 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1635 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1636 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1638 lp->ltvRecord.len = 2;
1639 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1640 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1643 //;?skip temporarily to see whether the RID or something else is the problem hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1645 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 2.4GHz : 0x%04x\n",
1646 lp->TxRateControl[0] );
1647 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 5.0GHz : 0x%04x\n",
1648 lp->TxRateControl[1] );
1649 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL result : 0x%04x\n",
1651 /* Power Management */
1652 lp->ltvRecord.len = 2;
1653 lp->ltvRecord.typ = CFG_CNF_PM_ENABLED;
1654 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PMEnabled );
1655 // lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0x8001 );
1656 DBG_TRACE( DbgInfo, "CFG_CNF_PM_ENABLED : 0x%04x\n", lp->PMEnabled );
1657 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1658 /* Multicast Receive */
1659 lp->ltvRecord.len = 2;
1660 lp->ltvRecord.typ = CFG_CNF_MCAST_RX;
1661 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastReceive );
1662 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1664 /* Max Sleep Duration */
1665 lp->ltvRecord.len = 2;
1666 lp->ltvRecord.typ = CFG_CNF_MAX_SLEEP_DURATION;
1667 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MaxSleepDuration );
1668 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1671 lp->ltvRecord.len = 2;
1672 lp->ltvRecord.typ = CFG_CREATE_IBSS;
1673 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->CreateIBSS );
1674 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1677 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1678 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1679 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1680 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : %s\n",
1681 // lp->NetworkName );
1683 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1684 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1685 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1687 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1689 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : ANY\n" );
1691 lp->ltvRecord.len = 2;
1692 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1693 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1696 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1698 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID result : 0x%04x\n",
1700 /* Own ATIM window */
1701 lp->ltvRecord.len = 2;
1702 lp->ltvRecord.typ = CFG_CNF_OWN_ATIM_WINDOW;
1703 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->atimWindow );
1704 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1707 /* Holdover Duration */
1708 lp->ltvRecord.len = 2;
1709 lp->ltvRecord.typ = CFG_CNF_HOLDOVER_DURATION;
1710 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->holdoverDuration );
1711 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1713 /* Promiscuous Mode */
1714 lp->ltvRecord.len = 2;
1715 lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
1716 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->promiscuousMode );
1717 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1719 /* Authentication */
1720 lp->ltvRecord.len = 2;
1721 lp->ltvRecord.typ = CFG_CNF_AUTHENTICATION;
1722 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->authentication );
1723 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1725 /* Connection Control */
1726 lp->ltvRecord.len = 2;
1727 lp->ltvRecord.typ = CFG_CNF_CONNECTION_CNTL;
1728 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->connectionControl );
1729 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1733 /* Probe data rate */
1734 /*lp->ltvRecord.len = 3;
1735 lp->ltvRecord.typ = CFG_PROBE_DATA_RATE;
1736 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->probeDataRates[0] );
1737 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->probeDataRates[1] );
1738 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1740 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 2.4GHz : 0x%04x\n",
1741 lp->probeDataRates[0] );
1742 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 5.0GHz : 0x%04x\n",
1743 lp->probeDataRates[1] );
1744 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE result : 0x%04x\n",
1748 /* The following are set in AP mode only */
1749 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
1750 //;?should we restore this to allow smaller memory footprint
1753 lp->ltvRecord.len = 2;
1754 lp->ltvRecord.typ = CFG_CNF_OWN_DTIM_PERIOD;
1755 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DTIMPeriod );
1756 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1758 /* Multicast PM Buffering */
1759 lp->ltvRecord.len = 2;
1760 lp->ltvRecord.typ = CFG_CNF_MCAST_PM_BUF;
1761 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->multicastPMBuffering );
1762 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1764 /* Reject ANY - Closed System */
1765 lp->ltvRecord.len = 2;
1766 lp->ltvRecord.typ = CFG_CNF_REJECT_ANY;
1767 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RejectAny );
1769 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1771 /* Exclude Unencrypted */
1772 lp->ltvRecord.len = 2;
1773 lp->ltvRecord.typ = CFG_CNF_EXCL_UNENCRYPTED;
1774 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ExcludeUnencrypted );
1776 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1778 /* IntraBSS Relay */
1779 lp->ltvRecord.len = 2;
1780 lp->ltvRecord.typ = CFG_CNF_INTRA_BSS_RELAY;
1781 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->intraBSSRelay );
1782 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1784 /* RTS Threshold 0 */
1785 lp->ltvRecord.len = 2;
1786 lp->ltvRecord.typ = CFG_RTS_THRH0;
1787 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1789 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1791 /* Tx Rate Control 0 */
1793 lp->ltvRecord.len = 3;
1794 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1795 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1796 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1798 lp->ltvRecord.len = 2;
1799 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1800 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1803 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1805 /* Own Beacon Interval */
1806 lp->ltvRecord.len = 2;
1807 lp->ltvRecord.typ = 0xFC31;
1808 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ownBeaconInterval );
1809 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1811 /* Co-Existence Behavior */
1812 lp->ltvRecord.len = 2;
1813 lp->ltvRecord.typ = 0xFCC7;
1814 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->coexistence );
1815 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1819 /* RTS Threshold 1 */
1820 lp->ltvRecord.len = 2;
1821 lp->ltvRecord.typ = CFG_RTS_THRH1;
1822 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].rtsThreshold );
1823 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1825 /* RTS Threshold 2 */
1826 lp->ltvRecord.len = 2;
1827 lp->ltvRecord.typ = CFG_RTS_THRH2;
1828 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].rtsThreshold );
1829 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1832 /* RTS Threshold 3 */
1833 lp->ltvRecord.len = 2;
1834 lp->ltvRecord.typ = CFG_RTS_THRH3;
1835 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].rtsThreshold );
1836 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1839 /* RTS Threshold 4 */
1840 lp->ltvRecord.len = 2;
1841 lp->ltvRecord.typ = CFG_RTS_THRH4;
1842 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].rtsThreshold );
1843 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1846 /* RTS Threshold 5 */
1847 lp->ltvRecord.len = 2;
1848 lp->ltvRecord.typ = CFG_RTS_THRH5;
1849 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].rtsThreshold );
1850 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1852 /* RTS Threshold 6 */
1853 lp->ltvRecord.len = 2;
1854 lp->ltvRecord.typ = CFG_RTS_THRH6;
1855 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].rtsThreshold );
1856 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1858 /* TX Rate Control 1 */
1859 lp->ltvRecord.len = 2;
1860 lp->ltvRecord.typ = CFG_TX_RATE_CNTL1;
1861 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].txRateCntl );
1862 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1864 /* TX Rate Control 2 */
1865 lp->ltvRecord.len = 2;
1866 lp->ltvRecord.typ = CFG_TX_RATE_CNTL2;
1867 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].txRateCntl );
1868 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1870 /* TX Rate Control 3 */
1871 lp->ltvRecord.len = 2;
1872 lp->ltvRecord.typ = CFG_TX_RATE_CNTL3;
1873 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].txRateCntl );
1874 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1876 /* TX Rate Control 4 */
1877 lp->ltvRecord.len = 2;
1878 lp->ltvRecord.typ = CFG_TX_RATE_CNTL4;
1879 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].txRateCntl );
1880 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1882 /* TX Rate Control 5 */
1883 lp->ltvRecord.len = 2;
1884 lp->ltvRecord.typ = CFG_TX_RATE_CNTL5;
1885 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].txRateCntl );
1886 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1888 /* TX Rate Control 6 */
1889 lp->ltvRecord.len = 2;
1890 lp->ltvRecord.typ = CFG_TX_RATE_CNTL6;
1891 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].txRateCntl );
1892 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1896 /* WDS addresses. It's okay to blindly send these parameters, because
1897 the port needs to be enabled, before anything is done with it. */
1900 lp->ltvRecord.len = 4;
1901 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR1;
1903 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[0].wdsAddress, ETH_ALEN );
1904 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1907 lp->ltvRecord.len = 4;
1908 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR2;
1910 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[1].wdsAddress, ETH_ALEN );
1911 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1914 lp->ltvRecord.len = 4;
1915 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR3;
1917 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[2].wdsAddress, ETH_ALEN );
1918 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1921 lp->ltvRecord.len = 4;
1922 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR4;
1924 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[3].wdsAddress, ETH_ALEN );
1925 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1928 lp->ltvRecord.len = 4;
1929 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR5;
1931 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[4].wdsAddress, ETH_ALEN );
1932 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1935 lp->ltvRecord.len = 4;
1936 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR6;
1938 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[5].wdsAddress, ETH_ALEN );
1939 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1940 #endif /* USE_WDS */
1941 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1944 /* Own MAC Address */
1946 DBG_TRACE(DbgInfo, "MAC Address : %pM\n",
1950 if ( WVLAN_VALID_MAC_ADDRESS( lp->MACAddress )) {
1951 /* Make the MAC address valid by:
1952 Clearing the multicast bit
1953 Setting the local MAC address bit
1955 //lp->MACAddress[0] &= ~0x03; //;?why is this commented out already in 720
1956 //lp->MACAddress[0] |= 0x02;
1958 lp->ltvRecord.len = 1 + ( ETH_ALEN / sizeof( hcf_16 ));
1959 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1960 //DBG_TRACE( DbgInfo, "CFG_NIC_MAC_ADDR\n" );
1961 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1963 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_MAC_ADDR\n" );
1964 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1966 /* MAC address is byte aligned, no endian conversion needed */
1967 memcpy( &( lp->ltvRecord.u.u8[0] ), lp->MACAddress, ETH_ALEN );
1968 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1969 //DBG_TRACE( DbgInfo, "CFG_XXX_MAC_ADDR result : 0x%04x\n",
1972 /* Update the MAC address in the netdevice struct */
1973 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN ); //;?what is the purpose of this seemingly complex logic
1976 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1977 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1978 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1979 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : %s\n",
1980 // lp->NetworkName );
1981 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1982 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1983 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1985 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1987 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : ANY\n" );
1988 lp->ltvRecord.len = 2;
1989 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1990 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1993 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1995 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID result : 0x%04x\n",
1997 /* enable/disable encryption */
1998 lp->ltvRecord.len = 2;
1999 lp->ltvRecord.typ = CFG_CNF_ENCRYPTION;
2000 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->EnableEncryption );
2001 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2003 /* Set the Authentication Key Management Suite */
2004 lp->ltvRecord.len = 2;
2005 lp->ltvRecord.typ = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
2006 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->AuthKeyMgmtSuite );
2007 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2009 /* If WEP (or no) keys are being used, write (or clear) them */
2010 if (lp->wext_enc != IW_ENCODE_ALG_TKIP)
2011 wl_set_wep_keys(lp);
2014 /* countryInfo, ltvCountryInfo, CFG_CNF_COUNTRY_INFO */
2016 DBG_LEAVE( DbgInfo );
2019 /*============================================================================*/
2022 /*******************************************************************************
2024 *******************************************************************************
2028 * Load the kernel module.
2037 * an errno value otherwise
2039 ******************************************************************************/
2040 static int __init wl_module_init( void )
2043 /*------------------------------------------------------------------------*/
2045 DBG_FUNC( "wl_module_init" );
2048 /* Convert "standard" PCMCIA parameter pc_debug to a reasonable DebugFlag value.
2049 * NOTE: The values all fall through to the lower values. */
2050 DbgInfo->DebugFlag = 0;
2051 DbgInfo->DebugFlag = DBG_TRACE_ON; //;?get this mess resolved one day
2052 if ( pc_debug ) switch( pc_debug ) {
2054 DbgInfo->DebugFlag |= DBG_DS_ON;
2056 DbgInfo->DebugFlag |= DBG_RX_ON | DBG_TX_ON;
2058 DbgInfo->DebugFlag |= DBG_PARAM_ON;
2060 DbgInfo->DebugFlag |= DBG_TRACE_ON;
2062 DbgInfo->DebugFlag |= DBG_VERBOSE_ON;
2064 DbgInfo->DebugFlag |= DBG_DEFAULTS;
2070 DBG_ENTER( DbgInfo );
2071 printk(KERN_INFO "%s\n", VERSION_INFO);
2072 printk(KERN_INFO "*** Modified for kernel 2.6 by Henk de Groot <pe1dnn@amsat.org>\n");
2073 printk(KERN_INFO "*** Based on 7.18 version by Andrey Borzenkov <arvidjaar@mail.ru> $Revision: 39 $\n");
2076 // ;?#if (HCF_TYPE) & HCF_TYPE_AP
2077 // DBG_PRINT( "Access Point Mode (AP) Support: YES\n" );
2079 // DBG_PRINT( "Access Point Mode (AP) Support: NO\n" );
2080 // #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2082 result = wl_adapter_init_module( );
2083 DBG_LEAVE( DbgInfo );
2086 /*============================================================================*/
2089 /*******************************************************************************
2091 *******************************************************************************
2095 * Unload the kernel module.
2105 ******************************************************************************/
2106 static void __exit wl_module_exit( void )
2108 DBG_FUNC( "wl_module_exit" );
2111 wl_adapter_cleanup_module( );
2112 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
2113 remove_proc_entry( "wlags", NULL ); //;?why so a-symmetric compared to location of proc_create_data
2116 DBG_LEAVE( DbgInfo );
2119 /*============================================================================*/
2121 module_init(wl_module_init);
2122 module_exit(wl_module_exit);
2124 /*******************************************************************************
2126 *******************************************************************************
2130 * The Interrupt Service Routine for the driver.
2134 * irq - the irq the interrupt came in on
2135 * dev_id - a buffer containing information about the request
2142 ******************************************************************************/
2143 irqreturn_t wl_isr( int irq, void *dev_id, struct pt_regs *regs )
2146 struct net_device *dev = (struct net_device *) dev_id;
2147 struct wl_private *lp = NULL;
2148 /*------------------------------------------------------------------------*/
2149 if (( dev == NULL ) || ( !netif_device_present( dev ))) {
2153 /* Set the wl_private pointer (lp), now that we know that dev is non-null */
2157 if ( lp->useRTS == 1 ) {
2158 DBG_PRINT( "EXITING ISR, IN RTS MODE...\n" );
2161 #endif /* USE_RTS */
2163 /* If we have interrupts pending, then put them on a system task
2164 queue. Otherwise turn interrupts back on */
2165 events = hcf_action( &lp->hcfCtx, HCF_ACT_INT_OFF );
2167 if ( events == HCF_INT_PENDING ) {
2168 /* Schedule the ISR handler as a bottom-half task in the
2169 tq_immediate queue */
2170 tasklet_schedule(&lp->task);
2172 //DBG_PRINT( "NOT OUR INTERRUPT\n" );
2173 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2176 return IRQ_RETVAL(events == HCF_INT_PENDING);
2178 /*============================================================================*/
2181 /*******************************************************************************
2183 *******************************************************************************
2187 * The ISR handler, scheduled to run in a deferred context by the ISR. This
2188 * is where the ISR's work actually gets done.
2192 * lp - a pointer to the device's private adapter structure
2198 ******************************************************************************/
2199 #define WVLAN_MAX_INT_SERVICES 50
2201 void wl_isr_handler( unsigned long p )
2203 struct net_device *dev;
2204 unsigned long flags;
2208 struct wl_private *lp = (struct wl_private *)p;
2209 /*------------------------------------------------------------------------*/
2212 DBG_PRINT( "wl_isr_handler lp adapter pointer is NULL!!!\n" );
2214 wl_lock( lp, &flags );
2216 dev = (struct net_device *)lp->dev;
2217 if ( dev != NULL && netif_device_present( dev ) ) stop = FALSE;
2218 for( count = 0; stop == FALSE && count < WVLAN_MAX_INT_SERVICES; count++ ) {
2220 result = hcf_service_nic( &lp->hcfCtx,
2221 (wci_bufp)lp->lookAheadBuf,
2222 sizeof( lp->lookAheadBuf ));
2223 if ( result == HCF_ERR_MIC ) {
2224 wl_wext_event_mic_failed( dev ); /* Send an event that MIC failed */
2225 //;?this seems wrong if HCF_ERR_MIC coincides with another event, stop gets FALSE
2226 //so why not do it always ;?
2229 #ifndef USE_MBOX_SYNC
2230 if ( lp->hcfCtx.IFB_MBInfoLen != 0 ) { /* anything in the mailbox */
2235 /* Check for a Link status event */
2236 if ( ( lp->hcfCtx.IFB_LinkStat & CFG_LINK_STAT_FW ) != 0 ) {
2237 wl_process_link_status( lp );
2240 /* Check for probe response events */
2241 if ( lp->ProbeResp.infoType != 0 &&
2242 lp->ProbeResp.infoType != 0xFFFF ) {
2243 wl_process_probe_response( lp );
2244 memset( &lp->ProbeResp, 0, sizeof( lp->ProbeResp ));
2245 lp->ProbeResp.infoType = 0xFFFF;
2248 /* Check for updated record events */
2249 if ( lp->updatedRecord.len != 0xFFFF ) {
2250 wl_process_updated_record( lp );
2251 lp->updatedRecord.len = 0xFFFF;
2254 /* Check for association status events */
2255 if ( lp->assoc_stat.len != 0xFFFF ) {
2256 wl_process_assoc_status( lp );
2257 lp->assoc_stat.len = 0xFFFF;
2260 /* Check for security status events */
2261 if ( lp->sec_stat.len != 0xFFFF ) {
2262 wl_process_security_status( lp );
2263 lp->sec_stat.len = 0xFFFF;
2268 if ( lp->use_dma ) {
2269 /* Check for DMA Rx packets */
2270 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_RDMAD ) {
2274 /* Return Tx DMA descriptors to host */
2275 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_TDMAD ) {
2276 wl_pci_dma_hcf_reclaim_tx( lp );
2281 #endif // ENABLE_DMA
2283 /* Check for Rx packets */
2284 if ( lp->hcfCtx.IFB_RxLen != 0 ) {
2288 /* Make sure that queued frames get sent */
2289 if ( wl_send( lp )) {
2294 /* We're done, so turn interrupts which were turned off in wl_isr, back on */
2295 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2296 wl_unlock( lp, &flags );
2300 /*============================================================================*/
2303 /*******************************************************************************
2305 *******************************************************************************
2309 * Notify the adapter that it has been removed. Since the adapter is gone,
2310 * we should no longer try to talk to it.
2314 * dev - a pointer to the device's net_device structure
2320 ******************************************************************************/
2321 void wl_remove( struct net_device *dev )
2323 struct wl_private *lp = wl_priv(dev);
2324 unsigned long flags;
2325 /*------------------------------------------------------------------------*/
2326 DBG_FUNC( "wl_remove" );
2327 DBG_ENTER( DbgInfo );
2329 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2331 wl_lock( lp, &flags );
2333 /* stop handling interrupts */
2334 wl_act_int_off( lp );
2335 lp->is_handling_int = WL_NOT_HANDLING_INT;
2338 * Disable the ports: just change state: since the
2339 * card is gone it is useless to talk to it and at
2340 * disconnect all state information is lost anyway.
2342 /* Reset portState */
2343 lp->portState = WVLAN_PORT_STATE_DISABLED;
2345 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
2347 //wl_disable_wds_ports( lp );
2349 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2351 /* Mark the device as unregistered */
2352 lp->is_registered = FALSE;
2354 /* Deregister the WDS ports as well */
2355 WL_WDS_NETDEV_DEREGISTER( lp );
2357 if ( lp->useRTS == 1 ) {
2358 wl_unlock( lp, &flags );
2360 DBG_LEAVE( DbgInfo );
2363 #endif /* USE_RTS */
2365 /* Inform the HCF that the card has been removed */
2366 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2368 wl_unlock( lp, &flags );
2370 DBG_LEAVE( DbgInfo );
2373 /*============================================================================*/
2376 /*******************************************************************************
2378 *******************************************************************************
2382 * Power-down and halt the adapter.
2386 * dev - a pointer to the device's net_device structure
2392 ******************************************************************************/
2393 void wl_suspend( struct net_device *dev )
2395 struct wl_private *lp = wl_priv(dev);
2396 unsigned long flags;
2397 /*------------------------------------------------------------------------*/
2398 DBG_FUNC( "wl_suspend" );
2399 DBG_ENTER( DbgInfo );
2401 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2403 /* The adapter is suspended:
2407 wl_lock( lp, &flags );
2409 /* Disable interrupt handling */
2410 wl_act_int_off( lp );
2413 wl_disconnect( lp );
2418 /* Disconnect from the adapter */
2419 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2421 /* Reset portState to be sure (should have been done by wl_disable */
2422 lp->portState = WVLAN_PORT_STATE_DISABLED;
2424 wl_unlock( lp, &flags );
2426 DBG_LEAVE( DbgInfo );
2429 /*============================================================================*/
2432 /*******************************************************************************
2434 *******************************************************************************
2438 * Resume a previously suspended adapter.
2442 * dev - a pointer to the device's net_device structure
2448 ******************************************************************************/
2449 void wl_resume(struct net_device *dev)
2451 struct wl_private *lp = wl_priv(dev);
2452 unsigned long flags;
2453 /*------------------------------------------------------------------------*/
2454 DBG_FUNC( "wl_resume" );
2455 DBG_ENTER( DbgInfo );
2457 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2459 wl_lock( lp, &flags );
2461 /* Connect to the adapter */
2462 hcf_connect( &lp->hcfCtx, dev->base_addr );
2464 /* Reset portState */
2465 lp->portState = WVLAN_PORT_STATE_DISABLED;
2467 /* Power might have been off, assume the card lost the firmware*/
2468 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
2470 /* Reload the firmware and restart */
2473 /* Resume interrupt handling */
2474 wl_act_int_on( lp );
2476 wl_unlock( lp, &flags );
2478 DBG_LEAVE( DbgInfo );
2481 /*============================================================================*/
2484 /*******************************************************************************
2486 *******************************************************************************
2490 * This function performs a check on the device and calls wl_remove() if
2491 * necessary. This function can be used for all bus types, but exists mostly
2492 * for the benefit of the Card Services driver, as there are times when
2493 * wl_remove() does not get called.
2497 * dev - a pointer to the device's net_device structure
2503 ******************************************************************************/
2504 void wl_release( struct net_device *dev )
2506 struct wl_private *lp = wl_priv(dev);
2507 /*------------------------------------------------------------------------*/
2508 DBG_FUNC( "wl_release" );
2509 DBG_ENTER( DbgInfo );
2511 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2512 /* If wl_remove() hasn't been called (i.e. when Card Services is shut
2513 down with the card in the slot), then call it */
2514 if ( lp->is_registered == TRUE ) {
2515 DBG_TRACE( DbgInfo, "Calling unregister_netdev(), as it wasn't called yet\n" );
2518 lp->is_registered = FALSE;
2521 DBG_LEAVE( DbgInfo );
2524 /*============================================================================*/
2527 /*******************************************************************************
2529 *******************************************************************************
2533 * Accessor function to retrieve the irq_mask module parameter
2541 * The irq_mask module parameter
2543 ******************************************************************************/
2544 p_u16 wl_get_irq_mask( void )
2547 } // wl_get_irq_mask
2548 /*============================================================================*/
2551 /*******************************************************************************
2553 *******************************************************************************
2557 * Accessor function to retrieve the irq_list module parameter
2565 * The irq_list module parameter
2567 ******************************************************************************/
2568 p_s8 * wl_get_irq_list( void )
2571 } // wl_get_irq_list
2572 /*============================================================================*/
2576 /*******************************************************************************
2578 *******************************************************************************
2582 * Used to enable MAC ports
2586 * lp - pointer to the device's private adapter structure
2592 ******************************************************************************/
2593 int wl_enable( struct wl_private *lp )
2595 int hcf_status = HCF_SUCCESS;
2596 /*------------------------------------------------------------------------*/
2597 DBG_FUNC( "wl_enable" );
2598 DBG_ENTER( DbgInfo );
2600 if ( lp->portState == WVLAN_PORT_STATE_ENABLED ) {
2601 DBG_TRACE( DbgInfo, "No action: Card already enabled\n" );
2602 } else if ( lp->portState == WVLAN_PORT_STATE_CONNECTED ) {
2603 //;?suspicuous logic, how can you be connected without being enabled so this is probably dead code
2604 DBG_TRACE( DbgInfo, "No action: Card already connected\n" );
2606 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_ENABLE );
2607 if ( hcf_status == HCF_SUCCESS ) {
2608 /* Set the status of the NIC to enabled */
2609 lp->portState = WVLAN_PORT_STATE_ENABLED; //;?bad mnemonic, NIC iso PORT
2611 if ( lp->use_dma ) {
2612 wl_pci_dma_hcf_supply( lp ); //;?always successful?
2617 if ( hcf_status != HCF_SUCCESS ) { //;?make this an assert
2618 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2620 DBG_LEAVE( DbgInfo );
2623 /*============================================================================*/
2627 /*******************************************************************************
2628 * wl_enable_wds_ports()
2629 *******************************************************************************
2633 * Used to enable the WDS MAC ports 1-6
2637 * lp - pointer to the device's private adapter structure
2643 ******************************************************************************/
2644 void wl_enable_wds_ports( struct wl_private * lp )
2647 DBG_FUNC( "wl_enable_wds_ports" );
2648 DBG_ENTER( DbgInfo );
2649 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2650 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2652 DBG_LEAVE( DbgInfo );
2654 } // wl_enable_wds_ports
2655 #endif /* USE_WDS */
2656 /*============================================================================*/
2659 /*******************************************************************************
2661 *******************************************************************************
2665 * Used to connect a MAC port
2669 * lp - pointer to the device's private adapter structure
2675 ******************************************************************************/
2676 int wl_connect( struct wl_private *lp )
2679 /*------------------------------------------------------------------------*/
2681 DBG_FUNC( "wl_connect" );
2682 DBG_ENTER( DbgInfo );
2684 if ( lp->portState != WVLAN_PORT_STATE_ENABLED ) {
2685 DBG_TRACE( DbgInfo, "No action: Not in enabled state\n" );
2686 DBG_LEAVE( DbgInfo );
2689 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_CONNECT );
2690 if ( hcf_status == HCF_SUCCESS ) {
2691 lp->portState = WVLAN_PORT_STATE_CONNECTED;
2693 DBG_LEAVE( DbgInfo );
2696 /*============================================================================*/
2699 /*******************************************************************************
2701 *******************************************************************************
2705 * Used to disconnect a MAC port
2709 * lp - pointer to the device's private adapter structure
2715 ******************************************************************************/
2716 int wl_disconnect( struct wl_private *lp )
2719 /*------------------------------------------------------------------------*/
2721 DBG_FUNC( "wl_disconnect" );
2722 DBG_ENTER( DbgInfo );
2724 if ( lp->portState != WVLAN_PORT_STATE_CONNECTED ) {
2725 DBG_TRACE( DbgInfo, "No action: Not in connected state\n" );
2726 DBG_LEAVE( DbgInfo );
2729 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISCONNECT );
2730 if ( hcf_status == HCF_SUCCESS ) {
2731 lp->portState = WVLAN_PORT_STATE_ENABLED;
2733 DBG_LEAVE( DbgInfo );
2736 /*============================================================================*/
2739 /*******************************************************************************
2741 *******************************************************************************
2745 * Used to disable MAC ports
2749 * lp - pointer to the device's private adapter structure
2750 * port - the MAC port to disable
2756 ******************************************************************************/
2757 int wl_disable( struct wl_private *lp )
2759 int hcf_status = HCF_SUCCESS;
2760 /*------------------------------------------------------------------------*/
2761 DBG_FUNC( "wl_disable" );
2762 DBG_ENTER( DbgInfo );
2764 if ( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
2765 DBG_TRACE( DbgInfo, "No action: Port state is disabled\n" );
2767 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISABLE );
2768 if ( hcf_status == HCF_SUCCESS ) {
2769 /* Set the status of the port to disabled */ //;?bad mnemonic use NIC iso PORT
2770 lp->portState = WVLAN_PORT_STATE_DISABLED;
2773 if ( lp->use_dma ) {
2774 wl_pci_dma_hcf_reclaim( lp );
2779 if ( hcf_status != HCF_SUCCESS ) {
2780 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2782 DBG_LEAVE( DbgInfo );
2785 /*============================================================================*/
2789 /*******************************************************************************
2790 * wl_disable_wds_ports()
2791 *******************************************************************************
2795 * Used to disable the WDS MAC ports 1-6
2799 * lp - pointer to the device's private adapter structure
2805 ******************************************************************************/
2806 void wl_disable_wds_ports( struct wl_private * lp )
2809 DBG_FUNC( "wl_disable_wds_ports" );
2810 DBG_ENTER( DbgInfo );
2812 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2813 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2815 // if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
2816 // wl_disable( lp, HCF_PORT_1 );
2817 // wl_disable( lp, HCF_PORT_2 );
2818 // wl_disable( lp, HCF_PORT_3 );
2819 // wl_disable( lp, HCF_PORT_4 );
2820 // wl_disable( lp, HCF_PORT_5 );
2821 // wl_disable( lp, HCF_PORT_6 );
2823 DBG_LEAVE( DbgInfo );
2825 } // wl_disable_wds_ports
2827 /*============================================================================*/
2830 #ifndef USE_MBOX_SYNC
2831 /*******************************************************************************
2833 *******************************************************************************
2836 * This function is used to read and process a mailbox message.
2841 * lp - pointer to the device's private adapter structure
2845 * an HCF status code
2847 ******************************************************************************/
2848 int wl_mbx( struct wl_private *lp )
2850 int hcf_status = HCF_SUCCESS;
2851 /*------------------------------------------------------------------------*/
2852 DBG_FUNC( "wl_mbx" );
2853 DBG_ENTER( DbgInfo );
2854 DBG_TRACE( DbgInfo, "Mailbox Info: IFB_MBInfoLen: %d\n",
2855 lp->hcfCtx.IFB_MBInfoLen );
2857 memset( &( lp->ltvRecord ), 0, sizeof( ltv_t ));
2859 lp->ltvRecord.len = MB_SIZE;
2860 lp->ltvRecord.typ = CFG_MB_INFO;
2861 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2863 if ( hcf_status != HCF_SUCCESS ) {
2864 DBG_ERROR( DbgInfo, "hcf_get_info returned 0x%x\n", hcf_status );
2866 DBG_LEAVE( DbgInfo );
2870 if ( lp->ltvRecord.typ == CFG_MB_INFO ) {
2871 DBG_LEAVE( DbgInfo );
2874 /* Endian translate the mailbox data, then process the message */
2875 wl_endian_translate_mailbox( &( lp->ltvRecord ));
2876 wl_process_mailbox( lp );
2877 DBG_LEAVE( DbgInfo );
2880 /*============================================================================*/
2883 /*******************************************************************************
2884 * wl_endian_translate_mailbox()
2885 *******************************************************************************
2889 * This function will perform the tedious task of endian translating all
2890 * fields within a mailbox message which need translating.
2894 * ltv - pointer to the LTV to endian translate
2900 ******************************************************************************/
2901 void wl_endian_translate_mailbox( ltv_t *ltv )
2904 DBG_FUNC( "wl_endian_translate_mailbox" );
2905 DBG_ENTER( DbgInfo );
2906 switch( ltv->typ ) {
2913 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
2915 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2916 ( sizeof( SCAN_RS_STRCT )));
2918 while( num_aps >= 1 ) {
2921 aps[num_aps].channel_id =
2922 CNV_LITTLE_TO_INT( aps[num_aps].channel_id );
2924 aps[num_aps].noise_level =
2925 CNV_LITTLE_TO_INT( aps[num_aps].noise_level );
2927 aps[num_aps].signal_level =
2928 CNV_LITTLE_TO_INT( aps[num_aps].signal_level );
2930 aps[num_aps].beacon_interval_time =
2931 CNV_LITTLE_TO_INT( aps[num_aps].beacon_interval_time );
2933 aps[num_aps].capability =
2934 CNV_LITTLE_TO_INT( aps[num_aps].capability );
2936 aps[num_aps].ssid_len =
2937 CNV_LITTLE_TO_INT( aps[num_aps].ssid_len );
2939 aps[num_aps].ssid_val[aps[num_aps].ssid_len] = 0;
2946 PROBE_RESP *probe_resp = (PROBE_RESP *)ltv;
2948 probe_resp->frameControl = CNV_LITTLE_TO_INT( probe_resp->frameControl );
2949 probe_resp->durID = CNV_LITTLE_TO_INT( probe_resp->durID );
2950 probe_resp->sequence = CNV_LITTLE_TO_INT( probe_resp->sequence );
2951 probe_resp->dataLength = CNV_LITTLE_TO_INT( probe_resp->dataLength );
2953 probe_resp->lenType = CNV_LITTLE_TO_INT( probe_resp->lenType );
2955 probe_resp->beaconInterval = CNV_LITTLE_TO_INT( probe_resp->beaconInterval );
2956 probe_resp->capability = CNV_LITTLE_TO_INT( probe_resp->capability );
2957 probe_resp->flags = CNV_LITTLE_TO_INT( probe_resp->flags );
2962 #define ls ((LINK_STATUS_STRCT *)ltv)
2963 ls->linkStatus = CNV_LITTLE_TO_INT( ls->linkStatus );
2967 case CFG_ASSOC_STAT:
2969 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
2971 as->assocStatus = CNV_LITTLE_TO_INT( as->assocStatus );
2975 case CFG_SECURITY_STAT:
2977 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
2979 ss->securityStatus = CNV_LITTLE_TO_INT( ss->securityStatus );
2980 ss->reason = CNV_LITTLE_TO_INT( ss->reason );
2994 DBG_LEAVE( DbgInfo );
2996 } // wl_endian_translate_mailbox
2997 /*============================================================================*/
2999 /*******************************************************************************
3000 * wl_process_mailbox()
3001 *******************************************************************************
3005 * This function processes the mailbox data.
3009 * ltv - pointer to the LTV to be processed.
3015 ******************************************************************************/
3016 void wl_process_mailbox( struct wl_private *lp )
3019 hcf_16 ltv_val = 0xFFFF;
3020 /*------------------------------------------------------------------------*/
3021 DBG_FUNC( "wl_process_mailbox" );
3022 DBG_ENTER( DbgInfo );
3023 ltv = &( lp->ltvRecord );
3025 switch( ltv->typ ) {
3028 DBG_TRACE( DbgInfo, "CFG_TALLIES\n" );
3031 DBG_TRACE( DbgInfo, "CFG_SCAN\n" );
3035 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
3037 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
3038 ( sizeof( SCAN_RS_STRCT )));
3040 lp->scan_results.num_aps = num_aps;
3042 DBG_TRACE( DbgInfo, "Number of APs: %d\n", num_aps );
3044 while( num_aps >= 1 ) {
3047 DBG_TRACE( DbgInfo, "AP : %d\n", num_aps );
3048 DBG_TRACE( DbgInfo, "=========================\n" );
3049 DBG_TRACE( DbgInfo, "Channel ID : 0x%04x\n",
3050 aps[num_aps].channel_id );
3051 DBG_TRACE( DbgInfo, "Noise Level : 0x%04x\n",
3052 aps[num_aps].noise_level );
3053 DBG_TRACE( DbgInfo, "Signal Level : 0x%04x\n",
3054 aps[num_aps].signal_level );
3055 DBG_TRACE( DbgInfo, "Beacon Interval : 0x%04x\n",
3056 aps[num_aps].beacon_interval_time );
3057 DBG_TRACE( DbgInfo, "Capability : 0x%04x\n",
3058 aps[num_aps].capability );
3059 DBG_TRACE( DbgInfo, "SSID Length : 0x%04x\n",
3060 aps[num_aps].ssid_len );
3061 DBG_TRACE(DbgInfo, "BSSID : %pM\n",
3062 aps[num_aps].bssid);
3064 if ( aps[num_aps].ssid_len != 0 ) {
3065 DBG_TRACE( DbgInfo, "SSID : %s.\n",
3066 aps[num_aps].ssid_val );
3068 DBG_TRACE( DbgInfo, "SSID : %s.\n", "ANY" );
3071 DBG_TRACE( DbgInfo, "\n" );
3073 /* Copy the info to the ScanResult structure in the private
3075 memcpy( &( lp->scan_results.APTable[num_aps]), &( aps[num_aps] ),
3076 sizeof( SCAN_RS_STRCT ));
3079 /* Set scan result to true so that any scan requests will
3081 lp->scan_results.scan_complete = TRUE;
3086 DBG_TRACE( DbgInfo, "CFG_ACS_SCAN\n" );
3089 PROBE_RESP *probe_rsp = (PROBE_RESP *)ltv;
3090 hcf_8 *wpa_ie = NULL;
3091 hcf_16 wpa_ie_len = 0;
3093 DBG_TRACE( DbgInfo, "(%s) =========================\n",
3096 DBG_TRACE( DbgInfo, "(%s) length : 0x%04x.\n",
3097 lp->dev->name, probe_rsp->length );
3099 if ( probe_rsp->length > 1 ) {
3100 DBG_TRACE( DbgInfo, "(%s) infoType : 0x%04x.\n",
3101 lp->dev->name, probe_rsp->infoType );
3103 DBG_TRACE( DbgInfo, "(%s) signal : 0x%02x.\n",
3104 lp->dev->name, probe_rsp->signal );
3106 DBG_TRACE( DbgInfo, "(%s) silence : 0x%02x.\n",
3107 lp->dev->name, probe_rsp->silence );
3109 DBG_TRACE( DbgInfo, "(%s) rxFlow : 0x%02x.\n",
3110 lp->dev->name, probe_rsp->rxFlow );
3112 DBG_TRACE( DbgInfo, "(%s) rate : 0x%02x.\n",
3113 lp->dev->name, probe_rsp->rate );
3115 DBG_TRACE( DbgInfo, "(%s) frame cntl : 0x%04x.\n",
3116 lp->dev->name, probe_rsp->frameControl );
3118 DBG_TRACE( DbgInfo, "(%s) durID : 0x%04x.\n",
3119 lp->dev->name, probe_rsp->durID );
3121 DBG_TRACE(DbgInfo, "(%s) address1 : %pM\n",
3122 lp->dev->name, probe_rsp->address1);
3124 DBG_TRACE(DbgInfo, "(%s) address2 : %pM\n",
3125 lp->dev->name, probe_rsp->address2);
3127 DBG_TRACE(DbgInfo, "(%s) BSSID : %pM\n",
3128 lp->dev->name, probe_rsp->BSSID);
3130 DBG_TRACE( DbgInfo, "(%s) sequence : 0x%04x.\n",
3131 lp->dev->name, probe_rsp->sequence );
3133 DBG_TRACE(DbgInfo, "(%s) address4 : %pM\n",
3134 lp->dev->name, probe_rsp->address4);
3136 DBG_TRACE( DbgInfo, "(%s) datalength : 0x%04x.\n",
3137 lp->dev->name, probe_rsp->dataLength );
3139 DBG_TRACE(DbgInfo, "(%s) DA : %pM\n",
3140 lp->dev->name, probe_rsp->DA);
3142 DBG_TRACE(DbgInfo, "(%s) SA : %pM\n",
3143 lp->dev->name, probe_rsp->SA);
3145 //DBG_TRACE( DbgInfo, "(%s) lenType : 0x%04x.\n",
3146 // lp->dev->name, probe_rsp->lenType );
3148 DBG_TRACE(DbgInfo, "(%s) timeStamp : "
3149 "%d.%d.%d.%d.%d.%d.%d.%d\n",
3151 probe_rsp->timeStamp[0],
3152 probe_rsp->timeStamp[1],
3153 probe_rsp->timeStamp[2],
3154 probe_rsp->timeStamp[3],
3155 probe_rsp->timeStamp[4],
3156 probe_rsp->timeStamp[5],
3157 probe_rsp->timeStamp[6],
3158 probe_rsp->timeStamp[7]);
3160 DBG_TRACE( DbgInfo, "(%s) beaconInt : 0x%04x.\n",
3161 lp->dev->name, probe_rsp->beaconInterval );
3163 DBG_TRACE( DbgInfo, "(%s) capability : 0x%04x.\n",
3164 lp->dev->name, probe_rsp->capability );
3166 DBG_TRACE( DbgInfo, "(%s) SSID len : 0x%04x.\n",
3167 lp->dev->name, probe_rsp->rawData[1] );
3169 if ( probe_rsp->rawData[1] > 0 ) {
3170 char ssid[HCF_MAX_NAME_LEN];
3172 memset( ssid, 0, sizeof( ssid ));
3173 strncpy( ssid, &probe_rsp->rawData[2],
3174 probe_rsp->rawData[1] );
3176 DBG_TRACE( DbgInfo, "(%s) SSID : %s\n",
3177 lp->dev->name, ssid );
3180 /* Parse out the WPA-IE, if one exists */
3181 wpa_ie = wl_parse_wpa_ie( probe_rsp, &wpa_ie_len );
3182 if ( wpa_ie != NULL ) {
3183 DBG_TRACE( DbgInfo, "(%s) WPA-IE : %s\n",
3184 lp->dev->name, wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
3187 DBG_TRACE( DbgInfo, "(%s) flags : 0x%04x.\n",
3188 lp->dev->name, probe_rsp->flags );
3191 DBG_TRACE( DbgInfo, "\n\n" );
3192 /* If probe response length is 1, then the scan is complete */
3193 if ( probe_rsp->length == 1 ) {
3194 DBG_TRACE( DbgInfo, "SCAN COMPLETE\n" );
3195 lp->probe_results.num_aps = lp->probe_num_aps;
3196 lp->probe_results.scan_complete = TRUE;
3198 /* Reset the counter for the next scan request */
3199 lp->probe_num_aps = 0;
3201 /* Send a wireless extensions event that the scan completed */
3202 wl_wext_event_scan_complete( lp->dev );
3204 /* Only copy to the table if the entry is unique; APs sometimes
3205 respond more than once to a probe */
3206 if ( lp->probe_num_aps == 0 ) {
3207 /* Copy the info to the ScanResult structure in the private
3209 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3210 probe_rsp, sizeof( PROBE_RESP ));
3212 /* Increment the number of APs detected */
3213 lp->probe_num_aps++;
3218 for( count = 0; count < lp->probe_num_aps; count++ ) {
3219 if ( memcmp( &( probe_rsp->BSSID ),
3220 lp->probe_results.ProbeTable[count].BSSID,
3227 /* Copy the info to the ScanResult structure in the
3228 private adapter struct. Only copy if there's room in the
3230 if ( lp->probe_num_aps < MAX_NAPS )
3232 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3233 probe_rsp, sizeof( PROBE_RESP ));
3237 DBG_WARNING( DbgInfo, "Num of scan results exceeds storage, truncating\n" );
3240 /* Increment the number of APs detected. Note I do this
3241 here even when I don't copy the probe response to the
3242 buffer in order to detect the overflow condition */
3243 lp->probe_num_aps++;
3252 #define ls ((LINK_STATUS_STRCT *)ltv)
3253 DBG_TRACE( DbgInfo, "CFG_LINK_STAT\n" );
3255 switch( ls->linkStatus ) {
3257 DBG_TRACE( DbgInfo, "Link Status : Connected\n" );
3258 wl_wext_event_ap( lp->dev );
3262 DBG_TRACE( DbgInfo, "Link Status : Disconnected\n" );
3266 DBG_TRACE( DbgInfo, "Link Status : Access Point Change\n" );
3270 DBG_TRACE( DbgInfo, "Link Status : Access Point Out of Range\n" );
3274 DBG_TRACE( DbgInfo, "Link Status : Access Point In Range\n" );
3278 DBG_TRACE( DbgInfo, "Link Status : UNKNOWN (0x%04x)\n",
3286 case CFG_ASSOC_STAT:
3287 DBG_TRACE( DbgInfo, "CFG_ASSOC_STAT\n" );
3290 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
3292 switch( as->assocStatus ) {
3294 DBG_TRACE( DbgInfo, "Association Status : STA Associated\n" );
3298 DBG_TRACE( DbgInfo, "Association Status : STA Reassociated\n" );
3302 DBG_TRACE( DbgInfo, "Association Status : STA Disassociated\n" );
3306 DBG_TRACE( DbgInfo, "Association Status : UNKNOWN (0x%04x)\n",
3311 DBG_TRACE(DbgInfo, "STA Address : %pM\n",
3314 if (( as->assocStatus == 2 ) && ( as->len == 8 )) {
3315 DBG_TRACE(DbgInfo, "Old AP Address : %pM\n",
3322 case CFG_SECURITY_STAT:
3323 DBG_TRACE( DbgInfo, "CFG_SECURITY_STAT\n" );
3326 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
3328 switch( ss->securityStatus ) {
3330 DBG_TRACE( DbgInfo, "Security Status : Dissassociate [AP]\n" );
3334 DBG_TRACE( DbgInfo, "Security Status : Deauthenticate [AP]\n" );
3338 DBG_TRACE( DbgInfo, "Security Status : Authenticate Fail [STA] or [AP]\n" );
3342 DBG_TRACE( DbgInfo, "Security Status : MIC Fail\n" );
3346 DBG_TRACE( DbgInfo, "Security Status : Associate Fail\n" );
3350 DBG_TRACE( DbgInfo, "Security Status : UNKNOWN %d\n",
3351 ss->securityStatus );
3355 DBG_TRACE(DbgInfo, "STA Address : %pM\n",
3358 DBG_TRACE(DbgInfo, "Reason : 0x%04x\n",
3365 DBG_TRACE( DbgInfo, "CFG_WMP, size is %d bytes\n", ltv->len );
3367 WMP_RSP_STRCT *wmp_rsp = (WMP_RSP_STRCT *)ltv;
3369 DBG_TRACE( DbgInfo, "CFG_WMP, pdu type is 0x%x\n",
3370 wmp_rsp->wmpRsp.wmpHdr.type );
3372 switch( wmp_rsp->wmpRsp.wmpHdr.type ) {
3373 case WVLAN_WMP_PDU_TYPE_LT_RSP:
3376 LINKTEST_RSP_STRCT *lt_rsp = (LINKTEST_RSP_STRCT *)ltv;
3378 DBG_TRACE( DbgInfo, "LINK TEST RESULT\n" );
3379 DBG_TRACE( DbgInfo, "================\n" );
3380 DBG_TRACE( DbgInfo, "Length : %d.\n", lt_rsp->len );
3382 DBG_TRACE( DbgInfo, "Name : %s.\n", lt_rsp->ltRsp.ltRsp.name );
3383 DBG_TRACE( DbgInfo, "Signal Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.signal );
3384 DBG_TRACE( DbgInfo, "Noise Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.noise );
3385 DBG_TRACE( DbgInfo, "Receive Flow : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.rxFlow );
3386 DBG_TRACE( DbgInfo, "Data Rate : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRate );
3387 DBG_TRACE( DbgInfo, "Protocol : 0x%04x.\n", lt_rsp->ltRsp.ltRsp.protocol );
3388 DBG_TRACE( DbgInfo, "Station : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.station );
3389 DBG_TRACE( DbgInfo, "Data Rate Cap : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRateCap );
3391 DBG_TRACE( DbgInfo, "Power Mgmt : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3392 lt_rsp->ltRsp.ltRsp.powerMgmt[0],
3393 lt_rsp->ltRsp.ltRsp.powerMgmt[1],
3394 lt_rsp->ltRsp.ltRsp.powerMgmt[2],
3395 lt_rsp->ltRsp.ltRsp.powerMgmt[3] );
3397 DBG_TRACE( DbgInfo, "Robustness : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3398 lt_rsp->ltRsp.ltRsp.robustness[0],
3399 lt_rsp->ltRsp.ltRsp.robustness[1],
3400 lt_rsp->ltRsp.ltRsp.robustness[2],
3401 lt_rsp->ltRsp.ltRsp.robustness[3] );
3403 DBG_TRACE( DbgInfo, "Scaling : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.scaling );
3416 DBG_TRACE( DbgInfo, "CFG_NULL\n" );
3419 case CFG_UPDATED_INFO_RECORD: // Updated Information Record
3420 DBG_TRACE( DbgInfo, "UPDATED INFORMATION RECORD\n" );
3422 ltv_val = CNV_INT_TO_LITTLE( ltv->u.u16[0] );
3424 /* Check and see which RID was updated */
3426 case CFG_CUR_COUNTRY_INFO: // Indicate Passive Scan Completion
3427 DBG_TRACE( DbgInfo, "Updated country info\n" );
3429 /* Do I need to hold off on updating RIDs until the process is
3434 case CFG_PORT_STAT: // Wait for Connect Event
3440 DBG_WARNING( DbgInfo, "Unknown RID: 0x%04x\n", ltv_val );
3446 DBG_TRACE( DbgInfo, "UNKNOWN MESSAGE: 0x%04x\n", ltv->typ );
3449 DBG_LEAVE( DbgInfo );
3451 } // wl_process_mailbox
3452 /*============================================================================*/
3453 #endif /* ifndef USE_MBOX_SYNC */
3456 /*******************************************************************************
3457 * wl_wds_netdev_register()
3458 *******************************************************************************
3462 * This function registers net_device structures with the system's network
3463 * layer for use with the WDS ports.
3468 * lp - pointer to the device's private adapter structure
3474 ******************************************************************************/
3475 void wl_wds_netdev_register( struct wl_private *lp )
3478 /*------------------------------------------------------------------------*/
3479 DBG_FUNC( "wl_wds_netdev_register" );
3480 DBG_ENTER( DbgInfo );
3481 //;?why is there no USE_WDS clause like in wl_enable_wds_ports
3482 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3483 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3484 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3485 if ( register_netdev( lp->wds_port[count].dev ) != 0 ) {
3486 DBG_WARNING( DbgInfo, "net device for WDS port %d could not be registered\n",
3489 lp->wds_port[count].is_registered = TRUE;
3491 /* Fill out the net_device structs with the MAC addr */
3492 memcpy( lp->wds_port[count].dev->dev_addr, lp->MACAddress, ETH_ALEN );
3493 lp->wds_port[count].dev->addr_len = ETH_ALEN;
3497 DBG_LEAVE( DbgInfo );
3499 } // wl_wds_netdev_register
3500 /*============================================================================*/
3503 /*******************************************************************************
3504 * wl_wds_netdev_deregister()
3505 *******************************************************************************
3509 * This function deregisters the WDS net_device structures used by the
3510 * system's network layer.
3515 * lp - pointer to the device's private adapter structure
3521 ******************************************************************************/
3522 void wl_wds_netdev_deregister( struct wl_private *lp )
3525 /*------------------------------------------------------------------------*/
3526 DBG_FUNC( "wl_wds_netdev_deregister" );
3527 DBG_ENTER( DbgInfo );
3528 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3529 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3530 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3531 unregister_netdev( lp->wds_port[count].dev );
3533 lp->wds_port[count].is_registered = FALSE;
3536 DBG_LEAVE( DbgInfo );
3538 } // wl_wds_netdev_deregister
3539 /*============================================================================*/
3540 #endif /* USE_WDS */
3543 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
3545 * The proc filesystem: function to read and entry
3547 static void printf_hcf_16(struct seq_file *m, const char *s, hcf_16 *p, int n)
3551 seq_printf(m, "%-20.20s: ", s);
3554 for (i = 0; i < n; i++) {
3557 seq_printf(m, "%04X ", p[i]);
3562 static void printf_hcf_8(struct seq_file *m, const char *s, hcf_8 *p, int n)
3566 seq_printf(m, "%-20.20s: ", s);
3569 for (i = 0; i <= n; i++) {
3572 seq_printf(m, "%02X ", p[i]);
3577 static void printf_strct(struct seq_file *m, const char *s, hcf_16 *p)
3581 seq_printf(m, "%-20.20s: ", s);
3584 for ( i = 0; i <= *p; i++ ) {
3587 seq_printf(m,"%04X ", p[i]);
3592 int scull_read_procmem(struct seq_file *m, void *v)
3594 struct wl_private *lp = m->private;
3596 CFG_HERMES_TALLIES_STRCT *p;
3599 seq_puts(m, "No wl_private in scull_read_procmem\n" );
3600 } else if ( lp->wlags49_type == 0 ){
3602 seq_printf(m, "Magic: 0x%04X\n", ifbp->IFB_Magic );
3603 seq_printf(m, "IOBase: 0x%04X\n", ifbp->IFB_IOBase );
3604 seq_printf(m, "LinkStat: 0x%04X\n", ifbp->IFB_LinkStat );
3605 seq_printf(m, "DSLinkStat: 0x%04X\n", ifbp->IFB_DSLinkStat );
3606 seq_printf(m, "TickIni: 0x%08lX\n", ifbp->IFB_TickIni );
3607 seq_printf(m, "TickCnt: 0x%04X\n", ifbp->IFB_TickCnt );
3608 seq_printf(m, "IntOffCnt: 0x%04X\n", ifbp->IFB_IntOffCnt );
3609 printf_hcf_16(m, "IFB_FWIdentity",
3610 &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
3611 } else if ( lp->wlags49_type == 1 ) {
3612 seq_printf(m, "Channel: 0x%04X\n", lp->Channel );
3613 /****** seq_printf(m, "slock: %d\n", lp->slock ); */
3614 //x struct tq_struct "task: 0x%04X\n", lp->task );
3615 //x struct net_device_stats "stats: 0x%04X\n", lp->stats );
3617 //x struct iw_statistics "wstats: 0x%04X\n", lp->wstats );
3618 //x seq_printf(m, "spy_number: 0x%04X\n", lp->spy_number );
3619 //x u_char spy_address[IW_MAX_SPY][ETH_ALEN];
3620 //x struct iw_quality spy_stat[IW_MAX_SPY];
3621 #endif // WIRELESS_EXT
3622 seq_printf(m, "IFB: 0x%p\n", &lp->hcfCtx );
3623 seq_printf(m, "flags: %#.8lX\n", lp->flags ); //;?use this format from now on
3624 seq_printf(m, "DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
3626 seq_printf(m, "DebugFlag (DbgInfo): 0x%08lX\n", DbgInfo->DebugFlag );
3628 seq_printf(m, "is_registered: 0x%04X\n", lp->is_registered );
3629 //x CFG_DRV_INFO_STRCT "driverInfo: 0x%04X\n", lp->driverInfo );
3630 printf_strct( m, "driverInfo", (hcf_16*)&lp->driverInfo );
3631 //x CFG_IDENTITY_STRCT "driverIdentity: 0x%04X\n", lp->driverIdentity );
3632 printf_strct( m, "driverIdentity", (hcf_16*)&lp->driverIdentity );
3633 //x CFG_FW_IDENTITY_STRCT "StationIdentity: 0x%04X\n", lp->StationIdentity );
3634 printf_strct( m, "StationIdentity", (hcf_16*)&lp->StationIdentity );
3635 //x CFG_PRI_IDENTITY_STRCT "PrimaryIdentity: 0x%04X\n", lp->PrimaryIdentity );
3636 printf_strct( m, "PrimaryIdentity", (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
3637 printf_strct( m, "PrimarySupplier", (hcf_16*)&lp->hcfCtx.IFB_PRISup );
3638 //x CFG_PRI_IDENTITY_STRCT "NICIdentity: 0x%04X\n", lp->NICIdentity );
3639 printf_strct( m, "NICIdentity", (hcf_16*)&lp->NICIdentity );
3640 //x ltv_t "ltvRecord: 0x%04X\n", lp->ltvRecord );
3641 seq_printf(m, "txBytes: 0x%08lX\n", lp->txBytes );
3642 seq_printf(m, "maxPort: 0x%04X\n", lp->maxPort ); /* 0 for STA, 6 for AP */
3643 /* Elements used for async notification from hardware */
3644 //x RID_LOG_STRCT RidList[10];
3645 //x ltv_t "updatedRecord: 0x%04X\n", lp->updatedRecord );
3646 //x PROBE_RESP "ProbeResp: 0x%04X\n", lp->ProbeResp );
3647 //x ASSOC_STATUS_STRCT "assoc_stat: 0x%04X\n", lp->assoc_stat );
3648 //x SECURITY_STATUS_STRCT "sec_stat: 0x%04X\n", lp->sec_stat );
3649 //x u_char lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
3650 seq_printf(m, "PortType: 0x%04X\n", lp->PortType ); // 1 - 3 (1 [Normal] | 3 [AdHoc])
3651 seq_printf(m, "Channel: 0x%04X\n", lp->Channel ); // 0 - 14 (0)
3652 //x hcf_16 TxRateControl[2];
3653 seq_printf(m, "TxRateControl[2]: 0x%04X 0x%04X\n",
3654 lp->TxRateControl[0], lp->TxRateControl[1] );
3655 seq_printf(m, "DistanceBetweenAPs: 0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
3656 seq_printf(m, "RTSThreshold: 0x%04X\n", lp->RTSThreshold ); // 0 - 2347 (2347)
3657 seq_printf(m, "PMEnabled: 0x%04X\n", lp->PMEnabled ); // 0 - 2, 8001 - 8002 (0)
3658 seq_printf(m, "MicrowaveRobustness: 0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
3659 seq_printf(m, "CreateIBSS: 0x%04X\n", lp->CreateIBSS ); // 0 - 1 (0)
3660 seq_printf(m, "MulticastReceive: 0x%04X\n", lp->MulticastReceive ); // 0 - 1 (1)
3661 seq_printf(m, "MaxSleepDuration: 0x%04X\n", lp->MaxSleepDuration ); // 0 - 65535 (100)
3662 //x hcf_8 MACAddress[ETH_ALEN];
3663 printf_hcf_8(m, "MACAddress", lp->MACAddress, ETH_ALEN );
3664 //x char NetworkName[HCF_MAX_NAME_LEN+1];
3665 seq_printf(m, "NetworkName: %.32s\n", lp->NetworkName );
3666 //x char StationName[HCF_MAX_NAME_LEN+1];
3667 seq_printf(m, "EnableEncryption: 0x%04X\n", lp->EnableEncryption ); // 0 - 1 (0)
3668 //x char Key1[MAX_KEY_LEN+1];
3669 printf_hcf_8( m, "Key1", lp->Key1, MAX_KEY_LEN );
3670 //x char Key2[MAX_KEY_LEN+1];
3671 //x char Key3[MAX_KEY_LEN+1];
3672 //x char Key4[MAX_KEY_LEN+1];
3673 seq_printf(m, "TransmitKeyID: 0x%04X\n", lp->TransmitKeyID ); // 1 - 4 (1)
3674 //x CFG_DEFAULT_KEYS_STRCT "DefaultKeys: 0x%04X\n", lp->DefaultKeys );
3675 //x u_char mailbox[MB_SIZE];
3676 //x char szEncryption[MAX_ENC_LEN];
3677 seq_printf(m, "driverEnable: 0x%04X\n", lp->driverEnable );
3678 seq_printf(m, "wolasEnable: 0x%04X\n", lp->wolasEnable );
3679 seq_printf(m, "atimWindow: 0x%04X\n", lp->atimWindow );
3680 seq_printf(m, "holdoverDuration: 0x%04X\n", lp->holdoverDuration );
3681 //x hcf_16 MulticastRate[2];
3682 seq_printf(m, "authentication: 0x%04X\n", lp->authentication ); // is this AP specific?
3683 seq_printf(m, "promiscuousMode: 0x%04X\n", lp->promiscuousMode );
3684 seq_printf(m, "DownloadFirmware: 0x%04X\n", lp->DownloadFirmware ); // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
3685 seq_printf(m, "AuthKeyMgmtSuite: 0x%04X\n", lp->AuthKeyMgmtSuite );
3686 seq_printf(m, "loadBalancing: 0x%04X\n", lp->loadBalancing );
3687 seq_printf(m, "mediumDistribution: 0x%04X\n", lp->mediumDistribution );
3688 seq_printf(m, "txPowLevel: 0x%04X\n", lp->txPowLevel );
3689 // seq_printf(m, "shortRetryLimit: 0x%04X\n", lp->shortRetryLimit );
3690 // seq_printf(m, "longRetryLimit: 0x%04X\n", lp->longRetryLimit );
3693 seq_printf(m, "connectionControl: 0x%04X\n", lp->connectionControl );
3694 //x //hcf_16 probeDataRates[2];
3695 seq_printf(m, "ownBeaconInterval: 0x%04X\n", lp->ownBeaconInterval );
3696 seq_printf(m, "coexistence: 0x%04X\n", lp->coexistence );
3697 //x WVLAN_FRAME "txF: 0x%04X\n", lp->txF );
3698 //x WVLAN_LFRAME txList[DEFAULT_NUM_TX_FRAMES];
3699 //x struct list_head "txFree: 0x%04X\n", lp->txFree );
3700 //x struct list_head txQ[WVLAN_MAX_TX_QUEUES];
3701 seq_printf(m, "netif_queue_on: 0x%04X\n", lp->netif_queue_on );
3702 seq_printf(m, "txQ_count: 0x%04X\n", lp->txQ_count );
3703 //x DESC_STRCT "desc_rx: 0x%04X\n", lp->desc_rx );
3704 //x DESC_STRCT "desc_tx: 0x%04X\n", lp->desc_tx );
3705 //x WVLAN_PORT_STATE "portState: 0x%04X\n", lp->portState );
3706 //x ScanResult "scan_results: 0x%04X\n", lp->scan_results );
3707 //x ProbeResult "probe_results: 0x%04X\n", lp->probe_results );
3708 seq_printf(m, "probe_num_aps: 0x%04X\n", lp->probe_num_aps );
3709 seq_printf(m, "use_dma: 0x%04X\n", lp->use_dma );
3710 //x DMA_STRCT "dma: 0x%04X\n", lp->dma );
3712 seq_printf(m, "useRTS: 0x%04X\n", lp->useRTS );
3714 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
3715 //;?should we restore this to allow smaller memory footprint
3716 //;?I guess not. This should be brought under Debug mode only
3717 seq_printf(m, "DTIMPeriod: 0x%04X\n", lp->DTIMPeriod ); // 1 - 255 (1)
3718 seq_printf(m, "multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
3719 seq_printf(m, "RejectAny: 0x%04X\n", lp->RejectAny ); // 0 - 1 (0)
3720 seq_printf(m, "ExcludeUnencrypted: 0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
3721 seq_printf(m, "intraBSSRelay: 0x%04X\n", lp->intraBSSRelay );
3722 seq_printf(m, "wlags49_type: 0x%08lX\n", lp->wlags49_type );
3724 //x WVLAN_WDS_IF wds_port[NUM_WDS_PORTS];
3727 } else if ( lp->wlags49_type == 2 ){
3728 seq_printf(m, "tallies to be added\n" );
3729 //Hermes Tallies (IFB substructure) {
3730 p = &lp->hcfCtx.IFB_NIC_Tallies;
3731 seq_printf(m, "TxUnicastFrames: %08lX\n", p->TxUnicastFrames );
3732 seq_printf(m, "TxMulticastFrames: %08lX\n", p->TxMulticastFrames );
3733 seq_printf(m, "TxFragments: %08lX\n", p->TxFragments );
3734 seq_printf(m, "TxUnicastOctets: %08lX\n", p->TxUnicastOctets );
3735 seq_printf(m, "TxMulticastOctets: %08lX\n", p->TxMulticastOctets );
3736 seq_printf(m, "TxDeferredTransmissions: %08lX\n", p->TxDeferredTransmissions );
3737 seq_printf(m, "TxSingleRetryFrames: %08lX\n", p->TxSingleRetryFrames );
3738 seq_printf(m, "TxMultipleRetryFrames: %08lX\n", p->TxMultipleRetryFrames );
3739 seq_printf(m, "TxRetryLimitExceeded: %08lX\n", p->TxRetryLimitExceeded );
3740 seq_printf(m, "TxDiscards: %08lX\n", p->TxDiscards );
3741 seq_printf(m, "RxUnicastFrames: %08lX\n", p->RxUnicastFrames );
3742 seq_printf(m, "RxMulticastFrames: %08lX\n", p->RxMulticastFrames );
3743 seq_printf(m, "RxFragments: %08lX\n", p->RxFragments );
3744 seq_printf(m, "RxUnicastOctets: %08lX\n", p->RxUnicastOctets );
3745 seq_printf(m, "RxMulticastOctets: %08lX\n", p->RxMulticastOctets );
3746 seq_printf(m, "RxFCSErrors: %08lX\n", p->RxFCSErrors );
3747 seq_printf(m, "RxDiscardsNoBuffer: %08lX\n", p->RxDiscardsNoBuffer );
3748 seq_printf(m, "TxDiscardsWrongSA: %08lX\n", p->TxDiscardsWrongSA );
3749 seq_printf(m, "RxWEPUndecryptable: %08lX\n", p->RxWEPUndecryptable );
3750 seq_printf(m, "RxMsgInMsgFragments: %08lX\n", p->RxMsgInMsgFragments );
3751 seq_printf(m, "RxMsgInBadMsgFragments: %08lX\n", p->RxMsgInBadMsgFragments );
3752 seq_printf(m, "RxDiscardsWEPICVError: %08lX\n", p->RxDiscardsWEPICVError );
3753 seq_printf(m, "RxDiscardsWEPExcluded: %08lX\n", p->RxDiscardsWEPExcluded );
3754 #if (HCF_EXT) & HCF_EXT_TALLIES_FW
3756 #endif // HCF_EXT_TALLIES_FW
3757 } else if ( lp->wlags49_type & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3759 DbgInfo->DebugFlag = lp->wlags49_type & 0x7FFF;
3761 lp->wlags49_type = 0; //default to IFB again ;?
3763 seq_printf(m, "unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
3766 "0x0001 - wl_private\n"
3767 "0x0002 - Tallies\n"
3768 "0x8xxx - Change debufflag\n"
3769 "ERROR 0001\nWARNING 0002\nNOTICE 0004\nTRACE 0008\n"
3770 "VERBOSE 0010\nPARAM 0020\nBREAK 0040\nRX 0100\n"
3771 "TX 0200\nDS 0400\n");
3774 } // scull_read_procmem
3776 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
3778 static char proc_number[11];
3779 unsigned int nr = 0;
3781 DBG_FUNC( "write_int" );
3782 DBG_ENTER( DbgInfo );
3786 } else if ( copy_from_user(proc_number, buffer, count) ) {
3790 proc_number[count] = 0;
3791 nr = simple_strtoul(proc_number , NULL, 0);
3792 *(unsigned int *)data = nr;
3793 if ( nr & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3795 DbgInfo->DebugFlag = nr & 0x7FFF;
3799 DBG_PRINT( "value: %08X\n", nr );
3800 DBG_LEAVE( DbgInfo );
3804 #endif /* SCULL_USE_PROC */
3807 #define RUN_AT(x) (jiffies+(x)) //"borrowed" from include/pcmcia/k_compat.h
3808 #define DS_OOR 0x8000 //Deepsleep OutOfRange Status
3810 lp->timer_oor_cnt = DS_OOR;
3811 init_timer( &lp->timer_oor );
3812 lp->timer_oor.function = timer_oor;
3813 lp->timer_oor.data = (unsigned long)lp;
3814 lp->timer_oor.expires = RUN_AT( 3 * HZ );
3815 add_timer( &lp->timer_oor );
3816 printk(KERN_NOTICE "wl_enable: %ld\n", jiffies ); //;?remove me 1 day
3819 /*******************************************************************************
3821 *******************************************************************************
3828 * arg - a u_long representing a pointer to a dev_link_t structure for the
3829 * device to be released.
3835 ******************************************************************************/
3836 void timer_oor( u_long arg )
3838 struct wl_private *lp = (struct wl_private *)arg;
3840 /*------------------------------------------------------------------------*/
3842 DBG_FUNC( "timer_oor" );
3843 DBG_ENTER( DbgInfo );
3844 DBG_PARAM( DbgInfo, "arg", "0x%08lx", arg );
3846 printk(KERN_NOTICE "timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt ); //;?remove me 1 day
3847 lp->timer_oor_cnt += 10;
3848 if ( (lp->timer_oor_cnt & ~DS_OOR) > 300 ) {
3849 lp->timer_oor_cnt = 300;
3851 lp->timer_oor_cnt |= DS_OOR;
3852 init_timer( &lp->timer_oor );
3853 lp->timer_oor.function = timer_oor;
3854 lp->timer_oor.data = (unsigned long)lp;
3855 lp->timer_oor.expires = RUN_AT( (lp->timer_oor_cnt & ~DS_OOR) * HZ );
3856 add_timer( &lp->timer_oor );
3858 DBG_LEAVE( DbgInfo );
3862 MODULE_LICENSE("Dual BSD/GPL");