1 /*******************************************************************************
3 * Wireless device driver for Linux (wlags49).
5 * Copyright (c) 1998-2003 Agere Systems Inc.
9 * Initially developed by TriplePoint, Inc.
10 * http://www.triplepoint.com
12 *------------------------------------------------------------------------------
14 * This file contains the main driver entry points and other adapter
17 *------------------------------------------------------------------------------
21 * This software is provided subject to the following terms and conditions,
22 * which you should read carefully before using the software. Using this
23 * software indicates your acceptance of these terms and conditions. If you do
24 * not agree with these terms and conditions, do not use the software.
26 * Copyright © 2003 Agere Systems Inc.
27 * All rights reserved.
29 * Redistribution and use in source or binary forms, with or without
30 * modifications, are permitted provided that the following conditions are met:
32 * . Redistributions of source code must retain the above copyright notice, this
33 * list of conditions and the following Disclaimer as comments in the code as
34 * well as in the documentation and/or other materials provided with the
37 * . Redistributions in binary form must reproduce the above copyright notice,
38 * this list of conditions and the following Disclaimer in the documentation
39 * and/or other materials provided with the distribution.
41 * . Neither the name of Agere Systems Inc. nor the names of the contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED
\93AS IS
\94 AND ANY EXPRESS OR IMPLIED WARRANTIES,
48 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
49 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
50 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
51 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
52 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
60 ******************************************************************************/
62 /*******************************************************************************
63 * constant definitions
64 ******************************************************************************/
66 /* Allow support for calling system fcns to access F/W image file */
67 #define __KERNEL_SYSCALLS__
69 /*******************************************************************************
71 ******************************************************************************/
72 #include <wl_version.h>
74 #include <linux/module.h>
75 #include <linux/proc_fs.h>
76 #include <linux/seq_file.h>
77 #include <linux/types.h>
78 #include <linux/kernel.h>
79 // #include <linux/sched.h>
80 // #include <linux/ptrace.h>
81 // #include <linux/slab.h>
82 // #include <linux/ctype.h>
83 // #include <linux/string.h>
84 // #include <linux/timer.h>
85 //#include <linux/interrupt.h>
86 // #include <linux/tqueue.h>
87 // #include <linux/in.h>
88 // #include <linux/delay.h>
89 // #include <asm/io.h>
90 // // #include <asm/bitops.h>
91 #include <linux/unistd.h>
92 #include <asm/uaccess.h>
94 #include <linux/netdevice.h>
95 #include <linux/etherdevice.h>
96 // #include <linux/skbuff.h>
97 // #include <linux/if_arp.h>
98 // #include <linux/ioport.h>
102 #include <linux/vmalloc.h>
110 //in order to get around:: wl_main.c:2229: `HREG_EV_RDMAD' undeclared (first use in this function)
114 #include <wl_internal.h>
117 #include <wl_netdev.h>
121 #include <wl_profile.h>
122 #endif /* USE_PROFILE */
126 #endif /* BUS_PCMCIA */
131 /*******************************************************************************
133 ******************************************************************************/
134 #define VALID_PARAM(C) \
138 printk(KERN_INFO "Wireless, parameter error: \"%s\"\n", #C); \
142 /*******************************************************************************
144 ******************************************************************************/
145 void wl_isr_handler( unsigned long p );
147 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
148 static int scull_read_procmem(struct seq_file *m, void *v);
149 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data);
152 * seq_file wrappers for procfile show routines.
154 static int scull_read_procmem_open(struct inode *inode, struct file *file)
156 return single_open(file, scull_read_procmem, PDE_DATA(inode));
159 static const struct file_operations scull_read_procmem_fops = {
160 .open = scull_read_procmem_open,
163 .release = single_release,
166 #endif /* SCULL_USE_PROC */
168 /*******************************************************************************
169 * module parameter definitions - set with 'insmod'
170 ******************************************************************************/
171 static p_u16 irq_mask = 0xdeb8; // IRQ3,4,5,7,9,10,11,12,14,15
172 static p_s8 irq_list[4] = { -1 };
175 MODULE_PARM(irq_mask, "h");
176 MODULE_PARM_DESC(irq_mask, "IRQ mask [0xdeb8]");
177 MODULE_PARM(irq_list, "1-4b");
178 MODULE_PARM_DESC(irq_list, "IRQ list [<irq_mask>]");
181 static p_u8 PARM_AUTHENTICATION = PARM_DEFAULT_AUTHENTICATION;
182 static p_u16 PARM_AUTH_KEY_MGMT_SUITE = PARM_DEFAULT_AUTH_KEY_MGMT_SUITE;
183 static p_u16 PARM_BRSC_2GHZ = PARM_DEFAULT_BRSC_2GHZ;
184 static p_u16 PARM_BRSC_5GHZ = PARM_DEFAULT_BRSC_5GHZ;
185 static p_u16 PARM_COEXISTENCE = PARM_DEFAULT_COEXISTENCE;
186 static p_u16 PARM_CONNECTION_CONTROL = PARM_DEFAULT_CONNECTION_CONTROL; //;?rename and move
187 static p_char *PARM_CREATE_IBSS = PARM_DEFAULT_CREATE_IBSS_STR;
188 static p_char *PARM_DESIRED_SSID = PARM_DEFAULT_SSID;
189 static p_char *PARM_DOWNLOAD_FIRMWARE = "";
190 static p_u16 PARM_ENABLE_ENCRYPTION = PARM_DEFAULT_ENABLE_ENCRYPTION;
191 static p_char *PARM_EXCLUDE_UNENCRYPTED = PARM_DEFAULT_EXCLUDE_UNENCRYPTED_STR;
192 static p_char *PARM_INTRA_BSS_RELAY = PARM_DEFAULT_INTRA_BSS_RELAY_STR;
193 static p_char *PARM_KEY1 = "";
194 static p_char *PARM_KEY2 = "";
195 static p_char *PARM_KEY3 = "";
196 static p_char *PARM_KEY4 = "";
197 static p_char *PARM_LOAD_BALANCING = PARM_DEFAULT_LOAD_BALANCING_STR;
198 static p_u16 PARM_MAX_SLEEP = PARM_DEFAULT_MAX_PM_SLEEP;
199 static p_char *PARM_MEDIUM_DISTRIBUTION = PARM_DEFAULT_MEDIUM_DISTRIBUTION_STR;
200 static p_char *PARM_MICROWAVE_ROBUSTNESS = PARM_DEFAULT_MICROWAVE_ROBUSTNESS_STR;
201 static p_char *PARM_MULTICAST_PM_BUFFERING = PARM_DEFAULT_MULTICAST_PM_BUFFERING_STR;
202 static p_u16 PARM_MULTICAST_RATE = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
203 static p_char *PARM_MULTICAST_RX = PARM_DEFAULT_MULTICAST_RX_STR;
204 static p_u8 PARM_NETWORK_ADDR[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
205 static p_u16 PARM_OWN_ATIM_WINDOW = PARM_DEFAULT_OWN_ATIM_WINDOW;
206 static p_u16 PARM_OWN_BEACON_INTERVAL = PARM_DEFAULT_OWN_BEACON_INTERVAL;
207 static p_u8 PARM_OWN_CHANNEL = PARM_DEFAULT_OWN_CHANNEL;
208 static p_u8 PARM_OWN_DTIM_PERIOD = PARM_DEFAULT_OWN_DTIM_PERIOD;
209 static p_char *PARM_OWN_NAME = PARM_DEFAULT_OWN_NAME;
210 static p_char *PARM_OWN_SSID = PARM_DEFAULT_SSID;
211 static p_u16 PARM_PM_ENABLED = WVLAN_PM_STATE_DISABLED;
212 static p_u16 PARM_PM_HOLDOVER_DURATION = PARM_DEFAULT_PM_HOLDOVER_DURATION;
213 static p_u8 PARM_PORT_TYPE = PARM_DEFAULT_PORT_TYPE;
214 static p_char *PARM_PROMISCUOUS_MODE = PARM_DEFAULT_PROMISCUOUS_MODE_STR;
215 static p_char *PARM_REJECT_ANY = PARM_DEFAULT_REJECT_ANY_STR;
217 static p_u16 PARM_RTS_THRESHOLD1 = PARM_DEFAULT_RTS_THRESHOLD;
218 static p_u16 PARM_RTS_THRESHOLD2 = PARM_DEFAULT_RTS_THRESHOLD;
219 static p_u16 PARM_RTS_THRESHOLD3 = PARM_DEFAULT_RTS_THRESHOLD;
220 static p_u16 PARM_RTS_THRESHOLD4 = PARM_DEFAULT_RTS_THRESHOLD;
221 static p_u16 PARM_RTS_THRESHOLD5 = PARM_DEFAULT_RTS_THRESHOLD;
222 static p_u16 PARM_RTS_THRESHOLD6 = PARM_DEFAULT_RTS_THRESHOLD;
224 static p_u16 PARM_RTS_THRESHOLD = PARM_DEFAULT_RTS_THRESHOLD;
225 static p_u16 PARM_SRSC_2GHZ = PARM_DEFAULT_SRSC_2GHZ;
226 static p_u16 PARM_SRSC_5GHZ = PARM_DEFAULT_SRSC_5GHZ;
227 static p_u8 PARM_SYSTEM_SCALE = PARM_DEFAULT_SYSTEM_SCALE;
228 static p_u8 PARM_TX_KEY = PARM_DEFAULT_TX_KEY;
229 static p_u16 PARM_TX_POW_LEVEL = PARM_DEFAULT_TX_POW_LEVEL;
231 static p_u16 PARM_TX_RATE1 = PARM_DEFAULT_TX_RATE_2GHZ;
232 static p_u16 PARM_TX_RATE2 = PARM_DEFAULT_TX_RATE_2GHZ;
233 static p_u16 PARM_TX_RATE3 = PARM_DEFAULT_TX_RATE_2GHZ;
234 static p_u16 PARM_TX_RATE4 = PARM_DEFAULT_TX_RATE_2GHZ;
235 static p_u16 PARM_TX_RATE5 = PARM_DEFAULT_TX_RATE_2GHZ;
236 static p_u16 PARM_TX_RATE6 = PARM_DEFAULT_TX_RATE_2GHZ;
238 static p_u16 PARM_TX_RATE = PARM_DEFAULT_TX_RATE_2GHZ;
240 static p_u8 PARM_WDS_ADDRESS1[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
241 static p_u8 PARM_WDS_ADDRESS2[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
242 static p_u8 PARM_WDS_ADDRESS3[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
243 static p_u8 PARM_WDS_ADDRESS4[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
244 static p_u8 PARM_WDS_ADDRESS5[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
245 static p_u8 PARM_WDS_ADDRESS6[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
250 MODULE_PARM(PARM_DESIRED_SSID, "s");
251 MODULE_PARM_DESC(PARM_DESIRED_SSID, "Network Name (<string>) [ANY]");
252 MODULE_PARM(PARM_OWN_SSID, "s");
253 MODULE_PARM_DESC(PARM_OWN_SSID, "Network Name (<string>) [ANY]");
254 MODULE_PARM(PARM_OWN_CHANNEL, "b");
255 MODULE_PARM_DESC(PARM_OWN_CHANNEL, "Channel (0 - 14) [0]");
256 MODULE_PARM(PARM_SYSTEM_SCALE, "b");
257 MODULE_PARM_DESC(PARM_SYSTEM_SCALE, "Distance Between APs (1 - 3) [1]");
258 MODULE_PARM(PARM_TX_RATE, "b");
259 MODULE_PARM_DESC(PARM_TX_RATE, "Transmit Rate Control");
260 MODULE_PARM(PARM_RTS_THRESHOLD, "h");
261 MODULE_PARM_DESC(PARM_RTS_THRESHOLD, "Medium Reservation (RTS/CTS Fragment Length) (256 - 2347) [2347]");
262 MODULE_PARM(PARM_MICROWAVE_ROBUSTNESS, "s");
263 MODULE_PARM_DESC(PARM_MICROWAVE_ROBUSTNESS, "Microwave Oven Robustness Enabled (<string> N or Y) [N]");
264 MODULE_PARM(PARM_OWN_NAME, "s");
265 MODULE_PARM_DESC(PARM_OWN_NAME, "Station Name (<string>) [Linux]");
267 MODULE_PARM(PARM_ENABLE_ENCRYPTION, "b");
268 MODULE_PARM_DESC(PARM_ENABLE_ENCRYPTION, "Encryption Mode (0 - 7) [0]");
270 MODULE_PARM(PARM_KEY1, "s");
271 MODULE_PARM_DESC(PARM_KEY1, "Data Encryption Key 1 (<string>) []");
272 MODULE_PARM(PARM_KEY2, "s");
273 MODULE_PARM_DESC(PARM_KEY2, "Data Encryption Key 2 (<string>) []");
274 MODULE_PARM(PARM_KEY3, "s");
275 MODULE_PARM_DESC(PARM_KEY3, "Data Encryption Key 3 (<string>) []");
276 MODULE_PARM(PARM_KEY4, "s");
277 MODULE_PARM_DESC(PARM_KEY4, "Data Encryption Key 4 (<string>) []");
278 MODULE_PARM(PARM_TX_KEY, "b");
279 MODULE_PARM_DESC(PARM_TX_KEY, "Transmit Key ID (1 - 4) [1]");
280 MODULE_PARM(PARM_MULTICAST_RATE, "b");
281 MODULE_PARM_DESC(PARM_MULTICAST_RATE, "Multicast Rate");
282 MODULE_PARM(PARM_DOWNLOAD_FIRMWARE, "s");
283 MODULE_PARM_DESC(PARM_DOWNLOAD_FIRMWARE, "filename of firmware image");
285 MODULE_PARM(PARM_AUTH_KEY_MGMT_SUITE, "b");
286 MODULE_PARM_DESC(PARM_AUTH_KEY_MGMT_SUITE, "Authentication Key Management suite (0-4) [0]");
288 MODULE_PARM(PARM_LOAD_BALANCING, "s");
289 MODULE_PARM_DESC(PARM_LOAD_BALANCING, "Load Balancing Enabled (<string> N or Y) [Y]");
290 MODULE_PARM(PARM_MEDIUM_DISTRIBUTION, "s");
291 MODULE_PARM_DESC(PARM_MEDIUM_DISTRIBUTION, "Medium Distribution Enabled (<string> N or Y) [Y]");
292 MODULE_PARM(PARM_TX_POW_LEVEL, "b");
293 MODULE_PARM_DESC(PARM_TX_POW_LEVEL, "Transmit Power (0 - 6) [3]");
294 MODULE_PARM(PARM_SRSC_2GHZ, "b");
295 MODULE_PARM_DESC(PARM_SRSC_2GHZ, "Supported Rate Set Control 2.4 GHz");
296 MODULE_PARM(PARM_SRSC_5GHZ, "b");
297 MODULE_PARM_DESC(PARM_SRSC_5GHZ, "Supported Rate Set Control 5.0 GHz");
298 MODULE_PARM(PARM_BRSC_2GHZ, "b");
299 MODULE_PARM_DESC(PARM_BRSC_2GHZ, "Basic Rate Set Control 2.4 GHz");
300 MODULE_PARM(PARM_BRSC_5GHZ, "b");
301 MODULE_PARM_DESC(PARM_BRSC_5GHZ, "Basic Rate Set Control 5.0 GHz");
302 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
303 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
304 MODULE_PARM(PARM_PM_ENABLED, "h");
305 MODULE_PARM_DESC(PARM_PM_ENABLED, "Power Management State (0 - 2, 8001 - 8002) [0]");
306 MODULE_PARM(PARM_PORT_TYPE, "b");
307 MODULE_PARM_DESC(PARM_PORT_TYPE, "Port Type (1 - 3) [1]");
308 //;?MODULE_PARM(PARM_CREATE_IBSS, "s");
309 //;?MODULE_PARM_DESC(PARM_CREATE_IBSS, "Create IBSS (<string> N or Y) [N]");
310 //;?MODULE_PARM(PARM_MULTICAST_RX, "s");
311 //;?MODULE_PARM_DESC(PARM_MULTICAST_RX, "Multicast Receive Enable (<string> N or Y) [Y]");
312 //;?MODULE_PARM(PARM_MAX_SLEEP, "h");
313 //;?MODULE_PARM_DESC(PARM_MAX_SLEEP, "Maximum Power Management Sleep Duration (0 - 65535) [100]");
314 //;?MODULE_PARM(PARM_NETWORK_ADDR, "6b");
315 //;?MODULE_PARM_DESC(PARM_NETWORK_ADDR, "Hardware Ethernet Address ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [<factory value>]");
316 //;?MODULE_PARM(PARM_AUTHENTICATION, "b");
319 //;?MODULE_PARM_DESC(PARM_AUTHENTICATION, "Authentication Type (0-2) [0] 0=Open 1=SharedKey 2=LEAP");
320 //;?MODULE_PARM_DESC(authentication, "Authentication Type (1-2) [1] 1=Open 2=SharedKey");
323 //;?MODULE_PARM(PARM_OWN_ATIM_WINDOW, "b");
324 //;?MODULE_PARM_DESC(PARM_OWN_ATIM_WINDOW, "ATIM Window time in TU for IBSS creation (0-100) [0]");
325 //;?MODULE_PARM(PARM_PM_HOLDOVER_DURATION, "b");
326 //;?MODULE_PARM_DESC(PARM_PM_HOLDOVER_DURATION, "Time station remains awake after MAC frame transfer when PM is on (0-65535) [100]");
327 //;?MODULE_PARM(PARM_PROMISCUOUS_MODE, "s");
328 //;?MODULE_PARM_DESC(PARM_PROMISCUOUS_MODE, "Promiscuous Mode Enable (<string> Y or N ) [N]" );
330 MODULE_PARM(PARM_CONNECTION_CONTROL, "b");
331 MODULE_PARM_DESC(PARM_CONNECTION_CONTROL, "Connection Control (0 - 3) [2]");
333 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
334 //;?should we restore this to allow smaller memory footprint
335 MODULE_PARM(PARM_OWN_DTIM_PERIOD, "b");
336 MODULE_PARM_DESC(PARM_OWN_DTIM_PERIOD, "DTIM Period (0 - 255) [1]");
337 MODULE_PARM(PARM_REJECT_ANY, "s");
338 MODULE_PARM_DESC(PARM_REJECT_ANY, "Closed System (<string> N or Y) [N]");
339 MODULE_PARM(PARM_EXCLUDE_UNENCRYPTED, "s");
340 MODULE_PARM_DESC(PARM_EXCLUDE_UNENCRYPTED, "Deny non-encrypted (<string> N or Y) [Y]");
341 MODULE_PARM(PARM_MULTICAST_PM_BUFFERING,"s");
342 MODULE_PARM_DESC(PARM_MULTICAST_PM_BUFFERING, "Buffer MAC frames for Tx after DTIM (<string> Y or N) [Y]");
343 MODULE_PARM(PARM_INTRA_BSS_RELAY, "s");
344 MODULE_PARM_DESC(PARM_INTRA_BSS_RELAY, "IntraBSS Relay (<string> N or Y) [Y]");
345 MODULE_PARM(PARM_RTS_THRESHOLD1, "h");
346 MODULE_PARM_DESC(PARM_RTS_THRESHOLD1, "RTS Threshold, WDS Port 1 (256 - 2347) [2347]");
347 MODULE_PARM(PARM_RTS_THRESHOLD2, "h");
348 MODULE_PARM_DESC(PARM_RTS_THRESHOLD2, "RTS Threshold, WDS Port 2 (256 - 2347) [2347]");
349 MODULE_PARM(PARM_RTS_THRESHOLD3, "h");
350 MODULE_PARM_DESC(PARM_RTS_THRESHOLD3, "RTS Threshold, WDS Port 3 (256 - 2347) [2347]");
351 MODULE_PARM(PARM_RTS_THRESHOLD4, "h");
352 MODULE_PARM_DESC(PARM_RTS_THRESHOLD4, "RTS Threshold, WDS Port 4 (256 - 2347) [2347]");
353 MODULE_PARM(PARM_RTS_THRESHOLD5, "h");
354 MODULE_PARM_DESC(PARM_RTS_THRESHOLD5, "RTS Threshold, WDS Port 5 (256 - 2347) [2347]");
355 MODULE_PARM(PARM_RTS_THRESHOLD6, "h");
356 MODULE_PARM_DESC(PARM_RTS_THRESHOLD6, "RTS Threshold, WDS Port 6 (256 - 2347) [2347]");
357 MODULE_PARM(PARM_TX_RATE1, "b");
358 MODULE_PARM_DESC(PARM_TX_RATE1, "Transmit Rate Control, WDS Port 1 (1 - 7) [3]");
359 MODULE_PARM(PARM_TX_RATE2, "b");
360 MODULE_PARM_DESC(PARM_TX_RATE2, "Transmit Rate Control, WDS Port 2 (1 - 7) [3]");
361 MODULE_PARM(PARM_TX_RATE3, "b");
362 MODULE_PARM_DESC(PARM_TX_RATE3, "Transmit Rate Control, WDS Port 3 (1 - 7) [3]");
363 MODULE_PARM(PARM_TX_RATE4, "b");
364 MODULE_PARM_DESC(PARM_TX_RATE4, "Transmit Rate Control, WDS Port 4 (1 - 7) [3]");
365 MODULE_PARM(PARM_TX_RATE5, "b");
366 MODULE_PARM_DESC(PARM_TX_RATE5, "Transmit Rate Control, WDS Port 5 (1 - 7) [3]");
367 MODULE_PARM(PARM_TX_RATE6, "b");
368 MODULE_PARM_DESC(PARM_TX_RATE6, "Transmit Rate Control, WDS Port 6 (1 - 7) [3]");
369 MODULE_PARM(PARM_WDS_ADDRESS1, "6b");
370 MODULE_PARM_DESC(PARM_WDS_ADDRESS1, "MAC Address, WDS Port 1 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
371 MODULE_PARM(PARM_WDS_ADDRESS2, "6b");
372 MODULE_PARM_DESC(PARM_WDS_ADDRESS2, "MAC Address, WDS Port 2 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
373 MODULE_PARM(PARM_WDS_ADDRESS3, "6b");
374 MODULE_PARM_DESC(PARM_WDS_ADDRESS3, "MAC Address, WDS Port 3 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
375 MODULE_PARM(PARM_WDS_ADDRESS4, "6b");
376 MODULE_PARM_DESC(PARM_WDS_ADDRESS4, "MAC Address, WDS Port 4 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
377 MODULE_PARM(PARM_WDS_ADDRESS5, "6b");
378 MODULE_PARM_DESC(PARM_WDS_ADDRESS5, "MAC Address, WDS Port 5 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
379 MODULE_PARM(PARM_WDS_ADDRESS6, "6b");
380 MODULE_PARM_DESC(PARM_WDS_ADDRESS6, "MAC Address, WDS Port 6 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
382 MODULE_PARM(PARM_OWN_BEACON_INTERVAL, "b");
383 MODULE_PARM_DESC(PARM_OWN_BEACON_INTERVAL, "Own Beacon Interval (20 - 200) [100]");
384 MODULE_PARM(PARM_COEXISTENCE, "b");
385 MODULE_PARM_DESC(PARM_COEXISTENCE, "Coexistence (0-7) [0]");
390 /* END NEW PARAMETERS */
391 /*******************************************************************************
392 * debugging specifics
393 ******************************************************************************/
396 static p_u32 pc_debug = DBG_LVL;
397 //MODULE_PARM(pc_debug, "i");
398 /*static ;?conflicts with my understanding of CL parameters and breaks now I moved
399 * the correspondig logic to wl_profile
400 */ p_u32 DebugFlag = ~0; //recognizable "undefined value" rather then DBG_DEFAULTS;
401 //MODULE_PARM(DebugFlag, "l");
403 dbg_info_t wl_info = { DBG_MOD_NAME, 0, 0 };
404 dbg_info_t *DbgInfo = &wl_info;
409 static p_char *useRTS = "N";
410 MODULE_PARM( useRTS, "s" );
411 MODULE_PARM_DESC( useRTS, "Use RTS test interface (<string> N or Y) [N]" );
414 /*******************************************************************************
415 * firmware download specifics
416 ******************************************************************************/
417 extern struct CFG_RANGE2_STRCT BASED
418 cfg_drv_act_ranges_pri; // describes primary-actor range of HCF
420 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
421 extern memimage ap; // AP firmware image to be downloaded
424 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
425 //extern memimage station; // STA firmware image to be downloaded
426 extern memimage fw_image; // firmware image to be downloaded
430 int wl_insert( struct net_device *dev )
433 int hcf_status = HCF_SUCCESS;
435 unsigned long flags = 0;
436 struct wl_private *lp = wl_priv(dev);
438 /* Initialize the adapter hardware. */
439 memset( &( lp->hcfCtx ), 0, sizeof( IFB_STRCT ));
441 /* Initialize the adapter parameters. */
442 spin_lock_init( &( lp->slock ));
444 /* Initialize states */
445 //lp->lockcount = 0; //PE1DNN
446 lp->is_handling_int = WL_NOT_HANDLING_INT;
447 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
451 DBG_PARAM( DbgInfo, "irq_mask", "0x%04x", irq_mask & 0x0FFFF );
452 DBG_PARAM( DbgInfo, "irq_list", "0x%02x 0x%02x 0x%02x 0x%02x",
453 irq_list[0] & 0x0FF, irq_list[1] & 0x0FF,
454 irq_list[2] & 0x0FF, irq_list[3] & 0x0FF );
455 DBG_PARAM( DbgInfo, PARM_NAME_DESIRED_SSID, "\"%s\"", PARM_DESIRED_SSID );
456 DBG_PARAM( DbgInfo, PARM_NAME_OWN_SSID, "\"%s\"", PARM_OWN_SSID );
457 DBG_PARAM( DbgInfo, PARM_NAME_OWN_CHANNEL, "%d", PARM_OWN_CHANNEL);
458 DBG_PARAM( DbgInfo, PARM_NAME_SYSTEM_SCALE, "%d", PARM_SYSTEM_SCALE );
459 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE, "%d", PARM_TX_RATE );
460 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD, "%d", PARM_RTS_THRESHOLD );
461 DBG_PARAM( DbgInfo, PARM_NAME_MICROWAVE_ROBUSTNESS, "\"%s\"", PARM_MICROWAVE_ROBUSTNESS );
462 DBG_PARAM( DbgInfo, PARM_NAME_OWN_NAME, "\"%s\"", PARM_OWN_NAME );
463 //;? DBG_PARAM( DbgInfo, PARM_NAME_ENABLE_ENCRYPTION, "\"%s\"", PARM_ENABLE_ENCRYPTION );
464 DBG_PARAM( DbgInfo, PARM_NAME_KEY1, "\"%s\"", PARM_KEY1 );
465 DBG_PARAM( DbgInfo, PARM_NAME_KEY2, "\"%s\"", PARM_KEY2 );
466 DBG_PARAM( DbgInfo, PARM_NAME_KEY3, "\"%s\"", PARM_KEY3 );
467 DBG_PARAM( DbgInfo, PARM_NAME_KEY4, "\"%s\"", PARM_KEY4 );
468 DBG_PARAM( DbgInfo, PARM_NAME_TX_KEY, "%d", PARM_TX_KEY );
469 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RATE, "%d", PARM_MULTICAST_RATE );
470 DBG_PARAM( DbgInfo, PARM_NAME_DOWNLOAD_FIRMWARE, "\"%s\"", PARM_DOWNLOAD_FIRMWARE );
471 DBG_PARAM( DbgInfo, PARM_NAME_AUTH_KEY_MGMT_SUITE, "%d", PARM_AUTH_KEY_MGMT_SUITE );
472 //;?#if (HCF_TYPE) & HCF_TYPE_STA
473 //;?should we make this code conditional depending on in STA mode
474 //;? DBG_PARAM( DbgInfo, PARM_NAME_PORT_TYPE, "%d", PARM_PORT_TYPE );
475 DBG_PARAM( DbgInfo, PARM_NAME_PM_ENABLED, "%04x", PARM_PM_ENABLED );
476 //;? DBG_PARAM( DbgInfo, PARM_NAME_CREATE_IBSS, "\"%s\"", PARM_CREATE_IBSS );
477 //;? DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RX, "\"%s\"", PARM_MULTICAST_RX );
478 //;? DBG_PARAM( DbgInfo, PARM_NAME_MAX_SLEEP, "%d", PARM_MAX_SLEEP );
480 DBG_PARAM(DbgInfo, PARM_NAME_NETWORK_ADDR, "\"%pM\"",
483 //;? DBG_PARAM( DbgInfo, PARM_NAME_AUTHENTICATION, "%d", PARM_AUTHENTICATION );
484 //;? DBG_PARAM( DbgInfo, PARM_NAME_OWN_ATIM_WINDOW, "%d", PARM_OWN_ATIM_WINDOW );
485 //;? DBG_PARAM( DbgInfo, PARM_NAME_PM_HOLDOVER_DURATION, "%d", PARM_PM_HOLDOVER_DURATION );
486 //;? DBG_PARAM( DbgInfo, PARM_NAME_PROMISCUOUS_MODE, "\"%s\"", PARM_PROMISCUOUS_MODE );
487 //;?#endif /* HCF_STA */
488 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
489 //;?should we restore this to allow smaller memory footprint
490 //;?I guess: no, since this is Debug mode only
491 DBG_PARAM( DbgInfo, PARM_NAME_OWN_DTIM_PERIOD, "%d", PARM_OWN_DTIM_PERIOD );
492 DBG_PARAM( DbgInfo, PARM_NAME_REJECT_ANY, "\"%s\"", PARM_REJECT_ANY );
493 DBG_PARAM( DbgInfo, PARM_NAME_EXCLUDE_UNENCRYPTED, "\"%s\"", PARM_EXCLUDE_UNENCRYPTED );
494 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_PM_BUFFERING, "\"%s\"", PARM_MULTICAST_PM_BUFFERING );
495 DBG_PARAM( DbgInfo, PARM_NAME_INTRA_BSS_RELAY, "\"%s\"", PARM_INTRA_BSS_RELAY );
497 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD1, "%d", PARM_RTS_THRESHOLD1 );
498 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD2, "%d", PARM_RTS_THRESHOLD2 );
499 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD3, "%d", PARM_RTS_THRESHOLD3 );
500 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD4, "%d", PARM_RTS_THRESHOLD4 );
501 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD5, "%d", PARM_RTS_THRESHOLD5 );
502 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD6, "%d", PARM_RTS_THRESHOLD6 );
503 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE1, "%d", PARM_TX_RATE1 );
504 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE2, "%d", PARM_TX_RATE2 );
505 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE3, "%d", PARM_TX_RATE3 );
506 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE4, "%d", PARM_TX_RATE4 );
507 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE5, "%d", PARM_TX_RATE5 );
508 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE6, "%d", PARM_TX_RATE6 );
509 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS1, "\"%pM\"",
511 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS2, "\"%pM\"",
513 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS3, "\"%pM\"",
515 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS4, "\"%pM\"",
517 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS5, "\"%pM\"",
519 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS6, "\"%pM\"",
524 VALID_PARAM( !PARM_DESIRED_SSID || ( strlen( PARM_DESIRED_SSID ) <= PARM_MAX_NAME_LEN ));
525 VALID_PARAM( !PARM_OWN_SSID || ( strlen( PARM_OWN_SSID ) <= PARM_MAX_NAME_LEN ));
526 VALID_PARAM(( PARM_OWN_CHANNEL <= PARM_MAX_OWN_CHANNEL ));
527 VALID_PARAM(( PARM_SYSTEM_SCALE >= PARM_MIN_SYSTEM_SCALE ) && ( PARM_SYSTEM_SCALE <= PARM_MAX_SYSTEM_SCALE ));
528 VALID_PARAM(( PARM_TX_RATE >= PARM_MIN_TX_RATE ) && ( PARM_TX_RATE <= PARM_MAX_TX_RATE ));
529 VALID_PARAM(( PARM_RTS_THRESHOLD <= PARM_MAX_RTS_THRESHOLD ));
530 VALID_PARAM( !PARM_MICROWAVE_ROBUSTNESS || strchr( "NnYy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL );
531 VALID_PARAM( !PARM_OWN_NAME || ( strlen( PARM_NAME_OWN_NAME ) <= PARM_MAX_NAME_LEN ));
532 VALID_PARAM(( PARM_ENABLE_ENCRYPTION <= PARM_MAX_ENABLE_ENCRYPTION ));
533 VALID_PARAM( is_valid_key_string( PARM_KEY1 ));
534 VALID_PARAM( is_valid_key_string( PARM_KEY2 ));
535 VALID_PARAM( is_valid_key_string( PARM_KEY3 ));
536 VALID_PARAM( is_valid_key_string( PARM_KEY4 ));
537 VALID_PARAM(( PARM_TX_KEY >= PARM_MIN_TX_KEY ) && ( PARM_TX_KEY <= PARM_MAX_TX_KEY ));
539 VALID_PARAM(( PARM_MULTICAST_RATE >= PARM_MIN_MULTICAST_RATE ) &&
540 ( PARM_MULTICAST_RATE <= PARM_MAX_MULTICAST_RATE ));
542 VALID_PARAM( !PARM_DOWNLOAD_FIRMWARE || ( strlen( PARM_DOWNLOAD_FIRMWARE ) <= 255 /*;?*/ ));
543 VALID_PARAM(( PARM_AUTH_KEY_MGMT_SUITE < PARM_MAX_AUTH_KEY_MGMT_SUITE ));
545 VALID_PARAM( !PARM_LOAD_BALANCING || strchr( "NnYy", PARM_LOAD_BALANCING[0] ) != NULL );
546 VALID_PARAM( !PARM_MEDIUM_DISTRIBUTION || strchr( "NnYy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL );
547 VALID_PARAM(( PARM_TX_POW_LEVEL <= PARM_MAX_TX_POW_LEVEL ));
549 VALID_PARAM(( PARM_PORT_TYPE >= PARM_MIN_PORT_TYPE ) && ( PARM_PORT_TYPE <= PARM_MAX_PORT_TYPE ));
550 VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
551 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
552 VALID_PARAM( !PARM_CREATE_IBSS || strchr( "NnYy", PARM_CREATE_IBSS[0] ) != NULL );
553 VALID_PARAM( !PARM_MULTICAST_RX || strchr( "NnYy", PARM_MULTICAST_RX[0] ) != NULL );
554 VALID_PARAM(( PARM_MAX_SLEEP <= PARM_MAX_MAX_PM_SLEEP ));
555 VALID_PARAM(( PARM_AUTHENTICATION <= PARM_MAX_AUTHENTICATION ));
556 VALID_PARAM(( PARM_OWN_ATIM_WINDOW <= PARM_MAX_OWN_ATIM_WINDOW ));
557 VALID_PARAM(( PARM_PM_HOLDOVER_DURATION <= PARM_MAX_PM_HOLDOVER_DURATION ));
558 VALID_PARAM( !PARM_PROMISCUOUS_MODE || strchr( "NnYy", PARM_PROMISCUOUS_MODE[0] ) != NULL );
559 VALID_PARAM(( PARM_CONNECTION_CONTROL <= PARM_MAX_CONNECTION_CONTROL ));
561 VALID_PARAM(( PARM_OWN_DTIM_PERIOD >= PARM_MIN_OWN_DTIM_PERIOD ));
562 VALID_PARAM( !PARM_REJECT_ANY || strchr( "NnYy", PARM_REJECT_ANY[0] ) != NULL );
563 VALID_PARAM( !PARM_EXCLUDE_UNENCRYPTED || strchr( "NnYy", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL );
564 VALID_PARAM( !PARM_MULTICAST_PM_BUFFERING || strchr( "NnYy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL );
565 VALID_PARAM( !PARM_INTRA_BSS_RELAY || strchr( "NnYy", PARM_INTRA_BSS_RELAY[0] ) != NULL );
567 VALID_PARAM(( PARM_RTS_THRESHOLD1 <= PARM_MAX_RTS_THRESHOLD ));
568 VALID_PARAM(( PARM_RTS_THRESHOLD2 <= PARM_MAX_RTS_THRESHOLD ));
569 VALID_PARAM(( PARM_RTS_THRESHOLD3 <= PARM_MAX_RTS_THRESHOLD ));
570 VALID_PARAM(( PARM_RTS_THRESHOLD4 <= PARM_MAX_RTS_THRESHOLD ));
571 VALID_PARAM(( PARM_RTS_THRESHOLD5 <= PARM_MAX_RTS_THRESHOLD ));
572 VALID_PARAM(( PARM_RTS_THRESHOLD6 <= PARM_MAX_RTS_THRESHOLD ));
573 VALID_PARAM(( PARM_TX_RATE1 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE1 <= PARM_MAX_TX_RATE ));
574 VALID_PARAM(( PARM_TX_RATE2 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE2 <= PARM_MAX_TX_RATE ));
575 VALID_PARAM(( PARM_TX_RATE3 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE3 <= PARM_MAX_TX_RATE ));
576 VALID_PARAM(( PARM_TX_RATE4 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE4 <= PARM_MAX_TX_RATE ));
577 VALID_PARAM(( PARM_TX_RATE5 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE5 <= PARM_MAX_TX_RATE ));
578 VALID_PARAM(( PARM_TX_RATE6 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE6 <= PARM_MAX_TX_RATE ));
581 VALID_PARAM(( PARM_OWN_BEACON_INTERVAL >= PARM_MIN_OWN_BEACON_INTERVAL ) && ( PARM_OWN_BEACON_INTERVAL <= PARM_MAX_OWN_BEACON_INTERVAL ));
582 VALID_PARAM(( PARM_COEXISTENCE <= PARM_COEXISTENCE ));
584 /* Set the driver parameters from the passed in parameters. */
586 /* THESE MODULE PARAMETERS ARE TO BE DEPRECATED IN FAVOR OF A NAMING CONVENTION
587 WHICH IS INLINE WITH THE FORTHCOMING WAVELAN API */
589 /* START NEW PARAMETERS */
591 lp->Channel = PARM_OWN_CHANNEL;
592 lp->DistanceBetweenAPs = PARM_SYSTEM_SCALE;
594 /* Need to determine how to handle the new bands for 5GHz */
595 lp->TxRateControl[0] = PARM_DEFAULT_TX_RATE_2GHZ;
596 lp->TxRateControl[1] = PARM_DEFAULT_TX_RATE_5GHZ;
598 lp->RTSThreshold = PARM_RTS_THRESHOLD;
600 /* Need to determine how to handle the new bands for 5GHz */
601 lp->MulticastRate[0] = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
602 lp->MulticastRate[1] = PARM_DEFAULT_MULTICAST_RATE_5GHZ;
604 if ( strchr( "Yy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL ) {
605 lp->MicrowaveRobustness = 1;
607 lp->MicrowaveRobustness = 0;
609 if ( PARM_DESIRED_SSID && ( strlen( PARM_DESIRED_SSID ) <= HCF_MAX_NAME_LEN )) {
610 strcpy( lp->NetworkName, PARM_DESIRED_SSID );
612 if ( PARM_OWN_SSID && ( strlen( PARM_OWN_SSID ) <= HCF_MAX_NAME_LEN )) {
613 strcpy( lp->NetworkName, PARM_OWN_SSID );
615 if ( PARM_OWN_NAME && ( strlen( PARM_OWN_NAME ) <= HCF_MAX_NAME_LEN )) {
616 strcpy( lp->StationName, PARM_OWN_NAME );
618 lp->EnableEncryption = PARM_ENABLE_ENCRYPTION;
619 if ( PARM_KEY1 && ( strlen( PARM_KEY1 ) <= MAX_KEY_LEN )) {
620 strcpy( lp->Key1, PARM_KEY1 );
622 if ( PARM_KEY2 && ( strlen( PARM_KEY2 ) <= MAX_KEY_LEN )) {
623 strcpy( lp->Key2, PARM_KEY2 );
625 if ( PARM_KEY3 && ( strlen( PARM_KEY3 ) <= MAX_KEY_LEN )) {
626 strcpy( lp->Key3, PARM_KEY3 );
628 if ( PARM_KEY4 && ( strlen( PARM_KEY4 ) <= MAX_KEY_LEN )) {
629 strcpy( lp->Key4, PARM_KEY4 );
632 lp->TransmitKeyID = PARM_TX_KEY;
634 key_string2key( lp->Key1, &(lp->DefaultKeys.key[0] ));
635 key_string2key( lp->Key2, &(lp->DefaultKeys.key[1] ));
636 key_string2key( lp->Key3, &(lp->DefaultKeys.key[2] ));
637 key_string2key( lp->Key4, &(lp->DefaultKeys.key[3] ));
639 lp->DownloadFirmware = 1 ; //;?to be upgraded PARM_DOWNLOAD_FIRMWARE;
640 lp->AuthKeyMgmtSuite = PARM_AUTH_KEY_MGMT_SUITE;
642 if ( strchr( "Yy", PARM_LOAD_BALANCING[0] ) != NULL ) {
643 lp->loadBalancing = 1;
645 lp->loadBalancing = 0;
648 if ( strchr( "Yy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL ) {
649 lp->mediumDistribution = 1;
651 lp->mediumDistribution = 0;
654 lp->txPowLevel = PARM_TX_POW_LEVEL;
656 lp->srsc[0] = PARM_SRSC_2GHZ;
657 lp->srsc[1] = PARM_SRSC_5GHZ;
658 lp->brsc[0] = PARM_BRSC_2GHZ;
659 lp->brsc[1] = PARM_BRSC_5GHZ;
660 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
661 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
662 lp->PortType = PARM_PORT_TYPE;
663 lp->MaxSleepDuration = PARM_MAX_SLEEP;
664 lp->authentication = PARM_AUTHENTICATION;
665 lp->atimWindow = PARM_OWN_ATIM_WINDOW;
666 lp->holdoverDuration = PARM_PM_HOLDOVER_DURATION;
667 lp->PMEnabled = PARM_PM_ENABLED; //;?
668 if ( strchr( "Yy", PARM_CREATE_IBSS[0] ) != NULL ) {
673 if ( strchr( "Nn", PARM_MULTICAST_RX[0] ) != NULL ) {
674 lp->MulticastReceive = 0;
676 lp->MulticastReceive = 1;
678 if ( strchr( "Yy", PARM_PROMISCUOUS_MODE[0] ) != NULL ) {
679 lp->promiscuousMode = 1;
681 lp->promiscuousMode = 0;
683 for( i = 0; i < ETH_ALEN; i++ ) {
684 lp->MACAddress[i] = PARM_NETWORK_ADDR[i];
687 lp->connectionControl = PARM_CONNECTION_CONTROL;
690 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
691 //;?should we restore this to allow smaller memory footprint
692 lp->DTIMPeriod = PARM_OWN_DTIM_PERIOD;
694 if ( strchr( "Yy", PARM_REJECT_ANY[0] ) != NULL ) {
699 if ( strchr( "Nn", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL ) {
700 lp->ExcludeUnencrypted = 0;
702 lp->ExcludeUnencrypted = 1;
704 if ( strchr( "Yy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL ) {
705 lp->multicastPMBuffering = 1;
707 lp->multicastPMBuffering = 0;
709 if ( strchr( "Yy", PARM_INTRA_BSS_RELAY[0] ) != NULL ) {
710 lp->intraBSSRelay = 1;
712 lp->intraBSSRelay = 0;
715 lp->ownBeaconInterval = PARM_OWN_BEACON_INTERVAL;
716 lp->coexistence = PARM_COEXISTENCE;
719 lp->wds_port[0].rtsThreshold = PARM_RTS_THRESHOLD1;
720 lp->wds_port[1].rtsThreshold = PARM_RTS_THRESHOLD2;
721 lp->wds_port[2].rtsThreshold = PARM_RTS_THRESHOLD3;
722 lp->wds_port[3].rtsThreshold = PARM_RTS_THRESHOLD4;
723 lp->wds_port[4].rtsThreshold = PARM_RTS_THRESHOLD5;
724 lp->wds_port[5].rtsThreshold = PARM_RTS_THRESHOLD6;
725 lp->wds_port[0].txRateCntl = PARM_TX_RATE1;
726 lp->wds_port[1].txRateCntl = PARM_TX_RATE2;
727 lp->wds_port[2].txRateCntl = PARM_TX_RATE3;
728 lp->wds_port[3].txRateCntl = PARM_TX_RATE4;
729 lp->wds_port[4].txRateCntl = PARM_TX_RATE5;
730 lp->wds_port[5].txRateCntl = PARM_TX_RATE6;
732 for( i = 0; i < ETH_ALEN; i++ ) {
733 lp->wds_port[0].wdsAddress[i] = PARM_WDS_ADDRESS1[i];
735 for( i = 0; i < ETH_ALEN; i++ ) {
736 lp->wds_port[1].wdsAddress[i] = PARM_WDS_ADDRESS2[i];
738 for( i = 0; i < ETH_ALEN; i++ ) {
739 lp->wds_port[2].wdsAddress[i] = PARM_WDS_ADDRESS3[i];
741 for( i = 0; i < ETH_ALEN; i++ ) {
742 lp->wds_port[3].wdsAddress[i] = PARM_WDS_ADDRESS4[i];
744 for( i = 0; i < ETH_ALEN; i++ ) {
745 lp->wds_port[4].wdsAddress[i] = PARM_WDS_ADDRESS5[i];
747 for( i = 0; i < ETH_ALEN; i++ ) {
748 lp->wds_port[5].wdsAddress[i] = PARM_WDS_ADDRESS6[i];
753 if ( strchr( "Yy", useRTS[0] ) != NULL ) {
761 /* END NEW PARAMETERS */
764 wl_lock( lp, &flags );
766 /* Initialize the portState variable */
767 lp->portState = WVLAN_PORT_STATE_DISABLED;
769 /* Initialize the ScanResult struct */
770 memset( &( lp->scan_results ), 0, sizeof( lp->scan_results ));
771 lp->scan_results.scan_complete = FALSE;
773 /* Initialize the ProbeResult struct */
774 memset( &( lp->probe_results ), 0, sizeof( lp->probe_results ));
775 lp->probe_results.scan_complete = FALSE;
776 lp->probe_num_aps = 0;
779 /* Initialize Tx queue stuff */
780 memset( lp->txList, 0, sizeof( lp->txList ));
782 INIT_LIST_HEAD( &( lp->txFree ));
788 for( i = 0; i < DEFAULT_NUM_TX_FRAMES; i++ ) {
789 list_add_tail( &( lp->txList[i].node ), &( lp->txFree ));
793 for( i = 0; i < WVLAN_MAX_TX_QUEUES; i++ ) {
794 INIT_LIST_HEAD( &( lp->txQ[i] ));
797 lp->netif_queue_on = TRUE;
799 /* Initialize the use_dma element in the adapter structure. Not sure if
800 this should be a compile-time or run-time configurable. So for now,
801 implement as run-time and just define here */
804 DBG_TRACE( DbgInfo, "HERMES 2.5 BUSMASTER DMA MODE\n" );
807 DBG_TRACE( DbgInfo, "HERMES 2.5 PORT I/O MODE\n" );
812 /* Register the ISR handler information here, so that it's not done
813 repeatedly in the ISR */
814 tasklet_init(&lp->task, wl_isr_handler, (unsigned long)lp);
816 /* Connect to the adapter */
817 DBG_TRACE( DbgInfo, "Calling hcf_connect()...\n" );
818 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
819 //HCF_ERR_INCOMP_FW is acceptable, because download must still take place
820 //HCF_ERR_INCOMP_PRI is not acceptable
821 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
822 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
823 wl_unlock( lp, &flags );
827 //;?should set HCF_version and how about driver_stat
828 lp->driverInfo.IO_address = dev->base_addr;
829 lp->driverInfo.IO_range = HCF_NUM_IO_PORTS; //;?conditionally 0x40 or 0x80 seems better
830 lp->driverInfo.IRQ_number = dev->irq;
831 lp->driverInfo.card_stat = lp->hcfCtx.IFB_CardStat;
832 //;? what happened to frame_type
834 /* Fill in the driver identity structure */
835 lp->driverIdentity.len = ( sizeof( lp->driverIdentity ) / sizeof( hcf_16 )) - 1;
836 lp->driverIdentity.typ = CFG_DRV_IDENTITY;
837 lp->driverIdentity.comp_id = DRV_IDENTITY;
838 lp->driverIdentity.variant = DRV_VARIANT;
839 lp->driverIdentity.version_major = DRV_MAJOR_VERSION;
840 lp->driverIdentity.version_minor = DRV_MINOR_VERSION;
843 /* Start the card here - This needs to be done in order to get the
844 MAC address for the network layer */
845 DBG_TRACE( DbgInfo, "Calling wvlan_go() to perform a card reset...\n" );
846 hcf_status = wl_go( lp );
848 if ( hcf_status != HCF_SUCCESS ) {
849 DBG_ERROR( DbgInfo, "wl_go() failed\n" );
850 wl_unlock( lp, &flags );
854 /* Certain RIDs must be set before enabling the ports */
855 wl_put_ltv_init( lp );
857 #if 0 //;?why was this already commented out in wl_lkm_720
858 /* Enable the ports */
859 if ( wl_adapter_is_open( lp->dev )) {
860 /* Enable the ports */
861 DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
862 hcf_status = wl_enable( lp );
864 if ( hcf_status != HCF_SUCCESS ) {
865 DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", hcf_status );
868 #if (HCF_TYPE) & HCF_TYPE_AP
869 DBG_TRACE( DbgInfo, "Enabling WDS Ports\n" );
870 //wl_enable_wds_ports( lp );
871 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
876 /* Fill out the MAC address information in the net_device struct */
877 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN );
878 dev->addr_len = ETH_ALEN;
880 lp->is_registered = TRUE;
883 /* Parse the config file for the sake of creating WDS ports if WDS is
884 configured there but not in the module options */
886 #endif /* USE_PROFILE */
888 /* If we're going into AP Mode, register the "virtual" ethernet devices
890 WL_WDS_NETDEV_REGISTER( lp );
892 /* Reset the DownloadFirmware variable in the private struct. If the
893 config file is not used, this will not matter; if it is used, it
894 will be reparsed in wl_open(). This is done because logic in wl_open
895 used to check if a firmware download is needed is broken by parsing
896 the file here; however, this parsing is needed to register WDS ports
897 in AP mode, if they are configured */
898 lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //;?download_firmware;
901 if ( lp->useRTS == 1 ) {
902 DBG_TRACE( DbgInfo, "ENTERING RTS MODE...\n" );
903 wl_act_int_off( lp );
904 lp->is_handling_int = WL_NOT_HANDLING_INT; // Not handling interrupts anymore
908 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT);
912 wl_unlock( lp, &flags );
914 DBG_TRACE( DbgInfo, "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
915 dev->name, dev->base_addr, dev->irq );
917 for( i = 0; i < ETH_ALEN; i++ ) {
918 printk( "%02X%c", dev->dev_addr[i], (( i < ( ETH_ALEN-1 )) ? ':' : '\n' ));
921 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
922 proc_create_data( "wlags", 0, NULL, &scull_read_procmem_fops, dev );
923 proc_mkdir("driver/wlags49", 0);
924 #endif /* SCULL_USE_PROC */
929 wl_hcf_error( dev, hcf_status );
933 DBG_ERROR( DbgInfo, "wl_insert() FAILED\n" );
935 if ( lp->is_registered == TRUE ) {
936 lp->is_registered = FALSE;
939 WL_WDS_NETDEV_DEREGISTER( lp );
945 /*============================================================================*/
948 /*******************************************************************************
950 *******************************************************************************
958 * dev - a pointer to the net_device struct of the wireless device
964 ******************************************************************************/
965 int wl_reset(struct net_device *dev)
967 struct wl_private *lp = wl_priv(dev);
968 int hcf_status = HCF_SUCCESS;
970 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
971 DBG_PARAM( DbgInfo, "dev->base_addr", "(%#03lx)", dev->base_addr );
974 * The caller should already have a lock and
975 * disable the interrupts, we do not lock here,
976 * nor do we enable/disable interrupts!
979 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", dev->base_addr );
980 if ( dev->base_addr ) {
981 /* Shutdown the adapter. */
982 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
984 /* Reset the driver information. */
987 /* Connect to the adapter. */
988 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
989 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
990 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
994 /* Check if firmware is present, if not change state */
995 if ( hcf_status == HCF_ERR_INCOMP_FW ) {
996 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
999 /* Initialize the portState variable */
1000 lp->portState = WVLAN_PORT_STATE_DISABLED;
1002 /* Restart the adapter. */
1003 hcf_status = wl_go( lp );
1004 if ( hcf_status != HCF_SUCCESS ) {
1005 DBG_ERROR( DbgInfo, "wl_go() failed, status: 0x%x\n", hcf_status );
1009 /* Certain RIDs must be set before enabling the ports */
1010 wl_put_ltv_init( lp );
1012 DBG_ERROR( DbgInfo, "Device Base Address INVALID!!!\n" );
1018 /*============================================================================*/
1021 /*******************************************************************************
1023 *******************************************************************************
1027 * Reset the adapter.
1031 * dev - a pointer to the net_device struct of the wireless device
1035 * an HCF status code
1037 ******************************************************************************/
1038 int wl_go( struct wl_private *lp )
1040 int hcf_status = HCF_SUCCESS;
1041 char *cp = NULL; //fw_image
1044 hcf_status = wl_disable( lp );
1045 if ( hcf_status != HCF_SUCCESS ) {
1046 DBG_TRACE( DbgInfo, "Disable port 0 failed: 0x%x\n", hcf_status );
1048 while (( hcf_status != HCF_SUCCESS ) && (retries < 10)) {
1050 hcf_status = wl_disable( lp );
1052 if ( hcf_status == HCF_SUCCESS ) {
1053 DBG_TRACE( DbgInfo, "Disable port 0 succes : %d retries\n", retries );
1055 DBG_TRACE( DbgInfo, "Disable port 0 failed after: %d retries\n", retries );
1059 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
1060 //DBG_TRACE( DbgInfo, "Disabling WDS Ports\n" );
1061 //wl_disable_wds_ports( lp );
1062 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1064 //;?what was the purpose of this
1065 // /* load the appropriate firmware image, depending on driver mode */
1066 // lp->ltvRecord.len = ( sizeof( CFG_RANGE20_STRCT ) / sizeof( hcf_16 )) - 1;
1067 // lp->ltvRecord.typ = CFG_DRV_ACT_RANGES_PRI;
1068 // hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1071 if ( strlen( lp->fw_image_filename ) ) {
1076 DBG_TRACE( DbgInfo, "F/W image:%s:\n", lp->fw_image_filename );
1077 /* Obtain a user-space process context, storing the original context */
1080 file_desc = open( lp->fw_image_filename, O_RDONLY, 0 );
1081 if ( file_desc == -1 ) {
1082 DBG_ERROR( DbgInfo, "No image file found\n" );
1084 DBG_TRACE( DbgInfo, "F/W image file found\n" );
1085 #define DHF_ALLOC_SIZE 96000 //just below 96K, let's hope it suffices for now and for the future
1086 cp = (char*)vmalloc( DHF_ALLOC_SIZE );
1088 DBG_ERROR( DbgInfo, "error in vmalloc\n" );
1090 rc = read( file_desc, cp, DHF_ALLOC_SIZE );
1091 if ( rc == DHF_ALLOC_SIZE ) {
1092 DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE );
1093 } else if ( rc > 0 ) {
1094 DBG_TRACE( DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp );
1095 rc = read( file_desc, &cp[rc], 1 );
1096 if ( rc == 0 ) { //;/change to an until-loop at rc<=0
1097 DBG_TRACE( DbgInfo, "no more to read\n" );
1101 DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\
1102 ", give up, too complicated, rc = %0X\n", rc );
1103 DBG_ERROR( DbgInfo, "still have to change code to get a real download now !!!!!!!!\n" );
1105 DBG_TRACE( DbgInfo, "before dhf_download_binary\n" );
1106 hcf_status = dhf_download_binary( (memimage *)cp );
1107 DBG_TRACE( DbgInfo, "after dhf_download_binary, before dhf_download_fw\n" );
1108 //;?improve error flow/handling
1109 hcf_status = dhf_download_fw( &lp->hcfCtx, (memimage *)cp );
1110 DBG_TRACE( DbgInfo, "after dhf_download_fw\n" );
1116 set_fs( fs ); /* Return to the original context */
1120 /* If firmware is present but the type is unknown then download anyway */
1121 if ( (lp->firmware_present == WL_FRIMWARE_PRESENT)
1123 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_STA )
1125 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_AP ) ) {
1126 /* Unknown type, download needed. */
1127 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1130 if(lp->firmware_present == WL_FRIMWARE_NOT_PRESENT)
1133 DBG_TRACE( DbgInfo, "Downloading STA firmware...\n" );
1134 // hcf_status = dhf_download_fw( &lp->hcfCtx, &station );
1135 hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image );
1137 if ( hcf_status != HCF_SUCCESS ) {
1138 DBG_ERROR( DbgInfo, "Firmware Download failed\n" );
1142 /* Report the FW versions */
1143 //;?obsolete, use the available IFB info:: wl_get_pri_records( lp );
1144 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1145 DBG_TRACE( DbgInfo, "downloaded station F/W\n" );
1146 } else if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1147 DBG_TRACE( DbgInfo, "downloaded AP F/W\n" );
1149 DBG_ERROR( DbgInfo, "unknown F/W type\n" );
1153 * Downloaded, no need to repeat this next time, assume the
1154 * contents stays in the card until it is powered off. Note we
1155 * do not switch firmware on the fly, the firmware is fixed in
1156 * the driver for now.
1158 lp->firmware_present = WL_FRIMWARE_PRESENT;
1160 DBG_TRACE( DbgInfo, "ComponentID:%04x variant:%04x major:%04x minor:%04x\n",
1161 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ),
1162 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.variant ),
1163 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_major ),
1164 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_minor ));
1166 /* now we will get the MAC address of the card */
1167 lp->ltvRecord.len = 4;
1168 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1169 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1172 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1174 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1175 if ( hcf_status != HCF_SUCCESS ) {
1176 DBG_ERROR( DbgInfo, "Could not retrieve MAC address\n" );
1179 memcpy( lp->MACAddress, &lp->ltvRecord.u.u8[0], ETH_ALEN );
1180 DBG_TRACE(DbgInfo, "Card MAC Address: %pM\n", lp->MACAddress);
1182 /* Write out configuration to the device, enable, and reconnect. However,
1183 only reconnect if in AP mode. For STA mode, need to wait for passive scan
1184 completion before a connect can be issued */
1186 /* Enable the ports */
1187 hcf_status = wl_enable( lp );
1189 if ( lp->DownloadFirmware == WVLAN_DRV_MODE_AP ) {
1191 wl_enable_wds_ports( lp );
1193 hcf_status = wl_connect( lp );
1197 /*============================================================================*/
1200 /*******************************************************************************
1202 *******************************************************************************
1206 * Write TxKeyID and WEP keys to the adapter. This is separated from
1207 * wl_apply() to allow dynamic WEP key updates through the wireless
1212 * lp - a pointer to the wireless adapter's private structure
1218 ******************************************************************************/
1219 void wl_set_wep_keys( struct wl_private *lp )
1223 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1224 if ( lp->EnableEncryption ) {
1225 /* NOTE: CFG_CNF_ENCRYPTION is set in wl_put_ltv() as it's a static
1229 lp->ltvRecord.len = 2;
1230 lp->ltvRecord.typ = CFG_TX_KEY_ID;
1231 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE(lp->TransmitKeyID - 1);
1233 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1235 DBG_TRACE( DbgInfo, "Key 1 len: %d\n", lp->DefaultKeys.key[0].len );
1236 DBG_TRACE( DbgInfo, "Key 2 len: %d\n", lp->DefaultKeys.key[1].len );
1237 DBG_TRACE( DbgInfo, "Key 3 len: %d\n", lp->DefaultKeys.key[2].len );
1238 DBG_TRACE( DbgInfo, "Key 4 len: %d\n", lp->DefaultKeys.key[3].len );
1241 lp->DefaultKeys.len = sizeof( lp->DefaultKeys ) / sizeof( hcf_16 ) - 1;
1242 lp->DefaultKeys.typ = CFG_DEFAULT_KEYS;
1244 /* endian translate the appropriate key information */
1245 for( count = 0; count < MAX_KEYS; count++ ) {
1246 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1249 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->DefaultKeys ));
1251 /* Reverse the above endian translation, since these keys are accessed
1253 for( count = 0; count < MAX_KEYS; count++ ) {
1254 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1257 DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption, lp->TransmitKeyID );
1258 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 );
1260 } // wl_set_wep_keys
1261 /*============================================================================*/
1264 /*******************************************************************************
1266 *******************************************************************************
1270 * Write the parameters to the adapter. (re-)enables the card if device is
1271 * open. Returns hcf_status of hcf_enable().
1275 * lp - a pointer to the wireless adapter's private structure
1279 * an HCF status code
1281 ******************************************************************************/
1282 int wl_apply(struct wl_private *lp)
1284 int hcf_status = HCF_SUCCESS;
1286 DBG_ASSERT( lp != NULL);
1287 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1289 if ( !( lp->flags & WVLAN2_UIL_BUSY )) {
1290 /* The adapter parameters have changed:
1296 if ( wl_adapter_is_open( lp->dev )) {
1297 /* Disconnect and disable if necessary */
1298 hcf_status = wl_disconnect( lp );
1299 if ( hcf_status != HCF_SUCCESS ) {
1300 DBG_ERROR( DbgInfo, "Disconnect failed\n" );
1303 hcf_status = wl_disable( lp );
1304 if ( hcf_status != HCF_SUCCESS ) {
1305 DBG_ERROR( DbgInfo, "Disable failed\n" );
1308 /* Write out configuration to the device, enable, and reconnect.
1309 However, only reconnect if in AP mode. For STA mode, need to
1310 wait for passive scan completion before a connect can be
1312 hcf_status = wl_put_ltv( lp );
1314 if ( hcf_status == HCF_SUCCESS ) {
1315 hcf_status = wl_enable( lp );
1317 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1318 hcf_status = wl_connect( lp );
1321 DBG_WARNING( DbgInfo, "wl_put_ltv() failed\n" );
1329 /*============================================================================*/
1332 /*******************************************************************************
1334 *******************************************************************************
1338 * Used to set basic parameters for card initialization.
1342 * lp - a pointer to the wireless adapter's private structure
1346 * an HCF status code
1348 ******************************************************************************/
1349 int wl_put_ltv_init( struct wl_private *lp )
1353 CFG_RID_LOG_STRCT *RidLog;
1356 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1360 lp->ltvRecord.len = 2;
1361 lp->ltvRecord.typ = CFG_CNTL_OPT;
1363 /* The Card Services build must ALWAYS be configured for 16-bit I/O. PCI or
1364 CardBus can be set to either 16/32 bit I/O, or Bus Master DMA, but only
1367 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_16BIT );
1369 if ( lp->use_dma ) {
1370 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_DMA );
1372 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1376 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1377 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT : 0x%04x\n",
1378 lp->ltvRecord.u.u16[0] );
1379 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT result : 0x%04x\n",
1382 /* Register the list of RIDs on which asynchronous notification is
1383 required. Note that this mechanism replaces the mailbox, so the mailbox
1384 can be queried by the host (if desired) without contention from us */
1387 lp->RidList[i].len = sizeof( lp->ProbeResp );
1388 lp->RidList[i].typ = CFG_ACS_SCAN;
1389 lp->RidList[i].bufp = (wci_recordp)&lp->ProbeResp;
1390 //lp->ProbeResp.infoType = 0xFFFF;
1393 lp->RidList[i].len = sizeof( lp->assoc_stat );
1394 lp->RidList[i].typ = CFG_ASSOC_STAT;
1395 lp->RidList[i].bufp = (wci_recordp)&lp->assoc_stat;
1396 lp->assoc_stat.len = 0xFFFF;
1399 lp->RidList[i].len = 4;
1400 lp->RidList[i].typ = CFG_UPDATED_INFO_RECORD;
1401 lp->RidList[i].bufp = (wci_recordp)&lp->updatedRecord;
1402 lp->updatedRecord.len = 0xFFFF;
1405 lp->RidList[i].len = sizeof( lp->sec_stat );
1406 lp->RidList[i].typ = CFG_SECURITY_STAT;
1407 lp->RidList[i].bufp = (wci_recordp)&lp->sec_stat;
1408 lp->sec_stat.len = 0xFFFF;
1411 lp->RidList[i].typ = 0; // Terminate List
1413 RidLog = (CFG_RID_LOG_STRCT *)&lp->ltvRecord;
1415 RidLog->typ = CFG_REG_INFO_LOG;
1416 RidLog->recordp = (RID_LOGP)&lp->RidList[0];
1418 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1419 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG\n" );
1420 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG result : 0x%04x\n",
1423 } // wl_put_ltv_init
1424 /*============================================================================*/
1427 /*******************************************************************************
1429 *******************************************************************************
1433 * Used by wvlan_apply() and wvlan_go to set the card's configuration.
1437 * lp - a pointer to the wireless adapter's private structure
1441 * an HCF status code
1443 ******************************************************************************/
1444 int wl_put_ltv( struct wl_private *lp )
1450 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1453 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1454 lp->maxPort = 6; //;?why set this here and not as part of download process
1459 /* Send our configuration to the card. Perform any endian translation
1461 /* Register the Mailbox; VxWorks does this elsewhere; why;? */
1462 lp->ltvRecord.len = 4;
1463 lp->ltvRecord.typ = CFG_REG_MB;
1464 lp->ltvRecord.u.u32[0] = (u_long)&( lp->mailbox );
1465 lp->ltvRecord.u.u16[2] = ( MB_SIZE / sizeof( hcf_16 ));
1466 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1468 /* Max Data Length */
1469 lp->ltvRecord.len = 2;
1470 lp->ltvRecord.typ = CFG_CNF_MAX_DATA_LEN;
1471 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( HCF_MAX_PACKET_SIZE );
1472 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1474 /* System Scale / Distance between APs */
1475 lp->ltvRecord.len = 2;
1476 lp->ltvRecord.typ = CFG_CNF_SYSTEM_SCALE;
1477 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DistanceBetweenAPs );
1478 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1481 if ( lp->CreateIBSS && ( lp->Channel == 0 )) {
1482 DBG_TRACE( DbgInfo, "Create IBSS" );
1485 lp->ltvRecord.len = 2;
1486 lp->ltvRecord.typ = CFG_CNF_OWN_CHANNEL;
1487 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->Channel );
1488 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1490 /* Microwave Robustness */
1491 lp->ltvRecord.len = 2;
1492 lp->ltvRecord.typ = CFG_CNF_MICRO_WAVE;
1493 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MicrowaveRobustness );
1494 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1496 /* Load Balancing */
1497 lp->ltvRecord.len = 2;
1498 lp->ltvRecord.typ = CFG_CNF_LOAD_BALANCING;
1499 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->loadBalancing );
1500 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1502 /* Medium Distribution */
1503 lp->ltvRecord.len = 2;
1504 lp->ltvRecord.typ = CFG_CNF_MEDIUM_DISTRIBUTION;
1505 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->mediumDistribution );
1506 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1510 /* Tx Power Level (for supported cards) */
1511 lp->ltvRecord.len = 2;
1512 lp->ltvRecord.typ = CFG_CNF_TX_POW_LVL;
1513 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->txPowLevel );
1514 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1516 /* Short Retry Limit */
1517 /*lp->ltvRecord.len = 2;
1518 lp->ltvRecord.typ = 0xFC32;
1519 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->shortRetryLimit );
1520 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1523 /* Long Retry Limit */
1524 /*lp->ltvRecord.len = 2;
1525 lp->ltvRecord.typ = 0xFC33;
1526 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->longRetryLimit );
1527 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1530 /* Supported Rate Set Control */
1531 lp->ltvRecord.len = 3;
1532 lp->ltvRecord.typ = CFG_SUPPORTED_RATE_SET_CNTL; //0xFC88;
1533 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->srsc[0] );
1534 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->srsc[1] );
1535 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1537 /* Basic Rate Set Control */
1538 lp->ltvRecord.len = 3;
1539 lp->ltvRecord.typ = CFG_BASIC_RATE_SET_CNTL; //0xFC89;
1540 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->brsc[0] );
1541 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->brsc[1] );
1542 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1544 /* Frame Burst Limit */
1545 /* Defined, but not currently available in Firmware */
1550 /* Multicast Rate */
1551 lp->ltvRecord.len = 3;
1552 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1553 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1554 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->MulticastRate[1] );
1556 lp->ltvRecord.len = 2;
1557 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1558 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1560 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1562 /* Own Name (Station Nickname) */
1563 if (( len = ( strlen( lp->StationName ) + 1 ) & ~0x01 ) != 0 ) {
1564 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : %s\n",
1565 // lp->StationName );
1567 lp->ltvRecord.len = 2 + ( len / sizeof( hcf_16 ));
1568 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1569 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->StationName ));
1571 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->StationName, len );
1573 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : EMPTY\n" );
1575 lp->ltvRecord.len = 2;
1576 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1577 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1580 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1582 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME result : 0x%04x\n",
1585 /* The following are set in STA mode only */
1586 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1589 lp->ltvRecord.len = 2;
1590 lp->ltvRecord.typ = CFG_RTS_THRH;
1591 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1592 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1595 lp->ltvRecord.len = 2;
1596 lp->ltvRecord.typ = CFG_CNF_PORT_TYPE;
1597 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PortType );
1598 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1600 /* Tx Rate Control */
1602 lp->ltvRecord.len = 3;
1603 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1604 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1605 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1607 lp->ltvRecord.len = 2;
1608 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1609 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1612 //;?skip temporarily to see whether the RID or something else is the problem hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1614 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 2.4GHz : 0x%04x\n",
1615 lp->TxRateControl[0] );
1616 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 5.0GHz : 0x%04x\n",
1617 lp->TxRateControl[1] );
1618 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL result : 0x%04x\n",
1620 /* Power Management */
1621 lp->ltvRecord.len = 2;
1622 lp->ltvRecord.typ = CFG_CNF_PM_ENABLED;
1623 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PMEnabled );
1624 // lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0x8001 );
1625 DBG_TRACE( DbgInfo, "CFG_CNF_PM_ENABLED : 0x%04x\n", lp->PMEnabled );
1626 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1627 /* Multicast Receive */
1628 lp->ltvRecord.len = 2;
1629 lp->ltvRecord.typ = CFG_CNF_MCAST_RX;
1630 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastReceive );
1631 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1633 /* Max Sleep Duration */
1634 lp->ltvRecord.len = 2;
1635 lp->ltvRecord.typ = CFG_CNF_MAX_SLEEP_DURATION;
1636 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MaxSleepDuration );
1637 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1640 lp->ltvRecord.len = 2;
1641 lp->ltvRecord.typ = CFG_CREATE_IBSS;
1642 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->CreateIBSS );
1643 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1646 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1647 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1648 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1649 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : %s\n",
1650 // lp->NetworkName );
1652 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1653 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1654 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1656 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1658 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : ANY\n" );
1660 lp->ltvRecord.len = 2;
1661 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1662 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1665 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1667 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID result : 0x%04x\n",
1669 /* Own ATIM window */
1670 lp->ltvRecord.len = 2;
1671 lp->ltvRecord.typ = CFG_CNF_OWN_ATIM_WINDOW;
1672 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->atimWindow );
1673 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1676 /* Holdover Duration */
1677 lp->ltvRecord.len = 2;
1678 lp->ltvRecord.typ = CFG_CNF_HOLDOVER_DURATION;
1679 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->holdoverDuration );
1680 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1682 /* Promiscuous Mode */
1683 lp->ltvRecord.len = 2;
1684 lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
1685 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->promiscuousMode );
1686 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1688 /* Authentication */
1689 lp->ltvRecord.len = 2;
1690 lp->ltvRecord.typ = CFG_CNF_AUTHENTICATION;
1691 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->authentication );
1692 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1694 /* Connection Control */
1695 lp->ltvRecord.len = 2;
1696 lp->ltvRecord.typ = CFG_CNF_CONNECTION_CNTL;
1697 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->connectionControl );
1698 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1702 /* Probe data rate */
1703 /*lp->ltvRecord.len = 3;
1704 lp->ltvRecord.typ = CFG_PROBE_DATA_RATE;
1705 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->probeDataRates[0] );
1706 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->probeDataRates[1] );
1707 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1709 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 2.4GHz : 0x%04x\n",
1710 lp->probeDataRates[0] );
1711 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 5.0GHz : 0x%04x\n",
1712 lp->probeDataRates[1] );
1713 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE result : 0x%04x\n",
1717 /* The following are set in AP mode only */
1718 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
1719 //;?should we restore this to allow smaller memory footprint
1722 lp->ltvRecord.len = 2;
1723 lp->ltvRecord.typ = CFG_CNF_OWN_DTIM_PERIOD;
1724 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DTIMPeriod );
1725 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1727 /* Multicast PM Buffering */
1728 lp->ltvRecord.len = 2;
1729 lp->ltvRecord.typ = CFG_CNF_MCAST_PM_BUF;
1730 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->multicastPMBuffering );
1731 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1733 /* Reject ANY - Closed System */
1734 lp->ltvRecord.len = 2;
1735 lp->ltvRecord.typ = CFG_CNF_REJECT_ANY;
1736 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RejectAny );
1738 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1740 /* Exclude Unencrypted */
1741 lp->ltvRecord.len = 2;
1742 lp->ltvRecord.typ = CFG_CNF_EXCL_UNENCRYPTED;
1743 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ExcludeUnencrypted );
1745 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1747 /* IntraBSS Relay */
1748 lp->ltvRecord.len = 2;
1749 lp->ltvRecord.typ = CFG_CNF_INTRA_BSS_RELAY;
1750 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->intraBSSRelay );
1751 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1753 /* RTS Threshold 0 */
1754 lp->ltvRecord.len = 2;
1755 lp->ltvRecord.typ = CFG_RTS_THRH0;
1756 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1758 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1760 /* Tx Rate Control 0 */
1762 lp->ltvRecord.len = 3;
1763 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1764 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1765 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1767 lp->ltvRecord.len = 2;
1768 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1769 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1772 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1774 /* Own Beacon Interval */
1775 lp->ltvRecord.len = 2;
1776 lp->ltvRecord.typ = 0xFC31;
1777 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ownBeaconInterval );
1778 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1780 /* Co-Existence Behavior */
1781 lp->ltvRecord.len = 2;
1782 lp->ltvRecord.typ = 0xFCC7;
1783 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->coexistence );
1784 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1788 /* RTS Threshold 1 */
1789 lp->ltvRecord.len = 2;
1790 lp->ltvRecord.typ = CFG_RTS_THRH1;
1791 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].rtsThreshold );
1792 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1794 /* RTS Threshold 2 */
1795 lp->ltvRecord.len = 2;
1796 lp->ltvRecord.typ = CFG_RTS_THRH2;
1797 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].rtsThreshold );
1798 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1801 /* RTS Threshold 3 */
1802 lp->ltvRecord.len = 2;
1803 lp->ltvRecord.typ = CFG_RTS_THRH3;
1804 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].rtsThreshold );
1805 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1808 /* RTS Threshold 4 */
1809 lp->ltvRecord.len = 2;
1810 lp->ltvRecord.typ = CFG_RTS_THRH4;
1811 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].rtsThreshold );
1812 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1815 /* RTS Threshold 5 */
1816 lp->ltvRecord.len = 2;
1817 lp->ltvRecord.typ = CFG_RTS_THRH5;
1818 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].rtsThreshold );
1819 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1821 /* RTS Threshold 6 */
1822 lp->ltvRecord.len = 2;
1823 lp->ltvRecord.typ = CFG_RTS_THRH6;
1824 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].rtsThreshold );
1825 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1827 /* TX Rate Control 1 */
1828 lp->ltvRecord.len = 2;
1829 lp->ltvRecord.typ = CFG_TX_RATE_CNTL1;
1830 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].txRateCntl );
1831 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1833 /* TX Rate Control 2 */
1834 lp->ltvRecord.len = 2;
1835 lp->ltvRecord.typ = CFG_TX_RATE_CNTL2;
1836 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].txRateCntl );
1837 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1839 /* TX Rate Control 3 */
1840 lp->ltvRecord.len = 2;
1841 lp->ltvRecord.typ = CFG_TX_RATE_CNTL3;
1842 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].txRateCntl );
1843 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1845 /* TX Rate Control 4 */
1846 lp->ltvRecord.len = 2;
1847 lp->ltvRecord.typ = CFG_TX_RATE_CNTL4;
1848 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].txRateCntl );
1849 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1851 /* TX Rate Control 5 */
1852 lp->ltvRecord.len = 2;
1853 lp->ltvRecord.typ = CFG_TX_RATE_CNTL5;
1854 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].txRateCntl );
1855 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1857 /* TX Rate Control 6 */
1858 lp->ltvRecord.len = 2;
1859 lp->ltvRecord.typ = CFG_TX_RATE_CNTL6;
1860 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].txRateCntl );
1861 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1865 /* WDS addresses. It's okay to blindly send these parameters, because
1866 the port needs to be enabled, before anything is done with it. */
1869 lp->ltvRecord.len = 4;
1870 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR1;
1872 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[0].wdsAddress, ETH_ALEN );
1873 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1876 lp->ltvRecord.len = 4;
1877 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR2;
1879 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[1].wdsAddress, ETH_ALEN );
1880 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1883 lp->ltvRecord.len = 4;
1884 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR3;
1886 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[2].wdsAddress, ETH_ALEN );
1887 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1890 lp->ltvRecord.len = 4;
1891 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR4;
1893 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[3].wdsAddress, ETH_ALEN );
1894 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1897 lp->ltvRecord.len = 4;
1898 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR5;
1900 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[4].wdsAddress, ETH_ALEN );
1901 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1904 lp->ltvRecord.len = 4;
1905 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR6;
1907 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[5].wdsAddress, ETH_ALEN );
1908 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1909 #endif /* USE_WDS */
1910 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1913 /* Own MAC Address */
1915 DBG_TRACE(DbgInfo, "MAC Address : %pM\n",
1919 if ( WVLAN_VALID_MAC_ADDRESS( lp->MACAddress )) {
1920 /* Make the MAC address valid by:
1921 Clearing the multicast bit
1922 Setting the local MAC address bit
1924 //lp->MACAddress[0] &= ~0x03; //;?why is this commented out already in 720
1925 //lp->MACAddress[0] |= 0x02;
1927 lp->ltvRecord.len = 1 + ( ETH_ALEN / sizeof( hcf_16 ));
1928 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1929 //DBG_TRACE( DbgInfo, "CFG_NIC_MAC_ADDR\n" );
1930 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1932 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_MAC_ADDR\n" );
1933 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1935 /* MAC address is byte aligned, no endian conversion needed */
1936 memcpy( &( lp->ltvRecord.u.u8[0] ), lp->MACAddress, ETH_ALEN );
1937 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1938 //DBG_TRACE( DbgInfo, "CFG_XXX_MAC_ADDR result : 0x%04x\n",
1941 /* Update the MAC address in the netdevice struct */
1942 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN ); //;?what is the purpose of this seemingly complex logic
1945 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1946 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1947 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1948 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : %s\n",
1949 // lp->NetworkName );
1950 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1951 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1952 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1954 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1956 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : ANY\n" );
1957 lp->ltvRecord.len = 2;
1958 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1959 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1962 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1964 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID result : 0x%04x\n",
1966 /* enable/disable encryption */
1967 lp->ltvRecord.len = 2;
1968 lp->ltvRecord.typ = CFG_CNF_ENCRYPTION;
1969 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->EnableEncryption );
1970 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1972 /* Set the Authentication Key Management Suite */
1973 lp->ltvRecord.len = 2;
1974 lp->ltvRecord.typ = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
1975 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->AuthKeyMgmtSuite );
1976 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1978 /* If WEP (or no) keys are being used, write (or clear) them */
1979 if (lp->wext_enc != IW_ENCODE_ALG_TKIP)
1980 wl_set_wep_keys(lp);
1983 /* countryInfo, ltvCountryInfo, CFG_CNF_COUNTRY_INFO */
1987 /*============================================================================*/
1990 /*******************************************************************************
1992 *******************************************************************************
1996 * Load the kernel module.
2005 * an errno value otherwise
2007 ******************************************************************************/
2008 static int __init wl_module_init( void )
2011 /*------------------------------------------------------------------------*/
2015 /* Convert "standard" PCMCIA parameter pc_debug to a reasonable DebugFlag value.
2016 * NOTE: The values all fall through to the lower values. */
2017 DbgInfo->DebugFlag = 0;
2018 DbgInfo->DebugFlag = DBG_TRACE_ON; //;?get this mess resolved one day
2019 if ( pc_debug ) switch( pc_debug ) {
2021 DbgInfo->DebugFlag |= DBG_DS_ON;
2023 DbgInfo->DebugFlag |= DBG_RX_ON | DBG_TX_ON;
2025 DbgInfo->DebugFlag |= DBG_PARAM_ON;
2027 DbgInfo->DebugFlag |= DBG_TRACE_ON;
2029 DbgInfo->DebugFlag |= DBG_VERBOSE_ON;
2031 DbgInfo->DebugFlag |= DBG_DEFAULTS;
2037 printk(KERN_INFO "%s\n", VERSION_INFO);
2038 printk(KERN_INFO "*** Modified for kernel 2.6 by Henk de Groot <pe1dnn@amsat.org>\n");
2039 printk(KERN_INFO "*** Based on 7.18 version by Andrey Borzenkov <arvidjaar@mail.ru> $Revision: 39 $\n");
2042 // ;?#if (HCF_TYPE) & HCF_TYPE_AP
2043 // DBG_PRINT( "Access Point Mode (AP) Support: YES\n" );
2045 // DBG_PRINT( "Access Point Mode (AP) Support: NO\n" );
2046 // #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2048 result = wl_adapter_init_module( );
2051 /*============================================================================*/
2054 /*******************************************************************************
2056 *******************************************************************************
2060 * Unload the kernel module.
2070 ******************************************************************************/
2071 static void __exit wl_module_exit( void )
2073 wl_adapter_cleanup_module( );
2074 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
2075 remove_proc_entry( "wlags", NULL ); //;?why so a-symmetric compared to location of proc_create_data
2078 /*============================================================================*/
2080 module_init(wl_module_init);
2081 module_exit(wl_module_exit);
2083 /*******************************************************************************
2085 *******************************************************************************
2089 * The Interrupt Service Routine for the driver.
2093 * irq - the irq the interrupt came in on
2094 * dev_id - a buffer containing information about the request
2101 ******************************************************************************/
2102 irqreturn_t wl_isr( int irq, void *dev_id, struct pt_regs *regs )
2105 struct net_device *dev = (struct net_device *) dev_id;
2106 struct wl_private *lp = NULL;
2107 /*------------------------------------------------------------------------*/
2108 if (( dev == NULL ) || ( !netif_device_present( dev ))) {
2112 /* Set the wl_private pointer (lp), now that we know that dev is non-null */
2116 if ( lp->useRTS == 1 ) {
2117 DBG_PRINT( "EXITING ISR, IN RTS MODE...\n" );
2120 #endif /* USE_RTS */
2122 /* If we have interrupts pending, then put them on a system task
2123 queue. Otherwise turn interrupts back on */
2124 events = hcf_action( &lp->hcfCtx, HCF_ACT_INT_OFF );
2126 if ( events == HCF_INT_PENDING ) {
2127 /* Schedule the ISR handler as a bottom-half task in the
2128 tq_immediate queue */
2129 tasklet_schedule(&lp->task);
2131 //DBG_PRINT( "NOT OUR INTERRUPT\n" );
2132 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2135 return IRQ_RETVAL(events == HCF_INT_PENDING);
2137 /*============================================================================*/
2140 /*******************************************************************************
2142 *******************************************************************************
2146 * The ISR handler, scheduled to run in a deferred context by the ISR. This
2147 * is where the ISR's work actually gets done.
2151 * lp - a pointer to the device's private adapter structure
2157 ******************************************************************************/
2158 #define WVLAN_MAX_INT_SERVICES 50
2160 void wl_isr_handler( unsigned long p )
2162 struct net_device *dev;
2163 unsigned long flags;
2167 struct wl_private *lp = (struct wl_private *)p;
2168 /*------------------------------------------------------------------------*/
2171 DBG_PRINT( "wl_isr_handler lp adapter pointer is NULL!!!\n" );
2173 wl_lock( lp, &flags );
2175 dev = (struct net_device *)lp->dev;
2176 if ( dev != NULL && netif_device_present( dev ) ) stop = FALSE;
2177 for( count = 0; stop == FALSE && count < WVLAN_MAX_INT_SERVICES; count++ ) {
2179 result = hcf_service_nic( &lp->hcfCtx,
2180 (wci_bufp)lp->lookAheadBuf,
2181 sizeof( lp->lookAheadBuf ));
2182 if ( result == HCF_ERR_MIC ) {
2183 wl_wext_event_mic_failed( dev ); /* Send an event that MIC failed */
2184 //;?this seems wrong if HCF_ERR_MIC coincides with another event, stop gets FALSE
2185 //so why not do it always ;?
2188 #ifndef USE_MBOX_SYNC
2189 if ( lp->hcfCtx.IFB_MBInfoLen != 0 ) { /* anything in the mailbox */
2194 /* Check for a Link status event */
2195 if ( ( lp->hcfCtx.IFB_LinkStat & CFG_LINK_STAT_FW ) != 0 ) {
2196 wl_process_link_status( lp );
2199 /* Check for probe response events */
2200 if ( lp->ProbeResp.infoType != 0 &&
2201 lp->ProbeResp.infoType != 0xFFFF ) {
2202 wl_process_probe_response( lp );
2203 memset( &lp->ProbeResp, 0, sizeof( lp->ProbeResp ));
2204 lp->ProbeResp.infoType = 0xFFFF;
2207 /* Check for updated record events */
2208 if ( lp->updatedRecord.len != 0xFFFF ) {
2209 wl_process_updated_record( lp );
2210 lp->updatedRecord.len = 0xFFFF;
2213 /* Check for association status events */
2214 if ( lp->assoc_stat.len != 0xFFFF ) {
2215 wl_process_assoc_status( lp );
2216 lp->assoc_stat.len = 0xFFFF;
2219 /* Check for security status events */
2220 if ( lp->sec_stat.len != 0xFFFF ) {
2221 wl_process_security_status( lp );
2222 lp->sec_stat.len = 0xFFFF;
2227 if ( lp->use_dma ) {
2228 /* Check for DMA Rx packets */
2229 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_RDMAD ) {
2233 /* Return Tx DMA descriptors to host */
2234 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_TDMAD ) {
2235 wl_pci_dma_hcf_reclaim_tx( lp );
2240 #endif // ENABLE_DMA
2242 /* Check for Rx packets */
2243 if ( lp->hcfCtx.IFB_RxLen != 0 ) {
2247 /* Make sure that queued frames get sent */
2248 if ( wl_send( lp )) {
2253 /* We're done, so turn interrupts which were turned off in wl_isr, back on */
2254 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2255 wl_unlock( lp, &flags );
2259 /*============================================================================*/
2262 /*******************************************************************************
2264 *******************************************************************************
2268 * Notify the adapter that it has been removed. Since the adapter is gone,
2269 * we should no longer try to talk to it.
2273 * dev - a pointer to the device's net_device structure
2279 ******************************************************************************/
2280 void wl_remove( struct net_device *dev )
2282 struct wl_private *lp = wl_priv(dev);
2283 unsigned long flags;
2285 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2287 wl_lock( lp, &flags );
2289 /* stop handling interrupts */
2290 wl_act_int_off( lp );
2291 lp->is_handling_int = WL_NOT_HANDLING_INT;
2294 * Disable the ports: just change state: since the
2295 * card is gone it is useless to talk to it and at
2296 * disconnect all state information is lost anyway.
2298 /* Reset portState */
2299 lp->portState = WVLAN_PORT_STATE_DISABLED;
2301 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
2303 //wl_disable_wds_ports( lp );
2305 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2307 /* Mark the device as unregistered */
2308 lp->is_registered = FALSE;
2310 /* Deregister the WDS ports as well */
2311 WL_WDS_NETDEV_DEREGISTER( lp );
2313 if ( lp->useRTS == 1 ) {
2314 wl_unlock( lp, &flags );
2317 #endif /* USE_RTS */
2319 /* Inform the HCF that the card has been removed */
2320 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2322 wl_unlock( lp, &flags );
2324 /*============================================================================*/
2327 /*******************************************************************************
2329 *******************************************************************************
2333 * Power-down and halt the adapter.
2337 * dev - a pointer to the device's net_device structure
2343 ******************************************************************************/
2344 void wl_suspend( struct net_device *dev )
2346 struct wl_private *lp = wl_priv(dev);
2347 unsigned long flags;
2349 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2351 /* The adapter is suspended:
2355 wl_lock( lp, &flags );
2357 /* Disable interrupt handling */
2358 wl_act_int_off( lp );
2361 wl_disconnect( lp );
2366 /* Disconnect from the adapter */
2367 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2369 /* Reset portState to be sure (should have been done by wl_disable */
2370 lp->portState = WVLAN_PORT_STATE_DISABLED;
2372 wl_unlock( lp, &flags );
2374 /*============================================================================*/
2377 /*******************************************************************************
2379 *******************************************************************************
2383 * Resume a previously suspended adapter.
2387 * dev - a pointer to the device's net_device structure
2393 ******************************************************************************/
2394 void wl_resume(struct net_device *dev)
2396 struct wl_private *lp = wl_priv(dev);
2397 unsigned long flags;
2399 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2401 wl_lock( lp, &flags );
2403 /* Connect to the adapter */
2404 hcf_connect( &lp->hcfCtx, dev->base_addr );
2406 /* Reset portState */
2407 lp->portState = WVLAN_PORT_STATE_DISABLED;
2409 /* Power might have been off, assume the card lost the firmware*/
2410 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
2412 /* Reload the firmware and restart */
2415 /* Resume interrupt handling */
2416 wl_act_int_on( lp );
2418 wl_unlock( lp, &flags );
2420 /*============================================================================*/
2423 /*******************************************************************************
2425 *******************************************************************************
2429 * This function performs a check on the device and calls wl_remove() if
2430 * necessary. This function can be used for all bus types, but exists mostly
2431 * for the benefit of the Card Services driver, as there are times when
2432 * wl_remove() does not get called.
2436 * dev - a pointer to the device's net_device structure
2442 ******************************************************************************/
2443 void wl_release( struct net_device *dev )
2445 struct wl_private *lp = wl_priv(dev);
2447 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2448 /* If wl_remove() hasn't been called (i.e. when Card Services is shut
2449 down with the card in the slot), then call it */
2450 if ( lp->is_registered == TRUE ) {
2451 DBG_TRACE( DbgInfo, "Calling unregister_netdev(), as it wasn't called yet\n" );
2454 lp->is_registered = FALSE;
2457 /*============================================================================*/
2460 /*******************************************************************************
2462 *******************************************************************************
2466 * Accessor function to retrieve the irq_mask module parameter
2474 * The irq_mask module parameter
2476 ******************************************************************************/
2477 p_u16 wl_get_irq_mask( void )
2480 } // wl_get_irq_mask
2481 /*============================================================================*/
2484 /*******************************************************************************
2486 *******************************************************************************
2490 * Accessor function to retrieve the irq_list module parameter
2498 * The irq_list module parameter
2500 ******************************************************************************/
2501 p_s8 * wl_get_irq_list( void )
2504 } // wl_get_irq_list
2505 /*============================================================================*/
2509 /*******************************************************************************
2511 *******************************************************************************
2515 * Used to enable MAC ports
2519 * lp - pointer to the device's private adapter structure
2525 ******************************************************************************/
2526 int wl_enable( struct wl_private *lp )
2528 int hcf_status = HCF_SUCCESS;
2530 if ( lp->portState == WVLAN_PORT_STATE_ENABLED ) {
2531 DBG_TRACE( DbgInfo, "No action: Card already enabled\n" );
2532 } else if ( lp->portState == WVLAN_PORT_STATE_CONNECTED ) {
2533 //;?suspicuous logic, how can you be connected without being enabled so this is probably dead code
2534 DBG_TRACE( DbgInfo, "No action: Card already connected\n" );
2536 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_ENABLE );
2537 if ( hcf_status == HCF_SUCCESS ) {
2538 /* Set the status of the NIC to enabled */
2539 lp->portState = WVLAN_PORT_STATE_ENABLED; //;?bad mnemonic, NIC iso PORT
2541 if ( lp->use_dma ) {
2542 wl_pci_dma_hcf_supply( lp ); //;?always successful?
2547 if ( hcf_status != HCF_SUCCESS ) { //;?make this an assert
2548 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2552 /*============================================================================*/
2556 /*******************************************************************************
2557 * wl_enable_wds_ports()
2558 *******************************************************************************
2562 * Used to enable the WDS MAC ports 1-6
2566 * lp - pointer to the device's private adapter structure
2572 ******************************************************************************/
2573 void wl_enable_wds_ports( struct wl_private * lp )
2575 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2576 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2578 } // wl_enable_wds_ports
2579 #endif /* USE_WDS */
2580 /*============================================================================*/
2583 /*******************************************************************************
2585 *******************************************************************************
2589 * Used to connect a MAC port
2593 * lp - pointer to the device's private adapter structure
2599 ******************************************************************************/
2600 int wl_connect( struct wl_private *lp )
2604 if ( lp->portState != WVLAN_PORT_STATE_ENABLED ) {
2605 DBG_TRACE( DbgInfo, "No action: Not in enabled state\n" );
2608 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_CONNECT );
2609 if ( hcf_status == HCF_SUCCESS ) {
2610 lp->portState = WVLAN_PORT_STATE_CONNECTED;
2614 /*============================================================================*/
2617 /*******************************************************************************
2619 *******************************************************************************
2623 * Used to disconnect a MAC port
2627 * lp - pointer to the device's private adapter structure
2633 ******************************************************************************/
2634 int wl_disconnect( struct wl_private *lp )
2638 if ( lp->portState != WVLAN_PORT_STATE_CONNECTED ) {
2639 DBG_TRACE( DbgInfo, "No action: Not in connected state\n" );
2642 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISCONNECT );
2643 if ( hcf_status == HCF_SUCCESS ) {
2644 lp->portState = WVLAN_PORT_STATE_ENABLED;
2648 /*============================================================================*/
2651 /*******************************************************************************
2653 *******************************************************************************
2657 * Used to disable MAC ports
2661 * lp - pointer to the device's private adapter structure
2662 * port - the MAC port to disable
2668 ******************************************************************************/
2669 int wl_disable( struct wl_private *lp )
2671 int hcf_status = HCF_SUCCESS;
2673 if ( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
2674 DBG_TRACE( DbgInfo, "No action: Port state is disabled\n" );
2676 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISABLE );
2677 if ( hcf_status == HCF_SUCCESS ) {
2678 /* Set the status of the port to disabled */ //;?bad mnemonic use NIC iso PORT
2679 lp->portState = WVLAN_PORT_STATE_DISABLED;
2682 if ( lp->use_dma ) {
2683 wl_pci_dma_hcf_reclaim( lp );
2688 if ( hcf_status != HCF_SUCCESS ) {
2689 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2693 /*============================================================================*/
2697 /*******************************************************************************
2698 * wl_disable_wds_ports()
2699 *******************************************************************************
2703 * Used to disable the WDS MAC ports 1-6
2707 * lp - pointer to the device's private adapter structure
2713 ******************************************************************************/
2714 void wl_disable_wds_ports( struct wl_private * lp )
2716 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2717 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2719 // if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
2720 // wl_disable( lp, HCF_PORT_1 );
2721 // wl_disable( lp, HCF_PORT_2 );
2722 // wl_disable( lp, HCF_PORT_3 );
2723 // wl_disable( lp, HCF_PORT_4 );
2724 // wl_disable( lp, HCF_PORT_5 );
2725 // wl_disable( lp, HCF_PORT_6 );
2728 } // wl_disable_wds_ports
2730 /*============================================================================*/
2733 #ifndef USE_MBOX_SYNC
2734 /*******************************************************************************
2736 *******************************************************************************
2739 * This function is used to read and process a mailbox message.
2744 * lp - pointer to the device's private adapter structure
2748 * an HCF status code
2750 ******************************************************************************/
2751 int wl_mbx( struct wl_private *lp )
2753 int hcf_status = HCF_SUCCESS;
2755 DBG_TRACE( DbgInfo, "Mailbox Info: IFB_MBInfoLen: %d\n",
2756 lp->hcfCtx.IFB_MBInfoLen );
2758 memset( &( lp->ltvRecord ), 0, sizeof( ltv_t ));
2760 lp->ltvRecord.len = MB_SIZE;
2761 lp->ltvRecord.typ = CFG_MB_INFO;
2762 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2764 if ( hcf_status != HCF_SUCCESS ) {
2765 DBG_ERROR( DbgInfo, "hcf_get_info returned 0x%x\n", hcf_status );
2769 if ( lp->ltvRecord.typ == CFG_MB_INFO )
2772 /* Endian translate the mailbox data, then process the message */
2773 wl_endian_translate_mailbox( &( lp->ltvRecord ));
2774 wl_process_mailbox( lp );
2777 /*============================================================================*/
2780 /*******************************************************************************
2781 * wl_endian_translate_mailbox()
2782 *******************************************************************************
2786 * This function will perform the tedious task of endian translating all
2787 * fields within a mailbox message which need translating.
2791 * ltv - pointer to the LTV to endian translate
2797 ******************************************************************************/
2798 void wl_endian_translate_mailbox( ltv_t *ltv )
2800 switch( ltv->typ ) {
2807 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
2809 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2810 ( sizeof( SCAN_RS_STRCT )));
2812 while( num_aps >= 1 ) {
2815 aps[num_aps].channel_id =
2816 CNV_LITTLE_TO_INT( aps[num_aps].channel_id );
2818 aps[num_aps].noise_level =
2819 CNV_LITTLE_TO_INT( aps[num_aps].noise_level );
2821 aps[num_aps].signal_level =
2822 CNV_LITTLE_TO_INT( aps[num_aps].signal_level );
2824 aps[num_aps].beacon_interval_time =
2825 CNV_LITTLE_TO_INT( aps[num_aps].beacon_interval_time );
2827 aps[num_aps].capability =
2828 CNV_LITTLE_TO_INT( aps[num_aps].capability );
2830 aps[num_aps].ssid_len =
2831 CNV_LITTLE_TO_INT( aps[num_aps].ssid_len );
2833 aps[num_aps].ssid_val[aps[num_aps].ssid_len] = 0;
2840 PROBE_RESP *probe_resp = (PROBE_RESP *)ltv;
2842 probe_resp->frameControl = CNV_LITTLE_TO_INT( probe_resp->frameControl );
2843 probe_resp->durID = CNV_LITTLE_TO_INT( probe_resp->durID );
2844 probe_resp->sequence = CNV_LITTLE_TO_INT( probe_resp->sequence );
2845 probe_resp->dataLength = CNV_LITTLE_TO_INT( probe_resp->dataLength );
2847 probe_resp->lenType = CNV_LITTLE_TO_INT( probe_resp->lenType );
2849 probe_resp->beaconInterval = CNV_LITTLE_TO_INT( probe_resp->beaconInterval );
2850 probe_resp->capability = CNV_LITTLE_TO_INT( probe_resp->capability );
2851 probe_resp->flags = CNV_LITTLE_TO_INT( probe_resp->flags );
2856 #define ls ((LINK_STATUS_STRCT *)ltv)
2857 ls->linkStatus = CNV_LITTLE_TO_INT( ls->linkStatus );
2861 case CFG_ASSOC_STAT:
2863 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
2865 as->assocStatus = CNV_LITTLE_TO_INT( as->assocStatus );
2869 case CFG_SECURITY_STAT:
2871 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
2873 ss->securityStatus = CNV_LITTLE_TO_INT( ss->securityStatus );
2874 ss->reason = CNV_LITTLE_TO_INT( ss->reason );
2887 } // wl_endian_translate_mailbox
2888 /*============================================================================*/
2890 /*******************************************************************************
2891 * wl_process_mailbox()
2892 *******************************************************************************
2896 * This function processes the mailbox data.
2900 * ltv - pointer to the LTV to be processed.
2906 ******************************************************************************/
2907 void wl_process_mailbox( struct wl_private *lp )
2910 hcf_16 ltv_val = 0xFFFF;
2912 ltv = &( lp->ltvRecord );
2914 switch( ltv->typ ) {
2917 DBG_TRACE( DbgInfo, "CFG_TALLIES\n" );
2920 DBG_TRACE( DbgInfo, "CFG_SCAN\n" );
2924 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
2926 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2927 ( sizeof( SCAN_RS_STRCT )));
2929 lp->scan_results.num_aps = num_aps;
2931 DBG_TRACE( DbgInfo, "Number of APs: %d\n", num_aps );
2933 while( num_aps >= 1 ) {
2936 DBG_TRACE( DbgInfo, "AP : %d\n", num_aps );
2937 DBG_TRACE( DbgInfo, "=========================\n" );
2938 DBG_TRACE( DbgInfo, "Channel ID : 0x%04x\n",
2939 aps[num_aps].channel_id );
2940 DBG_TRACE( DbgInfo, "Noise Level : 0x%04x\n",
2941 aps[num_aps].noise_level );
2942 DBG_TRACE( DbgInfo, "Signal Level : 0x%04x\n",
2943 aps[num_aps].signal_level );
2944 DBG_TRACE( DbgInfo, "Beacon Interval : 0x%04x\n",
2945 aps[num_aps].beacon_interval_time );
2946 DBG_TRACE( DbgInfo, "Capability : 0x%04x\n",
2947 aps[num_aps].capability );
2948 DBG_TRACE( DbgInfo, "SSID Length : 0x%04x\n",
2949 aps[num_aps].ssid_len );
2950 DBG_TRACE(DbgInfo, "BSSID : %pM\n",
2951 aps[num_aps].bssid);
2953 if ( aps[num_aps].ssid_len != 0 ) {
2954 DBG_TRACE( DbgInfo, "SSID : %s.\n",
2955 aps[num_aps].ssid_val );
2957 DBG_TRACE( DbgInfo, "SSID : %s.\n", "ANY" );
2960 DBG_TRACE( DbgInfo, "\n" );
2962 /* Copy the info to the ScanResult structure in the private
2964 memcpy( &( lp->scan_results.APTable[num_aps]), &( aps[num_aps] ),
2965 sizeof( SCAN_RS_STRCT ));
2968 /* Set scan result to true so that any scan requests will
2970 lp->scan_results.scan_complete = TRUE;
2975 DBG_TRACE( DbgInfo, "CFG_ACS_SCAN\n" );
2978 PROBE_RESP *probe_rsp = (PROBE_RESP *)ltv;
2979 hcf_8 *wpa_ie = NULL;
2980 hcf_16 wpa_ie_len = 0;
2982 DBG_TRACE( DbgInfo, "(%s) =========================\n",
2985 DBG_TRACE( DbgInfo, "(%s) length : 0x%04x.\n",
2986 lp->dev->name, probe_rsp->length );
2988 if ( probe_rsp->length > 1 ) {
2989 DBG_TRACE( DbgInfo, "(%s) infoType : 0x%04x.\n",
2990 lp->dev->name, probe_rsp->infoType );
2992 DBG_TRACE( DbgInfo, "(%s) signal : 0x%02x.\n",
2993 lp->dev->name, probe_rsp->signal );
2995 DBG_TRACE( DbgInfo, "(%s) silence : 0x%02x.\n",
2996 lp->dev->name, probe_rsp->silence );
2998 DBG_TRACE( DbgInfo, "(%s) rxFlow : 0x%02x.\n",
2999 lp->dev->name, probe_rsp->rxFlow );
3001 DBG_TRACE( DbgInfo, "(%s) rate : 0x%02x.\n",
3002 lp->dev->name, probe_rsp->rate );
3004 DBG_TRACE( DbgInfo, "(%s) frame cntl : 0x%04x.\n",
3005 lp->dev->name, probe_rsp->frameControl );
3007 DBG_TRACE( DbgInfo, "(%s) durID : 0x%04x.\n",
3008 lp->dev->name, probe_rsp->durID );
3010 DBG_TRACE(DbgInfo, "(%s) address1 : %pM\n",
3011 lp->dev->name, probe_rsp->address1);
3013 DBG_TRACE(DbgInfo, "(%s) address2 : %pM\n",
3014 lp->dev->name, probe_rsp->address2);
3016 DBG_TRACE(DbgInfo, "(%s) BSSID : %pM\n",
3017 lp->dev->name, probe_rsp->BSSID);
3019 DBG_TRACE( DbgInfo, "(%s) sequence : 0x%04x.\n",
3020 lp->dev->name, probe_rsp->sequence );
3022 DBG_TRACE(DbgInfo, "(%s) address4 : %pM\n",
3023 lp->dev->name, probe_rsp->address4);
3025 DBG_TRACE( DbgInfo, "(%s) datalength : 0x%04x.\n",
3026 lp->dev->name, probe_rsp->dataLength );
3028 DBG_TRACE(DbgInfo, "(%s) DA : %pM\n",
3029 lp->dev->name, probe_rsp->DA);
3031 DBG_TRACE(DbgInfo, "(%s) SA : %pM\n",
3032 lp->dev->name, probe_rsp->SA);
3034 //DBG_TRACE( DbgInfo, "(%s) lenType : 0x%04x.\n",
3035 // lp->dev->name, probe_rsp->lenType );
3037 DBG_TRACE(DbgInfo, "(%s) timeStamp : "
3038 "%d.%d.%d.%d.%d.%d.%d.%d\n",
3040 probe_rsp->timeStamp[0],
3041 probe_rsp->timeStamp[1],
3042 probe_rsp->timeStamp[2],
3043 probe_rsp->timeStamp[3],
3044 probe_rsp->timeStamp[4],
3045 probe_rsp->timeStamp[5],
3046 probe_rsp->timeStamp[6],
3047 probe_rsp->timeStamp[7]);
3049 DBG_TRACE( DbgInfo, "(%s) beaconInt : 0x%04x.\n",
3050 lp->dev->name, probe_rsp->beaconInterval );
3052 DBG_TRACE( DbgInfo, "(%s) capability : 0x%04x.\n",
3053 lp->dev->name, probe_rsp->capability );
3055 DBG_TRACE( DbgInfo, "(%s) SSID len : 0x%04x.\n",
3056 lp->dev->name, probe_rsp->rawData[1] );
3058 if ( probe_rsp->rawData[1] > 0 ) {
3059 char ssid[HCF_MAX_NAME_LEN];
3061 memset( ssid, 0, sizeof( ssid ));
3062 strncpy( ssid, &probe_rsp->rawData[2],
3064 probe_rsp->rawData[1],
3065 HCF_MAX_NAME_LEN - 1));
3067 DBG_TRACE( DbgInfo, "(%s) SSID : %s\n",
3068 lp->dev->name, ssid );
3071 /* Parse out the WPA-IE, if one exists */
3072 wpa_ie = wl_parse_wpa_ie( probe_rsp, &wpa_ie_len );
3073 if ( wpa_ie != NULL ) {
3074 DBG_TRACE( DbgInfo, "(%s) WPA-IE : %s\n",
3075 lp->dev->name, wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
3078 DBG_TRACE( DbgInfo, "(%s) flags : 0x%04x.\n",
3079 lp->dev->name, probe_rsp->flags );
3082 DBG_TRACE( DbgInfo, "\n\n" );
3083 /* If probe response length is 1, then the scan is complete */
3084 if ( probe_rsp->length == 1 ) {
3085 DBG_TRACE( DbgInfo, "SCAN COMPLETE\n" );
3086 lp->probe_results.num_aps = lp->probe_num_aps;
3087 lp->probe_results.scan_complete = TRUE;
3089 /* Reset the counter for the next scan request */
3090 lp->probe_num_aps = 0;
3092 /* Send a wireless extensions event that the scan completed */
3093 wl_wext_event_scan_complete( lp->dev );
3095 /* Only copy to the table if the entry is unique; APs sometimes
3096 respond more than once to a probe */
3097 if ( lp->probe_num_aps == 0 ) {
3098 /* Copy the info to the ScanResult structure in the private
3100 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3101 probe_rsp, sizeof( PROBE_RESP ));
3103 /* Increment the number of APs detected */
3104 lp->probe_num_aps++;
3109 for( count = 0; count < lp->probe_num_aps; count++ ) {
3110 if ( memcmp( &( probe_rsp->BSSID ),
3111 lp->probe_results.ProbeTable[count].BSSID,
3118 /* Copy the info to the ScanResult structure in the
3119 private adapter struct. Only copy if there's room in the
3121 if ( lp->probe_num_aps < MAX_NAPS )
3123 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3124 probe_rsp, sizeof( PROBE_RESP ));
3128 DBG_WARNING( DbgInfo, "Num of scan results exceeds storage, truncating\n" );
3131 /* Increment the number of APs detected. Note I do this
3132 here even when I don't copy the probe response to the
3133 buffer in order to detect the overflow condition */
3134 lp->probe_num_aps++;
3143 #define ls ((LINK_STATUS_STRCT *)ltv)
3144 DBG_TRACE( DbgInfo, "CFG_LINK_STAT\n" );
3146 switch( ls->linkStatus ) {
3148 DBG_TRACE( DbgInfo, "Link Status : Connected\n" );
3149 wl_wext_event_ap( lp->dev );
3153 DBG_TRACE( DbgInfo, "Link Status : Disconnected\n" );
3157 DBG_TRACE( DbgInfo, "Link Status : Access Point Change\n" );
3161 DBG_TRACE( DbgInfo, "Link Status : Access Point Out of Range\n" );
3165 DBG_TRACE( DbgInfo, "Link Status : Access Point In Range\n" );
3169 DBG_TRACE( DbgInfo, "Link Status : UNKNOWN (0x%04x)\n",
3177 case CFG_ASSOC_STAT:
3178 DBG_TRACE( DbgInfo, "CFG_ASSOC_STAT\n" );
3181 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
3183 switch( as->assocStatus ) {
3185 DBG_TRACE( DbgInfo, "Association Status : STA Associated\n" );
3189 DBG_TRACE( DbgInfo, "Association Status : STA Reassociated\n" );
3193 DBG_TRACE( DbgInfo, "Association Status : STA Disassociated\n" );
3197 DBG_TRACE( DbgInfo, "Association Status : UNKNOWN (0x%04x)\n",
3202 DBG_TRACE(DbgInfo, "STA Address : %pM\n",
3205 if (( as->assocStatus == 2 ) && ( as->len == 8 )) {
3206 DBG_TRACE(DbgInfo, "Old AP Address : %pM\n",
3213 case CFG_SECURITY_STAT:
3214 DBG_TRACE( DbgInfo, "CFG_SECURITY_STAT\n" );
3217 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
3219 switch( ss->securityStatus ) {
3221 DBG_TRACE( DbgInfo, "Security Status : Dissassociate [AP]\n" );
3225 DBG_TRACE( DbgInfo, "Security Status : Deauthenticate [AP]\n" );
3229 DBG_TRACE( DbgInfo, "Security Status : Authenticate Fail [STA] or [AP]\n" );
3233 DBG_TRACE( DbgInfo, "Security Status : MIC Fail\n" );
3237 DBG_TRACE( DbgInfo, "Security Status : Associate Fail\n" );
3241 DBG_TRACE( DbgInfo, "Security Status : UNKNOWN %d\n",
3242 ss->securityStatus );
3246 DBG_TRACE(DbgInfo, "STA Address : %pM\n",
3249 DBG_TRACE(DbgInfo, "Reason : 0x%04x\n",
3256 DBG_TRACE( DbgInfo, "CFG_WMP, size is %d bytes\n", ltv->len );
3258 WMP_RSP_STRCT *wmp_rsp = (WMP_RSP_STRCT *)ltv;
3260 DBG_TRACE( DbgInfo, "CFG_WMP, pdu type is 0x%x\n",
3261 wmp_rsp->wmpRsp.wmpHdr.type );
3263 switch( wmp_rsp->wmpRsp.wmpHdr.type ) {
3264 case WVLAN_WMP_PDU_TYPE_LT_RSP:
3267 LINKTEST_RSP_STRCT *lt_rsp = (LINKTEST_RSP_STRCT *)ltv;
3269 DBG_TRACE( DbgInfo, "LINK TEST RESULT\n" );
3270 DBG_TRACE( DbgInfo, "================\n" );
3271 DBG_TRACE( DbgInfo, "Length : %d.\n", lt_rsp->len );
3273 DBG_TRACE( DbgInfo, "Name : %s.\n", lt_rsp->ltRsp.ltRsp.name );
3274 DBG_TRACE( DbgInfo, "Signal Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.signal );
3275 DBG_TRACE( DbgInfo, "Noise Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.noise );
3276 DBG_TRACE( DbgInfo, "Receive Flow : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.rxFlow );
3277 DBG_TRACE( DbgInfo, "Data Rate : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRate );
3278 DBG_TRACE( DbgInfo, "Protocol : 0x%04x.\n", lt_rsp->ltRsp.ltRsp.protocol );
3279 DBG_TRACE( DbgInfo, "Station : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.station );
3280 DBG_TRACE( DbgInfo, "Data Rate Cap : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRateCap );
3282 DBG_TRACE( DbgInfo, "Power Mgmt : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3283 lt_rsp->ltRsp.ltRsp.powerMgmt[0],
3284 lt_rsp->ltRsp.ltRsp.powerMgmt[1],
3285 lt_rsp->ltRsp.ltRsp.powerMgmt[2],
3286 lt_rsp->ltRsp.ltRsp.powerMgmt[3] );
3288 DBG_TRACE( DbgInfo, "Robustness : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3289 lt_rsp->ltRsp.ltRsp.robustness[0],
3290 lt_rsp->ltRsp.ltRsp.robustness[1],
3291 lt_rsp->ltRsp.ltRsp.robustness[2],
3292 lt_rsp->ltRsp.ltRsp.robustness[3] );
3294 DBG_TRACE( DbgInfo, "Scaling : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.scaling );
3307 DBG_TRACE( DbgInfo, "CFG_NULL\n" );
3310 case CFG_UPDATED_INFO_RECORD: // Updated Information Record
3311 DBG_TRACE( DbgInfo, "UPDATED INFORMATION RECORD\n" );
3313 ltv_val = CNV_INT_TO_LITTLE( ltv->u.u16[0] );
3315 /* Check and see which RID was updated */
3317 case CFG_CUR_COUNTRY_INFO: // Indicate Passive Scan Completion
3318 DBG_TRACE( DbgInfo, "Updated country info\n" );
3320 /* Do I need to hold off on updating RIDs until the process is
3325 case CFG_PORT_STAT: // Wait for Connect Event
3331 DBG_WARNING( DbgInfo, "Unknown RID: 0x%04x\n", ltv_val );
3337 DBG_TRACE( DbgInfo, "UNKNOWN MESSAGE: 0x%04x\n", ltv->typ );
3340 } // wl_process_mailbox
3341 /*============================================================================*/
3342 #endif /* ifndef USE_MBOX_SYNC */
3345 /*******************************************************************************
3346 * wl_wds_netdev_register()
3347 *******************************************************************************
3351 * This function registers net_device structures with the system's network
3352 * layer for use with the WDS ports.
3357 * lp - pointer to the device's private adapter structure
3363 ******************************************************************************/
3364 void wl_wds_netdev_register( struct wl_private *lp )
3368 //;?why is there no USE_WDS clause like in wl_enable_wds_ports
3369 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3370 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3371 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3372 if ( register_netdev( lp->wds_port[count].dev ) != 0 ) {
3373 DBG_WARNING( DbgInfo, "net device for WDS port %d could not be registered\n",
3376 lp->wds_port[count].is_registered = TRUE;
3378 /* Fill out the net_device structs with the MAC addr */
3379 memcpy( lp->wds_port[count].dev->dev_addr, lp->MACAddress, ETH_ALEN );
3380 lp->wds_port[count].dev->addr_len = ETH_ALEN;
3384 } // wl_wds_netdev_register
3385 /*============================================================================*/
3388 /*******************************************************************************
3389 * wl_wds_netdev_deregister()
3390 *******************************************************************************
3394 * This function deregisters the WDS net_device structures used by the
3395 * system's network layer.
3400 * lp - pointer to the device's private adapter structure
3406 ******************************************************************************/
3407 void wl_wds_netdev_deregister( struct wl_private *lp )
3411 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3412 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3413 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3414 unregister_netdev( lp->wds_port[count].dev );
3416 lp->wds_port[count].is_registered = FALSE;
3419 } // wl_wds_netdev_deregister
3420 /*============================================================================*/
3421 #endif /* USE_WDS */
3424 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
3426 * The proc filesystem: function to read and entry
3428 static void printf_hcf_16(struct seq_file *m, const char *s, hcf_16 *p, int n)
3432 seq_printf(m, "%-20.20s: ", s);
3435 for (i = 0; i < n; i++) {
3438 seq_printf(m, "%04X ", p[i]);
3443 static void printf_hcf_8(struct seq_file *m, const char *s, hcf_8 *p, int n)
3447 seq_printf(m, "%-20.20s: ", s);
3450 for (i = 0; i <= n; i++) {
3453 seq_printf(m, "%02X ", p[i]);
3458 static void printf_strct(struct seq_file *m, const char *s, hcf_16 *p)
3462 seq_printf(m, "%-20.20s: ", s);
3465 for ( i = 0; i <= *p; i++ ) {
3468 seq_printf(m,"%04X ", p[i]);
3473 int scull_read_procmem(struct seq_file *m, void *v)
3475 struct wl_private *lp = m->private;
3477 CFG_HERMES_TALLIES_STRCT *p;
3480 seq_puts(m, "No wl_private in scull_read_procmem\n" );
3481 } else if ( lp->wlags49_type == 0 ){
3483 seq_printf(m, "Magic: 0x%04X\n", ifbp->IFB_Magic );
3484 seq_printf(m, "IOBase: 0x%04X\n", ifbp->IFB_IOBase );
3485 seq_printf(m, "LinkStat: 0x%04X\n", ifbp->IFB_LinkStat );
3486 seq_printf(m, "DSLinkStat: 0x%04X\n", ifbp->IFB_DSLinkStat );
3487 seq_printf(m, "TickIni: 0x%08lX\n", ifbp->IFB_TickIni );
3488 seq_printf(m, "TickCnt: 0x%04X\n", ifbp->IFB_TickCnt );
3489 seq_printf(m, "IntOffCnt: 0x%04X\n", ifbp->IFB_IntOffCnt );
3490 printf_hcf_16(m, "IFB_FWIdentity",
3491 &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
3492 } else if ( lp->wlags49_type == 1 ) {
3493 seq_printf(m, "Channel: 0x%04X\n", lp->Channel );
3494 /****** seq_printf(m, "slock: %d\n", lp->slock ); */
3495 //x struct tq_struct "task: 0x%04X\n", lp->task );
3496 //x struct net_device_stats "stats: 0x%04X\n", lp->stats );
3498 //x struct iw_statistics "wstats: 0x%04X\n", lp->wstats );
3499 //x seq_printf(m, "spy_number: 0x%04X\n", lp->spy_number );
3500 //x u_char spy_address[IW_MAX_SPY][ETH_ALEN];
3501 //x struct iw_quality spy_stat[IW_MAX_SPY];
3502 #endif // WIRELESS_EXT
3503 seq_printf(m, "IFB: 0x%p\n", &lp->hcfCtx );
3504 seq_printf(m, "flags: %#.8lX\n", lp->flags ); //;?use this format from now on
3505 seq_printf(m, "DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
3507 seq_printf(m, "DebugFlag (DbgInfo): 0x%08lX\n", DbgInfo->DebugFlag );
3509 seq_printf(m, "is_registered: 0x%04X\n", lp->is_registered );
3510 //x CFG_DRV_INFO_STRCT "driverInfo: 0x%04X\n", lp->driverInfo );
3511 printf_strct( m, "driverInfo", (hcf_16*)&lp->driverInfo );
3512 //x CFG_IDENTITY_STRCT "driverIdentity: 0x%04X\n", lp->driverIdentity );
3513 printf_strct( m, "driverIdentity", (hcf_16*)&lp->driverIdentity );
3514 //x CFG_FW_IDENTITY_STRCT "StationIdentity: 0x%04X\n", lp->StationIdentity );
3515 printf_strct( m, "StationIdentity", (hcf_16*)&lp->StationIdentity );
3516 //x CFG_PRI_IDENTITY_STRCT "PrimaryIdentity: 0x%04X\n", lp->PrimaryIdentity );
3517 printf_strct( m, "PrimaryIdentity", (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
3518 printf_strct( m, "PrimarySupplier", (hcf_16*)&lp->hcfCtx.IFB_PRISup );
3519 //x CFG_PRI_IDENTITY_STRCT "NICIdentity: 0x%04X\n", lp->NICIdentity );
3520 printf_strct( m, "NICIdentity", (hcf_16*)&lp->NICIdentity );
3521 //x ltv_t "ltvRecord: 0x%04X\n", lp->ltvRecord );
3522 seq_printf(m, "txBytes: 0x%08lX\n", lp->txBytes );
3523 seq_printf(m, "maxPort: 0x%04X\n", lp->maxPort ); /* 0 for STA, 6 for AP */
3524 /* Elements used for async notification from hardware */
3525 //x RID_LOG_STRCT RidList[10];
3526 //x ltv_t "updatedRecord: 0x%04X\n", lp->updatedRecord );
3527 //x PROBE_RESP "ProbeResp: 0x%04X\n", lp->ProbeResp );
3528 //x ASSOC_STATUS_STRCT "assoc_stat: 0x%04X\n", lp->assoc_stat );
3529 //x SECURITY_STATUS_STRCT "sec_stat: 0x%04X\n", lp->sec_stat );
3530 //x u_char lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
3531 seq_printf(m, "PortType: 0x%04X\n", lp->PortType ); // 1 - 3 (1 [Normal] | 3 [AdHoc])
3532 seq_printf(m, "Channel: 0x%04X\n", lp->Channel ); // 0 - 14 (0)
3533 //x hcf_16 TxRateControl[2];
3534 seq_printf(m, "TxRateControl[2]: 0x%04X 0x%04X\n",
3535 lp->TxRateControl[0], lp->TxRateControl[1] );
3536 seq_printf(m, "DistanceBetweenAPs: 0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
3537 seq_printf(m, "RTSThreshold: 0x%04X\n", lp->RTSThreshold ); // 0 - 2347 (2347)
3538 seq_printf(m, "PMEnabled: 0x%04X\n", lp->PMEnabled ); // 0 - 2, 8001 - 8002 (0)
3539 seq_printf(m, "MicrowaveRobustness: 0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
3540 seq_printf(m, "CreateIBSS: 0x%04X\n", lp->CreateIBSS ); // 0 - 1 (0)
3541 seq_printf(m, "MulticastReceive: 0x%04X\n", lp->MulticastReceive ); // 0 - 1 (1)
3542 seq_printf(m, "MaxSleepDuration: 0x%04X\n", lp->MaxSleepDuration ); // 0 - 65535 (100)
3543 //x hcf_8 MACAddress[ETH_ALEN];
3544 printf_hcf_8(m, "MACAddress", lp->MACAddress, ETH_ALEN );
3545 //x char NetworkName[HCF_MAX_NAME_LEN+1];
3546 seq_printf(m, "NetworkName: %.32s\n", lp->NetworkName );
3547 //x char StationName[HCF_MAX_NAME_LEN+1];
3548 seq_printf(m, "EnableEncryption: 0x%04X\n", lp->EnableEncryption ); // 0 - 1 (0)
3549 //x char Key1[MAX_KEY_LEN+1];
3550 printf_hcf_8( m, "Key1", lp->Key1, MAX_KEY_LEN );
3551 //x char Key2[MAX_KEY_LEN+1];
3552 //x char Key3[MAX_KEY_LEN+1];
3553 //x char Key4[MAX_KEY_LEN+1];
3554 seq_printf(m, "TransmitKeyID: 0x%04X\n", lp->TransmitKeyID ); // 1 - 4 (1)
3555 //x CFG_DEFAULT_KEYS_STRCT "DefaultKeys: 0x%04X\n", lp->DefaultKeys );
3556 //x u_char mailbox[MB_SIZE];
3557 //x char szEncryption[MAX_ENC_LEN];
3558 seq_printf(m, "driverEnable: 0x%04X\n", lp->driverEnable );
3559 seq_printf(m, "wolasEnable: 0x%04X\n", lp->wolasEnable );
3560 seq_printf(m, "atimWindow: 0x%04X\n", lp->atimWindow );
3561 seq_printf(m, "holdoverDuration: 0x%04X\n", lp->holdoverDuration );
3562 //x hcf_16 MulticastRate[2];
3563 seq_printf(m, "authentication: 0x%04X\n", lp->authentication ); // is this AP specific?
3564 seq_printf(m, "promiscuousMode: 0x%04X\n", lp->promiscuousMode );
3565 seq_printf(m, "DownloadFirmware: 0x%04X\n", lp->DownloadFirmware ); // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
3566 seq_printf(m, "AuthKeyMgmtSuite: 0x%04X\n", lp->AuthKeyMgmtSuite );
3567 seq_printf(m, "loadBalancing: 0x%04X\n", lp->loadBalancing );
3568 seq_printf(m, "mediumDistribution: 0x%04X\n", lp->mediumDistribution );
3569 seq_printf(m, "txPowLevel: 0x%04X\n", lp->txPowLevel );
3570 // seq_printf(m, "shortRetryLimit: 0x%04X\n", lp->shortRetryLimit );
3571 // seq_printf(m, "longRetryLimit: 0x%04X\n", lp->longRetryLimit );
3574 seq_printf(m, "connectionControl: 0x%04X\n", lp->connectionControl );
3575 //x //hcf_16 probeDataRates[2];
3576 seq_printf(m, "ownBeaconInterval: 0x%04X\n", lp->ownBeaconInterval );
3577 seq_printf(m, "coexistence: 0x%04X\n", lp->coexistence );
3578 //x WVLAN_FRAME "txF: 0x%04X\n", lp->txF );
3579 //x WVLAN_LFRAME txList[DEFAULT_NUM_TX_FRAMES];
3580 //x struct list_head "txFree: 0x%04X\n", lp->txFree );
3581 //x struct list_head txQ[WVLAN_MAX_TX_QUEUES];
3582 seq_printf(m, "netif_queue_on: 0x%04X\n", lp->netif_queue_on );
3583 seq_printf(m, "txQ_count: 0x%04X\n", lp->txQ_count );
3584 //x DESC_STRCT "desc_rx: 0x%04X\n", lp->desc_rx );
3585 //x DESC_STRCT "desc_tx: 0x%04X\n", lp->desc_tx );
3586 //x WVLAN_PORT_STATE "portState: 0x%04X\n", lp->portState );
3587 //x ScanResult "scan_results: 0x%04X\n", lp->scan_results );
3588 //x ProbeResult "probe_results: 0x%04X\n", lp->probe_results );
3589 seq_printf(m, "probe_num_aps: 0x%04X\n", lp->probe_num_aps );
3590 seq_printf(m, "use_dma: 0x%04X\n", lp->use_dma );
3591 //x DMA_STRCT "dma: 0x%04X\n", lp->dma );
3593 seq_printf(m, "useRTS: 0x%04X\n", lp->useRTS );
3595 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
3596 //;?should we restore this to allow smaller memory footprint
3597 //;?I guess not. This should be brought under Debug mode only
3598 seq_printf(m, "DTIMPeriod: 0x%04X\n", lp->DTIMPeriod ); // 1 - 255 (1)
3599 seq_printf(m, "multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
3600 seq_printf(m, "RejectAny: 0x%04X\n", lp->RejectAny ); // 0 - 1 (0)
3601 seq_printf(m, "ExcludeUnencrypted: 0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
3602 seq_printf(m, "intraBSSRelay: 0x%04X\n", lp->intraBSSRelay );
3603 seq_printf(m, "wlags49_type: 0x%08lX\n", lp->wlags49_type );
3605 //x WVLAN_WDS_IF wds_port[NUM_WDS_PORTS];
3608 } else if ( lp->wlags49_type == 2 ){
3609 seq_printf(m, "tallies to be added\n" );
3610 //Hermes Tallies (IFB substructure) {
3611 p = &lp->hcfCtx.IFB_NIC_Tallies;
3612 seq_printf(m, "TxUnicastFrames: %08lX\n", p->TxUnicastFrames );
3613 seq_printf(m, "TxMulticastFrames: %08lX\n", p->TxMulticastFrames );
3614 seq_printf(m, "TxFragments: %08lX\n", p->TxFragments );
3615 seq_printf(m, "TxUnicastOctets: %08lX\n", p->TxUnicastOctets );
3616 seq_printf(m, "TxMulticastOctets: %08lX\n", p->TxMulticastOctets );
3617 seq_printf(m, "TxDeferredTransmissions: %08lX\n", p->TxDeferredTransmissions );
3618 seq_printf(m, "TxSingleRetryFrames: %08lX\n", p->TxSingleRetryFrames );
3619 seq_printf(m, "TxMultipleRetryFrames: %08lX\n", p->TxMultipleRetryFrames );
3620 seq_printf(m, "TxRetryLimitExceeded: %08lX\n", p->TxRetryLimitExceeded );
3621 seq_printf(m, "TxDiscards: %08lX\n", p->TxDiscards );
3622 seq_printf(m, "RxUnicastFrames: %08lX\n", p->RxUnicastFrames );
3623 seq_printf(m, "RxMulticastFrames: %08lX\n", p->RxMulticastFrames );
3624 seq_printf(m, "RxFragments: %08lX\n", p->RxFragments );
3625 seq_printf(m, "RxUnicastOctets: %08lX\n", p->RxUnicastOctets );
3626 seq_printf(m, "RxMulticastOctets: %08lX\n", p->RxMulticastOctets );
3627 seq_printf(m, "RxFCSErrors: %08lX\n", p->RxFCSErrors );
3628 seq_printf(m, "RxDiscardsNoBuffer: %08lX\n", p->RxDiscardsNoBuffer );
3629 seq_printf(m, "TxDiscardsWrongSA: %08lX\n", p->TxDiscardsWrongSA );
3630 seq_printf(m, "RxWEPUndecryptable: %08lX\n", p->RxWEPUndecryptable );
3631 seq_printf(m, "RxMsgInMsgFragments: %08lX\n", p->RxMsgInMsgFragments );
3632 seq_printf(m, "RxMsgInBadMsgFragments: %08lX\n", p->RxMsgInBadMsgFragments );
3633 seq_printf(m, "RxDiscardsWEPICVError: %08lX\n", p->RxDiscardsWEPICVError );
3634 seq_printf(m, "RxDiscardsWEPExcluded: %08lX\n", p->RxDiscardsWEPExcluded );
3635 #if (HCF_EXT) & HCF_EXT_TALLIES_FW
3637 #endif // HCF_EXT_TALLIES_FW
3638 } else if ( lp->wlags49_type & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3640 DbgInfo->DebugFlag = lp->wlags49_type & 0x7FFF;
3642 lp->wlags49_type = 0; //default to IFB again ;?
3644 seq_printf(m, "unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
3647 "0x0001 - wl_private\n"
3648 "0x0002 - Tallies\n"
3649 "0x8xxx - Change debufflag\n"
3650 "ERROR 0001\nWARNING 0002\nNOTICE 0004\nTRACE 0008\n"
3651 "VERBOSE 0010\nPARAM 0020\nBREAK 0040\nRX 0100\n"
3652 "TX 0200\nDS 0400\n");
3655 } // scull_read_procmem
3657 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
3659 static char proc_number[11];
3660 unsigned int nr = 0;
3664 } else if ( copy_from_user(proc_number, buffer, count) ) {
3668 proc_number[count] = 0;
3669 nr = simple_strtoul(proc_number , NULL, 0);
3670 *(unsigned int *)data = nr;
3671 if ( nr & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3673 DbgInfo->DebugFlag = nr & 0x7FFF;
3677 DBG_PRINT( "value: %08X\n", nr );
3681 #endif /* SCULL_USE_PROC */
3684 #define RUN_AT(x) (jiffies+(x)) //"borrowed" from include/pcmcia/k_compat.h
3685 #define DS_OOR 0x8000 //Deepsleep OutOfRange Status
3687 lp->timer_oor_cnt = DS_OOR;
3688 init_timer( &lp->timer_oor );
3689 lp->timer_oor.function = timer_oor;
3690 lp->timer_oor.data = (unsigned long)lp;
3691 lp->timer_oor.expires = RUN_AT( 3 * HZ );
3692 add_timer( &lp->timer_oor );
3693 printk(KERN_NOTICE "wl_enable: %ld\n", jiffies ); //;?remove me 1 day
3696 /*******************************************************************************
3698 *******************************************************************************
3705 * arg - a u_long representing a pointer to a dev_link_t structure for the
3706 * device to be released.
3712 ******************************************************************************/
3713 void timer_oor( u_long arg )
3715 struct wl_private *lp = (struct wl_private *)arg;
3717 DBG_PARAM( DbgInfo, "arg", "0x%08lx", arg );
3719 printk(KERN_NOTICE "timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt ); //;?remove me 1 day
3720 lp->timer_oor_cnt += 10;
3721 if ( (lp->timer_oor_cnt & ~DS_OOR) > 300 ) {
3722 lp->timer_oor_cnt = 300;
3724 lp->timer_oor_cnt |= DS_OOR;
3725 init_timer( &lp->timer_oor );
3726 lp->timer_oor.function = timer_oor;
3727 lp->timer_oor.data = (unsigned long)lp;
3728 lp->timer_oor.expires = RUN_AT( (lp->timer_oor_cnt & ~DS_OOR) * HZ );
3729 add_timer( &lp->timer_oor );
3733 MODULE_LICENSE("Dual BSD/GPL");