GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / wlags49_h2 / wl_main.c
blobbddf9ff0481261bc464f3cec26e612bb59ded6db
1 /*******************************************************************************
2 * Agere Systems Inc.
3 * Wireless device driver for Linux (wlags49).
5 * Copyright (c) 1998-2003 Agere Systems Inc.
6 * All rights reserved.
7 * http://www.agere.com
9 * Initially developed by TriplePoint, Inc.
10 * http://www.triplepoint.com
12 *------------------------------------------------------------------------------
14 * This file contains the main driver entry points and other adapter
15 * specific routines.
17 *------------------------------------------------------------------------------
19 * SOFTWARE LICENSE
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
35 * distribution.
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.
45 * Disclaimer
47 * THIS SOFTWARE IS PROVIDED “AS IS” 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
58 * DAMAGE.
60 ******************************************************************************/
62 /*******************************************************************************
63 * constant definitions
64 ******************************************************************************/
66 /* Allow support for calling system fcns to access F/W iamge file */
67 #define __KERNEL_SYSCALLS__
69 /*******************************************************************************
70 * include files
71 ******************************************************************************/
72 #include <wl_version.h>
74 #include <linux/module.h>
75 #include <linux/proc_fs.h>
76 #include <linux/types.h>
77 #include <linux/kernel.h>
78 // #include <linux/sched.h>
79 // #include <linux/ptrace.h>
80 // #include <linux/slab.h>
81 // #include <linux/ctype.h>
82 // #include <linux/string.h>
83 // #include <linux/timer.h>
84 //#include <linux/interrupt.h>
85 // #include <linux/tqueue.h>
86 // #include <linux/in.h>
87 // #include <linux/delay.h>
88 // #include <asm/io.h>
89 // #include <asm/system.h>
90 // #include <asm/bitops.h>
91 #include <linux/unistd.h>
92 #include <asm/uaccess.h>
94 #include <linux/netdevice.h>
95 #include <linux/etherdevice.h>
96 // #include <linux/skbuff.h>
97 // #include <linux/if_arp.h>
98 // #include <linux/ioport.h>
100 #define BIN_DL 0
101 #if BIN_DL
102 #include <linux/vmalloc.h>
103 #endif // BIN_DL
106 #include <debug.h>
108 #include <hcf.h>
109 #include <dhf.h>
110 //in order to get around:: wl_main.c:2229: `HREG_EV_RDMAD' undeclared (first use in this function)
111 #include <hcfdef.h>
113 #include <wl_if.h>
114 #include <wl_internal.h>
115 #include <wl_util.h>
116 #include <wl_main.h>
117 #include <wl_netdev.h>
118 #include <wl_wext.h>
120 #ifdef USE_PROFILE
121 #include <wl_profile.h>
122 #endif /* USE_PROFILE */
124 #ifdef BUS_PCMCIA
125 #include <wl_cs.h>
126 #endif /* BUS_PCMCIA */
128 #ifdef BUS_PCI
129 #include <wl_pci.h>
130 #endif /* BUS_PCI */
131 /*******************************************************************************
132 * macro defintions
133 ******************************************************************************/
134 #define VALID_PARAM(C) \
136 if (!(C)) \
138 printk(KERN_INFO "Wireless, parameter error: \"%s\"\n", #C); \
139 goto failed; \
142 /*******************************************************************************
143 * local functions
144 ******************************************************************************/
145 void wl_isr_handler( unsigned long p );
147 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
148 //int scull_read_procmem(char *buf, char **start, off_t offset, int len, int unused);
149 int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data );
150 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data);
151 static void proc_write(const char *name, write_proc_t *w, void *data);
153 #endif /* SCULL_USE_PROC */
155 /*******************************************************************************
156 * module parameter definitions - set with 'insmod'
157 ******************************************************************************/
158 static p_u16 irq_mask = 0xdeb8; // IRQ3,4,5,7,9,10,11,12,14,15
159 static p_s8 irq_list[4] = { -1 };
162 static p_u8 PARM_AUTHENTICATION = PARM_DEFAULT_AUTHENTICATION;
163 static p_u16 PARM_AUTH_KEY_MGMT_SUITE = PARM_DEFAULT_AUTH_KEY_MGMT_SUITE;
164 static p_u16 PARM_BRSC_2GHZ = PARM_DEFAULT_BRSC_2GHZ;
165 static p_u16 PARM_BRSC_5GHZ = PARM_DEFAULT_BRSC_5GHZ;
166 static p_u16 PARM_COEXISTENCE = PARM_DEFAULT_COEXISTENCE;
167 static p_u16 PARM_CONNECTION_CONTROL = PARM_DEFAULT_CONNECTION_CONTROL; //;?rename and move
168 static p_char *PARM_CREATE_IBSS = PARM_DEFAULT_CREATE_IBSS_STR;
169 static p_char *PARM_DESIRED_SSID = PARM_DEFAULT_SSID;
170 static p_char *PARM_DOWNLOAD_FIRMWARE = "";
171 static p_u16 PARM_ENABLE_ENCRYPTION = PARM_DEFAULT_ENABLE_ENCRYPTION;
172 static p_char *PARM_EXCLUDE_UNENCRYPTED = PARM_DEFAULT_EXCLUDE_UNENCRYPTED_STR;
173 static p_char *PARM_INTRA_BSS_RELAY = PARM_DEFAULT_INTRA_BSS_RELAY_STR;
174 static p_char *PARM_KEY1 = "";
175 static p_char *PARM_KEY2 = "";
176 static p_char *PARM_KEY3 = "";
177 static p_char *PARM_KEY4 = "";
178 static p_char *PARM_LOAD_BALANCING = PARM_DEFAULT_LOAD_BALANCING_STR;
179 static p_u16 PARM_MAX_SLEEP = PARM_DEFAULT_MAX_PM_SLEEP;
180 static p_char *PARM_MEDIUM_DISTRIBUTION = PARM_DEFAULT_MEDIUM_DISTRIBUTION_STR;
181 static p_char *PARM_MICROWAVE_ROBUSTNESS = PARM_DEFAULT_MICROWAVE_ROBUSTNESS_STR;
182 static p_char *PARM_MULTICAST_PM_BUFFERING = PARM_DEFAULT_MULTICAST_PM_BUFFERING_STR;
183 static p_u16 PARM_MULTICAST_RATE = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
184 static p_char *PARM_MULTICAST_RX = PARM_DEFAULT_MULTICAST_RX_STR;
185 static p_u8 PARM_NETWORK_ADDR[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
186 static p_u16 PARM_OWN_ATIM_WINDOW = PARM_DEFAULT_OWN_ATIM_WINDOW;
187 static p_u16 PARM_OWN_BEACON_INTERVAL = PARM_DEFAULT_OWN_BEACON_INTERVAL;
188 static p_u8 PARM_OWN_CHANNEL = PARM_DEFAULT_OWN_CHANNEL;
189 static p_u8 PARM_OWN_DTIM_PERIOD = PARM_DEFAULT_OWN_DTIM_PERIOD;
190 static p_char *PARM_OWN_NAME = PARM_DEFAULT_OWN_NAME;
191 static p_char *PARM_OWN_SSID = PARM_DEFAULT_SSID;
192 static p_u16 PARM_PM_ENABLED = WVLAN_PM_STATE_DISABLED;
193 static p_u16 PARM_PM_HOLDOVER_DURATION = PARM_DEFAULT_PM_HOLDOVER_DURATION;
194 static p_u8 PARM_PORT_TYPE = PARM_DEFAULT_PORT_TYPE;
195 static p_char *PARM_PROMISCUOUS_MODE = PARM_DEFAULT_PROMISCUOUS_MODE_STR;
196 static p_char *PARM_REJECT_ANY = PARM_DEFAULT_REJECT_ANY_STR;
197 #ifdef USE_WDS
198 static p_u16 PARM_RTS_THRESHOLD1 = PARM_DEFAULT_RTS_THRESHOLD;
199 static p_u16 PARM_RTS_THRESHOLD2 = PARM_DEFAULT_RTS_THRESHOLD;
200 static p_u16 PARM_RTS_THRESHOLD3 = PARM_DEFAULT_RTS_THRESHOLD;
201 static p_u16 PARM_RTS_THRESHOLD4 = PARM_DEFAULT_RTS_THRESHOLD;
202 static p_u16 PARM_RTS_THRESHOLD5 = PARM_DEFAULT_RTS_THRESHOLD;
203 static p_u16 PARM_RTS_THRESHOLD6 = PARM_DEFAULT_RTS_THRESHOLD;
204 #endif // USE_WDS
205 static p_u16 PARM_RTS_THRESHOLD = PARM_DEFAULT_RTS_THRESHOLD;
206 static p_u16 PARM_SRSC_2GHZ = PARM_DEFAULT_SRSC_2GHZ;
207 static p_u16 PARM_SRSC_5GHZ = PARM_DEFAULT_SRSC_5GHZ;
208 static p_u8 PARM_SYSTEM_SCALE = PARM_DEFAULT_SYSTEM_SCALE;
209 static p_u8 PARM_TX_KEY = PARM_DEFAULT_TX_KEY;
210 static p_u16 PARM_TX_POW_LEVEL = PARM_DEFAULT_TX_POW_LEVEL;
211 #ifdef USE_WDS
212 static p_u16 PARM_TX_RATE1 = PARM_DEFAULT_TX_RATE_2GHZ;
213 static p_u16 PARM_TX_RATE2 = PARM_DEFAULT_TX_RATE_2GHZ;
214 static p_u16 PARM_TX_RATE3 = PARM_DEFAULT_TX_RATE_2GHZ;
215 static p_u16 PARM_TX_RATE4 = PARM_DEFAULT_TX_RATE_2GHZ;
216 static p_u16 PARM_TX_RATE5 = PARM_DEFAULT_TX_RATE_2GHZ;
217 static p_u16 PARM_TX_RATE6 = PARM_DEFAULT_TX_RATE_2GHZ;
218 #endif // USE_WDS
219 static p_u16 PARM_TX_RATE = PARM_DEFAULT_TX_RATE_2GHZ;
220 #ifdef USE_WDS
221 static p_u8 PARM_WDS_ADDRESS1[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
222 static p_u8 PARM_WDS_ADDRESS2[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
223 static p_u8 PARM_WDS_ADDRESS3[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
224 static p_u8 PARM_WDS_ADDRESS4[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
225 static p_u8 PARM_WDS_ADDRESS5[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
226 static p_u8 PARM_WDS_ADDRESS6[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
227 #endif // USE_WDS
231 /* END NEW PARAMETERS */
232 /*******************************************************************************
233 * debugging specifics
234 ******************************************************************************/
235 #if DBG
237 static p_u32 pc_debug = DBG_LVL;
238 //MODULE_PARM(pc_debug, "i");
239 /*static ;?conflicts with my understanding of CL parameters and breaks now I moved
240 * the correspondig logic to wl_profile
241 */ p_u32 DebugFlag = ~0; //recognizable "undefined value" rather then DBG_DEFAULTS;
242 //MODULE_PARM(DebugFlag, "l");
244 dbg_info_t wl_info = { DBG_MOD_NAME, 0, 0 };
245 dbg_info_t *DbgInfo = &wl_info;
247 #endif /* DBG */
248 #ifdef USE_RTS
250 static p_char *useRTS = "N";
251 MODULE_PARM( useRTS, "s" );
252 MODULE_PARM_DESC( useRTS, "Use RTS test interface (<string> N or Y) [N]" );
254 #endif /* USE_RTS */
255 /*******************************************************************************
256 * firmware download specifics
257 ******************************************************************************/
258 extern struct CFG_RANGE2_STRCT BASED
259 cfg_drv_act_ranges_pri; // describes primary-actor range of HCF
262 //extern memimage station; // STA firmware image to be downloaded
263 extern memimage fw_image; // firmware image to be downloaded
266 /*******************************************************************************
267 * wl_insert()
268 *******************************************************************************
270 * DESCRIPTION:
272 * wl_insert() is scheduled to run after a CARD_INSERTION event is
273 * received, to configure the PCMCIA socket, and to make the ethernet device
274 * available to the system.
276 * PARAMETERS:
278 * dev - a pointer to the net_device struct of the wireless device
280 * RETURNS:
282 * TRUE or FALSE
284 ******************************************************************************/
285 int wl_insert( struct net_device *dev )
287 int result = 0;
288 int hcf_status = HCF_SUCCESS;
289 int i;
290 unsigned long flags = 0;
291 struct wl_private *lp = wl_priv(dev);
292 /*------------------------------------------------------------------------*/
293 DBG_FUNC( "wl_insert" );
294 DBG_ENTER( DbgInfo );
296 /* Initialize the adapter hardware. */
297 memset( &( lp->hcfCtx ), 0, sizeof( IFB_STRCT ));
299 /* Initialize the adapter parameters. */
300 spin_lock_init( &( lp->slock ));
302 /* Intialize states */
303 //lp->lockcount = 0; //PE1DNN
304 lp->is_handling_int = WL_NOT_HANDLING_INT;
305 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
307 lp->dev = dev;
309 DBG_PARAM( DbgInfo, "irq_mask", "0x%04x", irq_mask & 0x0FFFF );
310 DBG_PARAM( DbgInfo, "irq_list", "0x%02x 0x%02x 0x%02x 0x%02x",
311 irq_list[0] & 0x0FF, irq_list[1] & 0x0FF,
312 irq_list[2] & 0x0FF, irq_list[3] & 0x0FF );
313 DBG_PARAM( DbgInfo, PARM_NAME_DESIRED_SSID, "\"%s\"", PARM_DESIRED_SSID );
314 DBG_PARAM( DbgInfo, PARM_NAME_OWN_SSID, "\"%s\"", PARM_OWN_SSID );
315 DBG_PARAM( DbgInfo, PARM_NAME_OWN_CHANNEL, "%d", PARM_OWN_CHANNEL);
316 DBG_PARAM( DbgInfo, PARM_NAME_SYSTEM_SCALE, "%d", PARM_SYSTEM_SCALE );
317 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE, "%d", PARM_TX_RATE );
318 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD, "%d", PARM_RTS_THRESHOLD );
319 DBG_PARAM( DbgInfo, PARM_NAME_MICROWAVE_ROBUSTNESS, "\"%s\"", PARM_MICROWAVE_ROBUSTNESS );
320 DBG_PARAM( DbgInfo, PARM_NAME_OWN_NAME, "\"%s\"", PARM_OWN_NAME );
321 //;? DBG_PARAM( DbgInfo, PARM_NAME_ENABLE_ENCRYPTION, "\"%s\"", PARM_ENABLE_ENCRYPTION );
322 DBG_PARAM( DbgInfo, PARM_NAME_KEY1, "\"%s\"", PARM_KEY1 );
323 DBG_PARAM( DbgInfo, PARM_NAME_KEY2, "\"%s\"", PARM_KEY2 );
324 DBG_PARAM( DbgInfo, PARM_NAME_KEY3, "\"%s\"", PARM_KEY3 );
325 DBG_PARAM( DbgInfo, PARM_NAME_KEY4, "\"%s\"", PARM_KEY4 );
326 DBG_PARAM( DbgInfo, PARM_NAME_TX_KEY, "%d", PARM_TX_KEY );
327 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RATE, "%d", PARM_MULTICAST_RATE );
328 DBG_PARAM( DbgInfo, PARM_NAME_DOWNLOAD_FIRMWARE, "\"%s\"", PARM_DOWNLOAD_FIRMWARE );
329 DBG_PARAM( DbgInfo, PARM_NAME_AUTH_KEY_MGMT_SUITE, "%d", PARM_AUTH_KEY_MGMT_SUITE );
330 //;?#if (HCF_TYPE) & HCF_TYPE_STA
331 //;?should we make this code conditional depending on in STA mode
332 //;? DBG_PARAM( DbgInfo, PARM_NAME_PORT_TYPE, "%d", PARM_PORT_TYPE );
333 DBG_PARAM( DbgInfo, PARM_NAME_PM_ENABLED, "%04x", PARM_PM_ENABLED );
334 //;? DBG_PARAM( DbgInfo, PARM_NAME_CREATE_IBSS, "\"%s\"", PARM_CREATE_IBSS );
335 //;? DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RX, "\"%s\"", PARM_MULTICAST_RX );
336 //;? DBG_PARAM( DbgInfo, PARM_NAME_MAX_SLEEP, "%d", PARM_MAX_SLEEP );
337 //;? DBG_PARAM( DbgInfo, PARM_NAME_NETWORK_ADDR, "\"%s\"", DbgHwAddr( PARM_NETWORK_ADDR ));
338 //;? DBG_PARAM( DbgInfo, PARM_NAME_AUTHENTICATION, "%d", PARM_AUTHENTICATION );
339 //;? DBG_PARAM( DbgInfo, PARM_NAME_OWN_ATIM_WINDOW, "%d", PARM_OWN_ATIM_WINDOW );
340 //;? DBG_PARAM( DbgInfo, PARM_NAME_PM_HOLDOVER_DURATION, "%d", PARM_PM_HOLDOVER_DURATION );
341 //;? DBG_PARAM( DbgInfo, PARM_NAME_PROMISCUOUS_MODE, "\"%s\"", PARM_PROMISCUOUS_MODE );
342 //;?#endif /* HCF_STA */
343 //;?should we restore this to allow smaller memory footprint
344 //;?I guess: no, since this is Debug mode only
345 DBG_PARAM( DbgInfo, PARM_NAME_OWN_DTIM_PERIOD, "%d", PARM_OWN_DTIM_PERIOD );
346 DBG_PARAM( DbgInfo, PARM_NAME_REJECT_ANY, "\"%s\"", PARM_REJECT_ANY );
347 DBG_PARAM( DbgInfo, PARM_NAME_EXCLUDE_UNENCRYPTED, "\"%s\"", PARM_EXCLUDE_UNENCRYPTED );
348 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_PM_BUFFERING, "\"%s\"", PARM_MULTICAST_PM_BUFFERING );
349 DBG_PARAM( DbgInfo, PARM_NAME_INTRA_BSS_RELAY, "\"%s\"", PARM_INTRA_BSS_RELAY );
350 #ifdef USE_WDS
351 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD1, "%d", PARM_RTS_THRESHOLD1 );
352 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD2, "%d", PARM_RTS_THRESHOLD2 );
353 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD3, "%d", PARM_RTS_THRESHOLD3 );
354 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD4, "%d", PARM_RTS_THRESHOLD4 );
355 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD5, "%d", PARM_RTS_THRESHOLD5 );
356 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD6, "%d", PARM_RTS_THRESHOLD6 );
357 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE1, "%d", PARM_TX_RATE1 );
358 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE2, "%d", PARM_TX_RATE2 );
359 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE3, "%d", PARM_TX_RATE3 );
360 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE4, "%d", PARM_TX_RATE4 );
361 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE5, "%d", PARM_TX_RATE5 );
362 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE6, "%d", PARM_TX_RATE6 );
363 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS1, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS1 ));
364 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS2, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS2 ));
365 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS3, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS3 ));
366 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS4, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS4 ));
367 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS5, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS5 ));
368 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS6, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS6 ));
369 #endif /* USE_WDS */
371 VALID_PARAM( !PARM_DESIRED_SSID || ( strlen( PARM_DESIRED_SSID ) <= PARM_MAX_NAME_LEN ));
372 VALID_PARAM( !PARM_OWN_SSID || ( strlen( PARM_OWN_SSID ) <= PARM_MAX_NAME_LEN ));
373 VALID_PARAM(( PARM_OWN_CHANNEL <= PARM_MAX_OWN_CHANNEL ));
374 VALID_PARAM(( PARM_SYSTEM_SCALE >= PARM_MIN_SYSTEM_SCALE ) && ( PARM_SYSTEM_SCALE <= PARM_MAX_SYSTEM_SCALE ));
375 VALID_PARAM(( PARM_TX_RATE >= PARM_MIN_TX_RATE ) && ( PARM_TX_RATE <= PARM_MAX_TX_RATE ));
376 VALID_PARAM(( PARM_RTS_THRESHOLD <= PARM_MAX_RTS_THRESHOLD ));
377 VALID_PARAM( !PARM_MICROWAVE_ROBUSTNESS || strchr( "NnYy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL );
378 VALID_PARAM( !PARM_OWN_NAME || ( strlen( PARM_NAME_OWN_NAME ) <= PARM_MAX_NAME_LEN ));
379 VALID_PARAM(( PARM_ENABLE_ENCRYPTION <= PARM_MAX_ENABLE_ENCRYPTION ));
380 VALID_PARAM( is_valid_key_string( PARM_KEY1 ));
381 VALID_PARAM( is_valid_key_string( PARM_KEY2 ));
382 VALID_PARAM( is_valid_key_string( PARM_KEY3 ));
383 VALID_PARAM( is_valid_key_string( PARM_KEY4 ));
384 VALID_PARAM(( PARM_TX_KEY >= PARM_MIN_TX_KEY ) && ( PARM_TX_KEY <= PARM_MAX_TX_KEY ));
386 VALID_PARAM(( PARM_MULTICAST_RATE >= PARM_MIN_MULTICAST_RATE ) &&
387 ( PARM_MULTICAST_RATE <= PARM_MAX_MULTICAST_RATE ));
389 VALID_PARAM( !PARM_DOWNLOAD_FIRMWARE || ( strlen( PARM_DOWNLOAD_FIRMWARE ) <= 255 /*;?*/ ));
390 VALID_PARAM(( PARM_AUTH_KEY_MGMT_SUITE < PARM_MAX_AUTH_KEY_MGMT_SUITE ));
392 VALID_PARAM( !PARM_LOAD_BALANCING || strchr( "NnYy", PARM_LOAD_BALANCING[0] ) != NULL );
393 VALID_PARAM( !PARM_MEDIUM_DISTRIBUTION || strchr( "NnYy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL );
394 VALID_PARAM(( PARM_TX_POW_LEVEL <= PARM_MAX_TX_POW_LEVEL ));
396 VALID_PARAM(( PARM_PORT_TYPE >= PARM_MIN_PORT_TYPE ) && ( PARM_PORT_TYPE <= PARM_MAX_PORT_TYPE ));
397 VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
398 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
399 VALID_PARAM( !PARM_CREATE_IBSS || strchr( "NnYy", PARM_CREATE_IBSS[0] ) != NULL );
400 VALID_PARAM( !PARM_MULTICAST_RX || strchr( "NnYy", PARM_MULTICAST_RX[0] ) != NULL );
401 VALID_PARAM(( PARM_MAX_SLEEP <= PARM_MAX_MAX_PM_SLEEP ));
402 VALID_PARAM(( PARM_AUTHENTICATION <= PARM_MAX_AUTHENTICATION ));
403 VALID_PARAM(( PARM_OWN_ATIM_WINDOW <= PARM_MAX_OWN_ATIM_WINDOW ));
404 VALID_PARAM(( PARM_PM_HOLDOVER_DURATION <= PARM_MAX_PM_HOLDOVER_DURATION ));
405 VALID_PARAM( !PARM_PROMISCUOUS_MODE || strchr( "NnYy", PARM_PROMISCUOUS_MODE[0] ) != NULL );
406 VALID_PARAM(( PARM_CONNECTION_CONTROL <= PARM_MAX_CONNECTION_CONTROL ));
408 VALID_PARAM(( PARM_OWN_DTIM_PERIOD >= PARM_MIN_OWN_DTIM_PERIOD ));
409 VALID_PARAM( !PARM_REJECT_ANY || strchr( "NnYy", PARM_REJECT_ANY[0] ) != NULL );
410 VALID_PARAM( !PARM_EXCLUDE_UNENCRYPTED || strchr( "NnYy", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL );
411 VALID_PARAM( !PARM_MULTICAST_PM_BUFFERING || strchr( "NnYy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL );
412 VALID_PARAM( !PARM_INTRA_BSS_RELAY || strchr( "NnYy", PARM_INTRA_BSS_RELAY[0] ) != NULL );
413 #ifdef USE_WDS
414 VALID_PARAM(( PARM_RTS_THRESHOLD1 <= PARM_MAX_RTS_THRESHOLD ));
415 VALID_PARAM(( PARM_RTS_THRESHOLD2 <= PARM_MAX_RTS_THRESHOLD ));
416 VALID_PARAM(( PARM_RTS_THRESHOLD3 <= PARM_MAX_RTS_THRESHOLD ));
417 VALID_PARAM(( PARM_RTS_THRESHOLD4 <= PARM_MAX_RTS_THRESHOLD ));
418 VALID_PARAM(( PARM_RTS_THRESHOLD5 <= PARM_MAX_RTS_THRESHOLD ));
419 VALID_PARAM(( PARM_RTS_THRESHOLD6 <= PARM_MAX_RTS_THRESHOLD ));
420 VALID_PARAM(( PARM_TX_RATE1 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE1 <= PARM_MAX_TX_RATE ));
421 VALID_PARAM(( PARM_TX_RATE2 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE2 <= PARM_MAX_TX_RATE ));
422 VALID_PARAM(( PARM_TX_RATE3 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE3 <= PARM_MAX_TX_RATE ));
423 VALID_PARAM(( PARM_TX_RATE4 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE4 <= PARM_MAX_TX_RATE ));
424 VALID_PARAM(( PARM_TX_RATE5 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE5 <= PARM_MAX_TX_RATE ));
425 VALID_PARAM(( PARM_TX_RATE6 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE6 <= PARM_MAX_TX_RATE ));
426 #endif /* USE_WDS */
428 VALID_PARAM(( PARM_OWN_BEACON_INTERVAL >= PARM_MIN_OWN_BEACON_INTERVAL ) && ( PARM_OWN_BEACON_INTERVAL <= PARM_MAX_OWN_BEACON_INTERVAL ));
429 VALID_PARAM(( PARM_COEXISTENCE <= PARM_COEXISTENCE ));
431 /* Set the driver parameters from the passed in parameters. */
433 /* THESE MODULE PARAMETERS ARE TO BE DEPRECATED IN FAVOR OF A NAMING CONVENTION
434 WHICH IS INLINE WITH THE FORTHCOMING WAVELAN API */
436 /* START NEW PARAMETERS */
438 lp->Channel = PARM_OWN_CHANNEL;
439 lp->DistanceBetweenAPs = PARM_SYSTEM_SCALE;
441 /* Need to determine how to handle the new bands for 5GHz */
442 lp->TxRateControl[0] = PARM_DEFAULT_TX_RATE_2GHZ;
443 lp->TxRateControl[1] = PARM_DEFAULT_TX_RATE_5GHZ;
445 lp->RTSThreshold = PARM_RTS_THRESHOLD;
447 /* Need to determine how to handle the new bands for 5GHz */
448 lp->MulticastRate[0] = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
449 lp->MulticastRate[1] = PARM_DEFAULT_MULTICAST_RATE_5GHZ;
451 if ( strchr( "Yy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL ) {
452 lp->MicrowaveRobustness = 1;
453 } else {
454 lp->MicrowaveRobustness = 0;
456 if ( PARM_DESIRED_SSID && ( strlen( PARM_DESIRED_SSID ) <= HCF_MAX_NAME_LEN )) {
457 strcpy( lp->NetworkName, PARM_DESIRED_SSID );
459 if ( PARM_OWN_SSID && ( strlen( PARM_OWN_SSID ) <= HCF_MAX_NAME_LEN )) {
460 strcpy( lp->NetworkName, PARM_OWN_SSID );
462 if ( PARM_OWN_NAME && ( strlen( PARM_OWN_NAME ) <= HCF_MAX_NAME_LEN )) {
463 strcpy( lp->StationName, PARM_OWN_NAME );
465 lp->EnableEncryption = PARM_ENABLE_ENCRYPTION;
466 if ( PARM_KEY1 && ( strlen( PARM_KEY1 ) <= MAX_KEY_LEN )) {
467 strcpy( lp->Key1, PARM_KEY1 );
469 if ( PARM_KEY2 && ( strlen( PARM_KEY2 ) <= MAX_KEY_LEN )) {
470 strcpy( lp->Key2, PARM_KEY2 );
472 if ( PARM_KEY3 && ( strlen( PARM_KEY3 ) <= MAX_KEY_LEN )) {
473 strcpy( lp->Key3, PARM_KEY3 );
475 if ( PARM_KEY4 && ( strlen( PARM_KEY4 ) <= MAX_KEY_LEN )) {
476 strcpy( lp->Key4, PARM_KEY4 );
479 lp->TransmitKeyID = PARM_TX_KEY;
481 key_string2key( lp->Key1, &(lp->DefaultKeys.key[0] ));
482 key_string2key( lp->Key2, &(lp->DefaultKeys.key[1] ));
483 key_string2key( lp->Key3, &(lp->DefaultKeys.key[2] ));
484 key_string2key( lp->Key4, &(lp->DefaultKeys.key[3] ));
486 lp->DownloadFirmware = 1 ; //;?to be upgraded PARM_DOWNLOAD_FIRMWARE;
487 lp->AuthKeyMgmtSuite = PARM_AUTH_KEY_MGMT_SUITE;
489 if ( strchr( "Yy", PARM_LOAD_BALANCING[0] ) != NULL ) {
490 lp->loadBalancing = 1;
491 } else {
492 lp->loadBalancing = 0;
495 if ( strchr( "Yy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL ) {
496 lp->mediumDistribution = 1;
497 } else {
498 lp->mediumDistribution = 0;
501 lp->txPowLevel = PARM_TX_POW_LEVEL;
503 lp->srsc[0] = PARM_SRSC_2GHZ;
504 lp->srsc[1] = PARM_SRSC_5GHZ;
505 lp->brsc[0] = PARM_BRSC_2GHZ;
506 lp->brsc[1] = PARM_BRSC_5GHZ;
507 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
508 lp->PortType = PARM_PORT_TYPE;
509 lp->MaxSleepDuration = PARM_MAX_SLEEP;
510 lp->authentication = PARM_AUTHENTICATION;
511 lp->atimWindow = PARM_OWN_ATIM_WINDOW;
512 lp->holdoverDuration = PARM_PM_HOLDOVER_DURATION;
513 lp->PMEnabled = PARM_PM_ENABLED; //;?
514 if ( strchr( "Yy", PARM_CREATE_IBSS[0] ) != NULL ) {
515 lp->CreateIBSS = 1;
516 } else {
517 lp->CreateIBSS = 0;
519 if ( strchr( "Nn", PARM_MULTICAST_RX[0] ) != NULL ) {
520 lp->MulticastReceive = 0;
521 } else {
522 lp->MulticastReceive = 1;
524 if ( strchr( "Yy", PARM_PROMISCUOUS_MODE[0] ) != NULL ) {
525 lp->promiscuousMode = 1;
526 } else {
527 lp->promiscuousMode = 0;
529 for( i = 0; i < ETH_ALEN; i++ ) {
530 lp->MACAddress[i] = PARM_NETWORK_ADDR[i];
533 lp->connectionControl = PARM_CONNECTION_CONTROL;
534 //;?should we restore this to allow smaller memory footprint
535 lp->DTIMPeriod = PARM_OWN_DTIM_PERIOD;
537 if ( strchr( "Yy", PARM_REJECT_ANY[0] ) != NULL ) {
538 lp->RejectAny = 1;
539 } else {
540 lp->RejectAny = 0;
542 if ( strchr( "Nn", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL ) {
543 lp->ExcludeUnencrypted = 0;
544 } else {
545 lp->ExcludeUnencrypted = 1;
547 if ( strchr( "Yy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL ) {
548 lp->multicastPMBuffering = 1;
549 } else {
550 lp->multicastPMBuffering = 0;
552 if ( strchr( "Yy", PARM_INTRA_BSS_RELAY[0] ) != NULL ) {
553 lp->intraBSSRelay = 1;
554 } else {
555 lp->intraBSSRelay = 0;
558 lp->ownBeaconInterval = PARM_OWN_BEACON_INTERVAL;
559 lp->coexistence = PARM_COEXISTENCE;
561 #ifdef USE_WDS
562 lp->wds_port[0].rtsThreshold = PARM_RTS_THRESHOLD1;
563 lp->wds_port[1].rtsThreshold = PARM_RTS_THRESHOLD2;
564 lp->wds_port[2].rtsThreshold = PARM_RTS_THRESHOLD3;
565 lp->wds_port[3].rtsThreshold = PARM_RTS_THRESHOLD4;
566 lp->wds_port[4].rtsThreshold = PARM_RTS_THRESHOLD5;
567 lp->wds_port[5].rtsThreshold = PARM_RTS_THRESHOLD6;
568 lp->wds_port[0].txRateCntl = PARM_TX_RATE1;
569 lp->wds_port[1].txRateCntl = PARM_TX_RATE2;
570 lp->wds_port[2].txRateCntl = PARM_TX_RATE3;
571 lp->wds_port[3].txRateCntl = PARM_TX_RATE4;
572 lp->wds_port[4].txRateCntl = PARM_TX_RATE5;
573 lp->wds_port[5].txRateCntl = PARM_TX_RATE6;
575 for( i = 0; i < ETH_ALEN; i++ ) {
576 lp->wds_port[0].wdsAddress[i] = PARM_WDS_ADDRESS1[i];
578 for( i = 0; i < ETH_ALEN; i++ ) {
579 lp->wds_port[1].wdsAddress[i] = PARM_WDS_ADDRESS2[i];
581 for( i = 0; i < ETH_ALEN; i++ ) {
582 lp->wds_port[2].wdsAddress[i] = PARM_WDS_ADDRESS3[i];
584 for( i = 0; i < ETH_ALEN; i++ ) {
585 lp->wds_port[3].wdsAddress[i] = PARM_WDS_ADDRESS4[i];
587 for( i = 0; i < ETH_ALEN; i++ ) {
588 lp->wds_port[4].wdsAddress[i] = PARM_WDS_ADDRESS5[i];
590 for( i = 0; i < ETH_ALEN; i++ ) {
591 lp->wds_port[5].wdsAddress[i] = PARM_WDS_ADDRESS6[i];
593 #endif /* USE_WDS */
594 #ifdef USE_RTS
595 if ( strchr( "Yy", useRTS[0] ) != NULL ) {
596 lp->useRTS = 1;
597 } else {
598 lp->useRTS = 0;
600 #endif /* USE_RTS */
603 /* END NEW PARAMETERS */
606 wl_lock( lp, &flags );
608 /* Initialize the portState variable */
609 lp->portState = WVLAN_PORT_STATE_DISABLED;
611 /* Initialize the ScanResult struct */
612 memset( &( lp->scan_results ), 0, sizeof( lp->scan_results ));
613 lp->scan_results.scan_complete = FALSE;
615 /* Initialize the ProbeResult struct */
616 memset( &( lp->probe_results ), 0, sizeof( lp->probe_results ));
617 lp->probe_results.scan_complete = FALSE;
618 lp->probe_num_aps = 0;
621 /* Initialize Tx queue stuff */
622 memset( lp->txList, 0, sizeof( lp->txList ));
624 INIT_LIST_HEAD( &( lp->txFree ));
626 lp->txF.skb = NULL;
627 lp->txF.port = 0;
630 for( i = 0; i < DEFAULT_NUM_TX_FRAMES; i++ ) {
631 list_add_tail( &( lp->txList[i].node ), &( lp->txFree ));
635 for( i = 0; i < WVLAN_MAX_TX_QUEUES; i++ ) {
636 INIT_LIST_HEAD( &( lp->txQ[i] ));
639 lp->netif_queue_on = TRUE;
640 lp->txQ_count = 0;
641 /* Initialize the use_dma element in the adapter structure. Not sure if
642 this should be a compile-time or run-time configurable. So for now,
643 implement as run-time and just define here */
644 #ifdef WARP
645 #ifdef ENABLE_DMA
646 DBG_TRACE( DbgInfo, "HERMES 2.5 BUSMASTER DMA MODE\n" );
647 lp->use_dma = 1;
648 #else
649 DBG_TRACE( DbgInfo, "HERMES 2.5 PORT I/O MODE\n" );
650 lp->use_dma = 0;
651 #endif // ENABLE_DMA
652 #endif // WARP
654 /* Register the ISR handler information here, so that it's not done
655 repeatedly in the ISR */
656 tasklet_init(&lp->task, wl_isr_handler, (unsigned long)lp);
658 /* Connect to the adapter */
659 DBG_TRACE( DbgInfo, "Calling hcf_connect()...\n" );
660 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
661 //HCF_ERR_INCOMP_FW is acceptable, because download must still take place
662 //HCF_ERR_INCOMP_PRI is not acceptable
663 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
664 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
665 wl_unlock( lp, &flags );
666 goto hcf_failed;
669 //;?should set HCF_version and how about driver_stat
670 lp->driverInfo.IO_address = dev->base_addr;
671 lp->driverInfo.IO_range = HCF_NUM_IO_PORTS; //;?conditionally 0x40 or 0x80 seems better
672 lp->driverInfo.IRQ_number = dev->irq;
673 lp->driverInfo.card_stat = lp->hcfCtx.IFB_CardStat;
674 //;? what happened to frame_type
676 /* Fill in the driver identity structure */
677 lp->driverIdentity.len = ( sizeof( lp->driverIdentity ) / sizeof( hcf_16 )) - 1;
678 lp->driverIdentity.typ = CFG_DRV_IDENTITY;
679 lp->driverIdentity.comp_id = DRV_IDENTITY;
680 lp->driverIdentity.variant = DRV_VARIANT;
681 lp->driverIdentity.version_major = DRV_MAJOR_VERSION;
682 lp->driverIdentity.version_minor = DRV_MINOR_VERSION;
685 /* Start the card here - This needs to be done in order to get the
686 MAC address for the network layer */
687 DBG_TRACE( DbgInfo, "Calling wvlan_go() to perform a card reset...\n" );
688 hcf_status = wl_go( lp );
690 if ( hcf_status != HCF_SUCCESS ) {
691 DBG_ERROR( DbgInfo, "wl_go() failed\n" );
692 wl_unlock( lp, &flags );
693 goto hcf_failed;
696 /* Certain RIDs must be set before enabling the ports */
697 wl_put_ltv_init( lp );
700 /* Fill out the MAC address information in the net_device struct */
701 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN );
702 dev->addr_len = ETH_ALEN;
704 lp->is_registered = TRUE;
706 #ifdef USE_PROFILE
707 /* Parse the config file for the sake of creating WDS ports if WDS is
708 configured there but not in the module options */
709 parse_config( dev );
710 #endif /* USE_PROFILE */
712 /* If we're going into AP Mode, register the "virtual" ethernet devices
713 needed for WDS */
714 WL_WDS_NETDEV_REGISTER( lp );
716 /* Reset the DownloadFirmware variable in the private struct. If the
717 config file is not used, this will not matter; if it is used, it
718 will be reparsed in wl_open(). This is done because logic in wl_open
719 used to check if a firmware download is needed is broken by parsing
720 the file here; however, this parsing is needed to register WDS ports
721 in AP mode, if they are configured */
722 lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //;?download_firmware;
724 #ifdef USE_RTS
725 if ( lp->useRTS == 1 ) {
726 DBG_TRACE( DbgInfo, "ENTERING RTS MODE...\n" );
727 wl_act_int_off( lp );
728 lp->is_handling_int = WL_NOT_HANDLING_INT; // Not handling interrupts anymore
730 wl_disable( lp );
732 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT);
734 #endif /* USE_RTS */
736 wl_unlock( lp, &flags );
738 DBG_TRACE( DbgInfo, "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
739 dev->name, dev->base_addr, dev->irq );
741 for( i = 0; i < ETH_ALEN; i++ ) {
742 printk( "%02X%c", dev->dev_addr[i], (( i < ( ETH_ALEN-1 )) ? ':' : '\n' ));
745 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
746 create_proc_read_entry( "wlags", 0, NULL, scull_read_procmem, dev );
747 proc_mkdir("driver/wlags49", 0);
748 proc_write("driver/wlags49/wlags49_type", write_int, &lp->wlags49_type);
749 #endif /* SCULL_USE_PROC */
751 DBG_LEAVE( DbgInfo );
752 return result;
754 hcf_failed:
755 wl_hcf_error( dev, hcf_status );
757 failed:
759 DBG_ERROR( DbgInfo, "wl_insert() FAILED\n" );
761 if ( lp->is_registered == TRUE ) {
762 lp->is_registered = FALSE;
765 WL_WDS_NETDEV_DEREGISTER( lp );
767 result = -EFAULT;
770 DBG_LEAVE( DbgInfo );
771 return result;
772 } // wl_insert
773 /*============================================================================*/
776 /*******************************************************************************
777 * wl_reset()
778 *******************************************************************************
780 * DESCRIPTION:
782 * Reset the adapter.
784 * PARAMETERS:
786 * dev - a pointer to the net_device struct of the wireless device
788 * RETURNS:
790 * an HCF status code
792 ******************************************************************************/
793 int wl_reset(struct net_device *dev)
795 struct wl_private *lp = wl_priv(dev);
796 int hcf_status = HCF_SUCCESS;
797 /*------------------------------------------------------------------------*/
798 DBG_FUNC( "wl_reset" );
799 DBG_ENTER( DbgInfo );
800 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
801 DBG_PARAM( DbgInfo, "dev->base_addr", "(%#03lx)", dev->base_addr );
804 * The caller should already have a lock and
805 * disable the interrupts, we do not lock here,
806 * nor do we enable/disable interrupts!
809 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", dev->base_addr );
810 if ( dev->base_addr ) {
811 /* Shutdown the adapter. */
812 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
814 /* Reset the driver information. */
815 lp->txBytes = 0;
817 /* Connect to the adapter. */
818 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
819 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
820 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
821 goto out;
824 /* Check if firmware is present, if not change state */
825 if ( hcf_status == HCF_ERR_INCOMP_FW ) {
826 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
829 /* Initialize the portState variable */
830 lp->portState = WVLAN_PORT_STATE_DISABLED;
832 /* Restart the adapter. */
833 hcf_status = wl_go( lp );
834 if ( hcf_status != HCF_SUCCESS ) {
835 DBG_ERROR( DbgInfo, "wl_go() failed, status: 0x%x\n", hcf_status );
836 goto out;
839 /* Certain RIDs must be set before enabling the ports */
840 wl_put_ltv_init( lp );
841 } else {
842 DBG_ERROR( DbgInfo, "Device Base Address INVALID!!!\n" );
845 out:
846 DBG_LEAVE( DbgInfo );
847 return hcf_status;
848 } // wl_reset
849 /*============================================================================*/
852 /*******************************************************************************
853 * wl_go()
854 *******************************************************************************
856 * DESCRIPTION:
858 * Reset the adapter.
860 * PARAMETERS:
862 * dev - a pointer to the net_device struct of the wireless device
864 * RETURNS:
866 * an HCF status code
868 ******************************************************************************/
869 int wl_go( struct wl_private *lp )
871 int hcf_status = HCF_SUCCESS;
872 char *cp = NULL; //fw_image
873 int retries = 0;
874 /*------------------------------------------------------------------------*/
875 DBG_FUNC( "wl_go" );
876 DBG_ENTER( DbgInfo );
878 hcf_status = wl_disable( lp );
879 if ( hcf_status != HCF_SUCCESS ) {
880 DBG_TRACE( DbgInfo, "Disable port 0 failed: 0x%x\n", hcf_status );
882 while (( hcf_status != HCF_SUCCESS ) && (retries < 10)) {
883 retries++;
884 hcf_status = wl_disable( lp );
886 if ( hcf_status == HCF_SUCCESS ) {
887 DBG_TRACE( DbgInfo, "Disable port 0 succes : %d retries\n", retries );
888 } else {
889 DBG_TRACE( DbgInfo, "Disable port 0 failed after: %d retries\n", retries );
893 //DBG_TRACE( DbgInfo, "Disabling WDS Ports\n" );
894 //wl_disable_wds_ports( lp );
896 //;?what was the purpose of this
897 // /* load the appropriate firmware image, depending on driver mode */
898 // lp->ltvRecord.len = ( sizeof( CFG_RANGE20_STRCT ) / sizeof( hcf_16 )) - 1;
899 // lp->ltvRecord.typ = CFG_DRV_ACT_RANGES_PRI;
900 // hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
902 #if BIN_DL
903 if ( strlen( lp->fw_image_filename ) ) {
904 mm_segment_t fs;
905 int file_desc;
906 int rc;
908 DBG_TRACE( DbgInfo, "F/W image:%s:\n", lp->fw_image_filename );
909 /* Obtain a user-space process context, storing the original context */
910 fs = get_fs( );
911 set_fs( get_ds( ));
912 file_desc = open( lp->fw_image_filename, O_RDONLY, 0 );
913 if ( file_desc == -1 ) {
914 DBG_ERROR( DbgInfo, "No image file found\n" );
915 } else {
916 DBG_TRACE( DbgInfo, "F/W image file found\n" );
917 #define DHF_ALLOC_SIZE 96000 //just below 96K, let's hope it suffices for now and for the future
918 cp = (char*)vmalloc( DHF_ALLOC_SIZE );
919 if ( cp == NULL ) {
920 DBG_ERROR( DbgInfo, "error in vmalloc\n" );
921 } else {
922 rc = read( file_desc, cp, DHF_ALLOC_SIZE );
923 if ( rc == DHF_ALLOC_SIZE ) {
924 DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE );
925 } else if ( rc > 0 ) {
926 DBG_TRACE( DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp );
927 rc = read( file_desc, &cp[rc], 1 );
928 if ( rc == 0 ) { //;/change to an until-loop at rc<=0
929 DBG_TRACE( DbgInfo, "no more to read\n" );
932 if ( rc != 0 ) {
933 DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\
934 ", give up, too complicated, rc = %0X\n", rc );
935 DBG_ERROR( DbgInfo, "still have to change code to get a real download now !!!!!!!!\n" );
936 } else {
937 DBG_TRACE( DbgInfo, "before dhf_download_binary\n" );
938 hcf_status = dhf_download_binary( (memimage *)cp );
939 DBG_TRACE( DbgInfo, "after dhf_download_binary, before dhf_download_fw\n" );
940 //;?improve error flow/handling
941 hcf_status = dhf_download_fw( &lp->hcfCtx, (memimage *)cp );
942 DBG_TRACE( DbgInfo, "after dhf_download_fw\n" );
944 vfree( cp );
946 close( file_desc );
948 set_fs( fs ); /* Return to the original context */
950 #endif // BIN_DL
952 /* If firmware is present but the type is unknown then download anyway */
953 if ( (lp->firmware_present == WL_FRIMWARE_PRESENT)
955 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_STA )
957 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_AP ) ) {
958 /* Unknown type, download needed. */
959 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
962 if(lp->firmware_present == WL_FRIMWARE_NOT_PRESENT)
964 if ( cp == NULL ) {
965 DBG_TRACE( DbgInfo, "Downloading STA firmware...\n" );
966 // hcf_status = dhf_download_fw( &lp->hcfCtx, &station );
967 hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image );
969 if ( hcf_status != HCF_SUCCESS ) {
970 DBG_ERROR( DbgInfo, "Firmware Download failed\n" );
971 DBG_LEAVE( DbgInfo );
972 return hcf_status;
975 /* Report the FW versions */
976 //;?obsolete, use the available IFB info:: wl_get_pri_records( lp );
977 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
978 DBG_TRACE( DbgInfo, "downloaded station F/W\n" );
979 } else if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
980 DBG_TRACE( DbgInfo, "downloaded AP F/W\n" );
981 } else {
982 DBG_ERROR( DbgInfo, "unknown F/W type\n" );
986 * Downloaded, no need to repeat this next time, assume the
987 * contents stays in the card until it is powered off. Note we
988 * do not switch firmware on the fly, the firmware is fixed in
989 * the driver for now.
991 lp->firmware_present = WL_FRIMWARE_PRESENT;
993 DBG_TRACE( DbgInfo, "ComponentID:%04x variant:%04x major:%04x minor:%04x\n",
994 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ),
995 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.variant ),
996 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_major ),
997 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_minor ));
999 /* now we wil get the MAC address of the card */
1000 lp->ltvRecord.len = 4;
1001 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1002 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1003 } else
1005 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1007 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1008 if ( hcf_status != HCF_SUCCESS ) {
1009 DBG_ERROR( DbgInfo, "Could not retrieve MAC address\n" );
1010 DBG_LEAVE( DbgInfo );
1011 return hcf_status;
1013 memcpy( lp->MACAddress, &lp->ltvRecord.u.u8[0], ETH_ALEN );
1014 DBG_TRACE( DbgInfo, "Card MAC Address: %s\n", DbgHwAddr( lp->MACAddress ));
1016 /* Write out configuration to the device, enable, and reconnect. However,
1017 only reconnect if in AP mode. For STA mode, need to wait for passive scan
1018 completion before a connect can be issued */
1019 wl_put_ltv( lp );
1020 /* Enable the ports */
1021 hcf_status = wl_enable( lp );
1023 if ( lp->DownloadFirmware == WVLAN_DRV_MODE_AP ) {
1024 #ifdef USE_WDS
1025 wl_enable_wds_ports( lp );
1026 #endif // USE_WDS
1027 hcf_status = wl_connect( lp );
1029 DBG_LEAVE( DbgInfo );
1030 return hcf_status;
1031 } // wl_go
1032 /*============================================================================*/
1035 /*******************************************************************************
1036 * wl_set_wep_keys()
1037 *******************************************************************************
1039 * DESCRIPTION:
1041 * Write TxKeyID and WEP keys to the adapter. This is separated from
1042 * wl_apply() to allow dynamic WEP key updates through the wireless
1043 * extensions.
1045 * PARAMETERS:
1047 * lp - a pointer to the wireless adapter's private structure
1049 * RETURNS:
1051 * N/A
1053 ******************************************************************************/
1054 void wl_set_wep_keys( struct wl_private *lp )
1056 int count = 0;
1057 /*------------------------------------------------------------------------*/
1058 DBG_FUNC( "wl_set_wep_keys" );
1059 DBG_ENTER( DbgInfo );
1060 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1061 if ( lp->EnableEncryption ) {
1062 /* NOTE: CFG_CNF_ENCRYPTION is set in wl_put_ltv() as it's a static
1063 RID */
1065 /* set TxKeyID */
1066 lp->ltvRecord.len = 2;
1067 lp->ltvRecord.typ = CFG_TX_KEY_ID;
1068 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE(lp->TransmitKeyID - 1);
1070 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1072 DBG_TRACE( DbgInfo, "Key 1 len: %d\n", lp->DefaultKeys.key[0].len );
1073 DBG_TRACE( DbgInfo, "Key 2 len: %d\n", lp->DefaultKeys.key[1].len );
1074 DBG_TRACE( DbgInfo, "Key 3 len: %d\n", lp->DefaultKeys.key[2].len );
1075 DBG_TRACE( DbgInfo, "Key 4 len: %d\n", lp->DefaultKeys.key[3].len );
1077 /* write keys */
1078 lp->DefaultKeys.len = sizeof( lp->DefaultKeys ) / sizeof( hcf_16 ) - 1;
1079 lp->DefaultKeys.typ = CFG_DEFAULT_KEYS;
1081 /* endian translate the appropriate key information */
1082 for( count = 0; count < MAX_KEYS; count++ ) {
1083 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1086 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->DefaultKeys ));
1088 /* Reverse the above endian translation, since these keys are accessed
1089 elsewhere */
1090 for( count = 0; count < MAX_KEYS; count++ ) {
1091 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1094 DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption, lp->TransmitKeyID );
1095 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 );
1098 DBG_LEAVE( DbgInfo );
1099 } // wl_set_wep_keys
1100 /*============================================================================*/
1103 /*******************************************************************************
1104 * wl_apply()
1105 *******************************************************************************
1107 * DESCRIPTION:
1109 * Write the parameters to the adapter. (re-)enables the card if device is
1110 * open. Returns hcf_status of hcf_enable().
1112 * PARAMETERS:
1114 * lp - a pointer to the wireless adapter's private structure
1116 * RETURNS:
1118 * an HCF status code
1120 ******************************************************************************/
1121 int wl_apply(struct wl_private *lp)
1123 int hcf_status = HCF_SUCCESS;
1124 /*------------------------------------------------------------------------*/
1125 DBG_FUNC( "wl_apply" );
1126 DBG_ENTER( DbgInfo );
1127 DBG_ASSERT( lp != NULL);
1128 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1130 if ( !( lp->flags & WVLAN2_UIL_BUSY )) {
1131 /* The adapter parameters have changed:
1132 disable card
1133 reload parameters
1134 enable card
1137 if ( wl_adapter_is_open( lp->dev )) {
1138 /* Disconnect and disable if necessary */
1139 hcf_status = wl_disconnect( lp );
1140 if ( hcf_status != HCF_SUCCESS ) {
1141 DBG_ERROR( DbgInfo, "Disconnect failed\n" );
1142 DBG_LEAVE( DbgInfo );
1143 return -1;
1145 hcf_status = wl_disable( lp );
1146 if ( hcf_status != HCF_SUCCESS ) {
1147 DBG_ERROR( DbgInfo, "Disable failed\n" );
1148 DBG_LEAVE( DbgInfo );
1149 return -1;
1150 } else {
1151 /* Write out configuration to the device, enable, and reconnect.
1152 However, only reconnect if in AP mode. For STA mode, need to
1153 wait for passive scan completion before a connect can be
1154 issued */
1155 hcf_status = wl_put_ltv( lp );
1157 if ( hcf_status == HCF_SUCCESS ) {
1158 hcf_status = wl_enable( lp );
1160 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1161 hcf_status = wl_connect( lp );
1163 } else {
1164 DBG_WARNING( DbgInfo, "wl_put_ltv() failed\n" );
1170 DBG_LEAVE( DbgInfo );
1171 return hcf_status;
1172 } // wl_apply
1173 /*============================================================================*/
1176 /*******************************************************************************
1177 * wl_put_ltv_init()
1178 *******************************************************************************
1180 * DESCRIPTION:
1182 * Used to set basic parameters for card initialization.
1184 * PARAMETERS:
1186 * lp - a pointer to the wireless adapter's private structure
1188 * RETURNS:
1190 * an HCF status code
1192 ******************************************************************************/
1193 int wl_put_ltv_init( struct wl_private *lp )
1195 int i;
1196 int hcf_status;
1197 CFG_RID_LOG_STRCT *RidLog;
1198 /*------------------------------------------------------------------------*/
1199 DBG_FUNC( "wl_put_ltv_init" );
1200 DBG_ENTER( DbgInfo );
1201 if ( lp == NULL ) {
1202 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1203 DBG_LEAVE( DbgInfo );
1204 return -1;
1206 /* DMA/IO */
1207 lp->ltvRecord.len = 2;
1208 lp->ltvRecord.typ = CFG_CNTL_OPT;
1210 /* The Card Services build must ALWAYS configure for 16-bit I/O. PCI or
1211 CardBus can be set to either 16/32 bit I/O, or Bus Master DMA, but only
1212 for Hermes-2.5 */
1213 #ifdef BUS_PCMCIA
1214 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_16BIT );
1215 #else
1216 if ( lp->use_dma ) {
1217 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_DMA );
1218 } else {
1219 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1222 #endif
1223 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1224 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT : 0x%04x\n",
1225 lp->ltvRecord.u.u16[0] );
1226 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT result : 0x%04x\n",
1227 hcf_status );
1229 /* Register the list of RIDs on which asynchronous notification is
1230 required. Note that this mechanism replaces the mailbox, so the mailbox
1231 can be queried by the host (if desired) without contention from us */
1232 i=0;
1234 lp->RidList[i].len = sizeof( lp->ProbeResp );
1235 lp->RidList[i].typ = CFG_ACS_SCAN;
1236 lp->RidList[i].bufp = (wci_recordp)&lp->ProbeResp;
1237 //lp->ProbeResp.infoType = 0xFFFF;
1238 i++;
1240 lp->RidList[i].len = sizeof( lp->assoc_stat );
1241 lp->RidList[i].typ = CFG_ASSOC_STAT;
1242 lp->RidList[i].bufp = (wci_recordp)&lp->assoc_stat;
1243 lp->assoc_stat.len = 0xFFFF;
1244 i++;
1246 lp->RidList[i].len = 4;
1247 lp->RidList[i].typ = CFG_UPDATED_INFO_RECORD;
1248 lp->RidList[i].bufp = (wci_recordp)&lp->updatedRecord;
1249 lp->updatedRecord.len = 0xFFFF;
1250 i++;
1252 lp->RidList[i].len = sizeof( lp->sec_stat );
1253 lp->RidList[i].typ = CFG_SECURITY_STAT;
1254 lp->RidList[i].bufp = (wci_recordp)&lp->sec_stat;
1255 lp->sec_stat.len = 0xFFFF;
1256 i++;
1258 lp->RidList[i].typ = 0; // Terminate List
1260 RidLog = (CFG_RID_LOG_STRCT *)&lp->ltvRecord;
1261 RidLog->len = 3;
1262 RidLog->typ = CFG_REG_INFO_LOG;
1263 RidLog->recordp = (RID_LOGP)&lp->RidList[0];
1265 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1266 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG\n" );
1267 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG result : 0x%04x\n",
1268 hcf_status );
1269 DBG_LEAVE( DbgInfo );
1270 return hcf_status;
1271 } // wl_put_ltv_init
1272 /*============================================================================*/
1275 /*******************************************************************************
1276 * wl_put_ltv()
1277 *******************************************************************************
1279 * DESCRIPTION:
1281 * Used by wvlan_apply() and wvlan_go to set the card's configuration.
1283 * PARAMETERS:
1285 * lp - a pointer to the wireless adapter's private structure
1287 * RETURNS:
1289 * an HCF status code
1291 ******************************************************************************/
1292 int wl_put_ltv( struct wl_private *lp )
1294 int len;
1295 int hcf_status;
1296 /*------------------------------------------------------------------------*/
1297 DBG_FUNC( "wl_put_ltv" );
1298 DBG_ENTER( DbgInfo );
1300 if ( lp == NULL ) {
1301 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1302 return -1;
1304 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1305 lp->maxPort = 6; //;?why set this here and not as part of download process
1306 } else {
1307 lp->maxPort = 0;
1310 /* Send our configuration to the card. Perform any endian translation
1311 necessary */
1312 /* Register the Mailbox; VxWorks does this elsewhere; why;? */
1313 lp->ltvRecord.len = 4;
1314 lp->ltvRecord.typ = CFG_REG_MB;
1315 lp->ltvRecord.u.u32[0] = (u_long)&( lp->mailbox );
1316 lp->ltvRecord.u.u16[2] = ( MB_SIZE / sizeof( hcf_16 ));
1317 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1319 /* Max Data Length */
1320 lp->ltvRecord.len = 2;
1321 lp->ltvRecord.typ = CFG_CNF_MAX_DATA_LEN;
1322 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( HCF_MAX_PACKET_SIZE );
1323 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1325 /* System Scale / Distance between APs */
1326 lp->ltvRecord.len = 2;
1327 lp->ltvRecord.typ = CFG_CNF_SYSTEM_SCALE;
1328 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DistanceBetweenAPs );
1329 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1331 /* Channel */
1332 if ( lp->CreateIBSS && ( lp->Channel == 0 )) {
1333 DBG_TRACE( DbgInfo, "Create IBSS" );
1334 lp->Channel = 10;
1336 lp->ltvRecord.len = 2;
1337 lp->ltvRecord.typ = CFG_CNF_OWN_CHANNEL;
1338 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->Channel );
1339 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1341 /* Microwave Robustness */
1342 lp->ltvRecord.len = 2;
1343 lp->ltvRecord.typ = CFG_CNF_MICRO_WAVE;
1344 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MicrowaveRobustness );
1345 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1347 /* Load Balancing */
1348 lp->ltvRecord.len = 2;
1349 lp->ltvRecord.typ = CFG_CNF_LOAD_BALANCING;
1350 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->loadBalancing );
1351 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1353 /* Medium Distribution */
1354 lp->ltvRecord.len = 2;
1355 lp->ltvRecord.typ = CFG_CNF_MEDIUM_DISTRIBUTION;
1356 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->mediumDistribution );
1357 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1358 /* Country Code */
1360 #ifdef WARP
1361 /* Tx Power Level (for supported cards) */
1362 lp->ltvRecord.len = 2;
1363 lp->ltvRecord.typ = CFG_CNF_TX_POW_LVL;
1364 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->txPowLevel );
1365 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1367 /* Short Retry Limit */
1368 /*lp->ltvRecord.len = 2;
1369 lp->ltvRecord.typ = 0xFC32;
1370 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->shortRetryLimit );
1371 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1374 /* Long Retry Limit */
1375 /*lp->ltvRecord.len = 2;
1376 lp->ltvRecord.typ = 0xFC33;
1377 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->longRetryLimit );
1378 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1381 /* Supported Rate Set Control */
1382 lp->ltvRecord.len = 3;
1383 lp->ltvRecord.typ = CFG_SUPPORTED_RATE_SET_CNTL; //0xFC88;
1384 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->srsc[0] );
1385 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->srsc[1] );
1386 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1388 /* Basic Rate Set Control */
1389 lp->ltvRecord.len = 3;
1390 lp->ltvRecord.typ = CFG_BASIC_RATE_SET_CNTL; //0xFC89;
1391 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->brsc[0] );
1392 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->brsc[1] );
1393 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1395 /* Frame Burst Limit */
1396 /* Defined, but not currently available in Firmware */
1398 #endif // WARP
1400 #ifdef WARP
1401 /* Multicast Rate */
1402 lp->ltvRecord.len = 3;
1403 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1404 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1405 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->MulticastRate[1] );
1406 #else
1407 lp->ltvRecord.len = 2;
1408 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1409 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1410 #endif // WARP
1411 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1413 /* Own Name (Station Nickname) */
1414 if (( len = ( strlen( lp->StationName ) + 1 ) & ~0x01 ) != 0 ) {
1415 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : %s\n",
1416 // lp->StationName );
1418 lp->ltvRecord.len = 2 + ( len / sizeof( hcf_16 ));
1419 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1420 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->StationName ));
1422 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->StationName, len );
1423 } else {
1424 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : EMPTY\n" );
1426 lp->ltvRecord.len = 2;
1427 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1428 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1431 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1433 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME result : 0x%04x\n",
1434 // hcf_status );
1436 /* The following are set in STA mode only */
1437 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1439 /* RTS Threshold */
1440 lp->ltvRecord.len = 2;
1441 lp->ltvRecord.typ = CFG_RTS_THRH;
1442 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1443 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1445 /* Port Type */
1446 lp->ltvRecord.len = 2;
1447 lp->ltvRecord.typ = CFG_CNF_PORT_TYPE;
1448 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PortType );
1449 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1451 /* Tx Rate Control */
1452 #ifdef WARP
1453 lp->ltvRecord.len = 3;
1454 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1455 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1456 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1457 #else
1458 lp->ltvRecord.len = 2;
1459 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1460 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1461 #endif // WARP
1463 //;?skip temporarily to see whether the RID or something else is the probelm hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1465 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 2.4GHz : 0x%04x\n",
1466 lp->TxRateControl[0] );
1467 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 5.0GHz : 0x%04x\n",
1468 lp->TxRateControl[1] );
1469 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL result : 0x%04x\n",
1470 hcf_status );
1471 /* Power Management */
1472 lp->ltvRecord.len = 2;
1473 lp->ltvRecord.typ = CFG_CNF_PM_ENABLED;
1474 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PMEnabled );
1475 // lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0x8001 );
1476 DBG_TRACE( DbgInfo, "CFG_CNF_PM_ENABLED : 0x%04x\n", lp->PMEnabled );
1477 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1478 /* Multicast Receive */
1479 lp->ltvRecord.len = 2;
1480 lp->ltvRecord.typ = CFG_CNF_MCAST_RX;
1481 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastReceive );
1482 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1484 /* Max Sleep Duration */
1485 lp->ltvRecord.len = 2;
1486 lp->ltvRecord.typ = CFG_CNF_MAX_SLEEP_DURATION;
1487 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MaxSleepDuration );
1488 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1490 /* Create IBSS */
1491 lp->ltvRecord.len = 2;
1492 lp->ltvRecord.typ = CFG_CREATE_IBSS;
1493 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->CreateIBSS );
1494 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1496 /* Desired SSID */
1497 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1498 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1499 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1500 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : %s\n",
1501 // lp->NetworkName );
1503 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1504 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1505 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1507 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1508 } else {
1509 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : ANY\n" );
1511 lp->ltvRecord.len = 2;
1512 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1513 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1516 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1518 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID result : 0x%04x\n",
1519 // hcf_status );
1520 /* Own ATIM window */
1521 lp->ltvRecord.len = 2;
1522 lp->ltvRecord.typ = CFG_CNF_OWN_ATIM_WINDOW;
1523 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->atimWindow );
1524 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1527 /* Holdover Duration */
1528 lp->ltvRecord.len = 2;
1529 lp->ltvRecord.typ = CFG_CNF_HOLDOVER_DURATION;
1530 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->holdoverDuration );
1531 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1533 /* Promiscuous Mode */
1534 lp->ltvRecord.len = 2;
1535 lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
1536 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->promiscuousMode );
1537 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1539 /* Authentication */
1540 lp->ltvRecord.len = 2;
1541 lp->ltvRecord.typ = CFG_CNF_AUTHENTICATION;
1542 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->authentication );
1543 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1544 #ifdef WARP
1545 /* Connection Control */
1546 lp->ltvRecord.len = 2;
1547 lp->ltvRecord.typ = CFG_CNF_CONNECTION_CNTL;
1548 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->connectionControl );
1549 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1553 /* Probe data rate */
1554 /*lp->ltvRecord.len = 3;
1555 lp->ltvRecord.typ = CFG_PROBE_DATA_RATE;
1556 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->probeDataRates[0] );
1557 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->probeDataRates[1] );
1558 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1560 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 2.4GHz : 0x%04x\n",
1561 lp->probeDataRates[0] );
1562 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 5.0GHz : 0x%04x\n",
1563 lp->probeDataRates[1] );
1564 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE result : 0x%04x\n",
1565 hcf_status );*/
1566 #endif // WARP
1567 } else {
1568 /* The following are set in AP mode only */
1571 /* Own MAC Address */
1572 //DBG_TRACE( DbgInfo, "MAC Address : %s\n",
1573 // DbgHwAddr( lp->MACAddress ));
1575 if ( WVLAN_VALID_MAC_ADDRESS( lp->MACAddress )) {
1576 /* Make the MAC address valid by:
1577 Clearing the multicast bit
1578 Setting the local MAC address bit
1580 //lp->MACAddress[0] &= ~0x03; //;?why is this commented out already in 720
1581 //lp->MACAddress[0] |= 0x02;
1583 lp->ltvRecord.len = 1 + ( ETH_ALEN / sizeof( hcf_16 ));
1584 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1585 //DBG_TRACE( DbgInfo, "CFG_NIC_MAC_ADDR\n" );
1586 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1587 } else {
1588 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_MAC_ADDR\n" );
1589 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1591 /* MAC address is byte aligned, no endian conversion needed */
1592 memcpy( &( lp->ltvRecord.u.u8[0] ), lp->MACAddress, ETH_ALEN );
1593 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1594 //DBG_TRACE( DbgInfo, "CFG_XXX_MAC_ADDR result : 0x%04x\n",
1595 // hcf_status );
1597 /* Update the MAC address in the netdevice struct */
1598 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN ); //;?what is the purpose of this seemingly complex logic
1600 /* Own SSID */
1601 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1602 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1603 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1604 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : %s\n",
1605 // lp->NetworkName );
1606 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1607 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1608 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1610 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1611 } else {
1612 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : ANY\n" );
1613 lp->ltvRecord.len = 2;
1614 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1615 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1618 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1620 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID result : 0x%04x\n",
1621 // hcf_status );
1622 /* enable/disable encryption */
1623 lp->ltvRecord.len = 2;
1624 lp->ltvRecord.typ = CFG_CNF_ENCRYPTION;
1625 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->EnableEncryption );
1626 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1628 /* Set the Authentication Key Management Suite */
1629 lp->ltvRecord.len = 2;
1630 lp->ltvRecord.typ = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
1631 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->AuthKeyMgmtSuite );
1632 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1633 /* WEP Keys */
1634 wl_set_wep_keys( lp );
1636 /* Country Code */
1637 /* countryInfo, ltvCountryInfo, CFG_CNF_COUNTRY_INFO */
1639 DBG_LEAVE( DbgInfo );
1640 return hcf_status;
1641 } // wl_put_ltv
1642 /*============================================================================*/
1645 /*******************************************************************************
1646 * init_module()
1647 *******************************************************************************
1649 * DESCRIPTION:
1651 * Load the kernel module.
1653 * PARAMETERS:
1655 * N/A
1657 * RETURNS:
1659 * 0 on success
1660 * an errno value otherwise
1662 ******************************************************************************/
1663 static int __init wl_module_init( void )
1665 int result;
1666 /*------------------------------------------------------------------------*/
1668 DBG_FUNC( "wl_module_init" );
1670 #if DBG
1671 /* Convert "standard" PCMCIA parameter pc_debug to a reasonable DebugFlag value.
1672 * NOTE: The values all fall through to the lower values. */
1673 DbgInfo->DebugFlag = 0;
1674 DbgInfo->DebugFlag = DBG_TRACE_ON; //;?get this mess resolved one day
1675 if ( pc_debug ) switch( pc_debug ) {
1676 case 8:
1677 DbgInfo->DebugFlag |= DBG_DS_ON;
1678 case 7:
1679 DbgInfo->DebugFlag |= DBG_RX_ON | DBG_TX_ON;
1680 case 6:
1681 DbgInfo->DebugFlag |= DBG_PARAM_ON;
1682 case 5:
1683 DbgInfo->DebugFlag |= DBG_TRACE_ON;
1684 case 4:
1685 DbgInfo->DebugFlag |= DBG_VERBOSE_ON;
1686 case 1:
1687 DbgInfo->DebugFlag |= DBG_DEFAULTS;
1688 default:
1689 break;
1691 #endif /* DBG */
1693 DBG_ENTER( DbgInfo );
1694 printk(KERN_INFO "%s\n", VERSION_INFO);
1695 printk(KERN_INFO "*** Modified for kernel 2.6 by Henk de Groot <pe1dnn@amsat.org>\n");
1696 printk(KERN_INFO "*** Based on 7.18 version by Andrey Borzenkov <arvidjaar@mail.ru> $Revision: 39 $\n");
1699 // ;?#if (HCF_TYPE) & HCF_TYPE_AP
1700 // DBG_PRINT( "Access Point Mode (AP) Support: YES\n" );
1701 // #else
1702 // DBG_PRINT( "Access Point Mode (AP) Support: NO\n" );
1703 // #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1705 result = wl_adapter_init_module( );
1706 DBG_LEAVE( DbgInfo );
1707 return result;
1708 } // init_module
1709 /*============================================================================*/
1712 /*******************************************************************************
1713 * cleanup_module()
1714 *******************************************************************************
1716 * DESCRIPTION:
1718 * Unload the kernel module.
1720 * PARAMETERS:
1722 * N/A
1724 * RETURNS:
1726 * N/A
1728 ******************************************************************************/
1729 static void __exit wl_module_exit( void )
1731 DBG_FUNC( "wl_module_exit" );
1732 DBG_ENTER(DbgInfo);
1734 wl_adapter_cleanup_module( );
1735 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
1736 remove_proc_entry( "wlags", NULL ); //;?why so a-symmetric compared to location of create_proc_read_entry
1737 #endif
1739 DBG_LEAVE( DbgInfo );
1740 return;
1741 } // cleanup_module
1742 /*============================================================================*/
1744 module_init(wl_module_init);
1745 module_exit(wl_module_exit);
1747 /*******************************************************************************
1748 * wl_isr()
1749 *******************************************************************************
1751 * DESCRIPTION:
1753 * The Interrupt Service Routine for the driver.
1755 * PARAMETERS:
1757 * irq - the irq the interrupt came in on
1758 * dev_id - a buffer containing information about the request
1759 * regs -
1761 * RETURNS:
1763 * N/A
1765 ******************************************************************************/
1766 irqreturn_t wl_isr( int irq, void *dev_id, struct pt_regs *regs )
1768 int events;
1769 struct net_device *dev = (struct net_device *) dev_id;
1770 struct wl_private *lp = NULL;
1771 /*------------------------------------------------------------------------*/
1772 if (( dev == NULL ) || ( !netif_device_present( dev ))) {
1773 return IRQ_NONE;
1776 /* Set the wl_private pointer (lp), now that we know that dev is non-null */
1777 lp = wl_priv(dev);
1779 #ifdef USE_RTS
1780 if ( lp->useRTS == 1 ) {
1781 DBG_PRINT( "EXITING ISR, IN RTS MODE...\n" );
1782 return;
1784 #endif /* USE_RTS */
1786 /* If we have interrupts pending, then put them on a system task
1787 queue. Otherwise turn interrupts back on */
1788 events = hcf_action( &lp->hcfCtx, HCF_ACT_INT_OFF );
1790 if ( events == HCF_INT_PENDING ) {
1791 /* Schedule the ISR handler as a bottom-half task in the
1792 tq_immediate queue */
1793 tasklet_schedule(&lp->task);
1794 } else {
1795 //DBG_PRINT( "NOT OUR INTERRUPT\n" );
1796 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
1799 return IRQ_RETVAL(events == HCF_INT_PENDING);
1800 } // wl_isr
1801 /*============================================================================*/
1804 /*******************************************************************************
1805 * wl_isr_handler()
1806 *******************************************************************************
1808 * DESCRIPTION:
1810 * The ISR handler, scheduled to run in a deferred context by the ISR. This
1811 * is where the ISR's work actually gets done.
1813 * PARAMETERS:
1815 * lp - a pointer to the device's private adapter structure
1817 * RETURNS:
1819 * N/A
1821 ******************************************************************************/
1822 #define WVLAN_MAX_INT_SERVICES 50
1824 void wl_isr_handler( unsigned long p )
1826 struct net_device *dev;
1827 unsigned long flags;
1828 bool_t stop = TRUE;
1829 int count;
1830 int result;
1831 struct wl_private *lp = (struct wl_private *)p;
1832 /*------------------------------------------------------------------------*/
1834 if ( lp == NULL ) {
1835 DBG_PRINT( "wl_isr_handler lp adapter pointer is NULL!!!\n" );
1836 } else {
1837 wl_lock( lp, &flags );
1839 dev = (struct net_device *)lp->dev;
1840 if ( dev != NULL && netif_device_present( dev ) ) stop = FALSE;
1841 for( count = 0; stop == FALSE && count < WVLAN_MAX_INT_SERVICES; count++ ) {
1842 stop = TRUE;
1843 result = hcf_service_nic( &lp->hcfCtx,
1844 (wci_bufp)lp->lookAheadBuf,
1845 sizeof( lp->lookAheadBuf ));
1846 if ( result == HCF_ERR_MIC ) {
1847 wl_wext_event_mic_failed( dev ); /* Send an event that MIC failed */
1848 //;?this seems wrong if HCF_ERR_MIC coincides with another event, stop gets FALSE
1849 //so why not do it always ;?
1852 #ifndef USE_MBOX_SYNC
1853 if ( lp->hcfCtx.IFB_MBInfoLen != 0 ) { /* anything in the mailbox */
1854 wl_mbx( lp );
1855 stop = FALSE;
1857 #endif
1858 /* Check for a Link status event */
1859 if ( ( lp->hcfCtx.IFB_LinkStat & CFG_LINK_STAT_FW ) != 0 ) {
1860 wl_process_link_status( lp );
1861 stop = FALSE;
1863 /* Check for probe response events */
1864 if ( lp->ProbeResp.infoType != 0 &&
1865 lp->ProbeResp.infoType != 0xFFFF ) {
1866 wl_process_probe_response( lp );
1867 memset( &lp->ProbeResp, 0, sizeof( lp->ProbeResp ));
1868 lp->ProbeResp.infoType = 0xFFFF;
1869 stop = FALSE;
1871 /* Check for updated record events */
1872 if ( lp->updatedRecord.len != 0xFFFF ) {
1873 wl_process_updated_record( lp );
1874 lp->updatedRecord.len = 0xFFFF;
1875 stop = FALSE;
1877 /* Check for association status events */
1878 if ( lp->assoc_stat.len != 0xFFFF ) {
1879 wl_process_assoc_status( lp );
1880 lp->assoc_stat.len = 0xFFFF;
1881 stop = FALSE;
1883 /* Check for security status events */
1884 if ( lp->sec_stat.len != 0xFFFF ) {
1885 wl_process_security_status( lp );
1886 lp->sec_stat.len = 0xFFFF;
1887 stop = FALSE;
1890 #ifdef ENABLE_DMA
1891 if ( lp->use_dma ) {
1892 /* Check for DMA Rx packets */
1893 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_RDMAD ) {
1894 wl_rx_dma( dev );
1895 stop = FALSE;
1897 /* Return Tx DMA descriptors to host */
1898 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_TDMAD ) {
1899 wl_pci_dma_hcf_reclaim_tx( lp );
1900 stop = FALSE;
1903 else
1904 #endif // ENABLE_DMA
1906 /* Check for Rx packets */
1907 if ( lp->hcfCtx.IFB_RxLen != 0 ) {
1908 wl_rx( dev );
1909 stop = FALSE;
1911 /* Make sure that queued frames get sent */
1912 if ( wl_send( lp )) {
1913 stop = FALSE;
1917 /* We're done, so turn interrupts which were turned off in wl_isr, back on */
1918 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
1919 wl_unlock( lp, &flags );
1921 return;
1922 } // wl_isr_handler
1923 /*============================================================================*/
1926 /*******************************************************************************
1927 * wl_remove()
1928 *******************************************************************************
1930 * DESCRIPTION:
1932 * Notify the adapter that it has been removed. Since the adapter is gone,
1933 * we should no longer try to talk to it.
1935 * PARAMETERS:
1937 * dev - a pointer to the device's net_device structure
1939 * RETURNS:
1941 * N/A
1943 ******************************************************************************/
1944 void wl_remove( struct net_device *dev )
1946 struct wl_private *lp = wl_priv(dev);
1947 unsigned long flags;
1948 /*------------------------------------------------------------------------*/
1949 DBG_FUNC( "wl_remove" );
1950 DBG_ENTER( DbgInfo );
1952 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
1954 wl_lock( lp, &flags );
1956 /* stop handling interrupts */
1957 wl_act_int_off( lp );
1958 lp->is_handling_int = WL_NOT_HANDLING_INT;
1961 * Disable the ports: just change state: since the
1962 * card is gone it is useless to talk to it and at
1963 * disconnect all state information is lost anyway.
1965 /* Reset portState */
1966 lp->portState = WVLAN_PORT_STATE_DISABLED;
1969 /* Mark the device as unregistered */
1970 lp->is_registered = FALSE;
1972 /* Deregister the WDS ports as well */
1973 WL_WDS_NETDEV_DEREGISTER( lp );
1974 #ifdef USE_RTS
1975 if ( lp->useRTS == 1 ) {
1976 wl_unlock( lp, &flags );
1978 DBG_LEAVE( DbgInfo );
1979 return;
1981 #endif /* USE_RTS */
1983 /* Inform the HCF that the card has been removed */
1984 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
1986 wl_unlock( lp, &flags );
1988 DBG_LEAVE( DbgInfo );
1989 return;
1990 } // wl_remove
1991 /*============================================================================*/
1994 /*******************************************************************************
1995 * wl_suspend()
1996 *******************************************************************************
1998 * DESCRIPTION:
2000 * Power-down and halt the adapter.
2002 * PARAMETERS:
2004 * dev - a pointer to the device's net_device structure
2006 * RETURNS:
2008 * N/A
2010 ******************************************************************************/
2011 void wl_suspend( struct net_device *dev )
2013 struct wl_private *lp = wl_priv(dev);
2014 unsigned long flags;
2015 /*------------------------------------------------------------------------*/
2016 DBG_FUNC( "wl_suspend" );
2017 DBG_ENTER( DbgInfo );
2019 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2021 /* The adapter is suspended:
2022 Stop the adapter
2023 Power down
2025 wl_lock( lp, &flags );
2027 /* Disable interrupt handling */
2028 wl_act_int_off( lp );
2030 /* Disconnect */
2031 wl_disconnect( lp );
2033 /* Disable */
2034 wl_disable( lp );
2036 /* Disconnect from the adapter */
2037 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2039 /* Reset portState to be sure (should have been done by wl_disable */
2040 lp->portState = WVLAN_PORT_STATE_DISABLED;
2042 wl_unlock( lp, &flags );
2044 DBG_LEAVE( DbgInfo );
2045 return;
2046 } // wl_suspend
2047 /*============================================================================*/
2050 /*******************************************************************************
2051 * wl_resume()
2052 *******************************************************************************
2054 * DESCRIPTION:
2056 * Resume a previously suspended adapter.
2058 * PARAMETERS:
2060 * dev - a pointer to the device's net_device structure
2062 * RETURNS:
2064 * N/A
2066 ******************************************************************************/
2067 void wl_resume(struct net_device *dev)
2069 struct wl_private *lp = wl_priv(dev);
2070 unsigned long flags;
2071 /*------------------------------------------------------------------------*/
2072 DBG_FUNC( "wl_resume" );
2073 DBG_ENTER( DbgInfo );
2075 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2077 wl_lock( lp, &flags );
2079 /* Connect to the adapter */
2080 hcf_connect( &lp->hcfCtx, dev->base_addr );
2082 /* Reset portState */
2083 lp->portState = WVLAN_PORT_STATE_DISABLED;
2085 /* Power might have been off, assume the card lost the firmware*/
2086 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
2088 /* Reload the firmware and restart */
2089 wl_reset( dev );
2091 /* Resume interrupt handling */
2092 wl_act_int_on( lp );
2094 wl_unlock( lp, &flags );
2096 DBG_LEAVE( DbgInfo );
2097 return;
2098 } // wl_resume
2099 /*============================================================================*/
2102 /*******************************************************************************
2103 * wl_release()
2104 *******************************************************************************
2106 * DESCRIPTION:
2108 * This function perfroms a check on the device and calls wl_remove() if
2109 * necessary. This function can be used for all bus types, but exists mostly
2110 * for the benefit of the Card Services driver, as there are times when
2111 * wl_remove() does not get called.
2113 * PARAMETERS:
2115 * dev - a pointer to the device's net_device structure
2117 * RETURNS:
2119 * N/A
2121 ******************************************************************************/
2122 void wl_release( struct net_device *dev )
2124 struct wl_private *lp = wl_priv(dev);
2125 /*------------------------------------------------------------------------*/
2126 DBG_FUNC( "wl_release" );
2127 DBG_ENTER( DbgInfo );
2129 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2130 /* If wl_remove() hasn't been called (i.e. when Card Services is shut
2131 down with the card in the slot), then call it */
2132 if ( lp->is_registered == TRUE ) {
2133 DBG_TRACE( DbgInfo, "Calling unregister_netdev(), as it wasn't called yet\n" );
2134 wl_remove( dev );
2136 lp->is_registered = FALSE;
2139 DBG_LEAVE( DbgInfo );
2140 return;
2141 } // wl_release
2142 /*============================================================================*/
2145 /*******************************************************************************
2146 * wl_get_irq_mask()
2147 *******************************************************************************
2149 * DESCRIPTION:
2151 * Accessor function to retrieve the irq_mask module parameter
2153 * PARAMETERS:
2155 * N/A
2157 * RETURNS:
2159 * The irq_mask module parameter
2161 ******************************************************************************/
2162 p_u16 wl_get_irq_mask( void )
2164 return irq_mask;
2165 } // wl_get_irq_mask
2166 /*============================================================================*/
2169 /*******************************************************************************
2170 * wl_get_irq_list()
2171 *******************************************************************************
2173 * DESCRIPTION:
2175 * Accessor function to retrieve the irq_list module parameter
2177 * PARAMETERS:
2179 * N/A
2181 * RETURNS:
2183 * The irq_list module parameter
2185 ******************************************************************************/
2186 p_s8 * wl_get_irq_list( void )
2188 return irq_list;
2189 } // wl_get_irq_list
2190 /*============================================================================*/
2194 /*******************************************************************************
2195 * wl_enable()
2196 *******************************************************************************
2198 * DESCRIPTION:
2200 * Used to enable MAC ports
2202 * PARAMETERS:
2204 * lp - pointer to the device's private adapter structure
2206 * RETURNS:
2208 * N/A
2210 ******************************************************************************/
2211 int wl_enable( struct wl_private *lp )
2213 int hcf_status = HCF_SUCCESS;
2214 /*------------------------------------------------------------------------*/
2215 DBG_FUNC( "wl_enable" );
2216 DBG_ENTER( DbgInfo );
2218 if ( lp->portState == WVLAN_PORT_STATE_ENABLED ) {
2219 DBG_TRACE( DbgInfo, "No action: Card already enabled\n" );
2220 } else if ( lp->portState == WVLAN_PORT_STATE_CONNECTED ) {
2221 //;?suspicuous logic, how can you be connected without being enabled so this is probably dead code
2222 DBG_TRACE( DbgInfo, "No action: Card already connected\n" );
2223 } else {
2224 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_ENABLE );
2225 if ( hcf_status == HCF_SUCCESS ) {
2226 /* Set the status of the NIC to enabled */
2227 lp->portState = WVLAN_PORT_STATE_ENABLED; //;?bad mnemonic, NIC iso PORT
2228 #ifdef ENABLE_DMA
2229 if ( lp->use_dma ) {
2230 wl_pci_dma_hcf_supply( lp ); //;?always succes?
2232 #endif
2235 if ( hcf_status != HCF_SUCCESS ) { //;?make this an assert
2236 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2238 DBG_LEAVE( DbgInfo );
2239 return hcf_status;
2240 } // wl_enable
2241 /*============================================================================*/
2244 #ifdef USE_WDS
2245 /*******************************************************************************
2246 * wl_enable_wds_ports()
2247 *******************************************************************************
2249 * DESCRIPTION:
2251 * Used to enable the WDS MAC ports 1-6
2253 * PARAMETERS:
2255 * lp - pointer to the device's private adapter structure
2257 * RETURNS:
2259 * N/A
2261 ******************************************************************************/
2262 void wl_enable_wds_ports( struct wl_private * lp )
2265 DBG_FUNC( "wl_enable_wds_ports" );
2266 DBG_ENTER( DbgInfo );
2267 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2268 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2270 DBG_LEAVE( DbgInfo );
2271 return;
2272 } // wl_enable_wds_ports
2273 #endif /* USE_WDS */
2274 /*============================================================================*/
2277 /*******************************************************************************
2278 * wl_connect()
2279 *******************************************************************************
2281 * DESCRIPTION:
2283 * Used to connect a MAC port
2285 * PARAMETERS:
2287 * lp - pointer to the device's private adapter structure
2289 * RETURNS:
2291 * N/A
2293 ******************************************************************************/
2294 int wl_connect( struct wl_private *lp )
2296 int hcf_status;
2297 /*------------------------------------------------------------------------*/
2299 DBG_FUNC( "wl_connect" );
2300 DBG_ENTER( DbgInfo );
2302 if ( lp->portState != WVLAN_PORT_STATE_ENABLED ) {
2303 DBG_TRACE( DbgInfo, "No action: Not in enabled state\n" );
2304 DBG_LEAVE( DbgInfo );
2305 return HCF_SUCCESS;
2307 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_CONNECT );
2308 if ( hcf_status == HCF_SUCCESS ) {
2309 lp->portState = WVLAN_PORT_STATE_CONNECTED;
2311 DBG_LEAVE( DbgInfo );
2312 return hcf_status;
2313 } // wl_connect
2314 /*============================================================================*/
2317 /*******************************************************************************
2318 * wl_disconnect()
2319 *******************************************************************************
2321 * DESCRIPTION:
2323 * Used to disconnect a MAC port
2325 * PARAMETERS:
2327 * lp - pointer to the device's private adapter structure
2329 * RETURNS:
2331 * N/A
2333 ******************************************************************************/
2334 int wl_disconnect( struct wl_private *lp )
2336 int hcf_status;
2337 /*------------------------------------------------------------------------*/
2339 DBG_FUNC( "wl_disconnect" );
2340 DBG_ENTER( DbgInfo );
2342 if ( lp->portState != WVLAN_PORT_STATE_CONNECTED ) {
2343 DBG_TRACE( DbgInfo, "No action: Not in connected state\n" );
2344 DBG_LEAVE( DbgInfo );
2345 return HCF_SUCCESS;
2347 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISCONNECT );
2348 if ( hcf_status == HCF_SUCCESS ) {
2349 lp->portState = WVLAN_PORT_STATE_ENABLED;
2351 DBG_LEAVE( DbgInfo );
2352 return hcf_status;
2353 } // wl_disconnect
2354 /*============================================================================*/
2357 /*******************************************************************************
2358 * wl_disable()
2359 *******************************************************************************
2361 * DESCRIPTION:
2363 * Used to disable MAC ports
2365 * PARAMETERS:
2367 * lp - pointer to the device's private adapter structure
2368 * port - the MAC port to disable
2370 * RETURNS:
2372 * N/A
2374 ******************************************************************************/
2375 int wl_disable( struct wl_private *lp )
2377 int hcf_status = HCF_SUCCESS;
2378 /*------------------------------------------------------------------------*/
2379 DBG_FUNC( "wl_disable" );
2380 DBG_ENTER( DbgInfo );
2382 if ( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
2383 DBG_TRACE( DbgInfo, "No action: Port state is disabled\n" );
2384 } else {
2385 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISABLE );
2386 if ( hcf_status == HCF_SUCCESS ) {
2387 /* Set the status of the port to disabled */ //;?bad mnemonic use NIC iso PORT
2388 lp->portState = WVLAN_PORT_STATE_DISABLED;
2390 #ifdef ENABLE_DMA
2391 if ( lp->use_dma ) {
2392 wl_pci_dma_hcf_reclaim( lp );
2394 #endif
2397 if ( hcf_status != HCF_SUCCESS ) {
2398 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2400 DBG_LEAVE( DbgInfo );
2401 return hcf_status;
2402 } // wl_disable
2403 /*============================================================================*/
2406 #ifdef USE_WDS
2407 /*******************************************************************************
2408 * wl_disable_wds_ports()
2409 *******************************************************************************
2411 * DESCRIPTION:
2413 * Used to disable the WDS MAC ports 1-6
2415 * PARAMETERS:
2417 * lp - pointer to the device's private adapter structure
2419 * RETURNS:
2421 * N/A
2423 ******************************************************************************/
2424 void wl_disable_wds_ports( struct wl_private * lp )
2427 DBG_FUNC( "wl_disable_wds_ports" );
2428 DBG_ENTER( DbgInfo );
2430 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2431 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2433 // if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
2434 // wl_disable( lp, HCF_PORT_1 );
2435 // wl_disable( lp, HCF_PORT_2 );
2436 // wl_disable( lp, HCF_PORT_3 );
2437 // wl_disable( lp, HCF_PORT_4 );
2438 // wl_disable( lp, HCF_PORT_5 );
2439 // wl_disable( lp, HCF_PORT_6 );
2440 // }
2441 DBG_LEAVE( DbgInfo );
2442 return;
2443 } // wl_disable_wds_ports
2444 #endif // USE_WDS
2445 /*============================================================================*/
2448 #ifndef USE_MBOX_SYNC
2449 /*******************************************************************************
2450 * wl_mbx()
2451 *******************************************************************************
2453 * DESCRIPTION:
2454 * This function is used to read and process a mailbox message.
2457 * PARAMETERS:
2459 * lp - pointer to the device's private adapter structure
2461 * RETURNS:
2463 * an HCF status code
2465 ******************************************************************************/
2466 int wl_mbx( struct wl_private *lp )
2468 int hcf_status = HCF_SUCCESS;
2469 /*------------------------------------------------------------------------*/
2470 DBG_FUNC( "wl_mbx" );
2471 DBG_ENTER( DbgInfo );
2472 DBG_TRACE( DbgInfo, "Mailbox Info: IFB_MBInfoLen: %d\n",
2473 lp->hcfCtx.IFB_MBInfoLen );
2475 memset( &( lp->ltvRecord ), 0, sizeof( ltv_t ));
2477 lp->ltvRecord.len = MB_SIZE;
2478 lp->ltvRecord.typ = CFG_MB_INFO;
2479 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2481 if ( hcf_status != HCF_SUCCESS ) {
2482 DBG_ERROR( DbgInfo, "hcf_get_info returned 0x%x\n", hcf_status );
2484 DBG_LEAVE( DbgInfo );
2485 return hcf_status;
2488 if ( lp->ltvRecord.typ == CFG_MB_INFO ) {
2489 DBG_LEAVE( DbgInfo );
2490 return hcf_status;
2492 /* Endian translate the mailbox data, then process the message */
2493 wl_endian_translate_mailbox( &( lp->ltvRecord ));
2494 wl_process_mailbox( lp );
2495 DBG_LEAVE( DbgInfo );
2496 return hcf_status;
2497 } // wl_mbx
2498 /*============================================================================*/
2501 /*******************************************************************************
2502 * wl_endian_translate_mailbox()
2503 *******************************************************************************
2505 * DESCRIPTION:
2507 * This function will perform the tedious task of endian translating all
2508 * fields withtin a mailbox message which need translating.
2510 * PARAMETERS:
2512 * ltv - pointer to the LTV to endian translate
2514 * RETURNS:
2516 * none
2518 ******************************************************************************/
2519 void wl_endian_translate_mailbox( ltv_t *ltv )
2522 DBG_FUNC( "wl_endian_translate_mailbox" );
2523 DBG_ENTER( DbgInfo );
2524 switch( ltv->typ ) {
2525 case CFG_TALLIES:
2526 break;
2528 case CFG_SCAN:
2530 int num_aps;
2531 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)&ltv->u.u8[0];
2533 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2534 ( sizeof( SCAN_RS_STRCT )));
2536 while( num_aps >= 1 ) {
2537 num_aps--;
2539 aps[num_aps].channel_id =
2540 CNV_LITTLE_TO_INT( aps[num_aps].channel_id );
2542 aps[num_aps].noise_level =
2543 CNV_LITTLE_TO_INT( aps[num_aps].noise_level );
2545 aps[num_aps].signal_level =
2546 CNV_LITTLE_TO_INT( aps[num_aps].signal_level );
2548 aps[num_aps].beacon_interval_time =
2549 CNV_LITTLE_TO_INT( aps[num_aps].beacon_interval_time );
2551 aps[num_aps].capability =
2552 CNV_LITTLE_TO_INT( aps[num_aps].capability );
2554 aps[num_aps].ssid_len =
2555 CNV_LITTLE_TO_INT( aps[num_aps].ssid_len );
2557 aps[num_aps].ssid_val[aps[num_aps].ssid_len] = 0;
2560 break;
2562 case CFG_ACS_SCAN:
2564 PROBE_RESP *probe_resp = (PROBE_RESP *)ltv;
2566 probe_resp->frameControl = CNV_LITTLE_TO_INT( probe_resp->frameControl );
2567 probe_resp->durID = CNV_LITTLE_TO_INT( probe_resp->durID );
2568 probe_resp->sequence = CNV_LITTLE_TO_INT( probe_resp->sequence );
2569 probe_resp->dataLength = CNV_LITTLE_TO_INT( probe_resp->dataLength );
2570 #ifndef WARP
2571 probe_resp->lenType = CNV_LITTLE_TO_INT( probe_resp->lenType );
2572 #endif // WARP
2573 probe_resp->beaconInterval = CNV_LITTLE_TO_INT( probe_resp->beaconInterval );
2574 probe_resp->capability = CNV_LITTLE_TO_INT( probe_resp->capability );
2575 probe_resp->flags = CNV_LITTLE_TO_INT( probe_resp->flags );
2577 break;
2579 case CFG_LINK_STAT:
2580 #define ls ((LINK_STATUS_STRCT *)ltv)
2581 ls->linkStatus = CNV_LITTLE_TO_INT( ls->linkStatus );
2582 break;
2583 #undef ls
2585 case CFG_ASSOC_STAT:
2587 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
2589 as->assocStatus = CNV_LITTLE_TO_INT( as->assocStatus );
2591 break;
2593 case CFG_SECURITY_STAT:
2595 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
2597 ss->securityStatus = CNV_LITTLE_TO_INT( ss->securityStatus );
2598 ss->reason = CNV_LITTLE_TO_INT( ss->reason );
2600 break;
2602 case CFG_WMP:
2603 break;
2605 case CFG_NULL:
2606 break;
2608 default:
2609 break;
2612 DBG_LEAVE( DbgInfo );
2613 return;
2614 } // wl_endian_translate_mailbox
2615 /*============================================================================*/
2617 /*******************************************************************************
2618 * wl_process_mailbox()
2619 *******************************************************************************
2621 * DESCRIPTION:
2623 * This function will process the mailbox data.
2625 * PARAMETERS:
2627 * ltv - pointer to the LTV to be processed.
2629 * RETURNS:
2631 * none
2633 ******************************************************************************/
2634 void wl_process_mailbox( struct wl_private *lp )
2636 ltv_t *ltv;
2637 hcf_16 ltv_val = 0xFFFF;
2638 /*------------------------------------------------------------------------*/
2639 DBG_FUNC( "wl_process_mailbox" );
2640 DBG_ENTER( DbgInfo );
2641 ltv = &( lp->ltvRecord );
2643 switch( ltv->typ ) {
2645 case CFG_TALLIES:
2646 DBG_TRACE( DbgInfo, "CFG_TALLIES\n" );
2647 break;
2648 case CFG_SCAN:
2649 DBG_TRACE( DbgInfo, "CFG_SCAN\n" );
2652 int num_aps;
2653 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)&ltv->u.u8[0];
2655 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2656 ( sizeof( SCAN_RS_STRCT )));
2658 lp->scan_results.num_aps = num_aps;
2660 DBG_TRACE( DbgInfo, "Number of APs: %d\n", num_aps );
2662 while( num_aps >= 1 ) {
2663 num_aps--;
2665 DBG_TRACE( DbgInfo, "AP : %d\n", num_aps );
2666 DBG_TRACE( DbgInfo, "=========================\n" );
2667 DBG_TRACE( DbgInfo, "Channel ID : 0x%04x\n",
2668 aps[num_aps].channel_id );
2669 DBG_TRACE( DbgInfo, "Noise Level : 0x%04x\n",
2670 aps[num_aps].noise_level );
2671 DBG_TRACE( DbgInfo, "Signal Level : 0x%04x\n",
2672 aps[num_aps].signal_level );
2673 DBG_TRACE( DbgInfo, "Beacon Interval : 0x%04x\n",
2674 aps[num_aps].beacon_interval_time );
2675 DBG_TRACE( DbgInfo, "Capability : 0x%04x\n",
2676 aps[num_aps].capability );
2677 DBG_TRACE( DbgInfo, "SSID Length : 0x%04x\n",
2678 aps[num_aps].ssid_len );
2679 DBG_TRACE( DbgInfo, "BSSID : %s\n",
2680 DbgHwAddr( aps[num_aps].bssid ));
2682 if ( aps[num_aps].ssid_len != 0 ) {
2683 DBG_TRACE( DbgInfo, "SSID : %s.\n",
2684 aps[num_aps].ssid_val );
2685 } else {
2686 DBG_TRACE( DbgInfo, "SSID : %s.\n", "ANY" );
2689 DBG_TRACE( DbgInfo, "\n" );
2691 /* Copy the info to the ScanResult structure in the private
2692 adapter struct */
2693 memcpy( &( lp->scan_results.APTable[num_aps]), &( aps[num_aps] ),
2694 sizeof( SCAN_RS_STRCT ));
2697 /* Set scan result to true so that any scan requests will
2698 complete */
2699 lp->scan_results.scan_complete = TRUE;
2702 break;
2703 case CFG_ACS_SCAN:
2704 DBG_TRACE( DbgInfo, "CFG_ACS_SCAN\n" );
2707 PROBE_RESP *probe_rsp = (PROBE_RESP *)ltv;
2708 hcf_8 *wpa_ie = NULL;
2709 hcf_16 wpa_ie_len = 0;
2711 DBG_TRACE( DbgInfo, "(%s) =========================\n",
2712 lp->dev->name );
2714 DBG_TRACE( DbgInfo, "(%s) length : 0x%04x.\n",
2715 lp->dev->name, probe_rsp->length );
2717 if ( probe_rsp->length > 1 ) {
2718 DBG_TRACE( DbgInfo, "(%s) infoType : 0x%04x.\n",
2719 lp->dev->name, probe_rsp->infoType );
2721 DBG_TRACE( DbgInfo, "(%s) signal : 0x%02x.\n",
2722 lp->dev->name, probe_rsp->signal );
2724 DBG_TRACE( DbgInfo, "(%s) silence : 0x%02x.\n",
2725 lp->dev->name, probe_rsp->silence );
2727 DBG_TRACE( DbgInfo, "(%s) rxFlow : 0x%02x.\n",
2728 lp->dev->name, probe_rsp->rxFlow );
2730 DBG_TRACE( DbgInfo, "(%s) rate : 0x%02x.\n",
2731 lp->dev->name, probe_rsp->rate );
2733 DBG_TRACE( DbgInfo, "(%s) frame cntl : 0x%04x.\n",
2734 lp->dev->name, probe_rsp->frameControl );
2736 DBG_TRACE( DbgInfo, "(%s) durID : 0x%04x.\n",
2737 lp->dev->name, probe_rsp->durID );
2739 DBG_TRACE( DbgInfo, "(%s) address1 : %s\n",
2740 lp->dev->name, DbgHwAddr( probe_rsp->address1 ));
2742 DBG_TRACE( DbgInfo, "(%s) address2 : %s\n",
2743 lp->dev->name, DbgHwAddr( probe_rsp->address2 ));
2745 DBG_TRACE( DbgInfo, "(%s) BSSID : %s\n",
2746 lp->dev->name, DbgHwAddr( probe_rsp->BSSID ));
2748 DBG_TRACE( DbgInfo, "(%s) sequence : 0x%04x.\n",
2749 lp->dev->name, probe_rsp->sequence );
2751 DBG_TRACE( DbgInfo, "(%s) address4 : %s\n",
2752 lp->dev->name, DbgHwAddr( probe_rsp->address4 ));
2754 DBG_TRACE( DbgInfo, "(%s) datalength : 0x%04x.\n",
2755 lp->dev->name, probe_rsp->dataLength );
2757 DBG_TRACE( DbgInfo, "(%s) DA : %s\n",
2758 lp->dev->name, DbgHwAddr( probe_rsp->DA ));
2760 DBG_TRACE( DbgInfo, "(%s) SA : %s\n",
2761 lp->dev->name, DbgHwAddr( probe_rsp->SA ));
2763 //DBG_TRACE( DbgInfo, "(%s) lenType : 0x%04x.\n",
2764 // lp->dev->name, probe_rsp->lenType );
2766 DBG_TRACE( DbgInfo, "(%s) timeStamp : %s\n",
2767 lp->dev->name, DbgHwAddr( probe_rsp->timeStamp ));
2769 DBG_TRACE( DbgInfo, "(%s) beaconInt : 0x%04x.\n",
2770 lp->dev->name, probe_rsp->beaconInterval );
2772 DBG_TRACE( DbgInfo, "(%s) capability : 0x%04x.\n",
2773 lp->dev->name, probe_rsp->capability );
2775 DBG_TRACE( DbgInfo, "(%s) SSID len : 0x%04x.\n",
2776 lp->dev->name, probe_rsp->rawData[1] );
2778 if ( probe_rsp->rawData[1] > 0 ) {
2779 char ssid[HCF_MAX_NAME_LEN];
2781 memset( ssid, 0, sizeof( ssid ));
2782 strncpy( ssid, &probe_rsp->rawData[2],
2783 probe_rsp->rawData[1] );
2785 DBG_TRACE( DbgInfo, "(%s) SSID : %s\n",
2786 lp->dev->name, ssid );
2789 /* Parse out the WPA-IE, if one exists */
2790 wpa_ie = wl_parse_wpa_ie( probe_rsp, &wpa_ie_len );
2791 if ( wpa_ie != NULL ) {
2792 DBG_TRACE( DbgInfo, "(%s) WPA-IE : %s\n",
2793 lp->dev->name, wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
2796 DBG_TRACE( DbgInfo, "(%s) flags : 0x%04x.\n",
2797 lp->dev->name, probe_rsp->flags );
2800 DBG_TRACE( DbgInfo, "\n\n" );
2801 /* If probe response length is 1, then the scan is complete */
2802 if ( probe_rsp->length == 1 ) {
2803 DBG_TRACE( DbgInfo, "SCAN COMPLETE\n" );
2804 lp->probe_results.num_aps = lp->probe_num_aps;
2805 lp->probe_results.scan_complete = TRUE;
2807 /* Reset the counter for the next scan request */
2808 lp->probe_num_aps = 0;
2810 /* Send a wireless extensions event that the scan completed */
2811 wl_wext_event_scan_complete( lp->dev );
2812 } else {
2813 /* Only copy to the table if the entry is unique; APs sometimes
2814 respond more than once to a probe */
2815 if ( lp->probe_num_aps == 0 ) {
2816 /* Copy the info to the ScanResult structure in the private
2817 adapter struct */
2818 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
2819 probe_rsp, sizeof( PROBE_RESP ));
2821 /* Increment the number of APs detected */
2822 lp->probe_num_aps++;
2823 } else {
2824 int count;
2825 int unique = 1;
2827 for( count = 0; count < lp->probe_num_aps; count++ ) {
2828 if ( memcmp( &( probe_rsp->BSSID ),
2829 lp->probe_results.ProbeTable[count].BSSID,
2830 ETH_ALEN ) == 0 ) {
2831 unique = 0;
2835 if ( unique ) {
2836 /* Copy the info to the ScanResult structure in the
2837 private adapter struct. Only copy if there's room in the
2838 table */
2839 if ( lp->probe_num_aps < MAX_NAPS )
2841 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
2842 probe_rsp, sizeof( PROBE_RESP ));
2844 else
2846 DBG_WARNING( DbgInfo, "Num of scan results exceeds storage, truncating\n" );
2849 /* Increment the number of APs detected. Note I do this
2850 here even when I don't copy the probe response to the
2851 buffer in order to detect the overflow condition */
2852 lp->probe_num_aps++;
2858 break;
2860 case CFG_LINK_STAT:
2861 #define ls ((LINK_STATUS_STRCT *)ltv)
2862 DBG_TRACE( DbgInfo, "CFG_LINK_STAT\n" );
2864 switch( ls->linkStatus ) {
2865 case 1:
2866 DBG_TRACE( DbgInfo, "Link Status : Connected\n" );
2867 wl_wext_event_ap( lp->dev );
2868 break;
2870 case 2:
2871 DBG_TRACE( DbgInfo, "Link Status : Disconnected\n" );
2872 break;
2874 case 3:
2875 DBG_TRACE( DbgInfo, "Link Status : Access Point Change\n" );
2876 break;
2878 case 4:
2879 DBG_TRACE( DbgInfo, "Link Status : Access Point Out of Range\n" );
2880 break;
2882 case 5:
2883 DBG_TRACE( DbgInfo, "Link Status : Access Point In Range\n" );
2884 break;
2886 default:
2887 DBG_TRACE( DbgInfo, "Link Status : UNKNOWN (0x%04x)\n",
2888 ls->linkStatus );
2889 break;
2892 break;
2893 #undef ls
2895 case CFG_ASSOC_STAT:
2896 DBG_TRACE( DbgInfo, "CFG_ASSOC_STAT\n" );
2899 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
2901 switch( as->assocStatus ) {
2902 case 1:
2903 DBG_TRACE( DbgInfo, "Association Status : STA Associated\n" );
2904 break;
2906 case 2:
2907 DBG_TRACE( DbgInfo, "Association Status : STA Reassociated\n" );
2908 break;
2910 case 3:
2911 DBG_TRACE( DbgInfo, "Association Status : STA Disassociated\n" );
2912 break;
2914 default:
2915 DBG_TRACE( DbgInfo, "Association Status : UNKNOWN (0x%04x)\n",
2916 as->assocStatus );
2917 break;
2920 DBG_TRACE( DbgInfo, "STA Address : %s\n",
2921 DbgHwAddr( as->staAddr ));
2923 if (( as->assocStatus == 2 ) && ( as->len == 8 )) {
2924 DBG_TRACE( DbgInfo, "Old AP Address : %s\n",
2925 DbgHwAddr( as->oldApAddr ));
2929 break;
2931 case CFG_SECURITY_STAT:
2932 DBG_TRACE( DbgInfo, "CFG_SECURITY_STAT\n" );
2935 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
2937 switch( ss->securityStatus ) {
2938 case 1:
2939 DBG_TRACE( DbgInfo, "Security Status : Dissassociate [AP]\n" );
2940 break;
2942 case 2:
2943 DBG_TRACE( DbgInfo, "Security Status : Deauthenticate [AP]\n" );
2944 break;
2946 case 3:
2947 DBG_TRACE( DbgInfo, "Security Status : Authenticate Fail [STA] or [AP]\n" );
2948 break;
2950 case 4:
2951 DBG_TRACE( DbgInfo, "Security Status : MIC Fail\n" );
2952 break;
2954 case 5:
2955 DBG_TRACE( DbgInfo, "Security Status : Associate Fail\n" );
2956 break;
2958 default:
2959 DBG_TRACE( DbgInfo, "Security Status : UNKNOWN %d\n",
2960 ss->securityStatus );
2961 break;
2964 DBG_TRACE( DbgInfo, "STA Address : %s\n", DbgHwAddr( ss->staAddr ));
2966 DBG_TRACE( DbgInfo, "Reason : 0x%04x \n", ss->reason );
2969 break;
2971 case CFG_WMP:
2972 DBG_TRACE( DbgInfo, "CFG_WMP, size is %d bytes\n", ltv->len );
2974 WMP_RSP_STRCT *wmp_rsp = (WMP_RSP_STRCT *)ltv;
2976 DBG_TRACE( DbgInfo, "CFG_WMP, pdu type is 0x%x\n",
2977 wmp_rsp->wmpRsp.wmpHdr.type );
2979 switch( wmp_rsp->wmpRsp.wmpHdr.type ) {
2980 case WVLAN_WMP_PDU_TYPE_LT_RSP:
2982 #if DBG
2983 LINKTEST_RSP_STRCT *lt_rsp = (LINKTEST_RSP_STRCT *)ltv;
2984 #endif // DBG
2985 DBG_TRACE( DbgInfo, "LINK TEST RESULT\n" );
2986 DBG_TRACE( DbgInfo, "================\n" );
2987 DBG_TRACE( DbgInfo, "Length : %d.\n", lt_rsp->len );
2989 DBG_TRACE( DbgInfo, "Name : %s.\n", lt_rsp->ltRsp.ltRsp.name );
2990 DBG_TRACE( DbgInfo, "Signal Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.signal );
2991 DBG_TRACE( DbgInfo, "Noise Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.noise );
2992 DBG_TRACE( DbgInfo, "Receive Flow : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.rxFlow );
2993 DBG_TRACE( DbgInfo, "Data Rate : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRate );
2994 DBG_TRACE( DbgInfo, "Protocol : 0x%04x.\n", lt_rsp->ltRsp.ltRsp.protocol );
2995 DBG_TRACE( DbgInfo, "Station : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.station );
2996 DBG_TRACE( DbgInfo, "Data Rate Cap : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRateCap );
2998 DBG_TRACE( DbgInfo, "Power Mgmt : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
2999 lt_rsp->ltRsp.ltRsp.powerMgmt[0],
3000 lt_rsp->ltRsp.ltRsp.powerMgmt[1],
3001 lt_rsp->ltRsp.ltRsp.powerMgmt[2],
3002 lt_rsp->ltRsp.ltRsp.powerMgmt[3] );
3004 DBG_TRACE( DbgInfo, "Robustness : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3005 lt_rsp->ltRsp.ltRsp.robustness[0],
3006 lt_rsp->ltRsp.ltRsp.robustness[1],
3007 lt_rsp->ltRsp.ltRsp.robustness[2],
3008 lt_rsp->ltRsp.ltRsp.robustness[3] );
3010 DBG_TRACE( DbgInfo, "Scaling : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.scaling );
3013 break;
3015 default:
3016 break;
3020 break;
3022 case CFG_NULL:
3023 DBG_TRACE( DbgInfo, "CFG_NULL\n" );
3024 break;
3026 case CFG_UPDATED_INFO_RECORD: // Updated Information Record
3027 DBG_TRACE( DbgInfo, "UPDATED INFORMATION RECORD\n" );
3029 ltv_val = CNV_INT_TO_LITTLE( ltv->u.u16[0] );
3031 /* Check and see which RID was updated */
3032 switch( ltv_val ) {
3033 case CFG_CUR_COUNTRY_INFO: // Indicate Passive Scan Completion
3034 DBG_TRACE( DbgInfo, "Updated country info\n" );
3036 /* Do I need to hold off on updating RIDs until the process is
3037 complete? */
3038 wl_connect( lp );
3039 break;
3041 case CFG_PORT_STAT: // Wait for Connect Event
3042 //wl_connect( lp );
3044 break;
3046 default:
3047 DBG_WARNING( DbgInfo, "Unknown RID: 0x%04x\n", ltv_val );
3050 break;
3052 default:
3053 DBG_TRACE( DbgInfo, "UNKNOWN MESSAGE: 0x%04x\n", ltv->typ );
3054 break;
3056 DBG_LEAVE( DbgInfo );
3057 return;
3058 } // wl_process_mailbox
3059 /*============================================================================*/
3060 #endif /* ifndef USE_MBOX_SYNC */
3062 #ifdef USE_WDS
3063 /*******************************************************************************
3064 * wl_wds_netdev_register()
3065 *******************************************************************************
3067 * DESCRIPTION:
3069 * This function registers net_device structures with the system's network
3070 * layer for use with the WDS ports.
3073 * PARAMETERS:
3075 * lp - pointer to the device's private adapter structure
3077 * RETURNS:
3079 * N/A
3081 ******************************************************************************/
3082 void wl_wds_netdev_register( struct wl_private *lp )
3084 int count;
3085 /*------------------------------------------------------------------------*/
3086 DBG_FUNC( "wl_wds_netdev_register" );
3087 DBG_ENTER( DbgInfo );
3088 //;?why is there no USE_WDS clause like in wl_enable_wds_ports
3089 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3090 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3091 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3092 if ( register_netdev( lp->wds_port[count].dev ) != 0 ) {
3093 DBG_WARNING( DbgInfo, "net device for WDS port %d could not be registered\n",
3094 ( count + 1 ));
3096 lp->wds_port[count].is_registered = TRUE;
3098 /* Fill out the net_device structs with the MAC addr */
3099 memcpy( lp->wds_port[count].dev->dev_addr, lp->MACAddress, ETH_ALEN );
3100 lp->wds_port[count].dev->addr_len = ETH_ALEN;
3104 DBG_LEAVE( DbgInfo );
3105 return;
3106 } // wl_wds_netdev_register
3107 /*============================================================================*/
3110 /*******************************************************************************
3111 * wl_wds_netdev_deregister()
3112 *******************************************************************************
3114 * DESCRIPTION:
3116 * This function deregisters the WDS net_device structures used by the
3117 * system's network layer.
3120 * PARAMETERS:
3122 * lp - pointer to the device's private adapter structure
3124 * RETURNS:
3126 * N/A
3128 ******************************************************************************/
3129 void wl_wds_netdev_deregister( struct wl_private *lp )
3131 int count;
3132 /*------------------------------------------------------------------------*/
3133 DBG_FUNC( "wl_wds_netdev_deregister" );
3134 DBG_ENTER( DbgInfo );
3135 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3136 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3137 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3138 unregister_netdev( lp->wds_port[count].dev );
3140 lp->wds_port[count].is_registered = FALSE;
3143 DBG_LEAVE( DbgInfo );
3144 return;
3145 } // wl_wds_netdev_deregister
3146 /*============================================================================*/
3147 #endif /* USE_WDS */
3150 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
3152 * The proc filesystem: function to read and entry
3154 int printf_hcf_16( char *s, char *buf, hcf_16* p, int n );
3155 int printf_hcf_16( char *s, char *buf, hcf_16* p, int n ) {
3157 int i, len;
3159 len = sprintf(buf, "%s", s );
3160 while ( len < 20 ) len += sprintf(buf+len, " " );
3161 len += sprintf(buf+len,": " );
3162 for ( i = 0; i < n; i++ ) {
3163 if ( len % 80 > 75 ) {
3164 len += sprintf(buf+len,"\n" );
3166 len += sprintf(buf+len,"%04X ", p[i] );
3168 len += sprintf(buf+len,"\n" );
3169 return len;
3170 } // printf_hcf_16
3172 int printf_hcf_8( char *s, char *buf, hcf_8* p, int n );
3173 int printf_hcf_8( char *s, char *buf, hcf_8* p, int n ) {
3175 int i, len;
3177 len = sprintf(buf, "%s", s );
3178 while ( len < 20 ) len += sprintf(buf+len, " " );
3179 len += sprintf(buf+len,": " );
3180 for ( i = 0; i <= n; i++ ) {
3181 if ( len % 80 > 77 ) {
3182 len += sprintf(buf+len,"\n" );
3184 len += sprintf(buf+len,"%02X ", p[i] );
3186 len += sprintf(buf+len,"\n" );
3187 return len;
3188 } // printf_hcf8
3190 int printf_strct( char *s, char *buf, hcf_16* p );
3191 int printf_strct( char *s, char *buf, hcf_16* p ) {
3193 int i, len;
3195 len = sprintf(buf, "%s", s );
3196 while ( len < 20 ) len += sprintf(buf+len, " " );
3197 len += sprintf(buf+len,": " );
3198 for ( i = 0; i <= *p; i++ ) {
3199 if ( len % 80 > 75 ) {
3200 len += sprintf(buf+len,"\n" );
3202 len += sprintf(buf+len,"%04X ", p[i] );
3204 len += sprintf(buf+len,"\n" );
3205 return len;
3206 } // printf_strct
3208 int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data )
3210 struct wl_private *lp = NULL;
3211 IFBP ifbp;
3212 CFG_HERMES_TALLIES_STRCT *p;
3214 #define LIMIT (PAGE_SIZE-80) /* don't print any more after this size */
3216 len=0;
3218 lp = ((struct net_device *)data)->priv;
3219 if (lp == NULL) {
3220 len += sprintf(buf+len,"No wl_private in scull_read_procmem\n" );
3221 } else if ( lp->wlags49_type == 0 ){
3222 ifbp = &lp->hcfCtx;
3223 len += sprintf(buf+len,"Magic: 0x%04X\n", ifbp->IFB_Magic );
3224 len += sprintf(buf+len,"IOBase: 0x%04X\n", ifbp->IFB_IOBase );
3225 len += sprintf(buf+len,"LinkStat: 0x%04X\n", ifbp->IFB_LinkStat );
3226 len += sprintf(buf+len,"DSLinkStat: 0x%04X\n", ifbp->IFB_DSLinkStat );
3227 len += sprintf(buf+len,"TickIni: 0x%08lX\n", ifbp->IFB_TickIni );
3228 len += sprintf(buf+len,"TickCnt: 0x%04X\n", ifbp->IFB_TickCnt );
3229 len += sprintf(buf+len,"IntOffCnt: 0x%04X\n", ifbp->IFB_IntOffCnt );
3230 len += printf_hcf_16( "IFB_FWIdentity", &buf[len],
3231 &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
3232 } else if ( lp->wlags49_type == 1 ) {
3233 len += sprintf(buf+len,"Channel: 0x%04X\n", lp->Channel );
3234 /****** len += sprintf(buf+len,"slock: %d\n", lp->slock ); */
3235 //x struct tq_struct "task: 0x%04X\n", lp->task );
3236 //x struct net_device_stats "stats: 0x%04X\n", lp->stats );
3237 #ifdef WIRELESS_EXT
3238 //x struct iw_statistics "wstats: 0x%04X\n", lp->wstats );
3239 //x len += sprintf(buf+len,"spy_number: 0x%04X\n", lp->spy_number );
3240 //x u_char spy_address[IW_MAX_SPY][ETH_ALEN];
3241 //x struct iw_quality spy_stat[IW_MAX_SPY];
3242 #endif // WIRELESS_EXT
3243 len += sprintf(buf+len,"IFB: 0x%p\n", &lp->hcfCtx );
3244 len += sprintf(buf+len,"flags: %#.8lX\n", lp->flags ); //;?use this format from now on
3245 len += sprintf(buf+len,"DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
3246 #if DBG
3247 len += sprintf(buf+len,"DebugFlag (DbgInfo): 0x%08lX\n", DbgInfo->DebugFlag );
3248 #endif // DBG
3249 len += sprintf(buf+len,"is_registered: 0x%04X\n", lp->is_registered );
3250 //x CFG_DRV_INFO_STRCT "driverInfo: 0x%04X\n", lp->driverInfo );
3251 len += printf_strct( "driverInfo", &buf[len], (hcf_16*)&lp->driverInfo );
3252 //x CFG_IDENTITY_STRCT "driverIdentity: 0x%04X\n", lp->driverIdentity );
3253 len += printf_strct( "driverIdentity", &buf[len], (hcf_16*)&lp->driverIdentity );
3254 //x CFG_FW_IDENTITY_STRCT "StationIdentity: 0x%04X\n", lp->StationIdentity );
3255 len += printf_strct( "StationIdentity", &buf[len], (hcf_16*)&lp->StationIdentity );
3256 //x CFG_PRI_IDENTITY_STRCT "PrimaryIdentity: 0x%04X\n", lp->PrimaryIdentity );
3257 len += printf_strct( "PrimaryIdentity", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
3258 len += printf_strct( "PrimarySupplier", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRISup );
3259 //x CFG_PRI_IDENTITY_STRCT "NICIdentity: 0x%04X\n", lp->NICIdentity );
3260 len += printf_strct( "NICIdentity", &buf[len], (hcf_16*)&lp->NICIdentity );
3261 //x ltv_t "ltvRecord: 0x%04X\n", lp->ltvRecord );
3262 len += sprintf(buf+len,"txBytes: 0x%08lX\n", lp->txBytes );
3263 len += sprintf(buf+len,"maxPort: 0x%04X\n", lp->maxPort ); /* 0 for STA, 6 for AP */
3264 /* Elements used for async notification from hardware */
3265 //x RID_LOG_STRCT RidList[10];
3266 //x ltv_t "updatedRecord: 0x%04X\n", lp->updatedRecord );
3267 //x PROBE_RESP "ProbeResp: 0x%04X\n", lp->ProbeResp );
3268 //x ASSOC_STATUS_STRCT "assoc_stat: 0x%04X\n", lp->assoc_stat );
3269 //x SECURITY_STATUS_STRCT "sec_stat: 0x%04X\n", lp->sec_stat );
3270 //x u_char lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
3271 len += sprintf(buf+len,"PortType: 0x%04X\n", lp->PortType ); // 1 - 3 (1 [Normal] | 3 [AdHoc])
3272 len += sprintf(buf+len,"Channel: 0x%04X\n", lp->Channel ); // 0 - 14 (0)
3273 //x hcf_16 TxRateControl[2];
3274 len += sprintf(buf+len,"TxRateControl[2]: 0x%04X 0x%04X\n",
3275 lp->TxRateControl[0], lp->TxRateControl[1] );
3276 len += sprintf(buf+len,"DistanceBetweenAPs: 0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
3277 len += sprintf(buf+len,"RTSThreshold: 0x%04X\n", lp->RTSThreshold ); // 0 - 2347 (2347)
3278 len += sprintf(buf+len,"PMEnabled: 0x%04X\n", lp->PMEnabled ); // 0 - 2, 8001 - 8002 (0)
3279 len += sprintf(buf+len,"MicrowaveRobustness: 0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
3280 len += sprintf(buf+len,"CreateIBSS: 0x%04X\n", lp->CreateIBSS ); // 0 - 1 (0)
3281 len += sprintf(buf+len,"MulticastReceive: 0x%04X\n", lp->MulticastReceive ); // 0 - 1 (1)
3282 len += sprintf(buf+len,"MaxSleepDuration: 0x%04X\n", lp->MaxSleepDuration ); // 0 - 65535 (100)
3283 //x hcf_8 MACAddress[ETH_ALEN];
3284 len += printf_hcf_8( "MACAddress", &buf[len], lp->MACAddress, ETH_ALEN );
3285 //x char NetworkName[HCF_MAX_NAME_LEN+1];
3286 len += sprintf(buf+len,"NetworkName: %.32s\n", lp->NetworkName );
3287 //x char StationName[HCF_MAX_NAME_LEN+1];
3288 len += sprintf(buf+len,"EnableEncryption: 0x%04X\n", lp->EnableEncryption ); // 0 - 1 (0)
3289 //x char Key1[MAX_KEY_LEN+1];
3290 len += printf_hcf_8( "Key1", &buf[len], lp->Key1, MAX_KEY_LEN );
3291 //x char Key2[MAX_KEY_LEN+1];
3292 //x char Key3[MAX_KEY_LEN+1];
3293 //x char Key4[MAX_KEY_LEN+1];
3294 len += sprintf(buf+len,"TransmitKeyID: 0x%04X\n", lp->TransmitKeyID ); // 1 - 4 (1)
3295 //x CFG_DEFAULT_KEYS_STRCT "DefaultKeys: 0x%04X\n", lp->DefaultKeys );
3296 //x u_char mailbox[MB_SIZE];
3297 //x char szEncryption[MAX_ENC_LEN];
3298 len += sprintf(buf+len,"driverEnable: 0x%04X\n", lp->driverEnable );
3299 len += sprintf(buf+len,"wolasEnable: 0x%04X\n", lp->wolasEnable );
3300 len += sprintf(buf+len,"atimWindow: 0x%04X\n", lp->atimWindow );
3301 len += sprintf(buf+len,"holdoverDuration: 0x%04X\n", lp->holdoverDuration );
3302 //x hcf_16 MulticastRate[2];
3303 len += sprintf(buf+len,"authentication: 0x%04X\n", lp->authentication ); // is this AP specific?
3304 len += sprintf(buf+len,"promiscuousMode: 0x%04X\n", lp->promiscuousMode );
3305 len += sprintf(buf+len,"DownloadFirmware: 0x%04X\n", lp->DownloadFirmware ); // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
3306 len += sprintf(buf+len,"AuthKeyMgmtSuite: 0x%04X\n", lp->AuthKeyMgmtSuite );
3307 len += sprintf(buf+len,"loadBalancing: 0x%04X\n", lp->loadBalancing );
3308 len += sprintf(buf+len,"mediumDistribution: 0x%04X\n", lp->mediumDistribution );
3309 len += sprintf(buf+len,"txPowLevel: 0x%04X\n", lp->txPowLevel );
3310 // len += sprintf(buf+len,"shortRetryLimit: 0x%04X\n", lp->shortRetryLimit );
3311 // len += sprintf(buf+len,"longRetryLimit: 0x%04X\n", lp->longRetryLimit );
3312 //x hcf_16 srsc[2];
3313 //x hcf_16 brsc[2];
3314 len += sprintf(buf+len,"connectionControl: 0x%04X\n", lp->connectionControl );
3315 //x //hcf_16 probeDataRates[2];
3316 len += sprintf(buf+len,"ownBeaconInterval: 0x%04X\n", lp->ownBeaconInterval );
3317 len += sprintf(buf+len,"coexistence: 0x%04X\n", lp->coexistence );
3318 //x WVLAN_FRAME "txF: 0x%04X\n", lp->txF );
3319 //x WVLAN_LFRAME txList[DEFAULT_NUM_TX_FRAMES];
3320 //x struct list_head "txFree: 0x%04X\n", lp->txFree );
3321 //x struct list_head txQ[WVLAN_MAX_TX_QUEUES];
3322 len += sprintf(buf+len,"netif_queue_on: 0x%04X\n", lp->netif_queue_on );
3323 len += sprintf(buf+len,"txQ_count: 0x%04X\n", lp->txQ_count );
3324 //x DESC_STRCT "desc_rx: 0x%04X\n", lp->desc_rx );
3325 //x DESC_STRCT "desc_tx: 0x%04X\n", lp->desc_tx );
3326 //x WVLAN_PORT_STATE "portState: 0x%04X\n", lp->portState );
3327 //x ScanResult "scan_results: 0x%04X\n", lp->scan_results );
3328 //x ProbeResult "probe_results: 0x%04X\n", lp->probe_results );
3329 len += sprintf(buf+len,"probe_num_aps: 0x%04X\n", lp->probe_num_aps );
3330 len += sprintf(buf+len,"use_dma: 0x%04X\n", lp->use_dma );
3331 //x DMA_STRCT "dma: 0x%04X\n", lp->dma );
3332 #ifdef USE_RTS
3333 len += sprintf(buf+len,"useRTS: 0x%04X\n", lp->useRTS );
3334 #endif // USE_RTS
3335 //;?should we restore this to allow smaller memory footprint
3336 //;?I guess not. This should be brought under Debug mode only
3337 len += sprintf(buf+len,"DTIMPeriod: 0x%04X\n", lp->DTIMPeriod ); // 1 - 255 (1)
3338 len += sprintf(buf+len,"multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
3339 len += sprintf(buf+len,"RejectAny: 0x%04X\n", lp->RejectAny ); // 0 - 1 (0)
3340 len += sprintf(buf+len,"ExcludeUnencrypted: 0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
3341 len += sprintf(buf+len,"intraBSSRelay: 0x%04X\n", lp->intraBSSRelay );
3342 len += sprintf(buf+len,"wlags49_type: 0x%08lX\n", lp->wlags49_type );
3343 #ifdef USE_WDS
3344 //x WVLAN_WDS_IF wds_port[NUM_WDS_PORTS];
3345 #endif // USE_WDS
3346 } else if ( lp->wlags49_type == 2 ){
3347 len += sprintf(buf+len,"tallies to be added\n" );
3348 //Hermes Tallies (IFB substructure) {
3349 p = &lp->hcfCtx.IFB_NIC_Tallies;
3350 len += sprintf(buf+len,"TxUnicastFrames: %08lX\n", p->TxUnicastFrames );
3351 len += sprintf(buf+len,"TxMulticastFrames: %08lX\n", p->TxMulticastFrames );
3352 len += sprintf(buf+len,"TxFragments: %08lX\n", p->TxFragments );
3353 len += sprintf(buf+len,"TxUnicastOctets: %08lX\n", p->TxUnicastOctets );
3354 len += sprintf(buf+len,"TxMulticastOctets: %08lX\n", p->TxMulticastOctets );
3355 len += sprintf(buf+len,"TxDeferredTransmissions: %08lX\n", p->TxDeferredTransmissions );
3356 len += sprintf(buf+len,"TxSingleRetryFrames: %08lX\n", p->TxSingleRetryFrames );
3357 len += sprintf(buf+len,"TxMultipleRetryFrames: %08lX\n", p->TxMultipleRetryFrames );
3358 len += sprintf(buf+len,"TxRetryLimitExceeded: %08lX\n", p->TxRetryLimitExceeded );
3359 len += sprintf(buf+len,"TxDiscards: %08lX\n", p->TxDiscards );
3360 len += sprintf(buf+len,"RxUnicastFrames: %08lX\n", p->RxUnicastFrames );
3361 len += sprintf(buf+len,"RxMulticastFrames: %08lX\n", p->RxMulticastFrames );
3362 len += sprintf(buf+len,"RxFragments: %08lX\n", p->RxFragments );
3363 len += sprintf(buf+len,"RxUnicastOctets: %08lX\n", p->RxUnicastOctets );
3364 len += sprintf(buf+len,"RxMulticastOctets: %08lX\n", p->RxMulticastOctets );
3365 len += sprintf(buf+len,"RxFCSErrors: %08lX\n", p->RxFCSErrors );
3366 len += sprintf(buf+len,"RxDiscardsNoBuffer: %08lX\n", p->RxDiscardsNoBuffer );
3367 len += sprintf(buf+len,"TxDiscardsWrongSA: %08lX\n", p->TxDiscardsWrongSA );
3368 len += sprintf(buf+len,"RxWEPUndecryptable: %08lX\n", p->RxWEPUndecryptable );
3369 len += sprintf(buf+len,"RxMsgInMsgFragments: %08lX\n", p->RxMsgInMsgFragments );
3370 len += sprintf(buf+len,"RxMsgInBadMsgFragments: %08lX\n", p->RxMsgInBadMsgFragments );
3371 len += sprintf(buf+len,"RxDiscardsWEPICVError: %08lX\n", p->RxDiscardsWEPICVError );
3372 len += sprintf(buf+len,"RxDiscardsWEPExcluded: %08lX\n", p->RxDiscardsWEPExcluded );
3373 #if (HCF_EXT) & HCF_EXT_TALLIES_FW
3374 //to be added ;?
3375 #endif // HCF_EXT_TALLIES_FW
3376 } else if ( lp->wlags49_type & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3377 #if DBG
3378 DbgInfo->DebugFlag = lp->wlags49_type & 0x7FFF;
3379 #endif // DBG
3380 lp->wlags49_type = 0; //default to IFB again ;?
3381 } else {
3382 len += sprintf(buf+len,"unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
3383 len += sprintf(buf+len,"0x0000 - IFB\n" );
3384 len += sprintf(buf+len,"0x0001 - wl_private\n" );
3385 len += sprintf(buf+len,"0x0002 - Tallies\n" );
3386 len += sprintf(buf+len,"0x8xxx - Change debufflag\n" );
3387 len += sprintf(buf+len,"ERROR 0001\nWARNING 0002\nNOTICE 0004\nTRACE 0008\n" );
3388 len += sprintf(buf+len,"VERBOSE 0010\nPARAM 0020\nBREAK 0040\nRX 0100\n" );
3389 len += sprintf(buf+len,"TX 0200\nDS 0400\n" );
3391 return len;
3392 } // scull_read_procmem
3394 static void proc_write(const char *name, write_proc_t *w, void *data)
3396 struct proc_dir_entry * entry = create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
3397 if (entry) {
3398 entry->write_proc = w;
3399 entry->data = data;
3401 } // proc_write
3403 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
3405 static char proc_number[11];
3406 unsigned int nr = 0;
3408 DBG_FUNC( "write_int" );
3409 DBG_ENTER( DbgInfo );
3411 if (count > 9) {
3412 count = -EINVAL;
3413 } else if ( copy_from_user(proc_number, buffer, count) ) {
3414 count = -EFAULT;
3416 if (count > 0 ) {
3417 proc_number[count] = 0;
3418 nr = simple_strtoul(proc_number , NULL, 0);
3419 *(unsigned int *)data = nr;
3420 if ( nr & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3421 #if DBG
3422 DbgInfo->DebugFlag = nr & 0x7FFF;
3423 #endif // DBG
3426 DBG_PRINT( "value: %08X\n", nr );
3427 DBG_LEAVE( DbgInfo );
3428 return count;
3429 } // write_int
3431 #endif /* SCULL_USE_PROC */
3433 #ifdef DN554
3434 #define RUN_AT(x) (jiffies+(x)) //"borrowed" from include/pcmcia/k_compat.h
3435 #define DS_OOR 0x8000 //Deepsleep OutOfRange Status
3437 lp->timer_oor_cnt = DS_OOR;
3438 init_timer( &lp->timer_oor );
3439 lp->timer_oor.function = timer_oor;
3440 lp->timer_oor.data = (unsigned long)lp;
3441 lp->timer_oor.expires = RUN_AT( 3 * HZ );
3442 add_timer( &lp->timer_oor );
3443 printk( "<5>wl_enable: %ld\n", jiffies ); //;?remove me 1 day
3444 #endif //DN554
3445 #ifdef DN554
3446 /*******************************************************************************
3447 * timer_oor()
3448 *******************************************************************************
3450 * DESCRIPTION:
3453 * PARAMETERS:
3455 * arg - a u_long representing a pointer to a dev_link_t structure for the
3456 * device to be released.
3458 * RETURNS:
3460 * N/A
3462 ******************************************************************************/
3463 void timer_oor( u_long arg )
3465 struct wl_private *lp = (struct wl_private *)arg;
3467 /*------------------------------------------------------------------------*/
3469 DBG_FUNC( "timer_oor" );
3470 DBG_ENTER( DbgInfo );
3471 DBG_PARAM( DbgInfo, "arg", "0x%08lx", arg );
3473 printk( "<5>timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt ); //;?remove me 1 day
3474 lp->timer_oor_cnt += 10;
3475 if ( (lp->timer_oor_cnt & ~DS_OOR) > 300 ) {
3476 lp->timer_oor_cnt = 300;
3478 lp->timer_oor_cnt |= DS_OOR;
3479 init_timer( &lp->timer_oor );
3480 lp->timer_oor.function = timer_oor;
3481 lp->timer_oor.data = (unsigned long)lp;
3482 lp->timer_oor.expires = RUN_AT( (lp->timer_oor_cnt & ~DS_OOR) * HZ );
3483 add_timer( &lp->timer_oor );
3485 DBG_LEAVE( DbgInfo );
3486 } // timer_oor
3487 #endif //DN554
3489 MODULE_LICENSE("Dual BSD/GPL");