1 /*******************************************************************************
3 * Wireless device driver for Linux (wlags49).
5 * Copyright (c) 1998-2003 Agere Systems Inc.
9 * Initially developed by TriplePoint, Inc.
10 * http://www.triplepoint.com
12 *------------------------------------------------------------------------------
14 * This file contains the main driver entry points and other adapter
17 *------------------------------------------------------------------------------
21 * This software is provided subject to the following terms and conditions,
22 * which you should read carefully before using the software. Using this
23 * software indicates your acceptance of these terms and conditions. If you do
24 * not agree with these terms and conditions, do not use the software.
26 * Copyright © 2003 Agere Systems Inc.
27 * All rights reserved.
29 * Redistribution and use in source or binary forms, with or without
30 * modifications, are permitted provided that the following conditions are met:
32 * . Redistributions of source code must retain the above copyright notice, this
33 * list of conditions and the following Disclaimer as comments in the code as
34 * well as in the documentation and/or other materials provided with the
37 * . Redistributions in binary form must reproduce the above copyright notice,
38 * this list of conditions and the following Disclaimer in the documentation
39 * and/or other materials provided with the distribution.
41 * . Neither the name of Agere Systems Inc. nor the names of the contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED
\93AS IS
\94 AND ANY EXPRESS OR IMPLIED WARRANTIES,
48 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
49 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
50 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
51 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
52 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
60 ******************************************************************************/
62 /*******************************************************************************
63 * constant definitions
64 ******************************************************************************/
66 /* Allow support for calling system fcns to access F/W image file */
67 #define __KERNEL_SYSCALLS__
69 /*******************************************************************************
71 ******************************************************************************/
72 #include <wl_version.h>
74 #include <linux/module.h>
75 #include <linux/proc_fs.h>
76 #include <linux/seq_file.h>
77 #include <linux/types.h>
78 #include <linux/kernel.h>
79 // #include <linux/sched.h>
80 // #include <linux/ptrace.h>
81 // #include <linux/slab.h>
82 // #include <linux/ctype.h>
83 // #include <linux/string.h>
84 // #include <linux/timer.h>
85 //#include <linux/interrupt.h>
86 // #include <linux/tqueue.h>
87 // #include <linux/in.h>
88 // #include <linux/delay.h>
89 // #include <asm/io.h>
90 // // #include <asm/bitops.h>
91 #include <linux/unistd.h>
92 #include <asm/uaccess.h>
94 #include <linux/netdevice.h>
95 #include <linux/etherdevice.h>
96 // #include <linux/skbuff.h>
97 // #include <linux/if_arp.h>
98 // #include <linux/ioport.h>
102 #include <linux/vmalloc.h>
110 //in order to get around:: wl_main.c:2229: `HREG_EV_RDMAD' undeclared (first use in this function)
114 #include <wl_internal.h>
117 #include <wl_netdev.h>
121 #include <wl_profile.h>
122 #endif /* USE_PROFILE */
126 #endif /* BUS_PCMCIA */
131 /*******************************************************************************
133 ******************************************************************************/
134 #define VALID_PARAM(C) \
138 printk(KERN_INFO "Wireless, parameter error: \"%s\"\n", #C); \
142 /*******************************************************************************
144 ******************************************************************************/
145 void wl_isr_handler( unsigned long p );
147 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
148 static int scull_read_procmem(struct seq_file *m, void *v);
149 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data);
152 * seq_file wrappers for procfile show routines.
154 static int scull_read_procmem_open(struct inode *inode, struct file *file)
156 return single_open(file, scull_read_procmem, PDE_DATA(inode));
159 static const struct file_operations scull_read_procmem_fops = {
160 .open = scull_read_procmem_open,
163 .release = single_release,
166 #endif /* SCULL_USE_PROC */
168 /*******************************************************************************
169 * module parameter definitions - set with 'insmod'
170 ******************************************************************************/
171 static p_u16 irq_mask = 0xdeb8; // IRQ3,4,5,7,9,10,11,12,14,15
172 static p_s8 irq_list[4] = { -1 };
175 MODULE_PARM(irq_mask, "h");
176 MODULE_PARM_DESC(irq_mask, "IRQ mask [0xdeb8]");
177 MODULE_PARM(irq_list, "1-4b");
178 MODULE_PARM_DESC(irq_list, "IRQ list [<irq_mask>]");
181 static p_u8 PARM_AUTHENTICATION = PARM_DEFAULT_AUTHENTICATION;
182 static p_u16 PARM_AUTH_KEY_MGMT_SUITE = PARM_DEFAULT_AUTH_KEY_MGMT_SUITE;
183 static p_u16 PARM_BRSC_2GHZ = PARM_DEFAULT_BRSC_2GHZ;
184 static p_u16 PARM_BRSC_5GHZ = PARM_DEFAULT_BRSC_5GHZ;
185 static p_u16 PARM_COEXISTENCE = PARM_DEFAULT_COEXISTENCE;
186 static p_u16 PARM_CONNECTION_CONTROL = PARM_DEFAULT_CONNECTION_CONTROL; //;?rename and move
187 static p_char *PARM_CREATE_IBSS = PARM_DEFAULT_CREATE_IBSS_STR;
188 static p_char *PARM_DESIRED_SSID = PARM_DEFAULT_SSID;
189 static p_char *PARM_DOWNLOAD_FIRMWARE = "";
190 static p_u16 PARM_ENABLE_ENCRYPTION = PARM_DEFAULT_ENABLE_ENCRYPTION;
191 static p_char *PARM_EXCLUDE_UNENCRYPTED = PARM_DEFAULT_EXCLUDE_UNENCRYPTED_STR;
192 static p_char *PARM_INTRA_BSS_RELAY = PARM_DEFAULT_INTRA_BSS_RELAY_STR;
193 static p_char *PARM_KEY1 = "";
194 static p_char *PARM_KEY2 = "";
195 static p_char *PARM_KEY3 = "";
196 static p_char *PARM_KEY4 = "";
197 static p_char *PARM_LOAD_BALANCING = PARM_DEFAULT_LOAD_BALANCING_STR;
198 static p_u16 PARM_MAX_SLEEP = PARM_DEFAULT_MAX_PM_SLEEP;
199 static p_char *PARM_MEDIUM_DISTRIBUTION = PARM_DEFAULT_MEDIUM_DISTRIBUTION_STR;
200 static p_char *PARM_MICROWAVE_ROBUSTNESS = PARM_DEFAULT_MICROWAVE_ROBUSTNESS_STR;
201 static p_char *PARM_MULTICAST_PM_BUFFERING = PARM_DEFAULT_MULTICAST_PM_BUFFERING_STR;
202 static p_u16 PARM_MULTICAST_RATE = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
203 static p_char *PARM_MULTICAST_RX = PARM_DEFAULT_MULTICAST_RX_STR;
204 static p_u8 PARM_NETWORK_ADDR[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
205 static p_u16 PARM_OWN_ATIM_WINDOW = PARM_DEFAULT_OWN_ATIM_WINDOW;
206 static p_u16 PARM_OWN_BEACON_INTERVAL = PARM_DEFAULT_OWN_BEACON_INTERVAL;
207 static p_u8 PARM_OWN_CHANNEL = PARM_DEFAULT_OWN_CHANNEL;
208 static p_u8 PARM_OWN_DTIM_PERIOD = PARM_DEFAULT_OWN_DTIM_PERIOD;
209 static p_char *PARM_OWN_NAME = PARM_DEFAULT_OWN_NAME;
210 static p_char *PARM_OWN_SSID = PARM_DEFAULT_SSID;
211 static p_u16 PARM_PM_ENABLED = WVLAN_PM_STATE_DISABLED;
212 static p_u16 PARM_PM_HOLDOVER_DURATION = PARM_DEFAULT_PM_HOLDOVER_DURATION;
213 static p_u8 PARM_PORT_TYPE = PARM_DEFAULT_PORT_TYPE;
214 static p_char *PARM_PROMISCUOUS_MODE = PARM_DEFAULT_PROMISCUOUS_MODE_STR;
215 static p_char *PARM_REJECT_ANY = PARM_DEFAULT_REJECT_ANY_STR;
217 static p_u16 PARM_RTS_THRESHOLD1 = PARM_DEFAULT_RTS_THRESHOLD;
218 static p_u16 PARM_RTS_THRESHOLD2 = PARM_DEFAULT_RTS_THRESHOLD;
219 static p_u16 PARM_RTS_THRESHOLD3 = PARM_DEFAULT_RTS_THRESHOLD;
220 static p_u16 PARM_RTS_THRESHOLD4 = PARM_DEFAULT_RTS_THRESHOLD;
221 static p_u16 PARM_RTS_THRESHOLD5 = PARM_DEFAULT_RTS_THRESHOLD;
222 static p_u16 PARM_RTS_THRESHOLD6 = PARM_DEFAULT_RTS_THRESHOLD;
224 static p_u16 PARM_RTS_THRESHOLD = PARM_DEFAULT_RTS_THRESHOLD;
225 static p_u16 PARM_SRSC_2GHZ = PARM_DEFAULT_SRSC_2GHZ;
226 static p_u16 PARM_SRSC_5GHZ = PARM_DEFAULT_SRSC_5GHZ;
227 static p_u8 PARM_SYSTEM_SCALE = PARM_DEFAULT_SYSTEM_SCALE;
228 static p_u8 PARM_TX_KEY = PARM_DEFAULT_TX_KEY;
229 static p_u16 PARM_TX_POW_LEVEL = PARM_DEFAULT_TX_POW_LEVEL;
231 static p_u16 PARM_TX_RATE1 = PARM_DEFAULT_TX_RATE_2GHZ;
232 static p_u16 PARM_TX_RATE2 = PARM_DEFAULT_TX_RATE_2GHZ;
233 static p_u16 PARM_TX_RATE3 = PARM_DEFAULT_TX_RATE_2GHZ;
234 static p_u16 PARM_TX_RATE4 = PARM_DEFAULT_TX_RATE_2GHZ;
235 static p_u16 PARM_TX_RATE5 = PARM_DEFAULT_TX_RATE_2GHZ;
236 static p_u16 PARM_TX_RATE6 = PARM_DEFAULT_TX_RATE_2GHZ;
238 static p_u16 PARM_TX_RATE = PARM_DEFAULT_TX_RATE_2GHZ;
240 static p_u8 PARM_WDS_ADDRESS1[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
241 static p_u8 PARM_WDS_ADDRESS2[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
242 static p_u8 PARM_WDS_ADDRESS3[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
243 static p_u8 PARM_WDS_ADDRESS4[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
244 static p_u8 PARM_WDS_ADDRESS5[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
245 static p_u8 PARM_WDS_ADDRESS6[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
250 MODULE_PARM(PARM_DESIRED_SSID, "s");
251 MODULE_PARM_DESC(PARM_DESIRED_SSID, "Network Name (<string>) [ANY]");
252 MODULE_PARM(PARM_OWN_SSID, "s");
253 MODULE_PARM_DESC(PARM_OWN_SSID, "Network Name (<string>) [ANY]");
254 MODULE_PARM(PARM_OWN_CHANNEL, "b");
255 MODULE_PARM_DESC(PARM_OWN_CHANNEL, "Channel (0 - 14) [0]");
256 MODULE_PARM(PARM_SYSTEM_SCALE, "b");
257 MODULE_PARM_DESC(PARM_SYSTEM_SCALE, "Distance Between APs (1 - 3) [1]");
258 MODULE_PARM(PARM_TX_RATE, "b");
259 MODULE_PARM_DESC(PARM_TX_RATE, "Transmit Rate Control");
260 MODULE_PARM(PARM_RTS_THRESHOLD, "h");
261 MODULE_PARM_DESC(PARM_RTS_THRESHOLD, "Medium Reservation (RTS/CTS Fragment Length) (256 - 2347) [2347]");
262 MODULE_PARM(PARM_MICROWAVE_ROBUSTNESS, "s");
263 MODULE_PARM_DESC(PARM_MICROWAVE_ROBUSTNESS, "Microwave Oven Robustness Enabled (<string> N or Y) [N]");
264 MODULE_PARM(PARM_OWN_NAME, "s");
265 MODULE_PARM_DESC(PARM_OWN_NAME, "Station Name (<string>) [Linux]");
267 MODULE_PARM(PARM_ENABLE_ENCRYPTION, "b");
268 MODULE_PARM_DESC(PARM_ENABLE_ENCRYPTION, "Encryption Mode (0 - 7) [0]");
270 MODULE_PARM(PARM_KEY1, "s");
271 MODULE_PARM_DESC(PARM_KEY1, "Data Encryption Key 1 (<string>) []");
272 MODULE_PARM(PARM_KEY2, "s");
273 MODULE_PARM_DESC(PARM_KEY2, "Data Encryption Key 2 (<string>) []");
274 MODULE_PARM(PARM_KEY3, "s");
275 MODULE_PARM_DESC(PARM_KEY3, "Data Encryption Key 3 (<string>) []");
276 MODULE_PARM(PARM_KEY4, "s");
277 MODULE_PARM_DESC(PARM_KEY4, "Data Encryption Key 4 (<string>) []");
278 MODULE_PARM(PARM_TX_KEY, "b");
279 MODULE_PARM_DESC(PARM_TX_KEY, "Transmit Key ID (1 - 4) [1]");
280 MODULE_PARM(PARM_MULTICAST_RATE, "b");
281 MODULE_PARM_DESC(PARM_MULTICAST_RATE, "Multicast Rate");
282 MODULE_PARM(PARM_DOWNLOAD_FIRMWARE, "s");
283 MODULE_PARM_DESC(PARM_DOWNLOAD_FIRMWARE, "filename of firmware image");
285 MODULE_PARM(PARM_AUTH_KEY_MGMT_SUITE, "b");
286 MODULE_PARM_DESC(PARM_AUTH_KEY_MGMT_SUITE, "Authentication Key Management suite (0-4) [0]");
288 MODULE_PARM(PARM_LOAD_BALANCING, "s");
289 MODULE_PARM_DESC(PARM_LOAD_BALANCING, "Load Balancing Enabled (<string> N or Y) [Y]");
290 MODULE_PARM(PARM_MEDIUM_DISTRIBUTION, "s");
291 MODULE_PARM_DESC(PARM_MEDIUM_DISTRIBUTION, "Medium Distribution Enabled (<string> N or Y) [Y]");
292 MODULE_PARM(PARM_TX_POW_LEVEL, "b");
293 MODULE_PARM_DESC(PARM_TX_POW_LEVEL, "Transmit Power (0 - 6) [3]");
294 MODULE_PARM(PARM_SRSC_2GHZ, "b");
295 MODULE_PARM_DESC(PARM_SRSC_2GHZ, "Supported Rate Set Control 2.4 GHz");
296 MODULE_PARM(PARM_SRSC_5GHZ, "b");
297 MODULE_PARM_DESC(PARM_SRSC_5GHZ, "Supported Rate Set Control 5.0 GHz");
298 MODULE_PARM(PARM_BRSC_2GHZ, "b");
299 MODULE_PARM_DESC(PARM_BRSC_2GHZ, "Basic Rate Set Control 2.4 GHz");
300 MODULE_PARM(PARM_BRSC_5GHZ, "b");
301 MODULE_PARM_DESC(PARM_BRSC_5GHZ, "Basic Rate Set Control 5.0 GHz");
302 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
303 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
304 MODULE_PARM(PARM_PM_ENABLED, "h");
305 MODULE_PARM_DESC(PARM_PM_ENABLED, "Power Management State (0 - 2, 8001 - 8002) [0]");
306 MODULE_PARM(PARM_PORT_TYPE, "b");
307 MODULE_PARM_DESC(PARM_PORT_TYPE, "Port Type (1 - 3) [1]");
308 //;?MODULE_PARM(PARM_CREATE_IBSS, "s");
309 //;?MODULE_PARM_DESC(PARM_CREATE_IBSS, "Create IBSS (<string> N or Y) [N]");
310 //;?MODULE_PARM(PARM_MULTICAST_RX, "s");
311 //;?MODULE_PARM_DESC(PARM_MULTICAST_RX, "Multicast Receive Enable (<string> N or Y) [Y]");
312 //;?MODULE_PARM(PARM_MAX_SLEEP, "h");
313 //;?MODULE_PARM_DESC(PARM_MAX_SLEEP, "Maximum Power Management Sleep Duration (0 - 65535) [100]");
314 //;?MODULE_PARM(PARM_NETWORK_ADDR, "6b");
315 //;?MODULE_PARM_DESC(PARM_NETWORK_ADDR, "Hardware Ethernet Address ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [<factory value>]");
316 //;?MODULE_PARM(PARM_AUTHENTICATION, "b");
319 //;?MODULE_PARM_DESC(PARM_AUTHENTICATION, "Authentication Type (0-2) [0] 0=Open 1=SharedKey 2=LEAP");
320 //;?MODULE_PARM_DESC(authentication, "Authentication Type (1-2) [1] 1=Open 2=SharedKey");
323 //;?MODULE_PARM(PARM_OWN_ATIM_WINDOW, "b");
324 //;?MODULE_PARM_DESC(PARM_OWN_ATIM_WINDOW, "ATIM Window time in TU for IBSS creation (0-100) [0]");
325 //;?MODULE_PARM(PARM_PM_HOLDOVER_DURATION, "b");
326 //;?MODULE_PARM_DESC(PARM_PM_HOLDOVER_DURATION, "Time station remains awake after MAC frame transfer when PM is on (0-65535) [100]");
327 //;?MODULE_PARM(PARM_PROMISCUOUS_MODE, "s");
328 //;?MODULE_PARM_DESC(PARM_PROMISCUOUS_MODE, "Promiscuous Mode Enable (<string> Y or N ) [N]" );
330 MODULE_PARM(PARM_CONNECTION_CONTROL, "b");
331 MODULE_PARM_DESC(PARM_CONNECTION_CONTROL, "Connection Control (0 - 3) [2]");
333 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
334 //;?should we restore this to allow smaller memory footprint
335 MODULE_PARM(PARM_OWN_DTIM_PERIOD, "b");
336 MODULE_PARM_DESC(PARM_OWN_DTIM_PERIOD, "DTIM Period (0 - 255) [1]");
337 MODULE_PARM(PARM_REJECT_ANY, "s");
338 MODULE_PARM_DESC(PARM_REJECT_ANY, "Closed System (<string> N or Y) [N]");
339 MODULE_PARM(PARM_EXCLUDE_UNENCRYPTED, "s");
340 MODULE_PARM_DESC(PARM_EXCLUDE_UNENCRYPTED, "Deny non-encrypted (<string> N or Y) [Y]");
341 MODULE_PARM(PARM_MULTICAST_PM_BUFFERING,"s");
342 MODULE_PARM_DESC(PARM_MULTICAST_PM_BUFFERING, "Buffer MAC frames for Tx after DTIM (<string> Y or N) [Y]");
343 MODULE_PARM(PARM_INTRA_BSS_RELAY, "s");
344 MODULE_PARM_DESC(PARM_INTRA_BSS_RELAY, "IntraBSS Relay (<string> N or Y) [Y]");
345 MODULE_PARM(PARM_RTS_THRESHOLD1, "h");
346 MODULE_PARM_DESC(PARM_RTS_THRESHOLD1, "RTS Threshold, WDS Port 1 (256 - 2347) [2347]");
347 MODULE_PARM(PARM_RTS_THRESHOLD2, "h");
348 MODULE_PARM_DESC(PARM_RTS_THRESHOLD2, "RTS Threshold, WDS Port 2 (256 - 2347) [2347]");
349 MODULE_PARM(PARM_RTS_THRESHOLD3, "h");
350 MODULE_PARM_DESC(PARM_RTS_THRESHOLD3, "RTS Threshold, WDS Port 3 (256 - 2347) [2347]");
351 MODULE_PARM(PARM_RTS_THRESHOLD4, "h");
352 MODULE_PARM_DESC(PARM_RTS_THRESHOLD4, "RTS Threshold, WDS Port 4 (256 - 2347) [2347]");
353 MODULE_PARM(PARM_RTS_THRESHOLD5, "h");
354 MODULE_PARM_DESC(PARM_RTS_THRESHOLD5, "RTS Threshold, WDS Port 5 (256 - 2347) [2347]");
355 MODULE_PARM(PARM_RTS_THRESHOLD6, "h");
356 MODULE_PARM_DESC(PARM_RTS_THRESHOLD6, "RTS Threshold, WDS Port 6 (256 - 2347) [2347]");
357 MODULE_PARM(PARM_TX_RATE1, "b");
358 MODULE_PARM_DESC(PARM_TX_RATE1, "Transmit Rate Control, WDS Port 1 (1 - 7) [3]");
359 MODULE_PARM(PARM_TX_RATE2, "b");
360 MODULE_PARM_DESC(PARM_TX_RATE2, "Transmit Rate Control, WDS Port 2 (1 - 7) [3]");
361 MODULE_PARM(PARM_TX_RATE3, "b");
362 MODULE_PARM_DESC(PARM_TX_RATE3, "Transmit Rate Control, WDS Port 3 (1 - 7) [3]");
363 MODULE_PARM(PARM_TX_RATE4, "b");
364 MODULE_PARM_DESC(PARM_TX_RATE4, "Transmit Rate Control, WDS Port 4 (1 - 7) [3]");
365 MODULE_PARM(PARM_TX_RATE5, "b");
366 MODULE_PARM_DESC(PARM_TX_RATE5, "Transmit Rate Control, WDS Port 5 (1 - 7) [3]");
367 MODULE_PARM(PARM_TX_RATE6, "b");
368 MODULE_PARM_DESC(PARM_TX_RATE6, "Transmit Rate Control, WDS Port 6 (1 - 7) [3]");
369 MODULE_PARM(PARM_WDS_ADDRESS1, "6b");
370 MODULE_PARM_DESC(PARM_WDS_ADDRESS1, "MAC Address, WDS Port 1 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
371 MODULE_PARM(PARM_WDS_ADDRESS2, "6b");
372 MODULE_PARM_DESC(PARM_WDS_ADDRESS2, "MAC Address, WDS Port 2 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
373 MODULE_PARM(PARM_WDS_ADDRESS3, "6b");
374 MODULE_PARM_DESC(PARM_WDS_ADDRESS3, "MAC Address, WDS Port 3 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
375 MODULE_PARM(PARM_WDS_ADDRESS4, "6b");
376 MODULE_PARM_DESC(PARM_WDS_ADDRESS4, "MAC Address, WDS Port 4 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
377 MODULE_PARM(PARM_WDS_ADDRESS5, "6b");
378 MODULE_PARM_DESC(PARM_WDS_ADDRESS5, "MAC Address, WDS Port 5 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
379 MODULE_PARM(PARM_WDS_ADDRESS6, "6b");
380 MODULE_PARM_DESC(PARM_WDS_ADDRESS6, "MAC Address, WDS Port 6 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
382 MODULE_PARM(PARM_OWN_BEACON_INTERVAL, "b");
383 MODULE_PARM_DESC(PARM_OWN_BEACON_INTERVAL, "Own Beacon Interval (20 - 200) [100]");
384 MODULE_PARM(PARM_COEXISTENCE, "b");
385 MODULE_PARM_DESC(PARM_COEXISTENCE, "Coexistence (0-7) [0]");
390 /* END NEW PARAMETERS */
391 /*******************************************************************************
392 * debugging specifics
393 ******************************************************************************/
396 static p_u32 pc_debug = DBG_LVL;
397 //MODULE_PARM(pc_debug, "i");
398 /*static ;?conflicts with my understanding of CL parameters and breaks now I moved
399 * the correspondig logic to wl_profile
400 */ p_u32 DebugFlag = ~0; //recognizable "undefined value" rather then DBG_DEFAULTS;
401 //MODULE_PARM(DebugFlag, "l");
403 dbg_info_t wl_info = { DBG_MOD_NAME, 0, 0 };
404 dbg_info_t *DbgInfo = &wl_info;
409 static p_char *useRTS = "N";
410 MODULE_PARM( useRTS, "s" );
411 MODULE_PARM_DESC( useRTS, "Use RTS test interface (<string> N or Y) [N]" );
414 /*******************************************************************************
415 * firmware download specifics
416 ******************************************************************************/
417 extern struct CFG_RANGE2_STRCT BASED
418 cfg_drv_act_ranges_pri; // describes primary-actor range of HCF
420 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
421 extern memimage ap; // AP firmware image to be downloaded
424 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
425 //extern memimage station; // STA firmware image to be downloaded
426 extern memimage fw_image; // firmware image to be downloaded
430 int wl_insert( struct net_device *dev )
433 int hcf_status = HCF_SUCCESS;
435 unsigned long flags = 0;
436 struct wl_private *lp = wl_priv(dev);
437 /*------------------------------------------------------------------------*/
438 DBG_ENTER( DbgInfo );
440 /* Initialize the adapter hardware. */
441 memset( &( lp->hcfCtx ), 0, sizeof( IFB_STRCT ));
443 /* Initialize the adapter parameters. */
444 spin_lock_init( &( lp->slock ));
446 /* Initialize states */
447 //lp->lockcount = 0; //PE1DNN
448 lp->is_handling_int = WL_NOT_HANDLING_INT;
449 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
453 DBG_PARAM( DbgInfo, "irq_mask", "0x%04x", irq_mask & 0x0FFFF );
454 DBG_PARAM( DbgInfo, "irq_list", "0x%02x 0x%02x 0x%02x 0x%02x",
455 irq_list[0] & 0x0FF, irq_list[1] & 0x0FF,
456 irq_list[2] & 0x0FF, irq_list[3] & 0x0FF );
457 DBG_PARAM( DbgInfo, PARM_NAME_DESIRED_SSID, "\"%s\"", PARM_DESIRED_SSID );
458 DBG_PARAM( DbgInfo, PARM_NAME_OWN_SSID, "\"%s\"", PARM_OWN_SSID );
459 DBG_PARAM( DbgInfo, PARM_NAME_OWN_CHANNEL, "%d", PARM_OWN_CHANNEL);
460 DBG_PARAM( DbgInfo, PARM_NAME_SYSTEM_SCALE, "%d", PARM_SYSTEM_SCALE );
461 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE, "%d", PARM_TX_RATE );
462 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD, "%d", PARM_RTS_THRESHOLD );
463 DBG_PARAM( DbgInfo, PARM_NAME_MICROWAVE_ROBUSTNESS, "\"%s\"", PARM_MICROWAVE_ROBUSTNESS );
464 DBG_PARAM( DbgInfo, PARM_NAME_OWN_NAME, "\"%s\"", PARM_OWN_NAME );
465 //;? DBG_PARAM( DbgInfo, PARM_NAME_ENABLE_ENCRYPTION, "\"%s\"", PARM_ENABLE_ENCRYPTION );
466 DBG_PARAM( DbgInfo, PARM_NAME_KEY1, "\"%s\"", PARM_KEY1 );
467 DBG_PARAM( DbgInfo, PARM_NAME_KEY2, "\"%s\"", PARM_KEY2 );
468 DBG_PARAM( DbgInfo, PARM_NAME_KEY3, "\"%s\"", PARM_KEY3 );
469 DBG_PARAM( DbgInfo, PARM_NAME_KEY4, "\"%s\"", PARM_KEY4 );
470 DBG_PARAM( DbgInfo, PARM_NAME_TX_KEY, "%d", PARM_TX_KEY );
471 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RATE, "%d", PARM_MULTICAST_RATE );
472 DBG_PARAM( DbgInfo, PARM_NAME_DOWNLOAD_FIRMWARE, "\"%s\"", PARM_DOWNLOAD_FIRMWARE );
473 DBG_PARAM( DbgInfo, PARM_NAME_AUTH_KEY_MGMT_SUITE, "%d", PARM_AUTH_KEY_MGMT_SUITE );
474 //;?#if (HCF_TYPE) & HCF_TYPE_STA
475 //;?should we make this code conditional depending on in STA mode
476 //;? DBG_PARAM( DbgInfo, PARM_NAME_PORT_TYPE, "%d", PARM_PORT_TYPE );
477 DBG_PARAM( DbgInfo, PARM_NAME_PM_ENABLED, "%04x", PARM_PM_ENABLED );
478 //;? DBG_PARAM( DbgInfo, PARM_NAME_CREATE_IBSS, "\"%s\"", PARM_CREATE_IBSS );
479 //;? DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RX, "\"%s\"", PARM_MULTICAST_RX );
480 //;? DBG_PARAM( DbgInfo, PARM_NAME_MAX_SLEEP, "%d", PARM_MAX_SLEEP );
482 DBG_PARAM(DbgInfo, PARM_NAME_NETWORK_ADDR, "\"%pM\"",
485 //;? DBG_PARAM( DbgInfo, PARM_NAME_AUTHENTICATION, "%d", PARM_AUTHENTICATION );
486 //;? DBG_PARAM( DbgInfo, PARM_NAME_OWN_ATIM_WINDOW, "%d", PARM_OWN_ATIM_WINDOW );
487 //;? DBG_PARAM( DbgInfo, PARM_NAME_PM_HOLDOVER_DURATION, "%d", PARM_PM_HOLDOVER_DURATION );
488 //;? DBG_PARAM( DbgInfo, PARM_NAME_PROMISCUOUS_MODE, "\"%s\"", PARM_PROMISCUOUS_MODE );
489 //;?#endif /* HCF_STA */
490 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
491 //;?should we restore this to allow smaller memory footprint
492 //;?I guess: no, since this is Debug mode only
493 DBG_PARAM( DbgInfo, PARM_NAME_OWN_DTIM_PERIOD, "%d", PARM_OWN_DTIM_PERIOD );
494 DBG_PARAM( DbgInfo, PARM_NAME_REJECT_ANY, "\"%s\"", PARM_REJECT_ANY );
495 DBG_PARAM( DbgInfo, PARM_NAME_EXCLUDE_UNENCRYPTED, "\"%s\"", PARM_EXCLUDE_UNENCRYPTED );
496 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_PM_BUFFERING, "\"%s\"", PARM_MULTICAST_PM_BUFFERING );
497 DBG_PARAM( DbgInfo, PARM_NAME_INTRA_BSS_RELAY, "\"%s\"", PARM_INTRA_BSS_RELAY );
499 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD1, "%d", PARM_RTS_THRESHOLD1 );
500 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD2, "%d", PARM_RTS_THRESHOLD2 );
501 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD3, "%d", PARM_RTS_THRESHOLD3 );
502 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD4, "%d", PARM_RTS_THRESHOLD4 );
503 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD5, "%d", PARM_RTS_THRESHOLD5 );
504 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD6, "%d", PARM_RTS_THRESHOLD6 );
505 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE1, "%d", PARM_TX_RATE1 );
506 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE2, "%d", PARM_TX_RATE2 );
507 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE3, "%d", PARM_TX_RATE3 );
508 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE4, "%d", PARM_TX_RATE4 );
509 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE5, "%d", PARM_TX_RATE5 );
510 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE6, "%d", PARM_TX_RATE6 );
511 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS1, "\"%pM\"",
513 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS2, "\"%pM\"",
515 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS3, "\"%pM\"",
517 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS4, "\"%pM\"",
519 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS5, "\"%pM\"",
521 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS6, "\"%pM\"",
526 VALID_PARAM( !PARM_DESIRED_SSID || ( strlen( PARM_DESIRED_SSID ) <= PARM_MAX_NAME_LEN ));
527 VALID_PARAM( !PARM_OWN_SSID || ( strlen( PARM_OWN_SSID ) <= PARM_MAX_NAME_LEN ));
528 VALID_PARAM(( PARM_OWN_CHANNEL <= PARM_MAX_OWN_CHANNEL ));
529 VALID_PARAM(( PARM_SYSTEM_SCALE >= PARM_MIN_SYSTEM_SCALE ) && ( PARM_SYSTEM_SCALE <= PARM_MAX_SYSTEM_SCALE ));
530 VALID_PARAM(( PARM_TX_RATE >= PARM_MIN_TX_RATE ) && ( PARM_TX_RATE <= PARM_MAX_TX_RATE ));
531 VALID_PARAM(( PARM_RTS_THRESHOLD <= PARM_MAX_RTS_THRESHOLD ));
532 VALID_PARAM( !PARM_MICROWAVE_ROBUSTNESS || strchr( "NnYy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL );
533 VALID_PARAM( !PARM_OWN_NAME || ( strlen( PARM_NAME_OWN_NAME ) <= PARM_MAX_NAME_LEN ));
534 VALID_PARAM(( PARM_ENABLE_ENCRYPTION <= PARM_MAX_ENABLE_ENCRYPTION ));
535 VALID_PARAM( is_valid_key_string( PARM_KEY1 ));
536 VALID_PARAM( is_valid_key_string( PARM_KEY2 ));
537 VALID_PARAM( is_valid_key_string( PARM_KEY3 ));
538 VALID_PARAM( is_valid_key_string( PARM_KEY4 ));
539 VALID_PARAM(( PARM_TX_KEY >= PARM_MIN_TX_KEY ) && ( PARM_TX_KEY <= PARM_MAX_TX_KEY ));
541 VALID_PARAM(( PARM_MULTICAST_RATE >= PARM_MIN_MULTICAST_RATE ) &&
542 ( PARM_MULTICAST_RATE <= PARM_MAX_MULTICAST_RATE ));
544 VALID_PARAM( !PARM_DOWNLOAD_FIRMWARE || ( strlen( PARM_DOWNLOAD_FIRMWARE ) <= 255 /*;?*/ ));
545 VALID_PARAM(( PARM_AUTH_KEY_MGMT_SUITE < PARM_MAX_AUTH_KEY_MGMT_SUITE ));
547 VALID_PARAM( !PARM_LOAD_BALANCING || strchr( "NnYy", PARM_LOAD_BALANCING[0] ) != NULL );
548 VALID_PARAM( !PARM_MEDIUM_DISTRIBUTION || strchr( "NnYy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL );
549 VALID_PARAM(( PARM_TX_POW_LEVEL <= PARM_MAX_TX_POW_LEVEL ));
551 VALID_PARAM(( PARM_PORT_TYPE >= PARM_MIN_PORT_TYPE ) && ( PARM_PORT_TYPE <= PARM_MAX_PORT_TYPE ));
552 VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
553 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
554 VALID_PARAM( !PARM_CREATE_IBSS || strchr( "NnYy", PARM_CREATE_IBSS[0] ) != NULL );
555 VALID_PARAM( !PARM_MULTICAST_RX || strchr( "NnYy", PARM_MULTICAST_RX[0] ) != NULL );
556 VALID_PARAM(( PARM_MAX_SLEEP <= PARM_MAX_MAX_PM_SLEEP ));
557 VALID_PARAM(( PARM_AUTHENTICATION <= PARM_MAX_AUTHENTICATION ));
558 VALID_PARAM(( PARM_OWN_ATIM_WINDOW <= PARM_MAX_OWN_ATIM_WINDOW ));
559 VALID_PARAM(( PARM_PM_HOLDOVER_DURATION <= PARM_MAX_PM_HOLDOVER_DURATION ));
560 VALID_PARAM( !PARM_PROMISCUOUS_MODE || strchr( "NnYy", PARM_PROMISCUOUS_MODE[0] ) != NULL );
561 VALID_PARAM(( PARM_CONNECTION_CONTROL <= PARM_MAX_CONNECTION_CONTROL ));
563 VALID_PARAM(( PARM_OWN_DTIM_PERIOD >= PARM_MIN_OWN_DTIM_PERIOD ));
564 VALID_PARAM( !PARM_REJECT_ANY || strchr( "NnYy", PARM_REJECT_ANY[0] ) != NULL );
565 VALID_PARAM( !PARM_EXCLUDE_UNENCRYPTED || strchr( "NnYy", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL );
566 VALID_PARAM( !PARM_MULTICAST_PM_BUFFERING || strchr( "NnYy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL );
567 VALID_PARAM( !PARM_INTRA_BSS_RELAY || strchr( "NnYy", PARM_INTRA_BSS_RELAY[0] ) != NULL );
569 VALID_PARAM(( PARM_RTS_THRESHOLD1 <= PARM_MAX_RTS_THRESHOLD ));
570 VALID_PARAM(( PARM_RTS_THRESHOLD2 <= PARM_MAX_RTS_THRESHOLD ));
571 VALID_PARAM(( PARM_RTS_THRESHOLD3 <= PARM_MAX_RTS_THRESHOLD ));
572 VALID_PARAM(( PARM_RTS_THRESHOLD4 <= PARM_MAX_RTS_THRESHOLD ));
573 VALID_PARAM(( PARM_RTS_THRESHOLD5 <= PARM_MAX_RTS_THRESHOLD ));
574 VALID_PARAM(( PARM_RTS_THRESHOLD6 <= PARM_MAX_RTS_THRESHOLD ));
575 VALID_PARAM(( PARM_TX_RATE1 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE1 <= PARM_MAX_TX_RATE ));
576 VALID_PARAM(( PARM_TX_RATE2 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE2 <= PARM_MAX_TX_RATE ));
577 VALID_PARAM(( PARM_TX_RATE3 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE3 <= PARM_MAX_TX_RATE ));
578 VALID_PARAM(( PARM_TX_RATE4 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE4 <= PARM_MAX_TX_RATE ));
579 VALID_PARAM(( PARM_TX_RATE5 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE5 <= PARM_MAX_TX_RATE ));
580 VALID_PARAM(( PARM_TX_RATE6 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE6 <= PARM_MAX_TX_RATE ));
583 VALID_PARAM(( PARM_OWN_BEACON_INTERVAL >= PARM_MIN_OWN_BEACON_INTERVAL ) && ( PARM_OWN_BEACON_INTERVAL <= PARM_MAX_OWN_BEACON_INTERVAL ));
584 VALID_PARAM(( PARM_COEXISTENCE <= PARM_COEXISTENCE ));
586 /* Set the driver parameters from the passed in parameters. */
588 /* THESE MODULE PARAMETERS ARE TO BE DEPRECATED IN FAVOR OF A NAMING CONVENTION
589 WHICH IS INLINE WITH THE FORTHCOMING WAVELAN API */
591 /* START NEW PARAMETERS */
593 lp->Channel = PARM_OWN_CHANNEL;
594 lp->DistanceBetweenAPs = PARM_SYSTEM_SCALE;
596 /* Need to determine how to handle the new bands for 5GHz */
597 lp->TxRateControl[0] = PARM_DEFAULT_TX_RATE_2GHZ;
598 lp->TxRateControl[1] = PARM_DEFAULT_TX_RATE_5GHZ;
600 lp->RTSThreshold = PARM_RTS_THRESHOLD;
602 /* Need to determine how to handle the new bands for 5GHz */
603 lp->MulticastRate[0] = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
604 lp->MulticastRate[1] = PARM_DEFAULT_MULTICAST_RATE_5GHZ;
606 if ( strchr( "Yy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL ) {
607 lp->MicrowaveRobustness = 1;
609 lp->MicrowaveRobustness = 0;
611 if ( PARM_DESIRED_SSID && ( strlen( PARM_DESIRED_SSID ) <= HCF_MAX_NAME_LEN )) {
612 strcpy( lp->NetworkName, PARM_DESIRED_SSID );
614 if ( PARM_OWN_SSID && ( strlen( PARM_OWN_SSID ) <= HCF_MAX_NAME_LEN )) {
615 strcpy( lp->NetworkName, PARM_OWN_SSID );
617 if ( PARM_OWN_NAME && ( strlen( PARM_OWN_NAME ) <= HCF_MAX_NAME_LEN )) {
618 strcpy( lp->StationName, PARM_OWN_NAME );
620 lp->EnableEncryption = PARM_ENABLE_ENCRYPTION;
621 if ( PARM_KEY1 && ( strlen( PARM_KEY1 ) <= MAX_KEY_LEN )) {
622 strcpy( lp->Key1, PARM_KEY1 );
624 if ( PARM_KEY2 && ( strlen( PARM_KEY2 ) <= MAX_KEY_LEN )) {
625 strcpy( lp->Key2, PARM_KEY2 );
627 if ( PARM_KEY3 && ( strlen( PARM_KEY3 ) <= MAX_KEY_LEN )) {
628 strcpy( lp->Key3, PARM_KEY3 );
630 if ( PARM_KEY4 && ( strlen( PARM_KEY4 ) <= MAX_KEY_LEN )) {
631 strcpy( lp->Key4, PARM_KEY4 );
634 lp->TransmitKeyID = PARM_TX_KEY;
636 key_string2key( lp->Key1, &(lp->DefaultKeys.key[0] ));
637 key_string2key( lp->Key2, &(lp->DefaultKeys.key[1] ));
638 key_string2key( lp->Key3, &(lp->DefaultKeys.key[2] ));
639 key_string2key( lp->Key4, &(lp->DefaultKeys.key[3] ));
641 lp->DownloadFirmware = 1 ; //;?to be upgraded PARM_DOWNLOAD_FIRMWARE;
642 lp->AuthKeyMgmtSuite = PARM_AUTH_KEY_MGMT_SUITE;
644 if ( strchr( "Yy", PARM_LOAD_BALANCING[0] ) != NULL ) {
645 lp->loadBalancing = 1;
647 lp->loadBalancing = 0;
650 if ( strchr( "Yy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL ) {
651 lp->mediumDistribution = 1;
653 lp->mediumDistribution = 0;
656 lp->txPowLevel = PARM_TX_POW_LEVEL;
658 lp->srsc[0] = PARM_SRSC_2GHZ;
659 lp->srsc[1] = PARM_SRSC_5GHZ;
660 lp->brsc[0] = PARM_BRSC_2GHZ;
661 lp->brsc[1] = PARM_BRSC_5GHZ;
662 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
663 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
664 lp->PortType = PARM_PORT_TYPE;
665 lp->MaxSleepDuration = PARM_MAX_SLEEP;
666 lp->authentication = PARM_AUTHENTICATION;
667 lp->atimWindow = PARM_OWN_ATIM_WINDOW;
668 lp->holdoverDuration = PARM_PM_HOLDOVER_DURATION;
669 lp->PMEnabled = PARM_PM_ENABLED; //;?
670 if ( strchr( "Yy", PARM_CREATE_IBSS[0] ) != NULL ) {
675 if ( strchr( "Nn", PARM_MULTICAST_RX[0] ) != NULL ) {
676 lp->MulticastReceive = 0;
678 lp->MulticastReceive = 1;
680 if ( strchr( "Yy", PARM_PROMISCUOUS_MODE[0] ) != NULL ) {
681 lp->promiscuousMode = 1;
683 lp->promiscuousMode = 0;
685 for( i = 0; i < ETH_ALEN; i++ ) {
686 lp->MACAddress[i] = PARM_NETWORK_ADDR[i];
689 lp->connectionControl = PARM_CONNECTION_CONTROL;
692 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
693 //;?should we restore this to allow smaller memory footprint
694 lp->DTIMPeriod = PARM_OWN_DTIM_PERIOD;
696 if ( strchr( "Yy", PARM_REJECT_ANY[0] ) != NULL ) {
701 if ( strchr( "Nn", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL ) {
702 lp->ExcludeUnencrypted = 0;
704 lp->ExcludeUnencrypted = 1;
706 if ( strchr( "Yy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL ) {
707 lp->multicastPMBuffering = 1;
709 lp->multicastPMBuffering = 0;
711 if ( strchr( "Yy", PARM_INTRA_BSS_RELAY[0] ) != NULL ) {
712 lp->intraBSSRelay = 1;
714 lp->intraBSSRelay = 0;
717 lp->ownBeaconInterval = PARM_OWN_BEACON_INTERVAL;
718 lp->coexistence = PARM_COEXISTENCE;
721 lp->wds_port[0].rtsThreshold = PARM_RTS_THRESHOLD1;
722 lp->wds_port[1].rtsThreshold = PARM_RTS_THRESHOLD2;
723 lp->wds_port[2].rtsThreshold = PARM_RTS_THRESHOLD3;
724 lp->wds_port[3].rtsThreshold = PARM_RTS_THRESHOLD4;
725 lp->wds_port[4].rtsThreshold = PARM_RTS_THRESHOLD5;
726 lp->wds_port[5].rtsThreshold = PARM_RTS_THRESHOLD6;
727 lp->wds_port[0].txRateCntl = PARM_TX_RATE1;
728 lp->wds_port[1].txRateCntl = PARM_TX_RATE2;
729 lp->wds_port[2].txRateCntl = PARM_TX_RATE3;
730 lp->wds_port[3].txRateCntl = PARM_TX_RATE4;
731 lp->wds_port[4].txRateCntl = PARM_TX_RATE5;
732 lp->wds_port[5].txRateCntl = PARM_TX_RATE6;
734 for( i = 0; i < ETH_ALEN; i++ ) {
735 lp->wds_port[0].wdsAddress[i] = PARM_WDS_ADDRESS1[i];
737 for( i = 0; i < ETH_ALEN; i++ ) {
738 lp->wds_port[1].wdsAddress[i] = PARM_WDS_ADDRESS2[i];
740 for( i = 0; i < ETH_ALEN; i++ ) {
741 lp->wds_port[2].wdsAddress[i] = PARM_WDS_ADDRESS3[i];
743 for( i = 0; i < ETH_ALEN; i++ ) {
744 lp->wds_port[3].wdsAddress[i] = PARM_WDS_ADDRESS4[i];
746 for( i = 0; i < ETH_ALEN; i++ ) {
747 lp->wds_port[4].wdsAddress[i] = PARM_WDS_ADDRESS5[i];
749 for( i = 0; i < ETH_ALEN; i++ ) {
750 lp->wds_port[5].wdsAddress[i] = PARM_WDS_ADDRESS6[i];
755 if ( strchr( "Yy", useRTS[0] ) != NULL ) {
763 /* END NEW PARAMETERS */
766 wl_lock( lp, &flags );
768 /* Initialize the portState variable */
769 lp->portState = WVLAN_PORT_STATE_DISABLED;
771 /* Initialize the ScanResult struct */
772 memset( &( lp->scan_results ), 0, sizeof( lp->scan_results ));
773 lp->scan_results.scan_complete = FALSE;
775 /* Initialize the ProbeResult struct */
776 memset( &( lp->probe_results ), 0, sizeof( lp->probe_results ));
777 lp->probe_results.scan_complete = FALSE;
778 lp->probe_num_aps = 0;
781 /* Initialize Tx queue stuff */
782 memset( lp->txList, 0, sizeof( lp->txList ));
784 INIT_LIST_HEAD( &( lp->txFree ));
790 for( i = 0; i < DEFAULT_NUM_TX_FRAMES; i++ ) {
791 list_add_tail( &( lp->txList[i].node ), &( lp->txFree ));
795 for( i = 0; i < WVLAN_MAX_TX_QUEUES; i++ ) {
796 INIT_LIST_HEAD( &( lp->txQ[i] ));
799 lp->netif_queue_on = TRUE;
801 /* Initialize the use_dma element in the adapter structure. Not sure if
802 this should be a compile-time or run-time configurable. So for now,
803 implement as run-time and just define here */
806 DBG_TRACE( DbgInfo, "HERMES 2.5 BUSMASTER DMA MODE\n" );
809 DBG_TRACE( DbgInfo, "HERMES 2.5 PORT I/O MODE\n" );
814 /* Register the ISR handler information here, so that it's not done
815 repeatedly in the ISR */
816 tasklet_init(&lp->task, wl_isr_handler, (unsigned long)lp);
818 /* Connect to the adapter */
819 DBG_TRACE( DbgInfo, "Calling hcf_connect()...\n" );
820 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
821 //HCF_ERR_INCOMP_FW is acceptable, because download must still take place
822 //HCF_ERR_INCOMP_PRI is not acceptable
823 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
824 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
825 wl_unlock( lp, &flags );
829 //;?should set HCF_version and how about driver_stat
830 lp->driverInfo.IO_address = dev->base_addr;
831 lp->driverInfo.IO_range = HCF_NUM_IO_PORTS; //;?conditionally 0x40 or 0x80 seems better
832 lp->driverInfo.IRQ_number = dev->irq;
833 lp->driverInfo.card_stat = lp->hcfCtx.IFB_CardStat;
834 //;? what happened to frame_type
836 /* Fill in the driver identity structure */
837 lp->driverIdentity.len = ( sizeof( lp->driverIdentity ) / sizeof( hcf_16 )) - 1;
838 lp->driverIdentity.typ = CFG_DRV_IDENTITY;
839 lp->driverIdentity.comp_id = DRV_IDENTITY;
840 lp->driverIdentity.variant = DRV_VARIANT;
841 lp->driverIdentity.version_major = DRV_MAJOR_VERSION;
842 lp->driverIdentity.version_minor = DRV_MINOR_VERSION;
845 /* Start the card here - This needs to be done in order to get the
846 MAC address for the network layer */
847 DBG_TRACE( DbgInfo, "Calling wvlan_go() to perform a card reset...\n" );
848 hcf_status = wl_go( lp );
850 if ( hcf_status != HCF_SUCCESS ) {
851 DBG_ERROR( DbgInfo, "wl_go() failed\n" );
852 wl_unlock( lp, &flags );
856 /* Certain RIDs must be set before enabling the ports */
857 wl_put_ltv_init( lp );
859 #if 0 //;?why was this already commented out in wl_lkm_720
860 /* Enable the ports */
861 if ( wl_adapter_is_open( lp->dev )) {
862 /* Enable the ports */
863 DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
864 hcf_status = wl_enable( lp );
866 if ( hcf_status != HCF_SUCCESS ) {
867 DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", hcf_status );
870 #if (HCF_TYPE) & HCF_TYPE_AP
871 DBG_TRACE( DbgInfo, "Enabling WDS Ports\n" );
872 //wl_enable_wds_ports( lp );
873 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
878 /* Fill out the MAC address information in the net_device struct */
879 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN );
880 dev->addr_len = ETH_ALEN;
882 lp->is_registered = TRUE;
885 /* Parse the config file for the sake of creating WDS ports if WDS is
886 configured there but not in the module options */
888 #endif /* USE_PROFILE */
890 /* If we're going into AP Mode, register the "virtual" ethernet devices
892 WL_WDS_NETDEV_REGISTER( lp );
894 /* Reset the DownloadFirmware variable in the private struct. If the
895 config file is not used, this will not matter; if it is used, it
896 will be reparsed in wl_open(). This is done because logic in wl_open
897 used to check if a firmware download is needed is broken by parsing
898 the file here; however, this parsing is needed to register WDS ports
899 in AP mode, if they are configured */
900 lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //;?download_firmware;
903 if ( lp->useRTS == 1 ) {
904 DBG_TRACE( DbgInfo, "ENTERING RTS MODE...\n" );
905 wl_act_int_off( lp );
906 lp->is_handling_int = WL_NOT_HANDLING_INT; // Not handling interrupts anymore
910 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT);
914 wl_unlock( lp, &flags );
916 DBG_TRACE( DbgInfo, "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
917 dev->name, dev->base_addr, dev->irq );
919 for( i = 0; i < ETH_ALEN; i++ ) {
920 printk( "%02X%c", dev->dev_addr[i], (( i < ( ETH_ALEN-1 )) ? ':' : '\n' ));
923 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
924 proc_create_data( "wlags", 0, NULL, &scull_read_procmem_fops, dev );
925 proc_mkdir("driver/wlags49", 0);
926 #endif /* SCULL_USE_PROC */
928 DBG_LEAVE( DbgInfo );
932 wl_hcf_error( dev, hcf_status );
936 DBG_ERROR( DbgInfo, "wl_insert() FAILED\n" );
938 if ( lp->is_registered == TRUE ) {
939 lp->is_registered = FALSE;
942 WL_WDS_NETDEV_DEREGISTER( lp );
947 DBG_LEAVE( DbgInfo );
950 /*============================================================================*/
953 /*******************************************************************************
955 *******************************************************************************
963 * dev - a pointer to the net_device struct of the wireless device
969 ******************************************************************************/
970 int wl_reset(struct net_device *dev)
972 struct wl_private *lp = wl_priv(dev);
973 int hcf_status = HCF_SUCCESS;
974 /*------------------------------------------------------------------------*/
975 DBG_ENTER( DbgInfo );
976 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
977 DBG_PARAM( DbgInfo, "dev->base_addr", "(%#03lx)", dev->base_addr );
980 * The caller should already have a lock and
981 * disable the interrupts, we do not lock here,
982 * nor do we enable/disable interrupts!
985 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", dev->base_addr );
986 if ( dev->base_addr ) {
987 /* Shutdown the adapter. */
988 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
990 /* Reset the driver information. */
993 /* Connect to the adapter. */
994 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
995 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
996 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
1000 /* Check if firmware is present, if not change state */
1001 if ( hcf_status == HCF_ERR_INCOMP_FW ) {
1002 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1005 /* Initialize the portState variable */
1006 lp->portState = WVLAN_PORT_STATE_DISABLED;
1008 /* Restart the adapter. */
1009 hcf_status = wl_go( lp );
1010 if ( hcf_status != HCF_SUCCESS ) {
1011 DBG_ERROR( DbgInfo, "wl_go() failed, status: 0x%x\n", hcf_status );
1015 /* Certain RIDs must be set before enabling the ports */
1016 wl_put_ltv_init( lp );
1018 DBG_ERROR( DbgInfo, "Device Base Address INVALID!!!\n" );
1022 DBG_LEAVE( DbgInfo );
1025 /*============================================================================*/
1028 /*******************************************************************************
1030 *******************************************************************************
1034 * Reset the adapter.
1038 * dev - a pointer to the net_device struct of the wireless device
1042 * an HCF status code
1044 ******************************************************************************/
1045 int wl_go( struct wl_private *lp )
1047 int hcf_status = HCF_SUCCESS;
1048 char *cp = NULL; //fw_image
1050 /*------------------------------------------------------------------------*/
1051 DBG_ENTER( DbgInfo );
1053 hcf_status = wl_disable( lp );
1054 if ( hcf_status != HCF_SUCCESS ) {
1055 DBG_TRACE( DbgInfo, "Disable port 0 failed: 0x%x\n", hcf_status );
1057 while (( hcf_status != HCF_SUCCESS ) && (retries < 10)) {
1059 hcf_status = wl_disable( lp );
1061 if ( hcf_status == HCF_SUCCESS ) {
1062 DBG_TRACE( DbgInfo, "Disable port 0 succes : %d retries\n", retries );
1064 DBG_TRACE( DbgInfo, "Disable port 0 failed after: %d retries\n", retries );
1068 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
1069 //DBG_TRACE( DbgInfo, "Disabling WDS Ports\n" );
1070 //wl_disable_wds_ports( lp );
1071 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1073 //;?what was the purpose of this
1074 // /* load the appropriate firmware image, depending on driver mode */
1075 // lp->ltvRecord.len = ( sizeof( CFG_RANGE20_STRCT ) / sizeof( hcf_16 )) - 1;
1076 // lp->ltvRecord.typ = CFG_DRV_ACT_RANGES_PRI;
1077 // hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1080 if ( strlen( lp->fw_image_filename ) ) {
1085 DBG_TRACE( DbgInfo, "F/W image:%s:\n", lp->fw_image_filename );
1086 /* Obtain a user-space process context, storing the original context */
1089 file_desc = open( lp->fw_image_filename, O_RDONLY, 0 );
1090 if ( file_desc == -1 ) {
1091 DBG_ERROR( DbgInfo, "No image file found\n" );
1093 DBG_TRACE( DbgInfo, "F/W image file found\n" );
1094 #define DHF_ALLOC_SIZE 96000 //just below 96K, let's hope it suffices for now and for the future
1095 cp = (char*)vmalloc( DHF_ALLOC_SIZE );
1097 DBG_ERROR( DbgInfo, "error in vmalloc\n" );
1099 rc = read( file_desc, cp, DHF_ALLOC_SIZE );
1100 if ( rc == DHF_ALLOC_SIZE ) {
1101 DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE );
1102 } else if ( rc > 0 ) {
1103 DBG_TRACE( DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp );
1104 rc = read( file_desc, &cp[rc], 1 );
1105 if ( rc == 0 ) { //;/change to an until-loop at rc<=0
1106 DBG_TRACE( DbgInfo, "no more to read\n" );
1110 DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\
1111 ", give up, too complicated, rc = %0X\n", rc );
1112 DBG_ERROR( DbgInfo, "still have to change code to get a real download now !!!!!!!!\n" );
1114 DBG_TRACE( DbgInfo, "before dhf_download_binary\n" );
1115 hcf_status = dhf_download_binary( (memimage *)cp );
1116 DBG_TRACE( DbgInfo, "after dhf_download_binary, before dhf_download_fw\n" );
1117 //;?improve error flow/handling
1118 hcf_status = dhf_download_fw( &lp->hcfCtx, (memimage *)cp );
1119 DBG_TRACE( DbgInfo, "after dhf_download_fw\n" );
1125 set_fs( fs ); /* Return to the original context */
1129 /* If firmware is present but the type is unknown then download anyway */
1130 if ( (lp->firmware_present == WL_FRIMWARE_PRESENT)
1132 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_STA )
1134 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_AP ) ) {
1135 /* Unknown type, download needed. */
1136 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1139 if(lp->firmware_present == WL_FRIMWARE_NOT_PRESENT)
1142 DBG_TRACE( DbgInfo, "Downloading STA firmware...\n" );
1143 // hcf_status = dhf_download_fw( &lp->hcfCtx, &station );
1144 hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image );
1146 if ( hcf_status != HCF_SUCCESS ) {
1147 DBG_ERROR( DbgInfo, "Firmware Download failed\n" );
1148 DBG_LEAVE( DbgInfo );
1152 /* Report the FW versions */
1153 //;?obsolete, use the available IFB info:: wl_get_pri_records( lp );
1154 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1155 DBG_TRACE( DbgInfo, "downloaded station F/W\n" );
1156 } else if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1157 DBG_TRACE( DbgInfo, "downloaded AP F/W\n" );
1159 DBG_ERROR( DbgInfo, "unknown F/W type\n" );
1163 * Downloaded, no need to repeat this next time, assume the
1164 * contents stays in the card until it is powered off. Note we
1165 * do not switch firmware on the fly, the firmware is fixed in
1166 * the driver for now.
1168 lp->firmware_present = WL_FRIMWARE_PRESENT;
1170 DBG_TRACE( DbgInfo, "ComponentID:%04x variant:%04x major:%04x minor:%04x\n",
1171 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ),
1172 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.variant ),
1173 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_major ),
1174 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_minor ));
1176 /* now we will get the MAC address of the card */
1177 lp->ltvRecord.len = 4;
1178 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1179 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1182 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1184 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1185 if ( hcf_status != HCF_SUCCESS ) {
1186 DBG_ERROR( DbgInfo, "Could not retrieve MAC address\n" );
1187 DBG_LEAVE( DbgInfo );
1190 memcpy( lp->MACAddress, &lp->ltvRecord.u.u8[0], ETH_ALEN );
1191 DBG_TRACE(DbgInfo, "Card MAC Address: %pM\n", lp->MACAddress);
1193 /* Write out configuration to the device, enable, and reconnect. However,
1194 only reconnect if in AP mode. For STA mode, need to wait for passive scan
1195 completion before a connect can be issued */
1197 /* Enable the ports */
1198 hcf_status = wl_enable( lp );
1200 if ( lp->DownloadFirmware == WVLAN_DRV_MODE_AP ) {
1202 wl_enable_wds_ports( lp );
1204 hcf_status = wl_connect( lp );
1206 DBG_LEAVE( DbgInfo );
1209 /*============================================================================*/
1212 /*******************************************************************************
1214 *******************************************************************************
1218 * Write TxKeyID and WEP keys to the adapter. This is separated from
1219 * wl_apply() to allow dynamic WEP key updates through the wireless
1224 * lp - a pointer to the wireless adapter's private structure
1230 ******************************************************************************/
1231 void wl_set_wep_keys( struct wl_private *lp )
1234 /*------------------------------------------------------------------------*/
1235 DBG_ENTER( DbgInfo );
1236 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1237 if ( lp->EnableEncryption ) {
1238 /* NOTE: CFG_CNF_ENCRYPTION is set in wl_put_ltv() as it's a static
1242 lp->ltvRecord.len = 2;
1243 lp->ltvRecord.typ = CFG_TX_KEY_ID;
1244 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE(lp->TransmitKeyID - 1);
1246 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1248 DBG_TRACE( DbgInfo, "Key 1 len: %d\n", lp->DefaultKeys.key[0].len );
1249 DBG_TRACE( DbgInfo, "Key 2 len: %d\n", lp->DefaultKeys.key[1].len );
1250 DBG_TRACE( DbgInfo, "Key 3 len: %d\n", lp->DefaultKeys.key[2].len );
1251 DBG_TRACE( DbgInfo, "Key 4 len: %d\n", lp->DefaultKeys.key[3].len );
1254 lp->DefaultKeys.len = sizeof( lp->DefaultKeys ) / sizeof( hcf_16 ) - 1;
1255 lp->DefaultKeys.typ = CFG_DEFAULT_KEYS;
1257 /* endian translate the appropriate key information */
1258 for( count = 0; count < MAX_KEYS; count++ ) {
1259 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1262 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->DefaultKeys ));
1264 /* Reverse the above endian translation, since these keys are accessed
1266 for( count = 0; count < MAX_KEYS; count++ ) {
1267 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1270 DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption, lp->TransmitKeyID );
1271 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 );
1274 DBG_LEAVE( DbgInfo );
1275 } // wl_set_wep_keys
1276 /*============================================================================*/
1279 /*******************************************************************************
1281 *******************************************************************************
1285 * Write the parameters to the adapter. (re-)enables the card if device is
1286 * open. Returns hcf_status of hcf_enable().
1290 * lp - a pointer to the wireless adapter's private structure
1294 * an HCF status code
1296 ******************************************************************************/
1297 int wl_apply(struct wl_private *lp)
1299 int hcf_status = HCF_SUCCESS;
1300 /*------------------------------------------------------------------------*/
1301 DBG_ENTER( DbgInfo );
1302 DBG_ASSERT( lp != NULL);
1303 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1305 if ( !( lp->flags & WVLAN2_UIL_BUSY )) {
1306 /* The adapter parameters have changed:
1312 if ( wl_adapter_is_open( lp->dev )) {
1313 /* Disconnect and disable if necessary */
1314 hcf_status = wl_disconnect( lp );
1315 if ( hcf_status != HCF_SUCCESS ) {
1316 DBG_ERROR( DbgInfo, "Disconnect failed\n" );
1317 DBG_LEAVE( DbgInfo );
1320 hcf_status = wl_disable( lp );
1321 if ( hcf_status != HCF_SUCCESS ) {
1322 DBG_ERROR( DbgInfo, "Disable failed\n" );
1323 DBG_LEAVE( DbgInfo );
1326 /* Write out configuration to the device, enable, and reconnect.
1327 However, only reconnect if in AP mode. For STA mode, need to
1328 wait for passive scan completion before a connect can be
1330 hcf_status = wl_put_ltv( lp );
1332 if ( hcf_status == HCF_SUCCESS ) {
1333 hcf_status = wl_enable( lp );
1335 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1336 hcf_status = wl_connect( lp );
1339 DBG_WARNING( DbgInfo, "wl_put_ltv() failed\n" );
1345 DBG_LEAVE( DbgInfo );
1348 /*============================================================================*/
1351 /*******************************************************************************
1353 *******************************************************************************
1357 * Used to set basic parameters for card initialization.
1361 * lp - a pointer to the wireless adapter's private structure
1365 * an HCF status code
1367 ******************************************************************************/
1368 int wl_put_ltv_init( struct wl_private *lp )
1372 CFG_RID_LOG_STRCT *RidLog;
1373 /*------------------------------------------------------------------------*/
1374 DBG_ENTER( DbgInfo );
1376 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1377 DBG_LEAVE( DbgInfo );
1381 lp->ltvRecord.len = 2;
1382 lp->ltvRecord.typ = CFG_CNTL_OPT;
1384 /* The Card Services build must ALWAYS be configured for 16-bit I/O. PCI or
1385 CardBus can be set to either 16/32 bit I/O, or Bus Master DMA, but only
1388 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_16BIT );
1390 if ( lp->use_dma ) {
1391 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_DMA );
1393 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1397 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1398 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT : 0x%04x\n",
1399 lp->ltvRecord.u.u16[0] );
1400 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT result : 0x%04x\n",
1403 /* Register the list of RIDs on which asynchronous notification is
1404 required. Note that this mechanism replaces the mailbox, so the mailbox
1405 can be queried by the host (if desired) without contention from us */
1408 lp->RidList[i].len = sizeof( lp->ProbeResp );
1409 lp->RidList[i].typ = CFG_ACS_SCAN;
1410 lp->RidList[i].bufp = (wci_recordp)&lp->ProbeResp;
1411 //lp->ProbeResp.infoType = 0xFFFF;
1414 lp->RidList[i].len = sizeof( lp->assoc_stat );
1415 lp->RidList[i].typ = CFG_ASSOC_STAT;
1416 lp->RidList[i].bufp = (wci_recordp)&lp->assoc_stat;
1417 lp->assoc_stat.len = 0xFFFF;
1420 lp->RidList[i].len = 4;
1421 lp->RidList[i].typ = CFG_UPDATED_INFO_RECORD;
1422 lp->RidList[i].bufp = (wci_recordp)&lp->updatedRecord;
1423 lp->updatedRecord.len = 0xFFFF;
1426 lp->RidList[i].len = sizeof( lp->sec_stat );
1427 lp->RidList[i].typ = CFG_SECURITY_STAT;
1428 lp->RidList[i].bufp = (wci_recordp)&lp->sec_stat;
1429 lp->sec_stat.len = 0xFFFF;
1432 lp->RidList[i].typ = 0; // Terminate List
1434 RidLog = (CFG_RID_LOG_STRCT *)&lp->ltvRecord;
1436 RidLog->typ = CFG_REG_INFO_LOG;
1437 RidLog->recordp = (RID_LOGP)&lp->RidList[0];
1439 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1440 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG\n" );
1441 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG result : 0x%04x\n",
1443 DBG_LEAVE( DbgInfo );
1445 } // wl_put_ltv_init
1446 /*============================================================================*/
1449 /*******************************************************************************
1451 *******************************************************************************
1455 * Used by wvlan_apply() and wvlan_go to set the card's configuration.
1459 * lp - a pointer to the wireless adapter's private structure
1463 * an HCF status code
1465 ******************************************************************************/
1466 int wl_put_ltv( struct wl_private *lp )
1470 /*------------------------------------------------------------------------*/
1471 DBG_ENTER( DbgInfo );
1474 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1477 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1478 lp->maxPort = 6; //;?why set this here and not as part of download process
1483 /* Send our configuration to the card. Perform any endian translation
1485 /* Register the Mailbox; VxWorks does this elsewhere; why;? */
1486 lp->ltvRecord.len = 4;
1487 lp->ltvRecord.typ = CFG_REG_MB;
1488 lp->ltvRecord.u.u32[0] = (u_long)&( lp->mailbox );
1489 lp->ltvRecord.u.u16[2] = ( MB_SIZE / sizeof( hcf_16 ));
1490 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1492 /* Max Data Length */
1493 lp->ltvRecord.len = 2;
1494 lp->ltvRecord.typ = CFG_CNF_MAX_DATA_LEN;
1495 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( HCF_MAX_PACKET_SIZE );
1496 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1498 /* System Scale / Distance between APs */
1499 lp->ltvRecord.len = 2;
1500 lp->ltvRecord.typ = CFG_CNF_SYSTEM_SCALE;
1501 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DistanceBetweenAPs );
1502 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1505 if ( lp->CreateIBSS && ( lp->Channel == 0 )) {
1506 DBG_TRACE( DbgInfo, "Create IBSS" );
1509 lp->ltvRecord.len = 2;
1510 lp->ltvRecord.typ = CFG_CNF_OWN_CHANNEL;
1511 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->Channel );
1512 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1514 /* Microwave Robustness */
1515 lp->ltvRecord.len = 2;
1516 lp->ltvRecord.typ = CFG_CNF_MICRO_WAVE;
1517 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MicrowaveRobustness );
1518 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1520 /* Load Balancing */
1521 lp->ltvRecord.len = 2;
1522 lp->ltvRecord.typ = CFG_CNF_LOAD_BALANCING;
1523 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->loadBalancing );
1524 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1526 /* Medium Distribution */
1527 lp->ltvRecord.len = 2;
1528 lp->ltvRecord.typ = CFG_CNF_MEDIUM_DISTRIBUTION;
1529 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->mediumDistribution );
1530 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1534 /* Tx Power Level (for supported cards) */
1535 lp->ltvRecord.len = 2;
1536 lp->ltvRecord.typ = CFG_CNF_TX_POW_LVL;
1537 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->txPowLevel );
1538 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1540 /* Short Retry Limit */
1541 /*lp->ltvRecord.len = 2;
1542 lp->ltvRecord.typ = 0xFC32;
1543 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->shortRetryLimit );
1544 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1547 /* Long Retry Limit */
1548 /*lp->ltvRecord.len = 2;
1549 lp->ltvRecord.typ = 0xFC33;
1550 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->longRetryLimit );
1551 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1554 /* Supported Rate Set Control */
1555 lp->ltvRecord.len = 3;
1556 lp->ltvRecord.typ = CFG_SUPPORTED_RATE_SET_CNTL; //0xFC88;
1557 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->srsc[0] );
1558 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->srsc[1] );
1559 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1561 /* Basic Rate Set Control */
1562 lp->ltvRecord.len = 3;
1563 lp->ltvRecord.typ = CFG_BASIC_RATE_SET_CNTL; //0xFC89;
1564 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->brsc[0] );
1565 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->brsc[1] );
1566 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1568 /* Frame Burst Limit */
1569 /* Defined, but not currently available in Firmware */
1574 /* Multicast Rate */
1575 lp->ltvRecord.len = 3;
1576 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1577 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1578 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->MulticastRate[1] );
1580 lp->ltvRecord.len = 2;
1581 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1582 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1584 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1586 /* Own Name (Station Nickname) */
1587 if (( len = ( strlen( lp->StationName ) + 1 ) & ~0x01 ) != 0 ) {
1588 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : %s\n",
1589 // lp->StationName );
1591 lp->ltvRecord.len = 2 + ( len / sizeof( hcf_16 ));
1592 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1593 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->StationName ));
1595 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->StationName, len );
1597 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : EMPTY\n" );
1599 lp->ltvRecord.len = 2;
1600 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1601 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1604 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1606 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME result : 0x%04x\n",
1609 /* The following are set in STA mode only */
1610 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1613 lp->ltvRecord.len = 2;
1614 lp->ltvRecord.typ = CFG_RTS_THRH;
1615 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1616 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1619 lp->ltvRecord.len = 2;
1620 lp->ltvRecord.typ = CFG_CNF_PORT_TYPE;
1621 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PortType );
1622 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1624 /* Tx Rate Control */
1626 lp->ltvRecord.len = 3;
1627 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1628 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1629 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1631 lp->ltvRecord.len = 2;
1632 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1633 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1636 //;?skip temporarily to see whether the RID or something else is the problem hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1638 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 2.4GHz : 0x%04x\n",
1639 lp->TxRateControl[0] );
1640 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 5.0GHz : 0x%04x\n",
1641 lp->TxRateControl[1] );
1642 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL result : 0x%04x\n",
1644 /* Power Management */
1645 lp->ltvRecord.len = 2;
1646 lp->ltvRecord.typ = CFG_CNF_PM_ENABLED;
1647 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PMEnabled );
1648 // lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0x8001 );
1649 DBG_TRACE( DbgInfo, "CFG_CNF_PM_ENABLED : 0x%04x\n", lp->PMEnabled );
1650 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1651 /* Multicast Receive */
1652 lp->ltvRecord.len = 2;
1653 lp->ltvRecord.typ = CFG_CNF_MCAST_RX;
1654 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastReceive );
1655 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1657 /* Max Sleep Duration */
1658 lp->ltvRecord.len = 2;
1659 lp->ltvRecord.typ = CFG_CNF_MAX_SLEEP_DURATION;
1660 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MaxSleepDuration );
1661 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1664 lp->ltvRecord.len = 2;
1665 lp->ltvRecord.typ = CFG_CREATE_IBSS;
1666 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->CreateIBSS );
1667 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1670 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1671 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1672 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1673 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : %s\n",
1674 // lp->NetworkName );
1676 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1677 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1678 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1680 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1682 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : ANY\n" );
1684 lp->ltvRecord.len = 2;
1685 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1686 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1689 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1691 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID result : 0x%04x\n",
1693 /* Own ATIM window */
1694 lp->ltvRecord.len = 2;
1695 lp->ltvRecord.typ = CFG_CNF_OWN_ATIM_WINDOW;
1696 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->atimWindow );
1697 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1700 /* Holdover Duration */
1701 lp->ltvRecord.len = 2;
1702 lp->ltvRecord.typ = CFG_CNF_HOLDOVER_DURATION;
1703 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->holdoverDuration );
1704 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1706 /* Promiscuous Mode */
1707 lp->ltvRecord.len = 2;
1708 lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
1709 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->promiscuousMode );
1710 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1712 /* Authentication */
1713 lp->ltvRecord.len = 2;
1714 lp->ltvRecord.typ = CFG_CNF_AUTHENTICATION;
1715 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->authentication );
1716 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1718 /* Connection Control */
1719 lp->ltvRecord.len = 2;
1720 lp->ltvRecord.typ = CFG_CNF_CONNECTION_CNTL;
1721 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->connectionControl );
1722 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1726 /* Probe data rate */
1727 /*lp->ltvRecord.len = 3;
1728 lp->ltvRecord.typ = CFG_PROBE_DATA_RATE;
1729 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->probeDataRates[0] );
1730 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->probeDataRates[1] );
1731 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1733 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 2.4GHz : 0x%04x\n",
1734 lp->probeDataRates[0] );
1735 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 5.0GHz : 0x%04x\n",
1736 lp->probeDataRates[1] );
1737 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE result : 0x%04x\n",
1741 /* The following are set in AP mode only */
1742 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
1743 //;?should we restore this to allow smaller memory footprint
1746 lp->ltvRecord.len = 2;
1747 lp->ltvRecord.typ = CFG_CNF_OWN_DTIM_PERIOD;
1748 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DTIMPeriod );
1749 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1751 /* Multicast PM Buffering */
1752 lp->ltvRecord.len = 2;
1753 lp->ltvRecord.typ = CFG_CNF_MCAST_PM_BUF;
1754 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->multicastPMBuffering );
1755 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1757 /* Reject ANY - Closed System */
1758 lp->ltvRecord.len = 2;
1759 lp->ltvRecord.typ = CFG_CNF_REJECT_ANY;
1760 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RejectAny );
1762 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1764 /* Exclude Unencrypted */
1765 lp->ltvRecord.len = 2;
1766 lp->ltvRecord.typ = CFG_CNF_EXCL_UNENCRYPTED;
1767 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ExcludeUnencrypted );
1769 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1771 /* IntraBSS Relay */
1772 lp->ltvRecord.len = 2;
1773 lp->ltvRecord.typ = CFG_CNF_INTRA_BSS_RELAY;
1774 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->intraBSSRelay );
1775 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1777 /* RTS Threshold 0 */
1778 lp->ltvRecord.len = 2;
1779 lp->ltvRecord.typ = CFG_RTS_THRH0;
1780 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1782 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1784 /* Tx Rate Control 0 */
1786 lp->ltvRecord.len = 3;
1787 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1788 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1789 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1791 lp->ltvRecord.len = 2;
1792 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1793 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1796 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1798 /* Own Beacon Interval */
1799 lp->ltvRecord.len = 2;
1800 lp->ltvRecord.typ = 0xFC31;
1801 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ownBeaconInterval );
1802 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1804 /* Co-Existence Behavior */
1805 lp->ltvRecord.len = 2;
1806 lp->ltvRecord.typ = 0xFCC7;
1807 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->coexistence );
1808 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1812 /* RTS Threshold 1 */
1813 lp->ltvRecord.len = 2;
1814 lp->ltvRecord.typ = CFG_RTS_THRH1;
1815 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].rtsThreshold );
1816 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1818 /* RTS Threshold 2 */
1819 lp->ltvRecord.len = 2;
1820 lp->ltvRecord.typ = CFG_RTS_THRH2;
1821 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].rtsThreshold );
1822 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1825 /* RTS Threshold 3 */
1826 lp->ltvRecord.len = 2;
1827 lp->ltvRecord.typ = CFG_RTS_THRH3;
1828 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].rtsThreshold );
1829 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1832 /* RTS Threshold 4 */
1833 lp->ltvRecord.len = 2;
1834 lp->ltvRecord.typ = CFG_RTS_THRH4;
1835 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].rtsThreshold );
1836 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1839 /* RTS Threshold 5 */
1840 lp->ltvRecord.len = 2;
1841 lp->ltvRecord.typ = CFG_RTS_THRH5;
1842 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].rtsThreshold );
1843 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1845 /* RTS Threshold 6 */
1846 lp->ltvRecord.len = 2;
1847 lp->ltvRecord.typ = CFG_RTS_THRH6;
1848 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].rtsThreshold );
1849 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1851 /* TX Rate Control 1 */
1852 lp->ltvRecord.len = 2;
1853 lp->ltvRecord.typ = CFG_TX_RATE_CNTL1;
1854 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].txRateCntl );
1855 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1857 /* TX Rate Control 2 */
1858 lp->ltvRecord.len = 2;
1859 lp->ltvRecord.typ = CFG_TX_RATE_CNTL2;
1860 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].txRateCntl );
1861 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1863 /* TX Rate Control 3 */
1864 lp->ltvRecord.len = 2;
1865 lp->ltvRecord.typ = CFG_TX_RATE_CNTL3;
1866 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].txRateCntl );
1867 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1869 /* TX Rate Control 4 */
1870 lp->ltvRecord.len = 2;
1871 lp->ltvRecord.typ = CFG_TX_RATE_CNTL4;
1872 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].txRateCntl );
1873 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1875 /* TX Rate Control 5 */
1876 lp->ltvRecord.len = 2;
1877 lp->ltvRecord.typ = CFG_TX_RATE_CNTL5;
1878 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].txRateCntl );
1879 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1881 /* TX Rate Control 6 */
1882 lp->ltvRecord.len = 2;
1883 lp->ltvRecord.typ = CFG_TX_RATE_CNTL6;
1884 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].txRateCntl );
1885 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1889 /* WDS addresses. It's okay to blindly send these parameters, because
1890 the port needs to be enabled, before anything is done with it. */
1893 lp->ltvRecord.len = 4;
1894 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR1;
1896 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[0].wdsAddress, ETH_ALEN );
1897 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1900 lp->ltvRecord.len = 4;
1901 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR2;
1903 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[1].wdsAddress, ETH_ALEN );
1904 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1907 lp->ltvRecord.len = 4;
1908 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR3;
1910 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[2].wdsAddress, ETH_ALEN );
1911 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1914 lp->ltvRecord.len = 4;
1915 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR4;
1917 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[3].wdsAddress, ETH_ALEN );
1918 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1921 lp->ltvRecord.len = 4;
1922 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR5;
1924 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[4].wdsAddress, ETH_ALEN );
1925 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1928 lp->ltvRecord.len = 4;
1929 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR6;
1931 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[5].wdsAddress, ETH_ALEN );
1932 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1933 #endif /* USE_WDS */
1934 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1937 /* Own MAC Address */
1939 DBG_TRACE(DbgInfo, "MAC Address : %pM\n",
1943 if ( WVLAN_VALID_MAC_ADDRESS( lp->MACAddress )) {
1944 /* Make the MAC address valid by:
1945 Clearing the multicast bit
1946 Setting the local MAC address bit
1948 //lp->MACAddress[0] &= ~0x03; //;?why is this commented out already in 720
1949 //lp->MACAddress[0] |= 0x02;
1951 lp->ltvRecord.len = 1 + ( ETH_ALEN / sizeof( hcf_16 ));
1952 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1953 //DBG_TRACE( DbgInfo, "CFG_NIC_MAC_ADDR\n" );
1954 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1956 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_MAC_ADDR\n" );
1957 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1959 /* MAC address is byte aligned, no endian conversion needed */
1960 memcpy( &( lp->ltvRecord.u.u8[0] ), lp->MACAddress, ETH_ALEN );
1961 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1962 //DBG_TRACE( DbgInfo, "CFG_XXX_MAC_ADDR result : 0x%04x\n",
1965 /* Update the MAC address in the netdevice struct */
1966 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN ); //;?what is the purpose of this seemingly complex logic
1969 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1970 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1971 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1972 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : %s\n",
1973 // lp->NetworkName );
1974 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1975 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1976 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1978 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1980 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : ANY\n" );
1981 lp->ltvRecord.len = 2;
1982 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1983 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1986 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1988 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID result : 0x%04x\n",
1990 /* enable/disable encryption */
1991 lp->ltvRecord.len = 2;
1992 lp->ltvRecord.typ = CFG_CNF_ENCRYPTION;
1993 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->EnableEncryption );
1994 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1996 /* Set the Authentication Key Management Suite */
1997 lp->ltvRecord.len = 2;
1998 lp->ltvRecord.typ = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
1999 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->AuthKeyMgmtSuite );
2000 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2002 /* If WEP (or no) keys are being used, write (or clear) them */
2003 if (lp->wext_enc != IW_ENCODE_ALG_TKIP)
2004 wl_set_wep_keys(lp);
2007 /* countryInfo, ltvCountryInfo, CFG_CNF_COUNTRY_INFO */
2009 DBG_LEAVE( DbgInfo );
2012 /*============================================================================*/
2015 /*******************************************************************************
2017 *******************************************************************************
2021 * Load the kernel module.
2030 * an errno value otherwise
2032 ******************************************************************************/
2033 static int __init wl_module_init( void )
2036 /*------------------------------------------------------------------------*/
2040 /* Convert "standard" PCMCIA parameter pc_debug to a reasonable DebugFlag value.
2041 * NOTE: The values all fall through to the lower values. */
2042 DbgInfo->DebugFlag = 0;
2043 DbgInfo->DebugFlag = DBG_TRACE_ON; //;?get this mess resolved one day
2044 if ( pc_debug ) switch( pc_debug ) {
2046 DbgInfo->DebugFlag |= DBG_DS_ON;
2048 DbgInfo->DebugFlag |= DBG_RX_ON | DBG_TX_ON;
2050 DbgInfo->DebugFlag |= DBG_PARAM_ON;
2052 DbgInfo->DebugFlag |= DBG_TRACE_ON;
2054 DbgInfo->DebugFlag |= DBG_VERBOSE_ON;
2056 DbgInfo->DebugFlag |= DBG_DEFAULTS;
2062 DBG_ENTER( DbgInfo );
2063 printk(KERN_INFO "%s\n", VERSION_INFO);
2064 printk(KERN_INFO "*** Modified for kernel 2.6 by Henk de Groot <pe1dnn@amsat.org>\n");
2065 printk(KERN_INFO "*** Based on 7.18 version by Andrey Borzenkov <arvidjaar@mail.ru> $Revision: 39 $\n");
2068 // ;?#if (HCF_TYPE) & HCF_TYPE_AP
2069 // DBG_PRINT( "Access Point Mode (AP) Support: YES\n" );
2071 // DBG_PRINT( "Access Point Mode (AP) Support: NO\n" );
2072 // #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2074 result = wl_adapter_init_module( );
2075 DBG_LEAVE( DbgInfo );
2078 /*============================================================================*/
2081 /*******************************************************************************
2083 *******************************************************************************
2087 * Unload the kernel module.
2097 ******************************************************************************/
2098 static void __exit wl_module_exit( void )
2102 wl_adapter_cleanup_module( );
2103 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
2104 remove_proc_entry( "wlags", NULL ); //;?why so a-symmetric compared to location of proc_create_data
2107 DBG_LEAVE( DbgInfo );
2110 /*============================================================================*/
2112 module_init(wl_module_init);
2113 module_exit(wl_module_exit);
2115 /*******************************************************************************
2117 *******************************************************************************
2121 * The Interrupt Service Routine for the driver.
2125 * irq - the irq the interrupt came in on
2126 * dev_id - a buffer containing information about the request
2133 ******************************************************************************/
2134 irqreturn_t wl_isr( int irq, void *dev_id, struct pt_regs *regs )
2137 struct net_device *dev = (struct net_device *) dev_id;
2138 struct wl_private *lp = NULL;
2139 /*------------------------------------------------------------------------*/
2140 if (( dev == NULL ) || ( !netif_device_present( dev ))) {
2144 /* Set the wl_private pointer (lp), now that we know that dev is non-null */
2148 if ( lp->useRTS == 1 ) {
2149 DBG_PRINT( "EXITING ISR, IN RTS MODE...\n" );
2152 #endif /* USE_RTS */
2154 /* If we have interrupts pending, then put them on a system task
2155 queue. Otherwise turn interrupts back on */
2156 events = hcf_action( &lp->hcfCtx, HCF_ACT_INT_OFF );
2158 if ( events == HCF_INT_PENDING ) {
2159 /* Schedule the ISR handler as a bottom-half task in the
2160 tq_immediate queue */
2161 tasklet_schedule(&lp->task);
2163 //DBG_PRINT( "NOT OUR INTERRUPT\n" );
2164 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2167 return IRQ_RETVAL(events == HCF_INT_PENDING);
2169 /*============================================================================*/
2172 /*******************************************************************************
2174 *******************************************************************************
2178 * The ISR handler, scheduled to run in a deferred context by the ISR. This
2179 * is where the ISR's work actually gets done.
2183 * lp - a pointer to the device's private adapter structure
2189 ******************************************************************************/
2190 #define WVLAN_MAX_INT_SERVICES 50
2192 void wl_isr_handler( unsigned long p )
2194 struct net_device *dev;
2195 unsigned long flags;
2199 struct wl_private *lp = (struct wl_private *)p;
2200 /*------------------------------------------------------------------------*/
2203 DBG_PRINT( "wl_isr_handler lp adapter pointer is NULL!!!\n" );
2205 wl_lock( lp, &flags );
2207 dev = (struct net_device *)lp->dev;
2208 if ( dev != NULL && netif_device_present( dev ) ) stop = FALSE;
2209 for( count = 0; stop == FALSE && count < WVLAN_MAX_INT_SERVICES; count++ ) {
2211 result = hcf_service_nic( &lp->hcfCtx,
2212 (wci_bufp)lp->lookAheadBuf,
2213 sizeof( lp->lookAheadBuf ));
2214 if ( result == HCF_ERR_MIC ) {
2215 wl_wext_event_mic_failed( dev ); /* Send an event that MIC failed */
2216 //;?this seems wrong if HCF_ERR_MIC coincides with another event, stop gets FALSE
2217 //so why not do it always ;?
2220 #ifndef USE_MBOX_SYNC
2221 if ( lp->hcfCtx.IFB_MBInfoLen != 0 ) { /* anything in the mailbox */
2226 /* Check for a Link status event */
2227 if ( ( lp->hcfCtx.IFB_LinkStat & CFG_LINK_STAT_FW ) != 0 ) {
2228 wl_process_link_status( lp );
2231 /* Check for probe response events */
2232 if ( lp->ProbeResp.infoType != 0 &&
2233 lp->ProbeResp.infoType != 0xFFFF ) {
2234 wl_process_probe_response( lp );
2235 memset( &lp->ProbeResp, 0, sizeof( lp->ProbeResp ));
2236 lp->ProbeResp.infoType = 0xFFFF;
2239 /* Check for updated record events */
2240 if ( lp->updatedRecord.len != 0xFFFF ) {
2241 wl_process_updated_record( lp );
2242 lp->updatedRecord.len = 0xFFFF;
2245 /* Check for association status events */
2246 if ( lp->assoc_stat.len != 0xFFFF ) {
2247 wl_process_assoc_status( lp );
2248 lp->assoc_stat.len = 0xFFFF;
2251 /* Check for security status events */
2252 if ( lp->sec_stat.len != 0xFFFF ) {
2253 wl_process_security_status( lp );
2254 lp->sec_stat.len = 0xFFFF;
2259 if ( lp->use_dma ) {
2260 /* Check for DMA Rx packets */
2261 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_RDMAD ) {
2265 /* Return Tx DMA descriptors to host */
2266 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_TDMAD ) {
2267 wl_pci_dma_hcf_reclaim_tx( lp );
2272 #endif // ENABLE_DMA
2274 /* Check for Rx packets */
2275 if ( lp->hcfCtx.IFB_RxLen != 0 ) {
2279 /* Make sure that queued frames get sent */
2280 if ( wl_send( lp )) {
2285 /* We're done, so turn interrupts which were turned off in wl_isr, back on */
2286 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2287 wl_unlock( lp, &flags );
2291 /*============================================================================*/
2294 /*******************************************************************************
2296 *******************************************************************************
2300 * Notify the adapter that it has been removed. Since the adapter is gone,
2301 * we should no longer try to talk to it.
2305 * dev - a pointer to the device's net_device structure
2311 ******************************************************************************/
2312 void wl_remove( struct net_device *dev )
2314 struct wl_private *lp = wl_priv(dev);
2315 unsigned long flags;
2316 /*------------------------------------------------------------------------*/
2317 DBG_ENTER( DbgInfo );
2319 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2321 wl_lock( lp, &flags );
2323 /* stop handling interrupts */
2324 wl_act_int_off( lp );
2325 lp->is_handling_int = WL_NOT_HANDLING_INT;
2328 * Disable the ports: just change state: since the
2329 * card is gone it is useless to talk to it and at
2330 * disconnect all state information is lost anyway.
2332 /* Reset portState */
2333 lp->portState = WVLAN_PORT_STATE_DISABLED;
2335 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
2337 //wl_disable_wds_ports( lp );
2339 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2341 /* Mark the device as unregistered */
2342 lp->is_registered = FALSE;
2344 /* Deregister the WDS ports as well */
2345 WL_WDS_NETDEV_DEREGISTER( lp );
2347 if ( lp->useRTS == 1 ) {
2348 wl_unlock( lp, &flags );
2350 DBG_LEAVE( DbgInfo );
2353 #endif /* USE_RTS */
2355 /* Inform the HCF that the card has been removed */
2356 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2358 wl_unlock( lp, &flags );
2360 DBG_LEAVE( DbgInfo );
2363 /*============================================================================*/
2366 /*******************************************************************************
2368 *******************************************************************************
2372 * Power-down and halt the adapter.
2376 * dev - a pointer to the device's net_device structure
2382 ******************************************************************************/
2383 void wl_suspend( struct net_device *dev )
2385 struct wl_private *lp = wl_priv(dev);
2386 unsigned long flags;
2387 /*------------------------------------------------------------------------*/
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_ENTER( DbgInfo );
2445 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2447 wl_lock( lp, &flags );
2449 /* Connect to the adapter */
2450 hcf_connect( &lp->hcfCtx, dev->base_addr );
2452 /* Reset portState */
2453 lp->portState = WVLAN_PORT_STATE_DISABLED;
2455 /* Power might have been off, assume the card lost the firmware*/
2456 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
2458 /* Reload the firmware and restart */
2461 /* Resume interrupt handling */
2462 wl_act_int_on( lp );
2464 wl_unlock( lp, &flags );
2466 DBG_LEAVE( DbgInfo );
2469 /*============================================================================*/
2472 /*******************************************************************************
2474 *******************************************************************************
2478 * This function performs a check on the device and calls wl_remove() if
2479 * necessary. This function can be used for all bus types, but exists mostly
2480 * for the benefit of the Card Services driver, as there are times when
2481 * wl_remove() does not get called.
2485 * dev - a pointer to the device's net_device structure
2491 ******************************************************************************/
2492 void wl_release( struct net_device *dev )
2494 struct wl_private *lp = wl_priv(dev);
2495 /*------------------------------------------------------------------------*/
2496 DBG_ENTER( DbgInfo );
2498 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2499 /* If wl_remove() hasn't been called (i.e. when Card Services is shut
2500 down with the card in the slot), then call it */
2501 if ( lp->is_registered == TRUE ) {
2502 DBG_TRACE( DbgInfo, "Calling unregister_netdev(), as it wasn't called yet\n" );
2505 lp->is_registered = FALSE;
2508 DBG_LEAVE( DbgInfo );
2511 /*============================================================================*/
2514 /*******************************************************************************
2516 *******************************************************************************
2520 * Accessor function to retrieve the irq_mask module parameter
2528 * The irq_mask module parameter
2530 ******************************************************************************/
2531 p_u16 wl_get_irq_mask( void )
2534 } // wl_get_irq_mask
2535 /*============================================================================*/
2538 /*******************************************************************************
2540 *******************************************************************************
2544 * Accessor function to retrieve the irq_list module parameter
2552 * The irq_list module parameter
2554 ******************************************************************************/
2555 p_s8 * wl_get_irq_list( void )
2558 } // wl_get_irq_list
2559 /*============================================================================*/
2563 /*******************************************************************************
2565 *******************************************************************************
2569 * Used to enable MAC ports
2573 * lp - pointer to the device's private adapter structure
2579 ******************************************************************************/
2580 int wl_enable( struct wl_private *lp )
2582 int hcf_status = HCF_SUCCESS;
2583 /*------------------------------------------------------------------------*/
2584 DBG_ENTER( DbgInfo );
2586 if ( lp->portState == WVLAN_PORT_STATE_ENABLED ) {
2587 DBG_TRACE( DbgInfo, "No action: Card already enabled\n" );
2588 } else if ( lp->portState == WVLAN_PORT_STATE_CONNECTED ) {
2589 //;?suspicuous logic, how can you be connected without being enabled so this is probably dead code
2590 DBG_TRACE( DbgInfo, "No action: Card already connected\n" );
2592 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_ENABLE );
2593 if ( hcf_status == HCF_SUCCESS ) {
2594 /* Set the status of the NIC to enabled */
2595 lp->portState = WVLAN_PORT_STATE_ENABLED; //;?bad mnemonic, NIC iso PORT
2597 if ( lp->use_dma ) {
2598 wl_pci_dma_hcf_supply( lp ); //;?always successful?
2603 if ( hcf_status != HCF_SUCCESS ) { //;?make this an assert
2604 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2606 DBG_LEAVE( DbgInfo );
2609 /*============================================================================*/
2613 /*******************************************************************************
2614 * wl_enable_wds_ports()
2615 *******************************************************************************
2619 * Used to enable the WDS MAC ports 1-6
2623 * lp - pointer to the device's private adapter structure
2629 ******************************************************************************/
2630 void wl_enable_wds_ports( struct wl_private * lp )
2632 DBG_ENTER( DbgInfo );
2633 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2634 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2636 DBG_LEAVE( DbgInfo );
2638 } // wl_enable_wds_ports
2639 #endif /* USE_WDS */
2640 /*============================================================================*/
2643 /*******************************************************************************
2645 *******************************************************************************
2649 * Used to connect a MAC port
2653 * lp - pointer to the device's private adapter structure
2659 ******************************************************************************/
2660 int wl_connect( struct wl_private *lp )
2663 /*------------------------------------------------------------------------*/
2665 DBG_ENTER( DbgInfo );
2667 if ( lp->portState != WVLAN_PORT_STATE_ENABLED ) {
2668 DBG_TRACE( DbgInfo, "No action: Not in enabled state\n" );
2669 DBG_LEAVE( DbgInfo );
2672 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_CONNECT );
2673 if ( hcf_status == HCF_SUCCESS ) {
2674 lp->portState = WVLAN_PORT_STATE_CONNECTED;
2676 DBG_LEAVE( DbgInfo );
2679 /*============================================================================*/
2682 /*******************************************************************************
2684 *******************************************************************************
2688 * Used to disconnect a MAC port
2692 * lp - pointer to the device's private adapter structure
2698 ******************************************************************************/
2699 int wl_disconnect( struct wl_private *lp )
2702 /*------------------------------------------------------------------------*/
2704 DBG_ENTER( DbgInfo );
2706 if ( lp->portState != WVLAN_PORT_STATE_CONNECTED ) {
2707 DBG_TRACE( DbgInfo, "No action: Not in connected state\n" );
2708 DBG_LEAVE( DbgInfo );
2711 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISCONNECT );
2712 if ( hcf_status == HCF_SUCCESS ) {
2713 lp->portState = WVLAN_PORT_STATE_ENABLED;
2715 DBG_LEAVE( DbgInfo );
2718 /*============================================================================*/
2721 /*******************************************************************************
2723 *******************************************************************************
2727 * Used to disable MAC ports
2731 * lp - pointer to the device's private adapter structure
2732 * port - the MAC port to disable
2738 ******************************************************************************/
2739 int wl_disable( struct wl_private *lp )
2741 int hcf_status = HCF_SUCCESS;
2742 /*------------------------------------------------------------------------*/
2743 DBG_ENTER( DbgInfo );
2745 if ( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
2746 DBG_TRACE( DbgInfo, "No action: Port state is disabled\n" );
2748 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISABLE );
2749 if ( hcf_status == HCF_SUCCESS ) {
2750 /* Set the status of the port to disabled */ //;?bad mnemonic use NIC iso PORT
2751 lp->portState = WVLAN_PORT_STATE_DISABLED;
2754 if ( lp->use_dma ) {
2755 wl_pci_dma_hcf_reclaim( lp );
2760 if ( hcf_status != HCF_SUCCESS ) {
2761 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2763 DBG_LEAVE( DbgInfo );
2766 /*============================================================================*/
2770 /*******************************************************************************
2771 * wl_disable_wds_ports()
2772 *******************************************************************************
2776 * Used to disable the WDS MAC ports 1-6
2780 * lp - pointer to the device's private adapter structure
2786 ******************************************************************************/
2787 void wl_disable_wds_ports( struct wl_private * lp )
2789 DBG_ENTER( DbgInfo );
2791 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2792 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2794 // if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
2795 // wl_disable( lp, HCF_PORT_1 );
2796 // wl_disable( lp, HCF_PORT_2 );
2797 // wl_disable( lp, HCF_PORT_3 );
2798 // wl_disable( lp, HCF_PORT_4 );
2799 // wl_disable( lp, HCF_PORT_5 );
2800 // wl_disable( lp, HCF_PORT_6 );
2802 DBG_LEAVE( DbgInfo );
2804 } // wl_disable_wds_ports
2806 /*============================================================================*/
2809 #ifndef USE_MBOX_SYNC
2810 /*******************************************************************************
2812 *******************************************************************************
2815 * This function is used to read and process a mailbox message.
2820 * lp - pointer to the device's private adapter structure
2824 * an HCF status code
2826 ******************************************************************************/
2827 int wl_mbx( struct wl_private *lp )
2829 int hcf_status = HCF_SUCCESS;
2830 /*------------------------------------------------------------------------*/
2831 DBG_ENTER( DbgInfo );
2832 DBG_TRACE( DbgInfo, "Mailbox Info: IFB_MBInfoLen: %d\n",
2833 lp->hcfCtx.IFB_MBInfoLen );
2835 memset( &( lp->ltvRecord ), 0, sizeof( ltv_t ));
2837 lp->ltvRecord.len = MB_SIZE;
2838 lp->ltvRecord.typ = CFG_MB_INFO;
2839 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2841 if ( hcf_status != HCF_SUCCESS ) {
2842 DBG_ERROR( DbgInfo, "hcf_get_info returned 0x%x\n", hcf_status );
2844 DBG_LEAVE( DbgInfo );
2848 if ( lp->ltvRecord.typ == CFG_MB_INFO ) {
2849 DBG_LEAVE( DbgInfo );
2852 /* Endian translate the mailbox data, then process the message */
2853 wl_endian_translate_mailbox( &( lp->ltvRecord ));
2854 wl_process_mailbox( lp );
2855 DBG_LEAVE( DbgInfo );
2858 /*============================================================================*/
2861 /*******************************************************************************
2862 * wl_endian_translate_mailbox()
2863 *******************************************************************************
2867 * This function will perform the tedious task of endian translating all
2868 * fields within a mailbox message which need translating.
2872 * ltv - pointer to the LTV to endian translate
2878 ******************************************************************************/
2879 void wl_endian_translate_mailbox( ltv_t *ltv )
2881 DBG_ENTER( DbgInfo );
2882 switch( ltv->typ ) {
2889 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
2891 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2892 ( sizeof( SCAN_RS_STRCT )));
2894 while( num_aps >= 1 ) {
2897 aps[num_aps].channel_id =
2898 CNV_LITTLE_TO_INT( aps[num_aps].channel_id );
2900 aps[num_aps].noise_level =
2901 CNV_LITTLE_TO_INT( aps[num_aps].noise_level );
2903 aps[num_aps].signal_level =
2904 CNV_LITTLE_TO_INT( aps[num_aps].signal_level );
2906 aps[num_aps].beacon_interval_time =
2907 CNV_LITTLE_TO_INT( aps[num_aps].beacon_interval_time );
2909 aps[num_aps].capability =
2910 CNV_LITTLE_TO_INT( aps[num_aps].capability );
2912 aps[num_aps].ssid_len =
2913 CNV_LITTLE_TO_INT( aps[num_aps].ssid_len );
2915 aps[num_aps].ssid_val[aps[num_aps].ssid_len] = 0;
2922 PROBE_RESP *probe_resp = (PROBE_RESP *)ltv;
2924 probe_resp->frameControl = CNV_LITTLE_TO_INT( probe_resp->frameControl );
2925 probe_resp->durID = CNV_LITTLE_TO_INT( probe_resp->durID );
2926 probe_resp->sequence = CNV_LITTLE_TO_INT( probe_resp->sequence );
2927 probe_resp->dataLength = CNV_LITTLE_TO_INT( probe_resp->dataLength );
2929 probe_resp->lenType = CNV_LITTLE_TO_INT( probe_resp->lenType );
2931 probe_resp->beaconInterval = CNV_LITTLE_TO_INT( probe_resp->beaconInterval );
2932 probe_resp->capability = CNV_LITTLE_TO_INT( probe_resp->capability );
2933 probe_resp->flags = CNV_LITTLE_TO_INT( probe_resp->flags );
2938 #define ls ((LINK_STATUS_STRCT *)ltv)
2939 ls->linkStatus = CNV_LITTLE_TO_INT( ls->linkStatus );
2943 case CFG_ASSOC_STAT:
2945 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
2947 as->assocStatus = CNV_LITTLE_TO_INT( as->assocStatus );
2951 case CFG_SECURITY_STAT:
2953 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
2955 ss->securityStatus = CNV_LITTLE_TO_INT( ss->securityStatus );
2956 ss->reason = CNV_LITTLE_TO_INT( ss->reason );
2970 DBG_LEAVE( DbgInfo );
2972 } // wl_endian_translate_mailbox
2973 /*============================================================================*/
2975 /*******************************************************************************
2976 * wl_process_mailbox()
2977 *******************************************************************************
2981 * This function processes the mailbox data.
2985 * ltv - pointer to the LTV to be processed.
2991 ******************************************************************************/
2992 void wl_process_mailbox( struct wl_private *lp )
2995 hcf_16 ltv_val = 0xFFFF;
2996 /*------------------------------------------------------------------------*/
2997 DBG_ENTER( DbgInfo );
2998 ltv = &( lp->ltvRecord );
3000 switch( ltv->typ ) {
3003 DBG_TRACE( DbgInfo, "CFG_TALLIES\n" );
3006 DBG_TRACE( DbgInfo, "CFG_SCAN\n" );
3010 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
3012 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
3013 ( sizeof( SCAN_RS_STRCT )));
3015 lp->scan_results.num_aps = num_aps;
3017 DBG_TRACE( DbgInfo, "Number of APs: %d\n", num_aps );
3019 while( num_aps >= 1 ) {
3022 DBG_TRACE( DbgInfo, "AP : %d\n", num_aps );
3023 DBG_TRACE( DbgInfo, "=========================\n" );
3024 DBG_TRACE( DbgInfo, "Channel ID : 0x%04x\n",
3025 aps[num_aps].channel_id );
3026 DBG_TRACE( DbgInfo, "Noise Level : 0x%04x\n",
3027 aps[num_aps].noise_level );
3028 DBG_TRACE( DbgInfo, "Signal Level : 0x%04x\n",
3029 aps[num_aps].signal_level );
3030 DBG_TRACE( DbgInfo, "Beacon Interval : 0x%04x\n",
3031 aps[num_aps].beacon_interval_time );
3032 DBG_TRACE( DbgInfo, "Capability : 0x%04x\n",
3033 aps[num_aps].capability );
3034 DBG_TRACE( DbgInfo, "SSID Length : 0x%04x\n",
3035 aps[num_aps].ssid_len );
3036 DBG_TRACE(DbgInfo, "BSSID : %pM\n",
3037 aps[num_aps].bssid);
3039 if ( aps[num_aps].ssid_len != 0 ) {
3040 DBG_TRACE( DbgInfo, "SSID : %s.\n",
3041 aps[num_aps].ssid_val );
3043 DBG_TRACE( DbgInfo, "SSID : %s.\n", "ANY" );
3046 DBG_TRACE( DbgInfo, "\n" );
3048 /* Copy the info to the ScanResult structure in the private
3050 memcpy( &( lp->scan_results.APTable[num_aps]), &( aps[num_aps] ),
3051 sizeof( SCAN_RS_STRCT ));
3054 /* Set scan result to true so that any scan requests will
3056 lp->scan_results.scan_complete = TRUE;
3061 DBG_TRACE( DbgInfo, "CFG_ACS_SCAN\n" );
3064 PROBE_RESP *probe_rsp = (PROBE_RESP *)ltv;
3065 hcf_8 *wpa_ie = NULL;
3066 hcf_16 wpa_ie_len = 0;
3068 DBG_TRACE( DbgInfo, "(%s) =========================\n",
3071 DBG_TRACE( DbgInfo, "(%s) length : 0x%04x.\n",
3072 lp->dev->name, probe_rsp->length );
3074 if ( probe_rsp->length > 1 ) {
3075 DBG_TRACE( DbgInfo, "(%s) infoType : 0x%04x.\n",
3076 lp->dev->name, probe_rsp->infoType );
3078 DBG_TRACE( DbgInfo, "(%s) signal : 0x%02x.\n",
3079 lp->dev->name, probe_rsp->signal );
3081 DBG_TRACE( DbgInfo, "(%s) silence : 0x%02x.\n",
3082 lp->dev->name, probe_rsp->silence );
3084 DBG_TRACE( DbgInfo, "(%s) rxFlow : 0x%02x.\n",
3085 lp->dev->name, probe_rsp->rxFlow );
3087 DBG_TRACE( DbgInfo, "(%s) rate : 0x%02x.\n",
3088 lp->dev->name, probe_rsp->rate );
3090 DBG_TRACE( DbgInfo, "(%s) frame cntl : 0x%04x.\n",
3091 lp->dev->name, probe_rsp->frameControl );
3093 DBG_TRACE( DbgInfo, "(%s) durID : 0x%04x.\n",
3094 lp->dev->name, probe_rsp->durID );
3096 DBG_TRACE(DbgInfo, "(%s) address1 : %pM\n",
3097 lp->dev->name, probe_rsp->address1);
3099 DBG_TRACE(DbgInfo, "(%s) address2 : %pM\n",
3100 lp->dev->name, probe_rsp->address2);
3102 DBG_TRACE(DbgInfo, "(%s) BSSID : %pM\n",
3103 lp->dev->name, probe_rsp->BSSID);
3105 DBG_TRACE( DbgInfo, "(%s) sequence : 0x%04x.\n",
3106 lp->dev->name, probe_rsp->sequence );
3108 DBG_TRACE(DbgInfo, "(%s) address4 : %pM\n",
3109 lp->dev->name, probe_rsp->address4);
3111 DBG_TRACE( DbgInfo, "(%s) datalength : 0x%04x.\n",
3112 lp->dev->name, probe_rsp->dataLength );
3114 DBG_TRACE(DbgInfo, "(%s) DA : %pM\n",
3115 lp->dev->name, probe_rsp->DA);
3117 DBG_TRACE(DbgInfo, "(%s) SA : %pM\n",
3118 lp->dev->name, probe_rsp->SA);
3120 //DBG_TRACE( DbgInfo, "(%s) lenType : 0x%04x.\n",
3121 // lp->dev->name, probe_rsp->lenType );
3123 DBG_TRACE(DbgInfo, "(%s) timeStamp : "
3124 "%d.%d.%d.%d.%d.%d.%d.%d\n",
3126 probe_rsp->timeStamp[0],
3127 probe_rsp->timeStamp[1],
3128 probe_rsp->timeStamp[2],
3129 probe_rsp->timeStamp[3],
3130 probe_rsp->timeStamp[4],
3131 probe_rsp->timeStamp[5],
3132 probe_rsp->timeStamp[6],
3133 probe_rsp->timeStamp[7]);
3135 DBG_TRACE( DbgInfo, "(%s) beaconInt : 0x%04x.\n",
3136 lp->dev->name, probe_rsp->beaconInterval );
3138 DBG_TRACE( DbgInfo, "(%s) capability : 0x%04x.\n",
3139 lp->dev->name, probe_rsp->capability );
3141 DBG_TRACE( DbgInfo, "(%s) SSID len : 0x%04x.\n",
3142 lp->dev->name, probe_rsp->rawData[1] );
3144 if ( probe_rsp->rawData[1] > 0 ) {
3145 char ssid[HCF_MAX_NAME_LEN];
3147 memset( ssid, 0, sizeof( ssid ));
3148 strncpy( ssid, &probe_rsp->rawData[2],
3150 probe_rsp->rawData[1],
3151 HCF_MAX_NAME_LEN - 1));
3153 DBG_TRACE( DbgInfo, "(%s) SSID : %s\n",
3154 lp->dev->name, ssid );
3157 /* Parse out the WPA-IE, if one exists */
3158 wpa_ie = wl_parse_wpa_ie( probe_rsp, &wpa_ie_len );
3159 if ( wpa_ie != NULL ) {
3160 DBG_TRACE( DbgInfo, "(%s) WPA-IE : %s\n",
3161 lp->dev->name, wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
3164 DBG_TRACE( DbgInfo, "(%s) flags : 0x%04x.\n",
3165 lp->dev->name, probe_rsp->flags );
3168 DBG_TRACE( DbgInfo, "\n\n" );
3169 /* If probe response length is 1, then the scan is complete */
3170 if ( probe_rsp->length == 1 ) {
3171 DBG_TRACE( DbgInfo, "SCAN COMPLETE\n" );
3172 lp->probe_results.num_aps = lp->probe_num_aps;
3173 lp->probe_results.scan_complete = TRUE;
3175 /* Reset the counter for the next scan request */
3176 lp->probe_num_aps = 0;
3178 /* Send a wireless extensions event that the scan completed */
3179 wl_wext_event_scan_complete( lp->dev );
3181 /* Only copy to the table if the entry is unique; APs sometimes
3182 respond more than once to a probe */
3183 if ( lp->probe_num_aps == 0 ) {
3184 /* Copy the info to the ScanResult structure in the private
3186 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3187 probe_rsp, sizeof( PROBE_RESP ));
3189 /* Increment the number of APs detected */
3190 lp->probe_num_aps++;
3195 for( count = 0; count < lp->probe_num_aps; count++ ) {
3196 if ( memcmp( &( probe_rsp->BSSID ),
3197 lp->probe_results.ProbeTable[count].BSSID,
3204 /* Copy the info to the ScanResult structure in the
3205 private adapter struct. Only copy if there's room in the
3207 if ( lp->probe_num_aps < MAX_NAPS )
3209 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3210 probe_rsp, sizeof( PROBE_RESP ));
3214 DBG_WARNING( DbgInfo, "Num of scan results exceeds storage, truncating\n" );
3217 /* Increment the number of APs detected. Note I do this
3218 here even when I don't copy the probe response to the
3219 buffer in order to detect the overflow condition */
3220 lp->probe_num_aps++;
3229 #define ls ((LINK_STATUS_STRCT *)ltv)
3230 DBG_TRACE( DbgInfo, "CFG_LINK_STAT\n" );
3232 switch( ls->linkStatus ) {
3234 DBG_TRACE( DbgInfo, "Link Status : Connected\n" );
3235 wl_wext_event_ap( lp->dev );
3239 DBG_TRACE( DbgInfo, "Link Status : Disconnected\n" );
3243 DBG_TRACE( DbgInfo, "Link Status : Access Point Change\n" );
3247 DBG_TRACE( DbgInfo, "Link Status : Access Point Out of Range\n" );
3251 DBG_TRACE( DbgInfo, "Link Status : Access Point In Range\n" );
3255 DBG_TRACE( DbgInfo, "Link Status : UNKNOWN (0x%04x)\n",
3263 case CFG_ASSOC_STAT:
3264 DBG_TRACE( DbgInfo, "CFG_ASSOC_STAT\n" );
3267 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
3269 switch( as->assocStatus ) {
3271 DBG_TRACE( DbgInfo, "Association Status : STA Associated\n" );
3275 DBG_TRACE( DbgInfo, "Association Status : STA Reassociated\n" );
3279 DBG_TRACE( DbgInfo, "Association Status : STA Disassociated\n" );
3283 DBG_TRACE( DbgInfo, "Association Status : UNKNOWN (0x%04x)\n",
3288 DBG_TRACE(DbgInfo, "STA Address : %pM\n",
3291 if (( as->assocStatus == 2 ) && ( as->len == 8 )) {
3292 DBG_TRACE(DbgInfo, "Old AP Address : %pM\n",
3299 case CFG_SECURITY_STAT:
3300 DBG_TRACE( DbgInfo, "CFG_SECURITY_STAT\n" );
3303 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
3305 switch( ss->securityStatus ) {
3307 DBG_TRACE( DbgInfo, "Security Status : Dissassociate [AP]\n" );
3311 DBG_TRACE( DbgInfo, "Security Status : Deauthenticate [AP]\n" );
3315 DBG_TRACE( DbgInfo, "Security Status : Authenticate Fail [STA] or [AP]\n" );
3319 DBG_TRACE( DbgInfo, "Security Status : MIC Fail\n" );
3323 DBG_TRACE( DbgInfo, "Security Status : Associate Fail\n" );
3327 DBG_TRACE( DbgInfo, "Security Status : UNKNOWN %d\n",
3328 ss->securityStatus );
3332 DBG_TRACE(DbgInfo, "STA Address : %pM\n",
3335 DBG_TRACE(DbgInfo, "Reason : 0x%04x\n",
3342 DBG_TRACE( DbgInfo, "CFG_WMP, size is %d bytes\n", ltv->len );
3344 WMP_RSP_STRCT *wmp_rsp = (WMP_RSP_STRCT *)ltv;
3346 DBG_TRACE( DbgInfo, "CFG_WMP, pdu type is 0x%x\n",
3347 wmp_rsp->wmpRsp.wmpHdr.type );
3349 switch( wmp_rsp->wmpRsp.wmpHdr.type ) {
3350 case WVLAN_WMP_PDU_TYPE_LT_RSP:
3353 LINKTEST_RSP_STRCT *lt_rsp = (LINKTEST_RSP_STRCT *)ltv;
3355 DBG_TRACE( DbgInfo, "LINK TEST RESULT\n" );
3356 DBG_TRACE( DbgInfo, "================\n" );
3357 DBG_TRACE( DbgInfo, "Length : %d.\n", lt_rsp->len );
3359 DBG_TRACE( DbgInfo, "Name : %s.\n", lt_rsp->ltRsp.ltRsp.name );
3360 DBG_TRACE( DbgInfo, "Signal Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.signal );
3361 DBG_TRACE( DbgInfo, "Noise Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.noise );
3362 DBG_TRACE( DbgInfo, "Receive Flow : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.rxFlow );
3363 DBG_TRACE( DbgInfo, "Data Rate : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRate );
3364 DBG_TRACE( DbgInfo, "Protocol : 0x%04x.\n", lt_rsp->ltRsp.ltRsp.protocol );
3365 DBG_TRACE( DbgInfo, "Station : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.station );
3366 DBG_TRACE( DbgInfo, "Data Rate Cap : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRateCap );
3368 DBG_TRACE( DbgInfo, "Power Mgmt : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3369 lt_rsp->ltRsp.ltRsp.powerMgmt[0],
3370 lt_rsp->ltRsp.ltRsp.powerMgmt[1],
3371 lt_rsp->ltRsp.ltRsp.powerMgmt[2],
3372 lt_rsp->ltRsp.ltRsp.powerMgmt[3] );
3374 DBG_TRACE( DbgInfo, "Robustness : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3375 lt_rsp->ltRsp.ltRsp.robustness[0],
3376 lt_rsp->ltRsp.ltRsp.robustness[1],
3377 lt_rsp->ltRsp.ltRsp.robustness[2],
3378 lt_rsp->ltRsp.ltRsp.robustness[3] );
3380 DBG_TRACE( DbgInfo, "Scaling : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.scaling );
3393 DBG_TRACE( DbgInfo, "CFG_NULL\n" );
3396 case CFG_UPDATED_INFO_RECORD: // Updated Information Record
3397 DBG_TRACE( DbgInfo, "UPDATED INFORMATION RECORD\n" );
3399 ltv_val = CNV_INT_TO_LITTLE( ltv->u.u16[0] );
3401 /* Check and see which RID was updated */
3403 case CFG_CUR_COUNTRY_INFO: // Indicate Passive Scan Completion
3404 DBG_TRACE( DbgInfo, "Updated country info\n" );
3406 /* Do I need to hold off on updating RIDs until the process is
3411 case CFG_PORT_STAT: // Wait for Connect Event
3417 DBG_WARNING( DbgInfo, "Unknown RID: 0x%04x\n", ltv_val );
3423 DBG_TRACE( DbgInfo, "UNKNOWN MESSAGE: 0x%04x\n", ltv->typ );
3426 DBG_LEAVE( DbgInfo );
3428 } // wl_process_mailbox
3429 /*============================================================================*/
3430 #endif /* ifndef USE_MBOX_SYNC */
3433 /*******************************************************************************
3434 * wl_wds_netdev_register()
3435 *******************************************************************************
3439 * This function registers net_device structures with the system's network
3440 * layer for use with the WDS ports.
3445 * lp - pointer to the device's private adapter structure
3451 ******************************************************************************/
3452 void wl_wds_netdev_register( struct wl_private *lp )
3455 /*------------------------------------------------------------------------*/
3456 DBG_ENTER( DbgInfo );
3457 //;?why is there no USE_WDS clause like in wl_enable_wds_ports
3458 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3459 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3460 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3461 if ( register_netdev( lp->wds_port[count].dev ) != 0 ) {
3462 DBG_WARNING( DbgInfo, "net device for WDS port %d could not be registered\n",
3465 lp->wds_port[count].is_registered = TRUE;
3467 /* Fill out the net_device structs with the MAC addr */
3468 memcpy( lp->wds_port[count].dev->dev_addr, lp->MACAddress, ETH_ALEN );
3469 lp->wds_port[count].dev->addr_len = ETH_ALEN;
3473 DBG_LEAVE( DbgInfo );
3475 } // wl_wds_netdev_register
3476 /*============================================================================*/
3479 /*******************************************************************************
3480 * wl_wds_netdev_deregister()
3481 *******************************************************************************
3485 * This function deregisters the WDS net_device structures used by the
3486 * system's network layer.
3491 * lp - pointer to the device's private adapter structure
3497 ******************************************************************************/
3498 void wl_wds_netdev_deregister( struct wl_private *lp )
3501 /*------------------------------------------------------------------------*/
3502 DBG_ENTER( DbgInfo );
3503 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3504 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3505 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3506 unregister_netdev( lp->wds_port[count].dev );
3508 lp->wds_port[count].is_registered = FALSE;
3511 DBG_LEAVE( DbgInfo );
3513 } // wl_wds_netdev_deregister
3514 /*============================================================================*/
3515 #endif /* USE_WDS */
3518 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
3520 * The proc filesystem: function to read and entry
3522 static void printf_hcf_16(struct seq_file *m, const char *s, hcf_16 *p, int n)
3526 seq_printf(m, "%-20.20s: ", s);
3529 for (i = 0; i < n; i++) {
3532 seq_printf(m, "%04X ", p[i]);
3537 static void printf_hcf_8(struct seq_file *m, const char *s, hcf_8 *p, int n)
3541 seq_printf(m, "%-20.20s: ", s);
3544 for (i = 0; i <= n; i++) {
3547 seq_printf(m, "%02X ", p[i]);
3552 static void printf_strct(struct seq_file *m, const char *s, hcf_16 *p)
3556 seq_printf(m, "%-20.20s: ", s);
3559 for ( i = 0; i <= *p; i++ ) {
3562 seq_printf(m,"%04X ", p[i]);
3567 int scull_read_procmem(struct seq_file *m, void *v)
3569 struct wl_private *lp = m->private;
3571 CFG_HERMES_TALLIES_STRCT *p;
3574 seq_puts(m, "No wl_private in scull_read_procmem\n" );
3575 } else if ( lp->wlags49_type == 0 ){
3577 seq_printf(m, "Magic: 0x%04X\n", ifbp->IFB_Magic );
3578 seq_printf(m, "IOBase: 0x%04X\n", ifbp->IFB_IOBase );
3579 seq_printf(m, "LinkStat: 0x%04X\n", ifbp->IFB_LinkStat );
3580 seq_printf(m, "DSLinkStat: 0x%04X\n", ifbp->IFB_DSLinkStat );
3581 seq_printf(m, "TickIni: 0x%08lX\n", ifbp->IFB_TickIni );
3582 seq_printf(m, "TickCnt: 0x%04X\n", ifbp->IFB_TickCnt );
3583 seq_printf(m, "IntOffCnt: 0x%04X\n", ifbp->IFB_IntOffCnt );
3584 printf_hcf_16(m, "IFB_FWIdentity",
3585 &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
3586 } else if ( lp->wlags49_type == 1 ) {
3587 seq_printf(m, "Channel: 0x%04X\n", lp->Channel );
3588 /****** seq_printf(m, "slock: %d\n", lp->slock ); */
3589 //x struct tq_struct "task: 0x%04X\n", lp->task );
3590 //x struct net_device_stats "stats: 0x%04X\n", lp->stats );
3592 //x struct iw_statistics "wstats: 0x%04X\n", lp->wstats );
3593 //x seq_printf(m, "spy_number: 0x%04X\n", lp->spy_number );
3594 //x u_char spy_address[IW_MAX_SPY][ETH_ALEN];
3595 //x struct iw_quality spy_stat[IW_MAX_SPY];
3596 #endif // WIRELESS_EXT
3597 seq_printf(m, "IFB: 0x%p\n", &lp->hcfCtx );
3598 seq_printf(m, "flags: %#.8lX\n", lp->flags ); //;?use this format from now on
3599 seq_printf(m, "DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
3601 seq_printf(m, "DebugFlag (DbgInfo): 0x%08lX\n", DbgInfo->DebugFlag );
3603 seq_printf(m, "is_registered: 0x%04X\n", lp->is_registered );
3604 //x CFG_DRV_INFO_STRCT "driverInfo: 0x%04X\n", lp->driverInfo );
3605 printf_strct( m, "driverInfo", (hcf_16*)&lp->driverInfo );
3606 //x CFG_IDENTITY_STRCT "driverIdentity: 0x%04X\n", lp->driverIdentity );
3607 printf_strct( m, "driverIdentity", (hcf_16*)&lp->driverIdentity );
3608 //x CFG_FW_IDENTITY_STRCT "StationIdentity: 0x%04X\n", lp->StationIdentity );
3609 printf_strct( m, "StationIdentity", (hcf_16*)&lp->StationIdentity );
3610 //x CFG_PRI_IDENTITY_STRCT "PrimaryIdentity: 0x%04X\n", lp->PrimaryIdentity );
3611 printf_strct( m, "PrimaryIdentity", (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
3612 printf_strct( m, "PrimarySupplier", (hcf_16*)&lp->hcfCtx.IFB_PRISup );
3613 //x CFG_PRI_IDENTITY_STRCT "NICIdentity: 0x%04X\n", lp->NICIdentity );
3614 printf_strct( m, "NICIdentity", (hcf_16*)&lp->NICIdentity );
3615 //x ltv_t "ltvRecord: 0x%04X\n", lp->ltvRecord );
3616 seq_printf(m, "txBytes: 0x%08lX\n", lp->txBytes );
3617 seq_printf(m, "maxPort: 0x%04X\n", lp->maxPort ); /* 0 for STA, 6 for AP */
3618 /* Elements used for async notification from hardware */
3619 //x RID_LOG_STRCT RidList[10];
3620 //x ltv_t "updatedRecord: 0x%04X\n", lp->updatedRecord );
3621 //x PROBE_RESP "ProbeResp: 0x%04X\n", lp->ProbeResp );
3622 //x ASSOC_STATUS_STRCT "assoc_stat: 0x%04X\n", lp->assoc_stat );
3623 //x SECURITY_STATUS_STRCT "sec_stat: 0x%04X\n", lp->sec_stat );
3624 //x u_char lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
3625 seq_printf(m, "PortType: 0x%04X\n", lp->PortType ); // 1 - 3 (1 [Normal] | 3 [AdHoc])
3626 seq_printf(m, "Channel: 0x%04X\n", lp->Channel ); // 0 - 14 (0)
3627 //x hcf_16 TxRateControl[2];
3628 seq_printf(m, "TxRateControl[2]: 0x%04X 0x%04X\n",
3629 lp->TxRateControl[0], lp->TxRateControl[1] );
3630 seq_printf(m, "DistanceBetweenAPs: 0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
3631 seq_printf(m, "RTSThreshold: 0x%04X\n", lp->RTSThreshold ); // 0 - 2347 (2347)
3632 seq_printf(m, "PMEnabled: 0x%04X\n", lp->PMEnabled ); // 0 - 2, 8001 - 8002 (0)
3633 seq_printf(m, "MicrowaveRobustness: 0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
3634 seq_printf(m, "CreateIBSS: 0x%04X\n", lp->CreateIBSS ); // 0 - 1 (0)
3635 seq_printf(m, "MulticastReceive: 0x%04X\n", lp->MulticastReceive ); // 0 - 1 (1)
3636 seq_printf(m, "MaxSleepDuration: 0x%04X\n", lp->MaxSleepDuration ); // 0 - 65535 (100)
3637 //x hcf_8 MACAddress[ETH_ALEN];
3638 printf_hcf_8(m, "MACAddress", lp->MACAddress, ETH_ALEN );
3639 //x char NetworkName[HCF_MAX_NAME_LEN+1];
3640 seq_printf(m, "NetworkName: %.32s\n", lp->NetworkName );
3641 //x char StationName[HCF_MAX_NAME_LEN+1];
3642 seq_printf(m, "EnableEncryption: 0x%04X\n", lp->EnableEncryption ); // 0 - 1 (0)
3643 //x char Key1[MAX_KEY_LEN+1];
3644 printf_hcf_8( m, "Key1", lp->Key1, MAX_KEY_LEN );
3645 //x char Key2[MAX_KEY_LEN+1];
3646 //x char Key3[MAX_KEY_LEN+1];
3647 //x char Key4[MAX_KEY_LEN+1];
3648 seq_printf(m, "TransmitKeyID: 0x%04X\n", lp->TransmitKeyID ); // 1 - 4 (1)
3649 //x CFG_DEFAULT_KEYS_STRCT "DefaultKeys: 0x%04X\n", lp->DefaultKeys );
3650 //x u_char mailbox[MB_SIZE];
3651 //x char szEncryption[MAX_ENC_LEN];
3652 seq_printf(m, "driverEnable: 0x%04X\n", lp->driverEnable );
3653 seq_printf(m, "wolasEnable: 0x%04X\n", lp->wolasEnable );
3654 seq_printf(m, "atimWindow: 0x%04X\n", lp->atimWindow );
3655 seq_printf(m, "holdoverDuration: 0x%04X\n", lp->holdoverDuration );
3656 //x hcf_16 MulticastRate[2];
3657 seq_printf(m, "authentication: 0x%04X\n", lp->authentication ); // is this AP specific?
3658 seq_printf(m, "promiscuousMode: 0x%04X\n", lp->promiscuousMode );
3659 seq_printf(m, "DownloadFirmware: 0x%04X\n", lp->DownloadFirmware ); // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
3660 seq_printf(m, "AuthKeyMgmtSuite: 0x%04X\n", lp->AuthKeyMgmtSuite );
3661 seq_printf(m, "loadBalancing: 0x%04X\n", lp->loadBalancing );
3662 seq_printf(m, "mediumDistribution: 0x%04X\n", lp->mediumDistribution );
3663 seq_printf(m, "txPowLevel: 0x%04X\n", lp->txPowLevel );
3664 // seq_printf(m, "shortRetryLimit: 0x%04X\n", lp->shortRetryLimit );
3665 // seq_printf(m, "longRetryLimit: 0x%04X\n", lp->longRetryLimit );
3668 seq_printf(m, "connectionControl: 0x%04X\n", lp->connectionControl );
3669 //x //hcf_16 probeDataRates[2];
3670 seq_printf(m, "ownBeaconInterval: 0x%04X\n", lp->ownBeaconInterval );
3671 seq_printf(m, "coexistence: 0x%04X\n", lp->coexistence );
3672 //x WVLAN_FRAME "txF: 0x%04X\n", lp->txF );
3673 //x WVLAN_LFRAME txList[DEFAULT_NUM_TX_FRAMES];
3674 //x struct list_head "txFree: 0x%04X\n", lp->txFree );
3675 //x struct list_head txQ[WVLAN_MAX_TX_QUEUES];
3676 seq_printf(m, "netif_queue_on: 0x%04X\n", lp->netif_queue_on );
3677 seq_printf(m, "txQ_count: 0x%04X\n", lp->txQ_count );
3678 //x DESC_STRCT "desc_rx: 0x%04X\n", lp->desc_rx );
3679 //x DESC_STRCT "desc_tx: 0x%04X\n", lp->desc_tx );
3680 //x WVLAN_PORT_STATE "portState: 0x%04X\n", lp->portState );
3681 //x ScanResult "scan_results: 0x%04X\n", lp->scan_results );
3682 //x ProbeResult "probe_results: 0x%04X\n", lp->probe_results );
3683 seq_printf(m, "probe_num_aps: 0x%04X\n", lp->probe_num_aps );
3684 seq_printf(m, "use_dma: 0x%04X\n", lp->use_dma );
3685 //x DMA_STRCT "dma: 0x%04X\n", lp->dma );
3687 seq_printf(m, "useRTS: 0x%04X\n", lp->useRTS );
3689 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
3690 //;?should we restore this to allow smaller memory footprint
3691 //;?I guess not. This should be brought under Debug mode only
3692 seq_printf(m, "DTIMPeriod: 0x%04X\n", lp->DTIMPeriod ); // 1 - 255 (1)
3693 seq_printf(m, "multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
3694 seq_printf(m, "RejectAny: 0x%04X\n", lp->RejectAny ); // 0 - 1 (0)
3695 seq_printf(m, "ExcludeUnencrypted: 0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
3696 seq_printf(m, "intraBSSRelay: 0x%04X\n", lp->intraBSSRelay );
3697 seq_printf(m, "wlags49_type: 0x%08lX\n", lp->wlags49_type );
3699 //x WVLAN_WDS_IF wds_port[NUM_WDS_PORTS];
3702 } else if ( lp->wlags49_type == 2 ){
3703 seq_printf(m, "tallies to be added\n" );
3704 //Hermes Tallies (IFB substructure) {
3705 p = &lp->hcfCtx.IFB_NIC_Tallies;
3706 seq_printf(m, "TxUnicastFrames: %08lX\n", p->TxUnicastFrames );
3707 seq_printf(m, "TxMulticastFrames: %08lX\n", p->TxMulticastFrames );
3708 seq_printf(m, "TxFragments: %08lX\n", p->TxFragments );
3709 seq_printf(m, "TxUnicastOctets: %08lX\n", p->TxUnicastOctets );
3710 seq_printf(m, "TxMulticastOctets: %08lX\n", p->TxMulticastOctets );
3711 seq_printf(m, "TxDeferredTransmissions: %08lX\n", p->TxDeferredTransmissions );
3712 seq_printf(m, "TxSingleRetryFrames: %08lX\n", p->TxSingleRetryFrames );
3713 seq_printf(m, "TxMultipleRetryFrames: %08lX\n", p->TxMultipleRetryFrames );
3714 seq_printf(m, "TxRetryLimitExceeded: %08lX\n", p->TxRetryLimitExceeded );
3715 seq_printf(m, "TxDiscards: %08lX\n", p->TxDiscards );
3716 seq_printf(m, "RxUnicastFrames: %08lX\n", p->RxUnicastFrames );
3717 seq_printf(m, "RxMulticastFrames: %08lX\n", p->RxMulticastFrames );
3718 seq_printf(m, "RxFragments: %08lX\n", p->RxFragments );
3719 seq_printf(m, "RxUnicastOctets: %08lX\n", p->RxUnicastOctets );
3720 seq_printf(m, "RxMulticastOctets: %08lX\n", p->RxMulticastOctets );
3721 seq_printf(m, "RxFCSErrors: %08lX\n", p->RxFCSErrors );
3722 seq_printf(m, "RxDiscardsNoBuffer: %08lX\n", p->RxDiscardsNoBuffer );
3723 seq_printf(m, "TxDiscardsWrongSA: %08lX\n", p->TxDiscardsWrongSA );
3724 seq_printf(m, "RxWEPUndecryptable: %08lX\n", p->RxWEPUndecryptable );
3725 seq_printf(m, "RxMsgInMsgFragments: %08lX\n", p->RxMsgInMsgFragments );
3726 seq_printf(m, "RxMsgInBadMsgFragments: %08lX\n", p->RxMsgInBadMsgFragments );
3727 seq_printf(m, "RxDiscardsWEPICVError: %08lX\n", p->RxDiscardsWEPICVError );
3728 seq_printf(m, "RxDiscardsWEPExcluded: %08lX\n", p->RxDiscardsWEPExcluded );
3729 #if (HCF_EXT) & HCF_EXT_TALLIES_FW
3731 #endif // HCF_EXT_TALLIES_FW
3732 } else if ( lp->wlags49_type & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3734 DbgInfo->DebugFlag = lp->wlags49_type & 0x7FFF;
3736 lp->wlags49_type = 0; //default to IFB again ;?
3738 seq_printf(m, "unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
3741 "0x0001 - wl_private\n"
3742 "0x0002 - Tallies\n"
3743 "0x8xxx - Change debufflag\n"
3744 "ERROR 0001\nWARNING 0002\nNOTICE 0004\nTRACE 0008\n"
3745 "VERBOSE 0010\nPARAM 0020\nBREAK 0040\nRX 0100\n"
3746 "TX 0200\nDS 0400\n");
3749 } // scull_read_procmem
3751 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
3753 static char proc_number[11];
3754 unsigned int nr = 0;
3756 DBG_ENTER( DbgInfo );
3760 } else if ( copy_from_user(proc_number, buffer, count) ) {
3764 proc_number[count] = 0;
3765 nr = simple_strtoul(proc_number , NULL, 0);
3766 *(unsigned int *)data = nr;
3767 if ( nr & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3769 DbgInfo->DebugFlag = nr & 0x7FFF;
3773 DBG_PRINT( "value: %08X\n", nr );
3774 DBG_LEAVE( DbgInfo );
3778 #endif /* SCULL_USE_PROC */
3781 #define RUN_AT(x) (jiffies+(x)) //"borrowed" from include/pcmcia/k_compat.h
3782 #define DS_OOR 0x8000 //Deepsleep OutOfRange Status
3784 lp->timer_oor_cnt = DS_OOR;
3785 init_timer( &lp->timer_oor );
3786 lp->timer_oor.function = timer_oor;
3787 lp->timer_oor.data = (unsigned long)lp;
3788 lp->timer_oor.expires = RUN_AT( 3 * HZ );
3789 add_timer( &lp->timer_oor );
3790 printk(KERN_NOTICE "wl_enable: %ld\n", jiffies ); //;?remove me 1 day
3793 /*******************************************************************************
3795 *******************************************************************************
3802 * arg - a u_long representing a pointer to a dev_link_t structure for the
3803 * device to be released.
3809 ******************************************************************************/
3810 void timer_oor( u_long arg )
3812 struct wl_private *lp = (struct wl_private *)arg;
3814 /*------------------------------------------------------------------------*/
3816 DBG_ENTER( DbgInfo );
3817 DBG_PARAM( DbgInfo, "arg", "0x%08lx", arg );
3819 printk(KERN_NOTICE "timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt ); //;?remove me 1 day
3820 lp->timer_oor_cnt += 10;
3821 if ( (lp->timer_oor_cnt & ~DS_OOR) > 300 ) {
3822 lp->timer_oor_cnt = 300;
3824 lp->timer_oor_cnt |= DS_OOR;
3825 init_timer( &lp->timer_oor );
3826 lp->timer_oor.function = timer_oor;
3827 lp->timer_oor.data = (unsigned long)lp;
3828 lp->timer_oor.expires = RUN_AT( (lp->timer_oor_cnt & ~DS_OOR) * HZ );
3829 add_timer( &lp->timer_oor );
3831 DBG_LEAVE( DbgInfo );
3835 MODULE_LICENSE("Dual BSD/GPL");