1 /*******************************************************************************
3 * Wireless device driver for Linux (wlags49).
5 * Copyright (c) 1998-2003 Agere Systems Inc.
9 * Initially developed by TriplePoint, Inc.
10 * http://www.triplepoint.com
12 *------------------------------------------------------------------------------
14 * This file contains the main driver entry points and other adapter
17 *------------------------------------------------------------------------------
21 * This software is provided subject to the following terms and conditions,
22 * which you should read carefully before using the software. Using this
23 * software indicates your acceptance of these terms and conditions. If you do
24 * not agree with these terms and conditions, do not use the software.
26 * Copyright © 2003 Agere Systems Inc.
27 * All rights reserved.
29 * Redistribution and use in source or binary forms, with or without
30 * modifications, are permitted provided that the following conditions are met:
32 * . Redistributions of source code must retain the above copyright notice, this
33 * list of conditions and the following Disclaimer as comments in the code as
34 * well as in the documentation and/or other materials provided with the
37 * . Redistributions in binary form must reproduce the above copyright notice,
38 * this list of conditions and the following Disclaimer in the documentation
39 * and/or other materials provided with the distribution.
41 * . Neither the name of Agere Systems Inc. nor the names of the contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED
\93AS IS
\94 AND ANY EXPRESS OR IMPLIED WARRANTIES,
48 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
49 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
50 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
51 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
52 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
60 ******************************************************************************/
62 /*******************************************************************************
63 * constant definitions
64 ******************************************************************************/
66 /* Allow support for calling system fcns to access F/W image file */
67 #define __KERNEL_SYSCALLS__
69 /*******************************************************************************
71 ******************************************************************************/
72 #include <wl_version.h>
74 #include <linux/module.h>
75 #include <linux/proc_fs.h>
76 #include <linux/seq_file.h>
77 #include <linux/types.h>
78 #include <linux/kernel.h>
79 #include <linux/unistd.h>
80 #include <linux/uaccess.h>
82 #include <linux/netdevice.h>
83 #include <linux/etherdevice.h>
87 #include <linux/vmalloc.h>
95 /* in order to get around:: wl_main.c:2229: `HREG_EV_RDMAD' undeclared (first use in this function) */
99 #include <wl_internal.h>
102 #include <wl_netdev.h>
106 #include <wl_profile.h>
107 #endif /* USE_PROFILE */
111 #endif /* BUS_PCMCIA */
116 /*******************************************************************************
118 ******************************************************************************/
119 #define VALID_PARAM(C) \
122 printk(KERN_INFO "Wireless, parameter error: \"%s\"\n", #C); \
126 /*******************************************************************************
128 ******************************************************************************/
129 void wl_isr_handler(unsigned long p);
131 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
132 static int scull_read_procmem(struct seq_file *m, void *v);
133 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data);
136 * seq_file wrappers for procfile show routines.
138 static int scull_read_procmem_open(struct inode *inode, struct file *file)
140 return single_open(file, scull_read_procmem, PDE_DATA(inode));
143 static const struct file_operations scull_read_procmem_fops = {
144 .open = scull_read_procmem_open,
147 .release = single_release,
150 #endif /* SCULL_USE_PROC */
152 /*******************************************************************************
153 * module parameter definitions - set with 'insmod'
154 ******************************************************************************/
155 static p_u16 irq_mask = 0xdeb8; /* IRQ3,4,5,7,9,10,11,12,14,15 */
156 static p_s8 irq_list[4] = { -1 };
159 MODULE_PARM(irq_mask, "h");
160 MODULE_PARM_DESC(irq_mask, "IRQ mask [0xdeb8]");
161 MODULE_PARM(irq_list, "1-4b");
162 MODULE_PARM_DESC(irq_list, "IRQ list [<irq_mask>]");
165 static p_u8 PARM_AUTHENTICATION = PARM_DEFAULT_AUTHENTICATION;
166 static p_u16 PARM_AUTH_KEY_MGMT_SUITE = PARM_DEFAULT_AUTH_KEY_MGMT_SUITE;
167 static p_u16 PARM_BRSC_2GHZ = PARM_DEFAULT_BRSC_2GHZ;
168 static p_u16 PARM_BRSC_5GHZ = PARM_DEFAULT_BRSC_5GHZ;
169 static p_u16 PARM_COEXISTENCE = PARM_DEFAULT_COEXISTENCE;
170 static p_u16 PARM_CONNECTION_CONTROL = PARM_DEFAULT_CONNECTION_CONTROL; /* ;?rename and move */
171 static p_char *PARM_CREATE_IBSS = PARM_DEFAULT_CREATE_IBSS_STR;
172 static p_char *PARM_DESIRED_SSID = PARM_DEFAULT_SSID;
173 static p_char *PARM_DOWNLOAD_FIRMWARE = "";
174 static p_u16 PARM_ENABLE_ENCRYPTION = PARM_DEFAULT_ENABLE_ENCRYPTION;
175 static p_char *PARM_EXCLUDE_UNENCRYPTED = PARM_DEFAULT_EXCLUDE_UNENCRYPTED_STR;
176 static p_char *PARM_INTRA_BSS_RELAY = PARM_DEFAULT_INTRA_BSS_RELAY_STR;
177 static p_char *PARM_KEY1 = "";
178 static p_char *PARM_KEY2 = "";
179 static p_char *PARM_KEY3 = "";
180 static p_char *PARM_KEY4 = "";
181 static p_char *PARM_LOAD_BALANCING = PARM_DEFAULT_LOAD_BALANCING_STR;
182 static p_u16 PARM_MAX_SLEEP = PARM_DEFAULT_MAX_PM_SLEEP;
183 static p_char *PARM_MEDIUM_DISTRIBUTION = PARM_DEFAULT_MEDIUM_DISTRIBUTION_STR;
184 static p_char *PARM_MICROWAVE_ROBUSTNESS = PARM_DEFAULT_MICROWAVE_ROBUSTNESS_STR;
185 static p_char *PARM_MULTICAST_PM_BUFFERING = PARM_DEFAULT_MULTICAST_PM_BUFFERING_STR;
186 static p_u16 PARM_MULTICAST_RATE = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
187 static p_char *PARM_MULTICAST_RX = PARM_DEFAULT_MULTICAST_RX_STR;
188 static p_u8 PARM_NETWORK_ADDR[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
189 static p_u16 PARM_OWN_ATIM_WINDOW = PARM_DEFAULT_OWN_ATIM_WINDOW;
190 static p_u16 PARM_OWN_BEACON_INTERVAL = PARM_DEFAULT_OWN_BEACON_INTERVAL;
191 static p_u8 PARM_OWN_CHANNEL = PARM_DEFAULT_OWN_CHANNEL;
192 static p_u8 PARM_OWN_DTIM_PERIOD = PARM_DEFAULT_OWN_DTIM_PERIOD;
193 static p_char *PARM_OWN_NAME = PARM_DEFAULT_OWN_NAME;
194 static p_char *PARM_OWN_SSID = PARM_DEFAULT_SSID;
195 static p_u16 PARM_PM_ENABLED = WVLAN_PM_STATE_DISABLED;
196 static p_u16 PARM_PM_HOLDOVER_DURATION = PARM_DEFAULT_PM_HOLDOVER_DURATION;
197 static p_u8 PARM_PORT_TYPE = PARM_DEFAULT_PORT_TYPE;
198 static p_char *PARM_PROMISCUOUS_MODE = PARM_DEFAULT_PROMISCUOUS_MODE_STR;
199 static p_char *PARM_REJECT_ANY = PARM_DEFAULT_REJECT_ANY_STR;
201 static p_u16 PARM_RTS_THRESHOLD1 = PARM_DEFAULT_RTS_THRESHOLD;
202 static p_u16 PARM_RTS_THRESHOLD2 = PARM_DEFAULT_RTS_THRESHOLD;
203 static p_u16 PARM_RTS_THRESHOLD3 = PARM_DEFAULT_RTS_THRESHOLD;
204 static p_u16 PARM_RTS_THRESHOLD4 = PARM_DEFAULT_RTS_THRESHOLD;
205 static p_u16 PARM_RTS_THRESHOLD5 = PARM_DEFAULT_RTS_THRESHOLD;
206 static p_u16 PARM_RTS_THRESHOLD6 = PARM_DEFAULT_RTS_THRESHOLD;
208 static p_u16 PARM_RTS_THRESHOLD = PARM_DEFAULT_RTS_THRESHOLD;
209 static p_u16 PARM_SRSC_2GHZ = PARM_DEFAULT_SRSC_2GHZ;
210 static p_u16 PARM_SRSC_5GHZ = PARM_DEFAULT_SRSC_5GHZ;
211 static p_u8 PARM_SYSTEM_SCALE = PARM_DEFAULT_SYSTEM_SCALE;
212 static p_u8 PARM_TX_KEY = PARM_DEFAULT_TX_KEY;
213 static p_u16 PARM_TX_POW_LEVEL = PARM_DEFAULT_TX_POW_LEVEL;
215 static p_u16 PARM_TX_RATE1 = PARM_DEFAULT_TX_RATE_2GHZ;
216 static p_u16 PARM_TX_RATE2 = PARM_DEFAULT_TX_RATE_2GHZ;
217 static p_u16 PARM_TX_RATE3 = PARM_DEFAULT_TX_RATE_2GHZ;
218 static p_u16 PARM_TX_RATE4 = PARM_DEFAULT_TX_RATE_2GHZ;
219 static p_u16 PARM_TX_RATE5 = PARM_DEFAULT_TX_RATE_2GHZ;
220 static p_u16 PARM_TX_RATE6 = PARM_DEFAULT_TX_RATE_2GHZ;
222 static p_u16 PARM_TX_RATE = PARM_DEFAULT_TX_RATE_2GHZ;
224 static p_u8 PARM_WDS_ADDRESS1[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
225 static p_u8 PARM_WDS_ADDRESS2[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
226 static p_u8 PARM_WDS_ADDRESS3[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
227 static p_u8 PARM_WDS_ADDRESS4[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
228 static p_u8 PARM_WDS_ADDRESS5[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
229 static p_u8 PARM_WDS_ADDRESS6[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
234 MODULE_PARM(PARM_DESIRED_SSID, "s");
235 MODULE_PARM_DESC(PARM_DESIRED_SSID, "Network Name (<string>) [ANY]");
236 MODULE_PARM(PARM_OWN_SSID, "s");
237 MODULE_PARM_DESC(PARM_OWN_SSID, "Network Name (<string>) [ANY]");
238 MODULE_PARM(PARM_OWN_CHANNEL, "b");
239 MODULE_PARM_DESC(PARM_OWN_CHANNEL, "Channel (0 - 14) [0]");
240 MODULE_PARM(PARM_SYSTEM_SCALE, "b");
241 MODULE_PARM_DESC(PARM_SYSTEM_SCALE, "Distance Between APs (1 - 3) [1]");
242 MODULE_PARM(PARM_TX_RATE, "b");
243 MODULE_PARM_DESC(PARM_TX_RATE, "Transmit Rate Control");
244 MODULE_PARM(PARM_RTS_THRESHOLD, "h");
245 MODULE_PARM_DESC(PARM_RTS_THRESHOLD, "Medium Reservation (RTS/CTS Fragment Length) (256 - 2347) [2347]");
246 MODULE_PARM(PARM_MICROWAVE_ROBUSTNESS, "s");
247 MODULE_PARM_DESC(PARM_MICROWAVE_ROBUSTNESS, "Microwave Oven Robustness Enabled (<string> N or Y) [N]");
248 MODULE_PARM(PARM_OWN_NAME, "s");
249 MODULE_PARM_DESC(PARM_OWN_NAME, "Station Name (<string>) [Linux]");
251 MODULE_PARM(PARM_ENABLE_ENCRYPTION, "b");
252 MODULE_PARM_DESC(PARM_ENABLE_ENCRYPTION, "Encryption Mode (0 - 7) [0]");
254 MODULE_PARM(PARM_KEY1, "s");
255 MODULE_PARM_DESC(PARM_KEY1, "Data Encryption Key 1 (<string>) []");
256 MODULE_PARM(PARM_KEY2, "s");
257 MODULE_PARM_DESC(PARM_KEY2, "Data Encryption Key 2 (<string>) []");
258 MODULE_PARM(PARM_KEY3, "s");
259 MODULE_PARM_DESC(PARM_KEY3, "Data Encryption Key 3 (<string>) []");
260 MODULE_PARM(PARM_KEY4, "s");
261 MODULE_PARM_DESC(PARM_KEY4, "Data Encryption Key 4 (<string>) []");
262 MODULE_PARM(PARM_TX_KEY, "b");
263 MODULE_PARM_DESC(PARM_TX_KEY, "Transmit Key ID (1 - 4) [1]");
264 MODULE_PARM(PARM_MULTICAST_RATE, "b");
265 MODULE_PARM_DESC(PARM_MULTICAST_RATE, "Multicast Rate");
266 MODULE_PARM(PARM_DOWNLOAD_FIRMWARE, "s");
267 MODULE_PARM_DESC(PARM_DOWNLOAD_FIRMWARE, "filename of firmware image");
269 MODULE_PARM(PARM_AUTH_KEY_MGMT_SUITE, "b");
270 MODULE_PARM_DESC(PARM_AUTH_KEY_MGMT_SUITE, "Authentication Key Management suite (0-4) [0]");
272 MODULE_PARM(PARM_LOAD_BALANCING, "s");
273 MODULE_PARM_DESC(PARM_LOAD_BALANCING, "Load Balancing Enabled (<string> N or Y) [Y]");
274 MODULE_PARM(PARM_MEDIUM_DISTRIBUTION, "s");
275 MODULE_PARM_DESC(PARM_MEDIUM_DISTRIBUTION, "Medium Distribution Enabled (<string> N or Y) [Y]");
276 MODULE_PARM(PARM_TX_POW_LEVEL, "b");
277 MODULE_PARM_DESC(PARM_TX_POW_LEVEL, "Transmit Power (0 - 6) [3]");
278 MODULE_PARM(PARM_SRSC_2GHZ, "b");
279 MODULE_PARM_DESC(PARM_SRSC_2GHZ, "Supported Rate Set Control 2.4 GHz");
280 MODULE_PARM(PARM_SRSC_5GHZ, "b");
281 MODULE_PARM_DESC(PARM_SRSC_5GHZ, "Supported Rate Set Control 5.0 GHz");
282 MODULE_PARM(PARM_BRSC_2GHZ, "b");
283 MODULE_PARM_DESC(PARM_BRSC_2GHZ, "Basic Rate Set Control 2.4 GHz");
284 MODULE_PARM(PARM_BRSC_5GHZ, "b");
285 MODULE_PARM_DESC(PARM_BRSC_5GHZ, "Basic Rate Set Control 5.0 GHz");
286 #if 1 /* (HCF_TYPE) & HCF_TYPE_STA */
287 /* ;?seems reasonable that even an AP-only driver could afford this small additional footprint */
288 MODULE_PARM(PARM_PM_ENABLED, "h");
289 MODULE_PARM_DESC(PARM_PM_ENABLED, "Power Management State (0 - 2, 8001 - 8002) [0]");
290 MODULE_PARM(PARM_PORT_TYPE, "b");
291 MODULE_PARM_DESC(PARM_PORT_TYPE, "Port Type (1 - 3) [1]");
293 * ;?MODULE_PARM(PARM_CREATE_IBSS, "s");
294 *;?MODULE_PARM_DESC(PARM_CREATE_IBSS, "Create IBSS (<string> N or Y) [N]");
295 *;?MODULE_PARM(PARM_MULTICAST_RX, "s");
296 *;?MODULE_PARM_DESC(PARM_MULTICAST_RX, "Multicast Receive Enable (<string> N or Y) [Y]");
297 *;?MODULE_PARM(PARM_MAX_SLEEP, "h");
298 *;?MODULE_PARM_DESC(PARM_MAX_SLEEP, "Maximum Power Management Sleep Duration (0 - 65535) [100]");
299 *;?MODULE_PARM(PARM_NETWORK_ADDR, "6b");
300 *;?MODULE_PARM_DESC(PARM_NETWORK_ADDR, "Hardware Ethernet Address ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [<factory value>]");
301 *;?MODULE_PARM(PARM_AUTHENTICATION, "b");
304 *;?MODULE_PARM_DESC(PARM_AUTHENTICATION, "Authentication Type (0-2) [0] 0=Open 1=SharedKey 2=LEAP");
305 *;?MODULE_PARM_DESC(authentication, "Authentication Type (1-2) [1] 1=Open 2=SharedKey");
308 *;?MODULE_PARM(PARM_OWN_ATIM_WINDOW, "b");
309 *;?MODULE_PARM_DESC(PARM_OWN_ATIM_WINDOW, "ATIM Window time in TU for IBSS creation (0-100) [0]");
310 *;?MODULE_PARM(PARM_PM_HOLDOVER_DURATION, "b");
311 *;?MODULE_PARM_DESC(PARM_PM_HOLDOVER_DURATION, "Time station remains awake after MAC frame transfer when PM is on (0-65535) [100]");
312 *;?MODULE_PARM(PARM_PROMISCUOUS_MODE, "s");
313 *;?MODULE_PARM_DESC(PARM_PROMISCUOUS_MODE, "Promiscuous Mode Enable (<string> Y or N ) [N]" );
316 MODULE_PARM(PARM_CONNECTION_CONTROL, "b");
317 MODULE_PARM_DESC(PARM_CONNECTION_CONTROL, "Connection Control (0 - 3) [2]");
319 #if 1 /* ;? (HCF_TYPE) & HCF_TYPE_AP */
320 /* ;?should we restore this to allow smaller memory footprint */
321 MODULE_PARM(PARM_OWN_DTIM_PERIOD, "b");
322 MODULE_PARM_DESC(PARM_OWN_DTIM_PERIOD, "DTIM Period (0 - 255) [1]");
323 MODULE_PARM(PARM_REJECT_ANY, "s");
324 MODULE_PARM_DESC(PARM_REJECT_ANY, "Closed System (<string> N or Y) [N]");
325 MODULE_PARM(PARM_EXCLUDE_UNENCRYPTED, "s");
326 MODULE_PARM_DESC(PARM_EXCLUDE_UNENCRYPTED, "Deny non-encrypted (<string> N or Y) [Y]");
327 MODULE_PARM(PARM_MULTICAST_PM_BUFFERING,"s");
328 MODULE_PARM_DESC(PARM_MULTICAST_PM_BUFFERING, "Buffer MAC frames for Tx after DTIM (<string> Y or N) [Y]");
329 MODULE_PARM(PARM_INTRA_BSS_RELAY, "s");
330 MODULE_PARM_DESC(PARM_INTRA_BSS_RELAY, "IntraBSS Relay (<string> N or Y) [Y]");
331 MODULE_PARM(PARM_RTS_THRESHOLD1, "h");
332 MODULE_PARM_DESC(PARM_RTS_THRESHOLD1, "RTS Threshold, WDS Port 1 (256 - 2347) [2347]");
333 MODULE_PARM(PARM_RTS_THRESHOLD2, "h");
334 MODULE_PARM_DESC(PARM_RTS_THRESHOLD2, "RTS Threshold, WDS Port 2 (256 - 2347) [2347]");
335 MODULE_PARM(PARM_RTS_THRESHOLD3, "h");
336 MODULE_PARM_DESC(PARM_RTS_THRESHOLD3, "RTS Threshold, WDS Port 3 (256 - 2347) [2347]");
337 MODULE_PARM(PARM_RTS_THRESHOLD4, "h");
338 MODULE_PARM_DESC(PARM_RTS_THRESHOLD4, "RTS Threshold, WDS Port 4 (256 - 2347) [2347]");
339 MODULE_PARM(PARM_RTS_THRESHOLD5, "h");
340 MODULE_PARM_DESC(PARM_RTS_THRESHOLD5, "RTS Threshold, WDS Port 5 (256 - 2347) [2347]");
341 MODULE_PARM(PARM_RTS_THRESHOLD6, "h");
342 MODULE_PARM_DESC(PARM_RTS_THRESHOLD6, "RTS Threshold, WDS Port 6 (256 - 2347) [2347]");
343 MODULE_PARM(PARM_TX_RATE1, "b");
344 MODULE_PARM_DESC(PARM_TX_RATE1, "Transmit Rate Control, WDS Port 1 (1 - 7) [3]");
345 MODULE_PARM(PARM_TX_RATE2, "b");
346 MODULE_PARM_DESC(PARM_TX_RATE2, "Transmit Rate Control, WDS Port 2 (1 - 7) [3]");
347 MODULE_PARM(PARM_TX_RATE3, "b");
348 MODULE_PARM_DESC(PARM_TX_RATE3, "Transmit Rate Control, WDS Port 3 (1 - 7) [3]");
349 MODULE_PARM(PARM_TX_RATE4, "b");
350 MODULE_PARM_DESC(PARM_TX_RATE4, "Transmit Rate Control, WDS Port 4 (1 - 7) [3]");
351 MODULE_PARM(PARM_TX_RATE5, "b");
352 MODULE_PARM_DESC(PARM_TX_RATE5, "Transmit Rate Control, WDS Port 5 (1 - 7) [3]");
353 MODULE_PARM(PARM_TX_RATE6, "b");
354 MODULE_PARM_DESC(PARM_TX_RATE6, "Transmit Rate Control, WDS Port 6 (1 - 7) [3]");
355 MODULE_PARM(PARM_WDS_ADDRESS1, "6b");
356 MODULE_PARM_DESC(PARM_WDS_ADDRESS1, "MAC Address, WDS Port 1 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
357 MODULE_PARM(PARM_WDS_ADDRESS2, "6b");
358 MODULE_PARM_DESC(PARM_WDS_ADDRESS2, "MAC Address, WDS Port 2 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
359 MODULE_PARM(PARM_WDS_ADDRESS3, "6b");
360 MODULE_PARM_DESC(PARM_WDS_ADDRESS3, "MAC Address, WDS Port 3 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
361 MODULE_PARM(PARM_WDS_ADDRESS4, "6b");
362 MODULE_PARM_DESC(PARM_WDS_ADDRESS4, "MAC Address, WDS Port 4 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
363 MODULE_PARM(PARM_WDS_ADDRESS5, "6b");
364 MODULE_PARM_DESC(PARM_WDS_ADDRESS5, "MAC Address, WDS Port 5 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
365 MODULE_PARM(PARM_WDS_ADDRESS6, "6b");
366 MODULE_PARM_DESC(PARM_WDS_ADDRESS6, "MAC Address, WDS Port 6 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
368 MODULE_PARM(PARM_OWN_BEACON_INTERVAL, "b");
369 MODULE_PARM_DESC(PARM_OWN_BEACON_INTERVAL, "Own Beacon Interval (20 - 200) [100]");
370 MODULE_PARM(PARM_COEXISTENCE, "b");
371 MODULE_PARM_DESC(PARM_COEXISTENCE, "Coexistence (0-7) [0]");
376 /* END NEW PARAMETERS */
377 /*******************************************************************************
378 * debugging specifics
379 ******************************************************************************/
382 static p_u32 pc_debug = DBG_LVL;
384 * MODULE_PARM(pc_debug, "i");
385 *static ;?conflicts with my understanding of CL parameters and breaks now I moved
386 * the correspondig logic to wl_profile
387 */ p_u32 DebugFlag = ~0; /* recognizable "undefined value" rather then DBG_DEFAULTS; */
388 /* MODULE_PARM(DebugFlag, "l"); */
390 static struct dbg_info wl_info = { KBUILD_MODNAME, 0, 0 };
391 struct dbg_info *DbgInfo = &wl_info;
396 static p_char *useRTS = "N";
397 MODULE_PARM(useRTS, "s");
398 MODULE_PARM_DESC(useRTS, "Use RTS test interface (<string> N or Y) [N]");
401 /*******************************************************************************
402 * firmware download specifics
403 ******************************************************************************/
404 extern struct CFG_RANGE2_STRCT BASED
405 cfg_drv_act_ranges_pri; // describes primary-actor range of HCF
407 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
408 extern memimage ap; // AP firmware image to be downloaded
411 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
412 //extern memimage station; // STA firmware image to be downloaded
413 extern memimage fw_image; // firmware image to be downloaded
417 int wl_insert(struct net_device *dev)
420 int hcf_status = HCF_SUCCESS;
422 unsigned long flags = 0;
423 struct wl_private *lp = wl_priv(dev);
425 /* Initialize the adapter hardware. */
426 memset(&(lp->hcfCtx), 0, sizeof(IFB_STRCT));
428 /* Initialize the adapter parameters. */
429 spin_lock_init(&(lp->slock));
431 /* Initialize states */
432 //lp->lockcount = 0; //PE1DNN
433 lp->is_handling_int = WL_NOT_HANDLING_INT;
434 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
438 DBG_PARAM(DbgInfo, "irq_mask", "0x%04x", irq_mask & 0x0FFFF);
439 DBG_PARAM(DbgInfo, "irq_list", "0x%02x 0x%02x 0x%02x 0x%02x",
440 irq_list[0] & 0x0FF, irq_list[1] & 0x0FF,
441 irq_list[2] & 0x0FF, irq_list[3] & 0x0FF);
442 DBG_PARAM(DbgInfo, PARM_NAME_DESIRED_SSID, "\"%s\"", PARM_DESIRED_SSID);
443 DBG_PARAM(DbgInfo, PARM_NAME_OWN_SSID, "\"%s\"", PARM_OWN_SSID);
444 DBG_PARAM(DbgInfo, PARM_NAME_OWN_CHANNEL, "%d", PARM_OWN_CHANNEL);
445 DBG_PARAM(DbgInfo, PARM_NAME_SYSTEM_SCALE, "%d", PARM_SYSTEM_SCALE);
446 DBG_PARAM(DbgInfo, PARM_NAME_TX_RATE, "%d", PARM_TX_RATE);
447 DBG_PARAM(DbgInfo, PARM_NAME_RTS_THRESHOLD, "%d", PARM_RTS_THRESHOLD);
448 DBG_PARAM(DbgInfo, PARM_NAME_MICROWAVE_ROBUSTNESS, "\"%s\"", PARM_MICROWAVE_ROBUSTNESS);
449 DBG_PARAM(DbgInfo, PARM_NAME_OWN_NAME, "\"%s\"", PARM_OWN_NAME);
450 //;? DBG_PARAM( DbgInfo, PARM_NAME_ENABLE_ENCRYPTION, "\"%s\"", PARM_ENABLE_ENCRYPTION );
451 DBG_PARAM(DbgInfo, PARM_NAME_KEY1, "\"%s\"", PARM_KEY1);
452 DBG_PARAM(DbgInfo, PARM_NAME_KEY2, "\"%s\"", PARM_KEY2);
453 DBG_PARAM(DbgInfo, PARM_NAME_KEY3, "\"%s\"", PARM_KEY3);
454 DBG_PARAM(DbgInfo, PARM_NAME_KEY4, "\"%s\"", PARM_KEY4);
455 DBG_PARAM(DbgInfo, PARM_NAME_TX_KEY, "%d", PARM_TX_KEY);
456 DBG_PARAM(DbgInfo, PARM_NAME_MULTICAST_RATE, "%d", PARM_MULTICAST_RATE);
457 DBG_PARAM(DbgInfo, PARM_NAME_DOWNLOAD_FIRMWARE, "\"%s\"", PARM_DOWNLOAD_FIRMWARE);
458 DBG_PARAM(DbgInfo, PARM_NAME_AUTH_KEY_MGMT_SUITE, "%d", PARM_AUTH_KEY_MGMT_SUITE);
459 //;?#if (HCF_TYPE) & HCF_TYPE_STA
460 //;?should we make this code conditional depending on in STA mode
461 //;? DBG_PARAM( DbgInfo, PARM_NAME_PORT_TYPE, "%d", PARM_PORT_TYPE );
462 DBG_PARAM(DbgInfo, PARM_NAME_PM_ENABLED, "%04x", PARM_PM_ENABLED);
463 //;? DBG_PARAM( DbgInfo, PARM_NAME_CREATE_IBSS, "\"%s\"", PARM_CREATE_IBSS );
464 //;? DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RX, "\"%s\"", PARM_MULTICAST_RX );
465 //;? DBG_PARAM( DbgInfo, PARM_NAME_MAX_SLEEP, "%d", PARM_MAX_SLEEP );
467 DBG_PARAM(DbgInfo, PARM_NAME_NETWORK_ADDR, "\"%pM\"",
470 //;? DBG_PARAM( DbgInfo, PARM_NAME_AUTHENTICATION, "%d", PARM_AUTHENTICATION );
471 //;? DBG_PARAM( DbgInfo, PARM_NAME_OWN_ATIM_WINDOW, "%d", PARM_OWN_ATIM_WINDOW );
472 //;? DBG_PARAM( DbgInfo, PARM_NAME_PM_HOLDOVER_DURATION, "%d", PARM_PM_HOLDOVER_DURATION );
473 //;? DBG_PARAM( DbgInfo, PARM_NAME_PROMISCUOUS_MODE, "\"%s\"", PARM_PROMISCUOUS_MODE );
474 //;?#endif /* HCF_STA */
475 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
476 //;?should we restore this to allow smaller memory footprint
477 //;?I guess: no, since this is Debug mode only
478 DBG_PARAM(DbgInfo, PARM_NAME_OWN_DTIM_PERIOD, "%d", PARM_OWN_DTIM_PERIOD);
479 DBG_PARAM(DbgInfo, PARM_NAME_REJECT_ANY, "\"%s\"", PARM_REJECT_ANY);
480 DBG_PARAM(DbgInfo, PARM_NAME_EXCLUDE_UNENCRYPTED, "\"%s\"", PARM_EXCLUDE_UNENCRYPTED);
481 DBG_PARAM(DbgInfo, PARM_NAME_MULTICAST_PM_BUFFERING, "\"%s\"", PARM_MULTICAST_PM_BUFFERING);
482 DBG_PARAM(DbgInfo, PARM_NAME_INTRA_BSS_RELAY, "\"%s\"", PARM_INTRA_BSS_RELAY);
484 DBG_PARAM(DbgInfo, PARM_NAME_RTS_THRESHOLD1, "%d", PARM_RTS_THRESHOLD1);
485 DBG_PARAM(DbgInfo, PARM_NAME_RTS_THRESHOLD2, "%d", PARM_RTS_THRESHOLD2);
486 DBG_PARAM(DbgInfo, PARM_NAME_RTS_THRESHOLD3, "%d", PARM_RTS_THRESHOLD3);
487 DBG_PARAM(DbgInfo, PARM_NAME_RTS_THRESHOLD4, "%d", PARM_RTS_THRESHOLD4);
488 DBG_PARAM(DbgInfo, PARM_NAME_RTS_THRESHOLD5, "%d", PARM_RTS_THRESHOLD5);
489 DBG_PARAM(DbgInfo, PARM_NAME_RTS_THRESHOLD6, "%d", PARM_RTS_THRESHOLD6);
490 DBG_PARAM(DbgInfo, PARM_NAME_TX_RATE1, "%d", PARM_TX_RATE1);
491 DBG_PARAM(DbgInfo, PARM_NAME_TX_RATE2, "%d", PARM_TX_RATE2);
492 DBG_PARAM(DbgInfo, PARM_NAME_TX_RATE3, "%d", PARM_TX_RATE3);
493 DBG_PARAM(DbgInfo, PARM_NAME_TX_RATE4, "%d", PARM_TX_RATE4);
494 DBG_PARAM(DbgInfo, PARM_NAME_TX_RATE5, "%d", PARM_TX_RATE5);
495 DBG_PARAM(DbgInfo, PARM_NAME_TX_RATE6, "%d", PARM_TX_RATE6);
496 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS1, "\"%pM\"",
498 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS2, "\"%pM\"",
500 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS3, "\"%pM\"",
502 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS4, "\"%pM\"",
504 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS5, "\"%pM\"",
506 DBG_PARAM(DbgInfo, PARM_NAME_WDS_ADDRESS6, "\"%pM\"",
511 VALID_PARAM(!PARM_DESIRED_SSID || (strlen(PARM_DESIRED_SSID) <= PARM_MAX_NAME_LEN));
512 VALID_PARAM(!PARM_OWN_SSID || (strlen(PARM_OWN_SSID) <= PARM_MAX_NAME_LEN));
513 VALID_PARAM((PARM_OWN_CHANNEL <= PARM_MAX_OWN_CHANNEL));
514 VALID_PARAM((PARM_SYSTEM_SCALE >= PARM_MIN_SYSTEM_SCALE) && (PARM_SYSTEM_SCALE <= PARM_MAX_SYSTEM_SCALE));
515 VALID_PARAM((PARM_TX_RATE >= PARM_MIN_TX_RATE) && (PARM_TX_RATE <= PARM_MAX_TX_RATE));
516 VALID_PARAM((PARM_RTS_THRESHOLD <= PARM_MAX_RTS_THRESHOLD));
517 VALID_PARAM(!PARM_MICROWAVE_ROBUSTNESS || strchr("NnYy", PARM_MICROWAVE_ROBUSTNESS[0]) != NULL);
518 VALID_PARAM(!PARM_OWN_NAME || (strlen(PARM_NAME_OWN_NAME) <= PARM_MAX_NAME_LEN));
519 VALID_PARAM((PARM_ENABLE_ENCRYPTION <= PARM_MAX_ENABLE_ENCRYPTION));
520 VALID_PARAM(is_valid_key_string(PARM_KEY1));
521 VALID_PARAM(is_valid_key_string(PARM_KEY2));
522 VALID_PARAM(is_valid_key_string(PARM_KEY3));
523 VALID_PARAM(is_valid_key_string(PARM_KEY4));
524 VALID_PARAM((PARM_TX_KEY >= PARM_MIN_TX_KEY) && (PARM_TX_KEY <= PARM_MAX_TX_KEY));
526 VALID_PARAM((PARM_MULTICAST_RATE >= PARM_MIN_MULTICAST_RATE) &&
527 (PARM_MULTICAST_RATE <= PARM_MAX_MULTICAST_RATE));
529 VALID_PARAM(!PARM_DOWNLOAD_FIRMWARE || (strlen(PARM_DOWNLOAD_FIRMWARE) <= 255 /*;?*/));
530 VALID_PARAM((PARM_AUTH_KEY_MGMT_SUITE < PARM_MAX_AUTH_KEY_MGMT_SUITE));
532 VALID_PARAM(!PARM_LOAD_BALANCING || strchr("NnYy", PARM_LOAD_BALANCING[0]) != NULL);
533 VALID_PARAM( !PARM_MEDIUM_DISTRIBUTION || strchr( "NnYy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL );
534 VALID_PARAM(( PARM_TX_POW_LEVEL <= PARM_MAX_TX_POW_LEVEL ));
536 VALID_PARAM(( PARM_PORT_TYPE >= PARM_MIN_PORT_TYPE ) && ( PARM_PORT_TYPE <= PARM_MAX_PORT_TYPE ));
537 VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
538 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
539 VALID_PARAM( !PARM_CREATE_IBSS || strchr( "NnYy", PARM_CREATE_IBSS[0] ) != NULL );
540 VALID_PARAM( !PARM_MULTICAST_RX || strchr( "NnYy", PARM_MULTICAST_RX[0] ) != NULL );
541 VALID_PARAM(( PARM_MAX_SLEEP <= PARM_MAX_MAX_PM_SLEEP ));
542 VALID_PARAM(( PARM_AUTHENTICATION <= PARM_MAX_AUTHENTICATION ));
543 VALID_PARAM(( PARM_OWN_ATIM_WINDOW <= PARM_MAX_OWN_ATIM_WINDOW ));
544 VALID_PARAM(( PARM_PM_HOLDOVER_DURATION <= PARM_MAX_PM_HOLDOVER_DURATION ));
545 VALID_PARAM( !PARM_PROMISCUOUS_MODE || strchr( "NnYy", PARM_PROMISCUOUS_MODE[0] ) != NULL );
546 VALID_PARAM(( PARM_CONNECTION_CONTROL <= PARM_MAX_CONNECTION_CONTROL ));
548 VALID_PARAM(( PARM_OWN_DTIM_PERIOD >= PARM_MIN_OWN_DTIM_PERIOD ));
549 VALID_PARAM( !PARM_REJECT_ANY || strchr( "NnYy", PARM_REJECT_ANY[0] ) != NULL );
550 VALID_PARAM( !PARM_EXCLUDE_UNENCRYPTED || strchr( "NnYy", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL );
551 VALID_PARAM( !PARM_MULTICAST_PM_BUFFERING || strchr( "NnYy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL );
552 VALID_PARAM( !PARM_INTRA_BSS_RELAY || strchr( "NnYy", PARM_INTRA_BSS_RELAY[0] ) != NULL );
554 VALID_PARAM(( PARM_RTS_THRESHOLD1 <= PARM_MAX_RTS_THRESHOLD ));
555 VALID_PARAM(( PARM_RTS_THRESHOLD2 <= PARM_MAX_RTS_THRESHOLD ));
556 VALID_PARAM(( PARM_RTS_THRESHOLD3 <= PARM_MAX_RTS_THRESHOLD ));
557 VALID_PARAM(( PARM_RTS_THRESHOLD4 <= PARM_MAX_RTS_THRESHOLD ));
558 VALID_PARAM(( PARM_RTS_THRESHOLD5 <= PARM_MAX_RTS_THRESHOLD ));
559 VALID_PARAM(( PARM_RTS_THRESHOLD6 <= PARM_MAX_RTS_THRESHOLD ));
560 VALID_PARAM(( PARM_TX_RATE1 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE1 <= PARM_MAX_TX_RATE ));
561 VALID_PARAM(( PARM_TX_RATE2 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE2 <= PARM_MAX_TX_RATE ));
562 VALID_PARAM(( PARM_TX_RATE3 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE3 <= PARM_MAX_TX_RATE ));
563 VALID_PARAM(( PARM_TX_RATE4 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE4 <= PARM_MAX_TX_RATE ));
564 VALID_PARAM(( PARM_TX_RATE5 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE5 <= PARM_MAX_TX_RATE ));
565 VALID_PARAM(( PARM_TX_RATE6 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE6 <= PARM_MAX_TX_RATE ));
568 VALID_PARAM(( PARM_OWN_BEACON_INTERVAL >= PARM_MIN_OWN_BEACON_INTERVAL ) && ( PARM_OWN_BEACON_INTERVAL <= PARM_MAX_OWN_BEACON_INTERVAL ));
569 VALID_PARAM(( PARM_COEXISTENCE <= PARM_COEXISTENCE ));
571 /* Set the driver parameters from the passed in parameters. */
573 /* THESE MODULE PARAMETERS ARE TO BE DEPRECATED IN FAVOR OF A NAMING CONVENTION
574 WHICH IS INLINE WITH THE FORTHCOMING WAVELAN API */
576 /* START NEW PARAMETERS */
578 lp->Channel = PARM_OWN_CHANNEL;
579 lp->DistanceBetweenAPs = PARM_SYSTEM_SCALE;
581 /* Need to determine how to handle the new bands for 5GHz */
582 lp->TxRateControl[0] = PARM_DEFAULT_TX_RATE_2GHZ;
583 lp->TxRateControl[1] = PARM_DEFAULT_TX_RATE_5GHZ;
585 lp->RTSThreshold = PARM_RTS_THRESHOLD;
587 /* Need to determine how to handle the new bands for 5GHz */
588 lp->MulticastRate[0] = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
589 lp->MulticastRate[1] = PARM_DEFAULT_MULTICAST_RATE_5GHZ;
591 if ( strchr( "Yy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL )
592 lp->MicrowaveRobustness = 1;
594 lp->MicrowaveRobustness = 0;
595 if ( PARM_DESIRED_SSID && ( strlen( PARM_DESIRED_SSID ) <= HCF_MAX_NAME_LEN ))
596 strcpy( lp->NetworkName, PARM_DESIRED_SSID );
597 if ( PARM_OWN_SSID && ( strlen( PARM_OWN_SSID ) <= HCF_MAX_NAME_LEN ))
598 strcpy( lp->NetworkName, PARM_OWN_SSID );
599 if ( PARM_OWN_NAME && ( strlen( PARM_OWN_NAME ) <= HCF_MAX_NAME_LEN ))
600 strcpy( lp->StationName, PARM_OWN_NAME );
601 lp->EnableEncryption = PARM_ENABLE_ENCRYPTION;
602 if ( PARM_KEY1 && ( strlen( PARM_KEY1 ) <= MAX_KEY_LEN ))
603 strcpy( lp->Key1, PARM_KEY1 );
604 if ( PARM_KEY2 && ( strlen( PARM_KEY2 ) <= MAX_KEY_LEN ))
605 strcpy( lp->Key2, PARM_KEY2 );
606 if ( PARM_KEY3 && ( strlen( PARM_KEY3 ) <= MAX_KEY_LEN ))
607 strcpy( lp->Key3, PARM_KEY3 );
608 if ( PARM_KEY4 && ( strlen( PARM_KEY4 ) <= MAX_KEY_LEN ))
609 strcpy( lp->Key4, PARM_KEY4 );
611 lp->TransmitKeyID = PARM_TX_KEY;
613 key_string2key( lp->Key1, &(lp->DefaultKeys.key[0] ));
614 key_string2key( lp->Key2, &(lp->DefaultKeys.key[1] ));
615 key_string2key( lp->Key3, &(lp->DefaultKeys.key[2] ));
616 key_string2key( lp->Key4, &(lp->DefaultKeys.key[3] ));
618 lp->DownloadFirmware = 1 ; //;?to be upgraded PARM_DOWNLOAD_FIRMWARE;
619 lp->AuthKeyMgmtSuite = PARM_AUTH_KEY_MGMT_SUITE;
621 if ( strchr( "Yy", PARM_LOAD_BALANCING[0] ) != NULL )
622 lp->loadBalancing = 1;
624 lp->loadBalancing = 0;
626 if ( strchr( "Yy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL )
627 lp->mediumDistribution = 1;
629 lp->mediumDistribution = 0;
631 lp->txPowLevel = PARM_TX_POW_LEVEL;
633 lp->srsc[0] = PARM_SRSC_2GHZ;
634 lp->srsc[1] = PARM_SRSC_5GHZ;
635 lp->brsc[0] = PARM_BRSC_2GHZ;
636 lp->brsc[1] = PARM_BRSC_5GHZ;
637 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
638 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
639 lp->PortType = PARM_PORT_TYPE;
640 lp->MaxSleepDuration = PARM_MAX_SLEEP;
641 lp->authentication = PARM_AUTHENTICATION;
642 lp->atimWindow = PARM_OWN_ATIM_WINDOW;
643 lp->holdoverDuration = PARM_PM_HOLDOVER_DURATION;
644 lp->PMEnabled = PARM_PM_ENABLED; //;?
645 if ( strchr( "Yy", PARM_CREATE_IBSS[0] ) != NULL )
649 if ( strchr( "Nn", PARM_MULTICAST_RX[0] ) != NULL )
650 lp->MulticastReceive = 0;
652 lp->MulticastReceive = 1;
653 if ( strchr( "Yy", PARM_PROMISCUOUS_MODE[0] ) != NULL )
654 lp->promiscuousMode = 1;
656 lp->promiscuousMode = 0;
657 for( i = 0; i < ETH_ALEN; i++ )
658 lp->MACAddress[i] = PARM_NETWORK_ADDR[i];
660 lp->connectionControl = PARM_CONNECTION_CONTROL;
663 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
664 //;?should we restore this to allow smaller memory footprint
665 lp->DTIMPeriod = PARM_OWN_DTIM_PERIOD;
667 if ( strchr( "Yy", PARM_REJECT_ANY[0] ) != NULL )
671 if ( strchr( "Nn", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL )
672 lp->ExcludeUnencrypted = 0;
674 lp->ExcludeUnencrypted = 1;
675 if ( strchr( "Yy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL )
676 lp->multicastPMBuffering = 1;
678 lp->multicastPMBuffering = 0;
679 if ( strchr( "Yy", PARM_INTRA_BSS_RELAY[0] ) != NULL )
680 lp->intraBSSRelay = 1;
682 lp->intraBSSRelay = 0;
684 lp->ownBeaconInterval = PARM_OWN_BEACON_INTERVAL;
685 lp->coexistence = PARM_COEXISTENCE;
688 lp->wds_port[0].rtsThreshold = PARM_RTS_THRESHOLD1;
689 lp->wds_port[1].rtsThreshold = PARM_RTS_THRESHOLD2;
690 lp->wds_port[2].rtsThreshold = PARM_RTS_THRESHOLD3;
691 lp->wds_port[3].rtsThreshold = PARM_RTS_THRESHOLD4;
692 lp->wds_port[4].rtsThreshold = PARM_RTS_THRESHOLD5;
693 lp->wds_port[5].rtsThreshold = PARM_RTS_THRESHOLD6;
694 lp->wds_port[0].txRateCntl = PARM_TX_RATE1;
695 lp->wds_port[1].txRateCntl = PARM_TX_RATE2;
696 lp->wds_port[2].txRateCntl = PARM_TX_RATE3;
697 lp->wds_port[3].txRateCntl = PARM_TX_RATE4;
698 lp->wds_port[4].txRateCntl = PARM_TX_RATE5;
699 lp->wds_port[5].txRateCntl = PARM_TX_RATE6;
701 for( i = 0; i < ETH_ALEN; i++ ) {
702 lp->wds_port[0].wdsAddress[i] = PARM_WDS_ADDRESS1[i];
704 for( i = 0; i < ETH_ALEN; i++ ) {
705 lp->wds_port[1].wdsAddress[i] = PARM_WDS_ADDRESS2[i];
707 for( i = 0; i < ETH_ALEN; i++ ) {
708 lp->wds_port[2].wdsAddress[i] = PARM_WDS_ADDRESS3[i];
710 for( i = 0; i < ETH_ALEN; i++ ) {
711 lp->wds_port[3].wdsAddress[i] = PARM_WDS_ADDRESS4[i];
713 for( i = 0; i < ETH_ALEN; i++ ) {
714 lp->wds_port[4].wdsAddress[i] = PARM_WDS_ADDRESS5[i];
716 for( i = 0; i < ETH_ALEN; i++ ) {
717 lp->wds_port[5].wdsAddress[i] = PARM_WDS_ADDRESS6[i];
722 if ( strchr( "Yy", useRTS[0] ) != NULL )
729 /* END NEW PARAMETERS */
732 wl_lock( lp, &flags );
734 /* Initialize the portState variable */
735 lp->portState = WVLAN_PORT_STATE_DISABLED;
737 /* Initialize the ScanResult struct */
738 memset( &( lp->scan_results ), 0, sizeof( lp->scan_results ));
739 lp->scan_results.scan_complete = FALSE;
741 /* Initialize the ProbeResult struct */
742 memset( &( lp->probe_results ), 0, sizeof( lp->probe_results ));
743 lp->probe_results.scan_complete = FALSE;
744 lp->probe_num_aps = 0;
747 /* Initialize Tx queue stuff */
748 memset( lp->txList, 0, sizeof( lp->txList ));
750 INIT_LIST_HEAD( &( lp->txFree ));
756 for( i = 0; i < DEFAULT_NUM_TX_FRAMES; i++ ) {
757 list_add_tail( &( lp->txList[i].node ), &( lp->txFree ));
761 for( i = 0; i < WVLAN_MAX_TX_QUEUES; i++ ) {
762 INIT_LIST_HEAD( &( lp->txQ[i] ));
765 lp->netif_queue_on = TRUE;
767 /* Initialize the use_dma element in the adapter structure. Not sure if
768 this should be a compile-time or run-time configurable. So for now,
769 implement as run-time and just define here */
772 DBG_TRACE( DbgInfo, "HERMES 2.5 BUSMASTER DMA MODE\n" );
775 DBG_TRACE( DbgInfo, "HERMES 2.5 PORT I/O MODE\n" );
780 /* Register the ISR handler information here, so that it's not done
781 repeatedly in the ISR */
782 tasklet_init(&lp->task, wl_isr_handler, (unsigned long)lp);
784 /* Connect to the adapter */
785 DBG_TRACE( DbgInfo, "Calling hcf_connect()...\n" );
786 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
787 //HCF_ERR_INCOMP_FW is acceptable, because download must still take place
788 //HCF_ERR_INCOMP_PRI is not acceptable
789 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
790 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
791 wl_unlock( lp, &flags );
795 //;?should set HCF_version and how about driver_stat
796 lp->driverInfo.IO_address = dev->base_addr;
797 lp->driverInfo.IO_range = HCF_NUM_IO_PORTS; //;?conditionally 0x40 or 0x80 seems better
798 lp->driverInfo.IRQ_number = dev->irq;
799 lp->driverInfo.card_stat = lp->hcfCtx.IFB_CardStat;
800 //;? what happened to frame_type
802 /* Fill in the driver identity structure */
803 lp->driverIdentity.len = ( sizeof( lp->driverIdentity ) / sizeof( hcf_16 )) - 1;
804 lp->driverIdentity.typ = CFG_DRV_IDENTITY;
805 lp->driverIdentity.comp_id = DRV_IDENTITY;
806 lp->driverIdentity.variant = DRV_VARIANT;
807 lp->driverIdentity.version_major = DRV_MAJOR_VERSION;
808 lp->driverIdentity.version_minor = DRV_MINOR_VERSION;
811 /* Start the card here - This needs to be done in order to get the
812 MAC address for the network layer */
813 DBG_TRACE( DbgInfo, "Calling wvlan_go() to perform a card reset...\n" );
814 hcf_status = wl_go( lp );
816 if ( hcf_status != HCF_SUCCESS ) {
817 DBG_ERROR( DbgInfo, "wl_go() failed\n" );
818 wl_unlock( lp, &flags );
822 /* Certain RIDs must be set before enabling the ports */
823 wl_put_ltv_init( lp );
825 #if 0 //;?why was this already commented out in wl_lkm_720
826 /* Enable the ports */
827 if ( wl_adapter_is_open( lp->dev )) {
828 /* Enable the ports */
829 DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
830 hcf_status = wl_enable( lp );
832 if ( hcf_status != HCF_SUCCESS ) {
833 DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", hcf_status );
836 #if (HCF_TYPE) & HCF_TYPE_AP
837 DBG_TRACE( DbgInfo, "Enabling WDS Ports\n" );
838 //wl_enable_wds_ports( lp );
839 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
844 /* Fill out the MAC address information in the net_device struct */
845 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN );
846 dev->addr_len = ETH_ALEN;
848 lp->is_registered = TRUE;
851 /* Parse the config file for the sake of creating WDS ports if WDS is
852 configured there but not in the module options */
854 #endif /* USE_PROFILE */
856 /* If we're going into AP Mode, register the "virtual" ethernet devices
858 WL_WDS_NETDEV_REGISTER( lp );
860 /* Reset the DownloadFirmware variable in the private struct. If the
861 config file is not used, this will not matter; if it is used, it
862 will be reparsed in wl_open(). This is done because logic in wl_open
863 used to check if a firmware download is needed is broken by parsing
864 the file here; however, this parsing is needed to register WDS ports
865 in AP mode, if they are configured */
866 lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //;?download_firmware;
869 if ( lp->useRTS == 1 ) {
870 DBG_TRACE( DbgInfo, "ENTERING RTS MODE...\n" );
871 wl_act_int_off( lp );
872 lp->is_handling_int = WL_NOT_HANDLING_INT; // Not handling interrupts anymore
876 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT);
880 wl_unlock( lp, &flags );
882 DBG_TRACE( DbgInfo, "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
883 dev->name, dev->base_addr, dev->irq );
885 for( i = 0; i < ETH_ALEN; i++ ) {
886 printk( "%02X%c", dev->dev_addr[i], (( i < ( ETH_ALEN-1 )) ? ':' : '\n' ));
889 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
890 proc_create_data( "wlags", 0, NULL, &scull_read_procmem_fops, dev );
891 proc_mkdir("driver/wlags49", 0);
892 #endif /* SCULL_USE_PROC */
897 wl_hcf_error( dev, hcf_status );
901 DBG_ERROR( DbgInfo, "wl_insert() FAILED\n" );
903 if ( lp->is_registered == TRUE ) {
904 lp->is_registered = FALSE;
907 WL_WDS_NETDEV_DEREGISTER( lp );
913 /*============================================================================*/
916 /*******************************************************************************
918 *******************************************************************************
926 * dev - a pointer to the net_device struct of the wireless device
932 ******************************************************************************/
933 int wl_reset(struct net_device *dev)
935 struct wl_private *lp = wl_priv(dev);
936 int hcf_status = HCF_SUCCESS;
938 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
939 DBG_PARAM( DbgInfo, "dev->base_addr", "(%#03lx)", dev->base_addr );
942 * The caller should already have a lock and
943 * disable the interrupts, we do not lock here,
944 * nor do we enable/disable interrupts!
947 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", dev->base_addr );
948 if ( dev->base_addr ) {
949 /* Shutdown the adapter. */
950 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
952 /* Reset the driver information. */
955 /* Connect to the adapter. */
956 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
957 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
958 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
962 /* Check if firmware is present, if not change state */
963 if ( hcf_status == HCF_ERR_INCOMP_FW ) {
964 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
967 /* Initialize the portState variable */
968 lp->portState = WVLAN_PORT_STATE_DISABLED;
970 /* Restart the adapter. */
971 hcf_status = wl_go( lp );
972 if ( hcf_status != HCF_SUCCESS ) {
973 DBG_ERROR( DbgInfo, "wl_go() failed, status: 0x%x\n", hcf_status );
977 /* Certain RIDs must be set before enabling the ports */
978 wl_put_ltv_init( lp );
980 DBG_ERROR( DbgInfo, "Device Base Address INVALID!!!\n" );
986 /*============================================================================*/
989 /*******************************************************************************
991 *******************************************************************************
999 * dev - a pointer to the net_device struct of the wireless device
1003 * an HCF status code
1005 ******************************************************************************/
1006 int wl_go( struct wl_private *lp )
1008 int hcf_status = HCF_SUCCESS;
1009 char *cp = NULL; //fw_image
1012 hcf_status = wl_disable( lp );
1013 if ( hcf_status != HCF_SUCCESS ) {
1014 DBG_TRACE( DbgInfo, "Disable port 0 failed: 0x%x\n", hcf_status );
1016 while (( hcf_status != HCF_SUCCESS ) && (retries < 10)) {
1018 hcf_status = wl_disable( lp );
1020 if ( hcf_status == HCF_SUCCESS ) {
1021 DBG_TRACE( DbgInfo, "Disable port 0 succes : %d retries\n", retries );
1023 DBG_TRACE( DbgInfo, "Disable port 0 failed after: %d retries\n", retries );
1027 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
1028 //DBG_TRACE( DbgInfo, "Disabling WDS Ports\n" );
1029 //wl_disable_wds_ports( lp );
1030 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1032 //;?what was the purpose of this
1033 // /* load the appropriate firmware image, depending on driver mode */
1034 // lp->ltvRecord.len = ( sizeof( CFG_RANGE20_STRCT ) / sizeof( hcf_16 )) - 1;
1035 // lp->ltvRecord.typ = CFG_DRV_ACT_RANGES_PRI;
1036 // hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1039 if ( strlen( lp->fw_image_filename ) ) {
1044 DBG_TRACE( DbgInfo, "F/W image:%s:\n", lp->fw_image_filename );
1045 /* Obtain a user-space process context, storing the original context */
1048 file_desc = open( lp->fw_image_filename, O_RDONLY, 0 );
1049 if ( file_desc == -1 ) {
1050 DBG_ERROR( DbgInfo, "No image file found\n" );
1052 DBG_TRACE( DbgInfo, "F/W image file found\n" );
1053 #define DHF_ALLOC_SIZE 96000 //just below 96K, let's hope it suffices for now and for the future
1054 cp = (char*)vmalloc( DHF_ALLOC_SIZE );
1056 DBG_ERROR( DbgInfo, "error in vmalloc\n" );
1058 rc = read( file_desc, cp, DHF_ALLOC_SIZE );
1059 if ( rc == DHF_ALLOC_SIZE ) {
1060 DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE );
1061 } else if ( rc > 0 ) {
1062 DBG_TRACE( DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp );
1063 rc = read( file_desc, &cp[rc], 1 );
1064 if ( rc == 0 ) { //;/change to an until-loop at rc<=0
1065 DBG_TRACE( DbgInfo, "no more to read\n" );
1069 DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\
1070 ", give up, too complicated, rc = %0X\n", rc );
1071 DBG_ERROR( DbgInfo, "still have to change code to get a real download now !!!!!!!!\n" );
1073 DBG_TRACE( DbgInfo, "before dhf_download_binary\n" );
1074 hcf_status = dhf_download_binary( (memimage *)cp );
1075 DBG_TRACE( DbgInfo, "after dhf_download_binary, before dhf_download_fw\n" );
1076 //;?improve error flow/handling
1077 hcf_status = dhf_download_fw( &lp->hcfCtx, (memimage *)cp );
1078 DBG_TRACE( DbgInfo, "after dhf_download_fw\n" );
1084 set_fs( fs ); /* Return to the original context */
1088 /* If firmware is present but the type is unknown then download anyway */
1089 if ( (lp->firmware_present == WL_FRIMWARE_PRESENT)
1091 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_STA )
1093 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_AP ) ) {
1094 /* Unknown type, download needed. */
1095 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1098 if(lp->firmware_present == WL_FRIMWARE_NOT_PRESENT)
1101 DBG_TRACE( DbgInfo, "Downloading STA firmware...\n" );
1102 // hcf_status = dhf_download_fw( &lp->hcfCtx, &station );
1103 hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image );
1105 if ( hcf_status != HCF_SUCCESS ) {
1106 DBG_ERROR( DbgInfo, "Firmware Download failed\n" );
1110 /* Report the FW versions */
1111 //;?obsolete, use the available IFB info:: wl_get_pri_records( lp );
1112 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1113 DBG_TRACE( DbgInfo, "downloaded station F/W\n" );
1114 } else if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1115 DBG_TRACE( DbgInfo, "downloaded AP F/W\n" );
1117 DBG_ERROR( DbgInfo, "unknown F/W type\n" );
1121 * Downloaded, no need to repeat this next time, assume the
1122 * contents stays in the card until it is powered off. Note we
1123 * do not switch firmware on the fly, the firmware is fixed in
1124 * the driver for now.
1126 lp->firmware_present = WL_FRIMWARE_PRESENT;
1128 DBG_TRACE( DbgInfo, "ComponentID:%04x variant:%04x major:%04x minor:%04x\n",
1129 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ),
1130 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.variant ),
1131 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_major ),
1132 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_minor ));
1134 /* now we will get the MAC address of the card */
1135 lp->ltvRecord.len = 4;
1136 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1137 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1140 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1142 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1143 if ( hcf_status != HCF_SUCCESS ) {
1144 DBG_ERROR( DbgInfo, "Could not retrieve MAC address\n" );
1147 memcpy( lp->MACAddress, &lp->ltvRecord.u.u8[0], ETH_ALEN );
1148 DBG_TRACE(DbgInfo, "Card MAC Address: %pM\n", lp->MACAddress);
1150 /* Write out configuration to the device, enable, and reconnect. However,
1151 only reconnect if in AP mode. For STA mode, need to wait for passive scan
1152 completion before a connect can be issued */
1154 /* Enable the ports */
1155 hcf_status = wl_enable( lp );
1157 if ( lp->DownloadFirmware == WVLAN_DRV_MODE_AP ) {
1159 wl_enable_wds_ports( lp );
1161 hcf_status = wl_connect( lp );
1165 /*============================================================================*/
1168 /*******************************************************************************
1170 *******************************************************************************
1174 * Write TxKeyID and WEP keys to the adapter. This is separated from
1175 * wl_apply() to allow dynamic WEP key updates through the wireless
1180 * lp - a pointer to the wireless adapter's private structure
1186 ******************************************************************************/
1187 void wl_set_wep_keys( struct wl_private *lp )
1191 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1192 if ( lp->EnableEncryption ) {
1193 /* NOTE: CFG_CNF_ENCRYPTION is set in wl_put_ltv() as it's a static
1197 lp->ltvRecord.len = 2;
1198 lp->ltvRecord.typ = CFG_TX_KEY_ID;
1199 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE(lp->TransmitKeyID - 1);
1201 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1203 DBG_TRACE( DbgInfo, "Key 1 len: %d\n", lp->DefaultKeys.key[0].len );
1204 DBG_TRACE( DbgInfo, "Key 2 len: %d\n", lp->DefaultKeys.key[1].len );
1205 DBG_TRACE( DbgInfo, "Key 3 len: %d\n", lp->DefaultKeys.key[2].len );
1206 DBG_TRACE( DbgInfo, "Key 4 len: %d\n", lp->DefaultKeys.key[3].len );
1209 lp->DefaultKeys.len = sizeof( lp->DefaultKeys ) / sizeof( hcf_16 ) - 1;
1210 lp->DefaultKeys.typ = CFG_DEFAULT_KEYS;
1212 /* endian translate the appropriate key information */
1213 for( count = 0; count < MAX_KEYS; count++ ) {
1214 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1217 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->DefaultKeys ));
1219 /* Reverse the above endian translation, since these keys are accessed
1221 for( count = 0; count < MAX_KEYS; count++ ) {
1222 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1225 DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption, lp->TransmitKeyID );
1226 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 );
1228 } // wl_set_wep_keys
1229 /*============================================================================*/
1232 /*******************************************************************************
1234 *******************************************************************************
1238 * Write the parameters to the adapter. (re-)enables the card if device is
1239 * open. Returns hcf_status of hcf_enable().
1243 * lp - a pointer to the wireless adapter's private structure
1247 * an HCF status code
1249 ******************************************************************************/
1250 int wl_apply(struct wl_private *lp)
1252 int hcf_status = HCF_SUCCESS;
1254 DBG_ASSERT( lp != NULL);
1255 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1257 if ( !( lp->flags & WVLAN2_UIL_BUSY )) {
1258 /* The adapter parameters have changed:
1264 if ( wl_adapter_is_open( lp->dev )) {
1265 /* Disconnect and disable if necessary */
1266 hcf_status = wl_disconnect( lp );
1267 if ( hcf_status != HCF_SUCCESS ) {
1268 DBG_ERROR( DbgInfo, "Disconnect failed\n" );
1271 hcf_status = wl_disable( lp );
1272 if ( hcf_status != HCF_SUCCESS ) {
1273 DBG_ERROR( DbgInfo, "Disable failed\n" );
1276 /* Write out configuration to the device, enable, and reconnect.
1277 However, only reconnect if in AP mode. For STA mode, need to
1278 wait for passive scan completion before a connect can be
1280 hcf_status = wl_put_ltv( lp );
1282 if ( hcf_status == HCF_SUCCESS ) {
1283 hcf_status = wl_enable( lp );
1285 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1286 hcf_status = wl_connect( lp );
1289 DBG_WARNING( DbgInfo, "wl_put_ltv() failed\n" );
1297 /*============================================================================*/
1300 /*******************************************************************************
1302 *******************************************************************************
1306 * Used to set basic parameters for card initialization.
1310 * lp - a pointer to the wireless adapter's private structure
1314 * an HCF status code
1316 ******************************************************************************/
1317 int wl_put_ltv_init( struct wl_private *lp )
1321 CFG_RID_LOG_STRCT *RidLog;
1324 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1328 lp->ltvRecord.len = 2;
1329 lp->ltvRecord.typ = CFG_CNTL_OPT;
1331 /* The Card Services build must ALWAYS be configured for 16-bit I/O. PCI or
1332 CardBus can be set to either 16/32 bit I/O, or Bus Master DMA, but only
1335 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_16BIT );
1337 if ( lp->use_dma ) {
1338 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_DMA );
1340 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1344 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1345 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT : 0x%04x\n",
1346 lp->ltvRecord.u.u16[0] );
1347 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT result : 0x%04x\n",
1350 /* Register the list of RIDs on which asynchronous notification is
1351 required. Note that this mechanism replaces the mailbox, so the mailbox
1352 can be queried by the host (if desired) without contention from us */
1355 lp->RidList[i].len = sizeof( lp->ProbeResp );
1356 lp->RidList[i].typ = CFG_ACS_SCAN;
1357 lp->RidList[i].bufp = (wci_recordp)&lp->ProbeResp;
1358 //lp->ProbeResp.infoType = 0xFFFF;
1361 lp->RidList[i].len = sizeof( lp->assoc_stat );
1362 lp->RidList[i].typ = CFG_ASSOC_STAT;
1363 lp->RidList[i].bufp = (wci_recordp)&lp->assoc_stat;
1364 lp->assoc_stat.len = 0xFFFF;
1367 lp->RidList[i].len = 4;
1368 lp->RidList[i].typ = CFG_UPDATED_INFO_RECORD;
1369 lp->RidList[i].bufp = (wci_recordp)&lp->updatedRecord;
1370 lp->updatedRecord.len = 0xFFFF;
1373 lp->RidList[i].len = sizeof( lp->sec_stat );
1374 lp->RidList[i].typ = CFG_SECURITY_STAT;
1375 lp->RidList[i].bufp = (wci_recordp)&lp->sec_stat;
1376 lp->sec_stat.len = 0xFFFF;
1379 lp->RidList[i].typ = 0; // Terminate List
1381 RidLog = (CFG_RID_LOG_STRCT *)&lp->ltvRecord;
1383 RidLog->typ = CFG_REG_INFO_LOG;
1384 RidLog->recordp = (RID_LOGP)&lp->RidList[0];
1386 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1387 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG\n" );
1388 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG result : 0x%04x\n",
1391 } // wl_put_ltv_init
1392 /*============================================================================*/
1395 /*******************************************************************************
1397 *******************************************************************************
1401 * Used by wvlan_apply() and wvlan_go to set the card's configuration.
1405 * lp - a pointer to the wireless adapter's private structure
1409 * an HCF status code
1411 ******************************************************************************/
1412 int wl_put_ltv( struct wl_private *lp )
1418 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1421 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1422 lp->maxPort = 6; //;?why set this here and not as part of download process
1427 /* Send our configuration to the card. Perform any endian translation
1429 /* Register the Mailbox; VxWorks does this elsewhere; why;? */
1430 lp->ltvRecord.len = 4;
1431 lp->ltvRecord.typ = CFG_REG_MB;
1432 lp->ltvRecord.u.u32[0] = (u_long)&( lp->mailbox );
1433 lp->ltvRecord.u.u16[2] = ( MB_SIZE / sizeof( hcf_16 ));
1434 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1436 /* Max Data Length */
1437 lp->ltvRecord.len = 2;
1438 lp->ltvRecord.typ = CFG_CNF_MAX_DATA_LEN;
1439 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( HCF_MAX_PACKET_SIZE );
1440 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1442 /* System Scale / Distance between APs */
1443 lp->ltvRecord.len = 2;
1444 lp->ltvRecord.typ = CFG_CNF_SYSTEM_SCALE;
1445 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DistanceBetweenAPs );
1446 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1449 if ( lp->CreateIBSS && ( lp->Channel == 0 )) {
1450 DBG_TRACE( DbgInfo, "Create IBSS" );
1453 lp->ltvRecord.len = 2;
1454 lp->ltvRecord.typ = CFG_CNF_OWN_CHANNEL;
1455 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->Channel );
1456 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1458 /* Microwave Robustness */
1459 lp->ltvRecord.len = 2;
1460 lp->ltvRecord.typ = CFG_CNF_MICRO_WAVE;
1461 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MicrowaveRobustness );
1462 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1464 /* Load Balancing */
1465 lp->ltvRecord.len = 2;
1466 lp->ltvRecord.typ = CFG_CNF_LOAD_BALANCING;
1467 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->loadBalancing );
1468 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1470 /* Medium Distribution */
1471 lp->ltvRecord.len = 2;
1472 lp->ltvRecord.typ = CFG_CNF_MEDIUM_DISTRIBUTION;
1473 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->mediumDistribution );
1474 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1478 /* Tx Power Level (for supported cards) */
1479 lp->ltvRecord.len = 2;
1480 lp->ltvRecord.typ = CFG_CNF_TX_POW_LVL;
1481 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->txPowLevel );
1482 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1484 /* Short Retry Limit */
1485 /*lp->ltvRecord.len = 2;
1486 lp->ltvRecord.typ = 0xFC32;
1487 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->shortRetryLimit );
1488 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1491 /* Long Retry Limit */
1492 /*lp->ltvRecord.len = 2;
1493 lp->ltvRecord.typ = 0xFC33;
1494 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->longRetryLimit );
1495 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1498 /* Supported Rate Set Control */
1499 lp->ltvRecord.len = 3;
1500 lp->ltvRecord.typ = CFG_SUPPORTED_RATE_SET_CNTL; //0xFC88;
1501 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->srsc[0] );
1502 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->srsc[1] );
1503 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1505 /* Basic Rate Set Control */
1506 lp->ltvRecord.len = 3;
1507 lp->ltvRecord.typ = CFG_BASIC_RATE_SET_CNTL; //0xFC89;
1508 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->brsc[0] );
1509 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->brsc[1] );
1510 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1512 /* Frame Burst Limit */
1513 /* Defined, but not currently available in Firmware */
1518 /* Multicast Rate */
1519 lp->ltvRecord.len = 3;
1520 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1521 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1522 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->MulticastRate[1] );
1524 lp->ltvRecord.len = 2;
1525 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1526 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1528 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1530 /* Own Name (Station Nickname) */
1531 len = (strlen(lp->StationName) + 1) & ~0x01;
1533 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : %s\n",
1534 // lp->StationName );
1536 lp->ltvRecord.len = 2 + ( len / sizeof( hcf_16 ));
1537 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1538 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->StationName ));
1540 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->StationName, len );
1542 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : EMPTY\n" );
1544 lp->ltvRecord.len = 2;
1545 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1546 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1549 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1551 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME result : 0x%04x\n",
1554 /* The following are set in STA mode only */
1555 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1558 lp->ltvRecord.len = 2;
1559 lp->ltvRecord.typ = CFG_RTS_THRH;
1560 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1561 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1564 lp->ltvRecord.len = 2;
1565 lp->ltvRecord.typ = CFG_CNF_PORT_TYPE;
1566 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PortType );
1567 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1569 /* Tx Rate Control */
1571 lp->ltvRecord.len = 3;
1572 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1573 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1574 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1576 lp->ltvRecord.len = 2;
1577 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1578 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1581 //;?skip temporarily to see whether the RID or something else is the problem hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1583 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 2.4GHz : 0x%04x\n",
1584 lp->TxRateControl[0] );
1585 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 5.0GHz : 0x%04x\n",
1586 lp->TxRateControl[1] );
1587 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL result : 0x%04x\n",
1589 /* Power Management */
1590 lp->ltvRecord.len = 2;
1591 lp->ltvRecord.typ = CFG_CNF_PM_ENABLED;
1592 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PMEnabled );
1593 // lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0x8001 );
1594 DBG_TRACE( DbgInfo, "CFG_CNF_PM_ENABLED : 0x%04x\n", lp->PMEnabled );
1595 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1596 /* Multicast Receive */
1597 lp->ltvRecord.len = 2;
1598 lp->ltvRecord.typ = CFG_CNF_MCAST_RX;
1599 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastReceive );
1600 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1602 /* Max Sleep Duration */
1603 lp->ltvRecord.len = 2;
1604 lp->ltvRecord.typ = CFG_CNF_MAX_SLEEP_DURATION;
1605 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MaxSleepDuration );
1606 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1609 lp->ltvRecord.len = 2;
1610 lp->ltvRecord.typ = CFG_CREATE_IBSS;
1611 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->CreateIBSS );
1612 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1615 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1616 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1617 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1618 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : %s\n",
1619 // lp->NetworkName );
1621 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1622 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1623 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1625 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1627 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : ANY\n" );
1629 lp->ltvRecord.len = 2;
1630 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1631 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1634 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1636 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID result : 0x%04x\n",
1638 /* Own ATIM window */
1639 lp->ltvRecord.len = 2;
1640 lp->ltvRecord.typ = CFG_CNF_OWN_ATIM_WINDOW;
1641 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->atimWindow );
1642 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1645 /* Holdover Duration */
1646 lp->ltvRecord.len = 2;
1647 lp->ltvRecord.typ = CFG_CNF_HOLDOVER_DURATION;
1648 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->holdoverDuration );
1649 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1651 /* Promiscuous Mode */
1652 lp->ltvRecord.len = 2;
1653 lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
1654 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->promiscuousMode );
1655 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1657 /* Authentication */
1658 lp->ltvRecord.len = 2;
1659 lp->ltvRecord.typ = CFG_CNF_AUTHENTICATION;
1660 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->authentication );
1661 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1663 /* Connection Control */
1664 lp->ltvRecord.len = 2;
1665 lp->ltvRecord.typ = CFG_CNF_CONNECTION_CNTL;
1666 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->connectionControl );
1667 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1671 /* Probe data rate */
1672 /*lp->ltvRecord.len = 3;
1673 lp->ltvRecord.typ = CFG_PROBE_DATA_RATE;
1674 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->probeDataRates[0] );
1675 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->probeDataRates[1] );
1676 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1678 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 2.4GHz : 0x%04x\n",
1679 lp->probeDataRates[0] );
1680 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 5.0GHz : 0x%04x\n",
1681 lp->probeDataRates[1] );
1682 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE result : 0x%04x\n",
1686 /* The following are set in AP mode only */
1687 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
1688 //;?should we restore this to allow smaller memory footprint
1691 lp->ltvRecord.len = 2;
1692 lp->ltvRecord.typ = CFG_CNF_OWN_DTIM_PERIOD;
1693 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DTIMPeriod );
1694 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1696 /* Multicast PM Buffering */
1697 lp->ltvRecord.len = 2;
1698 lp->ltvRecord.typ = CFG_CNF_MCAST_PM_BUF;
1699 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->multicastPMBuffering );
1700 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1702 /* Reject ANY - Closed System */
1703 lp->ltvRecord.len = 2;
1704 lp->ltvRecord.typ = CFG_CNF_REJECT_ANY;
1705 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RejectAny );
1707 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1709 /* Exclude Unencrypted */
1710 lp->ltvRecord.len = 2;
1711 lp->ltvRecord.typ = CFG_CNF_EXCL_UNENCRYPTED;
1712 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ExcludeUnencrypted );
1714 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1716 /* IntraBSS Relay */
1717 lp->ltvRecord.len = 2;
1718 lp->ltvRecord.typ = CFG_CNF_INTRA_BSS_RELAY;
1719 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->intraBSSRelay );
1720 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1722 /* RTS Threshold 0 */
1723 lp->ltvRecord.len = 2;
1724 lp->ltvRecord.typ = CFG_RTS_THRH0;
1725 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1727 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1729 /* Tx Rate Control 0 */
1731 lp->ltvRecord.len = 3;
1732 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1733 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1734 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1736 lp->ltvRecord.len = 2;
1737 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1738 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1741 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1743 /* Own Beacon Interval */
1744 lp->ltvRecord.len = 2;
1745 lp->ltvRecord.typ = 0xFC31;
1746 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ownBeaconInterval );
1747 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1749 /* Co-Existence Behavior */
1750 lp->ltvRecord.len = 2;
1751 lp->ltvRecord.typ = 0xFCC7;
1752 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->coexistence );
1753 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1757 /* RTS Threshold 1 */
1758 lp->ltvRecord.len = 2;
1759 lp->ltvRecord.typ = CFG_RTS_THRH1;
1760 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].rtsThreshold );
1761 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1763 /* RTS Threshold 2 */
1764 lp->ltvRecord.len = 2;
1765 lp->ltvRecord.typ = CFG_RTS_THRH2;
1766 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].rtsThreshold );
1767 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1770 /* RTS Threshold 3 */
1771 lp->ltvRecord.len = 2;
1772 lp->ltvRecord.typ = CFG_RTS_THRH3;
1773 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].rtsThreshold );
1774 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1777 /* RTS Threshold 4 */
1778 lp->ltvRecord.len = 2;
1779 lp->ltvRecord.typ = CFG_RTS_THRH4;
1780 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].rtsThreshold );
1781 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1784 /* RTS Threshold 5 */
1785 lp->ltvRecord.len = 2;
1786 lp->ltvRecord.typ = CFG_RTS_THRH5;
1787 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].rtsThreshold );
1788 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1790 /* RTS Threshold 6 */
1791 lp->ltvRecord.len = 2;
1792 lp->ltvRecord.typ = CFG_RTS_THRH6;
1793 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].rtsThreshold );
1794 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1796 /* TX Rate Control 1 */
1797 lp->ltvRecord.len = 2;
1798 lp->ltvRecord.typ = CFG_TX_RATE_CNTL1;
1799 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].txRateCntl );
1800 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1802 /* TX Rate Control 2 */
1803 lp->ltvRecord.len = 2;
1804 lp->ltvRecord.typ = CFG_TX_RATE_CNTL2;
1805 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].txRateCntl );
1806 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1808 /* TX Rate Control 3 */
1809 lp->ltvRecord.len = 2;
1810 lp->ltvRecord.typ = CFG_TX_RATE_CNTL3;
1811 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].txRateCntl );
1812 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1814 /* TX Rate Control 4 */
1815 lp->ltvRecord.len = 2;
1816 lp->ltvRecord.typ = CFG_TX_RATE_CNTL4;
1817 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].txRateCntl );
1818 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1820 /* TX Rate Control 5 */
1821 lp->ltvRecord.len = 2;
1822 lp->ltvRecord.typ = CFG_TX_RATE_CNTL5;
1823 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].txRateCntl );
1824 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1826 /* TX Rate Control 6 */
1827 lp->ltvRecord.len = 2;
1828 lp->ltvRecord.typ = CFG_TX_RATE_CNTL6;
1829 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].txRateCntl );
1830 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1834 /* WDS addresses. It's okay to blindly send these parameters, because
1835 the port needs to be enabled, before anything is done with it. */
1838 lp->ltvRecord.len = 4;
1839 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR1;
1841 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[0].wdsAddress, ETH_ALEN );
1842 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1845 lp->ltvRecord.len = 4;
1846 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR2;
1848 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[1].wdsAddress, ETH_ALEN );
1849 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1852 lp->ltvRecord.len = 4;
1853 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR3;
1855 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[2].wdsAddress, ETH_ALEN );
1856 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1859 lp->ltvRecord.len = 4;
1860 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR4;
1862 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[3].wdsAddress, ETH_ALEN );
1863 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1866 lp->ltvRecord.len = 4;
1867 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR5;
1869 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[4].wdsAddress, ETH_ALEN );
1870 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1873 lp->ltvRecord.len = 4;
1874 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR6;
1876 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[5].wdsAddress, ETH_ALEN );
1877 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1878 #endif /* USE_WDS */
1879 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1882 /* Own MAC Address */
1884 DBG_TRACE(DbgInfo, "MAC Address : %pM\n",
1888 if ( WVLAN_VALID_MAC_ADDRESS( lp->MACAddress )) {
1889 /* Make the MAC address valid by:
1890 Clearing the multicast bit
1891 Setting the local MAC address bit
1893 //lp->MACAddress[0] &= ~0x03; //;?why is this commented out already in 720
1894 //lp->MACAddress[0] |= 0x02;
1896 lp->ltvRecord.len = 1 + ( ETH_ALEN / sizeof( hcf_16 ));
1897 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1898 //DBG_TRACE( DbgInfo, "CFG_NIC_MAC_ADDR\n" );
1899 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1901 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_MAC_ADDR\n" );
1902 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1904 /* MAC address is byte aligned, no endian conversion needed */
1905 memcpy( &( lp->ltvRecord.u.u8[0] ), lp->MACAddress, ETH_ALEN );
1906 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1907 //DBG_TRACE( DbgInfo, "CFG_XXX_MAC_ADDR result : 0x%04x\n",
1910 /* Update the MAC address in the netdevice struct */
1911 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN ); //;?what is the purpose of this seemingly complex logic
1914 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1915 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1916 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1917 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : %s\n",
1918 // lp->NetworkName );
1919 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1920 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1921 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1923 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1925 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : ANY\n" );
1926 lp->ltvRecord.len = 2;
1927 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1928 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1931 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1933 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID result : 0x%04x\n",
1935 /* enable/disable encryption */
1936 lp->ltvRecord.len = 2;
1937 lp->ltvRecord.typ = CFG_CNF_ENCRYPTION;
1938 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->EnableEncryption );
1939 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1941 /* Set the Authentication Key Management Suite */
1942 lp->ltvRecord.len = 2;
1943 lp->ltvRecord.typ = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
1944 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->AuthKeyMgmtSuite );
1945 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1947 /* If WEP (or no) keys are being used, write (or clear) them */
1948 if (lp->wext_enc != IW_ENCODE_ALG_TKIP)
1949 wl_set_wep_keys(lp);
1952 /* countryInfo, ltvCountryInfo, CFG_CNF_COUNTRY_INFO */
1956 /*============================================================================*/
1959 /*******************************************************************************
1961 *******************************************************************************
1965 * Load the kernel module.
1974 * an errno value otherwise
1976 ******************************************************************************/
1977 static int __init wl_module_init( void )
1980 /*------------------------------------------------------------------------*/
1984 /* Convert "standard" PCMCIA parameter pc_debug to a reasonable DebugFlag value.
1985 * NOTE: The values all fall through to the lower values. */
1986 DbgInfo->DebugFlag = 0;
1987 DbgInfo->DebugFlag = DBG_TRACE_ON; //;?get this mess resolved one day
1988 if ( pc_debug ) switch( pc_debug ) {
1990 DbgInfo->DebugFlag |= DBG_DS_ON;
1992 DbgInfo->DebugFlag |= DBG_RX_ON | DBG_TX_ON;
1994 DbgInfo->DebugFlag |= DBG_PARAM_ON;
1996 DbgInfo->DebugFlag |= DBG_TRACE_ON;
1998 DbgInfo->DebugFlag |= DBG_VERBOSE_ON;
2000 DbgInfo->DebugFlag |= DBG_DEFAULTS;
2006 printk(KERN_INFO "%s\n", VERSION_INFO);
2007 printk(KERN_INFO "*** Modified for kernel 2.6 by Henk de Groot <pe1dnn@amsat.org>\n");
2008 printk(KERN_INFO "*** Based on 7.18 version by Andrey Borzenkov <arvidjaar@mail.ru> $Revision: 39 $\n");
2011 // ;?#if (HCF_TYPE) & HCF_TYPE_AP
2012 // DBG_PRINT( "Access Point Mode (AP) Support: YES\n" );
2014 // DBG_PRINT( "Access Point Mode (AP) Support: NO\n" );
2015 // #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2017 result = wl_adapter_init_module( );
2020 /*============================================================================*/
2023 /*******************************************************************************
2025 *******************************************************************************
2029 * Unload the kernel module.
2039 ******************************************************************************/
2040 static void __exit wl_module_exit( void )
2042 wl_adapter_cleanup_module( );
2043 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
2044 remove_proc_entry( "wlags", NULL ); //;?why so a-symmetric compared to location of proc_create_data
2047 /*============================================================================*/
2049 module_init(wl_module_init);
2050 module_exit(wl_module_exit);
2052 /*******************************************************************************
2054 *******************************************************************************
2058 * The Interrupt Service Routine for the driver.
2062 * irq - the irq the interrupt came in on
2063 * dev_id - a buffer containing information about the request
2070 ******************************************************************************/
2071 irqreturn_t wl_isr( int irq, void *dev_id, struct pt_regs *regs )
2074 struct net_device *dev = (struct net_device *) dev_id;
2075 struct wl_private *lp = NULL;
2076 /*------------------------------------------------------------------------*/
2077 if (( dev == NULL ) || ( !netif_device_present( dev ))) {
2081 /* Set the wl_private pointer (lp), now that we know that dev is non-null */
2085 if ( lp->useRTS == 1 ) {
2086 DBG_PRINT( "EXITING ISR, IN RTS MODE...\n" );
2089 #endif /* USE_RTS */
2091 /* If we have interrupts pending, then put them on a system task
2092 queue. Otherwise turn interrupts back on */
2093 events = hcf_action( &lp->hcfCtx, HCF_ACT_INT_OFF );
2095 if ( events == HCF_INT_PENDING ) {
2096 /* Schedule the ISR handler as a bottom-half task in the
2097 tq_immediate queue */
2098 tasklet_schedule(&lp->task);
2100 //DBG_PRINT( "NOT OUR INTERRUPT\n" );
2101 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2104 return IRQ_RETVAL(events == HCF_INT_PENDING);
2106 /*============================================================================*/
2109 /*******************************************************************************
2111 *******************************************************************************
2115 * The ISR handler, scheduled to run in a deferred context by the ISR. This
2116 * is where the ISR's work actually gets done.
2120 * lp - a pointer to the device's private adapter structure
2126 ******************************************************************************/
2127 #define WVLAN_MAX_INT_SERVICES 50
2129 void wl_isr_handler( unsigned long p )
2131 struct net_device *dev;
2132 unsigned long flags;
2136 struct wl_private *lp = (struct wl_private *)p;
2137 /*------------------------------------------------------------------------*/
2140 DBG_PRINT( "wl_isr_handler lp adapter pointer is NULL!!!\n" );
2142 wl_lock( lp, &flags );
2144 dev = (struct net_device *)lp->dev;
2145 if ( dev != NULL && netif_device_present( dev ) ) stop = FALSE;
2146 for( count = 0; stop == FALSE && count < WVLAN_MAX_INT_SERVICES; count++ ) {
2148 result = hcf_service_nic( &lp->hcfCtx,
2149 (wci_bufp)lp->lookAheadBuf,
2150 sizeof( lp->lookAheadBuf ));
2151 if ( result == HCF_ERR_MIC ) {
2152 wl_wext_event_mic_failed( dev ); /* Send an event that MIC failed */
2153 //;?this seems wrong if HCF_ERR_MIC coincides with another event, stop gets FALSE
2154 //so why not do it always ;?
2157 #ifndef USE_MBOX_SYNC
2158 if ( lp->hcfCtx.IFB_MBInfoLen != 0 ) { /* anything in the mailbox */
2163 /* Check for a Link status event */
2164 if ( ( lp->hcfCtx.IFB_LinkStat & CFG_LINK_STAT_FW ) != 0 ) {
2165 wl_process_link_status( lp );
2168 /* Check for probe response events */
2169 if ( lp->ProbeResp.infoType != 0 &&
2170 lp->ProbeResp.infoType != 0xFFFF ) {
2171 wl_process_probe_response( lp );
2172 memset( &lp->ProbeResp, 0, sizeof( lp->ProbeResp ));
2173 lp->ProbeResp.infoType = 0xFFFF;
2176 /* Check for updated record events */
2177 if ( lp->updatedRecord.len != 0xFFFF ) {
2178 wl_process_updated_record( lp );
2179 lp->updatedRecord.len = 0xFFFF;
2182 /* Check for association status events */
2183 if ( lp->assoc_stat.len != 0xFFFF ) {
2184 wl_process_assoc_status( lp );
2185 lp->assoc_stat.len = 0xFFFF;
2188 /* Check for security status events */
2189 if ( lp->sec_stat.len != 0xFFFF ) {
2190 wl_process_security_status( lp );
2191 lp->sec_stat.len = 0xFFFF;
2196 if ( lp->use_dma ) {
2197 /* Check for DMA Rx packets */
2198 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_RDMAD ) {
2202 /* Return Tx DMA descriptors to host */
2203 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_TDMAD ) {
2204 wl_pci_dma_hcf_reclaim_tx( lp );
2209 #endif // ENABLE_DMA
2211 /* Check for Rx packets */
2212 if ( lp->hcfCtx.IFB_RxLen != 0 ) {
2216 /* Make sure that queued frames get sent */
2217 if ( wl_send( lp )) {
2222 /* We're done, so turn interrupts which were turned off in wl_isr, back on */
2223 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2224 wl_unlock( lp, &flags );
2228 /*============================================================================*/
2231 /*******************************************************************************
2233 *******************************************************************************
2237 * Notify the adapter that it has been removed. Since the adapter is gone,
2238 * we should no longer try to talk to it.
2242 * dev - a pointer to the device's net_device structure
2248 ******************************************************************************/
2249 void wl_remove( struct net_device *dev )
2251 struct wl_private *lp = wl_priv(dev);
2252 unsigned long flags;
2254 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2256 wl_lock( lp, &flags );
2258 /* stop handling interrupts */
2259 wl_act_int_off( lp );
2260 lp->is_handling_int = WL_NOT_HANDLING_INT;
2263 * Disable the ports: just change state: since the
2264 * card is gone it is useless to talk to it and at
2265 * disconnect all state information is lost anyway.
2267 /* Reset portState */
2268 lp->portState = WVLAN_PORT_STATE_DISABLED;
2270 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
2272 //wl_disable_wds_ports( lp );
2274 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2276 /* Mark the device as unregistered */
2277 lp->is_registered = FALSE;
2279 /* Deregister the WDS ports as well */
2280 WL_WDS_NETDEV_DEREGISTER( lp );
2282 if ( lp->useRTS == 1 ) {
2283 wl_unlock( lp, &flags );
2286 #endif /* USE_RTS */
2288 /* Inform the HCF that the card has been removed */
2289 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2291 wl_unlock( lp, &flags );
2293 /*============================================================================*/
2296 /*******************************************************************************
2298 *******************************************************************************
2302 * Power-down and halt the adapter.
2306 * dev - a pointer to the device's net_device structure
2312 ******************************************************************************/
2313 void wl_suspend( struct net_device *dev )
2315 struct wl_private *lp = wl_priv(dev);
2316 unsigned long flags;
2318 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2320 /* The adapter is suspended:
2324 wl_lock( lp, &flags );
2326 /* Disable interrupt handling */
2327 wl_act_int_off( lp );
2330 wl_disconnect( lp );
2335 /* Disconnect from the adapter */
2336 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2338 /* Reset portState to be sure (should have been done by wl_disable */
2339 lp->portState = WVLAN_PORT_STATE_DISABLED;
2341 wl_unlock( lp, &flags );
2343 /*============================================================================*/
2346 /*******************************************************************************
2348 *******************************************************************************
2352 * Resume a previously suspended adapter.
2356 * dev - a pointer to the device's net_device structure
2362 ******************************************************************************/
2363 void wl_resume(struct net_device *dev)
2365 struct wl_private *lp = wl_priv(dev);
2366 unsigned long flags;
2368 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2370 wl_lock( lp, &flags );
2372 /* Connect to the adapter */
2373 hcf_connect( &lp->hcfCtx, dev->base_addr );
2375 /* Reset portState */
2376 lp->portState = WVLAN_PORT_STATE_DISABLED;
2378 /* Power might have been off, assume the card lost the firmware*/
2379 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
2381 /* Reload the firmware and restart */
2384 /* Resume interrupt handling */
2385 wl_act_int_on( lp );
2387 wl_unlock( lp, &flags );
2389 /*============================================================================*/
2392 /*******************************************************************************
2394 *******************************************************************************
2398 * This function performs a check on the device and calls wl_remove() if
2399 * necessary. This function can be used for all bus types, but exists mostly
2400 * for the benefit of the Card Services driver, as there are times when
2401 * wl_remove() does not get called.
2405 * dev - a pointer to the device's net_device structure
2411 ******************************************************************************/
2412 void wl_release( struct net_device *dev )
2414 struct wl_private *lp = wl_priv(dev);
2416 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2417 /* If wl_remove() hasn't been called (i.e. when Card Services is shut
2418 down with the card in the slot), then call it */
2419 if ( lp->is_registered == TRUE ) {
2420 DBG_TRACE( DbgInfo, "Calling unregister_netdev(), as it wasn't called yet\n" );
2423 lp->is_registered = FALSE;
2426 /*============================================================================*/
2429 /*******************************************************************************
2431 *******************************************************************************
2435 * Accessor function to retrieve the irq_mask module parameter
2443 * The irq_mask module parameter
2445 ******************************************************************************/
2446 p_u16 wl_get_irq_mask( void )
2449 } // wl_get_irq_mask
2450 /*============================================================================*/
2453 /*******************************************************************************
2455 *******************************************************************************
2459 * Accessor function to retrieve the irq_list module parameter
2467 * The irq_list module parameter
2469 ******************************************************************************/
2470 p_s8 * wl_get_irq_list( void )
2473 } // wl_get_irq_list
2474 /*============================================================================*/
2478 /*******************************************************************************
2480 *******************************************************************************
2484 * Used to enable MAC ports
2488 * lp - pointer to the device's private adapter structure
2494 ******************************************************************************/
2495 int wl_enable( struct wl_private *lp )
2497 int hcf_status = HCF_SUCCESS;
2499 if ( lp->portState == WVLAN_PORT_STATE_ENABLED ) {
2500 DBG_TRACE( DbgInfo, "No action: Card already enabled\n" );
2501 } else if ( lp->portState == WVLAN_PORT_STATE_CONNECTED ) {
2502 //;?suspicuous logic, how can you be connected without being enabled so this is probably dead code
2503 DBG_TRACE( DbgInfo, "No action: Card already connected\n" );
2505 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_ENABLE );
2506 if ( hcf_status == HCF_SUCCESS ) {
2507 /* Set the status of the NIC to enabled */
2508 lp->portState = WVLAN_PORT_STATE_ENABLED; //;?bad mnemonic, NIC iso PORT
2510 if ( lp->use_dma ) {
2511 wl_pci_dma_hcf_supply( lp ); //;?always successful?
2516 if ( hcf_status != HCF_SUCCESS ) { //;?make this an assert
2517 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2521 /*============================================================================*/
2525 /*******************************************************************************
2526 * wl_enable_wds_ports()
2527 *******************************************************************************
2531 * Used to enable the WDS MAC ports 1-6
2535 * lp - pointer to the device's private adapter structure
2541 ******************************************************************************/
2542 void wl_enable_wds_ports( struct wl_private * lp )
2544 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2545 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2547 } // wl_enable_wds_ports
2548 #endif /* USE_WDS */
2549 /*============================================================================*/
2552 /*******************************************************************************
2554 *******************************************************************************
2558 * Used to connect a MAC port
2562 * lp - pointer to the device's private adapter structure
2568 ******************************************************************************/
2569 int wl_connect( struct wl_private *lp )
2573 if ( lp->portState != WVLAN_PORT_STATE_ENABLED ) {
2574 DBG_TRACE( DbgInfo, "No action: Not in enabled state\n" );
2577 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_CONNECT );
2578 if ( hcf_status == HCF_SUCCESS ) {
2579 lp->portState = WVLAN_PORT_STATE_CONNECTED;
2583 /*============================================================================*/
2586 /*******************************************************************************
2588 *******************************************************************************
2592 * Used to disconnect a MAC port
2596 * lp - pointer to the device's private adapter structure
2602 ******************************************************************************/
2603 int wl_disconnect( struct wl_private *lp )
2607 if ( lp->portState != WVLAN_PORT_STATE_CONNECTED ) {
2608 DBG_TRACE( DbgInfo, "No action: Not in connected state\n" );
2611 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISCONNECT );
2612 if ( hcf_status == HCF_SUCCESS ) {
2613 lp->portState = WVLAN_PORT_STATE_ENABLED;
2617 /*============================================================================*/
2620 /*******************************************************************************
2622 *******************************************************************************
2626 * Used to disable MAC ports
2630 * lp - pointer to the device's private adapter structure
2631 * port - the MAC port to disable
2637 ******************************************************************************/
2638 int wl_disable( struct wl_private *lp )
2640 int hcf_status = HCF_SUCCESS;
2642 if ( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
2643 DBG_TRACE( DbgInfo, "No action: Port state is disabled\n" );
2645 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISABLE );
2646 if ( hcf_status == HCF_SUCCESS ) {
2647 /* Set the status of the port to disabled */ //;?bad mnemonic use NIC iso PORT
2648 lp->portState = WVLAN_PORT_STATE_DISABLED;
2651 if ( lp->use_dma ) {
2652 wl_pci_dma_hcf_reclaim( lp );
2657 if ( hcf_status != HCF_SUCCESS ) {
2658 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2662 /*============================================================================*/
2666 /*******************************************************************************
2667 * wl_disable_wds_ports()
2668 *******************************************************************************
2672 * Used to disable the WDS MAC ports 1-6
2676 * lp - pointer to the device's private adapter structure
2682 ******************************************************************************/
2683 void wl_disable_wds_ports( struct wl_private * lp )
2685 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2686 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2688 // if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
2689 // wl_disable( lp, HCF_PORT_1 );
2690 // wl_disable( lp, HCF_PORT_2 );
2691 // wl_disable( lp, HCF_PORT_3 );
2692 // wl_disable( lp, HCF_PORT_4 );
2693 // wl_disable( lp, HCF_PORT_5 );
2694 // wl_disable( lp, HCF_PORT_6 );
2697 } // wl_disable_wds_ports
2699 /*============================================================================*/
2702 #ifndef USE_MBOX_SYNC
2703 /*******************************************************************************
2705 *******************************************************************************
2708 * This function is used to read and process a mailbox message.
2713 * lp - pointer to the device's private adapter structure
2717 * an HCF status code
2719 ******************************************************************************/
2720 int wl_mbx( struct wl_private *lp )
2722 int hcf_status = HCF_SUCCESS;
2724 DBG_TRACE( DbgInfo, "Mailbox Info: IFB_MBInfoLen: %d\n",
2725 lp->hcfCtx.IFB_MBInfoLen );
2727 memset( &( lp->ltvRecord ), 0, sizeof( ltv_t ));
2729 lp->ltvRecord.len = MB_SIZE;
2730 lp->ltvRecord.typ = CFG_MB_INFO;
2731 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2733 if ( hcf_status != HCF_SUCCESS ) {
2734 DBG_ERROR( DbgInfo, "hcf_get_info returned 0x%x\n", hcf_status );
2738 if ( lp->ltvRecord.typ == CFG_MB_INFO )
2741 /* Endian translate the mailbox data, then process the message */
2742 wl_endian_translate_mailbox( &( lp->ltvRecord ));
2743 wl_process_mailbox( lp );
2746 /*============================================================================*/
2749 /*******************************************************************************
2750 * wl_endian_translate_mailbox()
2751 *******************************************************************************
2755 * This function will perform the tedious task of endian translating all
2756 * fields within a mailbox message which need translating.
2760 * ltv - pointer to the LTV to endian translate
2766 ******************************************************************************/
2767 void wl_endian_translate_mailbox( ltv_t *ltv )
2769 switch( ltv->typ ) {
2776 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
2778 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2779 ( sizeof( SCAN_RS_STRCT )));
2781 while( num_aps >= 1 ) {
2784 aps[num_aps].channel_id =
2785 CNV_LITTLE_TO_INT( aps[num_aps].channel_id );
2787 aps[num_aps].noise_level =
2788 CNV_LITTLE_TO_INT( aps[num_aps].noise_level );
2790 aps[num_aps].signal_level =
2791 CNV_LITTLE_TO_INT( aps[num_aps].signal_level );
2793 aps[num_aps].beacon_interval_time =
2794 CNV_LITTLE_TO_INT( aps[num_aps].beacon_interval_time );
2796 aps[num_aps].capability =
2797 CNV_LITTLE_TO_INT( aps[num_aps].capability );
2799 aps[num_aps].ssid_len =
2800 CNV_LITTLE_TO_INT( aps[num_aps].ssid_len );
2802 aps[num_aps].ssid_val[aps[num_aps].ssid_len] = 0;
2809 PROBE_RESP *probe_resp = (PROBE_RESP *)ltv;
2811 probe_resp->frameControl = CNV_LITTLE_TO_INT( probe_resp->frameControl );
2812 probe_resp->durID = CNV_LITTLE_TO_INT( probe_resp->durID );
2813 probe_resp->sequence = CNV_LITTLE_TO_INT( probe_resp->sequence );
2814 probe_resp->dataLength = CNV_LITTLE_TO_INT( probe_resp->dataLength );
2816 probe_resp->lenType = CNV_LITTLE_TO_INT( probe_resp->lenType );
2818 probe_resp->beaconInterval = CNV_LITTLE_TO_INT( probe_resp->beaconInterval );
2819 probe_resp->capability = CNV_LITTLE_TO_INT( probe_resp->capability );
2820 probe_resp->flags = CNV_LITTLE_TO_INT( probe_resp->flags );
2825 #define ls ((LINK_STATUS_STRCT *)ltv)
2826 ls->linkStatus = CNV_LITTLE_TO_INT( ls->linkStatus );
2830 case CFG_ASSOC_STAT:
2832 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
2834 as->assocStatus = CNV_LITTLE_TO_INT( as->assocStatus );
2838 case CFG_SECURITY_STAT:
2840 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
2842 ss->securityStatus = CNV_LITTLE_TO_INT( ss->securityStatus );
2843 ss->reason = CNV_LITTLE_TO_INT( ss->reason );
2856 } // wl_endian_translate_mailbox
2857 /*============================================================================*/
2859 /*******************************************************************************
2860 * wl_process_mailbox()
2861 *******************************************************************************
2865 * This function processes the mailbox data.
2869 * ltv - pointer to the LTV to be processed.
2875 ******************************************************************************/
2876 void wl_process_mailbox( struct wl_private *lp )
2879 hcf_16 ltv_val = 0xFFFF;
2881 ltv = &( lp->ltvRecord );
2883 switch( ltv->typ ) {
2886 DBG_TRACE( DbgInfo, "CFG_TALLIES\n" );
2889 DBG_TRACE( DbgInfo, "CFG_SCAN\n" );
2893 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)<v->u.u8[0];
2895 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2896 ( sizeof( SCAN_RS_STRCT )));
2898 lp->scan_results.num_aps = num_aps;
2900 DBG_TRACE( DbgInfo, "Number of APs: %d\n", num_aps );
2902 while( num_aps >= 1 ) {
2905 DBG_TRACE( DbgInfo, "AP : %d\n", num_aps );
2906 DBG_TRACE( DbgInfo, "=========================\n" );
2907 DBG_TRACE( DbgInfo, "Channel ID : 0x%04x\n",
2908 aps[num_aps].channel_id );
2909 DBG_TRACE( DbgInfo, "Noise Level : 0x%04x\n",
2910 aps[num_aps].noise_level );
2911 DBG_TRACE( DbgInfo, "Signal Level : 0x%04x\n",
2912 aps[num_aps].signal_level );
2913 DBG_TRACE( DbgInfo, "Beacon Interval : 0x%04x\n",
2914 aps[num_aps].beacon_interval_time );
2915 DBG_TRACE( DbgInfo, "Capability : 0x%04x\n",
2916 aps[num_aps].capability );
2917 DBG_TRACE( DbgInfo, "SSID Length : 0x%04x\n",
2918 aps[num_aps].ssid_len );
2919 DBG_TRACE(DbgInfo, "BSSID : %pM\n",
2920 aps[num_aps].bssid);
2922 if ( aps[num_aps].ssid_len != 0 ) {
2923 DBG_TRACE( DbgInfo, "SSID : %s.\n",
2924 aps[num_aps].ssid_val );
2926 DBG_TRACE( DbgInfo, "SSID : %s.\n", "ANY" );
2929 DBG_TRACE( DbgInfo, "\n" );
2931 /* Copy the info to the ScanResult structure in the private
2933 memcpy( &( lp->scan_results.APTable[num_aps]), &( aps[num_aps] ),
2934 sizeof( SCAN_RS_STRCT ));
2937 /* Set scan result to true so that any scan requests will
2939 lp->scan_results.scan_complete = TRUE;
2944 DBG_TRACE( DbgInfo, "CFG_ACS_SCAN\n" );
2947 PROBE_RESP *probe_rsp = (PROBE_RESP *)ltv;
2948 hcf_8 *wpa_ie = NULL;
2949 hcf_16 wpa_ie_len = 0;
2951 DBG_TRACE( DbgInfo, "(%s) =========================\n",
2954 DBG_TRACE( DbgInfo, "(%s) length : 0x%04x.\n",
2955 lp->dev->name, probe_rsp->length );
2957 if ( probe_rsp->length > 1 ) {
2958 DBG_TRACE( DbgInfo, "(%s) infoType : 0x%04x.\n",
2959 lp->dev->name, probe_rsp->infoType );
2961 DBG_TRACE( DbgInfo, "(%s) signal : 0x%02x.\n",
2962 lp->dev->name, probe_rsp->signal );
2964 DBG_TRACE( DbgInfo, "(%s) silence : 0x%02x.\n",
2965 lp->dev->name, probe_rsp->silence );
2967 DBG_TRACE( DbgInfo, "(%s) rxFlow : 0x%02x.\n",
2968 lp->dev->name, probe_rsp->rxFlow );
2970 DBG_TRACE( DbgInfo, "(%s) rate : 0x%02x.\n",
2971 lp->dev->name, probe_rsp->rate );
2973 DBG_TRACE( DbgInfo, "(%s) frame cntl : 0x%04x.\n",
2974 lp->dev->name, probe_rsp->frameControl );
2976 DBG_TRACE( DbgInfo, "(%s) durID : 0x%04x.\n",
2977 lp->dev->name, probe_rsp->durID );
2979 DBG_TRACE(DbgInfo, "(%s) address1 : %pM\n",
2980 lp->dev->name, probe_rsp->address1);
2982 DBG_TRACE(DbgInfo, "(%s) address2 : %pM\n",
2983 lp->dev->name, probe_rsp->address2);
2985 DBG_TRACE(DbgInfo, "(%s) BSSID : %pM\n",
2986 lp->dev->name, probe_rsp->BSSID);
2988 DBG_TRACE( DbgInfo, "(%s) sequence : 0x%04x.\n",
2989 lp->dev->name, probe_rsp->sequence );
2991 DBG_TRACE(DbgInfo, "(%s) address4 : %pM\n",
2992 lp->dev->name, probe_rsp->address4);
2994 DBG_TRACE( DbgInfo, "(%s) datalength : 0x%04x.\n",
2995 lp->dev->name, probe_rsp->dataLength );
2997 DBG_TRACE(DbgInfo, "(%s) DA : %pM\n",
2998 lp->dev->name, probe_rsp->DA);
3000 DBG_TRACE(DbgInfo, "(%s) SA : %pM\n",
3001 lp->dev->name, probe_rsp->SA);
3003 //DBG_TRACE( DbgInfo, "(%s) lenType : 0x%04x.\n",
3004 // lp->dev->name, probe_rsp->lenType );
3006 DBG_TRACE(DbgInfo, "(%s) timeStamp : "
3007 "%d.%d.%d.%d.%d.%d.%d.%d\n",
3009 probe_rsp->timeStamp[0],
3010 probe_rsp->timeStamp[1],
3011 probe_rsp->timeStamp[2],
3012 probe_rsp->timeStamp[3],
3013 probe_rsp->timeStamp[4],
3014 probe_rsp->timeStamp[5],
3015 probe_rsp->timeStamp[6],
3016 probe_rsp->timeStamp[7]);
3018 DBG_TRACE( DbgInfo, "(%s) beaconInt : 0x%04x.\n",
3019 lp->dev->name, probe_rsp->beaconInterval );
3021 DBG_TRACE( DbgInfo, "(%s) capability : 0x%04x.\n",
3022 lp->dev->name, probe_rsp->capability );
3024 DBG_TRACE( DbgInfo, "(%s) SSID len : 0x%04x.\n",
3025 lp->dev->name, probe_rsp->rawData[1] );
3027 if ( probe_rsp->rawData[1] > 0 ) {
3028 char ssid[HCF_MAX_NAME_LEN];
3030 memset( ssid, 0, sizeof( ssid ));
3031 strncpy( ssid, &probe_rsp->rawData[2],
3033 probe_rsp->rawData[1],
3034 HCF_MAX_NAME_LEN - 1));
3036 DBG_TRACE( DbgInfo, "(%s) SSID : %s\n",
3037 lp->dev->name, ssid );
3040 /* Parse out the WPA-IE, if one exists */
3041 wpa_ie = wl_parse_wpa_ie( probe_rsp, &wpa_ie_len );
3042 if ( wpa_ie != NULL ) {
3043 DBG_TRACE( DbgInfo, "(%s) WPA-IE : %s\n",
3044 lp->dev->name, wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
3047 DBG_TRACE( DbgInfo, "(%s) flags : 0x%04x.\n",
3048 lp->dev->name, probe_rsp->flags );
3051 DBG_TRACE( DbgInfo, "\n\n" );
3052 /* If probe response length is 1, then the scan is complete */
3053 if ( probe_rsp->length == 1 ) {
3054 DBG_TRACE( DbgInfo, "SCAN COMPLETE\n" );
3055 lp->probe_results.num_aps = lp->probe_num_aps;
3056 lp->probe_results.scan_complete = TRUE;
3058 /* Reset the counter for the next scan request */
3059 lp->probe_num_aps = 0;
3061 /* Send a wireless extensions event that the scan completed */
3062 wl_wext_event_scan_complete( lp->dev );
3064 /* Only copy to the table if the entry is unique; APs sometimes
3065 respond more than once to a probe */
3066 if ( lp->probe_num_aps == 0 ) {
3067 /* Copy the info to the ScanResult structure in the private
3069 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3070 probe_rsp, sizeof( PROBE_RESP ));
3072 /* Increment the number of APs detected */
3073 lp->probe_num_aps++;
3078 for( count = 0; count < lp->probe_num_aps; count++ ) {
3079 if ( memcmp( &( probe_rsp->BSSID ),
3080 lp->probe_results.ProbeTable[count].BSSID,
3087 /* Copy the info to the ScanResult structure in the
3088 private adapter struct. Only copy if there's room in the
3090 if ( lp->probe_num_aps < MAX_NAPS )
3092 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3093 probe_rsp, sizeof( PROBE_RESP ));
3097 DBG_WARNING( DbgInfo, "Num of scan results exceeds storage, truncating\n" );
3100 /* Increment the number of APs detected. Note I do this
3101 here even when I don't copy the probe response to the
3102 buffer in order to detect the overflow condition */
3103 lp->probe_num_aps++;
3112 #define ls ((LINK_STATUS_STRCT *)ltv)
3113 DBG_TRACE( DbgInfo, "CFG_LINK_STAT\n" );
3115 switch( ls->linkStatus ) {
3117 DBG_TRACE( DbgInfo, "Link Status : Connected\n" );
3118 wl_wext_event_ap( lp->dev );
3122 DBG_TRACE( DbgInfo, "Link Status : Disconnected\n" );
3126 DBG_TRACE( DbgInfo, "Link Status : Access Point Change\n" );
3130 DBG_TRACE( DbgInfo, "Link Status : Access Point Out of Range\n" );
3134 DBG_TRACE( DbgInfo, "Link Status : Access Point In Range\n" );
3138 DBG_TRACE( DbgInfo, "Link Status : UNKNOWN (0x%04x)\n",
3146 case CFG_ASSOC_STAT:
3147 DBG_TRACE( DbgInfo, "CFG_ASSOC_STAT\n" );
3150 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
3152 switch( as->assocStatus ) {
3154 DBG_TRACE( DbgInfo, "Association Status : STA Associated\n" );
3158 DBG_TRACE( DbgInfo, "Association Status : STA Reassociated\n" );
3162 DBG_TRACE( DbgInfo, "Association Status : STA Disassociated\n" );
3166 DBG_TRACE( DbgInfo, "Association Status : UNKNOWN (0x%04x)\n",
3171 DBG_TRACE(DbgInfo, "STA Address : %pM\n",
3174 if (( as->assocStatus == 2 ) && ( as->len == 8 )) {
3175 DBG_TRACE(DbgInfo, "Old AP Address : %pM\n",
3182 case CFG_SECURITY_STAT:
3183 DBG_TRACE( DbgInfo, "CFG_SECURITY_STAT\n" );
3186 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
3188 switch( ss->securityStatus ) {
3190 DBG_TRACE( DbgInfo, "Security Status : Dissassociate [AP]\n" );
3194 DBG_TRACE( DbgInfo, "Security Status : Deauthenticate [AP]\n" );
3198 DBG_TRACE( DbgInfo, "Security Status : Authenticate Fail [STA] or [AP]\n" );
3202 DBG_TRACE( DbgInfo, "Security Status : MIC Fail\n" );
3206 DBG_TRACE( DbgInfo, "Security Status : Associate Fail\n" );
3210 DBG_TRACE( DbgInfo, "Security Status : UNKNOWN %d\n",
3211 ss->securityStatus );
3215 DBG_TRACE(DbgInfo, "STA Address : %pM\n",
3218 DBG_TRACE(DbgInfo, "Reason : 0x%04x\n",
3225 DBG_TRACE( DbgInfo, "CFG_WMP, size is %d bytes\n", ltv->len );
3227 WMP_RSP_STRCT *wmp_rsp = (WMP_RSP_STRCT *)ltv;
3229 DBG_TRACE( DbgInfo, "CFG_WMP, pdu type is 0x%x\n",
3230 wmp_rsp->wmpRsp.wmpHdr.type );
3232 switch( wmp_rsp->wmpRsp.wmpHdr.type ) {
3233 case WVLAN_WMP_PDU_TYPE_LT_RSP:
3236 LINKTEST_RSP_STRCT *lt_rsp = (LINKTEST_RSP_STRCT *)ltv;
3238 DBG_TRACE( DbgInfo, "LINK TEST RESULT\n" );
3239 DBG_TRACE( DbgInfo, "================\n" );
3240 DBG_TRACE( DbgInfo, "Length : %d.\n", lt_rsp->len );
3242 DBG_TRACE( DbgInfo, "Name : %s.\n", lt_rsp->ltRsp.ltRsp.name );
3243 DBG_TRACE( DbgInfo, "Signal Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.signal );
3244 DBG_TRACE( DbgInfo, "Noise Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.noise );
3245 DBG_TRACE( DbgInfo, "Receive Flow : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.rxFlow );
3246 DBG_TRACE( DbgInfo, "Data Rate : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRate );
3247 DBG_TRACE( DbgInfo, "Protocol : 0x%04x.\n", lt_rsp->ltRsp.ltRsp.protocol );
3248 DBG_TRACE( DbgInfo, "Station : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.station );
3249 DBG_TRACE( DbgInfo, "Data Rate Cap : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRateCap );
3251 DBG_TRACE( DbgInfo, "Power Mgmt : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3252 lt_rsp->ltRsp.ltRsp.powerMgmt[0],
3253 lt_rsp->ltRsp.ltRsp.powerMgmt[1],
3254 lt_rsp->ltRsp.ltRsp.powerMgmt[2],
3255 lt_rsp->ltRsp.ltRsp.powerMgmt[3] );
3257 DBG_TRACE( DbgInfo, "Robustness : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3258 lt_rsp->ltRsp.ltRsp.robustness[0],
3259 lt_rsp->ltRsp.ltRsp.robustness[1],
3260 lt_rsp->ltRsp.ltRsp.robustness[2],
3261 lt_rsp->ltRsp.ltRsp.robustness[3] );
3263 DBG_TRACE( DbgInfo, "Scaling : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.scaling );
3276 DBG_TRACE( DbgInfo, "CFG_NULL\n" );
3279 case CFG_UPDATED_INFO_RECORD: // Updated Information Record
3280 DBG_TRACE( DbgInfo, "UPDATED INFORMATION RECORD\n" );
3282 ltv_val = CNV_INT_TO_LITTLE( ltv->u.u16[0] );
3284 /* Check and see which RID was updated */
3286 case CFG_CUR_COUNTRY_INFO: // Indicate Passive Scan Completion
3287 DBG_TRACE( DbgInfo, "Updated country info\n" );
3289 /* Do I need to hold off on updating RIDs until the process is
3294 case CFG_PORT_STAT: // Wait for Connect Event
3300 DBG_WARNING( DbgInfo, "Unknown RID: 0x%04x\n", ltv_val );
3306 DBG_TRACE( DbgInfo, "UNKNOWN MESSAGE: 0x%04x\n", ltv->typ );
3309 } // wl_process_mailbox
3310 /*============================================================================*/
3311 #endif /* ifndef USE_MBOX_SYNC */
3314 /*******************************************************************************
3315 * wl_wds_netdev_register()
3316 *******************************************************************************
3320 * This function registers net_device structures with the system's network
3321 * layer for use with the WDS ports.
3326 * lp - pointer to the device's private adapter structure
3332 ******************************************************************************/
3333 void wl_wds_netdev_register( struct wl_private *lp )
3337 //;?why is there no USE_WDS clause like in wl_enable_wds_ports
3338 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3339 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3340 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3341 if ( register_netdev( lp->wds_port[count].dev ) != 0 ) {
3342 DBG_WARNING( DbgInfo, "net device for WDS port %d could not be registered\n",
3345 lp->wds_port[count].is_registered = TRUE;
3347 /* Fill out the net_device structs with the MAC addr */
3348 memcpy( lp->wds_port[count].dev->dev_addr, lp->MACAddress, ETH_ALEN );
3349 lp->wds_port[count].dev->addr_len = ETH_ALEN;
3353 } // wl_wds_netdev_register
3354 /*============================================================================*/
3357 /*******************************************************************************
3358 * wl_wds_netdev_deregister()
3359 *******************************************************************************
3363 * This function deregisters the WDS net_device structures used by the
3364 * system's network layer.
3369 * lp - pointer to the device's private adapter structure
3375 ******************************************************************************/
3376 void wl_wds_netdev_deregister( struct wl_private *lp )
3380 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3381 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3382 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3383 unregister_netdev( lp->wds_port[count].dev );
3385 lp->wds_port[count].is_registered = FALSE;
3388 } // wl_wds_netdev_deregister
3389 /*============================================================================*/
3390 #endif /* USE_WDS */
3393 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
3395 * The proc filesystem: function to read and entry
3397 static void printf_hcf_16(struct seq_file *m, const char *s, hcf_16 *p, int n)
3401 seq_printf(m, "%-20.20s: ", s);
3404 for (i = 0; i < n; i++) {
3407 seq_printf(m, "%04X ", p[i]);
3412 static void printf_hcf_8(struct seq_file *m, const char *s, hcf_8 *p, int n)
3416 seq_printf(m, "%-20.20s: ", s);
3419 for (i = 0; i <= n; i++) {
3422 seq_printf(m, "%02X ", p[i]);
3427 static void printf_strct(struct seq_file *m, const char *s, hcf_16 *p)
3431 seq_printf(m, "%-20.20s: ", s);
3434 for ( i = 0; i <= *p; i++ ) {
3437 seq_printf(m,"%04X ", p[i]);
3442 int scull_read_procmem(struct seq_file *m, void *v)
3444 struct wl_private *lp = m->private;
3446 CFG_HERMES_TALLIES_STRCT *p;
3449 seq_puts(m, "No wl_private in scull_read_procmem\n" );
3450 } else if ( lp->wlags49_type == 0 ){
3452 seq_printf(m, "Magic: 0x%04X\n", ifbp->IFB_Magic );
3453 seq_printf(m, "IOBase: 0x%04X\n", ifbp->IFB_IOBase );
3454 seq_printf(m, "LinkStat: 0x%04X\n", ifbp->IFB_LinkStat );
3455 seq_printf(m, "DSLinkStat: 0x%04X\n", ifbp->IFB_DSLinkStat );
3456 seq_printf(m, "TickIni: 0x%08lX\n", ifbp->IFB_TickIni );
3457 seq_printf(m, "TickCnt: 0x%04X\n", ifbp->IFB_TickCnt );
3458 seq_printf(m, "IntOffCnt: 0x%04X\n", ifbp->IFB_IntOffCnt );
3459 printf_hcf_16(m, "IFB_FWIdentity",
3460 &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
3461 } else if ( lp->wlags49_type == 1 ) {
3462 seq_printf(m, "Channel: 0x%04X\n", lp->Channel );
3463 /****** seq_printf(m, "slock: %d\n", lp->slock ); */
3464 //x struct tq_struct "task: 0x%04X\n", lp->task );
3465 //x struct net_device_stats "stats: 0x%04X\n", lp->stats );
3467 //x struct iw_statistics "wstats: 0x%04X\n", lp->wstats );
3468 //x seq_printf(m, "spy_number: 0x%04X\n", lp->spy_number );
3469 //x u_char spy_address[IW_MAX_SPY][ETH_ALEN];
3470 //x struct iw_quality spy_stat[IW_MAX_SPY];
3471 #endif // WIRELESS_EXT
3472 seq_printf(m, "IFB: 0x%p\n", &lp->hcfCtx );
3473 seq_printf(m, "flags: %#.8lX\n", lp->flags ); //;?use this format from now on
3474 seq_printf(m, "DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
3476 seq_printf(m, "DebugFlag (DbgInfo): 0x%08lX\n", DbgInfo->DebugFlag );
3478 seq_printf(m, "is_registered: 0x%04X\n", lp->is_registered );
3479 //x CFG_DRV_INFO_STRCT "driverInfo: 0x%04X\n", lp->driverInfo );
3480 printf_strct( m, "driverInfo", (hcf_16*)&lp->driverInfo );
3481 //x CFG_IDENTITY_STRCT "driverIdentity: 0x%04X\n", lp->driverIdentity );
3482 printf_strct( m, "driverIdentity", (hcf_16*)&lp->driverIdentity );
3483 //x CFG_FW_IDENTITY_STRCT "StationIdentity: 0x%04X\n", lp->StationIdentity );
3484 printf_strct( m, "StationIdentity", (hcf_16*)&lp->StationIdentity );
3485 //x CFG_PRI_IDENTITY_STRCT "PrimaryIdentity: 0x%04X\n", lp->PrimaryIdentity );
3486 printf_strct( m, "PrimaryIdentity", (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
3487 printf_strct( m, "PrimarySupplier", (hcf_16*)&lp->hcfCtx.IFB_PRISup );
3488 //x CFG_PRI_IDENTITY_STRCT "NICIdentity: 0x%04X\n", lp->NICIdentity );
3489 printf_strct( m, "NICIdentity", (hcf_16*)&lp->NICIdentity );
3490 //x ltv_t "ltvRecord: 0x%04X\n", lp->ltvRecord );
3491 seq_printf(m, "txBytes: 0x%08lX\n", lp->txBytes );
3492 seq_printf(m, "maxPort: 0x%04X\n", lp->maxPort ); /* 0 for STA, 6 for AP */
3493 /* Elements used for async notification from hardware */
3494 //x RID_LOG_STRCT RidList[10];
3495 //x ltv_t "updatedRecord: 0x%04X\n", lp->updatedRecord );
3496 //x PROBE_RESP "ProbeResp: 0x%04X\n", lp->ProbeResp );
3497 //x ASSOC_STATUS_STRCT "assoc_stat: 0x%04X\n", lp->assoc_stat );
3498 //x SECURITY_STATUS_STRCT "sec_stat: 0x%04X\n", lp->sec_stat );
3499 //x u_char lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
3500 seq_printf(m, "PortType: 0x%04X\n", lp->PortType ); // 1 - 3 (1 [Normal] | 3 [AdHoc])
3501 seq_printf(m, "Channel: 0x%04X\n", lp->Channel ); // 0 - 14 (0)
3502 //x hcf_16 TxRateControl[2];
3503 seq_printf(m, "TxRateControl[2]: 0x%04X 0x%04X\n",
3504 lp->TxRateControl[0], lp->TxRateControl[1] );
3505 seq_printf(m, "DistanceBetweenAPs: 0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
3506 seq_printf(m, "RTSThreshold: 0x%04X\n", lp->RTSThreshold ); // 0 - 2347 (2347)
3507 seq_printf(m, "PMEnabled: 0x%04X\n", lp->PMEnabled ); // 0 - 2, 8001 - 8002 (0)
3508 seq_printf(m, "MicrowaveRobustness: 0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
3509 seq_printf(m, "CreateIBSS: 0x%04X\n", lp->CreateIBSS ); // 0 - 1 (0)
3510 seq_printf(m, "MulticastReceive: 0x%04X\n", lp->MulticastReceive ); // 0 - 1 (1)
3511 seq_printf(m, "MaxSleepDuration: 0x%04X\n", lp->MaxSleepDuration ); // 0 - 65535 (100)
3512 //x hcf_8 MACAddress[ETH_ALEN];
3513 printf_hcf_8(m, "MACAddress", lp->MACAddress, ETH_ALEN );
3514 //x char NetworkName[HCF_MAX_NAME_LEN+1];
3515 seq_printf(m, "NetworkName: %.32s\n", lp->NetworkName );
3516 //x char StationName[HCF_MAX_NAME_LEN+1];
3517 seq_printf(m, "EnableEncryption: 0x%04X\n", lp->EnableEncryption ); // 0 - 1 (0)
3518 //x char Key1[MAX_KEY_LEN+1];
3519 printf_hcf_8( m, "Key1", lp->Key1, MAX_KEY_LEN );
3520 //x char Key2[MAX_KEY_LEN+1];
3521 //x char Key3[MAX_KEY_LEN+1];
3522 //x char Key4[MAX_KEY_LEN+1];
3523 seq_printf(m, "TransmitKeyID: 0x%04X\n", lp->TransmitKeyID ); // 1 - 4 (1)
3524 //x CFG_DEFAULT_KEYS_STRCT "DefaultKeys: 0x%04X\n", lp->DefaultKeys );
3525 //x u_char mailbox[MB_SIZE];
3526 //x char szEncryption[MAX_ENC_LEN];
3527 seq_printf(m, "driverEnable: 0x%04X\n", lp->driverEnable );
3528 seq_printf(m, "wolasEnable: 0x%04X\n", lp->wolasEnable );
3529 seq_printf(m, "atimWindow: 0x%04X\n", lp->atimWindow );
3530 seq_printf(m, "holdoverDuration: 0x%04X\n", lp->holdoverDuration );
3531 //x hcf_16 MulticastRate[2];
3532 seq_printf(m, "authentication: 0x%04X\n", lp->authentication ); // is this AP specific?
3533 seq_printf(m, "promiscuousMode: 0x%04X\n", lp->promiscuousMode );
3534 seq_printf(m, "DownloadFirmware: 0x%04X\n", lp->DownloadFirmware ); // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
3535 seq_printf(m, "AuthKeyMgmtSuite: 0x%04X\n", lp->AuthKeyMgmtSuite );
3536 seq_printf(m, "loadBalancing: 0x%04X\n", lp->loadBalancing );
3537 seq_printf(m, "mediumDistribution: 0x%04X\n", lp->mediumDistribution );
3538 seq_printf(m, "txPowLevel: 0x%04X\n", lp->txPowLevel );
3539 // seq_printf(m, "shortRetryLimit: 0x%04X\n", lp->shortRetryLimit );
3540 // seq_printf(m, "longRetryLimit: 0x%04X\n", lp->longRetryLimit );
3543 seq_printf(m, "connectionControl: 0x%04X\n", lp->connectionControl );
3544 //x //hcf_16 probeDataRates[2];
3545 seq_printf(m, "ownBeaconInterval: 0x%04X\n", lp->ownBeaconInterval );
3546 seq_printf(m, "coexistence: 0x%04X\n", lp->coexistence );
3547 //x WVLAN_FRAME "txF: 0x%04X\n", lp->txF );
3548 //x WVLAN_LFRAME txList[DEFAULT_NUM_TX_FRAMES];
3549 //x struct list_head "txFree: 0x%04X\n", lp->txFree );
3550 //x struct list_head txQ[WVLAN_MAX_TX_QUEUES];
3551 seq_printf(m, "netif_queue_on: 0x%04X\n", lp->netif_queue_on );
3552 seq_printf(m, "txQ_count: 0x%04X\n", lp->txQ_count );
3553 //x DESC_STRCT "desc_rx: 0x%04X\n", lp->desc_rx );
3554 //x DESC_STRCT "desc_tx: 0x%04X\n", lp->desc_tx );
3555 //x WVLAN_PORT_STATE "portState: 0x%04X\n", lp->portState );
3556 //x ScanResult "scan_results: 0x%04X\n", lp->scan_results );
3557 //x ProbeResult "probe_results: 0x%04X\n", lp->probe_results );
3558 seq_printf(m, "probe_num_aps: 0x%04X\n", lp->probe_num_aps );
3559 seq_printf(m, "use_dma: 0x%04X\n", lp->use_dma );
3560 //x DMA_STRCT "dma: 0x%04X\n", lp->dma );
3562 seq_printf(m, "useRTS: 0x%04X\n", lp->useRTS );
3564 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
3565 //;?should we restore this to allow smaller memory footprint
3566 //;?I guess not. This should be brought under Debug mode only
3567 seq_printf(m, "DTIMPeriod: 0x%04X\n", lp->DTIMPeriod ); // 1 - 255 (1)
3568 seq_printf(m, "multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
3569 seq_printf(m, "RejectAny: 0x%04X\n", lp->RejectAny ); // 0 - 1 (0)
3570 seq_printf(m, "ExcludeUnencrypted: 0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
3571 seq_printf(m, "intraBSSRelay: 0x%04X\n", lp->intraBSSRelay );
3572 seq_printf(m, "wlags49_type: 0x%08lX\n", lp->wlags49_type );
3574 //x WVLAN_WDS_IF wds_port[NUM_WDS_PORTS];
3577 } else if ( lp->wlags49_type == 2 ){
3578 seq_printf(m, "tallies to be added\n" );
3579 //Hermes Tallies (IFB substructure) {
3580 p = &lp->hcfCtx.IFB_NIC_Tallies;
3581 seq_printf(m, "TxUnicastFrames: %08lX\n", p->TxUnicastFrames );
3582 seq_printf(m, "TxMulticastFrames: %08lX\n", p->TxMulticastFrames );
3583 seq_printf(m, "TxFragments: %08lX\n", p->TxFragments );
3584 seq_printf(m, "TxUnicastOctets: %08lX\n", p->TxUnicastOctets );
3585 seq_printf(m, "TxMulticastOctets: %08lX\n", p->TxMulticastOctets );
3586 seq_printf(m, "TxDeferredTransmissions: %08lX\n", p->TxDeferredTransmissions );
3587 seq_printf(m, "TxSingleRetryFrames: %08lX\n", p->TxSingleRetryFrames );
3588 seq_printf(m, "TxMultipleRetryFrames: %08lX\n", p->TxMultipleRetryFrames );
3589 seq_printf(m, "TxRetryLimitExceeded: %08lX\n", p->TxRetryLimitExceeded );
3590 seq_printf(m, "TxDiscards: %08lX\n", p->TxDiscards );
3591 seq_printf(m, "RxUnicastFrames: %08lX\n", p->RxUnicastFrames );
3592 seq_printf(m, "RxMulticastFrames: %08lX\n", p->RxMulticastFrames );
3593 seq_printf(m, "RxFragments: %08lX\n", p->RxFragments );
3594 seq_printf(m, "RxUnicastOctets: %08lX\n", p->RxUnicastOctets );
3595 seq_printf(m, "RxMulticastOctets: %08lX\n", p->RxMulticastOctets );
3596 seq_printf(m, "RxFCSErrors: %08lX\n", p->RxFCSErrors );
3597 seq_printf(m, "RxDiscardsNoBuffer: %08lX\n", p->RxDiscardsNoBuffer );
3598 seq_printf(m, "TxDiscardsWrongSA: %08lX\n", p->TxDiscardsWrongSA );
3599 seq_printf(m, "RxWEPUndecryptable: %08lX\n", p->RxWEPUndecryptable );
3600 seq_printf(m, "RxMsgInMsgFragments: %08lX\n", p->RxMsgInMsgFragments );
3601 seq_printf(m, "RxMsgInBadMsgFragments: %08lX\n", p->RxMsgInBadMsgFragments );
3602 seq_printf(m, "RxDiscardsWEPICVError: %08lX\n", p->RxDiscardsWEPICVError );
3603 seq_printf(m, "RxDiscardsWEPExcluded: %08lX\n", p->RxDiscardsWEPExcluded );
3604 #if (HCF_EXT) & HCF_EXT_TALLIES_FW
3606 #endif // HCF_EXT_TALLIES_FW
3607 } else if ( lp->wlags49_type & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3609 DbgInfo->DebugFlag = lp->wlags49_type & 0x7FFF;
3611 lp->wlags49_type = 0; //default to IFB again ;?
3613 seq_printf(m, "unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
3616 "0x0001 - wl_private\n"
3617 "0x0002 - Tallies\n"
3618 "0x8xxx - Change debufflag\n"
3619 "ERROR 0001\nWARNING 0002\nNOTICE 0004\nTRACE 0008\n"
3620 "VERBOSE 0010\nPARAM 0020\nBREAK 0040\nRX 0100\n"
3621 "TX 0200\nDS 0400\n");
3624 } // scull_read_procmem
3626 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
3628 static char proc_number[11];
3629 unsigned int nr = 0;
3633 } else if ( copy_from_user(proc_number, buffer, count) ) {
3637 proc_number[count] = 0;
3638 nr = simple_strtoul(proc_number , NULL, 0);
3639 *(unsigned int *)data = nr;
3640 if ( nr & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3642 DbgInfo->DebugFlag = nr & 0x7FFF;
3646 DBG_PRINT( "value: %08X\n", nr );
3650 #endif /* SCULL_USE_PROC */
3653 #define RUN_AT(x) (jiffies+(x)) //"borrowed" from include/pcmcia/k_compat.h
3654 #define DS_OOR 0x8000 //Deepsleep OutOfRange Status
3656 lp->timer_oor_cnt = DS_OOR;
3657 init_timer( &lp->timer_oor );
3658 lp->timer_oor.function = timer_oor;
3659 lp->timer_oor.data = (unsigned long)lp;
3660 lp->timer_oor.expires = RUN_AT( 3 * HZ );
3661 add_timer( &lp->timer_oor );
3662 printk(KERN_NOTICE "wl_enable: %ld\n", jiffies ); //;?remove me 1 day
3665 /*******************************************************************************
3667 *******************************************************************************
3674 * arg - a u_long representing a pointer to a dev_link_t structure for the
3675 * device to be released.
3681 ******************************************************************************/
3682 void timer_oor( u_long arg )
3684 struct wl_private *lp = (struct wl_private *)arg;
3686 DBG_PARAM( DbgInfo, "arg", "0x%08lx", arg );
3688 printk(KERN_NOTICE "timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt ); //;?remove me 1 day
3689 lp->timer_oor_cnt += 10;
3690 if ( (lp->timer_oor_cnt & ~DS_OOR) > 300 ) {
3691 lp->timer_oor_cnt = 300;
3693 lp->timer_oor_cnt |= DS_OOR;
3694 init_timer( &lp->timer_oor );
3695 lp->timer_oor.function = timer_oor;
3696 lp->timer_oor.data = (unsigned long)lp;
3697 lp->timer_oor.expires = RUN_AT( (lp->timer_oor_cnt & ~DS_OOR) * HZ );
3698 add_timer( &lp->timer_oor );
3702 MODULE_LICENSE("Dual BSD/GPL");