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 iamge 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/types.h>
77 #include <linux/kernel.h>
78 // #include <linux/sched.h>
79 // #include <linux/ptrace.h>
80 // #include <linux/slab.h>
81 // #include <linux/ctype.h>
82 // #include <linux/string.h>
83 // #include <linux/timer.h>
84 //#include <linux/interrupt.h>
85 // #include <linux/tqueue.h>
86 // #include <linux/in.h>
87 // #include <linux/delay.h>
88 // #include <asm/io.h>
89 // #include <asm/system.h>
90 // #include <asm/bitops.h>
91 #include <linux/unistd.h>
92 #include <asm/uaccess.h>
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 //int scull_read_procmem(char *buf, char **start, off_t offset, int len, int unused);
149 int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data );
150 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data);
151 static void proc_write(const char *name, write_proc_t *w, void *data);
153 #endif /* SCULL_USE_PROC */
155 /*******************************************************************************
156 * module parameter definitions - set with 'insmod'
157 ******************************************************************************/
158 static p_u16 irq_mask = 0xdeb8; // IRQ3,4,5,7,9,10,11,12,14,15
159 static p_s8 irq_list[4] = { -1 };
162 MODULE_PARM(irq_mask, "h");
163 MODULE_PARM_DESC(irq_mask, "IRQ mask [0xdeb8]");
164 MODULE_PARM(irq_list, "1-4b");
165 MODULE_PARM_DESC(irq_list, "IRQ list [<irq_mask>]");
168 static p_u8 PARM_AUTHENTICATION = PARM_DEFAULT_AUTHENTICATION;
169 static p_u16 PARM_AUTH_KEY_MGMT_SUITE = PARM_DEFAULT_AUTH_KEY_MGMT_SUITE;
170 static p_u16 PARM_BRSC_2GHZ = PARM_DEFAULT_BRSC_2GHZ;
171 static p_u16 PARM_BRSC_5GHZ = PARM_DEFAULT_BRSC_5GHZ;
172 static p_u16 PARM_COEXISTENCE = PARM_DEFAULT_COEXISTENCE;
173 static p_u16 PARM_CONNECTION_CONTROL = PARM_DEFAULT_CONNECTION_CONTROL; //;?rename and move
174 static p_char *PARM_CREATE_IBSS = PARM_DEFAULT_CREATE_IBSS_STR;
175 static p_char *PARM_DESIRED_SSID = PARM_DEFAULT_SSID;
176 static p_char *PARM_DOWNLOAD_FIRMWARE = "";
177 static p_u16 PARM_ENABLE_ENCRYPTION = PARM_DEFAULT_ENABLE_ENCRYPTION;
178 static p_char *PARM_EXCLUDE_UNENCRYPTED = PARM_DEFAULT_EXCLUDE_UNENCRYPTED_STR;
179 static p_char *PARM_INTRA_BSS_RELAY = PARM_DEFAULT_INTRA_BSS_RELAY_STR;
180 static p_char *PARM_KEY1 = "";
181 static p_char *PARM_KEY2 = "";
182 static p_char *PARM_KEY3 = "";
183 static p_char *PARM_KEY4 = "";
184 static p_char *PARM_LOAD_BALANCING = PARM_DEFAULT_LOAD_BALANCING_STR;
185 static p_u16 PARM_MAX_SLEEP = PARM_DEFAULT_MAX_PM_SLEEP;
186 static p_char *PARM_MEDIUM_DISTRIBUTION = PARM_DEFAULT_MEDIUM_DISTRIBUTION_STR;
187 static p_char *PARM_MICROWAVE_ROBUSTNESS = PARM_DEFAULT_MICROWAVE_ROBUSTNESS_STR;
188 static p_char *PARM_MULTICAST_PM_BUFFERING = PARM_DEFAULT_MULTICAST_PM_BUFFERING_STR;
189 static p_u16 PARM_MULTICAST_RATE = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
190 static p_char *PARM_MULTICAST_RX = PARM_DEFAULT_MULTICAST_RX_STR;
191 static p_u8 PARM_NETWORK_ADDR[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
192 static p_u16 PARM_OWN_ATIM_WINDOW = PARM_DEFAULT_OWN_ATIM_WINDOW;
193 static p_u16 PARM_OWN_BEACON_INTERVAL = PARM_DEFAULT_OWN_BEACON_INTERVAL;
194 static p_u8 PARM_OWN_CHANNEL = PARM_DEFAULT_OWN_CHANNEL;
195 static p_u8 PARM_OWN_DTIM_PERIOD = PARM_DEFAULT_OWN_DTIM_PERIOD;
196 static p_char *PARM_OWN_NAME = PARM_DEFAULT_OWN_NAME;
197 static p_char *PARM_OWN_SSID = PARM_DEFAULT_SSID;
198 static p_u16 PARM_PM_ENABLED = WVLAN_PM_STATE_DISABLED;
199 static p_u16 PARM_PM_HOLDOVER_DURATION = PARM_DEFAULT_PM_HOLDOVER_DURATION;
200 static p_u8 PARM_PORT_TYPE = PARM_DEFAULT_PORT_TYPE;
201 static p_char *PARM_PROMISCUOUS_MODE = PARM_DEFAULT_PROMISCUOUS_MODE_STR;
202 static p_char *PARM_REJECT_ANY = PARM_DEFAULT_REJECT_ANY_STR;
204 static p_u16 PARM_RTS_THRESHOLD1 = PARM_DEFAULT_RTS_THRESHOLD;
205 static p_u16 PARM_RTS_THRESHOLD2 = PARM_DEFAULT_RTS_THRESHOLD;
206 static p_u16 PARM_RTS_THRESHOLD3 = PARM_DEFAULT_RTS_THRESHOLD;
207 static p_u16 PARM_RTS_THRESHOLD4 = PARM_DEFAULT_RTS_THRESHOLD;
208 static p_u16 PARM_RTS_THRESHOLD5 = PARM_DEFAULT_RTS_THRESHOLD;
209 static p_u16 PARM_RTS_THRESHOLD6 = PARM_DEFAULT_RTS_THRESHOLD;
211 static p_u16 PARM_RTS_THRESHOLD = PARM_DEFAULT_RTS_THRESHOLD;
212 static p_u16 PARM_SRSC_2GHZ = PARM_DEFAULT_SRSC_2GHZ;
213 static p_u16 PARM_SRSC_5GHZ = PARM_DEFAULT_SRSC_5GHZ;
214 static p_u8 PARM_SYSTEM_SCALE = PARM_DEFAULT_SYSTEM_SCALE;
215 static p_u8 PARM_TX_KEY = PARM_DEFAULT_TX_KEY;
216 static p_u16 PARM_TX_POW_LEVEL = PARM_DEFAULT_TX_POW_LEVEL;
218 static p_u16 PARM_TX_RATE1 = PARM_DEFAULT_TX_RATE_2GHZ;
219 static p_u16 PARM_TX_RATE2 = PARM_DEFAULT_TX_RATE_2GHZ;
220 static p_u16 PARM_TX_RATE3 = PARM_DEFAULT_TX_RATE_2GHZ;
221 static p_u16 PARM_TX_RATE4 = PARM_DEFAULT_TX_RATE_2GHZ;
222 static p_u16 PARM_TX_RATE5 = PARM_DEFAULT_TX_RATE_2GHZ;
223 static p_u16 PARM_TX_RATE6 = PARM_DEFAULT_TX_RATE_2GHZ;
225 static p_u16 PARM_TX_RATE = PARM_DEFAULT_TX_RATE_2GHZ;
227 static p_u8 PARM_WDS_ADDRESS1[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
228 static p_u8 PARM_WDS_ADDRESS2[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
229 static p_u8 PARM_WDS_ADDRESS3[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
230 static p_u8 PARM_WDS_ADDRESS4[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
231 static p_u8 PARM_WDS_ADDRESS5[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
232 static p_u8 PARM_WDS_ADDRESS6[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
237 MODULE_PARM(PARM_DESIRED_SSID, "s");
238 MODULE_PARM_DESC(PARM_DESIRED_SSID, "Network Name (<string>) [ANY]");
239 MODULE_PARM(PARM_OWN_SSID, "s");
240 MODULE_PARM_DESC(PARM_OWN_SSID, "Network Name (<string>) [ANY]");
241 MODULE_PARM(PARM_OWN_CHANNEL, "b");
242 MODULE_PARM_DESC(PARM_OWN_CHANNEL, "Channel (0 - 14) [0]");
243 MODULE_PARM(PARM_SYSTEM_SCALE, "b");
244 MODULE_PARM_DESC(PARM_SYSTEM_SCALE, "Distance Between APs (1 - 3) [1]");
245 MODULE_PARM(PARM_TX_RATE, "b");
246 MODULE_PARM_DESC(PARM_TX_RATE, "Transmit Rate Control");
247 MODULE_PARM(PARM_RTS_THRESHOLD, "h");
248 MODULE_PARM_DESC(PARM_RTS_THRESHOLD, "Medium Reservation (RTS/CTS Fragment Length) (256 - 2347) [2347]");
249 MODULE_PARM(PARM_MICROWAVE_ROBUSTNESS, "s");
250 MODULE_PARM_DESC(PARM_MICROWAVE_ROBUSTNESS, "Microwave Oven Robustness Enabled (<string> N or Y) [N]");
251 MODULE_PARM(PARM_OWN_NAME, "s");
252 MODULE_PARM_DESC(PARM_OWN_NAME, "Station Name (<string>) [Linux]");
254 MODULE_PARM(PARM_ENABLE_ENCRYPTION, "b");
255 MODULE_PARM_DESC(PARM_ENABLE_ENCRYPTION, "Encryption Mode (0 - 7) [0]");
257 MODULE_PARM(PARM_KEY1, "s");
258 MODULE_PARM_DESC(PARM_KEY1, "Data Encryption Key 1 (<string>) []");
259 MODULE_PARM(PARM_KEY2, "s");
260 MODULE_PARM_DESC(PARM_KEY2, "Data Encryption Key 2 (<string>) []");
261 MODULE_PARM(PARM_KEY3, "s");
262 MODULE_PARM_DESC(PARM_KEY3, "Data Encryption Key 3 (<string>) []");
263 MODULE_PARM(PARM_KEY4, "s");
264 MODULE_PARM_DESC(PARM_KEY4, "Data Encryption Key 4 (<string>) []");
265 MODULE_PARM(PARM_TX_KEY, "b");
266 MODULE_PARM_DESC(PARM_TX_KEY, "Transmit Key ID (1 - 4) [1]");
267 MODULE_PARM(PARM_MULTICAST_RATE, "b");
268 MODULE_PARM_DESC(PARM_MULTICAST_RATE, "Multicast Rate");
269 MODULE_PARM(PARM_DOWNLOAD_FIRMWARE, "s");
270 MODULE_PARM_DESC(PARM_DOWNLOAD_FIRMWARE, "filename of firmware image");
272 MODULE_PARM(PARM_AUTH_KEY_MGMT_SUITE, "b");
273 MODULE_PARM_DESC(PARM_AUTH_KEY_MGMT_SUITE, "Authentication Key Management suite (0-4) [0]");
275 MODULE_PARM(PARM_LOAD_BALANCING, "s");
276 MODULE_PARM_DESC(PARM_LOAD_BALANCING, "Load Balancing Enabled (<string> N or Y) [Y]");
277 MODULE_PARM(PARM_MEDIUM_DISTRIBUTION, "s");
278 MODULE_PARM_DESC(PARM_MEDIUM_DISTRIBUTION, "Medium Distribution Enabled (<string> N or Y) [Y]");
279 MODULE_PARM(PARM_TX_POW_LEVEL, "b");
280 MODULE_PARM_DESC(PARM_TX_POW_LEVEL, "Transmit Power (0 - 6) [3]");
281 MODULE_PARM(PARM_SRSC_2GHZ, "b");
282 MODULE_PARM_DESC(PARM_SRSC_2GHZ, "Supported Rate Set Control 2.4 GHz");
283 MODULE_PARM(PARM_SRSC_5GHZ, "b");
284 MODULE_PARM_DESC(PARM_SRSC_5GHZ, "Supported Rate Set Control 5.0 GHz");
285 MODULE_PARM(PARM_BRSC_2GHZ, "b");
286 MODULE_PARM_DESC(PARM_BRSC_2GHZ, "Basic Rate Set Control 2.4 GHz");
287 MODULE_PARM(PARM_BRSC_5GHZ, "b");
288 MODULE_PARM_DESC(PARM_BRSC_5GHZ, "Basic Rate Set Control 5.0 GHz");
289 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
290 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
291 MODULE_PARM(PARM_PM_ENABLED, "h");
292 MODULE_PARM_DESC(PARM_PM_ENABLED, "Power Management State (0 - 2, 8001 - 8002) [0]");
293 MODULE_PARM(PARM_PORT_TYPE, "b");
294 MODULE_PARM_DESC(PARM_PORT_TYPE, "Port Type (1 - 3) [1]");
295 //;?MODULE_PARM(PARM_CREATE_IBSS, "s");
296 //;?MODULE_PARM_DESC(PARM_CREATE_IBSS, "Create IBSS (<string> N or Y) [N]");
297 //;?MODULE_PARM(PARM_MULTICAST_RX, "s");
298 //;?MODULE_PARM_DESC(PARM_MULTICAST_RX, "Multicast Receive Enable (<string> N or Y) [Y]");
299 //;?MODULE_PARM(PARM_MAX_SLEEP, "h");
300 //;?MODULE_PARM_DESC(PARM_MAX_SLEEP, "Maximum Power Management Sleep Duration (0 - 65535) [100]");
301 //;?MODULE_PARM(PARM_NETWORK_ADDR, "6b");
302 //;?MODULE_PARM_DESC(PARM_NETWORK_ADDR, "Hardware Ethernet Address ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [<factory value>]");
303 //;?MODULE_PARM(PARM_AUTHENTICATION, "b");
306 //;?MODULE_PARM_DESC(PARM_AUTHENTICATION, "Authentication Type (0-2) [0] 0=Open 1=SharedKey 2=LEAP");
307 //;?MODULE_PARM_DESC(authentication, "Authentication Type (1-2) [1] 1=Open 2=SharedKey");
310 //;?MODULE_PARM(PARM_OWN_ATIM_WINDOW, "b");
311 //;?MODULE_PARM_DESC(PARM_OWN_ATIM_WINDOW, "ATIM Window time in TU for IBSS creation (0-100) [0]");
312 //;?MODULE_PARM(PARM_PM_HOLDOVER_DURATION, "b");
313 //;?MODULE_PARM_DESC(PARM_PM_HOLDOVER_DURATION, "Time station remains awake after MAC frame transfer when PM is on (0-65535) [100]");
314 //;?MODULE_PARM(PARM_PROMISCUOUS_MODE, "s");
315 //;?MODULE_PARM_DESC(PARM_PROMISCUOUS_MODE, "Promiscuous Mode Enable (<string> Y or N ) [N]" );
317 MODULE_PARM(PARM_CONNECTION_CONTROL, "b");
318 MODULE_PARM_DESC(PARM_CONNECTION_CONTROL, "Connection Control (0 - 3) [2]");
320 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
321 //;?should we restore this to allow smaller memory footprint
322 MODULE_PARM(PARM_OWN_DTIM_PERIOD, "b");
323 MODULE_PARM_DESC(PARM_OWN_DTIM_PERIOD, "DTIM Period (0 - 255) [1]");
324 MODULE_PARM(PARM_REJECT_ANY, "s");
325 MODULE_PARM_DESC(PARM_REJECT_ANY, "Closed System (<string> N or Y) [N]");
326 MODULE_PARM(PARM_EXCLUDE_UNENCRYPTED, "s");
327 MODULE_PARM_DESC(PARM_EXCLUDE_UNENCRYPTED, "Deny non-encrypted (<string> N or Y) [Y]");
328 MODULE_PARM(PARM_MULTICAST_PM_BUFFERING,"s");
329 MODULE_PARM_DESC(PARM_MULTICAST_PM_BUFFERING, "Buffer MAC frames for Tx after DTIM (<string> Y or N) [Y]");
330 MODULE_PARM(PARM_INTRA_BSS_RELAY, "s");
331 MODULE_PARM_DESC(PARM_INTRA_BSS_RELAY, "IntraBSS Relay (<string> N or Y) [Y]");
332 MODULE_PARM(PARM_RTS_THRESHOLD1, "h");
333 MODULE_PARM_DESC(PARM_RTS_THRESHOLD1, "RTS Threshold, WDS Port 1 (256 - 2347) [2347]");
334 MODULE_PARM(PARM_RTS_THRESHOLD2, "h");
335 MODULE_PARM_DESC(PARM_RTS_THRESHOLD2, "RTS Threshold, WDS Port 2 (256 - 2347) [2347]");
336 MODULE_PARM(PARM_RTS_THRESHOLD3, "h");
337 MODULE_PARM_DESC(PARM_RTS_THRESHOLD3, "RTS Threshold, WDS Port 3 (256 - 2347) [2347]");
338 MODULE_PARM(PARM_RTS_THRESHOLD4, "h");
339 MODULE_PARM_DESC(PARM_RTS_THRESHOLD4, "RTS Threshold, WDS Port 4 (256 - 2347) [2347]");
340 MODULE_PARM(PARM_RTS_THRESHOLD5, "h");
341 MODULE_PARM_DESC(PARM_RTS_THRESHOLD5, "RTS Threshold, WDS Port 5 (256 - 2347) [2347]");
342 MODULE_PARM(PARM_RTS_THRESHOLD6, "h");
343 MODULE_PARM_DESC(PARM_RTS_THRESHOLD6, "RTS Threshold, WDS Port 6 (256 - 2347) [2347]");
344 MODULE_PARM(PARM_TX_RATE1, "b");
345 MODULE_PARM_DESC(PARM_TX_RATE1, "Transmit Rate Control, WDS Port 1 (1 - 7) [3]");
346 MODULE_PARM(PARM_TX_RATE2, "b");
347 MODULE_PARM_DESC(PARM_TX_RATE2, "Transmit Rate Control, WDS Port 2 (1 - 7) [3]");
348 MODULE_PARM(PARM_TX_RATE3, "b");
349 MODULE_PARM_DESC(PARM_TX_RATE3, "Transmit Rate Control, WDS Port 3 (1 - 7) [3]");
350 MODULE_PARM(PARM_TX_RATE4, "b");
351 MODULE_PARM_DESC(PARM_TX_RATE4, "Transmit Rate Control, WDS Port 4 (1 - 7) [3]");
352 MODULE_PARM(PARM_TX_RATE5, "b");
353 MODULE_PARM_DESC(PARM_TX_RATE5, "Transmit Rate Control, WDS Port 5 (1 - 7) [3]");
354 MODULE_PARM(PARM_TX_RATE6, "b");
355 MODULE_PARM_DESC(PARM_TX_RATE6, "Transmit Rate Control, WDS Port 6 (1 - 7) [3]");
356 MODULE_PARM(PARM_WDS_ADDRESS1, "6b");
357 MODULE_PARM_DESC(PARM_WDS_ADDRESS1, "MAC Address, WDS Port 1 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
358 MODULE_PARM(PARM_WDS_ADDRESS2, "6b");
359 MODULE_PARM_DESC(PARM_WDS_ADDRESS2, "MAC Address, WDS Port 2 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
360 MODULE_PARM(PARM_WDS_ADDRESS3, "6b");
361 MODULE_PARM_DESC(PARM_WDS_ADDRESS3, "MAC Address, WDS Port 3 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
362 MODULE_PARM(PARM_WDS_ADDRESS4, "6b");
363 MODULE_PARM_DESC(PARM_WDS_ADDRESS4, "MAC Address, WDS Port 4 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
364 MODULE_PARM(PARM_WDS_ADDRESS5, "6b");
365 MODULE_PARM_DESC(PARM_WDS_ADDRESS5, "MAC Address, WDS Port 5 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
366 MODULE_PARM(PARM_WDS_ADDRESS6, "6b");
367 MODULE_PARM_DESC(PARM_WDS_ADDRESS6, "MAC Address, WDS Port 6 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
369 MODULE_PARM(PARM_OWN_BEACON_INTERVAL, "b");
370 MODULE_PARM_DESC(PARM_OWN_BEACON_INTERVAL, "Own Beacon Interval (20 - 200) [100]");
371 MODULE_PARM(PARM_COEXISTENCE, "b");
372 MODULE_PARM_DESC(PARM_COEXISTENCE, "Coexistence (0-7) [0]");
377 /* END NEW PARAMETERS */
378 /*******************************************************************************
379 * debugging specifics
380 ******************************************************************************/
383 static p_u32 pc_debug = DBG_LVL;
384 //MODULE_PARM(pc_debug, "i");
385 /*static ;?conflicts with my understanding of CL parameters and breaks now I moved
386 * the correspondig logic to wl_profile
387 */ p_u32 DebugFlag = ~0; //recognizable "undefined value" rather then DBG_DEFAULTS;
388 //MODULE_PARM(DebugFlag, "l");
390 dbg_info_t wl_info = { DBG_MOD_NAME, 0, 0 };
391 dbg_info_t *DbgInfo = &wl_info;
396 static p_char *useRTS = "N";
397 MODULE_PARM( useRTS, "s" );
398 MODULE_PARM_DESC( useRTS, "Use RTS test interface (<string> N or Y) [N]" );
401 /*******************************************************************************
402 * firmware download specifics
403 ******************************************************************************/
404 extern struct CFG_RANGE2_STRCT BASED
405 cfg_drv_act_ranges_pri; // describes primary-actor range of HCF
407 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
408 extern memimage ap; // AP firmware image to be downloaded
411 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
412 //extern memimage station; // STA firmware image to be downloaded
413 extern memimage fw_image; // firmware image to be downloaded
417 int wl_insert( struct net_device *dev )
420 int hcf_status = HCF_SUCCESS;
422 unsigned long flags = 0;
423 struct wl_private *lp = wl_priv(dev);
424 /*------------------------------------------------------------------------*/
425 DBG_FUNC( "wl_insert" );
426 DBG_ENTER( DbgInfo );
428 /* Initialize the adapter hardware. */
429 memset( &( lp->hcfCtx ), 0, sizeof( IFB_STRCT ));
431 /* Initialize the adapter parameters. */
432 spin_lock_init( &( lp->slock ));
434 /* Intialize states */
435 //lp->lockcount = 0; //PE1DNN
436 lp->is_handling_int = WL_NOT_HANDLING_INT;
437 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
441 DBG_PARAM( DbgInfo, "irq_mask", "0x%04x", irq_mask & 0x0FFFF );
442 DBG_PARAM( DbgInfo, "irq_list", "0x%02x 0x%02x 0x%02x 0x%02x",
443 irq_list[0] & 0x0FF, irq_list[1] & 0x0FF,
444 irq_list[2] & 0x0FF, irq_list[3] & 0x0FF );
445 DBG_PARAM( DbgInfo, PARM_NAME_DESIRED_SSID, "\"%s\"", PARM_DESIRED_SSID );
446 DBG_PARAM( DbgInfo, PARM_NAME_OWN_SSID, "\"%s\"", PARM_OWN_SSID );
447 DBG_PARAM( DbgInfo, PARM_NAME_OWN_CHANNEL, "%d", PARM_OWN_CHANNEL);
448 DBG_PARAM( DbgInfo, PARM_NAME_SYSTEM_SCALE, "%d", PARM_SYSTEM_SCALE );
449 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE, "%d", PARM_TX_RATE );
450 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD, "%d", PARM_RTS_THRESHOLD );
451 DBG_PARAM( DbgInfo, PARM_NAME_MICROWAVE_ROBUSTNESS, "\"%s\"", PARM_MICROWAVE_ROBUSTNESS );
452 DBG_PARAM( DbgInfo, PARM_NAME_OWN_NAME, "\"%s\"", PARM_OWN_NAME );
453 //;? DBG_PARAM( DbgInfo, PARM_NAME_ENABLE_ENCRYPTION, "\"%s\"", PARM_ENABLE_ENCRYPTION );
454 DBG_PARAM( DbgInfo, PARM_NAME_KEY1, "\"%s\"", PARM_KEY1 );
455 DBG_PARAM( DbgInfo, PARM_NAME_KEY2, "\"%s\"", PARM_KEY2 );
456 DBG_PARAM( DbgInfo, PARM_NAME_KEY3, "\"%s\"", PARM_KEY3 );
457 DBG_PARAM( DbgInfo, PARM_NAME_KEY4, "\"%s\"", PARM_KEY4 );
458 DBG_PARAM( DbgInfo, PARM_NAME_TX_KEY, "%d", PARM_TX_KEY );
459 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RATE, "%d", PARM_MULTICAST_RATE );
460 DBG_PARAM( DbgInfo, PARM_NAME_DOWNLOAD_FIRMWARE, "\"%s\"", PARM_DOWNLOAD_FIRMWARE );
461 DBG_PARAM( DbgInfo, PARM_NAME_AUTH_KEY_MGMT_SUITE, "%d", PARM_AUTH_KEY_MGMT_SUITE );
462 //;?#if (HCF_TYPE) & HCF_TYPE_STA
463 //;?should we make this code conditional depending on in STA mode
464 //;? DBG_PARAM( DbgInfo, PARM_NAME_PORT_TYPE, "%d", PARM_PORT_TYPE );
465 DBG_PARAM( DbgInfo, PARM_NAME_PM_ENABLED, "%04x", PARM_PM_ENABLED );
466 //;? DBG_PARAM( DbgInfo, PARM_NAME_CREATE_IBSS, "\"%s\"", PARM_CREATE_IBSS );
467 //;? DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RX, "\"%s\"", PARM_MULTICAST_RX );
468 //;? DBG_PARAM( DbgInfo, PARM_NAME_MAX_SLEEP, "%d", PARM_MAX_SLEEP );
469 //;? DBG_PARAM( DbgInfo, PARM_NAME_NETWORK_ADDR, "\"%s\"", DbgHwAddr( PARM_NETWORK_ADDR ));
470 //;? DBG_PARAM( DbgInfo, PARM_NAME_AUTHENTICATION, "%d", PARM_AUTHENTICATION );
471 //;? DBG_PARAM( DbgInfo, PARM_NAME_OWN_ATIM_WINDOW, "%d", PARM_OWN_ATIM_WINDOW );
472 //;? DBG_PARAM( DbgInfo, PARM_NAME_PM_HOLDOVER_DURATION, "%d", PARM_PM_HOLDOVER_DURATION );
473 //;? DBG_PARAM( DbgInfo, PARM_NAME_PROMISCUOUS_MODE, "\"%s\"", PARM_PROMISCUOUS_MODE );
474 //;?#endif /* HCF_STA */
475 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
476 //;?should we restore this to allow smaller memory footprint
477 //;?I guess: no, since this is Debug mode only
478 DBG_PARAM( DbgInfo, PARM_NAME_OWN_DTIM_PERIOD, "%d", PARM_OWN_DTIM_PERIOD );
479 DBG_PARAM( DbgInfo, PARM_NAME_REJECT_ANY, "\"%s\"", PARM_REJECT_ANY );
480 DBG_PARAM( DbgInfo, PARM_NAME_EXCLUDE_UNENCRYPTED, "\"%s\"", PARM_EXCLUDE_UNENCRYPTED );
481 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_PM_BUFFERING, "\"%s\"", PARM_MULTICAST_PM_BUFFERING );
482 DBG_PARAM( DbgInfo, PARM_NAME_INTRA_BSS_RELAY, "\"%s\"", PARM_INTRA_BSS_RELAY );
484 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD1, "%d", PARM_RTS_THRESHOLD1 );
485 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD2, "%d", PARM_RTS_THRESHOLD2 );
486 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD3, "%d", PARM_RTS_THRESHOLD3 );
487 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD4, "%d", PARM_RTS_THRESHOLD4 );
488 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD5, "%d", PARM_RTS_THRESHOLD5 );
489 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD6, "%d", PARM_RTS_THRESHOLD6 );
490 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE1, "%d", PARM_TX_RATE1 );
491 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE2, "%d", PARM_TX_RATE2 );
492 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE3, "%d", PARM_TX_RATE3 );
493 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE4, "%d", PARM_TX_RATE4 );
494 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE5, "%d", PARM_TX_RATE5 );
495 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE6, "%d", PARM_TX_RATE6 );
496 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS1, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS1 ));
497 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS2, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS2 ));
498 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS3, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS3 ));
499 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS4, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS4 ));
500 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS5, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS5 ));
501 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS6, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS6 ));
505 VALID_PARAM( !PARM_DESIRED_SSID || ( strlen( PARM_DESIRED_SSID ) <= PARM_MAX_NAME_LEN ));
506 VALID_PARAM( !PARM_OWN_SSID || ( strlen( PARM_OWN_SSID ) <= PARM_MAX_NAME_LEN ));
507 VALID_PARAM(( PARM_OWN_CHANNEL <= PARM_MAX_OWN_CHANNEL ));
508 VALID_PARAM(( PARM_SYSTEM_SCALE >= PARM_MIN_SYSTEM_SCALE ) && ( PARM_SYSTEM_SCALE <= PARM_MAX_SYSTEM_SCALE ));
509 VALID_PARAM(( PARM_TX_RATE >= PARM_MIN_TX_RATE ) && ( PARM_TX_RATE <= PARM_MAX_TX_RATE ));
510 VALID_PARAM(( PARM_RTS_THRESHOLD <= PARM_MAX_RTS_THRESHOLD ));
511 VALID_PARAM( !PARM_MICROWAVE_ROBUSTNESS || strchr( "NnYy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL );
512 VALID_PARAM( !PARM_OWN_NAME || ( strlen( PARM_NAME_OWN_NAME ) <= PARM_MAX_NAME_LEN ));
513 VALID_PARAM(( PARM_ENABLE_ENCRYPTION <= PARM_MAX_ENABLE_ENCRYPTION ));
514 VALID_PARAM( is_valid_key_string( PARM_KEY1 ));
515 VALID_PARAM( is_valid_key_string( PARM_KEY2 ));
516 VALID_PARAM( is_valid_key_string( PARM_KEY3 ));
517 VALID_PARAM( is_valid_key_string( PARM_KEY4 ));
518 VALID_PARAM(( PARM_TX_KEY >= PARM_MIN_TX_KEY ) && ( PARM_TX_KEY <= PARM_MAX_TX_KEY ));
520 VALID_PARAM(( PARM_MULTICAST_RATE >= PARM_MIN_MULTICAST_RATE ) &&
521 ( PARM_MULTICAST_RATE <= PARM_MAX_MULTICAST_RATE ));
523 VALID_PARAM( !PARM_DOWNLOAD_FIRMWARE || ( strlen( PARM_DOWNLOAD_FIRMWARE ) <= 255 /*;?*/ ));
524 VALID_PARAM(( PARM_AUTH_KEY_MGMT_SUITE < PARM_MAX_AUTH_KEY_MGMT_SUITE ));
526 VALID_PARAM( !PARM_LOAD_BALANCING || strchr( "NnYy", PARM_LOAD_BALANCING[0] ) != NULL );
527 VALID_PARAM( !PARM_MEDIUM_DISTRIBUTION || strchr( "NnYy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL );
528 VALID_PARAM(( PARM_TX_POW_LEVEL <= PARM_MAX_TX_POW_LEVEL ));
530 VALID_PARAM(( PARM_PORT_TYPE >= PARM_MIN_PORT_TYPE ) && ( PARM_PORT_TYPE <= PARM_MAX_PORT_TYPE ));
531 VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
532 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
533 VALID_PARAM( !PARM_CREATE_IBSS || strchr( "NnYy", PARM_CREATE_IBSS[0] ) != NULL );
534 VALID_PARAM( !PARM_MULTICAST_RX || strchr( "NnYy", PARM_MULTICAST_RX[0] ) != NULL );
535 VALID_PARAM(( PARM_MAX_SLEEP <= PARM_MAX_MAX_PM_SLEEP ));
536 VALID_PARAM(( PARM_AUTHENTICATION <= PARM_MAX_AUTHENTICATION ));
537 VALID_PARAM(( PARM_OWN_ATIM_WINDOW <= PARM_MAX_OWN_ATIM_WINDOW ));
538 VALID_PARAM(( PARM_PM_HOLDOVER_DURATION <= PARM_MAX_PM_HOLDOVER_DURATION ));
539 VALID_PARAM( !PARM_PROMISCUOUS_MODE || strchr( "NnYy", PARM_PROMISCUOUS_MODE[0] ) != NULL );
540 VALID_PARAM(( PARM_CONNECTION_CONTROL <= PARM_MAX_CONNECTION_CONTROL ));
542 VALID_PARAM(( PARM_OWN_DTIM_PERIOD >= PARM_MIN_OWN_DTIM_PERIOD ));
543 VALID_PARAM( !PARM_REJECT_ANY || strchr( "NnYy", PARM_REJECT_ANY[0] ) != NULL );
544 VALID_PARAM( !PARM_EXCLUDE_UNENCRYPTED || strchr( "NnYy", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL );
545 VALID_PARAM( !PARM_MULTICAST_PM_BUFFERING || strchr( "NnYy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL );
546 VALID_PARAM( !PARM_INTRA_BSS_RELAY || strchr( "NnYy", PARM_INTRA_BSS_RELAY[0] ) != NULL );
548 VALID_PARAM(( PARM_RTS_THRESHOLD1 <= PARM_MAX_RTS_THRESHOLD ));
549 VALID_PARAM(( PARM_RTS_THRESHOLD2 <= PARM_MAX_RTS_THRESHOLD ));
550 VALID_PARAM(( PARM_RTS_THRESHOLD3 <= PARM_MAX_RTS_THRESHOLD ));
551 VALID_PARAM(( PARM_RTS_THRESHOLD4 <= PARM_MAX_RTS_THRESHOLD ));
552 VALID_PARAM(( PARM_RTS_THRESHOLD5 <= PARM_MAX_RTS_THRESHOLD ));
553 VALID_PARAM(( PARM_RTS_THRESHOLD6 <= PARM_MAX_RTS_THRESHOLD ));
554 VALID_PARAM(( PARM_TX_RATE1 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE1 <= PARM_MAX_TX_RATE ));
555 VALID_PARAM(( PARM_TX_RATE2 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE2 <= PARM_MAX_TX_RATE ));
556 VALID_PARAM(( PARM_TX_RATE3 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE3 <= PARM_MAX_TX_RATE ));
557 VALID_PARAM(( PARM_TX_RATE4 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE4 <= PARM_MAX_TX_RATE ));
558 VALID_PARAM(( PARM_TX_RATE5 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE5 <= PARM_MAX_TX_RATE ));
559 VALID_PARAM(( PARM_TX_RATE6 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE6 <= PARM_MAX_TX_RATE ));
562 VALID_PARAM(( PARM_OWN_BEACON_INTERVAL >= PARM_MIN_OWN_BEACON_INTERVAL ) && ( PARM_OWN_BEACON_INTERVAL <= PARM_MAX_OWN_BEACON_INTERVAL ));
563 VALID_PARAM(( PARM_COEXISTENCE <= PARM_COEXISTENCE ));
565 /* Set the driver parameters from the passed in parameters. */
567 /* THESE MODULE PARAMETERS ARE TO BE DEPRECATED IN FAVOR OF A NAMING CONVENTION
568 WHICH IS INLINE WITH THE FORTHCOMING WAVELAN API */
570 /* START NEW PARAMETERS */
572 lp->Channel = PARM_OWN_CHANNEL;
573 lp->DistanceBetweenAPs = PARM_SYSTEM_SCALE;
575 /* Need to determine how to handle the new bands for 5GHz */
576 lp->TxRateControl[0] = PARM_DEFAULT_TX_RATE_2GHZ;
577 lp->TxRateControl[1] = PARM_DEFAULT_TX_RATE_5GHZ;
579 lp->RTSThreshold = PARM_RTS_THRESHOLD;
581 /* Need to determine how to handle the new bands for 5GHz */
582 lp->MulticastRate[0] = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
583 lp->MulticastRate[1] = PARM_DEFAULT_MULTICAST_RATE_5GHZ;
585 if ( strchr( "Yy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL ) {
586 lp->MicrowaveRobustness = 1;
588 lp->MicrowaveRobustness = 0;
590 if ( PARM_DESIRED_SSID && ( strlen( PARM_DESIRED_SSID ) <= HCF_MAX_NAME_LEN )) {
591 strcpy( lp->NetworkName, PARM_DESIRED_SSID );
593 if ( PARM_OWN_SSID && ( strlen( PARM_OWN_SSID ) <= HCF_MAX_NAME_LEN )) {
594 strcpy( lp->NetworkName, PARM_OWN_SSID );
596 if ( PARM_OWN_NAME && ( strlen( PARM_OWN_NAME ) <= HCF_MAX_NAME_LEN )) {
597 strcpy( lp->StationName, PARM_OWN_NAME );
599 lp->EnableEncryption = PARM_ENABLE_ENCRYPTION;
600 if ( PARM_KEY1 && ( strlen( PARM_KEY1 ) <= MAX_KEY_LEN )) {
601 strcpy( lp->Key1, PARM_KEY1 );
603 if ( PARM_KEY2 && ( strlen( PARM_KEY2 ) <= MAX_KEY_LEN )) {
604 strcpy( lp->Key2, PARM_KEY2 );
606 if ( PARM_KEY3 && ( strlen( PARM_KEY3 ) <= MAX_KEY_LEN )) {
607 strcpy( lp->Key3, PARM_KEY3 );
609 if ( PARM_KEY4 && ( strlen( PARM_KEY4 ) <= MAX_KEY_LEN )) {
610 strcpy( lp->Key4, PARM_KEY4 );
613 lp->TransmitKeyID = PARM_TX_KEY;
615 key_string2key( lp->Key1, &(lp->DefaultKeys.key[0] ));
616 key_string2key( lp->Key2, &(lp->DefaultKeys.key[1] ));
617 key_string2key( lp->Key3, &(lp->DefaultKeys.key[2] ));
618 key_string2key( lp->Key4, &(lp->DefaultKeys.key[3] ));
620 lp->DownloadFirmware = 1 ; //;?to be upgraded PARM_DOWNLOAD_FIRMWARE;
621 lp->AuthKeyMgmtSuite = PARM_AUTH_KEY_MGMT_SUITE;
623 if ( strchr( "Yy", PARM_LOAD_BALANCING[0] ) != NULL ) {
624 lp->loadBalancing = 1;
626 lp->loadBalancing = 0;
629 if ( strchr( "Yy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL ) {
630 lp->mediumDistribution = 1;
632 lp->mediumDistribution = 0;
635 lp->txPowLevel = PARM_TX_POW_LEVEL;
637 lp->srsc[0] = PARM_SRSC_2GHZ;
638 lp->srsc[1] = PARM_SRSC_5GHZ;
639 lp->brsc[0] = PARM_BRSC_2GHZ;
640 lp->brsc[1] = PARM_BRSC_5GHZ;
641 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
642 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
643 lp->PortType = PARM_PORT_TYPE;
644 lp->MaxSleepDuration = PARM_MAX_SLEEP;
645 lp->authentication = PARM_AUTHENTICATION;
646 lp->atimWindow = PARM_OWN_ATIM_WINDOW;
647 lp->holdoverDuration = PARM_PM_HOLDOVER_DURATION;
648 lp->PMEnabled = PARM_PM_ENABLED; //;?
649 if ( strchr( "Yy", PARM_CREATE_IBSS[0] ) != NULL ) {
654 if ( strchr( "Nn", PARM_MULTICAST_RX[0] ) != NULL ) {
655 lp->MulticastReceive = 0;
657 lp->MulticastReceive = 1;
659 if ( strchr( "Yy", PARM_PROMISCUOUS_MODE[0] ) != NULL ) {
660 lp->promiscuousMode = 1;
662 lp->promiscuousMode = 0;
664 for( i = 0; i < ETH_ALEN; i++ ) {
665 lp->MACAddress[i] = PARM_NETWORK_ADDR[i];
668 lp->connectionControl = PARM_CONNECTION_CONTROL;
671 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
672 //;?should we restore this to allow smaller memory footprint
673 lp->DTIMPeriod = PARM_OWN_DTIM_PERIOD;
675 if ( strchr( "Yy", PARM_REJECT_ANY[0] ) != NULL ) {
680 if ( strchr( "Nn", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL ) {
681 lp->ExcludeUnencrypted = 0;
683 lp->ExcludeUnencrypted = 1;
685 if ( strchr( "Yy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL ) {
686 lp->multicastPMBuffering = 1;
688 lp->multicastPMBuffering = 0;
690 if ( strchr( "Yy", PARM_INTRA_BSS_RELAY[0] ) != NULL ) {
691 lp->intraBSSRelay = 1;
693 lp->intraBSSRelay = 0;
696 lp->ownBeaconInterval = PARM_OWN_BEACON_INTERVAL;
697 lp->coexistence = PARM_COEXISTENCE;
700 lp->wds_port[0].rtsThreshold = PARM_RTS_THRESHOLD1;
701 lp->wds_port[1].rtsThreshold = PARM_RTS_THRESHOLD2;
702 lp->wds_port[2].rtsThreshold = PARM_RTS_THRESHOLD3;
703 lp->wds_port[3].rtsThreshold = PARM_RTS_THRESHOLD4;
704 lp->wds_port[4].rtsThreshold = PARM_RTS_THRESHOLD5;
705 lp->wds_port[5].rtsThreshold = PARM_RTS_THRESHOLD6;
706 lp->wds_port[0].txRateCntl = PARM_TX_RATE1;
707 lp->wds_port[1].txRateCntl = PARM_TX_RATE2;
708 lp->wds_port[2].txRateCntl = PARM_TX_RATE3;
709 lp->wds_port[3].txRateCntl = PARM_TX_RATE4;
710 lp->wds_port[4].txRateCntl = PARM_TX_RATE5;
711 lp->wds_port[5].txRateCntl = PARM_TX_RATE6;
713 for( i = 0; i < ETH_ALEN; i++ ) {
714 lp->wds_port[0].wdsAddress[i] = PARM_WDS_ADDRESS1[i];
716 for( i = 0; i < ETH_ALEN; i++ ) {
717 lp->wds_port[1].wdsAddress[i] = PARM_WDS_ADDRESS2[i];
719 for( i = 0; i < ETH_ALEN; i++ ) {
720 lp->wds_port[2].wdsAddress[i] = PARM_WDS_ADDRESS3[i];
722 for( i = 0; i < ETH_ALEN; i++ ) {
723 lp->wds_port[3].wdsAddress[i] = PARM_WDS_ADDRESS4[i];
725 for( i = 0; i < ETH_ALEN; i++ ) {
726 lp->wds_port[4].wdsAddress[i] = PARM_WDS_ADDRESS5[i];
728 for( i = 0; i < ETH_ALEN; i++ ) {
729 lp->wds_port[5].wdsAddress[i] = PARM_WDS_ADDRESS6[i];
734 if ( strchr( "Yy", useRTS[0] ) != NULL ) {
742 /* END NEW PARAMETERS */
745 wl_lock( lp, &flags );
747 /* Initialize the portState variable */
748 lp->portState = WVLAN_PORT_STATE_DISABLED;
750 /* Initialize the ScanResult struct */
751 memset( &( lp->scan_results ), 0, sizeof( lp->scan_results ));
752 lp->scan_results.scan_complete = FALSE;
754 /* Initialize the ProbeResult struct */
755 memset( &( lp->probe_results ), 0, sizeof( lp->probe_results ));
756 lp->probe_results.scan_complete = FALSE;
757 lp->probe_num_aps = 0;
760 /* Initialize Tx queue stuff */
761 memset( lp->txList, 0, sizeof( lp->txList ));
763 INIT_LIST_HEAD( &( lp->txFree ));
769 for( i = 0; i < DEFAULT_NUM_TX_FRAMES; i++ ) {
770 list_add_tail( &( lp->txList[i].node ), &( lp->txFree ));
774 for( i = 0; i < WVLAN_MAX_TX_QUEUES; i++ ) {
775 INIT_LIST_HEAD( &( lp->txQ[i] ));
778 lp->netif_queue_on = TRUE;
780 /* Initialize the use_dma element in the adapter structure. Not sure if
781 this should be a compile-time or run-time configurable. So for now,
782 implement as run-time and just define here */
785 DBG_TRACE( DbgInfo, "HERMES 2.5 BUSMASTER DMA MODE\n" );
788 DBG_TRACE( DbgInfo, "HERMES 2.5 PORT I/O MODE\n" );
793 /* Register the ISR handler information here, so that it's not done
794 repeatedly in the ISR */
795 tasklet_init(&lp->task, wl_isr_handler, (unsigned long)lp);
797 /* Connect to the adapter */
798 DBG_TRACE( DbgInfo, "Calling hcf_connect()...\n" );
799 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
800 //HCF_ERR_INCOMP_FW is acceptable, because download must still take place
801 //HCF_ERR_INCOMP_PRI is not acceptable
802 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
803 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
804 wl_unlock( lp, &flags );
808 //;?should set HCF_version and how about driver_stat
809 lp->driverInfo.IO_address = dev->base_addr;
810 lp->driverInfo.IO_range = HCF_NUM_IO_PORTS; //;?conditionally 0x40 or 0x80 seems better
811 lp->driverInfo.IRQ_number = dev->irq;
812 lp->driverInfo.card_stat = lp->hcfCtx.IFB_CardStat;
813 //;? what happened to frame_type
815 /* Fill in the driver identity structure */
816 lp->driverIdentity.len = ( sizeof( lp->driverIdentity ) / sizeof( hcf_16 )) - 1;
817 lp->driverIdentity.typ = CFG_DRV_IDENTITY;
818 lp->driverIdentity.comp_id = DRV_IDENTITY;
819 lp->driverIdentity.variant = DRV_VARIANT;
820 lp->driverIdentity.version_major = DRV_MAJOR_VERSION;
821 lp->driverIdentity.version_minor = DRV_MINOR_VERSION;
824 /* Start the card here - This needs to be done in order to get the
825 MAC address for the network layer */
826 DBG_TRACE( DbgInfo, "Calling wvlan_go() to perform a card reset...\n" );
827 hcf_status = wl_go( lp );
829 if ( hcf_status != HCF_SUCCESS ) {
830 DBG_ERROR( DbgInfo, "wl_go() failed\n" );
831 wl_unlock( lp, &flags );
835 /* Certain RIDs must be set before enabling the ports */
836 wl_put_ltv_init( lp );
838 #if 0 //;?why was this already commented out in wl_lkm_720
839 /* Enable the ports */
840 if ( wl_adapter_is_open( lp->dev )) {
841 /* Enable the ports */
842 DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
843 hcf_status = wl_enable( lp );
845 if ( hcf_status != HCF_SUCCESS ) {
846 DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", hcf_status );
849 #if (HCF_TYPE) & HCF_TYPE_AP
850 DBG_TRACE( DbgInfo, "Enabling WDS Ports\n" );
851 //wl_enable_wds_ports( lp );
852 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
857 /* Fill out the MAC address information in the net_device struct */
858 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN );
859 dev->addr_len = ETH_ALEN;
861 lp->is_registered = TRUE;
864 /* Parse the config file for the sake of creating WDS ports if WDS is
865 configured there but not in the module options */
867 #endif /* USE_PROFILE */
869 /* If we're going into AP Mode, register the "virtual" ethernet devices
871 WL_WDS_NETDEV_REGISTER( lp );
873 /* Reset the DownloadFirmware variable in the private struct. If the
874 config file is not used, this will not matter; if it is used, it
875 will be reparsed in wl_open(). This is done because logic in wl_open
876 used to check if a firmware download is needed is broken by parsing
877 the file here; however, this parsing is needed to register WDS ports
878 in AP mode, if they are configured */
879 lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //;?download_firmware;
882 if ( lp->useRTS == 1 ) {
883 DBG_TRACE( DbgInfo, "ENTERING RTS MODE...\n" );
884 wl_act_int_off( lp );
885 lp->is_handling_int = WL_NOT_HANDLING_INT; // Not handling interrupts anymore
889 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT);
893 wl_unlock( lp, &flags );
895 DBG_TRACE( DbgInfo, "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
896 dev->name, dev->base_addr, dev->irq );
898 for( i = 0; i < ETH_ALEN; i++ ) {
899 printk( "%02X%c", dev->dev_addr[i], (( i < ( ETH_ALEN-1 )) ? ':' : '\n' ));
902 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
903 create_proc_read_entry( "wlags", 0, NULL, scull_read_procmem, dev );
904 proc_mkdir("driver/wlags49", 0);
905 proc_write("driver/wlags49/wlags49_type", write_int, &lp->wlags49_type);
906 #endif /* SCULL_USE_PROC */
908 DBG_LEAVE( DbgInfo );
912 wl_hcf_error( dev, hcf_status );
916 DBG_ERROR( DbgInfo, "wl_insert() FAILED\n" );
918 if ( lp->is_registered == TRUE ) {
919 lp->is_registered = FALSE;
922 WL_WDS_NETDEV_DEREGISTER( lp );
927 DBG_LEAVE( DbgInfo );
930 /*============================================================================*/
933 /*******************************************************************************
935 *******************************************************************************
943 * dev - a pointer to the net_device struct of the wireless device
949 ******************************************************************************/
950 int wl_reset(struct net_device *dev)
952 struct wl_private *lp = wl_priv(dev);
953 int hcf_status = HCF_SUCCESS;
954 /*------------------------------------------------------------------------*/
955 DBG_FUNC( "wl_reset" );
956 DBG_ENTER( DbgInfo );
957 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
958 DBG_PARAM( DbgInfo, "dev->base_addr", "(%#03lx)", dev->base_addr );
961 * The caller should already have a lock and
962 * disable the interrupts, we do not lock here,
963 * nor do we enable/disable interrupts!
966 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", dev->base_addr );
967 if ( dev->base_addr ) {
968 /* Shutdown the adapter. */
969 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
971 /* Reset the driver information. */
974 /* Connect to the adapter. */
975 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
976 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
977 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
981 /* Check if firmware is present, if not change state */
982 if ( hcf_status == HCF_ERR_INCOMP_FW ) {
983 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
986 /* Initialize the portState variable */
987 lp->portState = WVLAN_PORT_STATE_DISABLED;
989 /* Restart the adapter. */
990 hcf_status = wl_go( lp );
991 if ( hcf_status != HCF_SUCCESS ) {
992 DBG_ERROR( DbgInfo, "wl_go() failed, status: 0x%x\n", hcf_status );
996 /* Certain RIDs must be set before enabling the ports */
997 wl_put_ltv_init( lp );
999 DBG_ERROR( DbgInfo, "Device Base Address INVALID!!!\n" );
1003 DBG_LEAVE( DbgInfo );
1006 /*============================================================================*/
1009 /*******************************************************************************
1011 *******************************************************************************
1015 * Reset the adapter.
1019 * dev - a pointer to the net_device struct of the wireless device
1023 * an HCF status code
1025 ******************************************************************************/
1026 int wl_go( struct wl_private *lp )
1028 int hcf_status = HCF_SUCCESS;
1029 char *cp = NULL; //fw_image
1031 /*------------------------------------------------------------------------*/
1032 DBG_FUNC( "wl_go" );
1033 DBG_ENTER( DbgInfo );
1035 hcf_status = wl_disable( lp );
1036 if ( hcf_status != HCF_SUCCESS ) {
1037 DBG_TRACE( DbgInfo, "Disable port 0 failed: 0x%x\n", hcf_status );
1039 while (( hcf_status != HCF_SUCCESS ) && (retries < 10)) {
1041 hcf_status = wl_disable( lp );
1043 if ( hcf_status == HCF_SUCCESS ) {
1044 DBG_TRACE( DbgInfo, "Disable port 0 succes : %d retries\n", retries );
1046 DBG_TRACE( DbgInfo, "Disable port 0 failed after: %d retries\n", retries );
1050 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
1051 //DBG_TRACE( DbgInfo, "Disabling WDS Ports\n" );
1052 //wl_disable_wds_ports( lp );
1053 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1055 //;?what was the purpose of this
1056 // /* load the appropriate firmware image, depending on driver mode */
1057 // lp->ltvRecord.len = ( sizeof( CFG_RANGE20_STRCT ) / sizeof( hcf_16 )) - 1;
1058 // lp->ltvRecord.typ = CFG_DRV_ACT_RANGES_PRI;
1059 // hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1062 if ( strlen( lp->fw_image_filename ) ) {
1067 DBG_TRACE( DbgInfo, "F/W image:%s:\n", lp->fw_image_filename );
1068 /* Obtain a user-space process context, storing the original context */
1071 file_desc = open( lp->fw_image_filename, O_RDONLY, 0 );
1072 if ( file_desc == -1 ) {
1073 DBG_ERROR( DbgInfo, "No image file found\n" );
1075 DBG_TRACE( DbgInfo, "F/W image file found\n" );
1076 #define DHF_ALLOC_SIZE 96000 //just below 96K, let's hope it suffices for now and for the future
1077 cp = (char*)vmalloc( DHF_ALLOC_SIZE );
1079 DBG_ERROR( DbgInfo, "error in vmalloc\n" );
1081 rc = read( file_desc, cp, DHF_ALLOC_SIZE );
1082 if ( rc == DHF_ALLOC_SIZE ) {
1083 DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE );
1084 } else if ( rc > 0 ) {
1085 DBG_TRACE( DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp );
1086 rc = read( file_desc, &cp[rc], 1 );
1087 if ( rc == 0 ) { //;/change to an until-loop at rc<=0
1088 DBG_TRACE( DbgInfo, "no more to read\n" );
1092 DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\
1093 ", give up, too complicated, rc = %0X\n", rc );
1094 DBG_ERROR( DbgInfo, "still have to change code to get a real download now !!!!!!!!\n" );
1096 DBG_TRACE( DbgInfo, "before dhf_download_binary\n" );
1097 hcf_status = dhf_download_binary( (memimage *)cp );
1098 DBG_TRACE( DbgInfo, "after dhf_download_binary, before dhf_download_fw\n" );
1099 //;?improve error flow/handling
1100 hcf_status = dhf_download_fw( &lp->hcfCtx, (memimage *)cp );
1101 DBG_TRACE( DbgInfo, "after dhf_download_fw\n" );
1107 set_fs( fs ); /* Return to the original context */
1111 /* If firmware is present but the type is unknown then download anyway */
1112 if ( (lp->firmware_present == WL_FRIMWARE_PRESENT)
1114 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_STA )
1116 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_AP ) ) {
1117 /* Unknown type, download needed. */
1118 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1121 if(lp->firmware_present == WL_FRIMWARE_NOT_PRESENT)
1124 DBG_TRACE( DbgInfo, "Downloading STA firmware...\n" );
1125 // hcf_status = dhf_download_fw( &lp->hcfCtx, &station );
1126 hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image );
1128 if ( hcf_status != HCF_SUCCESS ) {
1129 DBG_ERROR( DbgInfo, "Firmware Download failed\n" );
1130 DBG_LEAVE( DbgInfo );
1134 /* Report the FW versions */
1135 //;?obsolete, use the available IFB info:: wl_get_pri_records( lp );
1136 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1137 DBG_TRACE( DbgInfo, "downloaded station F/W\n" );
1138 } else if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1139 DBG_TRACE( DbgInfo, "downloaded AP F/W\n" );
1141 DBG_ERROR( DbgInfo, "unknown F/W type\n" );
1145 * Downloaded, no need to repeat this next time, assume the
1146 * contents stays in the card until it is powered off. Note we
1147 * do not switch firmware on the fly, the firmware is fixed in
1148 * the driver for now.
1150 lp->firmware_present = WL_FRIMWARE_PRESENT;
1152 DBG_TRACE( DbgInfo, "ComponentID:%04x variant:%04x major:%04x minor:%04x\n",
1153 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ),
1154 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.variant ),
1155 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_major ),
1156 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_minor ));
1158 /* now we wil get the MAC address of the card */
1159 lp->ltvRecord.len = 4;
1160 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1161 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1164 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1166 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1167 if ( hcf_status != HCF_SUCCESS ) {
1168 DBG_ERROR( DbgInfo, "Could not retrieve MAC address\n" );
1169 DBG_LEAVE( DbgInfo );
1172 memcpy( lp->MACAddress, &lp->ltvRecord.u.u8[0], ETH_ALEN );
1173 DBG_TRACE( DbgInfo, "Card MAC Address: %s\n", DbgHwAddr( lp->MACAddress ));
1175 /* Write out configuration to the device, enable, and reconnect. However,
1176 only reconnect if in AP mode. For STA mode, need to wait for passive scan
1177 completion before a connect can be issued */
1179 /* Enable the ports */
1180 hcf_status = wl_enable( lp );
1182 if ( lp->DownloadFirmware == WVLAN_DRV_MODE_AP ) {
1184 wl_enable_wds_ports( lp );
1186 hcf_status = wl_connect( lp );
1188 DBG_LEAVE( DbgInfo );
1191 /*============================================================================*/
1194 /*******************************************************************************
1196 *******************************************************************************
1200 * Write TxKeyID and WEP keys to the adapter. This is separated from
1201 * wl_apply() to allow dynamic WEP key updates through the wireless
1206 * lp - a pointer to the wireless adapter's private structure
1212 ******************************************************************************/
1213 void wl_set_wep_keys( struct wl_private *lp )
1216 /*------------------------------------------------------------------------*/
1217 DBG_FUNC( "wl_set_wep_keys" );
1218 DBG_ENTER( DbgInfo );
1219 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1220 if ( lp->EnableEncryption ) {
1221 /* NOTE: CFG_CNF_ENCRYPTION is set in wl_put_ltv() as it's a static
1225 lp->ltvRecord.len = 2;
1226 lp->ltvRecord.typ = CFG_TX_KEY_ID;
1227 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE(lp->TransmitKeyID - 1);
1229 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1231 DBG_TRACE( DbgInfo, "Key 1 len: %d\n", lp->DefaultKeys.key[0].len );
1232 DBG_TRACE( DbgInfo, "Key 2 len: %d\n", lp->DefaultKeys.key[1].len );
1233 DBG_TRACE( DbgInfo, "Key 3 len: %d\n", lp->DefaultKeys.key[2].len );
1234 DBG_TRACE( DbgInfo, "Key 4 len: %d\n", lp->DefaultKeys.key[3].len );
1237 lp->DefaultKeys.len = sizeof( lp->DefaultKeys ) / sizeof( hcf_16 ) - 1;
1238 lp->DefaultKeys.typ = CFG_DEFAULT_KEYS;
1240 /* endian translate the appropriate key information */
1241 for( count = 0; count < MAX_KEYS; count++ ) {
1242 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1245 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->DefaultKeys ));
1247 /* Reverse the above endian translation, since these keys are accessed
1249 for( count = 0; count < MAX_KEYS; count++ ) {
1250 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1253 DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption, lp->TransmitKeyID );
1254 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 );
1257 DBG_LEAVE( DbgInfo );
1258 } // wl_set_wep_keys
1259 /*============================================================================*/
1262 /*******************************************************************************
1264 *******************************************************************************
1268 * Write the parameters to the adapter. (re-)enables the card if device is
1269 * open. Returns hcf_status of hcf_enable().
1273 * lp - a pointer to the wireless adapter's private structure
1277 * an HCF status code
1279 ******************************************************************************/
1280 int wl_apply(struct wl_private *lp)
1282 int hcf_status = HCF_SUCCESS;
1283 /*------------------------------------------------------------------------*/
1284 DBG_FUNC( "wl_apply" );
1285 DBG_ENTER( DbgInfo );
1286 DBG_ASSERT( lp != NULL);
1287 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1289 if ( !( lp->flags & WVLAN2_UIL_BUSY )) {
1290 /* The adapter parameters have changed:
1296 if ( wl_adapter_is_open( lp->dev )) {
1297 /* Disconnect and disable if necessary */
1298 hcf_status = wl_disconnect( lp );
1299 if ( hcf_status != HCF_SUCCESS ) {
1300 DBG_ERROR( DbgInfo, "Disconnect failed\n" );
1301 DBG_LEAVE( DbgInfo );
1304 hcf_status = wl_disable( lp );
1305 if ( hcf_status != HCF_SUCCESS ) {
1306 DBG_ERROR( DbgInfo, "Disable failed\n" );
1307 DBG_LEAVE( DbgInfo );
1310 /* Write out configuration to the device, enable, and reconnect.
1311 However, only reconnect if in AP mode. For STA mode, need to
1312 wait for passive scan completion before a connect can be
1314 hcf_status = wl_put_ltv( lp );
1316 if ( hcf_status == HCF_SUCCESS ) {
1317 hcf_status = wl_enable( lp );
1319 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1320 hcf_status = wl_connect( lp );
1323 DBG_WARNING( DbgInfo, "wl_put_ltv() failed\n" );
1329 DBG_LEAVE( DbgInfo );
1332 /*============================================================================*/
1335 /*******************************************************************************
1337 *******************************************************************************
1341 * Used to set basic parameters for card initialization.
1345 * lp - a pointer to the wireless adapter's private structure
1349 * an HCF status code
1351 ******************************************************************************/
1352 int wl_put_ltv_init( struct wl_private *lp )
1356 CFG_RID_LOG_STRCT *RidLog;
1357 /*------------------------------------------------------------------------*/
1358 DBG_FUNC( "wl_put_ltv_init" );
1359 DBG_ENTER( DbgInfo );
1361 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1362 DBG_LEAVE( DbgInfo );
1366 lp->ltvRecord.len = 2;
1367 lp->ltvRecord.typ = CFG_CNTL_OPT;
1369 /* The Card Services build must ALWAYS configure for 16-bit I/O. PCI or
1370 CardBus can be set to either 16/32 bit I/O, or Bus Master DMA, but only
1373 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_16BIT );
1375 if ( lp->use_dma ) {
1376 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_DMA );
1378 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1382 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1383 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT : 0x%04x\n",
1384 lp->ltvRecord.u.u16[0] );
1385 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT result : 0x%04x\n",
1388 /* Register the list of RIDs on which asynchronous notification is
1389 required. Note that this mechanism replaces the mailbox, so the mailbox
1390 can be queried by the host (if desired) without contention from us */
1393 lp->RidList[i].len = sizeof( lp->ProbeResp );
1394 lp->RidList[i].typ = CFG_ACS_SCAN;
1395 lp->RidList[i].bufp = (wci_recordp)&lp->ProbeResp;
1396 //lp->ProbeResp.infoType = 0xFFFF;
1399 lp->RidList[i].len = sizeof( lp->assoc_stat );
1400 lp->RidList[i].typ = CFG_ASSOC_STAT;
1401 lp->RidList[i].bufp = (wci_recordp)&lp->assoc_stat;
1402 lp->assoc_stat.len = 0xFFFF;
1405 lp->RidList[i].len = 4;
1406 lp->RidList[i].typ = CFG_UPDATED_INFO_RECORD;
1407 lp->RidList[i].bufp = (wci_recordp)&lp->updatedRecord;
1408 lp->updatedRecord.len = 0xFFFF;
1411 lp->RidList[i].len = sizeof( lp->sec_stat );
1412 lp->RidList[i].typ = CFG_SECURITY_STAT;
1413 lp->RidList[i].bufp = (wci_recordp)&lp->sec_stat;
1414 lp->sec_stat.len = 0xFFFF;
1417 lp->RidList[i].typ = 0; // Terminate List
1419 RidLog = (CFG_RID_LOG_STRCT *)&lp->ltvRecord;
1421 RidLog->typ = CFG_REG_INFO_LOG;
1422 RidLog->recordp = (RID_LOGP)&lp->RidList[0];
1424 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1425 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG\n" );
1426 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG result : 0x%04x\n",
1428 DBG_LEAVE( DbgInfo );
1430 } // wl_put_ltv_init
1431 /*============================================================================*/
1434 /*******************************************************************************
1436 *******************************************************************************
1440 * Used by wvlan_apply() and wvlan_go to set the card's configuration.
1444 * lp - a pointer to the wireless adapter's private structure
1448 * an HCF status code
1450 ******************************************************************************/
1451 int wl_put_ltv( struct wl_private *lp )
1455 /*------------------------------------------------------------------------*/
1456 DBG_FUNC( "wl_put_ltv" );
1457 DBG_ENTER( DbgInfo );
1460 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1463 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1464 lp->maxPort = 6; //;?why set this here and not as part of download process
1469 /* Send our configuration to the card. Perform any endian translation
1471 /* Register the Mailbox; VxWorks does this elsewhere; why;? */
1472 lp->ltvRecord.len = 4;
1473 lp->ltvRecord.typ = CFG_REG_MB;
1474 lp->ltvRecord.u.u32[0] = (u_long)&( lp->mailbox );
1475 lp->ltvRecord.u.u16[2] = ( MB_SIZE / sizeof( hcf_16 ));
1476 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1478 /* Max Data Length */
1479 lp->ltvRecord.len = 2;
1480 lp->ltvRecord.typ = CFG_CNF_MAX_DATA_LEN;
1481 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( HCF_MAX_PACKET_SIZE );
1482 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1484 /* System Scale / Distance between APs */
1485 lp->ltvRecord.len = 2;
1486 lp->ltvRecord.typ = CFG_CNF_SYSTEM_SCALE;
1487 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DistanceBetweenAPs );
1488 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1491 if ( lp->CreateIBSS && ( lp->Channel == 0 )) {
1492 DBG_TRACE( DbgInfo, "Create IBSS" );
1495 lp->ltvRecord.len = 2;
1496 lp->ltvRecord.typ = CFG_CNF_OWN_CHANNEL;
1497 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->Channel );
1498 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1500 /* Microwave Robustness */
1501 lp->ltvRecord.len = 2;
1502 lp->ltvRecord.typ = CFG_CNF_MICRO_WAVE;
1503 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MicrowaveRobustness );
1504 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1506 /* Load Balancing */
1507 lp->ltvRecord.len = 2;
1508 lp->ltvRecord.typ = CFG_CNF_LOAD_BALANCING;
1509 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->loadBalancing );
1510 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1512 /* Medium Distribution */
1513 lp->ltvRecord.len = 2;
1514 lp->ltvRecord.typ = CFG_CNF_MEDIUM_DISTRIBUTION;
1515 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->mediumDistribution );
1516 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1520 /* Tx Power Level (for supported cards) */
1521 lp->ltvRecord.len = 2;
1522 lp->ltvRecord.typ = CFG_CNF_TX_POW_LVL;
1523 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->txPowLevel );
1524 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1526 /* Short Retry Limit */
1527 /*lp->ltvRecord.len = 2;
1528 lp->ltvRecord.typ = 0xFC32;
1529 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->shortRetryLimit );
1530 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1533 /* Long Retry Limit */
1534 /*lp->ltvRecord.len = 2;
1535 lp->ltvRecord.typ = 0xFC33;
1536 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->longRetryLimit );
1537 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1540 /* Supported Rate Set Control */
1541 lp->ltvRecord.len = 3;
1542 lp->ltvRecord.typ = CFG_SUPPORTED_RATE_SET_CNTL; //0xFC88;
1543 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->srsc[0] );
1544 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->srsc[1] );
1545 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1547 /* Basic Rate Set Control */
1548 lp->ltvRecord.len = 3;
1549 lp->ltvRecord.typ = CFG_BASIC_RATE_SET_CNTL; //0xFC89;
1550 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->brsc[0] );
1551 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->brsc[1] );
1552 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1554 /* Frame Burst Limit */
1555 /* Defined, but not currently available in Firmware */
1560 /* Multicast Rate */
1561 lp->ltvRecord.len = 3;
1562 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1563 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1564 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->MulticastRate[1] );
1566 lp->ltvRecord.len = 2;
1567 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1568 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1570 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1572 /* Own Name (Station Nickname) */
1573 if (( len = ( strlen( lp->StationName ) + 1 ) & ~0x01 ) != 0 ) {
1574 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : %s\n",
1575 // lp->StationName );
1577 lp->ltvRecord.len = 2 + ( len / sizeof( hcf_16 ));
1578 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1579 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->StationName ));
1581 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->StationName, len );
1583 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : EMPTY\n" );
1585 lp->ltvRecord.len = 2;
1586 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1587 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1590 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1592 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME result : 0x%04x\n",
1595 /* The following are set in STA mode only */
1596 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1599 lp->ltvRecord.len = 2;
1600 lp->ltvRecord.typ = CFG_RTS_THRH;
1601 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1602 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1605 lp->ltvRecord.len = 2;
1606 lp->ltvRecord.typ = CFG_CNF_PORT_TYPE;
1607 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PortType );
1608 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1610 /* Tx Rate Control */
1612 lp->ltvRecord.len = 3;
1613 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1614 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1615 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1617 lp->ltvRecord.len = 2;
1618 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1619 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1622 //;?skip temporarily to see whether the RID or something else is the probelm hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1624 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 2.4GHz : 0x%04x\n",
1625 lp->TxRateControl[0] );
1626 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 5.0GHz : 0x%04x\n",
1627 lp->TxRateControl[1] );
1628 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL result : 0x%04x\n",
1630 /* Power Management */
1631 lp->ltvRecord.len = 2;
1632 lp->ltvRecord.typ = CFG_CNF_PM_ENABLED;
1633 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PMEnabled );
1634 // lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0x8001 );
1635 DBG_TRACE( DbgInfo, "CFG_CNF_PM_ENABLED : 0x%04x\n", lp->PMEnabled );
1636 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1637 /* Multicast Receive */
1638 lp->ltvRecord.len = 2;
1639 lp->ltvRecord.typ = CFG_CNF_MCAST_RX;
1640 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastReceive );
1641 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1643 /* Max Sleep Duration */
1644 lp->ltvRecord.len = 2;
1645 lp->ltvRecord.typ = CFG_CNF_MAX_SLEEP_DURATION;
1646 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MaxSleepDuration );
1647 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1650 lp->ltvRecord.len = 2;
1651 lp->ltvRecord.typ = CFG_CREATE_IBSS;
1652 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->CreateIBSS );
1653 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1656 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1657 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1658 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1659 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : %s\n",
1660 // lp->NetworkName );
1662 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1663 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1664 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1666 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1668 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : ANY\n" );
1670 lp->ltvRecord.len = 2;
1671 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1672 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1675 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1677 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID result : 0x%04x\n",
1679 /* Own ATIM window */
1680 lp->ltvRecord.len = 2;
1681 lp->ltvRecord.typ = CFG_CNF_OWN_ATIM_WINDOW;
1682 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->atimWindow );
1683 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1686 /* Holdover Duration */
1687 lp->ltvRecord.len = 2;
1688 lp->ltvRecord.typ = CFG_CNF_HOLDOVER_DURATION;
1689 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->holdoverDuration );
1690 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1692 /* Promiscuous Mode */
1693 lp->ltvRecord.len = 2;
1694 lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
1695 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->promiscuousMode );
1696 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1698 /* Authentication */
1699 lp->ltvRecord.len = 2;
1700 lp->ltvRecord.typ = CFG_CNF_AUTHENTICATION;
1701 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->authentication );
1702 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1704 /* Connection Control */
1705 lp->ltvRecord.len = 2;
1706 lp->ltvRecord.typ = CFG_CNF_CONNECTION_CNTL;
1707 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->connectionControl );
1708 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1712 /* Probe data rate */
1713 /*lp->ltvRecord.len = 3;
1714 lp->ltvRecord.typ = CFG_PROBE_DATA_RATE;
1715 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->probeDataRates[0] );
1716 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->probeDataRates[1] );
1717 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1719 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 2.4GHz : 0x%04x\n",
1720 lp->probeDataRates[0] );
1721 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 5.0GHz : 0x%04x\n",
1722 lp->probeDataRates[1] );
1723 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE result : 0x%04x\n",
1727 /* The following are set in AP mode only */
1728 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
1729 //;?should we restore this to allow smaller memory footprint
1732 lp->ltvRecord.len = 2;
1733 lp->ltvRecord.typ = CFG_CNF_OWN_DTIM_PERIOD;
1734 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DTIMPeriod );
1735 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1737 /* Multicast PM Buffering */
1738 lp->ltvRecord.len = 2;
1739 lp->ltvRecord.typ = CFG_CNF_MCAST_PM_BUF;
1740 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->multicastPMBuffering );
1741 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1743 /* Reject ANY - Closed System */
1744 lp->ltvRecord.len = 2;
1745 lp->ltvRecord.typ = CFG_CNF_REJECT_ANY;
1746 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RejectAny );
1748 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1750 /* Exclude Unencrypted */
1751 lp->ltvRecord.len = 2;
1752 lp->ltvRecord.typ = CFG_CNF_EXCL_UNENCRYPTED;
1753 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ExcludeUnencrypted );
1755 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1757 /* IntraBSS Relay */
1758 lp->ltvRecord.len = 2;
1759 lp->ltvRecord.typ = CFG_CNF_INTRA_BSS_RELAY;
1760 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->intraBSSRelay );
1761 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1763 /* RTS Threshold 0 */
1764 lp->ltvRecord.len = 2;
1765 lp->ltvRecord.typ = CFG_RTS_THRH0;
1766 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1768 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1770 /* Tx Rate Control 0 */
1772 lp->ltvRecord.len = 3;
1773 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1774 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1775 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1777 lp->ltvRecord.len = 2;
1778 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1779 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1782 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1784 /* Own Beacon Interval */
1785 lp->ltvRecord.len = 2;
1786 lp->ltvRecord.typ = 0xFC31;
1787 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ownBeaconInterval );
1788 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1790 /* Co-Existence Behavior */
1791 lp->ltvRecord.len = 2;
1792 lp->ltvRecord.typ = 0xFCC7;
1793 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->coexistence );
1794 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1798 /* RTS Threshold 1 */
1799 lp->ltvRecord.len = 2;
1800 lp->ltvRecord.typ = CFG_RTS_THRH1;
1801 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].rtsThreshold );
1802 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1804 /* RTS Threshold 2 */
1805 lp->ltvRecord.len = 2;
1806 lp->ltvRecord.typ = CFG_RTS_THRH2;
1807 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].rtsThreshold );
1808 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1811 /* RTS Threshold 3 */
1812 lp->ltvRecord.len = 2;
1813 lp->ltvRecord.typ = CFG_RTS_THRH3;
1814 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].rtsThreshold );
1815 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1818 /* RTS Threshold 4 */
1819 lp->ltvRecord.len = 2;
1820 lp->ltvRecord.typ = CFG_RTS_THRH4;
1821 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].rtsThreshold );
1822 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1825 /* RTS Threshold 5 */
1826 lp->ltvRecord.len = 2;
1827 lp->ltvRecord.typ = CFG_RTS_THRH5;
1828 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].rtsThreshold );
1829 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1831 /* RTS Threshold 6 */
1832 lp->ltvRecord.len = 2;
1833 lp->ltvRecord.typ = CFG_RTS_THRH6;
1834 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].rtsThreshold );
1835 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1837 /* TX Rate Control 1 */
1838 lp->ltvRecord.len = 2;
1839 lp->ltvRecord.typ = CFG_TX_RATE_CNTL1;
1840 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].txRateCntl );
1841 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1843 /* TX Rate Control 2 */
1844 lp->ltvRecord.len = 2;
1845 lp->ltvRecord.typ = CFG_TX_RATE_CNTL2;
1846 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].txRateCntl );
1847 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1849 /* TX Rate Control 3 */
1850 lp->ltvRecord.len = 2;
1851 lp->ltvRecord.typ = CFG_TX_RATE_CNTL3;
1852 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].txRateCntl );
1853 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1855 /* TX Rate Control 4 */
1856 lp->ltvRecord.len = 2;
1857 lp->ltvRecord.typ = CFG_TX_RATE_CNTL4;
1858 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].txRateCntl );
1859 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1861 /* TX Rate Control 5 */
1862 lp->ltvRecord.len = 2;
1863 lp->ltvRecord.typ = CFG_TX_RATE_CNTL5;
1864 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].txRateCntl );
1865 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1867 /* TX Rate Control 6 */
1868 lp->ltvRecord.len = 2;
1869 lp->ltvRecord.typ = CFG_TX_RATE_CNTL6;
1870 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].txRateCntl );
1871 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1875 /* WDS addresses. It's okay to blindly send these parameters, because
1876 the port needs to be enabled, before anything is done with it. */
1879 lp->ltvRecord.len = 4;
1880 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR1;
1882 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[0].wdsAddress, ETH_ALEN );
1883 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1886 lp->ltvRecord.len = 4;
1887 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR2;
1889 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[1].wdsAddress, ETH_ALEN );
1890 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1893 lp->ltvRecord.len = 4;
1894 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR3;
1896 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[2].wdsAddress, ETH_ALEN );
1897 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1900 lp->ltvRecord.len = 4;
1901 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR4;
1903 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[3].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_ADDR5;
1910 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[4].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_ADDR6;
1917 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[5].wdsAddress, ETH_ALEN );
1918 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1919 #endif /* USE_WDS */
1920 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1923 /* Own MAC Address */
1924 //DBG_TRACE( DbgInfo, "MAC Address : %s\n",
1925 // DbgHwAddr( lp->MACAddress ));
1927 if ( WVLAN_VALID_MAC_ADDRESS( lp->MACAddress )) {
1928 /* Make the MAC address valid by:
1929 Clearing the multicast bit
1930 Setting the local MAC address bit
1932 //lp->MACAddress[0] &= ~0x03; //;?why is this commented out already in 720
1933 //lp->MACAddress[0] |= 0x02;
1935 lp->ltvRecord.len = 1 + ( ETH_ALEN / sizeof( hcf_16 ));
1936 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1937 //DBG_TRACE( DbgInfo, "CFG_NIC_MAC_ADDR\n" );
1938 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1940 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_MAC_ADDR\n" );
1941 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1943 /* MAC address is byte aligned, no endian conversion needed */
1944 memcpy( &( lp->ltvRecord.u.u8[0] ), lp->MACAddress, ETH_ALEN );
1945 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1946 //DBG_TRACE( DbgInfo, "CFG_XXX_MAC_ADDR result : 0x%04x\n",
1949 /* Update the MAC address in the netdevice struct */
1950 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN ); //;?what is the purpose of this seemingly complex logic
1953 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1954 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1955 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1956 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : %s\n",
1957 // lp->NetworkName );
1958 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1959 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1960 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1962 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1964 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : ANY\n" );
1965 lp->ltvRecord.len = 2;
1966 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1967 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1970 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1972 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID result : 0x%04x\n",
1974 /* enable/disable encryption */
1975 lp->ltvRecord.len = 2;
1976 lp->ltvRecord.typ = CFG_CNF_ENCRYPTION;
1977 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->EnableEncryption );
1978 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1980 /* Set the Authentication Key Management Suite */
1981 lp->ltvRecord.len = 2;
1982 lp->ltvRecord.typ = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
1983 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->AuthKeyMgmtSuite );
1984 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1986 wl_set_wep_keys( lp );
1989 /* countryInfo, ltvCountryInfo, CFG_CNF_COUNTRY_INFO */
1991 DBG_LEAVE( DbgInfo );
1994 /*============================================================================*/
1997 /*******************************************************************************
1999 *******************************************************************************
2003 * Load the kernel module.
2012 * an errno value otherwise
2014 ******************************************************************************/
2015 static int __init wl_module_init( void )
2018 /*------------------------------------------------------------------------*/
2020 DBG_FUNC( "wl_module_init" );
2023 /* Convert "standard" PCMCIA parameter pc_debug to a reasonable DebugFlag value.
2024 * NOTE: The values all fall through to the lower values. */
2025 DbgInfo->DebugFlag = 0;
2026 DbgInfo->DebugFlag = DBG_TRACE_ON; //;?get this mess resolved one day
2027 if ( pc_debug ) switch( pc_debug ) {
2029 DbgInfo->DebugFlag |= DBG_DS_ON;
2031 DbgInfo->DebugFlag |= DBG_RX_ON | DBG_TX_ON;
2033 DbgInfo->DebugFlag |= DBG_PARAM_ON;
2035 DbgInfo->DebugFlag |= DBG_TRACE_ON;
2037 DbgInfo->DebugFlag |= DBG_VERBOSE_ON;
2039 DbgInfo->DebugFlag |= DBG_DEFAULTS;
2045 DBG_ENTER( DbgInfo );
2046 printk(KERN_INFO "%s\n", VERSION_INFO);
2047 printk(KERN_INFO "*** Modified for kernel 2.6 by Henk de Groot <pe1dnn@amsat.org>\n");
2048 printk(KERN_INFO "*** Based on 7.18 version by Andrey Borzenkov <arvidjaar@mail.ru> $Revision: 39 $\n");
2051 // ;?#if (HCF_TYPE) & HCF_TYPE_AP
2052 // DBG_PRINT( "Access Point Mode (AP) Support: YES\n" );
2054 // DBG_PRINT( "Access Point Mode (AP) Support: NO\n" );
2055 // #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2057 result = wl_adapter_init_module( );
2058 DBG_LEAVE( DbgInfo );
2061 /*============================================================================*/
2064 /*******************************************************************************
2066 *******************************************************************************
2070 * Unload the kernel module.
2080 ******************************************************************************/
2081 static void __exit wl_module_exit( void )
2083 DBG_FUNC( "wl_module_exit" );
2086 wl_adapter_cleanup_module( );
2087 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
2088 remove_proc_entry( "wlags", NULL ); //;?why so a-symmetric compared to location of create_proc_read_entry
2091 DBG_LEAVE( DbgInfo );
2094 /*============================================================================*/
2096 module_init(wl_module_init);
2097 module_exit(wl_module_exit);
2099 /*******************************************************************************
2101 *******************************************************************************
2105 * The Interrupt Service Routine for the driver.
2109 * irq - the irq the interrupt came in on
2110 * dev_id - a buffer containing information about the request
2117 ******************************************************************************/
2118 irqreturn_t wl_isr( int irq, void *dev_id, struct pt_regs *regs )
2121 struct net_device *dev = (struct net_device *) dev_id;
2122 struct wl_private *lp = NULL;
2123 /*------------------------------------------------------------------------*/
2124 if (( dev == NULL ) || ( !netif_device_present( dev ))) {
2128 /* Set the wl_private pointer (lp), now that we know that dev is non-null */
2132 if ( lp->useRTS == 1 ) {
2133 DBG_PRINT( "EXITING ISR, IN RTS MODE...\n" );
2136 #endif /* USE_RTS */
2138 /* If we have interrupts pending, then put them on a system task
2139 queue. Otherwise turn interrupts back on */
2140 events = hcf_action( &lp->hcfCtx, HCF_ACT_INT_OFF );
2142 if ( events == HCF_INT_PENDING ) {
2143 /* Schedule the ISR handler as a bottom-half task in the
2144 tq_immediate queue */
2145 tasklet_schedule(&lp->task);
2147 //DBG_PRINT( "NOT OUR INTERRUPT\n" );
2148 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2151 return IRQ_RETVAL(events == HCF_INT_PENDING);
2153 /*============================================================================*/
2156 /*******************************************************************************
2158 *******************************************************************************
2162 * The ISR handler, scheduled to run in a deferred context by the ISR. This
2163 * is where the ISR's work actually gets done.
2167 * lp - a pointer to the device's private adapter structure
2173 ******************************************************************************/
2174 #define WVLAN_MAX_INT_SERVICES 50
2176 void wl_isr_handler( unsigned long p )
2178 struct net_device *dev;
2179 unsigned long flags;
2183 struct wl_private *lp = (struct wl_private *)p;
2184 /*------------------------------------------------------------------------*/
2187 DBG_PRINT( "wl_isr_handler lp adapter pointer is NULL!!!\n" );
2189 wl_lock( lp, &flags );
2191 dev = (struct net_device *)lp->dev;
2192 if ( dev != NULL && netif_device_present( dev ) ) stop = FALSE;
2193 for( count = 0; stop == FALSE && count < WVLAN_MAX_INT_SERVICES; count++ ) {
2195 result = hcf_service_nic( &lp->hcfCtx,
2196 (wci_bufp)lp->lookAheadBuf,
2197 sizeof( lp->lookAheadBuf ));
2198 if ( result == HCF_ERR_MIC ) {
2199 wl_wext_event_mic_failed( dev ); /* Send an event that MIC failed */
2200 //;?this seems wrong if HCF_ERR_MIC coincides with another event, stop gets FALSE
2201 //so why not do it always ;?
2204 #ifndef USE_MBOX_SYNC
2205 if ( lp->hcfCtx.IFB_MBInfoLen != 0 ) { /* anything in the mailbox */
2210 /* Check for a Link status event */
2211 if ( ( lp->hcfCtx.IFB_LinkStat & CFG_LINK_STAT_FW ) != 0 ) {
2212 wl_process_link_status( lp );
2215 /* Check for probe response events */
2216 if ( lp->ProbeResp.infoType != 0 &&
2217 lp->ProbeResp.infoType != 0xFFFF ) {
2218 wl_process_probe_response( lp );
2219 memset( &lp->ProbeResp, 0, sizeof( lp->ProbeResp ));
2220 lp->ProbeResp.infoType = 0xFFFF;
2223 /* Check for updated record events */
2224 if ( lp->updatedRecord.len != 0xFFFF ) {
2225 wl_process_updated_record( lp );
2226 lp->updatedRecord.len = 0xFFFF;
2229 /* Check for association status events */
2230 if ( lp->assoc_stat.len != 0xFFFF ) {
2231 wl_process_assoc_status( lp );
2232 lp->assoc_stat.len = 0xFFFF;
2235 /* Check for security status events */
2236 if ( lp->sec_stat.len != 0xFFFF ) {
2237 wl_process_security_status( lp );
2238 lp->sec_stat.len = 0xFFFF;
2243 if ( lp->use_dma ) {
2244 /* Check for DMA Rx packets */
2245 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_RDMAD ) {
2249 /* Return Tx DMA descriptors to host */
2250 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_TDMAD ) {
2251 wl_pci_dma_hcf_reclaim_tx( lp );
2256 #endif // ENABLE_DMA
2258 /* Check for Rx packets */
2259 if ( lp->hcfCtx.IFB_RxLen != 0 ) {
2263 /* Make sure that queued frames get sent */
2264 if ( wl_send( lp )) {
2269 /* We're done, so turn interrupts which were turned off in wl_isr, back on */
2270 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2271 wl_unlock( lp, &flags );
2275 /*============================================================================*/
2278 /*******************************************************************************
2280 *******************************************************************************
2284 * Notify the adapter that it has been removed. Since the adapter is gone,
2285 * we should no longer try to talk to it.
2289 * dev - a pointer to the device's net_device structure
2295 ******************************************************************************/
2296 void wl_remove( struct net_device *dev )
2298 struct wl_private *lp = wl_priv(dev);
2299 unsigned long flags;
2300 /*------------------------------------------------------------------------*/
2301 DBG_FUNC( "wl_remove" );
2302 DBG_ENTER( DbgInfo );
2304 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2306 wl_lock( lp, &flags );
2308 /* stop handling interrupts */
2309 wl_act_int_off( lp );
2310 lp->is_handling_int = WL_NOT_HANDLING_INT;
2313 * Disable the ports: just change state: since the
2314 * card is gone it is useless to talk to it and at
2315 * disconnect all state information is lost anyway.
2317 /* Reset portState */
2318 lp->portState = WVLAN_PORT_STATE_DISABLED;
2320 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
2322 //wl_disable_wds_ports( lp );
2324 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2326 /* Mark the device as unregistered */
2327 lp->is_registered = FALSE;
2329 /* Deregister the WDS ports as well */
2330 WL_WDS_NETDEV_DEREGISTER( lp );
2332 if ( lp->useRTS == 1 ) {
2333 wl_unlock( lp, &flags );
2335 DBG_LEAVE( DbgInfo );
2338 #endif /* USE_RTS */
2340 /* Inform the HCF that the card has been removed */
2341 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2343 wl_unlock( lp, &flags );
2345 DBG_LEAVE( DbgInfo );
2348 /*============================================================================*/
2351 /*******************************************************************************
2353 *******************************************************************************
2357 * Power-down and halt the adapter.
2361 * dev - a pointer to the device's net_device structure
2367 ******************************************************************************/
2368 void wl_suspend( struct net_device *dev )
2370 struct wl_private *lp = wl_priv(dev);
2371 unsigned long flags;
2372 /*------------------------------------------------------------------------*/
2373 DBG_FUNC( "wl_suspend" );
2374 DBG_ENTER( DbgInfo );
2376 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2378 /* The adapter is suspended:
2382 wl_lock( lp, &flags );
2384 /* Disable interrupt handling */
2385 wl_act_int_off( lp );
2388 wl_disconnect( lp );
2393 /* Disconnect from the adapter */
2394 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2396 /* Reset portState to be sure (should have been done by wl_disable */
2397 lp->portState = WVLAN_PORT_STATE_DISABLED;
2399 wl_unlock( lp, &flags );
2401 DBG_LEAVE( DbgInfo );
2404 /*============================================================================*/
2407 /*******************************************************************************
2409 *******************************************************************************
2413 * Resume a previously suspended adapter.
2417 * dev - a pointer to the device's net_device structure
2423 ******************************************************************************/
2424 void wl_resume(struct net_device *dev)
2426 struct wl_private *lp = wl_priv(dev);
2427 unsigned long flags;
2428 /*------------------------------------------------------------------------*/
2429 DBG_FUNC( "wl_resume" );
2430 DBG_ENTER( DbgInfo );
2432 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2434 wl_lock( lp, &flags );
2436 /* Connect to the adapter */
2437 hcf_connect( &lp->hcfCtx, dev->base_addr );
2439 /* Reset portState */
2440 lp->portState = WVLAN_PORT_STATE_DISABLED;
2442 /* Power might have been off, assume the card lost the firmware*/
2443 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
2445 /* Reload the firmware and restart */
2448 /* Resume interrupt handling */
2449 wl_act_int_on( lp );
2451 wl_unlock( lp, &flags );
2453 DBG_LEAVE( DbgInfo );
2456 /*============================================================================*/
2459 /*******************************************************************************
2461 *******************************************************************************
2465 * This function perfroms a check on the device and calls wl_remove() if
2466 * necessary. This function can be used for all bus types, but exists mostly
2467 * for the benefit of the Card Services driver, as there are times when
2468 * wl_remove() does not get called.
2472 * dev - a pointer to the device's net_device structure
2478 ******************************************************************************/
2479 void wl_release( struct net_device *dev )
2481 struct wl_private *lp = wl_priv(dev);
2482 /*------------------------------------------------------------------------*/
2483 DBG_FUNC( "wl_release" );
2484 DBG_ENTER( DbgInfo );
2486 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2487 /* If wl_remove() hasn't been called (i.e. when Card Services is shut
2488 down with the card in the slot), then call it */
2489 if ( lp->is_registered == TRUE ) {
2490 DBG_TRACE( DbgInfo, "Calling unregister_netdev(), as it wasn't called yet\n" );
2493 lp->is_registered = FALSE;
2496 DBG_LEAVE( DbgInfo );
2499 /*============================================================================*/
2502 /*******************************************************************************
2504 *******************************************************************************
2508 * Accessor function to retrieve the irq_mask module parameter
2516 * The irq_mask module parameter
2518 ******************************************************************************/
2519 p_u16 wl_get_irq_mask( void )
2522 } // wl_get_irq_mask
2523 /*============================================================================*/
2526 /*******************************************************************************
2528 *******************************************************************************
2532 * Accessor function to retrieve the irq_list module parameter
2540 * The irq_list module parameter
2542 ******************************************************************************/
2543 p_s8 * wl_get_irq_list( void )
2546 } // wl_get_irq_list
2547 /*============================================================================*/
2551 /*******************************************************************************
2553 *******************************************************************************
2557 * Used to enable MAC ports
2561 * lp - pointer to the device's private adapter structure
2567 ******************************************************************************/
2568 int wl_enable( struct wl_private *lp )
2570 int hcf_status = HCF_SUCCESS;
2571 /*------------------------------------------------------------------------*/
2572 DBG_FUNC( "wl_enable" );
2573 DBG_ENTER( DbgInfo );
2575 if ( lp->portState == WVLAN_PORT_STATE_ENABLED ) {
2576 DBG_TRACE( DbgInfo, "No action: Card already enabled\n" );
2577 } else if ( lp->portState == WVLAN_PORT_STATE_CONNECTED ) {
2578 //;?suspicuous logic, how can you be connected without being enabled so this is probably dead code
2579 DBG_TRACE( DbgInfo, "No action: Card already connected\n" );
2581 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_ENABLE );
2582 if ( hcf_status == HCF_SUCCESS ) {
2583 /* Set the status of the NIC to enabled */
2584 lp->portState = WVLAN_PORT_STATE_ENABLED; //;?bad mnemonic, NIC iso PORT
2586 if ( lp->use_dma ) {
2587 wl_pci_dma_hcf_supply( lp ); //;?always succes?
2592 if ( hcf_status != HCF_SUCCESS ) { //;?make this an assert
2593 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2595 DBG_LEAVE( DbgInfo );
2598 /*============================================================================*/
2602 /*******************************************************************************
2603 * wl_enable_wds_ports()
2604 *******************************************************************************
2608 * Used to enable the WDS MAC ports 1-6
2612 * lp - pointer to the device's private adapter structure
2618 ******************************************************************************/
2619 void wl_enable_wds_ports( struct wl_private * lp )
2622 DBG_FUNC( "wl_enable_wds_ports" );
2623 DBG_ENTER( DbgInfo );
2624 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2625 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2627 DBG_LEAVE( DbgInfo );
2629 } // wl_enable_wds_ports
2630 #endif /* USE_WDS */
2631 /*============================================================================*/
2634 /*******************************************************************************
2636 *******************************************************************************
2640 * Used to connect a MAC port
2644 * lp - pointer to the device's private adapter structure
2650 ******************************************************************************/
2651 int wl_connect( struct wl_private *lp )
2654 /*------------------------------------------------------------------------*/
2656 DBG_FUNC( "wl_connect" );
2657 DBG_ENTER( DbgInfo );
2659 if ( lp->portState != WVLAN_PORT_STATE_ENABLED ) {
2660 DBG_TRACE( DbgInfo, "No action: Not in enabled state\n" );
2661 DBG_LEAVE( DbgInfo );
2664 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_CONNECT );
2665 if ( hcf_status == HCF_SUCCESS ) {
2666 lp->portState = WVLAN_PORT_STATE_CONNECTED;
2668 DBG_LEAVE( DbgInfo );
2671 /*============================================================================*/
2674 /*******************************************************************************
2676 *******************************************************************************
2680 * Used to disconnect a MAC port
2684 * lp - pointer to the device's private adapter structure
2690 ******************************************************************************/
2691 int wl_disconnect( struct wl_private *lp )
2694 /*------------------------------------------------------------------------*/
2696 DBG_FUNC( "wl_disconnect" );
2697 DBG_ENTER( DbgInfo );
2699 if ( lp->portState != WVLAN_PORT_STATE_CONNECTED ) {
2700 DBG_TRACE( DbgInfo, "No action: Not in connected state\n" );
2701 DBG_LEAVE( DbgInfo );
2704 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISCONNECT );
2705 if ( hcf_status == HCF_SUCCESS ) {
2706 lp->portState = WVLAN_PORT_STATE_ENABLED;
2708 DBG_LEAVE( DbgInfo );
2711 /*============================================================================*/
2714 /*******************************************************************************
2716 *******************************************************************************
2720 * Used to disable MAC ports
2724 * lp - pointer to the device's private adapter structure
2725 * port - the MAC port to disable
2731 ******************************************************************************/
2732 int wl_disable( struct wl_private *lp )
2734 int hcf_status = HCF_SUCCESS;
2735 /*------------------------------------------------------------------------*/
2736 DBG_FUNC( "wl_disable" );
2737 DBG_ENTER( DbgInfo );
2739 if ( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
2740 DBG_TRACE( DbgInfo, "No action: Port state is disabled\n" );
2742 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISABLE );
2743 if ( hcf_status == HCF_SUCCESS ) {
2744 /* Set the status of the port to disabled */ //;?bad mnemonic use NIC iso PORT
2745 lp->portState = WVLAN_PORT_STATE_DISABLED;
2748 if ( lp->use_dma ) {
2749 wl_pci_dma_hcf_reclaim( lp );
2754 if ( hcf_status != HCF_SUCCESS ) {
2755 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2757 DBG_LEAVE( DbgInfo );
2760 /*============================================================================*/
2764 /*******************************************************************************
2765 * wl_disable_wds_ports()
2766 *******************************************************************************
2770 * Used to disable the WDS MAC ports 1-6
2774 * lp - pointer to the device's private adapter structure
2780 ******************************************************************************/
2781 void wl_disable_wds_ports( struct wl_private * lp )
2784 DBG_FUNC( "wl_disable_wds_ports" );
2785 DBG_ENTER( DbgInfo );
2787 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2788 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2790 // if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
2791 // wl_disable( lp, HCF_PORT_1 );
2792 // wl_disable( lp, HCF_PORT_2 );
2793 // wl_disable( lp, HCF_PORT_3 );
2794 // wl_disable( lp, HCF_PORT_4 );
2795 // wl_disable( lp, HCF_PORT_5 );
2796 // wl_disable( lp, HCF_PORT_6 );
2798 DBG_LEAVE( DbgInfo );
2800 } // wl_disable_wds_ports
2802 /*============================================================================*/
2805 #ifndef USE_MBOX_SYNC
2806 /*******************************************************************************
2808 *******************************************************************************
2811 * This function is used to read and process a mailbox message.
2816 * lp - pointer to the device's private adapter structure
2820 * an HCF status code
2822 ******************************************************************************/
2823 int wl_mbx( struct wl_private *lp )
2825 int hcf_status = HCF_SUCCESS;
2826 /*------------------------------------------------------------------------*/
2827 DBG_FUNC( "wl_mbx" );
2828 DBG_ENTER( DbgInfo );
2829 DBG_TRACE( DbgInfo, "Mailbox Info: IFB_MBInfoLen: %d\n",
2830 lp->hcfCtx.IFB_MBInfoLen );
2832 memset( &( lp->ltvRecord ), 0, sizeof( ltv_t ));
2834 lp->ltvRecord.len = MB_SIZE;
2835 lp->ltvRecord.typ = CFG_MB_INFO;
2836 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2838 if ( hcf_status != HCF_SUCCESS ) {
2839 DBG_ERROR( DbgInfo, "hcf_get_info returned 0x%x\n", hcf_status );
2841 DBG_LEAVE( DbgInfo );
2845 if ( lp->ltvRecord.typ == CFG_MB_INFO ) {
2846 DBG_LEAVE( DbgInfo );
2849 /* Endian translate the mailbox data, then process the message */
2850 wl_endian_translate_mailbox( &( lp->ltvRecord ));
2851 wl_process_mailbox( lp );
2852 DBG_LEAVE( DbgInfo );
2855 /*============================================================================*/
2858 /*******************************************************************************
2859 * wl_endian_translate_mailbox()
2860 *******************************************************************************
2864 * This function will perform the tedious task of endian translating all
2865 * fields withtin a mailbox message which need translating.
2869 * ltv - pointer to the LTV to endian translate
2875 ******************************************************************************/
2876 void wl_endian_translate_mailbox( ltv_t *ltv )
2879 DBG_FUNC( "wl_endian_translate_mailbox" );
2880 DBG_ENTER( DbgInfo );
2881 switch( ltv->typ ) {
2888 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
2890 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2891 ( sizeof( SCAN_RS_STRCT )));
2893 while( num_aps >= 1 ) {
2896 aps[num_aps].channel_id =
2897 CNV_LITTLE_TO_INT( aps[num_aps].channel_id );
2899 aps[num_aps].noise_level =
2900 CNV_LITTLE_TO_INT( aps[num_aps].noise_level );
2902 aps[num_aps].signal_level =
2903 CNV_LITTLE_TO_INT( aps[num_aps].signal_level );
2905 aps[num_aps].beacon_interval_time =
2906 CNV_LITTLE_TO_INT( aps[num_aps].beacon_interval_time );
2908 aps[num_aps].capability =
2909 CNV_LITTLE_TO_INT( aps[num_aps].capability );
2911 aps[num_aps].ssid_len =
2912 CNV_LITTLE_TO_INT( aps[num_aps].ssid_len );
2914 aps[num_aps].ssid_val[aps[num_aps].ssid_len] = 0;
2921 PROBE_RESP *probe_resp = (PROBE_RESP *)ltv;
2923 probe_resp->frameControl = CNV_LITTLE_TO_INT( probe_resp->frameControl );
2924 probe_resp->durID = CNV_LITTLE_TO_INT( probe_resp->durID );
2925 probe_resp->sequence = CNV_LITTLE_TO_INT( probe_resp->sequence );
2926 probe_resp->dataLength = CNV_LITTLE_TO_INT( probe_resp->dataLength );
2928 probe_resp->lenType = CNV_LITTLE_TO_INT( probe_resp->lenType );
2930 probe_resp->beaconInterval = CNV_LITTLE_TO_INT( probe_resp->beaconInterval );
2931 probe_resp->capability = CNV_LITTLE_TO_INT( probe_resp->capability );
2932 probe_resp->flags = CNV_LITTLE_TO_INT( probe_resp->flags );
2937 #define ls ((LINK_STATUS_STRCT *)ltv)
2938 ls->linkStatus = CNV_LITTLE_TO_INT( ls->linkStatus );
2942 case CFG_ASSOC_STAT:
2944 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
2946 as->assocStatus = CNV_LITTLE_TO_INT( as->assocStatus );
2950 case CFG_SECURITY_STAT:
2952 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
2954 ss->securityStatus = CNV_LITTLE_TO_INT( ss->securityStatus );
2955 ss->reason = CNV_LITTLE_TO_INT( ss->reason );
2969 DBG_LEAVE( DbgInfo );
2971 } // wl_endian_translate_mailbox
2972 /*============================================================================*/
2974 /*******************************************************************************
2975 * wl_process_mailbox()
2976 *******************************************************************************
2980 * This function will process the mailbox data.
2984 * ltv - pointer to the LTV to be processed.
2990 ******************************************************************************/
2991 void wl_process_mailbox( struct wl_private *lp )
2994 hcf_16 ltv_val = 0xFFFF;
2995 /*------------------------------------------------------------------------*/
2996 DBG_FUNC( "wl_process_mailbox" );
2997 DBG_ENTER( DbgInfo );
2998 ltv = &( lp->ltvRecord );
3000 switch( ltv->typ ) {
3003 DBG_TRACE( DbgInfo, "CFG_TALLIES\n" );
3006 DBG_TRACE( DbgInfo, "CFG_SCAN\n" );
3010 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
3012 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
3013 ( sizeof( SCAN_RS_STRCT )));
3015 lp->scan_results.num_aps = num_aps;
3017 DBG_TRACE( DbgInfo, "Number of APs: %d\n", num_aps );
3019 while( num_aps >= 1 ) {
3022 DBG_TRACE( DbgInfo, "AP : %d\n", num_aps );
3023 DBG_TRACE( DbgInfo, "=========================\n" );
3024 DBG_TRACE( DbgInfo, "Channel ID : 0x%04x\n",
3025 aps[num_aps].channel_id );
3026 DBG_TRACE( DbgInfo, "Noise Level : 0x%04x\n",
3027 aps[num_aps].noise_level );
3028 DBG_TRACE( DbgInfo, "Signal Level : 0x%04x\n",
3029 aps[num_aps].signal_level );
3030 DBG_TRACE( DbgInfo, "Beacon Interval : 0x%04x\n",
3031 aps[num_aps].beacon_interval_time );
3032 DBG_TRACE( DbgInfo, "Capability : 0x%04x\n",
3033 aps[num_aps].capability );
3034 DBG_TRACE( DbgInfo, "SSID Length : 0x%04x\n",
3035 aps[num_aps].ssid_len );
3036 DBG_TRACE( DbgInfo, "BSSID : %s\n",
3037 DbgHwAddr( aps[num_aps].bssid ));
3039 if ( aps[num_aps].ssid_len != 0 ) {
3040 DBG_TRACE( DbgInfo, "SSID : %s.\n",
3041 aps[num_aps].ssid_val );
3043 DBG_TRACE( DbgInfo, "SSID : %s.\n", "ANY" );
3046 DBG_TRACE( DbgInfo, "\n" );
3048 /* Copy the info to the ScanResult structure in the private
3050 memcpy( &( lp->scan_results.APTable[num_aps]), &( aps[num_aps] ),
3051 sizeof( SCAN_RS_STRCT ));
3054 /* Set scan result to true so that any scan requests will
3056 lp->scan_results.scan_complete = TRUE;
3061 DBG_TRACE( DbgInfo, "CFG_ACS_SCAN\n" );
3064 PROBE_RESP *probe_rsp = (PROBE_RESP *)ltv;
3065 hcf_8 *wpa_ie = NULL;
3066 hcf_16 wpa_ie_len = 0;
3068 DBG_TRACE( DbgInfo, "(%s) =========================\n",
3071 DBG_TRACE( DbgInfo, "(%s) length : 0x%04x.\n",
3072 lp->dev->name, probe_rsp->length );
3074 if ( probe_rsp->length > 1 ) {
3075 DBG_TRACE( DbgInfo, "(%s) infoType : 0x%04x.\n",
3076 lp->dev->name, probe_rsp->infoType );
3078 DBG_TRACE( DbgInfo, "(%s) signal : 0x%02x.\n",
3079 lp->dev->name, probe_rsp->signal );
3081 DBG_TRACE( DbgInfo, "(%s) silence : 0x%02x.\n",
3082 lp->dev->name, probe_rsp->silence );
3084 DBG_TRACE( DbgInfo, "(%s) rxFlow : 0x%02x.\n",
3085 lp->dev->name, probe_rsp->rxFlow );
3087 DBG_TRACE( DbgInfo, "(%s) rate : 0x%02x.\n",
3088 lp->dev->name, probe_rsp->rate );
3090 DBG_TRACE( DbgInfo, "(%s) frame cntl : 0x%04x.\n",
3091 lp->dev->name, probe_rsp->frameControl );
3093 DBG_TRACE( DbgInfo, "(%s) durID : 0x%04x.\n",
3094 lp->dev->name, probe_rsp->durID );
3096 DBG_TRACE( DbgInfo, "(%s) address1 : %s\n",
3097 lp->dev->name, DbgHwAddr( probe_rsp->address1 ));
3099 DBG_TRACE( DbgInfo, "(%s) address2 : %s\n",
3100 lp->dev->name, DbgHwAddr( probe_rsp->address2 ));
3102 DBG_TRACE( DbgInfo, "(%s) BSSID : %s\n",
3103 lp->dev->name, DbgHwAddr( probe_rsp->BSSID ));
3105 DBG_TRACE( DbgInfo, "(%s) sequence : 0x%04x.\n",
3106 lp->dev->name, probe_rsp->sequence );
3108 DBG_TRACE( DbgInfo, "(%s) address4 : %s\n",
3109 lp->dev->name, DbgHwAddr( probe_rsp->address4 ));
3111 DBG_TRACE( DbgInfo, "(%s) datalength : 0x%04x.\n",
3112 lp->dev->name, probe_rsp->dataLength );
3114 DBG_TRACE( DbgInfo, "(%s) DA : %s\n",
3115 lp->dev->name, DbgHwAddr( probe_rsp->DA ));
3117 DBG_TRACE( DbgInfo, "(%s) SA : %s\n",
3118 lp->dev->name, DbgHwAddr( probe_rsp->SA ));
3120 //DBG_TRACE( DbgInfo, "(%s) lenType : 0x%04x.\n",
3121 // lp->dev->name, probe_rsp->lenType );
3123 DBG_TRACE( DbgInfo, "(%s) timeStamp : %s\n",
3124 lp->dev->name, DbgHwAddr( probe_rsp->timeStamp ));
3126 DBG_TRACE( DbgInfo, "(%s) beaconInt : 0x%04x.\n",
3127 lp->dev->name, probe_rsp->beaconInterval );
3129 DBG_TRACE( DbgInfo, "(%s) capability : 0x%04x.\n",
3130 lp->dev->name, probe_rsp->capability );
3132 DBG_TRACE( DbgInfo, "(%s) SSID len : 0x%04x.\n",
3133 lp->dev->name, probe_rsp->rawData[1] );
3135 if ( probe_rsp->rawData[1] > 0 ) {
3136 char ssid[HCF_MAX_NAME_LEN];
3138 memset( ssid, 0, sizeof( ssid ));
3139 strncpy( ssid, &probe_rsp->rawData[2],
3140 probe_rsp->rawData[1] );
3142 DBG_TRACE( DbgInfo, "(%s) SSID : %s\n",
3143 lp->dev->name, ssid );
3146 /* Parse out the WPA-IE, if one exists */
3147 wpa_ie = wl_parse_wpa_ie( probe_rsp, &wpa_ie_len );
3148 if ( wpa_ie != NULL ) {
3149 DBG_TRACE( DbgInfo, "(%s) WPA-IE : %s\n",
3150 lp->dev->name, wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
3153 DBG_TRACE( DbgInfo, "(%s) flags : 0x%04x.\n",
3154 lp->dev->name, probe_rsp->flags );
3157 DBG_TRACE( DbgInfo, "\n\n" );
3158 /* If probe response length is 1, then the scan is complete */
3159 if ( probe_rsp->length == 1 ) {
3160 DBG_TRACE( DbgInfo, "SCAN COMPLETE\n" );
3161 lp->probe_results.num_aps = lp->probe_num_aps;
3162 lp->probe_results.scan_complete = TRUE;
3164 /* Reset the counter for the next scan request */
3165 lp->probe_num_aps = 0;
3167 /* Send a wireless extensions event that the scan completed */
3168 wl_wext_event_scan_complete( lp->dev );
3170 /* Only copy to the table if the entry is unique; APs sometimes
3171 respond more than once to a probe */
3172 if ( lp->probe_num_aps == 0 ) {
3173 /* Copy the info to the ScanResult structure in the private
3175 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3176 probe_rsp, sizeof( PROBE_RESP ));
3178 /* Increment the number of APs detected */
3179 lp->probe_num_aps++;
3184 for( count = 0; count < lp->probe_num_aps; count++ ) {
3185 if ( memcmp( &( probe_rsp->BSSID ),
3186 lp->probe_results.ProbeTable[count].BSSID,
3193 /* Copy the info to the ScanResult structure in the
3194 private adapter struct. Only copy if there's room in the
3196 if ( lp->probe_num_aps < MAX_NAPS )
3198 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3199 probe_rsp, sizeof( PROBE_RESP ));
3203 DBG_WARNING( DbgInfo, "Num of scan results exceeds storage, truncating\n" );
3206 /* Increment the number of APs detected. Note I do this
3207 here even when I don't copy the probe response to the
3208 buffer in order to detect the overflow condition */
3209 lp->probe_num_aps++;
3218 #define ls ((LINK_STATUS_STRCT *)ltv)
3219 DBG_TRACE( DbgInfo, "CFG_LINK_STAT\n" );
3221 switch( ls->linkStatus ) {
3223 DBG_TRACE( DbgInfo, "Link Status : Connected\n" );
3224 wl_wext_event_ap( lp->dev );
3228 DBG_TRACE( DbgInfo, "Link Status : Disconnected\n" );
3232 DBG_TRACE( DbgInfo, "Link Status : Access Point Change\n" );
3236 DBG_TRACE( DbgInfo, "Link Status : Access Point Out of Range\n" );
3240 DBG_TRACE( DbgInfo, "Link Status : Access Point In Range\n" );
3244 DBG_TRACE( DbgInfo, "Link Status : UNKNOWN (0x%04x)\n",
3252 case CFG_ASSOC_STAT:
3253 DBG_TRACE( DbgInfo, "CFG_ASSOC_STAT\n" );
3256 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
3258 switch( as->assocStatus ) {
3260 DBG_TRACE( DbgInfo, "Association Status : STA Associated\n" );
3264 DBG_TRACE( DbgInfo, "Association Status : STA Reassociated\n" );
3268 DBG_TRACE( DbgInfo, "Association Status : STA Disassociated\n" );
3272 DBG_TRACE( DbgInfo, "Association Status : UNKNOWN (0x%04x)\n",
3277 DBG_TRACE( DbgInfo, "STA Address : %s\n",
3278 DbgHwAddr( as->staAddr ));
3280 if (( as->assocStatus == 2 ) && ( as->len == 8 )) {
3281 DBG_TRACE( DbgInfo, "Old AP Address : %s\n",
3282 DbgHwAddr( as->oldApAddr ));
3288 case CFG_SECURITY_STAT:
3289 DBG_TRACE( DbgInfo, "CFG_SECURITY_STAT\n" );
3292 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
3294 switch( ss->securityStatus ) {
3296 DBG_TRACE( DbgInfo, "Security Status : Dissassociate [AP]\n" );
3300 DBG_TRACE( DbgInfo, "Security Status : Deauthenticate [AP]\n" );
3304 DBG_TRACE( DbgInfo, "Security Status : Authenticate Fail [STA] or [AP]\n" );
3308 DBG_TRACE( DbgInfo, "Security Status : MIC Fail\n" );
3312 DBG_TRACE( DbgInfo, "Security Status : Associate Fail\n" );
3316 DBG_TRACE( DbgInfo, "Security Status : UNKNOWN %d\n",
3317 ss->securityStatus );
3321 DBG_TRACE( DbgInfo, "STA Address : %s\n", DbgHwAddr( ss->staAddr ));
3323 DBG_TRACE( DbgInfo, "Reason : 0x%04x \n", ss->reason );
3329 DBG_TRACE( DbgInfo, "CFG_WMP, size is %d bytes\n", ltv->len );
3331 WMP_RSP_STRCT *wmp_rsp = (WMP_RSP_STRCT *)ltv;
3333 DBG_TRACE( DbgInfo, "CFG_WMP, pdu type is 0x%x\n",
3334 wmp_rsp->wmpRsp.wmpHdr.type );
3336 switch( wmp_rsp->wmpRsp.wmpHdr.type ) {
3337 case WVLAN_WMP_PDU_TYPE_LT_RSP:
3340 LINKTEST_RSP_STRCT *lt_rsp = (LINKTEST_RSP_STRCT *)ltv;
3342 DBG_TRACE( DbgInfo, "LINK TEST RESULT\n" );
3343 DBG_TRACE( DbgInfo, "================\n" );
3344 DBG_TRACE( DbgInfo, "Length : %d.\n", lt_rsp->len );
3346 DBG_TRACE( DbgInfo, "Name : %s.\n", lt_rsp->ltRsp.ltRsp.name );
3347 DBG_TRACE( DbgInfo, "Signal Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.signal );
3348 DBG_TRACE( DbgInfo, "Noise Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.noise );
3349 DBG_TRACE( DbgInfo, "Receive Flow : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.rxFlow );
3350 DBG_TRACE( DbgInfo, "Data Rate : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRate );
3351 DBG_TRACE( DbgInfo, "Protocol : 0x%04x.\n", lt_rsp->ltRsp.ltRsp.protocol );
3352 DBG_TRACE( DbgInfo, "Station : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.station );
3353 DBG_TRACE( DbgInfo, "Data Rate Cap : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRateCap );
3355 DBG_TRACE( DbgInfo, "Power Mgmt : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3356 lt_rsp->ltRsp.ltRsp.powerMgmt[0],
3357 lt_rsp->ltRsp.ltRsp.powerMgmt[1],
3358 lt_rsp->ltRsp.ltRsp.powerMgmt[2],
3359 lt_rsp->ltRsp.ltRsp.powerMgmt[3] );
3361 DBG_TRACE( DbgInfo, "Robustness : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3362 lt_rsp->ltRsp.ltRsp.robustness[0],
3363 lt_rsp->ltRsp.ltRsp.robustness[1],
3364 lt_rsp->ltRsp.ltRsp.robustness[2],
3365 lt_rsp->ltRsp.ltRsp.robustness[3] );
3367 DBG_TRACE( DbgInfo, "Scaling : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.scaling );
3380 DBG_TRACE( DbgInfo, "CFG_NULL\n" );
3383 case CFG_UPDATED_INFO_RECORD: // Updated Information Record
3384 DBG_TRACE( DbgInfo, "UPDATED INFORMATION RECORD\n" );
3386 ltv_val = CNV_INT_TO_LITTLE( ltv->u.u16[0] );
3388 /* Check and see which RID was updated */
3390 case CFG_CUR_COUNTRY_INFO: // Indicate Passive Scan Completion
3391 DBG_TRACE( DbgInfo, "Updated country info\n" );
3393 /* Do I need to hold off on updating RIDs until the process is
3398 case CFG_PORT_STAT: // Wait for Connect Event
3404 DBG_WARNING( DbgInfo, "Unknown RID: 0x%04x\n", ltv_val );
3410 DBG_TRACE( DbgInfo, "UNKNOWN MESSAGE: 0x%04x\n", ltv->typ );
3413 DBG_LEAVE( DbgInfo );
3415 } // wl_process_mailbox
3416 /*============================================================================*/
3417 #endif /* ifndef USE_MBOX_SYNC */
3420 /*******************************************************************************
3421 * wl_wds_netdev_register()
3422 *******************************************************************************
3426 * This function registers net_device structures with the system's network
3427 * layer for use with the WDS ports.
3432 * lp - pointer to the device's private adapter structure
3438 ******************************************************************************/
3439 void wl_wds_netdev_register( struct wl_private *lp )
3442 /*------------------------------------------------------------------------*/
3443 DBG_FUNC( "wl_wds_netdev_register" );
3444 DBG_ENTER( DbgInfo );
3445 //;?why is there no USE_WDS clause like in wl_enable_wds_ports
3446 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3447 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3448 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3449 if ( register_netdev( lp->wds_port[count].dev ) != 0 ) {
3450 DBG_WARNING( DbgInfo, "net device for WDS port %d could not be registered\n",
3453 lp->wds_port[count].is_registered = TRUE;
3455 /* Fill out the net_device structs with the MAC addr */
3456 memcpy( lp->wds_port[count].dev->dev_addr, lp->MACAddress, ETH_ALEN );
3457 lp->wds_port[count].dev->addr_len = ETH_ALEN;
3461 DBG_LEAVE( DbgInfo );
3463 } // wl_wds_netdev_register
3464 /*============================================================================*/
3467 /*******************************************************************************
3468 * wl_wds_netdev_deregister()
3469 *******************************************************************************
3473 * This function deregisters the WDS net_device structures used by the
3474 * system's network layer.
3479 * lp - pointer to the device's private adapter structure
3485 ******************************************************************************/
3486 void wl_wds_netdev_deregister( struct wl_private *lp )
3489 /*------------------------------------------------------------------------*/
3490 DBG_FUNC( "wl_wds_netdev_deregister" );
3491 DBG_ENTER( DbgInfo );
3492 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3493 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3494 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3495 unregister_netdev( lp->wds_port[count].dev );
3497 lp->wds_port[count].is_registered = FALSE;
3500 DBG_LEAVE( DbgInfo );
3502 } // wl_wds_netdev_deregister
3503 /*============================================================================*/
3504 #endif /* USE_WDS */
3507 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
3509 * The proc filesystem: function to read and entry
3511 int printf_hcf_16( char *s, char *buf, hcf_16* p, int n );
3512 int printf_hcf_16( char *s, char *buf, hcf_16* p, int n ) {
3516 len = sprintf(buf, "%s", s );
3517 while ( len < 20 ) len += sprintf(buf+len, " " );
3518 len += sprintf(buf+len,": " );
3519 for ( i = 0; i < n; i++ ) {
3520 if ( len % 80 > 75 ) {
3521 len += sprintf(buf+len,"\n" );
3523 len += sprintf(buf+len,"%04X ", p[i] );
3525 len += sprintf(buf+len,"\n" );
3529 int printf_hcf_8( char *s, char *buf, hcf_8* p, int n );
3530 int printf_hcf_8( char *s, char *buf, hcf_8* p, int n ) {
3534 len = sprintf(buf, "%s", s );
3535 while ( len < 20 ) len += sprintf(buf+len, " " );
3536 len += sprintf(buf+len,": " );
3537 for ( i = 0; i <= n; i++ ) {
3538 if ( len % 80 > 77 ) {
3539 len += sprintf(buf+len,"\n" );
3541 len += sprintf(buf+len,"%02X ", p[i] );
3543 len += sprintf(buf+len,"\n" );
3547 int printf_strct( char *s, char *buf, hcf_16* p );
3548 int printf_strct( char *s, char *buf, hcf_16* p ) {
3552 len = sprintf(buf, "%s", s );
3553 while ( len < 20 ) len += sprintf(buf+len, " " );
3554 len += sprintf(buf+len,": " );
3555 for ( i = 0; i <= *p; i++ ) {
3556 if ( len % 80 > 75 ) {
3557 len += sprintf(buf+len,"\n" );
3559 len += sprintf(buf+len,"%04X ", p[i] );
3561 len += sprintf(buf+len,"\n" );
3565 int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data )
3567 struct wl_private *lp = NULL;
3569 CFG_HERMES_TALLIES_STRCT *p;
3571 #define LIMIT (PAGE_SIZE-80) /* don't print any more after this size */
3575 lp = ((struct net_device *)data)->priv;
3577 len += sprintf(buf+len,"No wl_private in scull_read_procmem\n" );
3578 } else if ( lp->wlags49_type == 0 ){
3580 len += sprintf(buf+len,"Magic: 0x%04X\n", ifbp->IFB_Magic );
3581 len += sprintf(buf+len,"IOBase: 0x%04X\n", ifbp->IFB_IOBase );
3582 len += sprintf(buf+len,"LinkStat: 0x%04X\n", ifbp->IFB_LinkStat );
3583 len += sprintf(buf+len,"DSLinkStat: 0x%04X\n", ifbp->IFB_DSLinkStat );
3584 len += sprintf(buf+len,"TickIni: 0x%08lX\n", ifbp->IFB_TickIni );
3585 len += sprintf(buf+len,"TickCnt: 0x%04X\n", ifbp->IFB_TickCnt );
3586 len += sprintf(buf+len,"IntOffCnt: 0x%04X\n", ifbp->IFB_IntOffCnt );
3587 len += printf_hcf_16( "IFB_FWIdentity", &buf[len],
3588 &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
3589 } else if ( lp->wlags49_type == 1 ) {
3590 len += sprintf(buf+len,"Channel: 0x%04X\n", lp->Channel );
3591 /****** len += sprintf(buf+len,"slock: %d\n", lp->slock ); */
3592 //x struct tq_struct "task: 0x%04X\n", lp->task );
3593 //x struct net_device_stats "stats: 0x%04X\n", lp->stats );
3595 //x struct iw_statistics "wstats: 0x%04X\n", lp->wstats );
3596 //x len += sprintf(buf+len,"spy_number: 0x%04X\n", lp->spy_number );
3597 //x u_char spy_address[IW_MAX_SPY][ETH_ALEN];
3598 //x struct iw_quality spy_stat[IW_MAX_SPY];
3599 #endif // WIRELESS_EXT
3600 len += sprintf(buf+len,"IFB: 0x%p\n", &lp->hcfCtx );
3601 len += sprintf(buf+len,"flags: %#.8lX\n", lp->flags ); //;?use this format from now on
3602 len += sprintf(buf+len,"DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
3604 len += sprintf(buf+len,"DebugFlag (DbgInfo): 0x%08lX\n", DbgInfo->DebugFlag );
3606 len += sprintf(buf+len,"is_registered: 0x%04X\n", lp->is_registered );
3607 //x CFG_DRV_INFO_STRCT "driverInfo: 0x%04X\n", lp->driverInfo );
3608 len += printf_strct( "driverInfo", &buf[len], (hcf_16*)&lp->driverInfo );
3609 //x CFG_IDENTITY_STRCT "driverIdentity: 0x%04X\n", lp->driverIdentity );
3610 len += printf_strct( "driverIdentity", &buf[len], (hcf_16*)&lp->driverIdentity );
3611 //x CFG_FW_IDENTITY_STRCT "StationIdentity: 0x%04X\n", lp->StationIdentity );
3612 len += printf_strct( "StationIdentity", &buf[len], (hcf_16*)&lp->StationIdentity );
3613 //x CFG_PRI_IDENTITY_STRCT "PrimaryIdentity: 0x%04X\n", lp->PrimaryIdentity );
3614 len += printf_strct( "PrimaryIdentity", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
3615 len += printf_strct( "PrimarySupplier", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRISup );
3616 //x CFG_PRI_IDENTITY_STRCT "NICIdentity: 0x%04X\n", lp->NICIdentity );
3617 len += printf_strct( "NICIdentity", &buf[len], (hcf_16*)&lp->NICIdentity );
3618 //x ltv_t "ltvRecord: 0x%04X\n", lp->ltvRecord );
3619 len += sprintf(buf+len,"txBytes: 0x%08lX\n", lp->txBytes );
3620 len += sprintf(buf+len,"maxPort: 0x%04X\n", lp->maxPort ); /* 0 for STA, 6 for AP */
3621 /* Elements used for async notification from hardware */
3622 //x RID_LOG_STRCT RidList[10];
3623 //x ltv_t "updatedRecord: 0x%04X\n", lp->updatedRecord );
3624 //x PROBE_RESP "ProbeResp: 0x%04X\n", lp->ProbeResp );
3625 //x ASSOC_STATUS_STRCT "assoc_stat: 0x%04X\n", lp->assoc_stat );
3626 //x SECURITY_STATUS_STRCT "sec_stat: 0x%04X\n", lp->sec_stat );
3627 //x u_char lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
3628 len += sprintf(buf+len,"PortType: 0x%04X\n", lp->PortType ); // 1 - 3 (1 [Normal] | 3 [AdHoc])
3629 len += sprintf(buf+len,"Channel: 0x%04X\n", lp->Channel ); // 0 - 14 (0)
3630 //x hcf_16 TxRateControl[2];
3631 len += sprintf(buf+len,"TxRateControl[2]: 0x%04X 0x%04X\n",
3632 lp->TxRateControl[0], lp->TxRateControl[1] );
3633 len += sprintf(buf+len,"DistanceBetweenAPs: 0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
3634 len += sprintf(buf+len,"RTSThreshold: 0x%04X\n", lp->RTSThreshold ); // 0 - 2347 (2347)
3635 len += sprintf(buf+len,"PMEnabled: 0x%04X\n", lp->PMEnabled ); // 0 - 2, 8001 - 8002 (0)
3636 len += sprintf(buf+len,"MicrowaveRobustness: 0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
3637 len += sprintf(buf+len,"CreateIBSS: 0x%04X\n", lp->CreateIBSS ); // 0 - 1 (0)
3638 len += sprintf(buf+len,"MulticastReceive: 0x%04X\n", lp->MulticastReceive ); // 0 - 1 (1)
3639 len += sprintf(buf+len,"MaxSleepDuration: 0x%04X\n", lp->MaxSleepDuration ); // 0 - 65535 (100)
3640 //x hcf_8 MACAddress[ETH_ALEN];
3641 len += printf_hcf_8( "MACAddress", &buf[len], lp->MACAddress, ETH_ALEN );
3642 //x char NetworkName[HCF_MAX_NAME_LEN+1];
3643 len += sprintf(buf+len,"NetworkName: %.32s\n", lp->NetworkName );
3644 //x char StationName[HCF_MAX_NAME_LEN+1];
3645 len += sprintf(buf+len,"EnableEncryption: 0x%04X\n", lp->EnableEncryption ); // 0 - 1 (0)
3646 //x char Key1[MAX_KEY_LEN+1];
3647 len += printf_hcf_8( "Key1", &buf[len], lp->Key1, MAX_KEY_LEN );
3648 //x char Key2[MAX_KEY_LEN+1];
3649 //x char Key3[MAX_KEY_LEN+1];
3650 //x char Key4[MAX_KEY_LEN+1];
3651 len += sprintf(buf+len,"TransmitKeyID: 0x%04X\n", lp->TransmitKeyID ); // 1 - 4 (1)
3652 //x CFG_DEFAULT_KEYS_STRCT "DefaultKeys: 0x%04X\n", lp->DefaultKeys );
3653 //x u_char mailbox[MB_SIZE];
3654 //x char szEncryption[MAX_ENC_LEN];
3655 len += sprintf(buf+len,"driverEnable: 0x%04X\n", lp->driverEnable );
3656 len += sprintf(buf+len,"wolasEnable: 0x%04X\n", lp->wolasEnable );
3657 len += sprintf(buf+len,"atimWindow: 0x%04X\n", lp->atimWindow );
3658 len += sprintf(buf+len,"holdoverDuration: 0x%04X\n", lp->holdoverDuration );
3659 //x hcf_16 MulticastRate[2];
3660 len += sprintf(buf+len,"authentication: 0x%04X\n", lp->authentication ); // is this AP specific?
3661 len += sprintf(buf+len,"promiscuousMode: 0x%04X\n", lp->promiscuousMode );
3662 len += sprintf(buf+len,"DownloadFirmware: 0x%04X\n", lp->DownloadFirmware ); // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
3663 len += sprintf(buf+len,"AuthKeyMgmtSuite: 0x%04X\n", lp->AuthKeyMgmtSuite );
3664 len += sprintf(buf+len,"loadBalancing: 0x%04X\n", lp->loadBalancing );
3665 len += sprintf(buf+len,"mediumDistribution: 0x%04X\n", lp->mediumDistribution );
3666 len += sprintf(buf+len,"txPowLevel: 0x%04X\n", lp->txPowLevel );
3667 // len += sprintf(buf+len,"shortRetryLimit: 0x%04X\n", lp->shortRetryLimit );
3668 // len += sprintf(buf+len,"longRetryLimit: 0x%04X\n", lp->longRetryLimit );
3671 len += sprintf(buf+len,"connectionControl: 0x%04X\n", lp->connectionControl );
3672 //x //hcf_16 probeDataRates[2];
3673 len += sprintf(buf+len,"ownBeaconInterval: 0x%04X\n", lp->ownBeaconInterval );
3674 len += sprintf(buf+len,"coexistence: 0x%04X\n", lp->coexistence );
3675 //x WVLAN_FRAME "txF: 0x%04X\n", lp->txF );
3676 //x WVLAN_LFRAME txList[DEFAULT_NUM_TX_FRAMES];
3677 //x struct list_head "txFree: 0x%04X\n", lp->txFree );
3678 //x struct list_head txQ[WVLAN_MAX_TX_QUEUES];
3679 len += sprintf(buf+len,"netif_queue_on: 0x%04X\n", lp->netif_queue_on );
3680 len += sprintf(buf+len,"txQ_count: 0x%04X\n", lp->txQ_count );
3681 //x DESC_STRCT "desc_rx: 0x%04X\n", lp->desc_rx );
3682 //x DESC_STRCT "desc_tx: 0x%04X\n", lp->desc_tx );
3683 //x WVLAN_PORT_STATE "portState: 0x%04X\n", lp->portState );
3684 //x ScanResult "scan_results: 0x%04X\n", lp->scan_results );
3685 //x ProbeResult "probe_results: 0x%04X\n", lp->probe_results );
3686 len += sprintf(buf+len,"probe_num_aps: 0x%04X\n", lp->probe_num_aps );
3687 len += sprintf(buf+len,"use_dma: 0x%04X\n", lp->use_dma );
3688 //x DMA_STRCT "dma: 0x%04X\n", lp->dma );
3690 len += sprintf(buf+len,"useRTS: 0x%04X\n", lp->useRTS );
3692 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
3693 //;?should we restore this to allow smaller memory footprint
3694 //;?I guess not. This should be brought under Debug mode only
3695 len += sprintf(buf+len,"DTIMPeriod: 0x%04X\n", lp->DTIMPeriod ); // 1 - 255 (1)
3696 len += sprintf(buf+len,"multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
3697 len += sprintf(buf+len,"RejectAny: 0x%04X\n", lp->RejectAny ); // 0 - 1 (0)
3698 len += sprintf(buf+len,"ExcludeUnencrypted: 0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
3699 len += sprintf(buf+len,"intraBSSRelay: 0x%04X\n", lp->intraBSSRelay );
3700 len += sprintf(buf+len,"wlags49_type: 0x%08lX\n", lp->wlags49_type );
3702 //x WVLAN_WDS_IF wds_port[NUM_WDS_PORTS];
3705 } else if ( lp->wlags49_type == 2 ){
3706 len += sprintf(buf+len,"tallies to be added\n" );
3707 //Hermes Tallies (IFB substructure) {
3708 p = &lp->hcfCtx.IFB_NIC_Tallies;
3709 len += sprintf(buf+len,"TxUnicastFrames: %08lX\n", p->TxUnicastFrames );
3710 len += sprintf(buf+len,"TxMulticastFrames: %08lX\n", p->TxMulticastFrames );
3711 len += sprintf(buf+len,"TxFragments: %08lX\n", p->TxFragments );
3712 len += sprintf(buf+len,"TxUnicastOctets: %08lX\n", p->TxUnicastOctets );
3713 len += sprintf(buf+len,"TxMulticastOctets: %08lX\n", p->TxMulticastOctets );
3714 len += sprintf(buf+len,"TxDeferredTransmissions: %08lX\n", p->TxDeferredTransmissions );
3715 len += sprintf(buf+len,"TxSingleRetryFrames: %08lX\n", p->TxSingleRetryFrames );
3716 len += sprintf(buf+len,"TxMultipleRetryFrames: %08lX\n", p->TxMultipleRetryFrames );
3717 len += sprintf(buf+len,"TxRetryLimitExceeded: %08lX\n", p->TxRetryLimitExceeded );
3718 len += sprintf(buf+len,"TxDiscards: %08lX\n", p->TxDiscards );
3719 len += sprintf(buf+len,"RxUnicastFrames: %08lX\n", p->RxUnicastFrames );
3720 len += sprintf(buf+len,"RxMulticastFrames: %08lX\n", p->RxMulticastFrames );
3721 len += sprintf(buf+len,"RxFragments: %08lX\n", p->RxFragments );
3722 len += sprintf(buf+len,"RxUnicastOctets: %08lX\n", p->RxUnicastOctets );
3723 len += sprintf(buf+len,"RxMulticastOctets: %08lX\n", p->RxMulticastOctets );
3724 len += sprintf(buf+len,"RxFCSErrors: %08lX\n", p->RxFCSErrors );
3725 len += sprintf(buf+len,"RxDiscardsNoBuffer: %08lX\n", p->RxDiscardsNoBuffer );
3726 len += sprintf(buf+len,"TxDiscardsWrongSA: %08lX\n", p->TxDiscardsWrongSA );
3727 len += sprintf(buf+len,"RxWEPUndecryptable: %08lX\n", p->RxWEPUndecryptable );
3728 len += sprintf(buf+len,"RxMsgInMsgFragments: %08lX\n", p->RxMsgInMsgFragments );
3729 len += sprintf(buf+len,"RxMsgInBadMsgFragments: %08lX\n", p->RxMsgInBadMsgFragments );
3730 len += sprintf(buf+len,"RxDiscardsWEPICVError: %08lX\n", p->RxDiscardsWEPICVError );
3731 len += sprintf(buf+len,"RxDiscardsWEPExcluded: %08lX\n", p->RxDiscardsWEPExcluded );
3732 #if (HCF_EXT) & HCF_EXT_TALLIES_FW
3734 #endif // HCF_EXT_TALLIES_FW
3735 } else if ( lp->wlags49_type & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3737 DbgInfo->DebugFlag = lp->wlags49_type & 0x7FFF;
3739 lp->wlags49_type = 0; //default to IFB again ;?
3741 len += sprintf(buf+len,"unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
3742 len += sprintf(buf+len,"0x0000 - IFB\n" );
3743 len += sprintf(buf+len,"0x0001 - wl_private\n" );
3744 len += sprintf(buf+len,"0x0002 - Tallies\n" );
3745 len += sprintf(buf+len,"0x8xxx - Change debufflag\n" );
3746 len += sprintf(buf+len,"ERROR 0001\nWARNING 0002\nNOTICE 0004\nTRACE 0008\n" );
3747 len += sprintf(buf+len,"VERBOSE 0010\nPARAM 0020\nBREAK 0040\nRX 0100\n" );
3748 len += sprintf(buf+len,"TX 0200\nDS 0400\n" );
3751 } // scull_read_procmem
3753 static void proc_write(const char *name, write_proc_t *w, void *data)
3755 struct proc_dir_entry * entry = create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
3757 entry->write_proc = w;
3762 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
3764 static char proc_number[11];
3765 unsigned int nr = 0;
3767 DBG_FUNC( "write_int" );
3768 DBG_ENTER( DbgInfo );
3772 } else if ( copy_from_user(proc_number, buffer, count) ) {
3776 proc_number[count] = 0;
3777 nr = simple_strtoul(proc_number , NULL, 0);
3778 *(unsigned int *)data = nr;
3779 if ( nr & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3781 DbgInfo->DebugFlag = nr & 0x7FFF;
3785 DBG_PRINT( "value: %08X\n", nr );
3786 DBG_LEAVE( DbgInfo );
3790 #endif /* SCULL_USE_PROC */
3793 #define RUN_AT(x) (jiffies+(x)) //"borrowed" from include/pcmcia/k_compat.h
3794 #define DS_OOR 0x8000 //Deepsleep OutOfRange Status
3796 lp->timer_oor_cnt = DS_OOR;
3797 init_timer( &lp->timer_oor );
3798 lp->timer_oor.function = timer_oor;
3799 lp->timer_oor.data = (unsigned long)lp;
3800 lp->timer_oor.expires = RUN_AT( 3 * HZ );
3801 add_timer( &lp->timer_oor );
3802 printk( "<5>wl_enable: %ld\n", jiffies ); //;?remove me 1 day
3805 /*******************************************************************************
3807 *******************************************************************************
3814 * arg - a u_long representing a pointer to a dev_link_t structure for the
3815 * device to be released.
3821 ******************************************************************************/
3822 void timer_oor( u_long arg )
3824 struct wl_private *lp = (struct wl_private *)arg;
3826 /*------------------------------------------------------------------------*/
3828 DBG_FUNC( "timer_oor" );
3829 DBG_ENTER( DbgInfo );
3830 DBG_PARAM( DbgInfo, "arg", "0x%08lx", arg );
3832 printk( "<5>timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt ); //;?remove me 1 day
3833 lp->timer_oor_cnt += 10;
3834 if ( (lp->timer_oor_cnt & ~DS_OOR) > 300 ) {
3835 lp->timer_oor_cnt = 300;
3837 lp->timer_oor_cnt |= DS_OOR;
3838 init_timer( &lp->timer_oor );
3839 lp->timer_oor.function = timer_oor;
3840 lp->timer_oor.data = (unsigned long)lp;
3841 lp->timer_oor.expires = RUN_AT( (lp->timer_oor_cnt & ~DS_OOR) * HZ );
3842 add_timer( &lp->timer_oor );
3844 DBG_LEAVE( DbgInfo );
3848 MODULE_LICENSE("Dual BSD/GPL");