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 /* Initialize 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 );
470 DBG_PARAM(DbgInfo, PARM_NAME_NETWORK_ADDR, "\"%pM\"",
473 //;? DBG_PARAM( DbgInfo, PARM_NAME_AUTHENTICATION, "%d", PARM_AUTHENTICATION );
474 //;? DBG_PARAM( DbgInfo, PARM_NAME_OWN_ATIM_WINDOW, "%d", PARM_OWN_ATIM_WINDOW );
475 //;? DBG_PARAM( DbgInfo, PARM_NAME_PM_HOLDOVER_DURATION, "%d", PARM_PM_HOLDOVER_DURATION );
476 //;? DBG_PARAM( DbgInfo, PARM_NAME_PROMISCUOUS_MODE, "\"%s\"", PARM_PROMISCUOUS_MODE );
477 //;?#endif /* HCF_STA */
478 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
479 //;?should we restore this to allow smaller memory footprint
480 //;?I guess: no, since this is Debug mode only
481 DBG_PARAM( DbgInfo, PARM_NAME_OWN_DTIM_PERIOD, "%d", PARM_OWN_DTIM_PERIOD );
482 DBG_PARAM( DbgInfo, PARM_NAME_REJECT_ANY, "\"%s\"", PARM_REJECT_ANY );
483 DBG_PARAM( DbgInfo, PARM_NAME_EXCLUDE_UNENCRYPTED, "\"%s\"", PARM_EXCLUDE_UNENCRYPTED );
484 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_PM_BUFFERING, "\"%s\"", PARM_MULTICAST_PM_BUFFERING );
485 DBG_PARAM( DbgInfo, PARM_NAME_INTRA_BSS_RELAY, "\"%s\"", PARM_INTRA_BSS_RELAY );
487 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD1, "%d", PARM_RTS_THRESHOLD1 );
488 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD2, "%d", PARM_RTS_THRESHOLD2 );
489 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD3, "%d", PARM_RTS_THRESHOLD3 );
490 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD4, "%d", PARM_RTS_THRESHOLD4 );
491 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD5, "%d", PARM_RTS_THRESHOLD5 );
492 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD6, "%d", PARM_RTS_THRESHOLD6 );
493 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE1, "%d", PARM_TX_RATE1 );
494 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE2, "%d", PARM_TX_RATE2 );
495 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE3, "%d", PARM_TX_RATE3 );
496 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE4, "%d", PARM_TX_RATE4 );
497 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE5, "%d", PARM_TX_RATE5 );
498 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE6, "%d", PARM_TX_RATE6 );
499 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS1, "\"%pM\"",
501 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS2, "\"%pM\"",
503 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS3, "\"%pM\"",
505 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS4, "\"%pM\"",
507 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS5, "\"%pM\"",
509 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS6, "\"%pM\"",
514 VALID_PARAM( !PARM_DESIRED_SSID || ( strlen( PARM_DESIRED_SSID ) <= PARM_MAX_NAME_LEN ));
515 VALID_PARAM( !PARM_OWN_SSID || ( strlen( PARM_OWN_SSID ) <= PARM_MAX_NAME_LEN ));
516 VALID_PARAM(( PARM_OWN_CHANNEL <= PARM_MAX_OWN_CHANNEL ));
517 VALID_PARAM(( PARM_SYSTEM_SCALE >= PARM_MIN_SYSTEM_SCALE ) && ( PARM_SYSTEM_SCALE <= PARM_MAX_SYSTEM_SCALE ));
518 VALID_PARAM(( PARM_TX_RATE >= PARM_MIN_TX_RATE ) && ( PARM_TX_RATE <= PARM_MAX_TX_RATE ));
519 VALID_PARAM(( PARM_RTS_THRESHOLD <= PARM_MAX_RTS_THRESHOLD ));
520 VALID_PARAM( !PARM_MICROWAVE_ROBUSTNESS || strchr( "NnYy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL );
521 VALID_PARAM( !PARM_OWN_NAME || ( strlen( PARM_NAME_OWN_NAME ) <= PARM_MAX_NAME_LEN ));
522 VALID_PARAM(( PARM_ENABLE_ENCRYPTION <= PARM_MAX_ENABLE_ENCRYPTION ));
523 VALID_PARAM( is_valid_key_string( PARM_KEY1 ));
524 VALID_PARAM( is_valid_key_string( PARM_KEY2 ));
525 VALID_PARAM( is_valid_key_string( PARM_KEY3 ));
526 VALID_PARAM( is_valid_key_string( PARM_KEY4 ));
527 VALID_PARAM(( PARM_TX_KEY >= PARM_MIN_TX_KEY ) && ( PARM_TX_KEY <= PARM_MAX_TX_KEY ));
529 VALID_PARAM(( PARM_MULTICAST_RATE >= PARM_MIN_MULTICAST_RATE ) &&
530 ( PARM_MULTICAST_RATE <= PARM_MAX_MULTICAST_RATE ));
532 VALID_PARAM( !PARM_DOWNLOAD_FIRMWARE || ( strlen( PARM_DOWNLOAD_FIRMWARE ) <= 255 /*;?*/ ));
533 VALID_PARAM(( PARM_AUTH_KEY_MGMT_SUITE < PARM_MAX_AUTH_KEY_MGMT_SUITE ));
535 VALID_PARAM( !PARM_LOAD_BALANCING || strchr( "NnYy", PARM_LOAD_BALANCING[0] ) != NULL );
536 VALID_PARAM( !PARM_MEDIUM_DISTRIBUTION || strchr( "NnYy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL );
537 VALID_PARAM(( PARM_TX_POW_LEVEL <= PARM_MAX_TX_POW_LEVEL ));
539 VALID_PARAM(( PARM_PORT_TYPE >= PARM_MIN_PORT_TYPE ) && ( PARM_PORT_TYPE <= PARM_MAX_PORT_TYPE ));
540 VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
541 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
542 VALID_PARAM( !PARM_CREATE_IBSS || strchr( "NnYy", PARM_CREATE_IBSS[0] ) != NULL );
543 VALID_PARAM( !PARM_MULTICAST_RX || strchr( "NnYy", PARM_MULTICAST_RX[0] ) != NULL );
544 VALID_PARAM(( PARM_MAX_SLEEP <= PARM_MAX_MAX_PM_SLEEP ));
545 VALID_PARAM(( PARM_AUTHENTICATION <= PARM_MAX_AUTHENTICATION ));
546 VALID_PARAM(( PARM_OWN_ATIM_WINDOW <= PARM_MAX_OWN_ATIM_WINDOW ));
547 VALID_PARAM(( PARM_PM_HOLDOVER_DURATION <= PARM_MAX_PM_HOLDOVER_DURATION ));
548 VALID_PARAM( !PARM_PROMISCUOUS_MODE || strchr( "NnYy", PARM_PROMISCUOUS_MODE[0] ) != NULL );
549 VALID_PARAM(( PARM_CONNECTION_CONTROL <= PARM_MAX_CONNECTION_CONTROL ));
551 VALID_PARAM(( PARM_OWN_DTIM_PERIOD >= PARM_MIN_OWN_DTIM_PERIOD ));
552 VALID_PARAM( !PARM_REJECT_ANY || strchr( "NnYy", PARM_REJECT_ANY[0] ) != NULL );
553 VALID_PARAM( !PARM_EXCLUDE_UNENCRYPTED || strchr( "NnYy", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL );
554 VALID_PARAM( !PARM_MULTICAST_PM_BUFFERING || strchr( "NnYy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL );
555 VALID_PARAM( !PARM_INTRA_BSS_RELAY || strchr( "NnYy", PARM_INTRA_BSS_RELAY[0] ) != NULL );
557 VALID_PARAM(( PARM_RTS_THRESHOLD1 <= PARM_MAX_RTS_THRESHOLD ));
558 VALID_PARAM(( PARM_RTS_THRESHOLD2 <= PARM_MAX_RTS_THRESHOLD ));
559 VALID_PARAM(( PARM_RTS_THRESHOLD3 <= PARM_MAX_RTS_THRESHOLD ));
560 VALID_PARAM(( PARM_RTS_THRESHOLD4 <= PARM_MAX_RTS_THRESHOLD ));
561 VALID_PARAM(( PARM_RTS_THRESHOLD5 <= PARM_MAX_RTS_THRESHOLD ));
562 VALID_PARAM(( PARM_RTS_THRESHOLD6 <= PARM_MAX_RTS_THRESHOLD ));
563 VALID_PARAM(( PARM_TX_RATE1 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE1 <= PARM_MAX_TX_RATE ));
564 VALID_PARAM(( PARM_TX_RATE2 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE2 <= PARM_MAX_TX_RATE ));
565 VALID_PARAM(( PARM_TX_RATE3 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE3 <= PARM_MAX_TX_RATE ));
566 VALID_PARAM(( PARM_TX_RATE4 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE4 <= PARM_MAX_TX_RATE ));
567 VALID_PARAM(( PARM_TX_RATE5 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE5 <= PARM_MAX_TX_RATE ));
568 VALID_PARAM(( PARM_TX_RATE6 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE6 <= PARM_MAX_TX_RATE ));
571 VALID_PARAM(( PARM_OWN_BEACON_INTERVAL >= PARM_MIN_OWN_BEACON_INTERVAL ) && ( PARM_OWN_BEACON_INTERVAL <= PARM_MAX_OWN_BEACON_INTERVAL ));
572 VALID_PARAM(( PARM_COEXISTENCE <= PARM_COEXISTENCE ));
574 /* Set the driver parameters from the passed in parameters. */
576 /* THESE MODULE PARAMETERS ARE TO BE DEPRECATED IN FAVOR OF A NAMING CONVENTION
577 WHICH IS INLINE WITH THE FORTHCOMING WAVELAN API */
579 /* START NEW PARAMETERS */
581 lp->Channel = PARM_OWN_CHANNEL;
582 lp->DistanceBetweenAPs = PARM_SYSTEM_SCALE;
584 /* Need to determine how to handle the new bands for 5GHz */
585 lp->TxRateControl[0] = PARM_DEFAULT_TX_RATE_2GHZ;
586 lp->TxRateControl[1] = PARM_DEFAULT_TX_RATE_5GHZ;
588 lp->RTSThreshold = PARM_RTS_THRESHOLD;
590 /* Need to determine how to handle the new bands for 5GHz */
591 lp->MulticastRate[0] = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
592 lp->MulticastRate[1] = PARM_DEFAULT_MULTICAST_RATE_5GHZ;
594 if ( strchr( "Yy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL ) {
595 lp->MicrowaveRobustness = 1;
597 lp->MicrowaveRobustness = 0;
599 if ( PARM_DESIRED_SSID && ( strlen( PARM_DESIRED_SSID ) <= HCF_MAX_NAME_LEN )) {
600 strcpy( lp->NetworkName, PARM_DESIRED_SSID );
602 if ( PARM_OWN_SSID && ( strlen( PARM_OWN_SSID ) <= HCF_MAX_NAME_LEN )) {
603 strcpy( lp->NetworkName, PARM_OWN_SSID );
605 if ( PARM_OWN_NAME && ( strlen( PARM_OWN_NAME ) <= HCF_MAX_NAME_LEN )) {
606 strcpy( lp->StationName, PARM_OWN_NAME );
608 lp->EnableEncryption = PARM_ENABLE_ENCRYPTION;
609 if ( PARM_KEY1 && ( strlen( PARM_KEY1 ) <= MAX_KEY_LEN )) {
610 strcpy( lp->Key1, PARM_KEY1 );
612 if ( PARM_KEY2 && ( strlen( PARM_KEY2 ) <= MAX_KEY_LEN )) {
613 strcpy( lp->Key2, PARM_KEY2 );
615 if ( PARM_KEY3 && ( strlen( PARM_KEY3 ) <= MAX_KEY_LEN )) {
616 strcpy( lp->Key3, PARM_KEY3 );
618 if ( PARM_KEY4 && ( strlen( PARM_KEY4 ) <= MAX_KEY_LEN )) {
619 strcpy( lp->Key4, PARM_KEY4 );
622 lp->TransmitKeyID = PARM_TX_KEY;
624 key_string2key( lp->Key1, &(lp->DefaultKeys.key[0] ));
625 key_string2key( lp->Key2, &(lp->DefaultKeys.key[1] ));
626 key_string2key( lp->Key3, &(lp->DefaultKeys.key[2] ));
627 key_string2key( lp->Key4, &(lp->DefaultKeys.key[3] ));
629 lp->DownloadFirmware = 1 ; //;?to be upgraded PARM_DOWNLOAD_FIRMWARE;
630 lp->AuthKeyMgmtSuite = PARM_AUTH_KEY_MGMT_SUITE;
632 if ( strchr( "Yy", PARM_LOAD_BALANCING[0] ) != NULL ) {
633 lp->loadBalancing = 1;
635 lp->loadBalancing = 0;
638 if ( strchr( "Yy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL ) {
639 lp->mediumDistribution = 1;
641 lp->mediumDistribution = 0;
644 lp->txPowLevel = PARM_TX_POW_LEVEL;
646 lp->srsc[0] = PARM_SRSC_2GHZ;
647 lp->srsc[1] = PARM_SRSC_5GHZ;
648 lp->brsc[0] = PARM_BRSC_2GHZ;
649 lp->brsc[1] = PARM_BRSC_5GHZ;
650 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
651 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
652 lp->PortType = PARM_PORT_TYPE;
653 lp->MaxSleepDuration = PARM_MAX_SLEEP;
654 lp->authentication = PARM_AUTHENTICATION;
655 lp->atimWindow = PARM_OWN_ATIM_WINDOW;
656 lp->holdoverDuration = PARM_PM_HOLDOVER_DURATION;
657 lp->PMEnabled = PARM_PM_ENABLED; //;?
658 if ( strchr( "Yy", PARM_CREATE_IBSS[0] ) != NULL ) {
663 if ( strchr( "Nn", PARM_MULTICAST_RX[0] ) != NULL ) {
664 lp->MulticastReceive = 0;
666 lp->MulticastReceive = 1;
668 if ( strchr( "Yy", PARM_PROMISCUOUS_MODE[0] ) != NULL ) {
669 lp->promiscuousMode = 1;
671 lp->promiscuousMode = 0;
673 for( i = 0; i < ETH_ALEN; i++ ) {
674 lp->MACAddress[i] = PARM_NETWORK_ADDR[i];
677 lp->connectionControl = PARM_CONNECTION_CONTROL;
680 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
681 //;?should we restore this to allow smaller memory footprint
682 lp->DTIMPeriod = PARM_OWN_DTIM_PERIOD;
684 if ( strchr( "Yy", PARM_REJECT_ANY[0] ) != NULL ) {
689 if ( strchr( "Nn", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL ) {
690 lp->ExcludeUnencrypted = 0;
692 lp->ExcludeUnencrypted = 1;
694 if ( strchr( "Yy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL ) {
695 lp->multicastPMBuffering = 1;
697 lp->multicastPMBuffering = 0;
699 if ( strchr( "Yy", PARM_INTRA_BSS_RELAY[0] ) != NULL ) {
700 lp->intraBSSRelay = 1;
702 lp->intraBSSRelay = 0;
705 lp->ownBeaconInterval = PARM_OWN_BEACON_INTERVAL;
706 lp->coexistence = PARM_COEXISTENCE;
709 lp->wds_port[0].rtsThreshold = PARM_RTS_THRESHOLD1;
710 lp->wds_port[1].rtsThreshold = PARM_RTS_THRESHOLD2;
711 lp->wds_port[2].rtsThreshold = PARM_RTS_THRESHOLD3;
712 lp->wds_port[3].rtsThreshold = PARM_RTS_THRESHOLD4;
713 lp->wds_port[4].rtsThreshold = PARM_RTS_THRESHOLD5;
714 lp->wds_port[5].rtsThreshold = PARM_RTS_THRESHOLD6;
715 lp->wds_port[0].txRateCntl = PARM_TX_RATE1;
716 lp->wds_port[1].txRateCntl = PARM_TX_RATE2;
717 lp->wds_port[2].txRateCntl = PARM_TX_RATE3;
718 lp->wds_port[3].txRateCntl = PARM_TX_RATE4;
719 lp->wds_port[4].txRateCntl = PARM_TX_RATE5;
720 lp->wds_port[5].txRateCntl = PARM_TX_RATE6;
722 for( i = 0; i < ETH_ALEN; i++ ) {
723 lp->wds_port[0].wdsAddress[i] = PARM_WDS_ADDRESS1[i];
725 for( i = 0; i < ETH_ALEN; i++ ) {
726 lp->wds_port[1].wdsAddress[i] = PARM_WDS_ADDRESS2[i];
728 for( i = 0; i < ETH_ALEN; i++ ) {
729 lp->wds_port[2].wdsAddress[i] = PARM_WDS_ADDRESS3[i];
731 for( i = 0; i < ETH_ALEN; i++ ) {
732 lp->wds_port[3].wdsAddress[i] = PARM_WDS_ADDRESS4[i];
734 for( i = 0; i < ETH_ALEN; i++ ) {
735 lp->wds_port[4].wdsAddress[i] = PARM_WDS_ADDRESS5[i];
737 for( i = 0; i < ETH_ALEN; i++ ) {
738 lp->wds_port[5].wdsAddress[i] = PARM_WDS_ADDRESS6[i];
743 if ( strchr( "Yy", useRTS[0] ) != NULL ) {
751 /* END NEW PARAMETERS */
754 wl_lock( lp, &flags );
756 /* Initialize the portState variable */
757 lp->portState = WVLAN_PORT_STATE_DISABLED;
759 /* Initialize the ScanResult struct */
760 memset( &( lp->scan_results ), 0, sizeof( lp->scan_results ));
761 lp->scan_results.scan_complete = FALSE;
763 /* Initialize the ProbeResult struct */
764 memset( &( lp->probe_results ), 0, sizeof( lp->probe_results ));
765 lp->probe_results.scan_complete = FALSE;
766 lp->probe_num_aps = 0;
769 /* Initialize Tx queue stuff */
770 memset( lp->txList, 0, sizeof( lp->txList ));
772 INIT_LIST_HEAD( &( lp->txFree ));
778 for( i = 0; i < DEFAULT_NUM_TX_FRAMES; i++ ) {
779 list_add_tail( &( lp->txList[i].node ), &( lp->txFree ));
783 for( i = 0; i < WVLAN_MAX_TX_QUEUES; i++ ) {
784 INIT_LIST_HEAD( &( lp->txQ[i] ));
787 lp->netif_queue_on = TRUE;
789 /* Initialize the use_dma element in the adapter structure. Not sure if
790 this should be a compile-time or run-time configurable. So for now,
791 implement as run-time and just define here */
794 DBG_TRACE( DbgInfo, "HERMES 2.5 BUSMASTER DMA MODE\n" );
797 DBG_TRACE( DbgInfo, "HERMES 2.5 PORT I/O MODE\n" );
802 /* Register the ISR handler information here, so that it's not done
803 repeatedly in the ISR */
804 tasklet_init(&lp->task, wl_isr_handler, (unsigned long)lp);
806 /* Connect to the adapter */
807 DBG_TRACE( DbgInfo, "Calling hcf_connect()...\n" );
808 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
809 //HCF_ERR_INCOMP_FW is acceptable, because download must still take place
810 //HCF_ERR_INCOMP_PRI is not acceptable
811 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
812 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
813 wl_unlock( lp, &flags );
817 //;?should set HCF_version and how about driver_stat
818 lp->driverInfo.IO_address = dev->base_addr;
819 lp->driverInfo.IO_range = HCF_NUM_IO_PORTS; //;?conditionally 0x40 or 0x80 seems better
820 lp->driverInfo.IRQ_number = dev->irq;
821 lp->driverInfo.card_stat = lp->hcfCtx.IFB_CardStat;
822 //;? what happened to frame_type
824 /* Fill in the driver identity structure */
825 lp->driverIdentity.len = ( sizeof( lp->driverIdentity ) / sizeof( hcf_16 )) - 1;
826 lp->driverIdentity.typ = CFG_DRV_IDENTITY;
827 lp->driverIdentity.comp_id = DRV_IDENTITY;
828 lp->driverIdentity.variant = DRV_VARIANT;
829 lp->driverIdentity.version_major = DRV_MAJOR_VERSION;
830 lp->driverIdentity.version_minor = DRV_MINOR_VERSION;
833 /* Start the card here - This needs to be done in order to get the
834 MAC address for the network layer */
835 DBG_TRACE( DbgInfo, "Calling wvlan_go() to perform a card reset...\n" );
836 hcf_status = wl_go( lp );
838 if ( hcf_status != HCF_SUCCESS ) {
839 DBG_ERROR( DbgInfo, "wl_go() failed\n" );
840 wl_unlock( lp, &flags );
844 /* Certain RIDs must be set before enabling the ports */
845 wl_put_ltv_init( lp );
847 #if 0 //;?why was this already commented out in wl_lkm_720
848 /* Enable the ports */
849 if ( wl_adapter_is_open( lp->dev )) {
850 /* Enable the ports */
851 DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
852 hcf_status = wl_enable( lp );
854 if ( hcf_status != HCF_SUCCESS ) {
855 DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", hcf_status );
858 #if (HCF_TYPE) & HCF_TYPE_AP
859 DBG_TRACE( DbgInfo, "Enabling WDS Ports\n" );
860 //wl_enable_wds_ports( lp );
861 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
866 /* Fill out the MAC address information in the net_device struct */
867 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN );
868 dev->addr_len = ETH_ALEN;
870 lp->is_registered = TRUE;
873 /* Parse the config file for the sake of creating WDS ports if WDS is
874 configured there but not in the module options */
876 #endif /* USE_PROFILE */
878 /* If we're going into AP Mode, register the "virtual" ethernet devices
880 WL_WDS_NETDEV_REGISTER( lp );
882 /* Reset the DownloadFirmware variable in the private struct. If the
883 config file is not used, this will not matter; if it is used, it
884 will be reparsed in wl_open(). This is done because logic in wl_open
885 used to check if a firmware download is needed is broken by parsing
886 the file here; however, this parsing is needed to register WDS ports
887 in AP mode, if they are configured */
888 lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //;?download_firmware;
891 if ( lp->useRTS == 1 ) {
892 DBG_TRACE( DbgInfo, "ENTERING RTS MODE...\n" );
893 wl_act_int_off( lp );
894 lp->is_handling_int = WL_NOT_HANDLING_INT; // Not handling interrupts anymore
898 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT);
902 wl_unlock( lp, &flags );
904 DBG_TRACE( DbgInfo, "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
905 dev->name, dev->base_addr, dev->irq );
907 for( i = 0; i < ETH_ALEN; i++ ) {
908 printk( "%02X%c", dev->dev_addr[i], (( i < ( ETH_ALEN-1 )) ? ':' : '\n' ));
911 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
912 create_proc_read_entry( "wlags", 0, NULL, scull_read_procmem, dev );
913 proc_mkdir("driver/wlags49", 0);
914 proc_write("driver/wlags49/wlags49_type", write_int, &lp->wlags49_type);
915 #endif /* SCULL_USE_PROC */
917 DBG_LEAVE( DbgInfo );
921 wl_hcf_error( dev, hcf_status );
925 DBG_ERROR( DbgInfo, "wl_insert() FAILED\n" );
927 if ( lp->is_registered == TRUE ) {
928 lp->is_registered = FALSE;
931 WL_WDS_NETDEV_DEREGISTER( lp );
936 DBG_LEAVE( DbgInfo );
939 /*============================================================================*/
942 /*******************************************************************************
944 *******************************************************************************
952 * dev - a pointer to the net_device struct of the wireless device
958 ******************************************************************************/
959 int wl_reset(struct net_device *dev)
961 struct wl_private *lp = wl_priv(dev);
962 int hcf_status = HCF_SUCCESS;
963 /*------------------------------------------------------------------------*/
964 DBG_FUNC( "wl_reset" );
965 DBG_ENTER( DbgInfo );
966 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
967 DBG_PARAM( DbgInfo, "dev->base_addr", "(%#03lx)", dev->base_addr );
970 * The caller should already have a lock and
971 * disable the interrupts, we do not lock here,
972 * nor do we enable/disable interrupts!
975 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", dev->base_addr );
976 if ( dev->base_addr ) {
977 /* Shutdown the adapter. */
978 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
980 /* Reset the driver information. */
983 /* Connect to the adapter. */
984 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
985 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
986 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
990 /* Check if firmware is present, if not change state */
991 if ( hcf_status == HCF_ERR_INCOMP_FW ) {
992 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
995 /* Initialize the portState variable */
996 lp->portState = WVLAN_PORT_STATE_DISABLED;
998 /* Restart the adapter. */
999 hcf_status = wl_go( lp );
1000 if ( hcf_status != HCF_SUCCESS ) {
1001 DBG_ERROR( DbgInfo, "wl_go() failed, status: 0x%x\n", hcf_status );
1005 /* Certain RIDs must be set before enabling the ports */
1006 wl_put_ltv_init( lp );
1008 DBG_ERROR( DbgInfo, "Device Base Address INVALID!!!\n" );
1012 DBG_LEAVE( DbgInfo );
1015 /*============================================================================*/
1018 /*******************************************************************************
1020 *******************************************************************************
1024 * Reset the adapter.
1028 * dev - a pointer to the net_device struct of the wireless device
1032 * an HCF status code
1034 ******************************************************************************/
1035 int wl_go( struct wl_private *lp )
1037 int hcf_status = HCF_SUCCESS;
1038 char *cp = NULL; //fw_image
1040 /*------------------------------------------------------------------------*/
1041 DBG_FUNC( "wl_go" );
1042 DBG_ENTER( DbgInfo );
1044 hcf_status = wl_disable( lp );
1045 if ( hcf_status != HCF_SUCCESS ) {
1046 DBG_TRACE( DbgInfo, "Disable port 0 failed: 0x%x\n", hcf_status );
1048 while (( hcf_status != HCF_SUCCESS ) && (retries < 10)) {
1050 hcf_status = wl_disable( lp );
1052 if ( hcf_status == HCF_SUCCESS ) {
1053 DBG_TRACE( DbgInfo, "Disable port 0 succes : %d retries\n", retries );
1055 DBG_TRACE( DbgInfo, "Disable port 0 failed after: %d retries\n", retries );
1059 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
1060 //DBG_TRACE( DbgInfo, "Disabling WDS Ports\n" );
1061 //wl_disable_wds_ports( lp );
1062 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1064 //;?what was the purpose of this
1065 // /* load the appropriate firmware image, depending on driver mode */
1066 // lp->ltvRecord.len = ( sizeof( CFG_RANGE20_STRCT ) / sizeof( hcf_16 )) - 1;
1067 // lp->ltvRecord.typ = CFG_DRV_ACT_RANGES_PRI;
1068 // hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1071 if ( strlen( lp->fw_image_filename ) ) {
1076 DBG_TRACE( DbgInfo, "F/W image:%s:\n", lp->fw_image_filename );
1077 /* Obtain a user-space process context, storing the original context */
1080 file_desc = open( lp->fw_image_filename, O_RDONLY, 0 );
1081 if ( file_desc == -1 ) {
1082 DBG_ERROR( DbgInfo, "No image file found\n" );
1084 DBG_TRACE( DbgInfo, "F/W image file found\n" );
1085 #define DHF_ALLOC_SIZE 96000 //just below 96K, let's hope it suffices for now and for the future
1086 cp = (char*)vmalloc( DHF_ALLOC_SIZE );
1088 DBG_ERROR( DbgInfo, "error in vmalloc\n" );
1090 rc = read( file_desc, cp, DHF_ALLOC_SIZE );
1091 if ( rc == DHF_ALLOC_SIZE ) {
1092 DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE );
1093 } else if ( rc > 0 ) {
1094 DBG_TRACE( DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp );
1095 rc = read( file_desc, &cp[rc], 1 );
1096 if ( rc == 0 ) { //;/change to an until-loop at rc<=0
1097 DBG_TRACE( DbgInfo, "no more to read\n" );
1101 DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\
1102 ", give up, too complicated, rc = %0X\n", rc );
1103 DBG_ERROR( DbgInfo, "still have to change code to get a real download now !!!!!!!!\n" );
1105 DBG_TRACE( DbgInfo, "before dhf_download_binary\n" );
1106 hcf_status = dhf_download_binary( (memimage *)cp );
1107 DBG_TRACE( DbgInfo, "after dhf_download_binary, before dhf_download_fw\n" );
1108 //;?improve error flow/handling
1109 hcf_status = dhf_download_fw( &lp->hcfCtx, (memimage *)cp );
1110 DBG_TRACE( DbgInfo, "after dhf_download_fw\n" );
1116 set_fs( fs ); /* Return to the original context */
1120 /* If firmware is present but the type is unknown then download anyway */
1121 if ( (lp->firmware_present == WL_FRIMWARE_PRESENT)
1123 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_STA )
1125 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_AP ) ) {
1126 /* Unknown type, download needed. */
1127 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1130 if(lp->firmware_present == WL_FRIMWARE_NOT_PRESENT)
1133 DBG_TRACE( DbgInfo, "Downloading STA firmware...\n" );
1134 // hcf_status = dhf_download_fw( &lp->hcfCtx, &station );
1135 // hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image ); /*(DEBLOBBED)*/
1136 hcf_status = HCF_ERR_INCOMP_FW;
1138 if ( hcf_status != HCF_SUCCESS ) {
1139 DBG_ERROR( DbgInfo, "Firmware Download failed\n" );
1140 DBG_LEAVE( DbgInfo );
1144 /* Report the FW versions */
1145 //;?obsolete, use the available IFB info:: wl_get_pri_records( lp );
1146 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1147 DBG_TRACE( DbgInfo, "downloaded station F/W\n" );
1148 } else if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1149 DBG_TRACE( DbgInfo, "downloaded AP F/W\n" );
1151 DBG_ERROR( DbgInfo, "unknown F/W type\n" );
1155 * Downloaded, no need to repeat this next time, assume the
1156 * contents stays in the card until it is powered off. Note we
1157 * do not switch firmware on the fly, the firmware is fixed in
1158 * the driver for now.
1160 lp->firmware_present = WL_FRIMWARE_PRESENT;
1162 DBG_TRACE( DbgInfo, "ComponentID:%04x variant:%04x major:%04x minor:%04x\n",
1163 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ),
1164 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.variant ),
1165 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_major ),
1166 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_minor ));
1168 /* now we wil get the MAC address of the card */
1169 lp->ltvRecord.len = 4;
1170 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1171 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1174 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1176 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1177 if ( hcf_status != HCF_SUCCESS ) {
1178 DBG_ERROR( DbgInfo, "Could not retrieve MAC address\n" );
1179 DBG_LEAVE( DbgInfo );
1182 memcpy( lp->MACAddress, &lp->ltvRecord.u.u8[0], ETH_ALEN );
1183 DBG_TRACE(DbgInfo, "Card MAC Address: %pM\n", lp->MACAddress);
1185 /* Write out configuration to the device, enable, and reconnect. However,
1186 only reconnect if in AP mode. For STA mode, need to wait for passive scan
1187 completion before a connect can be issued */
1189 /* Enable the ports */
1190 hcf_status = wl_enable( lp );
1192 if ( lp->DownloadFirmware == WVLAN_DRV_MODE_AP ) {
1194 wl_enable_wds_ports( lp );
1196 hcf_status = wl_connect( lp );
1198 DBG_LEAVE( DbgInfo );
1201 /*============================================================================*/
1204 /*******************************************************************************
1206 *******************************************************************************
1210 * Write TxKeyID and WEP keys to the adapter. This is separated from
1211 * wl_apply() to allow dynamic WEP key updates through the wireless
1216 * lp - a pointer to the wireless adapter's private structure
1222 ******************************************************************************/
1223 void wl_set_wep_keys( struct wl_private *lp )
1226 /*------------------------------------------------------------------------*/
1227 DBG_FUNC( "wl_set_wep_keys" );
1228 DBG_ENTER( DbgInfo );
1229 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1230 if ( lp->EnableEncryption ) {
1231 /* NOTE: CFG_CNF_ENCRYPTION is set in wl_put_ltv() as it's a static
1235 lp->ltvRecord.len = 2;
1236 lp->ltvRecord.typ = CFG_TX_KEY_ID;
1237 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE(lp->TransmitKeyID - 1);
1239 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1241 DBG_TRACE( DbgInfo, "Key 1 len: %d\n", lp->DefaultKeys.key[0].len );
1242 DBG_TRACE( DbgInfo, "Key 2 len: %d\n", lp->DefaultKeys.key[1].len );
1243 DBG_TRACE( DbgInfo, "Key 3 len: %d\n", lp->DefaultKeys.key[2].len );
1244 DBG_TRACE( DbgInfo, "Key 4 len: %d\n", lp->DefaultKeys.key[3].len );
1247 lp->DefaultKeys.len = sizeof( lp->DefaultKeys ) / sizeof( hcf_16 ) - 1;
1248 lp->DefaultKeys.typ = CFG_DEFAULT_KEYS;
1250 /* endian translate the appropriate key information */
1251 for( count = 0; count < MAX_KEYS; count++ ) {
1252 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1255 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->DefaultKeys ));
1257 /* Reverse the above endian translation, since these keys are accessed
1259 for( count = 0; count < MAX_KEYS; count++ ) {
1260 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1263 DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption, lp->TransmitKeyID );
1264 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 );
1267 DBG_LEAVE( DbgInfo );
1268 } // wl_set_wep_keys
1269 /*============================================================================*/
1272 /*******************************************************************************
1274 *******************************************************************************
1278 * Write the parameters to the adapter. (re-)enables the card if device is
1279 * open. Returns hcf_status of hcf_enable().
1283 * lp - a pointer to the wireless adapter's private structure
1287 * an HCF status code
1289 ******************************************************************************/
1290 int wl_apply(struct wl_private *lp)
1292 int hcf_status = HCF_SUCCESS;
1293 /*------------------------------------------------------------------------*/
1294 DBG_FUNC( "wl_apply" );
1295 DBG_ENTER( DbgInfo );
1296 DBG_ASSERT( lp != NULL);
1297 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1299 if ( !( lp->flags & WVLAN2_UIL_BUSY )) {
1300 /* The adapter parameters have changed:
1306 if ( wl_adapter_is_open( lp->dev )) {
1307 /* Disconnect and disable if necessary */
1308 hcf_status = wl_disconnect( lp );
1309 if ( hcf_status != HCF_SUCCESS ) {
1310 DBG_ERROR( DbgInfo, "Disconnect failed\n" );
1311 DBG_LEAVE( DbgInfo );
1314 hcf_status = wl_disable( lp );
1315 if ( hcf_status != HCF_SUCCESS ) {
1316 DBG_ERROR( DbgInfo, "Disable failed\n" );
1317 DBG_LEAVE( DbgInfo );
1320 /* Write out configuration to the device, enable, and reconnect.
1321 However, only reconnect if in AP mode. For STA mode, need to
1322 wait for passive scan completion before a connect can be
1324 hcf_status = wl_put_ltv( lp );
1326 if ( hcf_status == HCF_SUCCESS ) {
1327 hcf_status = wl_enable( lp );
1329 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1330 hcf_status = wl_connect( lp );
1333 DBG_WARNING( DbgInfo, "wl_put_ltv() failed\n" );
1339 DBG_LEAVE( DbgInfo );
1342 /*============================================================================*/
1345 /*******************************************************************************
1347 *******************************************************************************
1351 * Used to set basic parameters for card initialization.
1355 * lp - a pointer to the wireless adapter's private structure
1359 * an HCF status code
1361 ******************************************************************************/
1362 int wl_put_ltv_init( struct wl_private *lp )
1366 CFG_RID_LOG_STRCT *RidLog;
1367 /*------------------------------------------------------------------------*/
1368 DBG_FUNC( "wl_put_ltv_init" );
1369 DBG_ENTER( DbgInfo );
1371 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1372 DBG_LEAVE( DbgInfo );
1376 lp->ltvRecord.len = 2;
1377 lp->ltvRecord.typ = CFG_CNTL_OPT;
1379 /* The Card Services build must ALWAYS configure for 16-bit I/O. PCI or
1380 CardBus can be set to either 16/32 bit I/O, or Bus Master DMA, but only
1383 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_16BIT );
1385 if ( lp->use_dma ) {
1386 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_DMA );
1388 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1392 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1393 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT : 0x%04x\n",
1394 lp->ltvRecord.u.u16[0] );
1395 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT result : 0x%04x\n",
1398 /* Register the list of RIDs on which asynchronous notification is
1399 required. Note that this mechanism replaces the mailbox, so the mailbox
1400 can be queried by the host (if desired) without contention from us */
1403 lp->RidList[i].len = sizeof( lp->ProbeResp );
1404 lp->RidList[i].typ = CFG_ACS_SCAN;
1405 lp->RidList[i].bufp = (wci_recordp)&lp->ProbeResp;
1406 //lp->ProbeResp.infoType = 0xFFFF;
1409 lp->RidList[i].len = sizeof( lp->assoc_stat );
1410 lp->RidList[i].typ = CFG_ASSOC_STAT;
1411 lp->RidList[i].bufp = (wci_recordp)&lp->assoc_stat;
1412 lp->assoc_stat.len = 0xFFFF;
1415 lp->RidList[i].len = 4;
1416 lp->RidList[i].typ = CFG_UPDATED_INFO_RECORD;
1417 lp->RidList[i].bufp = (wci_recordp)&lp->updatedRecord;
1418 lp->updatedRecord.len = 0xFFFF;
1421 lp->RidList[i].len = sizeof( lp->sec_stat );
1422 lp->RidList[i].typ = CFG_SECURITY_STAT;
1423 lp->RidList[i].bufp = (wci_recordp)&lp->sec_stat;
1424 lp->sec_stat.len = 0xFFFF;
1427 lp->RidList[i].typ = 0; // Terminate List
1429 RidLog = (CFG_RID_LOG_STRCT *)&lp->ltvRecord;
1431 RidLog->typ = CFG_REG_INFO_LOG;
1432 RidLog->recordp = (RID_LOGP)&lp->RidList[0];
1434 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1435 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG\n" );
1436 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG result : 0x%04x\n",
1438 DBG_LEAVE( DbgInfo );
1440 } // wl_put_ltv_init
1441 /*============================================================================*/
1444 /*******************************************************************************
1446 *******************************************************************************
1450 * Used by wvlan_apply() and wvlan_go to set the card's configuration.
1454 * lp - a pointer to the wireless adapter's private structure
1458 * an HCF status code
1460 ******************************************************************************/
1461 int wl_put_ltv( struct wl_private *lp )
1465 /*------------------------------------------------------------------------*/
1466 DBG_FUNC( "wl_put_ltv" );
1467 DBG_ENTER( DbgInfo );
1470 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1473 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1474 lp->maxPort = 6; //;?why set this here and not as part of download process
1479 /* Send our configuration to the card. Perform any endian translation
1481 /* Register the Mailbox; VxWorks does this elsewhere; why;? */
1482 lp->ltvRecord.len = 4;
1483 lp->ltvRecord.typ = CFG_REG_MB;
1484 lp->ltvRecord.u.u32[0] = (u_long)&( lp->mailbox );
1485 lp->ltvRecord.u.u16[2] = ( MB_SIZE / sizeof( hcf_16 ));
1486 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1488 /* Max Data Length */
1489 lp->ltvRecord.len = 2;
1490 lp->ltvRecord.typ = CFG_CNF_MAX_DATA_LEN;
1491 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( HCF_MAX_PACKET_SIZE );
1492 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1494 /* System Scale / Distance between APs */
1495 lp->ltvRecord.len = 2;
1496 lp->ltvRecord.typ = CFG_CNF_SYSTEM_SCALE;
1497 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DistanceBetweenAPs );
1498 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1501 if ( lp->CreateIBSS && ( lp->Channel == 0 )) {
1502 DBG_TRACE( DbgInfo, "Create IBSS" );
1505 lp->ltvRecord.len = 2;
1506 lp->ltvRecord.typ = CFG_CNF_OWN_CHANNEL;
1507 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->Channel );
1508 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1510 /* Microwave Robustness */
1511 lp->ltvRecord.len = 2;
1512 lp->ltvRecord.typ = CFG_CNF_MICRO_WAVE;
1513 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MicrowaveRobustness );
1514 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1516 /* Load Balancing */
1517 lp->ltvRecord.len = 2;
1518 lp->ltvRecord.typ = CFG_CNF_LOAD_BALANCING;
1519 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->loadBalancing );
1520 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1522 /* Medium Distribution */
1523 lp->ltvRecord.len = 2;
1524 lp->ltvRecord.typ = CFG_CNF_MEDIUM_DISTRIBUTION;
1525 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->mediumDistribution );
1526 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1530 /* Tx Power Level (for supported cards) */
1531 lp->ltvRecord.len = 2;
1532 lp->ltvRecord.typ = CFG_CNF_TX_POW_LVL;
1533 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->txPowLevel );
1534 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1536 /* Short Retry Limit */
1537 /*lp->ltvRecord.len = 2;
1538 lp->ltvRecord.typ = 0xFC32;
1539 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->shortRetryLimit );
1540 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1543 /* Long Retry Limit */
1544 /*lp->ltvRecord.len = 2;
1545 lp->ltvRecord.typ = 0xFC33;
1546 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->longRetryLimit );
1547 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1550 /* Supported Rate Set Control */
1551 lp->ltvRecord.len = 3;
1552 lp->ltvRecord.typ = CFG_SUPPORTED_RATE_SET_CNTL; //0xFC88;
1553 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->srsc[0] );
1554 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->srsc[1] );
1555 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1557 /* Basic Rate Set Control */
1558 lp->ltvRecord.len = 3;
1559 lp->ltvRecord.typ = CFG_BASIC_RATE_SET_CNTL; //0xFC89;
1560 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->brsc[0] );
1561 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->brsc[1] );
1562 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1564 /* Frame Burst Limit */
1565 /* Defined, but not currently available in Firmware */
1570 /* Multicast Rate */
1571 lp->ltvRecord.len = 3;
1572 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1573 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1574 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->MulticastRate[1] );
1576 lp->ltvRecord.len = 2;
1577 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1578 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1580 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1582 /* Own Name (Station Nickname) */
1583 if (( len = ( strlen( lp->StationName ) + 1 ) & ~0x01 ) != 0 ) {
1584 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : %s\n",
1585 // lp->StationName );
1587 lp->ltvRecord.len = 2 + ( len / sizeof( hcf_16 ));
1588 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1589 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->StationName ));
1591 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->StationName, len );
1593 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : EMPTY\n" );
1595 lp->ltvRecord.len = 2;
1596 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1597 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1600 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1602 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME result : 0x%04x\n",
1605 /* The following are set in STA mode only */
1606 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1609 lp->ltvRecord.len = 2;
1610 lp->ltvRecord.typ = CFG_RTS_THRH;
1611 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1612 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1615 lp->ltvRecord.len = 2;
1616 lp->ltvRecord.typ = CFG_CNF_PORT_TYPE;
1617 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PortType );
1618 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1620 /* Tx Rate Control */
1622 lp->ltvRecord.len = 3;
1623 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1624 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1625 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1627 lp->ltvRecord.len = 2;
1628 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1629 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1632 //;?skip temporarily to see whether the RID or something else is the probelm hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1634 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 2.4GHz : 0x%04x\n",
1635 lp->TxRateControl[0] );
1636 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 5.0GHz : 0x%04x\n",
1637 lp->TxRateControl[1] );
1638 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL result : 0x%04x\n",
1640 /* Power Management */
1641 lp->ltvRecord.len = 2;
1642 lp->ltvRecord.typ = CFG_CNF_PM_ENABLED;
1643 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PMEnabled );
1644 // lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0x8001 );
1645 DBG_TRACE( DbgInfo, "CFG_CNF_PM_ENABLED : 0x%04x\n", lp->PMEnabled );
1646 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1647 /* Multicast Receive */
1648 lp->ltvRecord.len = 2;
1649 lp->ltvRecord.typ = CFG_CNF_MCAST_RX;
1650 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastReceive );
1651 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1653 /* Max Sleep Duration */
1654 lp->ltvRecord.len = 2;
1655 lp->ltvRecord.typ = CFG_CNF_MAX_SLEEP_DURATION;
1656 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MaxSleepDuration );
1657 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1660 lp->ltvRecord.len = 2;
1661 lp->ltvRecord.typ = CFG_CREATE_IBSS;
1662 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->CreateIBSS );
1663 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1666 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1667 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1668 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1669 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : %s\n",
1670 // lp->NetworkName );
1672 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1673 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1674 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1676 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1678 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : ANY\n" );
1680 lp->ltvRecord.len = 2;
1681 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1682 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1685 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1687 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID result : 0x%04x\n",
1689 /* Own ATIM window */
1690 lp->ltvRecord.len = 2;
1691 lp->ltvRecord.typ = CFG_CNF_OWN_ATIM_WINDOW;
1692 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->atimWindow );
1693 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1696 /* Holdover Duration */
1697 lp->ltvRecord.len = 2;
1698 lp->ltvRecord.typ = CFG_CNF_HOLDOVER_DURATION;
1699 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->holdoverDuration );
1700 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1702 /* Promiscuous Mode */
1703 lp->ltvRecord.len = 2;
1704 lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
1705 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->promiscuousMode );
1706 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1708 /* Authentication */
1709 lp->ltvRecord.len = 2;
1710 lp->ltvRecord.typ = CFG_CNF_AUTHENTICATION;
1711 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->authentication );
1712 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1714 /* Connection Control */
1715 lp->ltvRecord.len = 2;
1716 lp->ltvRecord.typ = CFG_CNF_CONNECTION_CNTL;
1717 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->connectionControl );
1718 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1722 /* Probe data rate */
1723 /*lp->ltvRecord.len = 3;
1724 lp->ltvRecord.typ = CFG_PROBE_DATA_RATE;
1725 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->probeDataRates[0] );
1726 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->probeDataRates[1] );
1727 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1729 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 2.4GHz : 0x%04x\n",
1730 lp->probeDataRates[0] );
1731 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 5.0GHz : 0x%04x\n",
1732 lp->probeDataRates[1] );
1733 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE result : 0x%04x\n",
1737 /* The following are set in AP mode only */
1738 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
1739 //;?should we restore this to allow smaller memory footprint
1742 lp->ltvRecord.len = 2;
1743 lp->ltvRecord.typ = CFG_CNF_OWN_DTIM_PERIOD;
1744 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DTIMPeriod );
1745 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1747 /* Multicast PM Buffering */
1748 lp->ltvRecord.len = 2;
1749 lp->ltvRecord.typ = CFG_CNF_MCAST_PM_BUF;
1750 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->multicastPMBuffering );
1751 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1753 /* Reject ANY - Closed System */
1754 lp->ltvRecord.len = 2;
1755 lp->ltvRecord.typ = CFG_CNF_REJECT_ANY;
1756 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RejectAny );
1758 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1760 /* Exclude Unencrypted */
1761 lp->ltvRecord.len = 2;
1762 lp->ltvRecord.typ = CFG_CNF_EXCL_UNENCRYPTED;
1763 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ExcludeUnencrypted );
1765 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1767 /* IntraBSS Relay */
1768 lp->ltvRecord.len = 2;
1769 lp->ltvRecord.typ = CFG_CNF_INTRA_BSS_RELAY;
1770 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->intraBSSRelay );
1771 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1773 /* RTS Threshold 0 */
1774 lp->ltvRecord.len = 2;
1775 lp->ltvRecord.typ = CFG_RTS_THRH0;
1776 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1778 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1780 /* Tx Rate Control 0 */
1782 lp->ltvRecord.len = 3;
1783 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1784 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1785 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1787 lp->ltvRecord.len = 2;
1788 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1789 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1792 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1794 /* Own Beacon Interval */
1795 lp->ltvRecord.len = 2;
1796 lp->ltvRecord.typ = 0xFC31;
1797 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ownBeaconInterval );
1798 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1800 /* Co-Existence Behavior */
1801 lp->ltvRecord.len = 2;
1802 lp->ltvRecord.typ = 0xFCC7;
1803 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->coexistence );
1804 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1808 /* RTS Threshold 1 */
1809 lp->ltvRecord.len = 2;
1810 lp->ltvRecord.typ = CFG_RTS_THRH1;
1811 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].rtsThreshold );
1812 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1814 /* RTS Threshold 2 */
1815 lp->ltvRecord.len = 2;
1816 lp->ltvRecord.typ = CFG_RTS_THRH2;
1817 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].rtsThreshold );
1818 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1821 /* RTS Threshold 3 */
1822 lp->ltvRecord.len = 2;
1823 lp->ltvRecord.typ = CFG_RTS_THRH3;
1824 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].rtsThreshold );
1825 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1828 /* RTS Threshold 4 */
1829 lp->ltvRecord.len = 2;
1830 lp->ltvRecord.typ = CFG_RTS_THRH4;
1831 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].rtsThreshold );
1832 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1835 /* RTS Threshold 5 */
1836 lp->ltvRecord.len = 2;
1837 lp->ltvRecord.typ = CFG_RTS_THRH5;
1838 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].rtsThreshold );
1839 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1841 /* RTS Threshold 6 */
1842 lp->ltvRecord.len = 2;
1843 lp->ltvRecord.typ = CFG_RTS_THRH6;
1844 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].rtsThreshold );
1845 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1847 /* TX Rate Control 1 */
1848 lp->ltvRecord.len = 2;
1849 lp->ltvRecord.typ = CFG_TX_RATE_CNTL1;
1850 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].txRateCntl );
1851 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1853 /* TX Rate Control 2 */
1854 lp->ltvRecord.len = 2;
1855 lp->ltvRecord.typ = CFG_TX_RATE_CNTL2;
1856 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].txRateCntl );
1857 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1859 /* TX Rate Control 3 */
1860 lp->ltvRecord.len = 2;
1861 lp->ltvRecord.typ = CFG_TX_RATE_CNTL3;
1862 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].txRateCntl );
1863 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1865 /* TX Rate Control 4 */
1866 lp->ltvRecord.len = 2;
1867 lp->ltvRecord.typ = CFG_TX_RATE_CNTL4;
1868 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].txRateCntl );
1869 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1871 /* TX Rate Control 5 */
1872 lp->ltvRecord.len = 2;
1873 lp->ltvRecord.typ = CFG_TX_RATE_CNTL5;
1874 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].txRateCntl );
1875 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1877 /* TX Rate Control 6 */
1878 lp->ltvRecord.len = 2;
1879 lp->ltvRecord.typ = CFG_TX_RATE_CNTL6;
1880 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].txRateCntl );
1881 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1885 /* WDS addresses. It's okay to blindly send these parameters, because
1886 the port needs to be enabled, before anything is done with it. */
1889 lp->ltvRecord.len = 4;
1890 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR1;
1892 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[0].wdsAddress, ETH_ALEN );
1893 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1896 lp->ltvRecord.len = 4;
1897 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR2;
1899 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[1].wdsAddress, ETH_ALEN );
1900 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1903 lp->ltvRecord.len = 4;
1904 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR3;
1906 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[2].wdsAddress, ETH_ALEN );
1907 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1910 lp->ltvRecord.len = 4;
1911 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR4;
1913 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[3].wdsAddress, ETH_ALEN );
1914 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1917 lp->ltvRecord.len = 4;
1918 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR5;
1920 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[4].wdsAddress, ETH_ALEN );
1921 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1924 lp->ltvRecord.len = 4;
1925 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR6;
1927 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[5].wdsAddress, ETH_ALEN );
1928 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1929 #endif /* USE_WDS */
1930 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1933 /* Own MAC Address */
1935 DBG_TRACE(DbgInfo, "MAC Address : %pM\n",
1939 if ( WVLAN_VALID_MAC_ADDRESS( lp->MACAddress )) {
1940 /* Make the MAC address valid by:
1941 Clearing the multicast bit
1942 Setting the local MAC address bit
1944 //lp->MACAddress[0] &= ~0x03; //;?why is this commented out already in 720
1945 //lp->MACAddress[0] |= 0x02;
1947 lp->ltvRecord.len = 1 + ( ETH_ALEN / sizeof( hcf_16 ));
1948 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1949 //DBG_TRACE( DbgInfo, "CFG_NIC_MAC_ADDR\n" );
1950 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1952 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_MAC_ADDR\n" );
1953 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1955 /* MAC address is byte aligned, no endian conversion needed */
1956 memcpy( &( lp->ltvRecord.u.u8[0] ), lp->MACAddress, ETH_ALEN );
1957 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1958 //DBG_TRACE( DbgInfo, "CFG_XXX_MAC_ADDR result : 0x%04x\n",
1961 /* Update the MAC address in the netdevice struct */
1962 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN ); //;?what is the purpose of this seemingly complex logic
1965 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1966 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1967 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1968 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : %s\n",
1969 // lp->NetworkName );
1970 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1971 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1972 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1974 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1976 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : ANY\n" );
1977 lp->ltvRecord.len = 2;
1978 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1979 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1982 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1984 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID result : 0x%04x\n",
1986 /* enable/disable encryption */
1987 lp->ltvRecord.len = 2;
1988 lp->ltvRecord.typ = CFG_CNF_ENCRYPTION;
1989 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->EnableEncryption );
1990 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1992 /* Set the Authentication Key Management Suite */
1993 lp->ltvRecord.len = 2;
1994 lp->ltvRecord.typ = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
1995 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->AuthKeyMgmtSuite );
1996 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1998 /* If WEP (or no) keys are being used, write (or clear) them */
1999 if (lp->wext_enc != IW_ENCODE_ALG_TKIP)
2000 wl_set_wep_keys(lp);
2003 /* countryInfo, ltvCountryInfo, CFG_CNF_COUNTRY_INFO */
2005 DBG_LEAVE( DbgInfo );
2008 /*============================================================================*/
2011 /*******************************************************************************
2013 *******************************************************************************
2017 * Load the kernel module.
2026 * an errno value otherwise
2028 ******************************************************************************/
2029 static int __init wl_module_init( void )
2032 /*------------------------------------------------------------------------*/
2034 DBG_FUNC( "wl_module_init" );
2037 /* Convert "standard" PCMCIA parameter pc_debug to a reasonable DebugFlag value.
2038 * NOTE: The values all fall through to the lower values. */
2039 DbgInfo->DebugFlag = 0;
2040 DbgInfo->DebugFlag = DBG_TRACE_ON; //;?get this mess resolved one day
2041 if ( pc_debug ) switch( pc_debug ) {
2043 DbgInfo->DebugFlag |= DBG_DS_ON;
2045 DbgInfo->DebugFlag |= DBG_RX_ON | DBG_TX_ON;
2047 DbgInfo->DebugFlag |= DBG_PARAM_ON;
2049 DbgInfo->DebugFlag |= DBG_TRACE_ON;
2051 DbgInfo->DebugFlag |= DBG_VERBOSE_ON;
2053 DbgInfo->DebugFlag |= DBG_DEFAULTS;
2059 DBG_ENTER( DbgInfo );
2060 printk(KERN_INFO "%s\n", VERSION_INFO);
2061 printk(KERN_INFO "*** Modified for kernel 2.6 by Henk de Groot <pe1dnn@amsat.org>\n");
2062 printk(KERN_INFO "*** Based on 7.18 version by Andrey Borzenkov <arvidjaar@mail.ru> $Revision: 39 $\n");
2065 // ;?#if (HCF_TYPE) & HCF_TYPE_AP
2066 // DBG_PRINT( "Access Point Mode (AP) Support: YES\n" );
2068 // DBG_PRINT( "Access Point Mode (AP) Support: NO\n" );
2069 // #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2071 result = wl_adapter_init_module( );
2072 DBG_LEAVE( DbgInfo );
2075 /*============================================================================*/
2078 /*******************************************************************************
2080 *******************************************************************************
2084 * Unload the kernel module.
2094 ******************************************************************************/
2095 static void __exit wl_module_exit( void )
2097 DBG_FUNC( "wl_module_exit" );
2100 wl_adapter_cleanup_module( );
2101 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
2102 remove_proc_entry( "wlags", NULL ); //;?why so a-symmetric compared to location of create_proc_read_entry
2105 DBG_LEAVE( DbgInfo );
2108 /*============================================================================*/
2110 module_init(wl_module_init);
2111 module_exit(wl_module_exit);
2113 /*******************************************************************************
2115 *******************************************************************************
2119 * The Interrupt Service Routine for the driver.
2123 * irq - the irq the interrupt came in on
2124 * dev_id - a buffer containing information about the request
2131 ******************************************************************************/
2132 irqreturn_t wl_isr( int irq, void *dev_id, struct pt_regs *regs )
2135 struct net_device *dev = (struct net_device *) dev_id;
2136 struct wl_private *lp = NULL;
2137 /*------------------------------------------------------------------------*/
2138 if (( dev == NULL ) || ( !netif_device_present( dev ))) {
2142 /* Set the wl_private pointer (lp), now that we know that dev is non-null */
2146 if ( lp->useRTS == 1 ) {
2147 DBG_PRINT( "EXITING ISR, IN RTS MODE...\n" );
2150 #endif /* USE_RTS */
2152 /* If we have interrupts pending, then put them on a system task
2153 queue. Otherwise turn interrupts back on */
2154 events = hcf_action( &lp->hcfCtx, HCF_ACT_INT_OFF );
2156 if ( events == HCF_INT_PENDING ) {
2157 /* Schedule the ISR handler as a bottom-half task in the
2158 tq_immediate queue */
2159 tasklet_schedule(&lp->task);
2161 //DBG_PRINT( "NOT OUR INTERRUPT\n" );
2162 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2165 return IRQ_RETVAL(events == HCF_INT_PENDING);
2167 /*============================================================================*/
2170 /*******************************************************************************
2172 *******************************************************************************
2176 * The ISR handler, scheduled to run in a deferred context by the ISR. This
2177 * is where the ISR's work actually gets done.
2181 * lp - a pointer to the device's private adapter structure
2187 ******************************************************************************/
2188 #define WVLAN_MAX_INT_SERVICES 50
2190 void wl_isr_handler( unsigned long p )
2192 struct net_device *dev;
2193 unsigned long flags;
2197 struct wl_private *lp = (struct wl_private *)p;
2198 /*------------------------------------------------------------------------*/
2201 DBG_PRINT( "wl_isr_handler lp adapter pointer is NULL!!!\n" );
2203 wl_lock( lp, &flags );
2205 dev = (struct net_device *)lp->dev;
2206 if ( dev != NULL && netif_device_present( dev ) ) stop = FALSE;
2207 for( count = 0; stop == FALSE && count < WVLAN_MAX_INT_SERVICES; count++ ) {
2209 result = hcf_service_nic( &lp->hcfCtx,
2210 (wci_bufp)lp->lookAheadBuf,
2211 sizeof( lp->lookAheadBuf ));
2212 if ( result == HCF_ERR_MIC ) {
2213 wl_wext_event_mic_failed( dev ); /* Send an event that MIC failed */
2214 //;?this seems wrong if HCF_ERR_MIC coincides with another event, stop gets FALSE
2215 //so why not do it always ;?
2218 #ifndef USE_MBOX_SYNC
2219 if ( lp->hcfCtx.IFB_MBInfoLen != 0 ) { /* anything in the mailbox */
2224 /* Check for a Link status event */
2225 if ( ( lp->hcfCtx.IFB_LinkStat & CFG_LINK_STAT_FW ) != 0 ) {
2226 wl_process_link_status( lp );
2229 /* Check for probe response events */
2230 if ( lp->ProbeResp.infoType != 0 &&
2231 lp->ProbeResp.infoType != 0xFFFF ) {
2232 wl_process_probe_response( lp );
2233 memset( &lp->ProbeResp, 0, sizeof( lp->ProbeResp ));
2234 lp->ProbeResp.infoType = 0xFFFF;
2237 /* Check for updated record events */
2238 if ( lp->updatedRecord.len != 0xFFFF ) {
2239 wl_process_updated_record( lp );
2240 lp->updatedRecord.len = 0xFFFF;
2243 /* Check for association status events */
2244 if ( lp->assoc_stat.len != 0xFFFF ) {
2245 wl_process_assoc_status( lp );
2246 lp->assoc_stat.len = 0xFFFF;
2249 /* Check for security status events */
2250 if ( lp->sec_stat.len != 0xFFFF ) {
2251 wl_process_security_status( lp );
2252 lp->sec_stat.len = 0xFFFF;
2257 if ( lp->use_dma ) {
2258 /* Check for DMA Rx packets */
2259 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_RDMAD ) {
2263 /* Return Tx DMA descriptors to host */
2264 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_TDMAD ) {
2265 wl_pci_dma_hcf_reclaim_tx( lp );
2270 #endif // ENABLE_DMA
2272 /* Check for Rx packets */
2273 if ( lp->hcfCtx.IFB_RxLen != 0 ) {
2277 /* Make sure that queued frames get sent */
2278 if ( wl_send( lp )) {
2283 /* We're done, so turn interrupts which were turned off in wl_isr, back on */
2284 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2285 wl_unlock( lp, &flags );
2289 /*============================================================================*/
2292 /*******************************************************************************
2294 *******************************************************************************
2298 * Notify the adapter that it has been removed. Since the adapter is gone,
2299 * we should no longer try to talk to it.
2303 * dev - a pointer to the device's net_device structure
2309 ******************************************************************************/
2310 void wl_remove( struct net_device *dev )
2312 struct wl_private *lp = wl_priv(dev);
2313 unsigned long flags;
2314 /*------------------------------------------------------------------------*/
2315 DBG_FUNC( "wl_remove" );
2316 DBG_ENTER( DbgInfo );
2318 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2320 wl_lock( lp, &flags );
2322 /* stop handling interrupts */
2323 wl_act_int_off( lp );
2324 lp->is_handling_int = WL_NOT_HANDLING_INT;
2327 * Disable the ports: just change state: since the
2328 * card is gone it is useless to talk to it and at
2329 * disconnect all state information is lost anyway.
2331 /* Reset portState */
2332 lp->portState = WVLAN_PORT_STATE_DISABLED;
2334 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
2336 //wl_disable_wds_ports( lp );
2338 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2340 /* Mark the device as unregistered */
2341 lp->is_registered = FALSE;
2343 /* Deregister the WDS ports as well */
2344 WL_WDS_NETDEV_DEREGISTER( lp );
2346 if ( lp->useRTS == 1 ) {
2347 wl_unlock( lp, &flags );
2349 DBG_LEAVE( DbgInfo );
2352 #endif /* USE_RTS */
2354 /* Inform the HCF that the card has been removed */
2355 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2357 wl_unlock( lp, &flags );
2359 DBG_LEAVE( DbgInfo );
2362 /*============================================================================*/
2365 /*******************************************************************************
2367 *******************************************************************************
2371 * Power-down and halt the adapter.
2375 * dev - a pointer to the device's net_device structure
2381 ******************************************************************************/
2382 void wl_suspend( struct net_device *dev )
2384 struct wl_private *lp = wl_priv(dev);
2385 unsigned long flags;
2386 /*------------------------------------------------------------------------*/
2387 DBG_FUNC( "wl_suspend" );
2388 DBG_ENTER( DbgInfo );
2390 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2392 /* The adapter is suspended:
2396 wl_lock( lp, &flags );
2398 /* Disable interrupt handling */
2399 wl_act_int_off( lp );
2402 wl_disconnect( lp );
2407 /* Disconnect from the adapter */
2408 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2410 /* Reset portState to be sure (should have been done by wl_disable */
2411 lp->portState = WVLAN_PORT_STATE_DISABLED;
2413 wl_unlock( lp, &flags );
2415 DBG_LEAVE( DbgInfo );
2418 /*============================================================================*/
2421 /*******************************************************************************
2423 *******************************************************************************
2427 * Resume a previously suspended adapter.
2431 * dev - a pointer to the device's net_device structure
2437 ******************************************************************************/
2438 void wl_resume(struct net_device *dev)
2440 struct wl_private *lp = wl_priv(dev);
2441 unsigned long flags;
2442 /*------------------------------------------------------------------------*/
2443 DBG_FUNC( "wl_resume" );
2444 DBG_ENTER( DbgInfo );
2446 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2448 wl_lock( lp, &flags );
2450 /* Connect to the adapter */
2451 hcf_connect( &lp->hcfCtx, dev->base_addr );
2453 /* Reset portState */
2454 lp->portState = WVLAN_PORT_STATE_DISABLED;
2456 /* Power might have been off, assume the card lost the firmware*/
2457 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
2459 /* Reload the firmware and restart */
2462 /* Resume interrupt handling */
2463 wl_act_int_on( lp );
2465 wl_unlock( lp, &flags );
2467 DBG_LEAVE( DbgInfo );
2470 /*============================================================================*/
2473 /*******************************************************************************
2475 *******************************************************************************
2479 * This function perfroms a check on the device and calls wl_remove() if
2480 * necessary. This function can be used for all bus types, but exists mostly
2481 * for the benefit of the Card Services driver, as there are times when
2482 * wl_remove() does not get called.
2486 * dev - a pointer to the device's net_device structure
2492 ******************************************************************************/
2493 void wl_release( struct net_device *dev )
2495 struct wl_private *lp = wl_priv(dev);
2496 /*------------------------------------------------------------------------*/
2497 DBG_FUNC( "wl_release" );
2498 DBG_ENTER( DbgInfo );
2500 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2501 /* If wl_remove() hasn't been called (i.e. when Card Services is shut
2502 down with the card in the slot), then call it */
2503 if ( lp->is_registered == TRUE ) {
2504 DBG_TRACE( DbgInfo, "Calling unregister_netdev(), as it wasn't called yet\n" );
2507 lp->is_registered = FALSE;
2510 DBG_LEAVE( DbgInfo );
2513 /*============================================================================*/
2516 /*******************************************************************************
2518 *******************************************************************************
2522 * Accessor function to retrieve the irq_mask module parameter
2530 * The irq_mask module parameter
2532 ******************************************************************************/
2533 p_u16 wl_get_irq_mask( void )
2536 } // wl_get_irq_mask
2537 /*============================================================================*/
2540 /*******************************************************************************
2542 *******************************************************************************
2546 * Accessor function to retrieve the irq_list module parameter
2554 * The irq_list module parameter
2556 ******************************************************************************/
2557 p_s8 * wl_get_irq_list( void )
2560 } // wl_get_irq_list
2561 /*============================================================================*/
2565 /*******************************************************************************
2567 *******************************************************************************
2571 * Used to enable MAC ports
2575 * lp - pointer to the device's private adapter structure
2581 ******************************************************************************/
2582 int wl_enable( struct wl_private *lp )
2584 int hcf_status = HCF_SUCCESS;
2585 /*------------------------------------------------------------------------*/
2586 DBG_FUNC( "wl_enable" );
2587 DBG_ENTER( DbgInfo );
2589 if ( lp->portState == WVLAN_PORT_STATE_ENABLED ) {
2590 DBG_TRACE( DbgInfo, "No action: Card already enabled\n" );
2591 } else if ( lp->portState == WVLAN_PORT_STATE_CONNECTED ) {
2592 //;?suspicuous logic, how can you be connected without being enabled so this is probably dead code
2593 DBG_TRACE( DbgInfo, "No action: Card already connected\n" );
2595 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_ENABLE );
2596 if ( hcf_status == HCF_SUCCESS ) {
2597 /* Set the status of the NIC to enabled */
2598 lp->portState = WVLAN_PORT_STATE_ENABLED; //;?bad mnemonic, NIC iso PORT
2600 if ( lp->use_dma ) {
2601 wl_pci_dma_hcf_supply( lp ); //;?always succes?
2606 if ( hcf_status != HCF_SUCCESS ) { //;?make this an assert
2607 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2609 DBG_LEAVE( DbgInfo );
2612 /*============================================================================*/
2616 /*******************************************************************************
2617 * wl_enable_wds_ports()
2618 *******************************************************************************
2622 * Used to enable the WDS MAC ports 1-6
2626 * lp - pointer to the device's private adapter structure
2632 ******************************************************************************/
2633 void wl_enable_wds_ports( struct wl_private * lp )
2636 DBG_FUNC( "wl_enable_wds_ports" );
2637 DBG_ENTER( DbgInfo );
2638 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2639 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2641 DBG_LEAVE( DbgInfo );
2643 } // wl_enable_wds_ports
2644 #endif /* USE_WDS */
2645 /*============================================================================*/
2648 /*******************************************************************************
2650 *******************************************************************************
2654 * Used to connect a MAC port
2658 * lp - pointer to the device's private adapter structure
2664 ******************************************************************************/
2665 int wl_connect( struct wl_private *lp )
2668 /*------------------------------------------------------------------------*/
2670 DBG_FUNC( "wl_connect" );
2671 DBG_ENTER( DbgInfo );
2673 if ( lp->portState != WVLAN_PORT_STATE_ENABLED ) {
2674 DBG_TRACE( DbgInfo, "No action: Not in enabled state\n" );
2675 DBG_LEAVE( DbgInfo );
2678 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_CONNECT );
2679 if ( hcf_status == HCF_SUCCESS ) {
2680 lp->portState = WVLAN_PORT_STATE_CONNECTED;
2682 DBG_LEAVE( DbgInfo );
2685 /*============================================================================*/
2688 /*******************************************************************************
2690 *******************************************************************************
2694 * Used to disconnect a MAC port
2698 * lp - pointer to the device's private adapter structure
2704 ******************************************************************************/
2705 int wl_disconnect( struct wl_private *lp )
2708 /*------------------------------------------------------------------------*/
2710 DBG_FUNC( "wl_disconnect" );
2711 DBG_ENTER( DbgInfo );
2713 if ( lp->portState != WVLAN_PORT_STATE_CONNECTED ) {
2714 DBG_TRACE( DbgInfo, "No action: Not in connected state\n" );
2715 DBG_LEAVE( DbgInfo );
2718 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISCONNECT );
2719 if ( hcf_status == HCF_SUCCESS ) {
2720 lp->portState = WVLAN_PORT_STATE_ENABLED;
2722 DBG_LEAVE( DbgInfo );
2725 /*============================================================================*/
2728 /*******************************************************************************
2730 *******************************************************************************
2734 * Used to disable MAC ports
2738 * lp - pointer to the device's private adapter structure
2739 * port - the MAC port to disable
2745 ******************************************************************************/
2746 int wl_disable( struct wl_private *lp )
2748 int hcf_status = HCF_SUCCESS;
2749 /*------------------------------------------------------------------------*/
2750 DBG_FUNC( "wl_disable" );
2751 DBG_ENTER( DbgInfo );
2753 if ( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
2754 DBG_TRACE( DbgInfo, "No action: Port state is disabled\n" );
2756 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISABLE );
2757 if ( hcf_status == HCF_SUCCESS ) {
2758 /* Set the status of the port to disabled */ //;?bad mnemonic use NIC iso PORT
2759 lp->portState = WVLAN_PORT_STATE_DISABLED;
2762 if ( lp->use_dma ) {
2763 wl_pci_dma_hcf_reclaim( lp );
2768 if ( hcf_status != HCF_SUCCESS ) {
2769 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2771 DBG_LEAVE( DbgInfo );
2774 /*============================================================================*/
2778 /*******************************************************************************
2779 * wl_disable_wds_ports()
2780 *******************************************************************************
2784 * Used to disable the WDS MAC ports 1-6
2788 * lp - pointer to the device's private adapter structure
2794 ******************************************************************************/
2795 void wl_disable_wds_ports( struct wl_private * lp )
2798 DBG_FUNC( "wl_disable_wds_ports" );
2799 DBG_ENTER( DbgInfo );
2801 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2802 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2804 // if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
2805 // wl_disable( lp, HCF_PORT_1 );
2806 // wl_disable( lp, HCF_PORT_2 );
2807 // wl_disable( lp, HCF_PORT_3 );
2808 // wl_disable( lp, HCF_PORT_4 );
2809 // wl_disable( lp, HCF_PORT_5 );
2810 // wl_disable( lp, HCF_PORT_6 );
2812 DBG_LEAVE( DbgInfo );
2814 } // wl_disable_wds_ports
2816 /*============================================================================*/
2819 #ifndef USE_MBOX_SYNC
2820 /*******************************************************************************
2822 *******************************************************************************
2825 * This function is used to read and process a mailbox message.
2830 * lp - pointer to the device's private adapter structure
2834 * an HCF status code
2836 ******************************************************************************/
2837 int wl_mbx( struct wl_private *lp )
2839 int hcf_status = HCF_SUCCESS;
2840 /*------------------------------------------------------------------------*/
2841 DBG_FUNC( "wl_mbx" );
2842 DBG_ENTER( DbgInfo );
2843 DBG_TRACE( DbgInfo, "Mailbox Info: IFB_MBInfoLen: %d\n",
2844 lp->hcfCtx.IFB_MBInfoLen );
2846 memset( &( lp->ltvRecord ), 0, sizeof( ltv_t ));
2848 lp->ltvRecord.len = MB_SIZE;
2849 lp->ltvRecord.typ = CFG_MB_INFO;
2850 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2852 if ( hcf_status != HCF_SUCCESS ) {
2853 DBG_ERROR( DbgInfo, "hcf_get_info returned 0x%x\n", hcf_status );
2855 DBG_LEAVE( DbgInfo );
2859 if ( lp->ltvRecord.typ == CFG_MB_INFO ) {
2860 DBG_LEAVE( DbgInfo );
2863 /* Endian translate the mailbox data, then process the message */
2864 wl_endian_translate_mailbox( &( lp->ltvRecord ));
2865 wl_process_mailbox( lp );
2866 DBG_LEAVE( DbgInfo );
2869 /*============================================================================*/
2872 /*******************************************************************************
2873 * wl_endian_translate_mailbox()
2874 *******************************************************************************
2878 * This function will perform the tedious task of endian translating all
2879 * fields withtin a mailbox message which need translating.
2883 * ltv - pointer to the LTV to endian translate
2889 ******************************************************************************/
2890 void wl_endian_translate_mailbox( ltv_t *ltv )
2893 DBG_FUNC( "wl_endian_translate_mailbox" );
2894 DBG_ENTER( DbgInfo );
2895 switch( ltv->typ ) {
2902 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
2904 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2905 ( sizeof( SCAN_RS_STRCT )));
2907 while( num_aps >= 1 ) {
2910 aps[num_aps].channel_id =
2911 CNV_LITTLE_TO_INT( aps[num_aps].channel_id );
2913 aps[num_aps].noise_level =
2914 CNV_LITTLE_TO_INT( aps[num_aps].noise_level );
2916 aps[num_aps].signal_level =
2917 CNV_LITTLE_TO_INT( aps[num_aps].signal_level );
2919 aps[num_aps].beacon_interval_time =
2920 CNV_LITTLE_TO_INT( aps[num_aps].beacon_interval_time );
2922 aps[num_aps].capability =
2923 CNV_LITTLE_TO_INT( aps[num_aps].capability );
2925 aps[num_aps].ssid_len =
2926 CNV_LITTLE_TO_INT( aps[num_aps].ssid_len );
2928 aps[num_aps].ssid_val[aps[num_aps].ssid_len] = 0;
2935 PROBE_RESP *probe_resp = (PROBE_RESP *)ltv;
2937 probe_resp->frameControl = CNV_LITTLE_TO_INT( probe_resp->frameControl );
2938 probe_resp->durID = CNV_LITTLE_TO_INT( probe_resp->durID );
2939 probe_resp->sequence = CNV_LITTLE_TO_INT( probe_resp->sequence );
2940 probe_resp->dataLength = CNV_LITTLE_TO_INT( probe_resp->dataLength );
2942 probe_resp->lenType = CNV_LITTLE_TO_INT( probe_resp->lenType );
2944 probe_resp->beaconInterval = CNV_LITTLE_TO_INT( probe_resp->beaconInterval );
2945 probe_resp->capability = CNV_LITTLE_TO_INT( probe_resp->capability );
2946 probe_resp->flags = CNV_LITTLE_TO_INT( probe_resp->flags );
2951 #define ls ((LINK_STATUS_STRCT *)ltv)
2952 ls->linkStatus = CNV_LITTLE_TO_INT( ls->linkStatus );
2956 case CFG_ASSOC_STAT:
2958 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
2960 as->assocStatus = CNV_LITTLE_TO_INT( as->assocStatus );
2964 case CFG_SECURITY_STAT:
2966 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
2968 ss->securityStatus = CNV_LITTLE_TO_INT( ss->securityStatus );
2969 ss->reason = CNV_LITTLE_TO_INT( ss->reason );
2983 DBG_LEAVE( DbgInfo );
2985 } // wl_endian_translate_mailbox
2986 /*============================================================================*/
2988 /*******************************************************************************
2989 * wl_process_mailbox()
2990 *******************************************************************************
2994 * This function will process the mailbox data.
2998 * ltv - pointer to the LTV to be processed.
3004 ******************************************************************************/
3005 void wl_process_mailbox( struct wl_private *lp )
3008 hcf_16 ltv_val = 0xFFFF;
3009 /*------------------------------------------------------------------------*/
3010 DBG_FUNC( "wl_process_mailbox" );
3011 DBG_ENTER( DbgInfo );
3012 ltv = &( lp->ltvRecord );
3014 switch( ltv->typ ) {
3017 DBG_TRACE( DbgInfo, "CFG_TALLIES\n" );
3020 DBG_TRACE( DbgInfo, "CFG_SCAN\n" );
3024 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
3026 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
3027 ( sizeof( SCAN_RS_STRCT )));
3029 lp->scan_results.num_aps = num_aps;
3031 DBG_TRACE( DbgInfo, "Number of APs: %d\n", num_aps );
3033 while( num_aps >= 1 ) {
3036 DBG_TRACE( DbgInfo, "AP : %d\n", num_aps );
3037 DBG_TRACE( DbgInfo, "=========================\n" );
3038 DBG_TRACE( DbgInfo, "Channel ID : 0x%04x\n",
3039 aps[num_aps].channel_id );
3040 DBG_TRACE( DbgInfo, "Noise Level : 0x%04x\n",
3041 aps[num_aps].noise_level );
3042 DBG_TRACE( DbgInfo, "Signal Level : 0x%04x\n",
3043 aps[num_aps].signal_level );
3044 DBG_TRACE( DbgInfo, "Beacon Interval : 0x%04x\n",
3045 aps[num_aps].beacon_interval_time );
3046 DBG_TRACE( DbgInfo, "Capability : 0x%04x\n",
3047 aps[num_aps].capability );
3048 DBG_TRACE( DbgInfo, "SSID Length : 0x%04x\n",
3049 aps[num_aps].ssid_len );
3050 DBG_TRACE(DbgInfo, "BSSID : %pM\n",
3051 aps[num_aps].bssid);
3053 if ( aps[num_aps].ssid_len != 0 ) {
3054 DBG_TRACE( DbgInfo, "SSID : %s.\n",
3055 aps[num_aps].ssid_val );
3057 DBG_TRACE( DbgInfo, "SSID : %s.\n", "ANY" );
3060 DBG_TRACE( DbgInfo, "\n" );
3062 /* Copy the info to the ScanResult structure in the private
3064 memcpy( &( lp->scan_results.APTable[num_aps]), &( aps[num_aps] ),
3065 sizeof( SCAN_RS_STRCT ));
3068 /* Set scan result to true so that any scan requests will
3070 lp->scan_results.scan_complete = TRUE;
3075 DBG_TRACE( DbgInfo, "CFG_ACS_SCAN\n" );
3078 PROBE_RESP *probe_rsp = (PROBE_RESP *)ltv;
3079 hcf_8 *wpa_ie = NULL;
3080 hcf_16 wpa_ie_len = 0;
3082 DBG_TRACE( DbgInfo, "(%s) =========================\n",
3085 DBG_TRACE( DbgInfo, "(%s) length : 0x%04x.\n",
3086 lp->dev->name, probe_rsp->length );
3088 if ( probe_rsp->length > 1 ) {
3089 DBG_TRACE( DbgInfo, "(%s) infoType : 0x%04x.\n",
3090 lp->dev->name, probe_rsp->infoType );
3092 DBG_TRACE( DbgInfo, "(%s) signal : 0x%02x.\n",
3093 lp->dev->name, probe_rsp->signal );
3095 DBG_TRACE( DbgInfo, "(%s) silence : 0x%02x.\n",
3096 lp->dev->name, probe_rsp->silence );
3098 DBG_TRACE( DbgInfo, "(%s) rxFlow : 0x%02x.\n",
3099 lp->dev->name, probe_rsp->rxFlow );
3101 DBG_TRACE( DbgInfo, "(%s) rate : 0x%02x.\n",
3102 lp->dev->name, probe_rsp->rate );
3104 DBG_TRACE( DbgInfo, "(%s) frame cntl : 0x%04x.\n",
3105 lp->dev->name, probe_rsp->frameControl );
3107 DBG_TRACE( DbgInfo, "(%s) durID : 0x%04x.\n",
3108 lp->dev->name, probe_rsp->durID );
3110 DBG_TRACE(DbgInfo, "(%s) address1 : %pM\n",
3111 lp->dev->name, probe_rsp->address1);
3113 DBG_TRACE(DbgInfo, "(%s) address2 : %pM\n",
3114 lp->dev->name, probe_rsp->address2);
3116 DBG_TRACE(DbgInfo, "(%s) BSSID : %pM\n",
3117 lp->dev->name, probe_rsp->BSSID);
3119 DBG_TRACE( DbgInfo, "(%s) sequence : 0x%04x.\n",
3120 lp->dev->name, probe_rsp->sequence );
3122 DBG_TRACE(DbgInfo, "(%s) address4 : %pM\n",
3123 lp->dev->name, probe_rsp->address4);
3125 DBG_TRACE( DbgInfo, "(%s) datalength : 0x%04x.\n",
3126 lp->dev->name, probe_rsp->dataLength );
3128 DBG_TRACE(DbgInfo, "(%s) DA : %pM\n",
3129 lp->dev->name, probe_rsp->DA);
3131 DBG_TRACE(DbgInfo, "(%s) SA : %pM\n",
3132 lp->dev->name, probe_rsp->SA);
3134 //DBG_TRACE( DbgInfo, "(%s) lenType : 0x%04x.\n",
3135 // lp->dev->name, probe_rsp->lenType );
3137 DBG_TRACE(DbgInfo, "(%s) timeStamp : "
3138 "%d.%d.%d.%d.%d.%d.%d.%d\n",
3140 probe_rsp->timeStamp[0],
3141 probe_rsp->timeStamp[1],
3142 probe_rsp->timeStamp[2],
3143 probe_rsp->timeStamp[3],
3144 probe_rsp->timeStamp[4],
3145 probe_rsp->timeStamp[5],
3146 probe_rsp->timeStamp[6],
3147 probe_rsp->timeStamp[7]);
3149 DBG_TRACE( DbgInfo, "(%s) beaconInt : 0x%04x.\n",
3150 lp->dev->name, probe_rsp->beaconInterval );
3152 DBG_TRACE( DbgInfo, "(%s) capability : 0x%04x.\n",
3153 lp->dev->name, probe_rsp->capability );
3155 DBG_TRACE( DbgInfo, "(%s) SSID len : 0x%04x.\n",
3156 lp->dev->name, probe_rsp->rawData[1] );
3158 if ( probe_rsp->rawData[1] > 0 ) {
3159 char ssid[HCF_MAX_NAME_LEN];
3161 memset( ssid, 0, sizeof( ssid ));
3162 strncpy( ssid, &probe_rsp->rawData[2],
3163 probe_rsp->rawData[1] );
3165 DBG_TRACE( DbgInfo, "(%s) SSID : %s\n",
3166 lp->dev->name, ssid );
3169 /* Parse out the WPA-IE, if one exists */
3170 wpa_ie = wl_parse_wpa_ie( probe_rsp, &wpa_ie_len );
3171 if ( wpa_ie != NULL ) {
3172 DBG_TRACE( DbgInfo, "(%s) WPA-IE : %s\n",
3173 lp->dev->name, wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
3176 DBG_TRACE( DbgInfo, "(%s) flags : 0x%04x.\n",
3177 lp->dev->name, probe_rsp->flags );
3180 DBG_TRACE( DbgInfo, "\n\n" );
3181 /* If probe response length is 1, then the scan is complete */
3182 if ( probe_rsp->length == 1 ) {
3183 DBG_TRACE( DbgInfo, "SCAN COMPLETE\n" );
3184 lp->probe_results.num_aps = lp->probe_num_aps;
3185 lp->probe_results.scan_complete = TRUE;
3187 /* Reset the counter for the next scan request */
3188 lp->probe_num_aps = 0;
3190 /* Send a wireless extensions event that the scan completed */
3191 wl_wext_event_scan_complete( lp->dev );
3193 /* Only copy to the table if the entry is unique; APs sometimes
3194 respond more than once to a probe */
3195 if ( lp->probe_num_aps == 0 ) {
3196 /* Copy the info to the ScanResult structure in the private
3198 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3199 probe_rsp, sizeof( PROBE_RESP ));
3201 /* Increment the number of APs detected */
3202 lp->probe_num_aps++;
3207 for( count = 0; count < lp->probe_num_aps; count++ ) {
3208 if ( memcmp( &( probe_rsp->BSSID ),
3209 lp->probe_results.ProbeTable[count].BSSID,
3216 /* Copy the info to the ScanResult structure in the
3217 private adapter struct. Only copy if there's room in the
3219 if ( lp->probe_num_aps < MAX_NAPS )
3221 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3222 probe_rsp, sizeof( PROBE_RESP ));
3226 DBG_WARNING( DbgInfo, "Num of scan results exceeds storage, truncating\n" );
3229 /* Increment the number of APs detected. Note I do this
3230 here even when I don't copy the probe response to the
3231 buffer in order to detect the overflow condition */
3232 lp->probe_num_aps++;
3241 #define ls ((LINK_STATUS_STRCT *)ltv)
3242 DBG_TRACE( DbgInfo, "CFG_LINK_STAT\n" );
3244 switch( ls->linkStatus ) {
3246 DBG_TRACE( DbgInfo, "Link Status : Connected\n" );
3247 wl_wext_event_ap( lp->dev );
3251 DBG_TRACE( DbgInfo, "Link Status : Disconnected\n" );
3255 DBG_TRACE( DbgInfo, "Link Status : Access Point Change\n" );
3259 DBG_TRACE( DbgInfo, "Link Status : Access Point Out of Range\n" );
3263 DBG_TRACE( DbgInfo, "Link Status : Access Point In Range\n" );
3267 DBG_TRACE( DbgInfo, "Link Status : UNKNOWN (0x%04x)\n",
3275 case CFG_ASSOC_STAT:
3276 DBG_TRACE( DbgInfo, "CFG_ASSOC_STAT\n" );
3279 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
3281 switch( as->assocStatus ) {
3283 DBG_TRACE( DbgInfo, "Association Status : STA Associated\n" );
3287 DBG_TRACE( DbgInfo, "Association Status : STA Reassociated\n" );
3291 DBG_TRACE( DbgInfo, "Association Status : STA Disassociated\n" );
3295 DBG_TRACE( DbgInfo, "Association Status : UNKNOWN (0x%04x)\n",
3300 DBG_TRACE(DbgInfo, "STA Address : %pM\n",
3303 if (( as->assocStatus == 2 ) && ( as->len == 8 )) {
3304 DBG_TRACE(DbgInfo, "Old AP Address : %pM\n",
3311 case CFG_SECURITY_STAT:
3312 DBG_TRACE( DbgInfo, "CFG_SECURITY_STAT\n" );
3315 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
3317 switch( ss->securityStatus ) {
3319 DBG_TRACE( DbgInfo, "Security Status : Dissassociate [AP]\n" );
3323 DBG_TRACE( DbgInfo, "Security Status : Deauthenticate [AP]\n" );
3327 DBG_TRACE( DbgInfo, "Security Status : Authenticate Fail [STA] or [AP]\n" );
3331 DBG_TRACE( DbgInfo, "Security Status : MIC Fail\n" );
3335 DBG_TRACE( DbgInfo, "Security Status : Associate Fail\n" );
3339 DBG_TRACE( DbgInfo, "Security Status : UNKNOWN %d\n",
3340 ss->securityStatus );
3344 DBG_TRACE(DbgInfo, "STA Address : %pM\n",
3347 DBG_TRACE(DbgInfo, "Reason : 0x%04x\n",
3354 DBG_TRACE( DbgInfo, "CFG_WMP, size is %d bytes\n", ltv->len );
3356 WMP_RSP_STRCT *wmp_rsp = (WMP_RSP_STRCT *)ltv;
3358 DBG_TRACE( DbgInfo, "CFG_WMP, pdu type is 0x%x\n",
3359 wmp_rsp->wmpRsp.wmpHdr.type );
3361 switch( wmp_rsp->wmpRsp.wmpHdr.type ) {
3362 case WVLAN_WMP_PDU_TYPE_LT_RSP:
3365 LINKTEST_RSP_STRCT *lt_rsp = (LINKTEST_RSP_STRCT *)ltv;
3367 DBG_TRACE( DbgInfo, "LINK TEST RESULT\n" );
3368 DBG_TRACE( DbgInfo, "================\n" );
3369 DBG_TRACE( DbgInfo, "Length : %d.\n", lt_rsp->len );
3371 DBG_TRACE( DbgInfo, "Name : %s.\n", lt_rsp->ltRsp.ltRsp.name );
3372 DBG_TRACE( DbgInfo, "Signal Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.signal );
3373 DBG_TRACE( DbgInfo, "Noise Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.noise );
3374 DBG_TRACE( DbgInfo, "Receive Flow : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.rxFlow );
3375 DBG_TRACE( DbgInfo, "Data Rate : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRate );
3376 DBG_TRACE( DbgInfo, "Protocol : 0x%04x.\n", lt_rsp->ltRsp.ltRsp.protocol );
3377 DBG_TRACE( DbgInfo, "Station : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.station );
3378 DBG_TRACE( DbgInfo, "Data Rate Cap : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRateCap );
3380 DBG_TRACE( DbgInfo, "Power Mgmt : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3381 lt_rsp->ltRsp.ltRsp.powerMgmt[0],
3382 lt_rsp->ltRsp.ltRsp.powerMgmt[1],
3383 lt_rsp->ltRsp.ltRsp.powerMgmt[2],
3384 lt_rsp->ltRsp.ltRsp.powerMgmt[3] );
3386 DBG_TRACE( DbgInfo, "Robustness : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3387 lt_rsp->ltRsp.ltRsp.robustness[0],
3388 lt_rsp->ltRsp.ltRsp.robustness[1],
3389 lt_rsp->ltRsp.ltRsp.robustness[2],
3390 lt_rsp->ltRsp.ltRsp.robustness[3] );
3392 DBG_TRACE( DbgInfo, "Scaling : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.scaling );
3405 DBG_TRACE( DbgInfo, "CFG_NULL\n" );
3408 case CFG_UPDATED_INFO_RECORD: // Updated Information Record
3409 DBG_TRACE( DbgInfo, "UPDATED INFORMATION RECORD\n" );
3411 ltv_val = CNV_INT_TO_LITTLE( ltv->u.u16[0] );
3413 /* Check and see which RID was updated */
3415 case CFG_CUR_COUNTRY_INFO: // Indicate Passive Scan Completion
3416 DBG_TRACE( DbgInfo, "Updated country info\n" );
3418 /* Do I need to hold off on updating RIDs until the process is
3423 case CFG_PORT_STAT: // Wait for Connect Event
3429 DBG_WARNING( DbgInfo, "Unknown RID: 0x%04x\n", ltv_val );
3435 DBG_TRACE( DbgInfo, "UNKNOWN MESSAGE: 0x%04x\n", ltv->typ );
3438 DBG_LEAVE( DbgInfo );
3440 } // wl_process_mailbox
3441 /*============================================================================*/
3442 #endif /* ifndef USE_MBOX_SYNC */
3445 /*******************************************************************************
3446 * wl_wds_netdev_register()
3447 *******************************************************************************
3451 * This function registers net_device structures with the system's network
3452 * layer for use with the WDS ports.
3457 * lp - pointer to the device's private adapter structure
3463 ******************************************************************************/
3464 void wl_wds_netdev_register( struct wl_private *lp )
3467 /*------------------------------------------------------------------------*/
3468 DBG_FUNC( "wl_wds_netdev_register" );
3469 DBG_ENTER( DbgInfo );
3470 //;?why is there no USE_WDS clause like in wl_enable_wds_ports
3471 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3472 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3473 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3474 if ( register_netdev( lp->wds_port[count].dev ) != 0 ) {
3475 DBG_WARNING( DbgInfo, "net device for WDS port %d could not be registered\n",
3478 lp->wds_port[count].is_registered = TRUE;
3480 /* Fill out the net_device structs with the MAC addr */
3481 memcpy( lp->wds_port[count].dev->dev_addr, lp->MACAddress, ETH_ALEN );
3482 lp->wds_port[count].dev->addr_len = ETH_ALEN;
3486 DBG_LEAVE( DbgInfo );
3488 } // wl_wds_netdev_register
3489 /*============================================================================*/
3492 /*******************************************************************************
3493 * wl_wds_netdev_deregister()
3494 *******************************************************************************
3498 * This function deregisters the WDS net_device structures used by the
3499 * system's network layer.
3504 * lp - pointer to the device's private adapter structure
3510 ******************************************************************************/
3511 void wl_wds_netdev_deregister( struct wl_private *lp )
3514 /*------------------------------------------------------------------------*/
3515 DBG_FUNC( "wl_wds_netdev_deregister" );
3516 DBG_ENTER( DbgInfo );
3517 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3518 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3519 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3520 unregister_netdev( lp->wds_port[count].dev );
3522 lp->wds_port[count].is_registered = FALSE;
3525 DBG_LEAVE( DbgInfo );
3527 } // wl_wds_netdev_deregister
3528 /*============================================================================*/
3529 #endif /* USE_WDS */
3532 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
3534 * The proc filesystem: function to read and entry
3536 int printf_hcf_16( char *s, char *buf, hcf_16* p, int n );
3537 int printf_hcf_16( char *s, char *buf, hcf_16* p, int n ) {
3541 len = sprintf(buf, "%s", s );
3542 while ( len < 20 ) len += sprintf(buf+len, " " );
3543 len += sprintf(buf+len,": " );
3544 for ( i = 0; i < n; i++ ) {
3545 if ( len % 80 > 75 ) {
3546 len += sprintf(buf+len,"\n" );
3548 len += sprintf(buf+len,"%04X ", p[i] );
3550 len += sprintf(buf+len,"\n" );
3554 int printf_hcf_8( char *s, char *buf, hcf_8* p, int n );
3555 int printf_hcf_8( char *s, char *buf, hcf_8* p, int n ) {
3559 len = sprintf(buf, "%s", s );
3560 while ( len < 20 ) len += sprintf(buf+len, " " );
3561 len += sprintf(buf+len,": " );
3562 for ( i = 0; i <= n; i++ ) {
3563 if ( len % 80 > 77 ) {
3564 len += sprintf(buf+len,"\n" );
3566 len += sprintf(buf+len,"%02X ", p[i] );
3568 len += sprintf(buf+len,"\n" );
3572 int printf_strct( char *s, char *buf, hcf_16* p );
3573 int printf_strct( char *s, char *buf, hcf_16* p ) {
3577 len = sprintf(buf, "%s", s );
3578 while ( len < 20 ) len += sprintf(buf+len, " " );
3579 len += sprintf(buf+len,": " );
3580 for ( i = 0; i <= *p; i++ ) {
3581 if ( len % 80 > 75 ) {
3582 len += sprintf(buf+len,"\n" );
3584 len += sprintf(buf+len,"%04X ", p[i] );
3586 len += sprintf(buf+len,"\n" );
3590 int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data )
3592 struct wl_private *lp = NULL;
3594 CFG_HERMES_TALLIES_STRCT *p;
3596 #define LIMIT (PAGE_SIZE-80) /* don't print any more after this size */
3600 lp = ((struct net_device *)data)->priv;
3602 len += sprintf(buf+len,"No wl_private in scull_read_procmem\n" );
3603 } else if ( lp->wlags49_type == 0 ){
3605 len += sprintf(buf+len,"Magic: 0x%04X\n", ifbp->IFB_Magic );
3606 len += sprintf(buf+len,"IOBase: 0x%04X\n", ifbp->IFB_IOBase );
3607 len += sprintf(buf+len,"LinkStat: 0x%04X\n", ifbp->IFB_LinkStat );
3608 len += sprintf(buf+len,"DSLinkStat: 0x%04X\n", ifbp->IFB_DSLinkStat );
3609 len += sprintf(buf+len,"TickIni: 0x%08lX\n", ifbp->IFB_TickIni );
3610 len += sprintf(buf+len,"TickCnt: 0x%04X\n", ifbp->IFB_TickCnt );
3611 len += sprintf(buf+len,"IntOffCnt: 0x%04X\n", ifbp->IFB_IntOffCnt );
3612 len += printf_hcf_16( "IFB_FWIdentity", &buf[len],
3613 &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
3614 } else if ( lp->wlags49_type == 1 ) {
3615 len += sprintf(buf+len,"Channel: 0x%04X\n", lp->Channel );
3616 /****** len += sprintf(buf+len,"slock: %d\n", lp->slock ); */
3617 //x struct tq_struct "task: 0x%04X\n", lp->task );
3618 //x struct net_device_stats "stats: 0x%04X\n", lp->stats );
3620 //x struct iw_statistics "wstats: 0x%04X\n", lp->wstats );
3621 //x len += sprintf(buf+len,"spy_number: 0x%04X\n", lp->spy_number );
3622 //x u_char spy_address[IW_MAX_SPY][ETH_ALEN];
3623 //x struct iw_quality spy_stat[IW_MAX_SPY];
3624 #endif // WIRELESS_EXT
3625 len += sprintf(buf+len,"IFB: 0x%p\n", &lp->hcfCtx );
3626 len += sprintf(buf+len,"flags: %#.8lX\n", lp->flags ); //;?use this format from now on
3627 len += sprintf(buf+len,"DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
3629 len += sprintf(buf+len,"DebugFlag (DbgInfo): 0x%08lX\n", DbgInfo->DebugFlag );
3631 len += sprintf(buf+len,"is_registered: 0x%04X\n", lp->is_registered );
3632 //x CFG_DRV_INFO_STRCT "driverInfo: 0x%04X\n", lp->driverInfo );
3633 len += printf_strct( "driverInfo", &buf[len], (hcf_16*)&lp->driverInfo );
3634 //x CFG_IDENTITY_STRCT "driverIdentity: 0x%04X\n", lp->driverIdentity );
3635 len += printf_strct( "driverIdentity", &buf[len], (hcf_16*)&lp->driverIdentity );
3636 //x CFG_FW_IDENTITY_STRCT "StationIdentity: 0x%04X\n", lp->StationIdentity );
3637 len += printf_strct( "StationIdentity", &buf[len], (hcf_16*)&lp->StationIdentity );
3638 //x CFG_PRI_IDENTITY_STRCT "PrimaryIdentity: 0x%04X\n", lp->PrimaryIdentity );
3639 len += printf_strct( "PrimaryIdentity", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
3640 len += printf_strct( "PrimarySupplier", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRISup );
3641 //x CFG_PRI_IDENTITY_STRCT "NICIdentity: 0x%04X\n", lp->NICIdentity );
3642 len += printf_strct( "NICIdentity", &buf[len], (hcf_16*)&lp->NICIdentity );
3643 //x ltv_t "ltvRecord: 0x%04X\n", lp->ltvRecord );
3644 len += sprintf(buf+len,"txBytes: 0x%08lX\n", lp->txBytes );
3645 len += sprintf(buf+len,"maxPort: 0x%04X\n", lp->maxPort ); /* 0 for STA, 6 for AP */
3646 /* Elements used for async notification from hardware */
3647 //x RID_LOG_STRCT RidList[10];
3648 //x ltv_t "updatedRecord: 0x%04X\n", lp->updatedRecord );
3649 //x PROBE_RESP "ProbeResp: 0x%04X\n", lp->ProbeResp );
3650 //x ASSOC_STATUS_STRCT "assoc_stat: 0x%04X\n", lp->assoc_stat );
3651 //x SECURITY_STATUS_STRCT "sec_stat: 0x%04X\n", lp->sec_stat );
3652 //x u_char lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
3653 len += sprintf(buf+len,"PortType: 0x%04X\n", lp->PortType ); // 1 - 3 (1 [Normal] | 3 [AdHoc])
3654 len += sprintf(buf+len,"Channel: 0x%04X\n", lp->Channel ); // 0 - 14 (0)
3655 //x hcf_16 TxRateControl[2];
3656 len += sprintf(buf+len,"TxRateControl[2]: 0x%04X 0x%04X\n",
3657 lp->TxRateControl[0], lp->TxRateControl[1] );
3658 len += sprintf(buf+len,"DistanceBetweenAPs: 0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
3659 len += sprintf(buf+len,"RTSThreshold: 0x%04X\n", lp->RTSThreshold ); // 0 - 2347 (2347)
3660 len += sprintf(buf+len,"PMEnabled: 0x%04X\n", lp->PMEnabled ); // 0 - 2, 8001 - 8002 (0)
3661 len += sprintf(buf+len,"MicrowaveRobustness: 0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
3662 len += sprintf(buf+len,"CreateIBSS: 0x%04X\n", lp->CreateIBSS ); // 0 - 1 (0)
3663 len += sprintf(buf+len,"MulticastReceive: 0x%04X\n", lp->MulticastReceive ); // 0 - 1 (1)
3664 len += sprintf(buf+len,"MaxSleepDuration: 0x%04X\n", lp->MaxSleepDuration ); // 0 - 65535 (100)
3665 //x hcf_8 MACAddress[ETH_ALEN];
3666 len += printf_hcf_8( "MACAddress", &buf[len], lp->MACAddress, ETH_ALEN );
3667 //x char NetworkName[HCF_MAX_NAME_LEN+1];
3668 len += sprintf(buf+len,"NetworkName: %.32s\n", lp->NetworkName );
3669 //x char StationName[HCF_MAX_NAME_LEN+1];
3670 len += sprintf(buf+len,"EnableEncryption: 0x%04X\n", lp->EnableEncryption ); // 0 - 1 (0)
3671 //x char Key1[MAX_KEY_LEN+1];
3672 len += printf_hcf_8( "Key1", &buf[len], lp->Key1, MAX_KEY_LEN );
3673 //x char Key2[MAX_KEY_LEN+1];
3674 //x char Key3[MAX_KEY_LEN+1];
3675 //x char Key4[MAX_KEY_LEN+1];
3676 len += sprintf(buf+len,"TransmitKeyID: 0x%04X\n", lp->TransmitKeyID ); // 1 - 4 (1)
3677 //x CFG_DEFAULT_KEYS_STRCT "DefaultKeys: 0x%04X\n", lp->DefaultKeys );
3678 //x u_char mailbox[MB_SIZE];
3679 //x char szEncryption[MAX_ENC_LEN];
3680 len += sprintf(buf+len,"driverEnable: 0x%04X\n", lp->driverEnable );
3681 len += sprintf(buf+len,"wolasEnable: 0x%04X\n", lp->wolasEnable );
3682 len += sprintf(buf+len,"atimWindow: 0x%04X\n", lp->atimWindow );
3683 len += sprintf(buf+len,"holdoverDuration: 0x%04X\n", lp->holdoverDuration );
3684 //x hcf_16 MulticastRate[2];
3685 len += sprintf(buf+len,"authentication: 0x%04X\n", lp->authentication ); // is this AP specific?
3686 len += sprintf(buf+len,"promiscuousMode: 0x%04X\n", lp->promiscuousMode );
3687 len += sprintf(buf+len,"DownloadFirmware: 0x%04X\n", lp->DownloadFirmware ); // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
3688 len += sprintf(buf+len,"AuthKeyMgmtSuite: 0x%04X\n", lp->AuthKeyMgmtSuite );
3689 len += sprintf(buf+len,"loadBalancing: 0x%04X\n", lp->loadBalancing );
3690 len += sprintf(buf+len,"mediumDistribution: 0x%04X\n", lp->mediumDistribution );
3691 len += sprintf(buf+len,"txPowLevel: 0x%04X\n", lp->txPowLevel );
3692 // len += sprintf(buf+len,"shortRetryLimit: 0x%04X\n", lp->shortRetryLimit );
3693 // len += sprintf(buf+len,"longRetryLimit: 0x%04X\n", lp->longRetryLimit );
3696 len += sprintf(buf+len,"connectionControl: 0x%04X\n", lp->connectionControl );
3697 //x //hcf_16 probeDataRates[2];
3698 len += sprintf(buf+len,"ownBeaconInterval: 0x%04X\n", lp->ownBeaconInterval );
3699 len += sprintf(buf+len,"coexistence: 0x%04X\n", lp->coexistence );
3700 //x WVLAN_FRAME "txF: 0x%04X\n", lp->txF );
3701 //x WVLAN_LFRAME txList[DEFAULT_NUM_TX_FRAMES];
3702 //x struct list_head "txFree: 0x%04X\n", lp->txFree );
3703 //x struct list_head txQ[WVLAN_MAX_TX_QUEUES];
3704 len += sprintf(buf+len,"netif_queue_on: 0x%04X\n", lp->netif_queue_on );
3705 len += sprintf(buf+len,"txQ_count: 0x%04X\n", lp->txQ_count );
3706 //x DESC_STRCT "desc_rx: 0x%04X\n", lp->desc_rx );
3707 //x DESC_STRCT "desc_tx: 0x%04X\n", lp->desc_tx );
3708 //x WVLAN_PORT_STATE "portState: 0x%04X\n", lp->portState );
3709 //x ScanResult "scan_results: 0x%04X\n", lp->scan_results );
3710 //x ProbeResult "probe_results: 0x%04X\n", lp->probe_results );
3711 len += sprintf(buf+len,"probe_num_aps: 0x%04X\n", lp->probe_num_aps );
3712 len += sprintf(buf+len,"use_dma: 0x%04X\n", lp->use_dma );
3713 //x DMA_STRCT "dma: 0x%04X\n", lp->dma );
3715 len += sprintf(buf+len,"useRTS: 0x%04X\n", lp->useRTS );
3717 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
3718 //;?should we restore this to allow smaller memory footprint
3719 //;?I guess not. This should be brought under Debug mode only
3720 len += sprintf(buf+len,"DTIMPeriod: 0x%04X\n", lp->DTIMPeriod ); // 1 - 255 (1)
3721 len += sprintf(buf+len,"multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
3722 len += sprintf(buf+len,"RejectAny: 0x%04X\n", lp->RejectAny ); // 0 - 1 (0)
3723 len += sprintf(buf+len,"ExcludeUnencrypted: 0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
3724 len += sprintf(buf+len,"intraBSSRelay: 0x%04X\n", lp->intraBSSRelay );
3725 len += sprintf(buf+len,"wlags49_type: 0x%08lX\n", lp->wlags49_type );
3727 //x WVLAN_WDS_IF wds_port[NUM_WDS_PORTS];
3730 } else if ( lp->wlags49_type == 2 ){
3731 len += sprintf(buf+len,"tallies to be added\n" );
3732 //Hermes Tallies (IFB substructure) {
3733 p = &lp->hcfCtx.IFB_NIC_Tallies;
3734 len += sprintf(buf+len,"TxUnicastFrames: %08lX\n", p->TxUnicastFrames );
3735 len += sprintf(buf+len,"TxMulticastFrames: %08lX\n", p->TxMulticastFrames );
3736 len += sprintf(buf+len,"TxFragments: %08lX\n", p->TxFragments );
3737 len += sprintf(buf+len,"TxUnicastOctets: %08lX\n", p->TxUnicastOctets );
3738 len += sprintf(buf+len,"TxMulticastOctets: %08lX\n", p->TxMulticastOctets );
3739 len += sprintf(buf+len,"TxDeferredTransmissions: %08lX\n", p->TxDeferredTransmissions );
3740 len += sprintf(buf+len,"TxSingleRetryFrames: %08lX\n", p->TxSingleRetryFrames );
3741 len += sprintf(buf+len,"TxMultipleRetryFrames: %08lX\n", p->TxMultipleRetryFrames );
3742 len += sprintf(buf+len,"TxRetryLimitExceeded: %08lX\n", p->TxRetryLimitExceeded );
3743 len += sprintf(buf+len,"TxDiscards: %08lX\n", p->TxDiscards );
3744 len += sprintf(buf+len,"RxUnicastFrames: %08lX\n", p->RxUnicastFrames );
3745 len += sprintf(buf+len,"RxMulticastFrames: %08lX\n", p->RxMulticastFrames );
3746 len += sprintf(buf+len,"RxFragments: %08lX\n", p->RxFragments );
3747 len += sprintf(buf+len,"RxUnicastOctets: %08lX\n", p->RxUnicastOctets );
3748 len += sprintf(buf+len,"RxMulticastOctets: %08lX\n", p->RxMulticastOctets );
3749 len += sprintf(buf+len,"RxFCSErrors: %08lX\n", p->RxFCSErrors );
3750 len += sprintf(buf+len,"RxDiscardsNoBuffer: %08lX\n", p->RxDiscardsNoBuffer );
3751 len += sprintf(buf+len,"TxDiscardsWrongSA: %08lX\n", p->TxDiscardsWrongSA );
3752 len += sprintf(buf+len,"RxWEPUndecryptable: %08lX\n", p->RxWEPUndecryptable );
3753 len += sprintf(buf+len,"RxMsgInMsgFragments: %08lX\n", p->RxMsgInMsgFragments );
3754 len += sprintf(buf+len,"RxMsgInBadMsgFragments: %08lX\n", p->RxMsgInBadMsgFragments );
3755 len += sprintf(buf+len,"RxDiscardsWEPICVError: %08lX\n", p->RxDiscardsWEPICVError );
3756 len += sprintf(buf+len,"RxDiscardsWEPExcluded: %08lX\n", p->RxDiscardsWEPExcluded );
3757 #if (HCF_EXT) & HCF_EXT_TALLIES_FW
3759 #endif // HCF_EXT_TALLIES_FW
3760 } else if ( lp->wlags49_type & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3762 DbgInfo->DebugFlag = lp->wlags49_type & 0x7FFF;
3764 lp->wlags49_type = 0; //default to IFB again ;?
3766 len += sprintf(buf+len,"unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
3767 len += sprintf(buf+len,"0x0000 - IFB\n" );
3768 len += sprintf(buf+len,"0x0001 - wl_private\n" );
3769 len += sprintf(buf+len,"0x0002 - Tallies\n" );
3770 len += sprintf(buf+len,"0x8xxx - Change debufflag\n" );
3771 len += sprintf(buf+len,"ERROR 0001\nWARNING 0002\nNOTICE 0004\nTRACE 0008\n" );
3772 len += sprintf(buf+len,"VERBOSE 0010\nPARAM 0020\nBREAK 0040\nRX 0100\n" );
3773 len += sprintf(buf+len,"TX 0200\nDS 0400\n" );
3776 } // scull_read_procmem
3778 static void proc_write(const char *name, write_proc_t *w, void *data)
3780 struct proc_dir_entry * entry = create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
3782 entry->write_proc = w;
3787 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
3789 static char proc_number[11];
3790 unsigned int nr = 0;
3792 DBG_FUNC( "write_int" );
3793 DBG_ENTER( DbgInfo );
3797 } else if ( copy_from_user(proc_number, buffer, count) ) {
3801 proc_number[count] = 0;
3802 nr = simple_strtoul(proc_number , NULL, 0);
3803 *(unsigned int *)data = nr;
3804 if ( nr & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3806 DbgInfo->DebugFlag = nr & 0x7FFF;
3810 DBG_PRINT( "value: %08X\n", nr );
3811 DBG_LEAVE( DbgInfo );
3815 #endif /* SCULL_USE_PROC */
3818 #define RUN_AT(x) (jiffies+(x)) //"borrowed" from include/pcmcia/k_compat.h
3819 #define DS_OOR 0x8000 //Deepsleep OutOfRange Status
3821 lp->timer_oor_cnt = DS_OOR;
3822 init_timer( &lp->timer_oor );
3823 lp->timer_oor.function = timer_oor;
3824 lp->timer_oor.data = (unsigned long)lp;
3825 lp->timer_oor.expires = RUN_AT( 3 * HZ );
3826 add_timer( &lp->timer_oor );
3827 printk( "<5>wl_enable: %ld\n", jiffies ); //;?remove me 1 day
3830 /*******************************************************************************
3832 *******************************************************************************
3839 * arg - a u_long representing a pointer to a dev_link_t structure for the
3840 * device to be released.
3846 ******************************************************************************/
3847 void timer_oor( u_long arg )
3849 struct wl_private *lp = (struct wl_private *)arg;
3851 /*------------------------------------------------------------------------*/
3853 DBG_FUNC( "timer_oor" );
3854 DBG_ENTER( DbgInfo );
3855 DBG_PARAM( DbgInfo, "arg", "0x%08lx", arg );
3857 printk( "<5>timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt ); //;?remove me 1 day
3858 lp->timer_oor_cnt += 10;
3859 if ( (lp->timer_oor_cnt & ~DS_OOR) > 300 ) {
3860 lp->timer_oor_cnt = 300;
3862 lp->timer_oor_cnt |= DS_OOR;
3863 init_timer( &lp->timer_oor );
3864 lp->timer_oor.function = timer_oor;
3865 lp->timer_oor.data = (unsigned long)lp;
3866 lp->timer_oor.expires = RUN_AT( (lp->timer_oor_cnt & ~DS_OOR) * HZ );
3867 add_timer( &lp->timer_oor );
3869 DBG_LEAVE( DbgInfo );
3873 MODULE_LICENSE("Dual BSD/GPL");