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/types.h>
77 #include <linux/kernel.h>
78 // #include <linux/sched.h>
79 // #include <linux/ptrace.h>
80 // #include <linux/slab.h>
81 // #include <linux/ctype.h>
82 // #include <linux/string.h>
83 // #include <linux/timer.h>
84 //#include <linux/interrupt.h>
85 // #include <linux/tqueue.h>
86 // #include <linux/in.h>
87 // #include <linux/delay.h>
88 // #include <asm/io.h>
89 // // #include <asm/bitops.h>
90 #include <linux/unistd.h>
91 #include <asm/uaccess.h>
93 #include <linux/netdevice.h>
94 #include <linux/etherdevice.h>
95 // #include <linux/skbuff.h>
96 // #include <linux/if_arp.h>
97 // #include <linux/ioport.h>
101 #include <linux/vmalloc.h>
109 //in order to get around:: wl_main.c:2229: `HREG_EV_RDMAD' undeclared (first use in this function)
113 #include <wl_internal.h>
116 #include <wl_netdev.h>
120 #include <wl_profile.h>
121 #endif /* USE_PROFILE */
125 #endif /* BUS_PCMCIA */
130 /*******************************************************************************
132 ******************************************************************************/
133 #define VALID_PARAM(C) \
137 printk(KERN_INFO "Wireless, parameter error: \"%s\"\n", #C); \
141 /*******************************************************************************
143 ******************************************************************************/
144 void wl_isr_handler( unsigned long p );
146 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
147 //int scull_read_procmem(char *buf, char **start, off_t offset, int len, int unused);
148 int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data );
149 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data);
150 static void proc_write(const char *name, write_proc_t *w, void *data);
152 #endif /* SCULL_USE_PROC */
154 /*******************************************************************************
155 * module parameter definitions - set with 'insmod'
156 ******************************************************************************/
157 static p_u16 irq_mask = 0xdeb8; // IRQ3,4,5,7,9,10,11,12,14,15
158 static p_s8 irq_list[4] = { -1 };
161 MODULE_PARM(irq_mask, "h");
162 MODULE_PARM_DESC(irq_mask, "IRQ mask [0xdeb8]");
163 MODULE_PARM(irq_list, "1-4b");
164 MODULE_PARM_DESC(irq_list, "IRQ list [<irq_mask>]");
167 static p_u8 PARM_AUTHENTICATION = PARM_DEFAULT_AUTHENTICATION;
168 static p_u16 PARM_AUTH_KEY_MGMT_SUITE = PARM_DEFAULT_AUTH_KEY_MGMT_SUITE;
169 static p_u16 PARM_BRSC_2GHZ = PARM_DEFAULT_BRSC_2GHZ;
170 static p_u16 PARM_BRSC_5GHZ = PARM_DEFAULT_BRSC_5GHZ;
171 static p_u16 PARM_COEXISTENCE = PARM_DEFAULT_COEXISTENCE;
172 static p_u16 PARM_CONNECTION_CONTROL = PARM_DEFAULT_CONNECTION_CONTROL; //;?rename and move
173 static p_char *PARM_CREATE_IBSS = PARM_DEFAULT_CREATE_IBSS_STR;
174 static p_char *PARM_DESIRED_SSID = PARM_DEFAULT_SSID;
175 static p_char *PARM_DOWNLOAD_FIRMWARE = "";
176 static p_u16 PARM_ENABLE_ENCRYPTION = PARM_DEFAULT_ENABLE_ENCRYPTION;
177 static p_char *PARM_EXCLUDE_UNENCRYPTED = PARM_DEFAULT_EXCLUDE_UNENCRYPTED_STR;
178 static p_char *PARM_INTRA_BSS_RELAY = PARM_DEFAULT_INTRA_BSS_RELAY_STR;
179 static p_char *PARM_KEY1 = "";
180 static p_char *PARM_KEY2 = "";
181 static p_char *PARM_KEY3 = "";
182 static p_char *PARM_KEY4 = "";
183 static p_char *PARM_LOAD_BALANCING = PARM_DEFAULT_LOAD_BALANCING_STR;
184 static p_u16 PARM_MAX_SLEEP = PARM_DEFAULT_MAX_PM_SLEEP;
185 static p_char *PARM_MEDIUM_DISTRIBUTION = PARM_DEFAULT_MEDIUM_DISTRIBUTION_STR;
186 static p_char *PARM_MICROWAVE_ROBUSTNESS = PARM_DEFAULT_MICROWAVE_ROBUSTNESS_STR;
187 static p_char *PARM_MULTICAST_PM_BUFFERING = PARM_DEFAULT_MULTICAST_PM_BUFFERING_STR;
188 static p_u16 PARM_MULTICAST_RATE = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
189 static p_char *PARM_MULTICAST_RX = PARM_DEFAULT_MULTICAST_RX_STR;
190 static p_u8 PARM_NETWORK_ADDR[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
191 static p_u16 PARM_OWN_ATIM_WINDOW = PARM_DEFAULT_OWN_ATIM_WINDOW;
192 static p_u16 PARM_OWN_BEACON_INTERVAL = PARM_DEFAULT_OWN_BEACON_INTERVAL;
193 static p_u8 PARM_OWN_CHANNEL = PARM_DEFAULT_OWN_CHANNEL;
194 static p_u8 PARM_OWN_DTIM_PERIOD = PARM_DEFAULT_OWN_DTIM_PERIOD;
195 static p_char *PARM_OWN_NAME = PARM_DEFAULT_OWN_NAME;
196 static p_char *PARM_OWN_SSID = PARM_DEFAULT_SSID;
197 static p_u16 PARM_PM_ENABLED = WVLAN_PM_STATE_DISABLED;
198 static p_u16 PARM_PM_HOLDOVER_DURATION = PARM_DEFAULT_PM_HOLDOVER_DURATION;
199 static p_u8 PARM_PORT_TYPE = PARM_DEFAULT_PORT_TYPE;
200 static p_char *PARM_PROMISCUOUS_MODE = PARM_DEFAULT_PROMISCUOUS_MODE_STR;
201 static p_char *PARM_REJECT_ANY = PARM_DEFAULT_REJECT_ANY_STR;
203 static p_u16 PARM_RTS_THRESHOLD1 = PARM_DEFAULT_RTS_THRESHOLD;
204 static p_u16 PARM_RTS_THRESHOLD2 = PARM_DEFAULT_RTS_THRESHOLD;
205 static p_u16 PARM_RTS_THRESHOLD3 = PARM_DEFAULT_RTS_THRESHOLD;
206 static p_u16 PARM_RTS_THRESHOLD4 = PARM_DEFAULT_RTS_THRESHOLD;
207 static p_u16 PARM_RTS_THRESHOLD5 = PARM_DEFAULT_RTS_THRESHOLD;
208 static p_u16 PARM_RTS_THRESHOLD6 = PARM_DEFAULT_RTS_THRESHOLD;
210 static p_u16 PARM_RTS_THRESHOLD = PARM_DEFAULT_RTS_THRESHOLD;
211 static p_u16 PARM_SRSC_2GHZ = PARM_DEFAULT_SRSC_2GHZ;
212 static p_u16 PARM_SRSC_5GHZ = PARM_DEFAULT_SRSC_5GHZ;
213 static p_u8 PARM_SYSTEM_SCALE = PARM_DEFAULT_SYSTEM_SCALE;
214 static p_u8 PARM_TX_KEY = PARM_DEFAULT_TX_KEY;
215 static p_u16 PARM_TX_POW_LEVEL = PARM_DEFAULT_TX_POW_LEVEL;
217 static p_u16 PARM_TX_RATE1 = PARM_DEFAULT_TX_RATE_2GHZ;
218 static p_u16 PARM_TX_RATE2 = PARM_DEFAULT_TX_RATE_2GHZ;
219 static p_u16 PARM_TX_RATE3 = PARM_DEFAULT_TX_RATE_2GHZ;
220 static p_u16 PARM_TX_RATE4 = PARM_DEFAULT_TX_RATE_2GHZ;
221 static p_u16 PARM_TX_RATE5 = PARM_DEFAULT_TX_RATE_2GHZ;
222 static p_u16 PARM_TX_RATE6 = PARM_DEFAULT_TX_RATE_2GHZ;
224 static p_u16 PARM_TX_RATE = PARM_DEFAULT_TX_RATE_2GHZ;
226 static p_u8 PARM_WDS_ADDRESS1[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
227 static p_u8 PARM_WDS_ADDRESS2[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
228 static p_u8 PARM_WDS_ADDRESS3[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
229 static p_u8 PARM_WDS_ADDRESS4[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
230 static p_u8 PARM_WDS_ADDRESS5[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
231 static p_u8 PARM_WDS_ADDRESS6[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
236 MODULE_PARM(PARM_DESIRED_SSID, "s");
237 MODULE_PARM_DESC(PARM_DESIRED_SSID, "Network Name (<string>) [ANY]");
238 MODULE_PARM(PARM_OWN_SSID, "s");
239 MODULE_PARM_DESC(PARM_OWN_SSID, "Network Name (<string>) [ANY]");
240 MODULE_PARM(PARM_OWN_CHANNEL, "b");
241 MODULE_PARM_DESC(PARM_OWN_CHANNEL, "Channel (0 - 14) [0]");
242 MODULE_PARM(PARM_SYSTEM_SCALE, "b");
243 MODULE_PARM_DESC(PARM_SYSTEM_SCALE, "Distance Between APs (1 - 3) [1]");
244 MODULE_PARM(PARM_TX_RATE, "b");
245 MODULE_PARM_DESC(PARM_TX_RATE, "Transmit Rate Control");
246 MODULE_PARM(PARM_RTS_THRESHOLD, "h");
247 MODULE_PARM_DESC(PARM_RTS_THRESHOLD, "Medium Reservation (RTS/CTS Fragment Length) (256 - 2347) [2347]");
248 MODULE_PARM(PARM_MICROWAVE_ROBUSTNESS, "s");
249 MODULE_PARM_DESC(PARM_MICROWAVE_ROBUSTNESS, "Microwave Oven Robustness Enabled (<string> N or Y) [N]");
250 MODULE_PARM(PARM_OWN_NAME, "s");
251 MODULE_PARM_DESC(PARM_OWN_NAME, "Station Name (<string>) [Linux]");
253 MODULE_PARM(PARM_ENABLE_ENCRYPTION, "b");
254 MODULE_PARM_DESC(PARM_ENABLE_ENCRYPTION, "Encryption Mode (0 - 7) [0]");
256 MODULE_PARM(PARM_KEY1, "s");
257 MODULE_PARM_DESC(PARM_KEY1, "Data Encryption Key 1 (<string>) []");
258 MODULE_PARM(PARM_KEY2, "s");
259 MODULE_PARM_DESC(PARM_KEY2, "Data Encryption Key 2 (<string>) []");
260 MODULE_PARM(PARM_KEY3, "s");
261 MODULE_PARM_DESC(PARM_KEY3, "Data Encryption Key 3 (<string>) []");
262 MODULE_PARM(PARM_KEY4, "s");
263 MODULE_PARM_DESC(PARM_KEY4, "Data Encryption Key 4 (<string>) []");
264 MODULE_PARM(PARM_TX_KEY, "b");
265 MODULE_PARM_DESC(PARM_TX_KEY, "Transmit Key ID (1 - 4) [1]");
266 MODULE_PARM(PARM_MULTICAST_RATE, "b");
267 MODULE_PARM_DESC(PARM_MULTICAST_RATE, "Multicast Rate");
268 MODULE_PARM(PARM_DOWNLOAD_FIRMWARE, "s");
269 MODULE_PARM_DESC(PARM_DOWNLOAD_FIRMWARE, "filename of firmware image");
271 MODULE_PARM(PARM_AUTH_KEY_MGMT_SUITE, "b");
272 MODULE_PARM_DESC(PARM_AUTH_KEY_MGMT_SUITE, "Authentication Key Management suite (0-4) [0]");
274 MODULE_PARM(PARM_LOAD_BALANCING, "s");
275 MODULE_PARM_DESC(PARM_LOAD_BALANCING, "Load Balancing Enabled (<string> N or Y) [Y]");
276 MODULE_PARM(PARM_MEDIUM_DISTRIBUTION, "s");
277 MODULE_PARM_DESC(PARM_MEDIUM_DISTRIBUTION, "Medium Distribution Enabled (<string> N or Y) [Y]");
278 MODULE_PARM(PARM_TX_POW_LEVEL, "b");
279 MODULE_PARM_DESC(PARM_TX_POW_LEVEL, "Transmit Power (0 - 6) [3]");
280 MODULE_PARM(PARM_SRSC_2GHZ, "b");
281 MODULE_PARM_DESC(PARM_SRSC_2GHZ, "Supported Rate Set Control 2.4 GHz");
282 MODULE_PARM(PARM_SRSC_5GHZ, "b");
283 MODULE_PARM_DESC(PARM_SRSC_5GHZ, "Supported Rate Set Control 5.0 GHz");
284 MODULE_PARM(PARM_BRSC_2GHZ, "b");
285 MODULE_PARM_DESC(PARM_BRSC_2GHZ, "Basic Rate Set Control 2.4 GHz");
286 MODULE_PARM(PARM_BRSC_5GHZ, "b");
287 MODULE_PARM_DESC(PARM_BRSC_5GHZ, "Basic Rate Set Control 5.0 GHz");
288 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
289 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
290 MODULE_PARM(PARM_PM_ENABLED, "h");
291 MODULE_PARM_DESC(PARM_PM_ENABLED, "Power Management State (0 - 2, 8001 - 8002) [0]");
292 MODULE_PARM(PARM_PORT_TYPE, "b");
293 MODULE_PARM_DESC(PARM_PORT_TYPE, "Port Type (1 - 3) [1]");
294 //;?MODULE_PARM(PARM_CREATE_IBSS, "s");
295 //;?MODULE_PARM_DESC(PARM_CREATE_IBSS, "Create IBSS (<string> N or Y) [N]");
296 //;?MODULE_PARM(PARM_MULTICAST_RX, "s");
297 //;?MODULE_PARM_DESC(PARM_MULTICAST_RX, "Multicast Receive Enable (<string> N or Y) [Y]");
298 //;?MODULE_PARM(PARM_MAX_SLEEP, "h");
299 //;?MODULE_PARM_DESC(PARM_MAX_SLEEP, "Maximum Power Management Sleep Duration (0 - 65535) [100]");
300 //;?MODULE_PARM(PARM_NETWORK_ADDR, "6b");
301 //;?MODULE_PARM_DESC(PARM_NETWORK_ADDR, "Hardware Ethernet Address ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [<factory value>]");
302 //;?MODULE_PARM(PARM_AUTHENTICATION, "b");
305 //;?MODULE_PARM_DESC(PARM_AUTHENTICATION, "Authentication Type (0-2) [0] 0=Open 1=SharedKey 2=LEAP");
306 //;?MODULE_PARM_DESC(authentication, "Authentication Type (1-2) [1] 1=Open 2=SharedKey");
309 //;?MODULE_PARM(PARM_OWN_ATIM_WINDOW, "b");
310 //;?MODULE_PARM_DESC(PARM_OWN_ATIM_WINDOW, "ATIM Window time in TU for IBSS creation (0-100) [0]");
311 //;?MODULE_PARM(PARM_PM_HOLDOVER_DURATION, "b");
312 //;?MODULE_PARM_DESC(PARM_PM_HOLDOVER_DURATION, "Time station remains awake after MAC frame transfer when PM is on (0-65535) [100]");
313 //;?MODULE_PARM(PARM_PROMISCUOUS_MODE, "s");
314 //;?MODULE_PARM_DESC(PARM_PROMISCUOUS_MODE, "Promiscuous Mode Enable (<string> Y or N ) [N]" );
316 MODULE_PARM(PARM_CONNECTION_CONTROL, "b");
317 MODULE_PARM_DESC(PARM_CONNECTION_CONTROL, "Connection Control (0 - 3) [2]");
319 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
320 //;?should we restore this to allow smaller memory footprint
321 MODULE_PARM(PARM_OWN_DTIM_PERIOD, "b");
322 MODULE_PARM_DESC(PARM_OWN_DTIM_PERIOD, "DTIM Period (0 - 255) [1]");
323 MODULE_PARM(PARM_REJECT_ANY, "s");
324 MODULE_PARM_DESC(PARM_REJECT_ANY, "Closed System (<string> N or Y) [N]");
325 MODULE_PARM(PARM_EXCLUDE_UNENCRYPTED, "s");
326 MODULE_PARM_DESC(PARM_EXCLUDE_UNENCRYPTED, "Deny non-encrypted (<string> N or Y) [Y]");
327 MODULE_PARM(PARM_MULTICAST_PM_BUFFERING,"s");
328 MODULE_PARM_DESC(PARM_MULTICAST_PM_BUFFERING, "Buffer MAC frames for Tx after DTIM (<string> Y or N) [Y]");
329 MODULE_PARM(PARM_INTRA_BSS_RELAY, "s");
330 MODULE_PARM_DESC(PARM_INTRA_BSS_RELAY, "IntraBSS Relay (<string> N or Y) [Y]");
331 MODULE_PARM(PARM_RTS_THRESHOLD1, "h");
332 MODULE_PARM_DESC(PARM_RTS_THRESHOLD1, "RTS Threshold, WDS Port 1 (256 - 2347) [2347]");
333 MODULE_PARM(PARM_RTS_THRESHOLD2, "h");
334 MODULE_PARM_DESC(PARM_RTS_THRESHOLD2, "RTS Threshold, WDS Port 2 (256 - 2347) [2347]");
335 MODULE_PARM(PARM_RTS_THRESHOLD3, "h");
336 MODULE_PARM_DESC(PARM_RTS_THRESHOLD3, "RTS Threshold, WDS Port 3 (256 - 2347) [2347]");
337 MODULE_PARM(PARM_RTS_THRESHOLD4, "h");
338 MODULE_PARM_DESC(PARM_RTS_THRESHOLD4, "RTS Threshold, WDS Port 4 (256 - 2347) [2347]");
339 MODULE_PARM(PARM_RTS_THRESHOLD5, "h");
340 MODULE_PARM_DESC(PARM_RTS_THRESHOLD5, "RTS Threshold, WDS Port 5 (256 - 2347) [2347]");
341 MODULE_PARM(PARM_RTS_THRESHOLD6, "h");
342 MODULE_PARM_DESC(PARM_RTS_THRESHOLD6, "RTS Threshold, WDS Port 6 (256 - 2347) [2347]");
343 MODULE_PARM(PARM_TX_RATE1, "b");
344 MODULE_PARM_DESC(PARM_TX_RATE1, "Transmit Rate Control, WDS Port 1 (1 - 7) [3]");
345 MODULE_PARM(PARM_TX_RATE2, "b");
346 MODULE_PARM_DESC(PARM_TX_RATE2, "Transmit Rate Control, WDS Port 2 (1 - 7) [3]");
347 MODULE_PARM(PARM_TX_RATE3, "b");
348 MODULE_PARM_DESC(PARM_TX_RATE3, "Transmit Rate Control, WDS Port 3 (1 - 7) [3]");
349 MODULE_PARM(PARM_TX_RATE4, "b");
350 MODULE_PARM_DESC(PARM_TX_RATE4, "Transmit Rate Control, WDS Port 4 (1 - 7) [3]");
351 MODULE_PARM(PARM_TX_RATE5, "b");
352 MODULE_PARM_DESC(PARM_TX_RATE5, "Transmit Rate Control, WDS Port 5 (1 - 7) [3]");
353 MODULE_PARM(PARM_TX_RATE6, "b");
354 MODULE_PARM_DESC(PARM_TX_RATE6, "Transmit Rate Control, WDS Port 6 (1 - 7) [3]");
355 MODULE_PARM(PARM_WDS_ADDRESS1, "6b");
356 MODULE_PARM_DESC(PARM_WDS_ADDRESS1, "MAC Address, WDS Port 1 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
357 MODULE_PARM(PARM_WDS_ADDRESS2, "6b");
358 MODULE_PARM_DESC(PARM_WDS_ADDRESS2, "MAC Address, WDS Port 2 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
359 MODULE_PARM(PARM_WDS_ADDRESS3, "6b");
360 MODULE_PARM_DESC(PARM_WDS_ADDRESS3, "MAC Address, WDS Port 3 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
361 MODULE_PARM(PARM_WDS_ADDRESS4, "6b");
362 MODULE_PARM_DESC(PARM_WDS_ADDRESS4, "MAC Address, WDS Port 4 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
363 MODULE_PARM(PARM_WDS_ADDRESS5, "6b");
364 MODULE_PARM_DESC(PARM_WDS_ADDRESS5, "MAC Address, WDS Port 5 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
365 MODULE_PARM(PARM_WDS_ADDRESS6, "6b");
366 MODULE_PARM_DESC(PARM_WDS_ADDRESS6, "MAC Address, WDS Port 6 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
368 MODULE_PARM(PARM_OWN_BEACON_INTERVAL, "b");
369 MODULE_PARM_DESC(PARM_OWN_BEACON_INTERVAL, "Own Beacon Interval (20 - 200) [100]");
370 MODULE_PARM(PARM_COEXISTENCE, "b");
371 MODULE_PARM_DESC(PARM_COEXISTENCE, "Coexistence (0-7) [0]");
376 /* END NEW PARAMETERS */
377 /*******************************************************************************
378 * debugging specifics
379 ******************************************************************************/
382 static p_u32 pc_debug = DBG_LVL;
383 //MODULE_PARM(pc_debug, "i");
384 /*static ;?conflicts with my understanding of CL parameters and breaks now I moved
385 * the correspondig logic to wl_profile
386 */ p_u32 DebugFlag = ~0; //recognizable "undefined value" rather then DBG_DEFAULTS;
387 //MODULE_PARM(DebugFlag, "l");
389 dbg_info_t wl_info = { DBG_MOD_NAME, 0, 0 };
390 dbg_info_t *DbgInfo = &wl_info;
395 static p_char *useRTS = "N";
396 MODULE_PARM( useRTS, "s" );
397 MODULE_PARM_DESC( useRTS, "Use RTS test interface (<string> N or Y) [N]" );
400 /*******************************************************************************
401 * firmware download specifics
402 ******************************************************************************/
403 extern struct CFG_RANGE2_STRCT BASED
404 cfg_drv_act_ranges_pri; // describes primary-actor range of HCF
406 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
407 extern memimage ap; // AP firmware image to be downloaded
410 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
411 //extern memimage station; // STA firmware image to be downloaded
412 extern memimage fw_image; // firmware image to be downloaded
416 int wl_insert( struct net_device *dev )
419 int hcf_status = HCF_SUCCESS;
421 unsigned long flags = 0;
422 struct wl_private *lp = wl_priv(dev);
423 /*------------------------------------------------------------------------*/
424 DBG_FUNC( "wl_insert" );
425 DBG_ENTER( DbgInfo );
427 /* Initialize the adapter hardware. */
428 memset( &( lp->hcfCtx ), 0, sizeof( IFB_STRCT ));
430 /* Initialize the adapter parameters. */
431 spin_lock_init( &( lp->slock ));
433 /* Initialize states */
434 //lp->lockcount = 0; //PE1DNN
435 lp->is_handling_int = WL_NOT_HANDLING_INT;
436 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
440 DBG_PARAM( DbgInfo, "irq_mask", "0x%04x", irq_mask & 0x0FFFF );
441 DBG_PARAM( DbgInfo, "irq_list", "0x%02x 0x%02x 0x%02x 0x%02x",
442 irq_list[0] & 0x0FF, irq_list[1] & 0x0FF,
443 irq_list[2] & 0x0FF, irq_list[3] & 0x0FF );
444 DBG_PARAM( DbgInfo, PARM_NAME_DESIRED_SSID, "\"%s\"", PARM_DESIRED_SSID );
445 DBG_PARAM( DbgInfo, PARM_NAME_OWN_SSID, "\"%s\"", PARM_OWN_SSID );
446 DBG_PARAM( DbgInfo, PARM_NAME_OWN_CHANNEL, "%d", PARM_OWN_CHANNEL);
447 DBG_PARAM( DbgInfo, PARM_NAME_SYSTEM_SCALE, "%d", PARM_SYSTEM_SCALE );
448 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE, "%d", PARM_TX_RATE );
449 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD, "%d", PARM_RTS_THRESHOLD );
450 DBG_PARAM( DbgInfo, PARM_NAME_MICROWAVE_ROBUSTNESS, "\"%s\"", PARM_MICROWAVE_ROBUSTNESS );
451 DBG_PARAM( DbgInfo, PARM_NAME_OWN_NAME, "\"%s\"", PARM_OWN_NAME );
452 //;? DBG_PARAM( DbgInfo, PARM_NAME_ENABLE_ENCRYPTION, "\"%s\"", PARM_ENABLE_ENCRYPTION );
453 DBG_PARAM( DbgInfo, PARM_NAME_KEY1, "\"%s\"", PARM_KEY1 );
454 DBG_PARAM( DbgInfo, PARM_NAME_KEY2, "\"%s\"", PARM_KEY2 );
455 DBG_PARAM( DbgInfo, PARM_NAME_KEY3, "\"%s\"", PARM_KEY3 );
456 DBG_PARAM( DbgInfo, PARM_NAME_KEY4, "\"%s\"", PARM_KEY4 );
457 DBG_PARAM( DbgInfo, PARM_NAME_TX_KEY, "%d", PARM_TX_KEY );
458 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RATE, "%d", PARM_MULTICAST_RATE );
459 DBG_PARAM( DbgInfo, PARM_NAME_DOWNLOAD_FIRMWARE, "\"%s\"", PARM_DOWNLOAD_FIRMWARE );
460 DBG_PARAM( DbgInfo, PARM_NAME_AUTH_KEY_MGMT_SUITE, "%d", PARM_AUTH_KEY_MGMT_SUITE );
461 //;?#if (HCF_TYPE) & HCF_TYPE_STA
462 //;?should we make this code conditional depending on in STA mode
463 //;? DBG_PARAM( DbgInfo, PARM_NAME_PORT_TYPE, "%d", PARM_PORT_TYPE );
464 DBG_PARAM( DbgInfo, PARM_NAME_PM_ENABLED, "%04x", PARM_PM_ENABLED );
465 //;? DBG_PARAM( DbgInfo, PARM_NAME_CREATE_IBSS, "\"%s\"", PARM_CREATE_IBSS );
466 //;? DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RX, "\"%s\"", PARM_MULTICAST_RX );
467 //;? DBG_PARAM( DbgInfo, PARM_NAME_MAX_SLEEP, "%d", PARM_MAX_SLEEP );
469 DBG_PARAM(DbgInfo, PARM_NAME_NETWORK_ADDR, "\"%pM\"",
472 //;? DBG_PARAM( DbgInfo, PARM_NAME_AUTHENTICATION, "%d", PARM_AUTHENTICATION );
473 //;? DBG_PARAM( DbgInfo, PARM_NAME_OWN_ATIM_WINDOW, "%d", PARM_OWN_ATIM_WINDOW );
474 //;? DBG_PARAM( DbgInfo, PARM_NAME_PM_HOLDOVER_DURATION, "%d", PARM_PM_HOLDOVER_DURATION );
475 //;? DBG_PARAM( DbgInfo, PARM_NAME_PROMISCUOUS_MODE, "\"%s\"", PARM_PROMISCUOUS_MODE );
476 //;?#endif /* HCF_STA */
477 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
478 //;?should we restore this to allow smaller memory footprint
479 //;?I guess: no, since this is Debug mode only
480 DBG_PARAM( DbgInfo, PARM_NAME_OWN_DTIM_PERIOD, "%d", PARM_OWN_DTIM_PERIOD );
481 DBG_PARAM( DbgInfo, PARM_NAME_REJECT_ANY, "\"%s\"", PARM_REJECT_ANY );
482 DBG_PARAM( DbgInfo, PARM_NAME_EXCLUDE_UNENCRYPTED, "\"%s\"", PARM_EXCLUDE_UNENCRYPTED );
483 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_PM_BUFFERING, "\"%s\"", PARM_MULTICAST_PM_BUFFERING );
484 DBG_PARAM( DbgInfo, PARM_NAME_INTRA_BSS_RELAY, "\"%s\"", PARM_INTRA_BSS_RELAY );
486 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD1, "%d", PARM_RTS_THRESHOLD1 );
487 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD2, "%d", PARM_RTS_THRESHOLD2 );
488 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD3, "%d", PARM_RTS_THRESHOLD3 );
489 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD4, "%d", PARM_RTS_THRESHOLD4 );
490 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD5, "%d", PARM_RTS_THRESHOLD5 );
491 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD6, "%d", PARM_RTS_THRESHOLD6 );
492 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE1, "%d", PARM_TX_RATE1 );
493 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE2, "%d", PARM_TX_RATE2 );
494 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE3, "%d", PARM_TX_RATE3 );
495 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE4, "%d", PARM_TX_RATE4 );
496 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE5, "%d", PARM_TX_RATE5 );
497 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE6, "%d", PARM_TX_RATE6 );
498 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS1, "\"%pM\"",
500 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS2, "\"%pM\"",
502 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS3, "\"%pM\"",
504 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS4, "\"%pM\"",
506 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS5, "\"%pM\"",
508 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS6, "\"%pM\"",
513 VALID_PARAM( !PARM_DESIRED_SSID || ( strlen( PARM_DESIRED_SSID ) <= PARM_MAX_NAME_LEN ));
514 VALID_PARAM( !PARM_OWN_SSID || ( strlen( PARM_OWN_SSID ) <= PARM_MAX_NAME_LEN ));
515 VALID_PARAM(( PARM_OWN_CHANNEL <= PARM_MAX_OWN_CHANNEL ));
516 VALID_PARAM(( PARM_SYSTEM_SCALE >= PARM_MIN_SYSTEM_SCALE ) && ( PARM_SYSTEM_SCALE <= PARM_MAX_SYSTEM_SCALE ));
517 VALID_PARAM(( PARM_TX_RATE >= PARM_MIN_TX_RATE ) && ( PARM_TX_RATE <= PARM_MAX_TX_RATE ));
518 VALID_PARAM(( PARM_RTS_THRESHOLD <= PARM_MAX_RTS_THRESHOLD ));
519 VALID_PARAM( !PARM_MICROWAVE_ROBUSTNESS || strchr( "NnYy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL );
520 VALID_PARAM( !PARM_OWN_NAME || ( strlen( PARM_NAME_OWN_NAME ) <= PARM_MAX_NAME_LEN ));
521 VALID_PARAM(( PARM_ENABLE_ENCRYPTION <= PARM_MAX_ENABLE_ENCRYPTION ));
522 VALID_PARAM( is_valid_key_string( PARM_KEY1 ));
523 VALID_PARAM( is_valid_key_string( PARM_KEY2 ));
524 VALID_PARAM( is_valid_key_string( PARM_KEY3 ));
525 VALID_PARAM( is_valid_key_string( PARM_KEY4 ));
526 VALID_PARAM(( PARM_TX_KEY >= PARM_MIN_TX_KEY ) && ( PARM_TX_KEY <= PARM_MAX_TX_KEY ));
528 VALID_PARAM(( PARM_MULTICAST_RATE >= PARM_MIN_MULTICAST_RATE ) &&
529 ( PARM_MULTICAST_RATE <= PARM_MAX_MULTICAST_RATE ));
531 VALID_PARAM( !PARM_DOWNLOAD_FIRMWARE || ( strlen( PARM_DOWNLOAD_FIRMWARE ) <= 255 /*;?*/ ));
532 VALID_PARAM(( PARM_AUTH_KEY_MGMT_SUITE < PARM_MAX_AUTH_KEY_MGMT_SUITE ));
534 VALID_PARAM( !PARM_LOAD_BALANCING || strchr( "NnYy", PARM_LOAD_BALANCING[0] ) != NULL );
535 VALID_PARAM( !PARM_MEDIUM_DISTRIBUTION || strchr( "NnYy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL );
536 VALID_PARAM(( PARM_TX_POW_LEVEL <= PARM_MAX_TX_POW_LEVEL ));
538 VALID_PARAM(( PARM_PORT_TYPE >= PARM_MIN_PORT_TYPE ) && ( PARM_PORT_TYPE <= PARM_MAX_PORT_TYPE ));
539 VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
540 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
541 VALID_PARAM( !PARM_CREATE_IBSS || strchr( "NnYy", PARM_CREATE_IBSS[0] ) != NULL );
542 VALID_PARAM( !PARM_MULTICAST_RX || strchr( "NnYy", PARM_MULTICAST_RX[0] ) != NULL );
543 VALID_PARAM(( PARM_MAX_SLEEP <= PARM_MAX_MAX_PM_SLEEP ));
544 VALID_PARAM(( PARM_AUTHENTICATION <= PARM_MAX_AUTHENTICATION ));
545 VALID_PARAM(( PARM_OWN_ATIM_WINDOW <= PARM_MAX_OWN_ATIM_WINDOW ));
546 VALID_PARAM(( PARM_PM_HOLDOVER_DURATION <= PARM_MAX_PM_HOLDOVER_DURATION ));
547 VALID_PARAM( !PARM_PROMISCUOUS_MODE || strchr( "NnYy", PARM_PROMISCUOUS_MODE[0] ) != NULL );
548 VALID_PARAM(( PARM_CONNECTION_CONTROL <= PARM_MAX_CONNECTION_CONTROL ));
550 VALID_PARAM(( PARM_OWN_DTIM_PERIOD >= PARM_MIN_OWN_DTIM_PERIOD ));
551 VALID_PARAM( !PARM_REJECT_ANY || strchr( "NnYy", PARM_REJECT_ANY[0] ) != NULL );
552 VALID_PARAM( !PARM_EXCLUDE_UNENCRYPTED || strchr( "NnYy", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL );
553 VALID_PARAM( !PARM_MULTICAST_PM_BUFFERING || strchr( "NnYy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL );
554 VALID_PARAM( !PARM_INTRA_BSS_RELAY || strchr( "NnYy", PARM_INTRA_BSS_RELAY[0] ) != NULL );
556 VALID_PARAM(( PARM_RTS_THRESHOLD1 <= PARM_MAX_RTS_THRESHOLD ));
557 VALID_PARAM(( PARM_RTS_THRESHOLD2 <= PARM_MAX_RTS_THRESHOLD ));
558 VALID_PARAM(( PARM_RTS_THRESHOLD3 <= PARM_MAX_RTS_THRESHOLD ));
559 VALID_PARAM(( PARM_RTS_THRESHOLD4 <= PARM_MAX_RTS_THRESHOLD ));
560 VALID_PARAM(( PARM_RTS_THRESHOLD5 <= PARM_MAX_RTS_THRESHOLD ));
561 VALID_PARAM(( PARM_RTS_THRESHOLD6 <= PARM_MAX_RTS_THRESHOLD ));
562 VALID_PARAM(( PARM_TX_RATE1 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE1 <= PARM_MAX_TX_RATE ));
563 VALID_PARAM(( PARM_TX_RATE2 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE2 <= PARM_MAX_TX_RATE ));
564 VALID_PARAM(( PARM_TX_RATE3 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE3 <= PARM_MAX_TX_RATE ));
565 VALID_PARAM(( PARM_TX_RATE4 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE4 <= PARM_MAX_TX_RATE ));
566 VALID_PARAM(( PARM_TX_RATE5 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE5 <= PARM_MAX_TX_RATE ));
567 VALID_PARAM(( PARM_TX_RATE6 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE6 <= PARM_MAX_TX_RATE ));
570 VALID_PARAM(( PARM_OWN_BEACON_INTERVAL >= PARM_MIN_OWN_BEACON_INTERVAL ) && ( PARM_OWN_BEACON_INTERVAL <= PARM_MAX_OWN_BEACON_INTERVAL ));
571 VALID_PARAM(( PARM_COEXISTENCE <= PARM_COEXISTENCE ));
573 /* Set the driver parameters from the passed in parameters. */
575 /* THESE MODULE PARAMETERS ARE TO BE DEPRECATED IN FAVOR OF A NAMING CONVENTION
576 WHICH IS INLINE WITH THE FORTHCOMING WAVELAN API */
578 /* START NEW PARAMETERS */
580 lp->Channel = PARM_OWN_CHANNEL;
581 lp->DistanceBetweenAPs = PARM_SYSTEM_SCALE;
583 /* Need to determine how to handle the new bands for 5GHz */
584 lp->TxRateControl[0] = PARM_DEFAULT_TX_RATE_2GHZ;
585 lp->TxRateControl[1] = PARM_DEFAULT_TX_RATE_5GHZ;
587 lp->RTSThreshold = PARM_RTS_THRESHOLD;
589 /* Need to determine how to handle the new bands for 5GHz */
590 lp->MulticastRate[0] = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
591 lp->MulticastRate[1] = PARM_DEFAULT_MULTICAST_RATE_5GHZ;
593 if ( strchr( "Yy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL ) {
594 lp->MicrowaveRobustness = 1;
596 lp->MicrowaveRobustness = 0;
598 if ( PARM_DESIRED_SSID && ( strlen( PARM_DESIRED_SSID ) <= HCF_MAX_NAME_LEN )) {
599 strcpy( lp->NetworkName, PARM_DESIRED_SSID );
601 if ( PARM_OWN_SSID && ( strlen( PARM_OWN_SSID ) <= HCF_MAX_NAME_LEN )) {
602 strcpy( lp->NetworkName, PARM_OWN_SSID );
604 if ( PARM_OWN_NAME && ( strlen( PARM_OWN_NAME ) <= HCF_MAX_NAME_LEN )) {
605 strcpy( lp->StationName, PARM_OWN_NAME );
607 lp->EnableEncryption = PARM_ENABLE_ENCRYPTION;
608 if ( PARM_KEY1 && ( strlen( PARM_KEY1 ) <= MAX_KEY_LEN )) {
609 strcpy( lp->Key1, PARM_KEY1 );
611 if ( PARM_KEY2 && ( strlen( PARM_KEY2 ) <= MAX_KEY_LEN )) {
612 strcpy( lp->Key2, PARM_KEY2 );
614 if ( PARM_KEY3 && ( strlen( PARM_KEY3 ) <= MAX_KEY_LEN )) {
615 strcpy( lp->Key3, PARM_KEY3 );
617 if ( PARM_KEY4 && ( strlen( PARM_KEY4 ) <= MAX_KEY_LEN )) {
618 strcpy( lp->Key4, PARM_KEY4 );
621 lp->TransmitKeyID = PARM_TX_KEY;
623 key_string2key( lp->Key1, &(lp->DefaultKeys.key[0] ));
624 key_string2key( lp->Key2, &(lp->DefaultKeys.key[1] ));
625 key_string2key( lp->Key3, &(lp->DefaultKeys.key[2] ));
626 key_string2key( lp->Key4, &(lp->DefaultKeys.key[3] ));
628 lp->DownloadFirmware = 1 ; //;?to be upgraded PARM_DOWNLOAD_FIRMWARE;
629 lp->AuthKeyMgmtSuite = PARM_AUTH_KEY_MGMT_SUITE;
631 if ( strchr( "Yy", PARM_LOAD_BALANCING[0] ) != NULL ) {
632 lp->loadBalancing = 1;
634 lp->loadBalancing = 0;
637 if ( strchr( "Yy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL ) {
638 lp->mediumDistribution = 1;
640 lp->mediumDistribution = 0;
643 lp->txPowLevel = PARM_TX_POW_LEVEL;
645 lp->srsc[0] = PARM_SRSC_2GHZ;
646 lp->srsc[1] = PARM_SRSC_5GHZ;
647 lp->brsc[0] = PARM_BRSC_2GHZ;
648 lp->brsc[1] = PARM_BRSC_5GHZ;
649 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
650 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
651 lp->PortType = PARM_PORT_TYPE;
652 lp->MaxSleepDuration = PARM_MAX_SLEEP;
653 lp->authentication = PARM_AUTHENTICATION;
654 lp->atimWindow = PARM_OWN_ATIM_WINDOW;
655 lp->holdoverDuration = PARM_PM_HOLDOVER_DURATION;
656 lp->PMEnabled = PARM_PM_ENABLED; //;?
657 if ( strchr( "Yy", PARM_CREATE_IBSS[0] ) != NULL ) {
662 if ( strchr( "Nn", PARM_MULTICAST_RX[0] ) != NULL ) {
663 lp->MulticastReceive = 0;
665 lp->MulticastReceive = 1;
667 if ( strchr( "Yy", PARM_PROMISCUOUS_MODE[0] ) != NULL ) {
668 lp->promiscuousMode = 1;
670 lp->promiscuousMode = 0;
672 for( i = 0; i < ETH_ALEN; i++ ) {
673 lp->MACAddress[i] = PARM_NETWORK_ADDR[i];
676 lp->connectionControl = PARM_CONNECTION_CONTROL;
679 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
680 //;?should we restore this to allow smaller memory footprint
681 lp->DTIMPeriod = PARM_OWN_DTIM_PERIOD;
683 if ( strchr( "Yy", PARM_REJECT_ANY[0] ) != NULL ) {
688 if ( strchr( "Nn", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL ) {
689 lp->ExcludeUnencrypted = 0;
691 lp->ExcludeUnencrypted = 1;
693 if ( strchr( "Yy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL ) {
694 lp->multicastPMBuffering = 1;
696 lp->multicastPMBuffering = 0;
698 if ( strchr( "Yy", PARM_INTRA_BSS_RELAY[0] ) != NULL ) {
699 lp->intraBSSRelay = 1;
701 lp->intraBSSRelay = 0;
704 lp->ownBeaconInterval = PARM_OWN_BEACON_INTERVAL;
705 lp->coexistence = PARM_COEXISTENCE;
708 lp->wds_port[0].rtsThreshold = PARM_RTS_THRESHOLD1;
709 lp->wds_port[1].rtsThreshold = PARM_RTS_THRESHOLD2;
710 lp->wds_port[2].rtsThreshold = PARM_RTS_THRESHOLD3;
711 lp->wds_port[3].rtsThreshold = PARM_RTS_THRESHOLD4;
712 lp->wds_port[4].rtsThreshold = PARM_RTS_THRESHOLD5;
713 lp->wds_port[5].rtsThreshold = PARM_RTS_THRESHOLD6;
714 lp->wds_port[0].txRateCntl = PARM_TX_RATE1;
715 lp->wds_port[1].txRateCntl = PARM_TX_RATE2;
716 lp->wds_port[2].txRateCntl = PARM_TX_RATE3;
717 lp->wds_port[3].txRateCntl = PARM_TX_RATE4;
718 lp->wds_port[4].txRateCntl = PARM_TX_RATE5;
719 lp->wds_port[5].txRateCntl = PARM_TX_RATE6;
721 for( i = 0; i < ETH_ALEN; i++ ) {
722 lp->wds_port[0].wdsAddress[i] = PARM_WDS_ADDRESS1[i];
724 for( i = 0; i < ETH_ALEN; i++ ) {
725 lp->wds_port[1].wdsAddress[i] = PARM_WDS_ADDRESS2[i];
727 for( i = 0; i < ETH_ALEN; i++ ) {
728 lp->wds_port[2].wdsAddress[i] = PARM_WDS_ADDRESS3[i];
730 for( i = 0; i < ETH_ALEN; i++ ) {
731 lp->wds_port[3].wdsAddress[i] = PARM_WDS_ADDRESS4[i];
733 for( i = 0; i < ETH_ALEN; i++ ) {
734 lp->wds_port[4].wdsAddress[i] = PARM_WDS_ADDRESS5[i];
736 for( i = 0; i < ETH_ALEN; i++ ) {
737 lp->wds_port[5].wdsAddress[i] = PARM_WDS_ADDRESS6[i];
742 if ( strchr( "Yy", useRTS[0] ) != NULL ) {
750 /* END NEW PARAMETERS */
753 wl_lock( lp, &flags );
755 /* Initialize the portState variable */
756 lp->portState = WVLAN_PORT_STATE_DISABLED;
758 /* Initialize the ScanResult struct */
759 memset( &( lp->scan_results ), 0, sizeof( lp->scan_results ));
760 lp->scan_results.scan_complete = FALSE;
762 /* Initialize the ProbeResult struct */
763 memset( &( lp->probe_results ), 0, sizeof( lp->probe_results ));
764 lp->probe_results.scan_complete = FALSE;
765 lp->probe_num_aps = 0;
768 /* Initialize Tx queue stuff */
769 memset( lp->txList, 0, sizeof( lp->txList ));
771 INIT_LIST_HEAD( &( lp->txFree ));
777 for( i = 0; i < DEFAULT_NUM_TX_FRAMES; i++ ) {
778 list_add_tail( &( lp->txList[i].node ), &( lp->txFree ));
782 for( i = 0; i < WVLAN_MAX_TX_QUEUES; i++ ) {
783 INIT_LIST_HEAD( &( lp->txQ[i] ));
786 lp->netif_queue_on = TRUE;
788 /* Initialize the use_dma element in the adapter structure. Not sure if
789 this should be a compile-time or run-time configurable. So for now,
790 implement as run-time and just define here */
793 DBG_TRACE( DbgInfo, "HERMES 2.5 BUSMASTER DMA MODE\n" );
796 DBG_TRACE( DbgInfo, "HERMES 2.5 PORT I/O MODE\n" );
801 /* Register the ISR handler information here, so that it's not done
802 repeatedly in the ISR */
803 tasklet_init(&lp->task, wl_isr_handler, (unsigned long)lp);
805 /* Connect to the adapter */
806 DBG_TRACE( DbgInfo, "Calling hcf_connect()...\n" );
807 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
808 //HCF_ERR_INCOMP_FW is acceptable, because download must still take place
809 //HCF_ERR_INCOMP_PRI is not acceptable
810 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
811 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
812 wl_unlock( lp, &flags );
816 //;?should set HCF_version and how about driver_stat
817 lp->driverInfo.IO_address = dev->base_addr;
818 lp->driverInfo.IO_range = HCF_NUM_IO_PORTS; //;?conditionally 0x40 or 0x80 seems better
819 lp->driverInfo.IRQ_number = dev->irq;
820 lp->driverInfo.card_stat = lp->hcfCtx.IFB_CardStat;
821 //;? what happened to frame_type
823 /* Fill in the driver identity structure */
824 lp->driverIdentity.len = ( sizeof( lp->driverIdentity ) / sizeof( hcf_16 )) - 1;
825 lp->driverIdentity.typ = CFG_DRV_IDENTITY;
826 lp->driverIdentity.comp_id = DRV_IDENTITY;
827 lp->driverIdentity.variant = DRV_VARIANT;
828 lp->driverIdentity.version_major = DRV_MAJOR_VERSION;
829 lp->driverIdentity.version_minor = DRV_MINOR_VERSION;
832 /* Start the card here - This needs to be done in order to get the
833 MAC address for the network layer */
834 DBG_TRACE( DbgInfo, "Calling wvlan_go() to perform a card reset...\n" );
835 hcf_status = wl_go( lp );
837 if ( hcf_status != HCF_SUCCESS ) {
838 DBG_ERROR( DbgInfo, "wl_go() failed\n" );
839 wl_unlock( lp, &flags );
843 /* Certain RIDs must be set before enabling the ports */
844 wl_put_ltv_init( lp );
846 #if 0 //;?why was this already commented out in wl_lkm_720
847 /* Enable the ports */
848 if ( wl_adapter_is_open( lp->dev )) {
849 /* Enable the ports */
850 DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
851 hcf_status = wl_enable( lp );
853 if ( hcf_status != HCF_SUCCESS ) {
854 DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", hcf_status );
857 #if (HCF_TYPE) & HCF_TYPE_AP
858 DBG_TRACE( DbgInfo, "Enabling WDS Ports\n" );
859 //wl_enable_wds_ports( lp );
860 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
865 /* Fill out the MAC address information in the net_device struct */
866 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN );
867 dev->addr_len = ETH_ALEN;
869 lp->is_registered = TRUE;
872 /* Parse the config file for the sake of creating WDS ports if WDS is
873 configured there but not in the module options */
875 #endif /* USE_PROFILE */
877 /* If we're going into AP Mode, register the "virtual" ethernet devices
879 WL_WDS_NETDEV_REGISTER( lp );
881 /* Reset the DownloadFirmware variable in the private struct. If the
882 config file is not used, this will not matter; if it is used, it
883 will be reparsed in wl_open(). This is done because logic in wl_open
884 used to check if a firmware download is needed is broken by parsing
885 the file here; however, this parsing is needed to register WDS ports
886 in AP mode, if they are configured */
887 lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //;?download_firmware;
890 if ( lp->useRTS == 1 ) {
891 DBG_TRACE( DbgInfo, "ENTERING RTS MODE...\n" );
892 wl_act_int_off( lp );
893 lp->is_handling_int = WL_NOT_HANDLING_INT; // Not handling interrupts anymore
897 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT);
901 wl_unlock( lp, &flags );
903 DBG_TRACE( DbgInfo, "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
904 dev->name, dev->base_addr, dev->irq );
906 for( i = 0; i < ETH_ALEN; i++ ) {
907 printk( "%02X%c", dev->dev_addr[i], (( i < ( ETH_ALEN-1 )) ? ':' : '\n' ));
910 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
911 create_proc_read_entry( "wlags", 0, NULL, scull_read_procmem, dev );
912 proc_mkdir("driver/wlags49", 0);
913 proc_write("driver/wlags49/wlags49_type", write_int, &lp->wlags49_type);
914 #endif /* SCULL_USE_PROC */
916 DBG_LEAVE( DbgInfo );
920 wl_hcf_error( dev, hcf_status );
924 DBG_ERROR( DbgInfo, "wl_insert() FAILED\n" );
926 if ( lp->is_registered == TRUE ) {
927 lp->is_registered = FALSE;
930 WL_WDS_NETDEV_DEREGISTER( lp );
935 DBG_LEAVE( DbgInfo );
938 /*============================================================================*/
941 /*******************************************************************************
943 *******************************************************************************
951 * dev - a pointer to the net_device struct of the wireless device
957 ******************************************************************************/
958 int wl_reset(struct net_device *dev)
960 struct wl_private *lp = wl_priv(dev);
961 int hcf_status = HCF_SUCCESS;
962 /*------------------------------------------------------------------------*/
963 DBG_FUNC( "wl_reset" );
964 DBG_ENTER( DbgInfo );
965 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
966 DBG_PARAM( DbgInfo, "dev->base_addr", "(%#03lx)", dev->base_addr );
969 * The caller should already have a lock and
970 * disable the interrupts, we do not lock here,
971 * nor do we enable/disable interrupts!
974 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", dev->base_addr );
975 if ( dev->base_addr ) {
976 /* Shutdown the adapter. */
977 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
979 /* Reset the driver information. */
982 /* Connect to the adapter. */
983 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
984 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
985 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
989 /* Check if firmware is present, if not change state */
990 if ( hcf_status == HCF_ERR_INCOMP_FW ) {
991 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
994 /* Initialize the portState variable */
995 lp->portState = WVLAN_PORT_STATE_DISABLED;
997 /* Restart the adapter. */
998 hcf_status = wl_go( lp );
999 if ( hcf_status != HCF_SUCCESS ) {
1000 DBG_ERROR( DbgInfo, "wl_go() failed, status: 0x%x\n", hcf_status );
1004 /* Certain RIDs must be set before enabling the ports */
1005 wl_put_ltv_init( lp );
1007 DBG_ERROR( DbgInfo, "Device Base Address INVALID!!!\n" );
1011 DBG_LEAVE( DbgInfo );
1014 /*============================================================================*/
1017 /*******************************************************************************
1019 *******************************************************************************
1023 * Reset the adapter.
1027 * dev - a pointer to the net_device struct of the wireless device
1031 * an HCF status code
1033 ******************************************************************************/
1034 int wl_go( struct wl_private *lp )
1036 int hcf_status = HCF_SUCCESS;
1037 char *cp = NULL; //fw_image
1039 /*------------------------------------------------------------------------*/
1040 DBG_FUNC( "wl_go" );
1041 DBG_ENTER( DbgInfo );
1043 hcf_status = wl_disable( lp );
1044 if ( hcf_status != HCF_SUCCESS ) {
1045 DBG_TRACE( DbgInfo, "Disable port 0 failed: 0x%x\n", hcf_status );
1047 while (( hcf_status != HCF_SUCCESS ) && (retries < 10)) {
1049 hcf_status = wl_disable( lp );
1051 if ( hcf_status == HCF_SUCCESS ) {
1052 DBG_TRACE( DbgInfo, "Disable port 0 succes : %d retries\n", retries );
1054 DBG_TRACE( DbgInfo, "Disable port 0 failed after: %d retries\n", retries );
1058 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
1059 //DBG_TRACE( DbgInfo, "Disabling WDS Ports\n" );
1060 //wl_disable_wds_ports( lp );
1061 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1063 //;?what was the purpose of this
1064 // /* load the appropriate firmware image, depending on driver mode */
1065 // lp->ltvRecord.len = ( sizeof( CFG_RANGE20_STRCT ) / sizeof( hcf_16 )) - 1;
1066 // lp->ltvRecord.typ = CFG_DRV_ACT_RANGES_PRI;
1067 // hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1070 if ( strlen( lp->fw_image_filename ) ) {
1075 DBG_TRACE( DbgInfo, "F/W image:%s:\n", lp->fw_image_filename );
1076 /* Obtain a user-space process context, storing the original context */
1079 file_desc = open( lp->fw_image_filename, O_RDONLY, 0 );
1080 if ( file_desc == -1 ) {
1081 DBG_ERROR( DbgInfo, "No image file found\n" );
1083 DBG_TRACE( DbgInfo, "F/W image file found\n" );
1084 #define DHF_ALLOC_SIZE 96000 //just below 96K, let's hope it suffices for now and for the future
1085 cp = (char*)vmalloc( DHF_ALLOC_SIZE );
1087 DBG_ERROR( DbgInfo, "error in vmalloc\n" );
1089 rc = read( file_desc, cp, DHF_ALLOC_SIZE );
1090 if ( rc == DHF_ALLOC_SIZE ) {
1091 DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE );
1092 } else if ( rc > 0 ) {
1093 DBG_TRACE( DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp );
1094 rc = read( file_desc, &cp[rc], 1 );
1095 if ( rc == 0 ) { //;/change to an until-loop at rc<=0
1096 DBG_TRACE( DbgInfo, "no more to read\n" );
1100 DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\
1101 ", give up, too complicated, rc = %0X\n", rc );
1102 DBG_ERROR( DbgInfo, "still have to change code to get a real download now !!!!!!!!\n" );
1104 DBG_TRACE( DbgInfo, "before dhf_download_binary\n" );
1105 hcf_status = dhf_download_binary( (memimage *)cp );
1106 DBG_TRACE( DbgInfo, "after dhf_download_binary, before dhf_download_fw\n" );
1107 //;?improve error flow/handling
1108 hcf_status = dhf_download_fw( &lp->hcfCtx, (memimage *)cp );
1109 DBG_TRACE( DbgInfo, "after dhf_download_fw\n" );
1115 set_fs( fs ); /* Return to the original context */
1119 /* If firmware is present but the type is unknown then download anyway */
1120 if ( (lp->firmware_present == WL_FRIMWARE_PRESENT)
1122 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_STA )
1124 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_AP ) ) {
1125 /* Unknown type, download needed. */
1126 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1129 if(lp->firmware_present == WL_FRIMWARE_NOT_PRESENT)
1132 DBG_TRACE( DbgInfo, "Downloading STA firmware...\n" );
1133 // hcf_status = dhf_download_fw( &lp->hcfCtx, &station );
1134 hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image );
1136 if ( hcf_status != HCF_SUCCESS ) {
1137 DBG_ERROR( DbgInfo, "Firmware Download failed\n" );
1138 DBG_LEAVE( DbgInfo );
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" );
1177 DBG_LEAVE( DbgInfo );
1180 memcpy( lp->MACAddress, &lp->ltvRecord.u.u8[0], ETH_ALEN );
1181 DBG_TRACE(DbgInfo, "Card MAC Address: %pM\n", lp->MACAddress);
1183 /* Write out configuration to the device, enable, and reconnect. However,
1184 only reconnect if in AP mode. For STA mode, need to wait for passive scan
1185 completion before a connect can be issued */
1187 /* Enable the ports */
1188 hcf_status = wl_enable( lp );
1190 if ( lp->DownloadFirmware == WVLAN_DRV_MODE_AP ) {
1192 wl_enable_wds_ports( lp );
1194 hcf_status = wl_connect( lp );
1196 DBG_LEAVE( DbgInfo );
1199 /*============================================================================*/
1202 /*******************************************************************************
1204 *******************************************************************************
1208 * Write TxKeyID and WEP keys to the adapter. This is separated from
1209 * wl_apply() to allow dynamic WEP key updates through the wireless
1214 * lp - a pointer to the wireless adapter's private structure
1220 ******************************************************************************/
1221 void wl_set_wep_keys( struct wl_private *lp )
1224 /*------------------------------------------------------------------------*/
1225 DBG_FUNC( "wl_set_wep_keys" );
1226 DBG_ENTER( DbgInfo );
1227 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1228 if ( lp->EnableEncryption ) {
1229 /* NOTE: CFG_CNF_ENCRYPTION is set in wl_put_ltv() as it's a static
1233 lp->ltvRecord.len = 2;
1234 lp->ltvRecord.typ = CFG_TX_KEY_ID;
1235 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE(lp->TransmitKeyID - 1);
1237 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1239 DBG_TRACE( DbgInfo, "Key 1 len: %d\n", lp->DefaultKeys.key[0].len );
1240 DBG_TRACE( DbgInfo, "Key 2 len: %d\n", lp->DefaultKeys.key[1].len );
1241 DBG_TRACE( DbgInfo, "Key 3 len: %d\n", lp->DefaultKeys.key[2].len );
1242 DBG_TRACE( DbgInfo, "Key 4 len: %d\n", lp->DefaultKeys.key[3].len );
1245 lp->DefaultKeys.len = sizeof( lp->DefaultKeys ) / sizeof( hcf_16 ) - 1;
1246 lp->DefaultKeys.typ = CFG_DEFAULT_KEYS;
1248 /* endian translate the appropriate key information */
1249 for( count = 0; count < MAX_KEYS; count++ ) {
1250 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1253 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->DefaultKeys ));
1255 /* Reverse the above endian translation, since these keys are accessed
1257 for( count = 0; count < MAX_KEYS; count++ ) {
1258 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1261 DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption, lp->TransmitKeyID );
1262 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 );
1265 DBG_LEAVE( DbgInfo );
1266 } // wl_set_wep_keys
1267 /*============================================================================*/
1270 /*******************************************************************************
1272 *******************************************************************************
1276 * Write the parameters to the adapter. (re-)enables the card if device is
1277 * open. Returns hcf_status of hcf_enable().
1281 * lp - a pointer to the wireless adapter's private structure
1285 * an HCF status code
1287 ******************************************************************************/
1288 int wl_apply(struct wl_private *lp)
1290 int hcf_status = HCF_SUCCESS;
1291 /*------------------------------------------------------------------------*/
1292 DBG_FUNC( "wl_apply" );
1293 DBG_ENTER( DbgInfo );
1294 DBG_ASSERT( lp != NULL);
1295 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1297 if ( !( lp->flags & WVLAN2_UIL_BUSY )) {
1298 /* The adapter parameters have changed:
1304 if ( wl_adapter_is_open( lp->dev )) {
1305 /* Disconnect and disable if necessary */
1306 hcf_status = wl_disconnect( lp );
1307 if ( hcf_status != HCF_SUCCESS ) {
1308 DBG_ERROR( DbgInfo, "Disconnect failed\n" );
1309 DBG_LEAVE( DbgInfo );
1312 hcf_status = wl_disable( lp );
1313 if ( hcf_status != HCF_SUCCESS ) {
1314 DBG_ERROR( DbgInfo, "Disable failed\n" );
1315 DBG_LEAVE( DbgInfo );
1318 /* Write out configuration to the device, enable, and reconnect.
1319 However, only reconnect if in AP mode. For STA mode, need to
1320 wait for passive scan completion before a connect can be
1322 hcf_status = wl_put_ltv( lp );
1324 if ( hcf_status == HCF_SUCCESS ) {
1325 hcf_status = wl_enable( lp );
1327 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1328 hcf_status = wl_connect( lp );
1331 DBG_WARNING( DbgInfo, "wl_put_ltv() failed\n" );
1337 DBG_LEAVE( DbgInfo );
1340 /*============================================================================*/
1343 /*******************************************************************************
1345 *******************************************************************************
1349 * Used to set basic parameters for card initialization.
1353 * lp - a pointer to the wireless adapter's private structure
1357 * an HCF status code
1359 ******************************************************************************/
1360 int wl_put_ltv_init( struct wl_private *lp )
1364 CFG_RID_LOG_STRCT *RidLog;
1365 /*------------------------------------------------------------------------*/
1366 DBG_FUNC( "wl_put_ltv_init" );
1367 DBG_ENTER( DbgInfo );
1369 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1370 DBG_LEAVE( DbgInfo );
1374 lp->ltvRecord.len = 2;
1375 lp->ltvRecord.typ = CFG_CNTL_OPT;
1377 /* The Card Services build must ALWAYS be configured for 16-bit I/O. PCI or
1378 CardBus can be set to either 16/32 bit I/O, or Bus Master DMA, but only
1381 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_16BIT );
1383 if ( lp->use_dma ) {
1384 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_DMA );
1386 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1390 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1391 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT : 0x%04x\n",
1392 lp->ltvRecord.u.u16[0] );
1393 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT result : 0x%04x\n",
1396 /* Register the list of RIDs on which asynchronous notification is
1397 required. Note that this mechanism replaces the mailbox, so the mailbox
1398 can be queried by the host (if desired) without contention from us */
1401 lp->RidList[i].len = sizeof( lp->ProbeResp );
1402 lp->RidList[i].typ = CFG_ACS_SCAN;
1403 lp->RidList[i].bufp = (wci_recordp)&lp->ProbeResp;
1404 //lp->ProbeResp.infoType = 0xFFFF;
1407 lp->RidList[i].len = sizeof( lp->assoc_stat );
1408 lp->RidList[i].typ = CFG_ASSOC_STAT;
1409 lp->RidList[i].bufp = (wci_recordp)&lp->assoc_stat;
1410 lp->assoc_stat.len = 0xFFFF;
1413 lp->RidList[i].len = 4;
1414 lp->RidList[i].typ = CFG_UPDATED_INFO_RECORD;
1415 lp->RidList[i].bufp = (wci_recordp)&lp->updatedRecord;
1416 lp->updatedRecord.len = 0xFFFF;
1419 lp->RidList[i].len = sizeof( lp->sec_stat );
1420 lp->RidList[i].typ = CFG_SECURITY_STAT;
1421 lp->RidList[i].bufp = (wci_recordp)&lp->sec_stat;
1422 lp->sec_stat.len = 0xFFFF;
1425 lp->RidList[i].typ = 0; // Terminate List
1427 RidLog = (CFG_RID_LOG_STRCT *)&lp->ltvRecord;
1429 RidLog->typ = CFG_REG_INFO_LOG;
1430 RidLog->recordp = (RID_LOGP)&lp->RidList[0];
1432 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1433 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG\n" );
1434 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG result : 0x%04x\n",
1436 DBG_LEAVE( DbgInfo );
1438 } // wl_put_ltv_init
1439 /*============================================================================*/
1442 /*******************************************************************************
1444 *******************************************************************************
1448 * Used by wvlan_apply() and wvlan_go to set the card's configuration.
1452 * lp - a pointer to the wireless adapter's private structure
1456 * an HCF status code
1458 ******************************************************************************/
1459 int wl_put_ltv( struct wl_private *lp )
1463 /*------------------------------------------------------------------------*/
1464 DBG_FUNC( "wl_put_ltv" );
1465 DBG_ENTER( DbgInfo );
1468 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1471 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1472 lp->maxPort = 6; //;?why set this here and not as part of download process
1477 /* Send our configuration to the card. Perform any endian translation
1479 /* Register the Mailbox; VxWorks does this elsewhere; why;? */
1480 lp->ltvRecord.len = 4;
1481 lp->ltvRecord.typ = CFG_REG_MB;
1482 lp->ltvRecord.u.u32[0] = (u_long)&( lp->mailbox );
1483 lp->ltvRecord.u.u16[2] = ( MB_SIZE / sizeof( hcf_16 ));
1484 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1486 /* Max Data Length */
1487 lp->ltvRecord.len = 2;
1488 lp->ltvRecord.typ = CFG_CNF_MAX_DATA_LEN;
1489 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( HCF_MAX_PACKET_SIZE );
1490 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1492 /* System Scale / Distance between APs */
1493 lp->ltvRecord.len = 2;
1494 lp->ltvRecord.typ = CFG_CNF_SYSTEM_SCALE;
1495 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DistanceBetweenAPs );
1496 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1499 if ( lp->CreateIBSS && ( lp->Channel == 0 )) {
1500 DBG_TRACE( DbgInfo, "Create IBSS" );
1503 lp->ltvRecord.len = 2;
1504 lp->ltvRecord.typ = CFG_CNF_OWN_CHANNEL;
1505 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->Channel );
1506 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1508 /* Microwave Robustness */
1509 lp->ltvRecord.len = 2;
1510 lp->ltvRecord.typ = CFG_CNF_MICRO_WAVE;
1511 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MicrowaveRobustness );
1512 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1514 /* Load Balancing */
1515 lp->ltvRecord.len = 2;
1516 lp->ltvRecord.typ = CFG_CNF_LOAD_BALANCING;
1517 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->loadBalancing );
1518 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1520 /* Medium Distribution */
1521 lp->ltvRecord.len = 2;
1522 lp->ltvRecord.typ = CFG_CNF_MEDIUM_DISTRIBUTION;
1523 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->mediumDistribution );
1524 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1528 /* Tx Power Level (for supported cards) */
1529 lp->ltvRecord.len = 2;
1530 lp->ltvRecord.typ = CFG_CNF_TX_POW_LVL;
1531 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->txPowLevel );
1532 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1534 /* Short Retry Limit */
1535 /*lp->ltvRecord.len = 2;
1536 lp->ltvRecord.typ = 0xFC32;
1537 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->shortRetryLimit );
1538 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1541 /* Long Retry Limit */
1542 /*lp->ltvRecord.len = 2;
1543 lp->ltvRecord.typ = 0xFC33;
1544 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->longRetryLimit );
1545 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1548 /* Supported Rate Set Control */
1549 lp->ltvRecord.len = 3;
1550 lp->ltvRecord.typ = CFG_SUPPORTED_RATE_SET_CNTL; //0xFC88;
1551 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->srsc[0] );
1552 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->srsc[1] );
1553 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1555 /* Basic Rate Set Control */
1556 lp->ltvRecord.len = 3;
1557 lp->ltvRecord.typ = CFG_BASIC_RATE_SET_CNTL; //0xFC89;
1558 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->brsc[0] );
1559 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->brsc[1] );
1560 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1562 /* Frame Burst Limit */
1563 /* Defined, but not currently available in Firmware */
1568 /* Multicast Rate */
1569 lp->ltvRecord.len = 3;
1570 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1571 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1572 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->MulticastRate[1] );
1574 lp->ltvRecord.len = 2;
1575 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1576 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1578 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1580 /* Own Name (Station Nickname) */
1581 if (( len = ( strlen( lp->StationName ) + 1 ) & ~0x01 ) != 0 ) {
1582 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : %s\n",
1583 // lp->StationName );
1585 lp->ltvRecord.len = 2 + ( len / sizeof( hcf_16 ));
1586 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1587 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->StationName ));
1589 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->StationName, len );
1591 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : EMPTY\n" );
1593 lp->ltvRecord.len = 2;
1594 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1595 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1598 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1600 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME result : 0x%04x\n",
1603 /* The following are set in STA mode only */
1604 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1607 lp->ltvRecord.len = 2;
1608 lp->ltvRecord.typ = CFG_RTS_THRH;
1609 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1610 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1613 lp->ltvRecord.len = 2;
1614 lp->ltvRecord.typ = CFG_CNF_PORT_TYPE;
1615 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PortType );
1616 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1618 /* Tx Rate Control */
1620 lp->ltvRecord.len = 3;
1621 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1622 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1623 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1625 lp->ltvRecord.len = 2;
1626 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1627 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1630 //;?skip temporarily to see whether the RID or something else is the problem hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1632 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 2.4GHz : 0x%04x\n",
1633 lp->TxRateControl[0] );
1634 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 5.0GHz : 0x%04x\n",
1635 lp->TxRateControl[1] );
1636 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL result : 0x%04x\n",
1638 /* Power Management */
1639 lp->ltvRecord.len = 2;
1640 lp->ltvRecord.typ = CFG_CNF_PM_ENABLED;
1641 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PMEnabled );
1642 // lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0x8001 );
1643 DBG_TRACE( DbgInfo, "CFG_CNF_PM_ENABLED : 0x%04x\n", lp->PMEnabled );
1644 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1645 /* Multicast Receive */
1646 lp->ltvRecord.len = 2;
1647 lp->ltvRecord.typ = CFG_CNF_MCAST_RX;
1648 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastReceive );
1649 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1651 /* Max Sleep Duration */
1652 lp->ltvRecord.len = 2;
1653 lp->ltvRecord.typ = CFG_CNF_MAX_SLEEP_DURATION;
1654 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MaxSleepDuration );
1655 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1658 lp->ltvRecord.len = 2;
1659 lp->ltvRecord.typ = CFG_CREATE_IBSS;
1660 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->CreateIBSS );
1661 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1664 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1665 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1666 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1667 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : %s\n",
1668 // lp->NetworkName );
1670 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1671 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1672 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1674 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1676 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : ANY\n" );
1678 lp->ltvRecord.len = 2;
1679 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1680 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1683 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1685 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID result : 0x%04x\n",
1687 /* Own ATIM window */
1688 lp->ltvRecord.len = 2;
1689 lp->ltvRecord.typ = CFG_CNF_OWN_ATIM_WINDOW;
1690 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->atimWindow );
1691 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1694 /* Holdover Duration */
1695 lp->ltvRecord.len = 2;
1696 lp->ltvRecord.typ = CFG_CNF_HOLDOVER_DURATION;
1697 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->holdoverDuration );
1698 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1700 /* Promiscuous Mode */
1701 lp->ltvRecord.len = 2;
1702 lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
1703 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->promiscuousMode );
1704 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1706 /* Authentication */
1707 lp->ltvRecord.len = 2;
1708 lp->ltvRecord.typ = CFG_CNF_AUTHENTICATION;
1709 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->authentication );
1710 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1712 /* Connection Control */
1713 lp->ltvRecord.len = 2;
1714 lp->ltvRecord.typ = CFG_CNF_CONNECTION_CNTL;
1715 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->connectionControl );
1716 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1720 /* Probe data rate */
1721 /*lp->ltvRecord.len = 3;
1722 lp->ltvRecord.typ = CFG_PROBE_DATA_RATE;
1723 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->probeDataRates[0] );
1724 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->probeDataRates[1] );
1725 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1727 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 2.4GHz : 0x%04x\n",
1728 lp->probeDataRates[0] );
1729 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 5.0GHz : 0x%04x\n",
1730 lp->probeDataRates[1] );
1731 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE result : 0x%04x\n",
1735 /* The following are set in AP mode only */
1736 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
1737 //;?should we restore this to allow smaller memory footprint
1740 lp->ltvRecord.len = 2;
1741 lp->ltvRecord.typ = CFG_CNF_OWN_DTIM_PERIOD;
1742 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DTIMPeriod );
1743 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1745 /* Multicast PM Buffering */
1746 lp->ltvRecord.len = 2;
1747 lp->ltvRecord.typ = CFG_CNF_MCAST_PM_BUF;
1748 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->multicastPMBuffering );
1749 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1751 /* Reject ANY - Closed System */
1752 lp->ltvRecord.len = 2;
1753 lp->ltvRecord.typ = CFG_CNF_REJECT_ANY;
1754 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RejectAny );
1756 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1758 /* Exclude Unencrypted */
1759 lp->ltvRecord.len = 2;
1760 lp->ltvRecord.typ = CFG_CNF_EXCL_UNENCRYPTED;
1761 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ExcludeUnencrypted );
1763 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1765 /* IntraBSS Relay */
1766 lp->ltvRecord.len = 2;
1767 lp->ltvRecord.typ = CFG_CNF_INTRA_BSS_RELAY;
1768 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->intraBSSRelay );
1769 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1771 /* RTS Threshold 0 */
1772 lp->ltvRecord.len = 2;
1773 lp->ltvRecord.typ = CFG_RTS_THRH0;
1774 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1776 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1778 /* Tx Rate Control 0 */
1780 lp->ltvRecord.len = 3;
1781 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1782 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1783 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1785 lp->ltvRecord.len = 2;
1786 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1787 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1790 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1792 /* Own Beacon Interval */
1793 lp->ltvRecord.len = 2;
1794 lp->ltvRecord.typ = 0xFC31;
1795 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ownBeaconInterval );
1796 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1798 /* Co-Existence Behavior */
1799 lp->ltvRecord.len = 2;
1800 lp->ltvRecord.typ = 0xFCC7;
1801 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->coexistence );
1802 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1806 /* RTS Threshold 1 */
1807 lp->ltvRecord.len = 2;
1808 lp->ltvRecord.typ = CFG_RTS_THRH1;
1809 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].rtsThreshold );
1810 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1812 /* RTS Threshold 2 */
1813 lp->ltvRecord.len = 2;
1814 lp->ltvRecord.typ = CFG_RTS_THRH2;
1815 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].rtsThreshold );
1816 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1819 /* RTS Threshold 3 */
1820 lp->ltvRecord.len = 2;
1821 lp->ltvRecord.typ = CFG_RTS_THRH3;
1822 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].rtsThreshold );
1823 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1826 /* RTS Threshold 4 */
1827 lp->ltvRecord.len = 2;
1828 lp->ltvRecord.typ = CFG_RTS_THRH4;
1829 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].rtsThreshold );
1830 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1833 /* RTS Threshold 5 */
1834 lp->ltvRecord.len = 2;
1835 lp->ltvRecord.typ = CFG_RTS_THRH5;
1836 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].rtsThreshold );
1837 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1839 /* RTS Threshold 6 */
1840 lp->ltvRecord.len = 2;
1841 lp->ltvRecord.typ = CFG_RTS_THRH6;
1842 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].rtsThreshold );
1843 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1845 /* TX Rate Control 1 */
1846 lp->ltvRecord.len = 2;
1847 lp->ltvRecord.typ = CFG_TX_RATE_CNTL1;
1848 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].txRateCntl );
1849 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1851 /* TX Rate Control 2 */
1852 lp->ltvRecord.len = 2;
1853 lp->ltvRecord.typ = CFG_TX_RATE_CNTL2;
1854 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].txRateCntl );
1855 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1857 /* TX Rate Control 3 */
1858 lp->ltvRecord.len = 2;
1859 lp->ltvRecord.typ = CFG_TX_RATE_CNTL3;
1860 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].txRateCntl );
1861 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1863 /* TX Rate Control 4 */
1864 lp->ltvRecord.len = 2;
1865 lp->ltvRecord.typ = CFG_TX_RATE_CNTL4;
1866 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].txRateCntl );
1867 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1869 /* TX Rate Control 5 */
1870 lp->ltvRecord.len = 2;
1871 lp->ltvRecord.typ = CFG_TX_RATE_CNTL5;
1872 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].txRateCntl );
1873 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1875 /* TX Rate Control 6 */
1876 lp->ltvRecord.len = 2;
1877 lp->ltvRecord.typ = CFG_TX_RATE_CNTL6;
1878 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].txRateCntl );
1879 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1883 /* WDS addresses. It's okay to blindly send these parameters, because
1884 the port needs to be enabled, before anything is done with it. */
1887 lp->ltvRecord.len = 4;
1888 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR1;
1890 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[0].wdsAddress, ETH_ALEN );
1891 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1894 lp->ltvRecord.len = 4;
1895 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR2;
1897 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[1].wdsAddress, ETH_ALEN );
1898 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1901 lp->ltvRecord.len = 4;
1902 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR3;
1904 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[2].wdsAddress, ETH_ALEN );
1905 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1908 lp->ltvRecord.len = 4;
1909 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR4;
1911 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[3].wdsAddress, ETH_ALEN );
1912 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1915 lp->ltvRecord.len = 4;
1916 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR5;
1918 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[4].wdsAddress, ETH_ALEN );
1919 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1922 lp->ltvRecord.len = 4;
1923 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR6;
1925 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[5].wdsAddress, ETH_ALEN );
1926 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1927 #endif /* USE_WDS */
1928 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1931 /* Own MAC Address */
1933 DBG_TRACE(DbgInfo, "MAC Address : %pM\n",
1937 if ( WVLAN_VALID_MAC_ADDRESS( lp->MACAddress )) {
1938 /* Make the MAC address valid by:
1939 Clearing the multicast bit
1940 Setting the local MAC address bit
1942 //lp->MACAddress[0] &= ~0x03; //;?why is this commented out already in 720
1943 //lp->MACAddress[0] |= 0x02;
1945 lp->ltvRecord.len = 1 + ( ETH_ALEN / sizeof( hcf_16 ));
1946 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1947 //DBG_TRACE( DbgInfo, "CFG_NIC_MAC_ADDR\n" );
1948 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1950 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_MAC_ADDR\n" );
1951 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1953 /* MAC address is byte aligned, no endian conversion needed */
1954 memcpy( &( lp->ltvRecord.u.u8[0] ), lp->MACAddress, ETH_ALEN );
1955 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1956 //DBG_TRACE( DbgInfo, "CFG_XXX_MAC_ADDR result : 0x%04x\n",
1959 /* Update the MAC address in the netdevice struct */
1960 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN ); //;?what is the purpose of this seemingly complex logic
1963 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1964 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1965 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1966 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : %s\n",
1967 // lp->NetworkName );
1968 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1969 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1970 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1972 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1974 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : ANY\n" );
1975 lp->ltvRecord.len = 2;
1976 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1977 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1980 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1982 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID result : 0x%04x\n",
1984 /* enable/disable encryption */
1985 lp->ltvRecord.len = 2;
1986 lp->ltvRecord.typ = CFG_CNF_ENCRYPTION;
1987 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->EnableEncryption );
1988 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1990 /* Set the Authentication Key Management Suite */
1991 lp->ltvRecord.len = 2;
1992 lp->ltvRecord.typ = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
1993 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->AuthKeyMgmtSuite );
1994 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1996 /* If WEP (or no) keys are being used, write (or clear) them */
1997 if (lp->wext_enc != IW_ENCODE_ALG_TKIP)
1998 wl_set_wep_keys(lp);
2001 /* countryInfo, ltvCountryInfo, CFG_CNF_COUNTRY_INFO */
2003 DBG_LEAVE( DbgInfo );
2006 /*============================================================================*/
2009 /*******************************************************************************
2011 *******************************************************************************
2015 * Load the kernel module.
2024 * an errno value otherwise
2026 ******************************************************************************/
2027 static int __init wl_module_init( void )
2030 /*------------------------------------------------------------------------*/
2032 DBG_FUNC( "wl_module_init" );
2035 /* Convert "standard" PCMCIA parameter pc_debug to a reasonable DebugFlag value.
2036 * NOTE: The values all fall through to the lower values. */
2037 DbgInfo->DebugFlag = 0;
2038 DbgInfo->DebugFlag = DBG_TRACE_ON; //;?get this mess resolved one day
2039 if ( pc_debug ) switch( pc_debug ) {
2041 DbgInfo->DebugFlag |= DBG_DS_ON;
2043 DbgInfo->DebugFlag |= DBG_RX_ON | DBG_TX_ON;
2045 DbgInfo->DebugFlag |= DBG_PARAM_ON;
2047 DbgInfo->DebugFlag |= DBG_TRACE_ON;
2049 DbgInfo->DebugFlag |= DBG_VERBOSE_ON;
2051 DbgInfo->DebugFlag |= DBG_DEFAULTS;
2057 DBG_ENTER( DbgInfo );
2058 printk(KERN_INFO "%s\n", VERSION_INFO);
2059 printk(KERN_INFO "*** Modified for kernel 2.6 by Henk de Groot <pe1dnn@amsat.org>\n");
2060 printk(KERN_INFO "*** Based on 7.18 version by Andrey Borzenkov <arvidjaar@mail.ru> $Revision: 39 $\n");
2063 // ;?#if (HCF_TYPE) & HCF_TYPE_AP
2064 // DBG_PRINT( "Access Point Mode (AP) Support: YES\n" );
2066 // DBG_PRINT( "Access Point Mode (AP) Support: NO\n" );
2067 // #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2069 result = wl_adapter_init_module( );
2070 DBG_LEAVE( DbgInfo );
2073 /*============================================================================*/
2076 /*******************************************************************************
2078 *******************************************************************************
2082 * Unload the kernel module.
2092 ******************************************************************************/
2093 static void __exit wl_module_exit( void )
2095 DBG_FUNC( "wl_module_exit" );
2098 wl_adapter_cleanup_module( );
2099 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
2100 remove_proc_entry( "wlags", NULL ); //;?why so a-symmetric compared to location of create_proc_read_entry
2103 DBG_LEAVE( DbgInfo );
2106 /*============================================================================*/
2108 module_init(wl_module_init);
2109 module_exit(wl_module_exit);
2111 /*******************************************************************************
2113 *******************************************************************************
2117 * The Interrupt Service Routine for the driver.
2121 * irq - the irq the interrupt came in on
2122 * dev_id - a buffer containing information about the request
2129 ******************************************************************************/
2130 irqreturn_t wl_isr( int irq, void *dev_id, struct pt_regs *regs )
2133 struct net_device *dev = (struct net_device *) dev_id;
2134 struct wl_private *lp = NULL;
2135 /*------------------------------------------------------------------------*/
2136 if (( dev == NULL ) || ( !netif_device_present( dev ))) {
2140 /* Set the wl_private pointer (lp), now that we know that dev is non-null */
2144 if ( lp->useRTS == 1 ) {
2145 DBG_PRINT( "EXITING ISR, IN RTS MODE...\n" );
2148 #endif /* USE_RTS */
2150 /* If we have interrupts pending, then put them on a system task
2151 queue. Otherwise turn interrupts back on */
2152 events = hcf_action( &lp->hcfCtx, HCF_ACT_INT_OFF );
2154 if ( events == HCF_INT_PENDING ) {
2155 /* Schedule the ISR handler as a bottom-half task in the
2156 tq_immediate queue */
2157 tasklet_schedule(&lp->task);
2159 //DBG_PRINT( "NOT OUR INTERRUPT\n" );
2160 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2163 return IRQ_RETVAL(events == HCF_INT_PENDING);
2165 /*============================================================================*/
2168 /*******************************************************************************
2170 *******************************************************************************
2174 * The ISR handler, scheduled to run in a deferred context by the ISR. This
2175 * is where the ISR's work actually gets done.
2179 * lp - a pointer to the device's private adapter structure
2185 ******************************************************************************/
2186 #define WVLAN_MAX_INT_SERVICES 50
2188 void wl_isr_handler( unsigned long p )
2190 struct net_device *dev;
2191 unsigned long flags;
2195 struct wl_private *lp = (struct wl_private *)p;
2196 /*------------------------------------------------------------------------*/
2199 DBG_PRINT( "wl_isr_handler lp adapter pointer is NULL!!!\n" );
2201 wl_lock( lp, &flags );
2203 dev = (struct net_device *)lp->dev;
2204 if ( dev != NULL && netif_device_present( dev ) ) stop = FALSE;
2205 for( count = 0; stop == FALSE && count < WVLAN_MAX_INT_SERVICES; count++ ) {
2207 result = hcf_service_nic( &lp->hcfCtx,
2208 (wci_bufp)lp->lookAheadBuf,
2209 sizeof( lp->lookAheadBuf ));
2210 if ( result == HCF_ERR_MIC ) {
2211 wl_wext_event_mic_failed( dev ); /* Send an event that MIC failed */
2212 //;?this seems wrong if HCF_ERR_MIC coincides with another event, stop gets FALSE
2213 //so why not do it always ;?
2216 #ifndef USE_MBOX_SYNC
2217 if ( lp->hcfCtx.IFB_MBInfoLen != 0 ) { /* anything in the mailbox */
2222 /* Check for a Link status event */
2223 if ( ( lp->hcfCtx.IFB_LinkStat & CFG_LINK_STAT_FW ) != 0 ) {
2224 wl_process_link_status( lp );
2227 /* Check for probe response events */
2228 if ( lp->ProbeResp.infoType != 0 &&
2229 lp->ProbeResp.infoType != 0xFFFF ) {
2230 wl_process_probe_response( lp );
2231 memset( &lp->ProbeResp, 0, sizeof( lp->ProbeResp ));
2232 lp->ProbeResp.infoType = 0xFFFF;
2235 /* Check for updated record events */
2236 if ( lp->updatedRecord.len != 0xFFFF ) {
2237 wl_process_updated_record( lp );
2238 lp->updatedRecord.len = 0xFFFF;
2241 /* Check for association status events */
2242 if ( lp->assoc_stat.len != 0xFFFF ) {
2243 wl_process_assoc_status( lp );
2244 lp->assoc_stat.len = 0xFFFF;
2247 /* Check for security status events */
2248 if ( lp->sec_stat.len != 0xFFFF ) {
2249 wl_process_security_status( lp );
2250 lp->sec_stat.len = 0xFFFF;
2255 if ( lp->use_dma ) {
2256 /* Check for DMA Rx packets */
2257 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_RDMAD ) {
2261 /* Return Tx DMA descriptors to host */
2262 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_TDMAD ) {
2263 wl_pci_dma_hcf_reclaim_tx( lp );
2268 #endif // ENABLE_DMA
2270 /* Check for Rx packets */
2271 if ( lp->hcfCtx.IFB_RxLen != 0 ) {
2275 /* Make sure that queued frames get sent */
2276 if ( wl_send( lp )) {
2281 /* We're done, so turn interrupts which were turned off in wl_isr, back on */
2282 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2283 wl_unlock( lp, &flags );
2287 /*============================================================================*/
2290 /*******************************************************************************
2292 *******************************************************************************
2296 * Notify the adapter that it has been removed. Since the adapter is gone,
2297 * we should no longer try to talk to it.
2301 * dev - a pointer to the device's net_device structure
2307 ******************************************************************************/
2308 void wl_remove( struct net_device *dev )
2310 struct wl_private *lp = wl_priv(dev);
2311 unsigned long flags;
2312 /*------------------------------------------------------------------------*/
2313 DBG_FUNC( "wl_remove" );
2314 DBG_ENTER( DbgInfo );
2316 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2318 wl_lock( lp, &flags );
2320 /* stop handling interrupts */
2321 wl_act_int_off( lp );
2322 lp->is_handling_int = WL_NOT_HANDLING_INT;
2325 * Disable the ports: just change state: since the
2326 * card is gone it is useless to talk to it and at
2327 * disconnect all state information is lost anyway.
2329 /* Reset portState */
2330 lp->portState = WVLAN_PORT_STATE_DISABLED;
2332 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
2334 //wl_disable_wds_ports( lp );
2336 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2338 /* Mark the device as unregistered */
2339 lp->is_registered = FALSE;
2341 /* Deregister the WDS ports as well */
2342 WL_WDS_NETDEV_DEREGISTER( lp );
2344 if ( lp->useRTS == 1 ) {
2345 wl_unlock( lp, &flags );
2347 DBG_LEAVE( DbgInfo );
2350 #endif /* USE_RTS */
2352 /* Inform the HCF that the card has been removed */
2353 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2355 wl_unlock( lp, &flags );
2357 DBG_LEAVE( DbgInfo );
2360 /*============================================================================*/
2363 /*******************************************************************************
2365 *******************************************************************************
2369 * Power-down and halt the adapter.
2373 * dev - a pointer to the device's net_device structure
2379 ******************************************************************************/
2380 void wl_suspend( struct net_device *dev )
2382 struct wl_private *lp = wl_priv(dev);
2383 unsigned long flags;
2384 /*------------------------------------------------------------------------*/
2385 DBG_FUNC( "wl_suspend" );
2386 DBG_ENTER( DbgInfo );
2388 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2390 /* The adapter is suspended:
2394 wl_lock( lp, &flags );
2396 /* Disable interrupt handling */
2397 wl_act_int_off( lp );
2400 wl_disconnect( lp );
2405 /* Disconnect from the adapter */
2406 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2408 /* Reset portState to be sure (should have been done by wl_disable */
2409 lp->portState = WVLAN_PORT_STATE_DISABLED;
2411 wl_unlock( lp, &flags );
2413 DBG_LEAVE( DbgInfo );
2416 /*============================================================================*/
2419 /*******************************************************************************
2421 *******************************************************************************
2425 * Resume a previously suspended adapter.
2429 * dev - a pointer to the device's net_device structure
2435 ******************************************************************************/
2436 void wl_resume(struct net_device *dev)
2438 struct wl_private *lp = wl_priv(dev);
2439 unsigned long flags;
2440 /*------------------------------------------------------------------------*/
2441 DBG_FUNC( "wl_resume" );
2442 DBG_ENTER( DbgInfo );
2444 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2446 wl_lock( lp, &flags );
2448 /* Connect to the adapter */
2449 hcf_connect( &lp->hcfCtx, dev->base_addr );
2451 /* Reset portState */
2452 lp->portState = WVLAN_PORT_STATE_DISABLED;
2454 /* Power might have been off, assume the card lost the firmware*/
2455 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
2457 /* Reload the firmware and restart */
2460 /* Resume interrupt handling */
2461 wl_act_int_on( lp );
2463 wl_unlock( lp, &flags );
2465 DBG_LEAVE( DbgInfo );
2468 /*============================================================================*/
2471 /*******************************************************************************
2473 *******************************************************************************
2477 * This function performs a check on the device and calls wl_remove() if
2478 * necessary. This function can be used for all bus types, but exists mostly
2479 * for the benefit of the Card Services driver, as there are times when
2480 * wl_remove() does not get called.
2484 * dev - a pointer to the device's net_device structure
2490 ******************************************************************************/
2491 void wl_release( struct net_device *dev )
2493 struct wl_private *lp = wl_priv(dev);
2494 /*------------------------------------------------------------------------*/
2495 DBG_FUNC( "wl_release" );
2496 DBG_ENTER( DbgInfo );
2498 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2499 /* If wl_remove() hasn't been called (i.e. when Card Services is shut
2500 down with the card in the slot), then call it */
2501 if ( lp->is_registered == TRUE ) {
2502 DBG_TRACE( DbgInfo, "Calling unregister_netdev(), as it wasn't called yet\n" );
2505 lp->is_registered = FALSE;
2508 DBG_LEAVE( DbgInfo );
2511 /*============================================================================*/
2514 /*******************************************************************************
2516 *******************************************************************************
2520 * Accessor function to retrieve the irq_mask module parameter
2528 * The irq_mask module parameter
2530 ******************************************************************************/
2531 p_u16 wl_get_irq_mask( void )
2534 } // wl_get_irq_mask
2535 /*============================================================================*/
2538 /*******************************************************************************
2540 *******************************************************************************
2544 * Accessor function to retrieve the irq_list module parameter
2552 * The irq_list module parameter
2554 ******************************************************************************/
2555 p_s8 * wl_get_irq_list( void )
2558 } // wl_get_irq_list
2559 /*============================================================================*/
2563 /*******************************************************************************
2565 *******************************************************************************
2569 * Used to enable MAC ports
2573 * lp - pointer to the device's private adapter structure
2579 ******************************************************************************/
2580 int wl_enable( struct wl_private *lp )
2582 int hcf_status = HCF_SUCCESS;
2583 /*------------------------------------------------------------------------*/
2584 DBG_FUNC( "wl_enable" );
2585 DBG_ENTER( DbgInfo );
2587 if ( lp->portState == WVLAN_PORT_STATE_ENABLED ) {
2588 DBG_TRACE( DbgInfo, "No action: Card already enabled\n" );
2589 } else if ( lp->portState == WVLAN_PORT_STATE_CONNECTED ) {
2590 //;?suspicuous logic, how can you be connected without being enabled so this is probably dead code
2591 DBG_TRACE( DbgInfo, "No action: Card already connected\n" );
2593 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_ENABLE );
2594 if ( hcf_status == HCF_SUCCESS ) {
2595 /* Set the status of the NIC to enabled */
2596 lp->portState = WVLAN_PORT_STATE_ENABLED; //;?bad mnemonic, NIC iso PORT
2598 if ( lp->use_dma ) {
2599 wl_pci_dma_hcf_supply( lp ); //;?always successful?
2604 if ( hcf_status != HCF_SUCCESS ) { //;?make this an assert
2605 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2607 DBG_LEAVE( DbgInfo );
2610 /*============================================================================*/
2614 /*******************************************************************************
2615 * wl_enable_wds_ports()
2616 *******************************************************************************
2620 * Used to enable the WDS MAC ports 1-6
2624 * lp - pointer to the device's private adapter structure
2630 ******************************************************************************/
2631 void wl_enable_wds_ports( struct wl_private * lp )
2634 DBG_FUNC( "wl_enable_wds_ports" );
2635 DBG_ENTER( DbgInfo );
2636 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2637 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2639 DBG_LEAVE( DbgInfo );
2641 } // wl_enable_wds_ports
2642 #endif /* USE_WDS */
2643 /*============================================================================*/
2646 /*******************************************************************************
2648 *******************************************************************************
2652 * Used to connect a MAC port
2656 * lp - pointer to the device's private adapter structure
2662 ******************************************************************************/
2663 int wl_connect( struct wl_private *lp )
2666 /*------------------------------------------------------------------------*/
2668 DBG_FUNC( "wl_connect" );
2669 DBG_ENTER( DbgInfo );
2671 if ( lp->portState != WVLAN_PORT_STATE_ENABLED ) {
2672 DBG_TRACE( DbgInfo, "No action: Not in enabled state\n" );
2673 DBG_LEAVE( DbgInfo );
2676 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_CONNECT );
2677 if ( hcf_status == HCF_SUCCESS ) {
2678 lp->portState = WVLAN_PORT_STATE_CONNECTED;
2680 DBG_LEAVE( DbgInfo );
2683 /*============================================================================*/
2686 /*******************************************************************************
2688 *******************************************************************************
2692 * Used to disconnect a MAC port
2696 * lp - pointer to the device's private adapter structure
2702 ******************************************************************************/
2703 int wl_disconnect( struct wl_private *lp )
2706 /*------------------------------------------------------------------------*/
2708 DBG_FUNC( "wl_disconnect" );
2709 DBG_ENTER( DbgInfo );
2711 if ( lp->portState != WVLAN_PORT_STATE_CONNECTED ) {
2712 DBG_TRACE( DbgInfo, "No action: Not in connected state\n" );
2713 DBG_LEAVE( DbgInfo );
2716 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISCONNECT );
2717 if ( hcf_status == HCF_SUCCESS ) {
2718 lp->portState = WVLAN_PORT_STATE_ENABLED;
2720 DBG_LEAVE( DbgInfo );
2723 /*============================================================================*/
2726 /*******************************************************************************
2728 *******************************************************************************
2732 * Used to disable MAC ports
2736 * lp - pointer to the device's private adapter structure
2737 * port - the MAC port to disable
2743 ******************************************************************************/
2744 int wl_disable( struct wl_private *lp )
2746 int hcf_status = HCF_SUCCESS;
2747 /*------------------------------------------------------------------------*/
2748 DBG_FUNC( "wl_disable" );
2749 DBG_ENTER( DbgInfo );
2751 if ( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
2752 DBG_TRACE( DbgInfo, "No action: Port state is disabled\n" );
2754 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISABLE );
2755 if ( hcf_status == HCF_SUCCESS ) {
2756 /* Set the status of the port to disabled */ //;?bad mnemonic use NIC iso PORT
2757 lp->portState = WVLAN_PORT_STATE_DISABLED;
2760 if ( lp->use_dma ) {
2761 wl_pci_dma_hcf_reclaim( lp );
2766 if ( hcf_status != HCF_SUCCESS ) {
2767 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2769 DBG_LEAVE( DbgInfo );
2772 /*============================================================================*/
2776 /*******************************************************************************
2777 * wl_disable_wds_ports()
2778 *******************************************************************************
2782 * Used to disable the WDS MAC ports 1-6
2786 * lp - pointer to the device's private adapter structure
2792 ******************************************************************************/
2793 void wl_disable_wds_ports( struct wl_private * lp )
2796 DBG_FUNC( "wl_disable_wds_ports" );
2797 DBG_ENTER( DbgInfo );
2799 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2800 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2802 // if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
2803 // wl_disable( lp, HCF_PORT_1 );
2804 // wl_disable( lp, HCF_PORT_2 );
2805 // wl_disable( lp, HCF_PORT_3 );
2806 // wl_disable( lp, HCF_PORT_4 );
2807 // wl_disable( lp, HCF_PORT_5 );
2808 // wl_disable( lp, HCF_PORT_6 );
2810 DBG_LEAVE( DbgInfo );
2812 } // wl_disable_wds_ports
2814 /*============================================================================*/
2817 #ifndef USE_MBOX_SYNC
2818 /*******************************************************************************
2820 *******************************************************************************
2823 * This function is used to read and process a mailbox message.
2828 * lp - pointer to the device's private adapter structure
2832 * an HCF status code
2834 ******************************************************************************/
2835 int wl_mbx( struct wl_private *lp )
2837 int hcf_status = HCF_SUCCESS;
2838 /*------------------------------------------------------------------------*/
2839 DBG_FUNC( "wl_mbx" );
2840 DBG_ENTER( DbgInfo );
2841 DBG_TRACE( DbgInfo, "Mailbox Info: IFB_MBInfoLen: %d\n",
2842 lp->hcfCtx.IFB_MBInfoLen );
2844 memset( &( lp->ltvRecord ), 0, sizeof( ltv_t ));
2846 lp->ltvRecord.len = MB_SIZE;
2847 lp->ltvRecord.typ = CFG_MB_INFO;
2848 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2850 if ( hcf_status != HCF_SUCCESS ) {
2851 DBG_ERROR( DbgInfo, "hcf_get_info returned 0x%x\n", hcf_status );
2853 DBG_LEAVE( DbgInfo );
2857 if ( lp->ltvRecord.typ == CFG_MB_INFO ) {
2858 DBG_LEAVE( DbgInfo );
2861 /* Endian translate the mailbox data, then process the message */
2862 wl_endian_translate_mailbox( &( lp->ltvRecord ));
2863 wl_process_mailbox( lp );
2864 DBG_LEAVE( DbgInfo );
2867 /*============================================================================*/
2870 /*******************************************************************************
2871 * wl_endian_translate_mailbox()
2872 *******************************************************************************
2876 * This function will perform the tedious task of endian translating all
2877 * fields within a mailbox message which need translating.
2881 * ltv - pointer to the LTV to endian translate
2887 ******************************************************************************/
2888 void wl_endian_translate_mailbox( ltv_t *ltv )
2891 DBG_FUNC( "wl_endian_translate_mailbox" );
2892 DBG_ENTER( DbgInfo );
2893 switch( ltv->typ ) {
2900 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
2902 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2903 ( sizeof( SCAN_RS_STRCT )));
2905 while( num_aps >= 1 ) {
2908 aps[num_aps].channel_id =
2909 CNV_LITTLE_TO_INT( aps[num_aps].channel_id );
2911 aps[num_aps].noise_level =
2912 CNV_LITTLE_TO_INT( aps[num_aps].noise_level );
2914 aps[num_aps].signal_level =
2915 CNV_LITTLE_TO_INT( aps[num_aps].signal_level );
2917 aps[num_aps].beacon_interval_time =
2918 CNV_LITTLE_TO_INT( aps[num_aps].beacon_interval_time );
2920 aps[num_aps].capability =
2921 CNV_LITTLE_TO_INT( aps[num_aps].capability );
2923 aps[num_aps].ssid_len =
2924 CNV_LITTLE_TO_INT( aps[num_aps].ssid_len );
2926 aps[num_aps].ssid_val[aps[num_aps].ssid_len] = 0;
2933 PROBE_RESP *probe_resp = (PROBE_RESP *)ltv;
2935 probe_resp->frameControl = CNV_LITTLE_TO_INT( probe_resp->frameControl );
2936 probe_resp->durID = CNV_LITTLE_TO_INT( probe_resp->durID );
2937 probe_resp->sequence = CNV_LITTLE_TO_INT( probe_resp->sequence );
2938 probe_resp->dataLength = CNV_LITTLE_TO_INT( probe_resp->dataLength );
2940 probe_resp->lenType = CNV_LITTLE_TO_INT( probe_resp->lenType );
2942 probe_resp->beaconInterval = CNV_LITTLE_TO_INT( probe_resp->beaconInterval );
2943 probe_resp->capability = CNV_LITTLE_TO_INT( probe_resp->capability );
2944 probe_resp->flags = CNV_LITTLE_TO_INT( probe_resp->flags );
2949 #define ls ((LINK_STATUS_STRCT *)ltv)
2950 ls->linkStatus = CNV_LITTLE_TO_INT( ls->linkStatus );
2954 case CFG_ASSOC_STAT:
2956 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
2958 as->assocStatus = CNV_LITTLE_TO_INT( as->assocStatus );
2962 case CFG_SECURITY_STAT:
2964 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
2966 ss->securityStatus = CNV_LITTLE_TO_INT( ss->securityStatus );
2967 ss->reason = CNV_LITTLE_TO_INT( ss->reason );
2981 DBG_LEAVE( DbgInfo );
2983 } // wl_endian_translate_mailbox
2984 /*============================================================================*/
2986 /*******************************************************************************
2987 * wl_process_mailbox()
2988 *******************************************************************************
2992 * This function processes the mailbox data.
2996 * ltv - pointer to the LTV to be processed.
3002 ******************************************************************************/
3003 void wl_process_mailbox( struct wl_private *lp )
3006 hcf_16 ltv_val = 0xFFFF;
3007 /*------------------------------------------------------------------------*/
3008 DBG_FUNC( "wl_process_mailbox" );
3009 DBG_ENTER( DbgInfo );
3010 ltv = &( lp->ltvRecord );
3012 switch( ltv->typ ) {
3015 DBG_TRACE( DbgInfo, "CFG_TALLIES\n" );
3018 DBG_TRACE( DbgInfo, "CFG_SCAN\n" );
3022 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
3024 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
3025 ( sizeof( SCAN_RS_STRCT )));
3027 lp->scan_results.num_aps = num_aps;
3029 DBG_TRACE( DbgInfo, "Number of APs: %d\n", num_aps );
3031 while( num_aps >= 1 ) {
3034 DBG_TRACE( DbgInfo, "AP : %d\n", num_aps );
3035 DBG_TRACE( DbgInfo, "=========================\n" );
3036 DBG_TRACE( DbgInfo, "Channel ID : 0x%04x\n",
3037 aps[num_aps].channel_id );
3038 DBG_TRACE( DbgInfo, "Noise Level : 0x%04x\n",
3039 aps[num_aps].noise_level );
3040 DBG_TRACE( DbgInfo, "Signal Level : 0x%04x\n",
3041 aps[num_aps].signal_level );
3042 DBG_TRACE( DbgInfo, "Beacon Interval : 0x%04x\n",
3043 aps[num_aps].beacon_interval_time );
3044 DBG_TRACE( DbgInfo, "Capability : 0x%04x\n",
3045 aps[num_aps].capability );
3046 DBG_TRACE( DbgInfo, "SSID Length : 0x%04x\n",
3047 aps[num_aps].ssid_len );
3048 DBG_TRACE(DbgInfo, "BSSID : %pM\n",
3049 aps[num_aps].bssid);
3051 if ( aps[num_aps].ssid_len != 0 ) {
3052 DBG_TRACE( DbgInfo, "SSID : %s.\n",
3053 aps[num_aps].ssid_val );
3055 DBG_TRACE( DbgInfo, "SSID : %s.\n", "ANY" );
3058 DBG_TRACE( DbgInfo, "\n" );
3060 /* Copy the info to the ScanResult structure in the private
3062 memcpy( &( lp->scan_results.APTable[num_aps]), &( aps[num_aps] ),
3063 sizeof( SCAN_RS_STRCT ));
3066 /* Set scan result to true so that any scan requests will
3068 lp->scan_results.scan_complete = TRUE;
3073 DBG_TRACE( DbgInfo, "CFG_ACS_SCAN\n" );
3076 PROBE_RESP *probe_rsp = (PROBE_RESP *)ltv;
3077 hcf_8 *wpa_ie = NULL;
3078 hcf_16 wpa_ie_len = 0;
3080 DBG_TRACE( DbgInfo, "(%s) =========================\n",
3083 DBG_TRACE( DbgInfo, "(%s) length : 0x%04x.\n",
3084 lp->dev->name, probe_rsp->length );
3086 if ( probe_rsp->length > 1 ) {
3087 DBG_TRACE( DbgInfo, "(%s) infoType : 0x%04x.\n",
3088 lp->dev->name, probe_rsp->infoType );
3090 DBG_TRACE( DbgInfo, "(%s) signal : 0x%02x.\n",
3091 lp->dev->name, probe_rsp->signal );
3093 DBG_TRACE( DbgInfo, "(%s) silence : 0x%02x.\n",
3094 lp->dev->name, probe_rsp->silence );
3096 DBG_TRACE( DbgInfo, "(%s) rxFlow : 0x%02x.\n",
3097 lp->dev->name, probe_rsp->rxFlow );
3099 DBG_TRACE( DbgInfo, "(%s) rate : 0x%02x.\n",
3100 lp->dev->name, probe_rsp->rate );
3102 DBG_TRACE( DbgInfo, "(%s) frame cntl : 0x%04x.\n",
3103 lp->dev->name, probe_rsp->frameControl );
3105 DBG_TRACE( DbgInfo, "(%s) durID : 0x%04x.\n",
3106 lp->dev->name, probe_rsp->durID );
3108 DBG_TRACE(DbgInfo, "(%s) address1 : %pM\n",
3109 lp->dev->name, probe_rsp->address1);
3111 DBG_TRACE(DbgInfo, "(%s) address2 : %pM\n",
3112 lp->dev->name, probe_rsp->address2);
3114 DBG_TRACE(DbgInfo, "(%s) BSSID : %pM\n",
3115 lp->dev->name, probe_rsp->BSSID);
3117 DBG_TRACE( DbgInfo, "(%s) sequence : 0x%04x.\n",
3118 lp->dev->name, probe_rsp->sequence );
3120 DBG_TRACE(DbgInfo, "(%s) address4 : %pM\n",
3121 lp->dev->name, probe_rsp->address4);
3123 DBG_TRACE( DbgInfo, "(%s) datalength : 0x%04x.\n",
3124 lp->dev->name, probe_rsp->dataLength );
3126 DBG_TRACE(DbgInfo, "(%s) DA : %pM\n",
3127 lp->dev->name, probe_rsp->DA);
3129 DBG_TRACE(DbgInfo, "(%s) SA : %pM\n",
3130 lp->dev->name, probe_rsp->SA);
3132 //DBG_TRACE( DbgInfo, "(%s) lenType : 0x%04x.\n",
3133 // lp->dev->name, probe_rsp->lenType );
3135 DBG_TRACE(DbgInfo, "(%s) timeStamp : "
3136 "%d.%d.%d.%d.%d.%d.%d.%d\n",
3138 probe_rsp->timeStamp[0],
3139 probe_rsp->timeStamp[1],
3140 probe_rsp->timeStamp[2],
3141 probe_rsp->timeStamp[3],
3142 probe_rsp->timeStamp[4],
3143 probe_rsp->timeStamp[5],
3144 probe_rsp->timeStamp[6],
3145 probe_rsp->timeStamp[7]);
3147 DBG_TRACE( DbgInfo, "(%s) beaconInt : 0x%04x.\n",
3148 lp->dev->name, probe_rsp->beaconInterval );
3150 DBG_TRACE( DbgInfo, "(%s) capability : 0x%04x.\n",
3151 lp->dev->name, probe_rsp->capability );
3153 DBG_TRACE( DbgInfo, "(%s) SSID len : 0x%04x.\n",
3154 lp->dev->name, probe_rsp->rawData[1] );
3156 if ( probe_rsp->rawData[1] > 0 ) {
3157 char ssid[HCF_MAX_NAME_LEN];
3159 memset( ssid, 0, sizeof( ssid ));
3160 strncpy( ssid, &probe_rsp->rawData[2],
3161 probe_rsp->rawData[1] );
3163 DBG_TRACE( DbgInfo, "(%s) SSID : %s\n",
3164 lp->dev->name, ssid );
3167 /* Parse out the WPA-IE, if one exists */
3168 wpa_ie = wl_parse_wpa_ie( probe_rsp, &wpa_ie_len );
3169 if ( wpa_ie != NULL ) {
3170 DBG_TRACE( DbgInfo, "(%s) WPA-IE : %s\n",
3171 lp->dev->name, wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
3174 DBG_TRACE( DbgInfo, "(%s) flags : 0x%04x.\n",
3175 lp->dev->name, probe_rsp->flags );
3178 DBG_TRACE( DbgInfo, "\n\n" );
3179 /* If probe response length is 1, then the scan is complete */
3180 if ( probe_rsp->length == 1 ) {
3181 DBG_TRACE( DbgInfo, "SCAN COMPLETE\n" );
3182 lp->probe_results.num_aps = lp->probe_num_aps;
3183 lp->probe_results.scan_complete = TRUE;
3185 /* Reset the counter for the next scan request */
3186 lp->probe_num_aps = 0;
3188 /* Send a wireless extensions event that the scan completed */
3189 wl_wext_event_scan_complete( lp->dev );
3191 /* Only copy to the table if the entry is unique; APs sometimes
3192 respond more than once to a probe */
3193 if ( lp->probe_num_aps == 0 ) {
3194 /* Copy the info to the ScanResult structure in the private
3196 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3197 probe_rsp, sizeof( PROBE_RESP ));
3199 /* Increment the number of APs detected */
3200 lp->probe_num_aps++;
3205 for( count = 0; count < lp->probe_num_aps; count++ ) {
3206 if ( memcmp( &( probe_rsp->BSSID ),
3207 lp->probe_results.ProbeTable[count].BSSID,
3214 /* Copy the info to the ScanResult structure in the
3215 private adapter struct. Only copy if there's room in the
3217 if ( lp->probe_num_aps < MAX_NAPS )
3219 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3220 probe_rsp, sizeof( PROBE_RESP ));
3224 DBG_WARNING( DbgInfo, "Num of scan results exceeds storage, truncating\n" );
3227 /* Increment the number of APs detected. Note I do this
3228 here even when I don't copy the probe response to the
3229 buffer in order to detect the overflow condition */
3230 lp->probe_num_aps++;
3239 #define ls ((LINK_STATUS_STRCT *)ltv)
3240 DBG_TRACE( DbgInfo, "CFG_LINK_STAT\n" );
3242 switch( ls->linkStatus ) {
3244 DBG_TRACE( DbgInfo, "Link Status : Connected\n" );
3245 wl_wext_event_ap( lp->dev );
3249 DBG_TRACE( DbgInfo, "Link Status : Disconnected\n" );
3253 DBG_TRACE( DbgInfo, "Link Status : Access Point Change\n" );
3257 DBG_TRACE( DbgInfo, "Link Status : Access Point Out of Range\n" );
3261 DBG_TRACE( DbgInfo, "Link Status : Access Point In Range\n" );
3265 DBG_TRACE( DbgInfo, "Link Status : UNKNOWN (0x%04x)\n",
3273 case CFG_ASSOC_STAT:
3274 DBG_TRACE( DbgInfo, "CFG_ASSOC_STAT\n" );
3277 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
3279 switch( as->assocStatus ) {
3281 DBG_TRACE( DbgInfo, "Association Status : STA Associated\n" );
3285 DBG_TRACE( DbgInfo, "Association Status : STA Reassociated\n" );
3289 DBG_TRACE( DbgInfo, "Association Status : STA Disassociated\n" );
3293 DBG_TRACE( DbgInfo, "Association Status : UNKNOWN (0x%04x)\n",
3298 DBG_TRACE(DbgInfo, "STA Address : %pM\n",
3301 if (( as->assocStatus == 2 ) && ( as->len == 8 )) {
3302 DBG_TRACE(DbgInfo, "Old AP Address : %pM\n",
3309 case CFG_SECURITY_STAT:
3310 DBG_TRACE( DbgInfo, "CFG_SECURITY_STAT\n" );
3313 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
3315 switch( ss->securityStatus ) {
3317 DBG_TRACE( DbgInfo, "Security Status : Dissassociate [AP]\n" );
3321 DBG_TRACE( DbgInfo, "Security Status : Deauthenticate [AP]\n" );
3325 DBG_TRACE( DbgInfo, "Security Status : Authenticate Fail [STA] or [AP]\n" );
3329 DBG_TRACE( DbgInfo, "Security Status : MIC Fail\n" );
3333 DBG_TRACE( DbgInfo, "Security Status : Associate Fail\n" );
3337 DBG_TRACE( DbgInfo, "Security Status : UNKNOWN %d\n",
3338 ss->securityStatus );
3342 DBG_TRACE(DbgInfo, "STA Address : %pM\n",
3345 DBG_TRACE(DbgInfo, "Reason : 0x%04x\n",
3352 DBG_TRACE( DbgInfo, "CFG_WMP, size is %d bytes\n", ltv->len );
3354 WMP_RSP_STRCT *wmp_rsp = (WMP_RSP_STRCT *)ltv;
3356 DBG_TRACE( DbgInfo, "CFG_WMP, pdu type is 0x%x\n",
3357 wmp_rsp->wmpRsp.wmpHdr.type );
3359 switch( wmp_rsp->wmpRsp.wmpHdr.type ) {
3360 case WVLAN_WMP_PDU_TYPE_LT_RSP:
3363 LINKTEST_RSP_STRCT *lt_rsp = (LINKTEST_RSP_STRCT *)ltv;
3365 DBG_TRACE( DbgInfo, "LINK TEST RESULT\n" );
3366 DBG_TRACE( DbgInfo, "================\n" );
3367 DBG_TRACE( DbgInfo, "Length : %d.\n", lt_rsp->len );
3369 DBG_TRACE( DbgInfo, "Name : %s.\n", lt_rsp->ltRsp.ltRsp.name );
3370 DBG_TRACE( DbgInfo, "Signal Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.signal );
3371 DBG_TRACE( DbgInfo, "Noise Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.noise );
3372 DBG_TRACE( DbgInfo, "Receive Flow : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.rxFlow );
3373 DBG_TRACE( DbgInfo, "Data Rate : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRate );
3374 DBG_TRACE( DbgInfo, "Protocol : 0x%04x.\n", lt_rsp->ltRsp.ltRsp.protocol );
3375 DBG_TRACE( DbgInfo, "Station : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.station );
3376 DBG_TRACE( DbgInfo, "Data Rate Cap : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRateCap );
3378 DBG_TRACE( DbgInfo, "Power Mgmt : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3379 lt_rsp->ltRsp.ltRsp.powerMgmt[0],
3380 lt_rsp->ltRsp.ltRsp.powerMgmt[1],
3381 lt_rsp->ltRsp.ltRsp.powerMgmt[2],
3382 lt_rsp->ltRsp.ltRsp.powerMgmt[3] );
3384 DBG_TRACE( DbgInfo, "Robustness : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3385 lt_rsp->ltRsp.ltRsp.robustness[0],
3386 lt_rsp->ltRsp.ltRsp.robustness[1],
3387 lt_rsp->ltRsp.ltRsp.robustness[2],
3388 lt_rsp->ltRsp.ltRsp.robustness[3] );
3390 DBG_TRACE( DbgInfo, "Scaling : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.scaling );
3403 DBG_TRACE( DbgInfo, "CFG_NULL\n" );
3406 case CFG_UPDATED_INFO_RECORD: // Updated Information Record
3407 DBG_TRACE( DbgInfo, "UPDATED INFORMATION RECORD\n" );
3409 ltv_val = CNV_INT_TO_LITTLE( ltv->u.u16[0] );
3411 /* Check and see which RID was updated */
3413 case CFG_CUR_COUNTRY_INFO: // Indicate Passive Scan Completion
3414 DBG_TRACE( DbgInfo, "Updated country info\n" );
3416 /* Do I need to hold off on updating RIDs until the process is
3421 case CFG_PORT_STAT: // Wait for Connect Event
3427 DBG_WARNING( DbgInfo, "Unknown RID: 0x%04x\n", ltv_val );
3433 DBG_TRACE( DbgInfo, "UNKNOWN MESSAGE: 0x%04x\n", ltv->typ );
3436 DBG_LEAVE( DbgInfo );
3438 } // wl_process_mailbox
3439 /*============================================================================*/
3440 #endif /* ifndef USE_MBOX_SYNC */
3443 /*******************************************************************************
3444 * wl_wds_netdev_register()
3445 *******************************************************************************
3449 * This function registers net_device structures with the system's network
3450 * layer for use with the WDS ports.
3455 * lp - pointer to the device's private adapter structure
3461 ******************************************************************************/
3462 void wl_wds_netdev_register( struct wl_private *lp )
3465 /*------------------------------------------------------------------------*/
3466 DBG_FUNC( "wl_wds_netdev_register" );
3467 DBG_ENTER( DbgInfo );
3468 //;?why is there no USE_WDS clause like in wl_enable_wds_ports
3469 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3470 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3471 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3472 if ( register_netdev( lp->wds_port[count].dev ) != 0 ) {
3473 DBG_WARNING( DbgInfo, "net device for WDS port %d could not be registered\n",
3476 lp->wds_port[count].is_registered = TRUE;
3478 /* Fill out the net_device structs with the MAC addr */
3479 memcpy( lp->wds_port[count].dev->dev_addr, lp->MACAddress, ETH_ALEN );
3480 lp->wds_port[count].dev->addr_len = ETH_ALEN;
3484 DBG_LEAVE( DbgInfo );
3486 } // wl_wds_netdev_register
3487 /*============================================================================*/
3490 /*******************************************************************************
3491 * wl_wds_netdev_deregister()
3492 *******************************************************************************
3496 * This function deregisters the WDS net_device structures used by the
3497 * system's network layer.
3502 * lp - pointer to the device's private adapter structure
3508 ******************************************************************************/
3509 void wl_wds_netdev_deregister( struct wl_private *lp )
3512 /*------------------------------------------------------------------------*/
3513 DBG_FUNC( "wl_wds_netdev_deregister" );
3514 DBG_ENTER( DbgInfo );
3515 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3516 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3517 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3518 unregister_netdev( lp->wds_port[count].dev );
3520 lp->wds_port[count].is_registered = FALSE;
3523 DBG_LEAVE( DbgInfo );
3525 } // wl_wds_netdev_deregister
3526 /*============================================================================*/
3527 #endif /* USE_WDS */
3530 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
3532 * The proc filesystem: function to read and entry
3534 int printf_hcf_16( char *s, char *buf, hcf_16* p, int n );
3535 int printf_hcf_16( char *s, char *buf, hcf_16* p, int n ) {
3539 len = sprintf(buf, "%s", s );
3540 while ( len < 20 ) len += sprintf(buf+len, " " );
3541 len += sprintf(buf+len,": " );
3542 for ( i = 0; i < n; i++ ) {
3543 if ( len % 80 > 75 ) {
3544 len += sprintf(buf+len,"\n" );
3546 len += sprintf(buf+len,"%04X ", p[i] );
3548 len += sprintf(buf+len,"\n" );
3552 int printf_hcf_8( char *s, char *buf, hcf_8* p, int n );
3553 int printf_hcf_8( char *s, char *buf, hcf_8* p, int n ) {
3557 len = sprintf(buf, "%s", s );
3558 while ( len < 20 ) len += sprintf(buf+len, " " );
3559 len += sprintf(buf+len,": " );
3560 for ( i = 0; i <= n; i++ ) {
3561 if ( len % 80 > 77 ) {
3562 len += sprintf(buf+len,"\n" );
3564 len += sprintf(buf+len,"%02X ", p[i] );
3566 len += sprintf(buf+len,"\n" );
3570 int printf_strct( char *s, char *buf, hcf_16* p );
3571 int printf_strct( char *s, char *buf, hcf_16* p ) {
3575 len = sprintf(buf, "%s", s );
3576 while ( len < 20 ) len += sprintf(buf+len, " " );
3577 len += sprintf(buf+len,": " );
3578 for ( i = 0; i <= *p; i++ ) {
3579 if ( len % 80 > 75 ) {
3580 len += sprintf(buf+len,"\n" );
3582 len += sprintf(buf+len,"%04X ", p[i] );
3584 len += sprintf(buf+len,"\n" );
3588 int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data )
3590 struct wl_private *lp = NULL;
3592 CFG_HERMES_TALLIES_STRCT *p;
3594 #define LIMIT (PAGE_SIZE-80) /* don't print any more after this size */
3598 lp = ((struct net_device *)data)->priv;
3600 len += sprintf(buf+len,"No wl_private in scull_read_procmem\n" );
3601 } else if ( lp->wlags49_type == 0 ){
3603 len += sprintf(buf+len,"Magic: 0x%04X\n", ifbp->IFB_Magic );
3604 len += sprintf(buf+len,"IOBase: 0x%04X\n", ifbp->IFB_IOBase );
3605 len += sprintf(buf+len,"LinkStat: 0x%04X\n", ifbp->IFB_LinkStat );
3606 len += sprintf(buf+len,"DSLinkStat: 0x%04X\n", ifbp->IFB_DSLinkStat );
3607 len += sprintf(buf+len,"TickIni: 0x%08lX\n", ifbp->IFB_TickIni );
3608 len += sprintf(buf+len,"TickCnt: 0x%04X\n", ifbp->IFB_TickCnt );
3609 len += sprintf(buf+len,"IntOffCnt: 0x%04X\n", ifbp->IFB_IntOffCnt );
3610 len += printf_hcf_16( "IFB_FWIdentity", &buf[len],
3611 &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
3612 } else if ( lp->wlags49_type == 1 ) {
3613 len += sprintf(buf+len,"Channel: 0x%04X\n", lp->Channel );
3614 /****** len += sprintf(buf+len,"slock: %d\n", lp->slock ); */
3615 //x struct tq_struct "task: 0x%04X\n", lp->task );
3616 //x struct net_device_stats "stats: 0x%04X\n", lp->stats );
3618 //x struct iw_statistics "wstats: 0x%04X\n", lp->wstats );
3619 //x len += sprintf(buf+len,"spy_number: 0x%04X\n", lp->spy_number );
3620 //x u_char spy_address[IW_MAX_SPY][ETH_ALEN];
3621 //x struct iw_quality spy_stat[IW_MAX_SPY];
3622 #endif // WIRELESS_EXT
3623 len += sprintf(buf+len,"IFB: 0x%p\n", &lp->hcfCtx );
3624 len += sprintf(buf+len,"flags: %#.8lX\n", lp->flags ); //;?use this format from now on
3625 len += sprintf(buf+len,"DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
3627 len += sprintf(buf+len,"DebugFlag (DbgInfo): 0x%08lX\n", DbgInfo->DebugFlag );
3629 len += sprintf(buf+len,"is_registered: 0x%04X\n", lp->is_registered );
3630 //x CFG_DRV_INFO_STRCT "driverInfo: 0x%04X\n", lp->driverInfo );
3631 len += printf_strct( "driverInfo", &buf[len], (hcf_16*)&lp->driverInfo );
3632 //x CFG_IDENTITY_STRCT "driverIdentity: 0x%04X\n", lp->driverIdentity );
3633 len += printf_strct( "driverIdentity", &buf[len], (hcf_16*)&lp->driverIdentity );
3634 //x CFG_FW_IDENTITY_STRCT "StationIdentity: 0x%04X\n", lp->StationIdentity );
3635 len += printf_strct( "StationIdentity", &buf[len], (hcf_16*)&lp->StationIdentity );
3636 //x CFG_PRI_IDENTITY_STRCT "PrimaryIdentity: 0x%04X\n", lp->PrimaryIdentity );
3637 len += printf_strct( "PrimaryIdentity", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
3638 len += printf_strct( "PrimarySupplier", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRISup );
3639 //x CFG_PRI_IDENTITY_STRCT "NICIdentity: 0x%04X\n", lp->NICIdentity );
3640 len += printf_strct( "NICIdentity", &buf[len], (hcf_16*)&lp->NICIdentity );
3641 //x ltv_t "ltvRecord: 0x%04X\n", lp->ltvRecord );
3642 len += sprintf(buf+len,"txBytes: 0x%08lX\n", lp->txBytes );
3643 len += sprintf(buf+len,"maxPort: 0x%04X\n", lp->maxPort ); /* 0 for STA, 6 for AP */
3644 /* Elements used for async notification from hardware */
3645 //x RID_LOG_STRCT RidList[10];
3646 //x ltv_t "updatedRecord: 0x%04X\n", lp->updatedRecord );
3647 //x PROBE_RESP "ProbeResp: 0x%04X\n", lp->ProbeResp );
3648 //x ASSOC_STATUS_STRCT "assoc_stat: 0x%04X\n", lp->assoc_stat );
3649 //x SECURITY_STATUS_STRCT "sec_stat: 0x%04X\n", lp->sec_stat );
3650 //x u_char lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
3651 len += sprintf(buf+len,"PortType: 0x%04X\n", lp->PortType ); // 1 - 3 (1 [Normal] | 3 [AdHoc])
3652 len += sprintf(buf+len,"Channel: 0x%04X\n", lp->Channel ); // 0 - 14 (0)
3653 //x hcf_16 TxRateControl[2];
3654 len += sprintf(buf+len,"TxRateControl[2]: 0x%04X 0x%04X\n",
3655 lp->TxRateControl[0], lp->TxRateControl[1] );
3656 len += sprintf(buf+len,"DistanceBetweenAPs: 0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
3657 len += sprintf(buf+len,"RTSThreshold: 0x%04X\n", lp->RTSThreshold ); // 0 - 2347 (2347)
3658 len += sprintf(buf+len,"PMEnabled: 0x%04X\n", lp->PMEnabled ); // 0 - 2, 8001 - 8002 (0)
3659 len += sprintf(buf+len,"MicrowaveRobustness: 0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
3660 len += sprintf(buf+len,"CreateIBSS: 0x%04X\n", lp->CreateIBSS ); // 0 - 1 (0)
3661 len += sprintf(buf+len,"MulticastReceive: 0x%04X\n", lp->MulticastReceive ); // 0 - 1 (1)
3662 len += sprintf(buf+len,"MaxSleepDuration: 0x%04X\n", lp->MaxSleepDuration ); // 0 - 65535 (100)
3663 //x hcf_8 MACAddress[ETH_ALEN];
3664 len += printf_hcf_8( "MACAddress", &buf[len], lp->MACAddress, ETH_ALEN );
3665 //x char NetworkName[HCF_MAX_NAME_LEN+1];
3666 len += sprintf(buf+len,"NetworkName: %.32s\n", lp->NetworkName );
3667 //x char StationName[HCF_MAX_NAME_LEN+1];
3668 len += sprintf(buf+len,"EnableEncryption: 0x%04X\n", lp->EnableEncryption ); // 0 - 1 (0)
3669 //x char Key1[MAX_KEY_LEN+1];
3670 len += printf_hcf_8( "Key1", &buf[len], lp->Key1, MAX_KEY_LEN );
3671 //x char Key2[MAX_KEY_LEN+1];
3672 //x char Key3[MAX_KEY_LEN+1];
3673 //x char Key4[MAX_KEY_LEN+1];
3674 len += sprintf(buf+len,"TransmitKeyID: 0x%04X\n", lp->TransmitKeyID ); // 1 - 4 (1)
3675 //x CFG_DEFAULT_KEYS_STRCT "DefaultKeys: 0x%04X\n", lp->DefaultKeys );
3676 //x u_char mailbox[MB_SIZE];
3677 //x char szEncryption[MAX_ENC_LEN];
3678 len += sprintf(buf+len,"driverEnable: 0x%04X\n", lp->driverEnable );
3679 len += sprintf(buf+len,"wolasEnable: 0x%04X\n", lp->wolasEnable );
3680 len += sprintf(buf+len,"atimWindow: 0x%04X\n", lp->atimWindow );
3681 len += sprintf(buf+len,"holdoverDuration: 0x%04X\n", lp->holdoverDuration );
3682 //x hcf_16 MulticastRate[2];
3683 len += sprintf(buf+len,"authentication: 0x%04X\n", lp->authentication ); // is this AP specific?
3684 len += sprintf(buf+len,"promiscuousMode: 0x%04X\n", lp->promiscuousMode );
3685 len += sprintf(buf+len,"DownloadFirmware: 0x%04X\n", lp->DownloadFirmware ); // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
3686 len += sprintf(buf+len,"AuthKeyMgmtSuite: 0x%04X\n", lp->AuthKeyMgmtSuite );
3687 len += sprintf(buf+len,"loadBalancing: 0x%04X\n", lp->loadBalancing );
3688 len += sprintf(buf+len,"mediumDistribution: 0x%04X\n", lp->mediumDistribution );
3689 len += sprintf(buf+len,"txPowLevel: 0x%04X\n", lp->txPowLevel );
3690 // len += sprintf(buf+len,"shortRetryLimit: 0x%04X\n", lp->shortRetryLimit );
3691 // len += sprintf(buf+len,"longRetryLimit: 0x%04X\n", lp->longRetryLimit );
3694 len += sprintf(buf+len,"connectionControl: 0x%04X\n", lp->connectionControl );
3695 //x //hcf_16 probeDataRates[2];
3696 len += sprintf(buf+len,"ownBeaconInterval: 0x%04X\n", lp->ownBeaconInterval );
3697 len += sprintf(buf+len,"coexistence: 0x%04X\n", lp->coexistence );
3698 //x WVLAN_FRAME "txF: 0x%04X\n", lp->txF );
3699 //x WVLAN_LFRAME txList[DEFAULT_NUM_TX_FRAMES];
3700 //x struct list_head "txFree: 0x%04X\n", lp->txFree );
3701 //x struct list_head txQ[WVLAN_MAX_TX_QUEUES];
3702 len += sprintf(buf+len,"netif_queue_on: 0x%04X\n", lp->netif_queue_on );
3703 len += sprintf(buf+len,"txQ_count: 0x%04X\n", lp->txQ_count );
3704 //x DESC_STRCT "desc_rx: 0x%04X\n", lp->desc_rx );
3705 //x DESC_STRCT "desc_tx: 0x%04X\n", lp->desc_tx );
3706 //x WVLAN_PORT_STATE "portState: 0x%04X\n", lp->portState );
3707 //x ScanResult "scan_results: 0x%04X\n", lp->scan_results );
3708 //x ProbeResult "probe_results: 0x%04X\n", lp->probe_results );
3709 len += sprintf(buf+len,"probe_num_aps: 0x%04X\n", lp->probe_num_aps );
3710 len += sprintf(buf+len,"use_dma: 0x%04X\n", lp->use_dma );
3711 //x DMA_STRCT "dma: 0x%04X\n", lp->dma );
3713 len += sprintf(buf+len,"useRTS: 0x%04X\n", lp->useRTS );
3715 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
3716 //;?should we restore this to allow smaller memory footprint
3717 //;?I guess not. This should be brought under Debug mode only
3718 len += sprintf(buf+len,"DTIMPeriod: 0x%04X\n", lp->DTIMPeriod ); // 1 - 255 (1)
3719 len += sprintf(buf+len,"multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
3720 len += sprintf(buf+len,"RejectAny: 0x%04X\n", lp->RejectAny ); // 0 - 1 (0)
3721 len += sprintf(buf+len,"ExcludeUnencrypted: 0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
3722 len += sprintf(buf+len,"intraBSSRelay: 0x%04X\n", lp->intraBSSRelay );
3723 len += sprintf(buf+len,"wlags49_type: 0x%08lX\n", lp->wlags49_type );
3725 //x WVLAN_WDS_IF wds_port[NUM_WDS_PORTS];
3728 } else if ( lp->wlags49_type == 2 ){
3729 len += sprintf(buf+len,"tallies to be added\n" );
3730 //Hermes Tallies (IFB substructure) {
3731 p = &lp->hcfCtx.IFB_NIC_Tallies;
3732 len += sprintf(buf+len,"TxUnicastFrames: %08lX\n", p->TxUnicastFrames );
3733 len += sprintf(buf+len,"TxMulticastFrames: %08lX\n", p->TxMulticastFrames );
3734 len += sprintf(buf+len,"TxFragments: %08lX\n", p->TxFragments );
3735 len += sprintf(buf+len,"TxUnicastOctets: %08lX\n", p->TxUnicastOctets );
3736 len += sprintf(buf+len,"TxMulticastOctets: %08lX\n", p->TxMulticastOctets );
3737 len += sprintf(buf+len,"TxDeferredTransmissions: %08lX\n", p->TxDeferredTransmissions );
3738 len += sprintf(buf+len,"TxSingleRetryFrames: %08lX\n", p->TxSingleRetryFrames );
3739 len += sprintf(buf+len,"TxMultipleRetryFrames: %08lX\n", p->TxMultipleRetryFrames );
3740 len += sprintf(buf+len,"TxRetryLimitExceeded: %08lX\n", p->TxRetryLimitExceeded );
3741 len += sprintf(buf+len,"TxDiscards: %08lX\n", p->TxDiscards );
3742 len += sprintf(buf+len,"RxUnicastFrames: %08lX\n", p->RxUnicastFrames );
3743 len += sprintf(buf+len,"RxMulticastFrames: %08lX\n", p->RxMulticastFrames );
3744 len += sprintf(buf+len,"RxFragments: %08lX\n", p->RxFragments );
3745 len += sprintf(buf+len,"RxUnicastOctets: %08lX\n", p->RxUnicastOctets );
3746 len += sprintf(buf+len,"RxMulticastOctets: %08lX\n", p->RxMulticastOctets );
3747 len += sprintf(buf+len,"RxFCSErrors: %08lX\n", p->RxFCSErrors );
3748 len += sprintf(buf+len,"RxDiscardsNoBuffer: %08lX\n", p->RxDiscardsNoBuffer );
3749 len += sprintf(buf+len,"TxDiscardsWrongSA: %08lX\n", p->TxDiscardsWrongSA );
3750 len += sprintf(buf+len,"RxWEPUndecryptable: %08lX\n", p->RxWEPUndecryptable );
3751 len += sprintf(buf+len,"RxMsgInMsgFragments: %08lX\n", p->RxMsgInMsgFragments );
3752 len += sprintf(buf+len,"RxMsgInBadMsgFragments: %08lX\n", p->RxMsgInBadMsgFragments );
3753 len += sprintf(buf+len,"RxDiscardsWEPICVError: %08lX\n", p->RxDiscardsWEPICVError );
3754 len += sprintf(buf+len,"RxDiscardsWEPExcluded: %08lX\n", p->RxDiscardsWEPExcluded );
3755 #if (HCF_EXT) & HCF_EXT_TALLIES_FW
3757 #endif // HCF_EXT_TALLIES_FW
3758 } else if ( lp->wlags49_type & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3760 DbgInfo->DebugFlag = lp->wlags49_type & 0x7FFF;
3762 lp->wlags49_type = 0; //default to IFB again ;?
3764 len += sprintf(buf+len,"unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
3765 len += sprintf(buf+len,"0x0000 - IFB\n" );
3766 len += sprintf(buf+len,"0x0001 - wl_private\n" );
3767 len += sprintf(buf+len,"0x0002 - Tallies\n" );
3768 len += sprintf(buf+len,"0x8xxx - Change debufflag\n" );
3769 len += sprintf(buf+len,"ERROR 0001\nWARNING 0002\nNOTICE 0004\nTRACE 0008\n" );
3770 len += sprintf(buf+len,"VERBOSE 0010\nPARAM 0020\nBREAK 0040\nRX 0100\n" );
3771 len += sprintf(buf+len,"TX 0200\nDS 0400\n" );
3774 } // scull_read_procmem
3776 static void proc_write(const char *name, write_proc_t *w, void *data)
3778 struct proc_dir_entry * entry = create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
3780 entry->write_proc = w;
3785 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
3787 static char proc_number[11];
3788 unsigned int nr = 0;
3790 DBG_FUNC( "write_int" );
3791 DBG_ENTER( DbgInfo );
3795 } else if ( copy_from_user(proc_number, buffer, count) ) {
3799 proc_number[count] = 0;
3800 nr = simple_strtoul(proc_number , NULL, 0);
3801 *(unsigned int *)data = nr;
3802 if ( nr & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3804 DbgInfo->DebugFlag = nr & 0x7FFF;
3808 DBG_PRINT( "value: %08X\n", nr );
3809 DBG_LEAVE( DbgInfo );
3813 #endif /* SCULL_USE_PROC */
3816 #define RUN_AT(x) (jiffies+(x)) //"borrowed" from include/pcmcia/k_compat.h
3817 #define DS_OOR 0x8000 //Deepsleep OutOfRange Status
3819 lp->timer_oor_cnt = DS_OOR;
3820 init_timer( &lp->timer_oor );
3821 lp->timer_oor.function = timer_oor;
3822 lp->timer_oor.data = (unsigned long)lp;
3823 lp->timer_oor.expires = RUN_AT( 3 * HZ );
3824 add_timer( &lp->timer_oor );
3825 printk(KERN_NOTICE "wl_enable: %ld\n", jiffies ); //;?remove me 1 day
3828 /*******************************************************************************
3830 *******************************************************************************
3837 * arg - a u_long representing a pointer to a dev_link_t structure for the
3838 * device to be released.
3844 ******************************************************************************/
3845 void timer_oor( u_long arg )
3847 struct wl_private *lp = (struct wl_private *)arg;
3849 /*------------------------------------------------------------------------*/
3851 DBG_FUNC( "timer_oor" );
3852 DBG_ENTER( DbgInfo );
3853 DBG_PARAM( DbgInfo, "arg", "0x%08lx", arg );
3855 printk(KERN_NOTICE "timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt ); //;?remove me 1 day
3856 lp->timer_oor_cnt += 10;
3857 if ( (lp->timer_oor_cnt & ~DS_OOR) > 300 ) {
3858 lp->timer_oor_cnt = 300;
3860 lp->timer_oor_cnt |= DS_OOR;
3861 init_timer( &lp->timer_oor );
3862 lp->timer_oor.function = timer_oor;
3863 lp->timer_oor.data = (unsigned long)lp;
3864 lp->timer_oor.expires = RUN_AT( (lp->timer_oor_cnt & ~DS_OOR) * HZ );
3865 add_timer( &lp->timer_oor );
3867 DBG_LEAVE( DbgInfo );
3871 MODULE_LICENSE("Dual BSD/GPL");