Merge branch 'misc' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / wlags49_h2 / wl_main.c
1 /*******************************************************************************
2 * Agere Systems Inc.
3 * Wireless device driver for Linux (wlags49).
4 *
5 * Copyright (c) 1998-2003 Agere Systems Inc.
6 * All rights reserved.
7 * http://www.agere.com
8 *
9 * Initially developed by TriplePoint, Inc.
10 * http://www.triplepoint.com
11 *
12 *------------------------------------------------------------------------------
13 *
14 * This file contains the main driver entry points and other adapter
15 * specific routines.
16 *
17 *------------------------------------------------------------------------------
18 *
19 * SOFTWARE LICENSE
20 *
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.
25 *
26 * Copyright © 2003 Agere Systems Inc.
27 * All rights reserved.
28 *
29 * Redistribution and use in source or binary forms, with or without
30 * modifications, are permitted provided that the following conditions are met:
31 *
32 * . Redistributions of source code must retain the above copyright notice, this
33 * list of conditions and the following Disclaimer as comments in the code as
34 * well as in the documentation and/or other materials provided with the
35 * distribution.
36 *
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.
40 *
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.
44 *
45 * Disclaimer
46 *
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
58 * DAMAGE.
59 *
60 ******************************************************************************/
61
62 /*******************************************************************************
63 * constant definitions
64 ******************************************************************************/
65
66 /* Allow support for calling system fcns to access F/W iamge file */
67 #define __KERNEL_SYSCALLS__
68
69 /*******************************************************************************
70 * include files
71 ******************************************************************************/
72 #include <wl_version.h>
73
74 #include <linux/module.h>
75 #include <linux/proc_fs.h>
76 #include <linux/types.h>
77 #include <linux/kernel.h>
78 // #include <linux/sched.h>
79 // #include <linux/ptrace.h>
80 // #include <linux/slab.h>
81 // #include <linux/ctype.h>
82 // #include <linux/string.h>
83 // #include <linux/timer.h>
84 //#include <linux/interrupt.h>
85 // #include <linux/tqueue.h>
86 // #include <linux/in.h>
87 // #include <linux/delay.h>
88 // #include <asm/io.h>
89 // #include <asm/system.h>
90 // #include <asm/bitops.h>
91 #include <linux/unistd.h>
92 #include <asm/uaccess.h>
93
94 #include <linux/netdevice.h>
95 #include <linux/etherdevice.h>
96 // #include <linux/skbuff.h>
97 // #include <linux/if_arp.h>
98 // #include <linux/ioport.h>
99
100 #define BIN_DL 0
101 #if BIN_DL
102 #include <linux/vmalloc.h>
103 #endif // BIN_DL
104
105
106 #include <debug.h>
107
108 #include <hcf.h>
109 #include <dhf.h>
110 //in order to get around:: wl_main.c:2229: `HREG_EV_RDMAD' undeclared (first use in this function)
111 #include <hcfdef.h>
112
113 #include <wl_if.h>
114 #include <wl_internal.h>
115 #include <wl_util.h>
116 #include <wl_main.h>
117 #include <wl_netdev.h>
118 #include <wl_wext.h>
119
120 #ifdef USE_PROFILE
121 #include <wl_profile.h>
122 #endif /* USE_PROFILE */
123
124 #ifdef BUS_PCMCIA
125 #include <wl_cs.h>
126 #endif /* BUS_PCMCIA */
127
128 #ifdef BUS_PCI
129 #include <wl_pci.h>
130 #endif /* BUS_PCI */
131 /*******************************************************************************
132 * macro defintions
133 ******************************************************************************/
134 #define VALID_PARAM(C) \
135 { \
136 if (!(C)) \
137 { \
138 printk(KERN_INFO "Wireless, parameter error: \"%s\"\n", #C); \
139 goto failed; \
140 } \
141 }
142 /*******************************************************************************
143 * local functions
144 ******************************************************************************/
145 void wl_isr_handler( unsigned long p );
146
147 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
148 //int scull_read_procmem(char *buf, char **start, off_t offset, int len, int unused);
149 int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data );
150 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data);
151 static void proc_write(const char *name, write_proc_t *w, void *data);
152
153 #endif /* SCULL_USE_PROC */
154
155 /*******************************************************************************
156 * module parameter definitions - set with 'insmod'
157 ******************************************************************************/
158 static p_u16 irq_mask = 0xdeb8; // IRQ3,4,5,7,9,10,11,12,14,15
159 static p_s8 irq_list[4] = { -1 };
160
161 #if 0
162 MODULE_PARM(irq_mask, "h");
163 MODULE_PARM_DESC(irq_mask, "IRQ mask [0xdeb8]");
164 MODULE_PARM(irq_list, "1-4b");
165 MODULE_PARM_DESC(irq_list, "IRQ list [<irq_mask>]");
166 #endif
167
168 static p_u8 PARM_AUTHENTICATION = PARM_DEFAULT_AUTHENTICATION;
169 static p_u16 PARM_AUTH_KEY_MGMT_SUITE = PARM_DEFAULT_AUTH_KEY_MGMT_SUITE;
170 static p_u16 PARM_BRSC_2GHZ = PARM_DEFAULT_BRSC_2GHZ;
171 static p_u16 PARM_BRSC_5GHZ = PARM_DEFAULT_BRSC_5GHZ;
172 static p_u16 PARM_COEXISTENCE = PARM_DEFAULT_COEXISTENCE;
173 static p_u16 PARM_CONNECTION_CONTROL = PARM_DEFAULT_CONNECTION_CONTROL; //;?rename and move
174 static p_char *PARM_CREATE_IBSS = PARM_DEFAULT_CREATE_IBSS_STR;
175 static p_char *PARM_DESIRED_SSID = PARM_DEFAULT_SSID;
176 static p_char *PARM_DOWNLOAD_FIRMWARE = "";
177 static p_u16 PARM_ENABLE_ENCRYPTION = PARM_DEFAULT_ENABLE_ENCRYPTION;
178 static p_char *PARM_EXCLUDE_UNENCRYPTED = PARM_DEFAULT_EXCLUDE_UNENCRYPTED_STR;
179 static p_char *PARM_INTRA_BSS_RELAY = PARM_DEFAULT_INTRA_BSS_RELAY_STR;
180 static p_char *PARM_KEY1 = "";
181 static p_char *PARM_KEY2 = "";
182 static p_char *PARM_KEY3 = "";
183 static p_char *PARM_KEY4 = "";
184 static p_char *PARM_LOAD_BALANCING = PARM_DEFAULT_LOAD_BALANCING_STR;
185 static p_u16 PARM_MAX_SLEEP = PARM_DEFAULT_MAX_PM_SLEEP;
186 static p_char *PARM_MEDIUM_DISTRIBUTION = PARM_DEFAULT_MEDIUM_DISTRIBUTION_STR;
187 static p_char *PARM_MICROWAVE_ROBUSTNESS = PARM_DEFAULT_MICROWAVE_ROBUSTNESS_STR;
188 static p_char *PARM_MULTICAST_PM_BUFFERING = PARM_DEFAULT_MULTICAST_PM_BUFFERING_STR;
189 static p_u16 PARM_MULTICAST_RATE = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
190 static p_char *PARM_MULTICAST_RX = PARM_DEFAULT_MULTICAST_RX_STR;
191 static p_u8 PARM_NETWORK_ADDR[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
192 static p_u16 PARM_OWN_ATIM_WINDOW = PARM_DEFAULT_OWN_ATIM_WINDOW;
193 static p_u16 PARM_OWN_BEACON_INTERVAL = PARM_DEFAULT_OWN_BEACON_INTERVAL;
194 static p_u8 PARM_OWN_CHANNEL = PARM_DEFAULT_OWN_CHANNEL;
195 static p_u8 PARM_OWN_DTIM_PERIOD = PARM_DEFAULT_OWN_DTIM_PERIOD;
196 static p_char *PARM_OWN_NAME = PARM_DEFAULT_OWN_NAME;
197 static p_char *PARM_OWN_SSID = PARM_DEFAULT_SSID;
198 static p_u16 PARM_PM_ENABLED = WVLAN_PM_STATE_DISABLED;
199 static p_u16 PARM_PM_HOLDOVER_DURATION = PARM_DEFAULT_PM_HOLDOVER_DURATION;
200 static p_u8 PARM_PORT_TYPE = PARM_DEFAULT_PORT_TYPE;
201 static p_char *PARM_PROMISCUOUS_MODE = PARM_DEFAULT_PROMISCUOUS_MODE_STR;
202 static p_char *PARM_REJECT_ANY = PARM_DEFAULT_REJECT_ANY_STR;
203 #ifdef USE_WDS
204 static p_u16 PARM_RTS_THRESHOLD1 = PARM_DEFAULT_RTS_THRESHOLD;
205 static p_u16 PARM_RTS_THRESHOLD2 = PARM_DEFAULT_RTS_THRESHOLD;
206 static p_u16 PARM_RTS_THRESHOLD3 = PARM_DEFAULT_RTS_THRESHOLD;
207 static p_u16 PARM_RTS_THRESHOLD4 = PARM_DEFAULT_RTS_THRESHOLD;
208 static p_u16 PARM_RTS_THRESHOLD5 = PARM_DEFAULT_RTS_THRESHOLD;
209 static p_u16 PARM_RTS_THRESHOLD6 = PARM_DEFAULT_RTS_THRESHOLD;
210 #endif // USE_WDS
211 static p_u16 PARM_RTS_THRESHOLD = PARM_DEFAULT_RTS_THRESHOLD;
212 static p_u16 PARM_SRSC_2GHZ = PARM_DEFAULT_SRSC_2GHZ;
213 static p_u16 PARM_SRSC_5GHZ = PARM_DEFAULT_SRSC_5GHZ;
214 static p_u8 PARM_SYSTEM_SCALE = PARM_DEFAULT_SYSTEM_SCALE;
215 static p_u8 PARM_TX_KEY = PARM_DEFAULT_TX_KEY;
216 static p_u16 PARM_TX_POW_LEVEL = PARM_DEFAULT_TX_POW_LEVEL;
217 #ifdef USE_WDS
218 static p_u16 PARM_TX_RATE1 = PARM_DEFAULT_TX_RATE_2GHZ;
219 static p_u16 PARM_TX_RATE2 = PARM_DEFAULT_TX_RATE_2GHZ;
220 static p_u16 PARM_TX_RATE3 = PARM_DEFAULT_TX_RATE_2GHZ;
221 static p_u16 PARM_TX_RATE4 = PARM_DEFAULT_TX_RATE_2GHZ;
222 static p_u16 PARM_TX_RATE5 = PARM_DEFAULT_TX_RATE_2GHZ;
223 static p_u16 PARM_TX_RATE6 = PARM_DEFAULT_TX_RATE_2GHZ;
224 #endif // USE_WDS
225 static p_u16 PARM_TX_RATE = PARM_DEFAULT_TX_RATE_2GHZ;
226 #ifdef USE_WDS
227 static p_u8 PARM_WDS_ADDRESS1[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
228 static p_u8 PARM_WDS_ADDRESS2[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
229 static p_u8 PARM_WDS_ADDRESS3[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
230 static p_u8 PARM_WDS_ADDRESS4[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
231 static p_u8 PARM_WDS_ADDRESS5[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
232 static p_u8 PARM_WDS_ADDRESS6[ETH_ALEN] = PARM_DEFAULT_NETWORK_ADDR;
233 #endif // USE_WDS
234
235
236 #if 0
237 MODULE_PARM(PARM_DESIRED_SSID, "s");
238 MODULE_PARM_DESC(PARM_DESIRED_SSID, "Network Name (<string>) [ANY]");
239 MODULE_PARM(PARM_OWN_SSID, "s");
240 MODULE_PARM_DESC(PARM_OWN_SSID, "Network Name (<string>) [ANY]");
241 MODULE_PARM(PARM_OWN_CHANNEL, "b");
242 MODULE_PARM_DESC(PARM_OWN_CHANNEL, "Channel (0 - 14) [0]");
243 MODULE_PARM(PARM_SYSTEM_SCALE, "b");
244 MODULE_PARM_DESC(PARM_SYSTEM_SCALE, "Distance Between APs (1 - 3) [1]");
245 MODULE_PARM(PARM_TX_RATE, "b");
246 MODULE_PARM_DESC(PARM_TX_RATE, "Transmit Rate Control");
247 MODULE_PARM(PARM_RTS_THRESHOLD, "h");
248 MODULE_PARM_DESC(PARM_RTS_THRESHOLD, "Medium Reservation (RTS/CTS Fragment Length) (256 - 2347) [2347]");
249 MODULE_PARM(PARM_MICROWAVE_ROBUSTNESS, "s");
250 MODULE_PARM_DESC(PARM_MICROWAVE_ROBUSTNESS, "Microwave Oven Robustness Enabled (<string> N or Y) [N]");
251 MODULE_PARM(PARM_OWN_NAME, "s");
252 MODULE_PARM_DESC(PARM_OWN_NAME, "Station Name (<string>) [Linux]");
253
254 MODULE_PARM(PARM_ENABLE_ENCRYPTION, "b");
255 MODULE_PARM_DESC(PARM_ENABLE_ENCRYPTION, "Encryption Mode (0 - 7) [0]");
256
257 MODULE_PARM(PARM_KEY1, "s");
258 MODULE_PARM_DESC(PARM_KEY1, "Data Encryption Key 1 (<string>) []");
259 MODULE_PARM(PARM_KEY2, "s");
260 MODULE_PARM_DESC(PARM_KEY2, "Data Encryption Key 2 (<string>) []");
261 MODULE_PARM(PARM_KEY3, "s");
262 MODULE_PARM_DESC(PARM_KEY3, "Data Encryption Key 3 (<string>) []");
263 MODULE_PARM(PARM_KEY4, "s");
264 MODULE_PARM_DESC(PARM_KEY4, "Data Encryption Key 4 (<string>) []");
265 MODULE_PARM(PARM_TX_KEY, "b");
266 MODULE_PARM_DESC(PARM_TX_KEY, "Transmit Key ID (1 - 4) [1]");
267 MODULE_PARM(PARM_MULTICAST_RATE, "b");
268 MODULE_PARM_DESC(PARM_MULTICAST_RATE, "Multicast Rate");
269 MODULE_PARM(PARM_DOWNLOAD_FIRMWARE, "s");
270 MODULE_PARM_DESC(PARM_DOWNLOAD_FIRMWARE, "filename of firmware image");
271
272 MODULE_PARM(PARM_AUTH_KEY_MGMT_SUITE, "b");
273 MODULE_PARM_DESC(PARM_AUTH_KEY_MGMT_SUITE, "Authentication Key Management suite (0-4) [0]");
274
275 MODULE_PARM(PARM_LOAD_BALANCING, "s");
276 MODULE_PARM_DESC(PARM_LOAD_BALANCING, "Load Balancing Enabled (<string> N or Y) [Y]");
277 MODULE_PARM(PARM_MEDIUM_DISTRIBUTION, "s");
278 MODULE_PARM_DESC(PARM_MEDIUM_DISTRIBUTION, "Medium Distribution Enabled (<string> N or Y) [Y]");
279 MODULE_PARM(PARM_TX_POW_LEVEL, "b");
280 MODULE_PARM_DESC(PARM_TX_POW_LEVEL, "Transmit Power (0 - 6) [3]");
281 MODULE_PARM(PARM_SRSC_2GHZ, "b");
282 MODULE_PARM_DESC(PARM_SRSC_2GHZ, "Supported Rate Set Control 2.4 GHz");
283 MODULE_PARM(PARM_SRSC_5GHZ, "b");
284 MODULE_PARM_DESC(PARM_SRSC_5GHZ, "Supported Rate Set Control 5.0 GHz");
285 MODULE_PARM(PARM_BRSC_2GHZ, "b");
286 MODULE_PARM_DESC(PARM_BRSC_2GHZ, "Basic Rate Set Control 2.4 GHz");
287 MODULE_PARM(PARM_BRSC_5GHZ, "b");
288 MODULE_PARM_DESC(PARM_BRSC_5GHZ, "Basic Rate Set Control 5.0 GHz");
289 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
290 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
291 MODULE_PARM(PARM_PM_ENABLED, "h");
292 MODULE_PARM_DESC(PARM_PM_ENABLED, "Power Management State (0 - 2, 8001 - 8002) [0]");
293 MODULE_PARM(PARM_PORT_TYPE, "b");
294 MODULE_PARM_DESC(PARM_PORT_TYPE, "Port Type (1 - 3) [1]");
295 //;?MODULE_PARM(PARM_CREATE_IBSS, "s");
296 //;?MODULE_PARM_DESC(PARM_CREATE_IBSS, "Create IBSS (<string> N or Y) [N]");
297 //;?MODULE_PARM(PARM_MULTICAST_RX, "s");
298 //;?MODULE_PARM_DESC(PARM_MULTICAST_RX, "Multicast Receive Enable (<string> N or Y) [Y]");
299 //;?MODULE_PARM(PARM_MAX_SLEEP, "h");
300 //;?MODULE_PARM_DESC(PARM_MAX_SLEEP, "Maximum Power Management Sleep Duration (0 - 65535) [100]");
301 //;?MODULE_PARM(PARM_NETWORK_ADDR, "6b");
302 //;?MODULE_PARM_DESC(PARM_NETWORK_ADDR, "Hardware Ethernet Address ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [<factory value>]");
303 //;?MODULE_PARM(PARM_AUTHENTICATION, "b");
304 //
305 //tracker 12448
306 //;?MODULE_PARM_DESC(PARM_AUTHENTICATION, "Authentication Type (0-2) [0] 0=Open 1=SharedKey 2=LEAP");
307 //;?MODULE_PARM_DESC(authentication, "Authentication Type (1-2) [1] 1=Open 2=SharedKey");
308 //tracker 12448
309 //
310 //;?MODULE_PARM(PARM_OWN_ATIM_WINDOW, "b");
311 //;?MODULE_PARM_DESC(PARM_OWN_ATIM_WINDOW, "ATIM Window time in TU for IBSS creation (0-100) [0]");
312 //;?MODULE_PARM(PARM_PM_HOLDOVER_DURATION, "b");
313 //;?MODULE_PARM_DESC(PARM_PM_HOLDOVER_DURATION, "Time station remains awake after MAC frame transfer when PM is on (0-65535) [100]");
314 //;?MODULE_PARM(PARM_PROMISCUOUS_MODE, "s");
315 //;?MODULE_PARM_DESC(PARM_PROMISCUOUS_MODE, "Promiscuous Mode Enable (<string> Y or N ) [N]" );
316 //;?
317 MODULE_PARM(PARM_CONNECTION_CONTROL, "b");
318 MODULE_PARM_DESC(PARM_CONNECTION_CONTROL, "Connection Control (0 - 3) [2]");
319 #endif /* HCF_STA */
320 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
321 //;?should we restore this to allow smaller memory footprint
322 MODULE_PARM(PARM_OWN_DTIM_PERIOD, "b");
323 MODULE_PARM_DESC(PARM_OWN_DTIM_PERIOD, "DTIM Period (0 - 255) [1]");
324 MODULE_PARM(PARM_REJECT_ANY, "s");
325 MODULE_PARM_DESC(PARM_REJECT_ANY, "Closed System (<string> N or Y) [N]");
326 MODULE_PARM(PARM_EXCLUDE_UNENCRYPTED, "s");
327 MODULE_PARM_DESC(PARM_EXCLUDE_UNENCRYPTED, "Deny non-encrypted (<string> N or Y) [Y]");
328 MODULE_PARM(PARM_MULTICAST_PM_BUFFERING,"s");
329 MODULE_PARM_DESC(PARM_MULTICAST_PM_BUFFERING, "Buffer MAC frames for Tx after DTIM (<string> Y or N) [Y]");
330 MODULE_PARM(PARM_INTRA_BSS_RELAY, "s");
331 MODULE_PARM_DESC(PARM_INTRA_BSS_RELAY, "IntraBSS Relay (<string> N or Y) [Y]");
332 MODULE_PARM(PARM_RTS_THRESHOLD1, "h");
333 MODULE_PARM_DESC(PARM_RTS_THRESHOLD1, "RTS Threshold, WDS Port 1 (256 - 2347) [2347]");
334 MODULE_PARM(PARM_RTS_THRESHOLD2, "h");
335 MODULE_PARM_DESC(PARM_RTS_THRESHOLD2, "RTS Threshold, WDS Port 2 (256 - 2347) [2347]");
336 MODULE_PARM(PARM_RTS_THRESHOLD3, "h");
337 MODULE_PARM_DESC(PARM_RTS_THRESHOLD3, "RTS Threshold, WDS Port 3 (256 - 2347) [2347]");
338 MODULE_PARM(PARM_RTS_THRESHOLD4, "h");
339 MODULE_PARM_DESC(PARM_RTS_THRESHOLD4, "RTS Threshold, WDS Port 4 (256 - 2347) [2347]");
340 MODULE_PARM(PARM_RTS_THRESHOLD5, "h");
341 MODULE_PARM_DESC(PARM_RTS_THRESHOLD5, "RTS Threshold, WDS Port 5 (256 - 2347) [2347]");
342 MODULE_PARM(PARM_RTS_THRESHOLD6, "h");
343 MODULE_PARM_DESC(PARM_RTS_THRESHOLD6, "RTS Threshold, WDS Port 6 (256 - 2347) [2347]");
344 MODULE_PARM(PARM_TX_RATE1, "b");
345 MODULE_PARM_DESC(PARM_TX_RATE1, "Transmit Rate Control, WDS Port 1 (1 - 7) [3]");
346 MODULE_PARM(PARM_TX_RATE2, "b");
347 MODULE_PARM_DESC(PARM_TX_RATE2, "Transmit Rate Control, WDS Port 2 (1 - 7) [3]");
348 MODULE_PARM(PARM_TX_RATE3, "b");
349 MODULE_PARM_DESC(PARM_TX_RATE3, "Transmit Rate Control, WDS Port 3 (1 - 7) [3]");
350 MODULE_PARM(PARM_TX_RATE4, "b");
351 MODULE_PARM_DESC(PARM_TX_RATE4, "Transmit Rate Control, WDS Port 4 (1 - 7) [3]");
352 MODULE_PARM(PARM_TX_RATE5, "b");
353 MODULE_PARM_DESC(PARM_TX_RATE5, "Transmit Rate Control, WDS Port 5 (1 - 7) [3]");
354 MODULE_PARM(PARM_TX_RATE6, "b");
355 MODULE_PARM_DESC(PARM_TX_RATE6, "Transmit Rate Control, WDS Port 6 (1 - 7) [3]");
356 MODULE_PARM(PARM_WDS_ADDRESS1, "6b");
357 MODULE_PARM_DESC(PARM_WDS_ADDRESS1, "MAC Address, WDS Port 1 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
358 MODULE_PARM(PARM_WDS_ADDRESS2, "6b");
359 MODULE_PARM_DESC(PARM_WDS_ADDRESS2, "MAC Address, WDS Port 2 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
360 MODULE_PARM(PARM_WDS_ADDRESS3, "6b");
361 MODULE_PARM_DESC(PARM_WDS_ADDRESS3, "MAC Address, WDS Port 3 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
362 MODULE_PARM(PARM_WDS_ADDRESS4, "6b");
363 MODULE_PARM_DESC(PARM_WDS_ADDRESS4, "MAC Address, WDS Port 4 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
364 MODULE_PARM(PARM_WDS_ADDRESS5, "6b");
365 MODULE_PARM_DESC(PARM_WDS_ADDRESS5, "MAC Address, WDS Port 5 ([0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff],[0x00-0xff]) [{0}]");
366 MODULE_PARM(PARM_WDS_ADDRESS6, "6b");
367 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
369 MODULE_PARM(PARM_OWN_BEACON_INTERVAL, "b");
370 MODULE_PARM_DESC(PARM_OWN_BEACON_INTERVAL, "Own Beacon Interval (20 - 200) [100]");
371 MODULE_PARM(PARM_COEXISTENCE, "b");
372 MODULE_PARM_DESC(PARM_COEXISTENCE, "Coexistence (0-7) [0]");
373
374 #endif /* HCF_AP */
375 #endif
376
377 /* END NEW PARAMETERS */
378 /*******************************************************************************
379 * debugging specifics
380 ******************************************************************************/
381 #if DBG
382
383 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");
389
390 dbg_info_t wl_info = { DBG_MOD_NAME, 0, 0 };
391 dbg_info_t *DbgInfo = &wl_info;
392
393 #endif /* DBG */
394 #ifdef USE_RTS
395
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]" );
399
400 #endif /* USE_RTS */
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
406
407 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
408 extern memimage ap; // AP firmware image to be downloaded
409 #endif /* HCF_AP */
410
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
414 #endif /* HCF_STA */
415
416
417 /*******************************************************************************
418 * wl_insert()
419 *******************************************************************************
420 *
421 * DESCRIPTION:
422 *
423 * wl_insert() is scheduled to run after a CARD_INSERTION event is
424 * received, to configure the PCMCIA socket, and to make the ethernet device
425 * available to the system.
426 *
427 * PARAMETERS:
428 *
429 * dev - a pointer to the net_device struct of the wireless device
430 *
431 * RETURNS:
432 *
433 * TRUE or FALSE
434 *
435 ******************************************************************************/
436 int wl_insert( struct net_device *dev )
437 {
438 int result = 0;
439 int hcf_status = HCF_SUCCESS;
440 int i;
441 unsigned long flags = 0;
442 struct wl_private *lp = wl_priv(dev);
443 /*------------------------------------------------------------------------*/
444 DBG_FUNC( "wl_insert" );
445 DBG_ENTER( DbgInfo );
446
447 /* Initialize the adapter hardware. */
448 memset( &( lp->hcfCtx ), 0, sizeof( IFB_STRCT ));
449
450 /* Initialize the adapter parameters. */
451 spin_lock_init( &( lp->slock ));
452
453 /* Intialize states */
454 //lp->lockcount = 0; //PE1DNN
455 lp->is_handling_int = WL_NOT_HANDLING_INT;
456 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
457
458 lp->dev = dev;
459
460 DBG_PARAM( DbgInfo, "irq_mask", "0x%04x", irq_mask & 0x0FFFF );
461 DBG_PARAM( DbgInfo, "irq_list", "0x%02x 0x%02x 0x%02x 0x%02x",
462 irq_list[0] & 0x0FF, irq_list[1] & 0x0FF,
463 irq_list[2] & 0x0FF, irq_list[3] & 0x0FF );
464 DBG_PARAM( DbgInfo, PARM_NAME_DESIRED_SSID, "\"%s\"", PARM_DESIRED_SSID );
465 DBG_PARAM( DbgInfo, PARM_NAME_OWN_SSID, "\"%s\"", PARM_OWN_SSID );
466 DBG_PARAM( DbgInfo, PARM_NAME_OWN_CHANNEL, "%d", PARM_OWN_CHANNEL);
467 DBG_PARAM( DbgInfo, PARM_NAME_SYSTEM_SCALE, "%d", PARM_SYSTEM_SCALE );
468 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE, "%d", PARM_TX_RATE );
469 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD, "%d", PARM_RTS_THRESHOLD );
470 DBG_PARAM( DbgInfo, PARM_NAME_MICROWAVE_ROBUSTNESS, "\"%s\"", PARM_MICROWAVE_ROBUSTNESS );
471 DBG_PARAM( DbgInfo, PARM_NAME_OWN_NAME, "\"%s\"", PARM_OWN_NAME );
472 //;? DBG_PARAM( DbgInfo, PARM_NAME_ENABLE_ENCRYPTION, "\"%s\"", PARM_ENABLE_ENCRYPTION );
473 DBG_PARAM( DbgInfo, PARM_NAME_KEY1, "\"%s\"", PARM_KEY1 );
474 DBG_PARAM( DbgInfo, PARM_NAME_KEY2, "\"%s\"", PARM_KEY2 );
475 DBG_PARAM( DbgInfo, PARM_NAME_KEY3, "\"%s\"", PARM_KEY3 );
476 DBG_PARAM( DbgInfo, PARM_NAME_KEY4, "\"%s\"", PARM_KEY4 );
477 DBG_PARAM( DbgInfo, PARM_NAME_TX_KEY, "%d", PARM_TX_KEY );
478 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RATE, "%d", PARM_MULTICAST_RATE );
479 DBG_PARAM( DbgInfo, PARM_NAME_DOWNLOAD_FIRMWARE, "\"%s\"", PARM_DOWNLOAD_FIRMWARE );
480 DBG_PARAM( DbgInfo, PARM_NAME_AUTH_KEY_MGMT_SUITE, "%d", PARM_AUTH_KEY_MGMT_SUITE );
481 //;?#if (HCF_TYPE) & HCF_TYPE_STA
482 //;?should we make this code conditional depending on in STA mode
483 //;? DBG_PARAM( DbgInfo, PARM_NAME_PORT_TYPE, "%d", PARM_PORT_TYPE );
484 DBG_PARAM( DbgInfo, PARM_NAME_PM_ENABLED, "%04x", PARM_PM_ENABLED );
485 //;? DBG_PARAM( DbgInfo, PARM_NAME_CREATE_IBSS, "\"%s\"", PARM_CREATE_IBSS );
486 //;? DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_RX, "\"%s\"", PARM_MULTICAST_RX );
487 //;? DBG_PARAM( DbgInfo, PARM_NAME_MAX_SLEEP, "%d", PARM_MAX_SLEEP );
488 //;? DBG_PARAM( DbgInfo, PARM_NAME_NETWORK_ADDR, "\"%s\"", DbgHwAddr( PARM_NETWORK_ADDR ));
489 //;? DBG_PARAM( DbgInfo, PARM_NAME_AUTHENTICATION, "%d", PARM_AUTHENTICATION );
490 //;? DBG_PARAM( DbgInfo, PARM_NAME_OWN_ATIM_WINDOW, "%d", PARM_OWN_ATIM_WINDOW );
491 //;? DBG_PARAM( DbgInfo, PARM_NAME_PM_HOLDOVER_DURATION, "%d", PARM_PM_HOLDOVER_DURATION );
492 //;? DBG_PARAM( DbgInfo, PARM_NAME_PROMISCUOUS_MODE, "\"%s\"", PARM_PROMISCUOUS_MODE );
493 //;?#endif /* HCF_STA */
494 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
495 //;?should we restore this to allow smaller memory footprint
496 //;?I guess: no, since this is Debug mode only
497 DBG_PARAM( DbgInfo, PARM_NAME_OWN_DTIM_PERIOD, "%d", PARM_OWN_DTIM_PERIOD );
498 DBG_PARAM( DbgInfo, PARM_NAME_REJECT_ANY, "\"%s\"", PARM_REJECT_ANY );
499 DBG_PARAM( DbgInfo, PARM_NAME_EXCLUDE_UNENCRYPTED, "\"%s\"", PARM_EXCLUDE_UNENCRYPTED );
500 DBG_PARAM( DbgInfo, PARM_NAME_MULTICAST_PM_BUFFERING, "\"%s\"", PARM_MULTICAST_PM_BUFFERING );
501 DBG_PARAM( DbgInfo, PARM_NAME_INTRA_BSS_RELAY, "\"%s\"", PARM_INTRA_BSS_RELAY );
502 #ifdef USE_WDS
503 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD1, "%d", PARM_RTS_THRESHOLD1 );
504 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD2, "%d", PARM_RTS_THRESHOLD2 );
505 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD3, "%d", PARM_RTS_THRESHOLD3 );
506 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD4, "%d", PARM_RTS_THRESHOLD4 );
507 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD5, "%d", PARM_RTS_THRESHOLD5 );
508 DBG_PARAM( DbgInfo, PARM_NAME_RTS_THRESHOLD6, "%d", PARM_RTS_THRESHOLD6 );
509 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE1, "%d", PARM_TX_RATE1 );
510 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE2, "%d", PARM_TX_RATE2 );
511 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE3, "%d", PARM_TX_RATE3 );
512 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE4, "%d", PARM_TX_RATE4 );
513 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE5, "%d", PARM_TX_RATE5 );
514 DBG_PARAM( DbgInfo, PARM_NAME_TX_RATE6, "%d", PARM_TX_RATE6 );
515 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS1, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS1 ));
516 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS2, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS2 ));
517 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS3, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS3 ));
518 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS4, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS4 ));
519 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS5, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS5 ));
520 DBG_PARAM( DbgInfo, PARM_NAME_WDS_ADDRESS6, "\"%s\"", DbgHwAddr( PARM_WDS_ADDRESS6 ));
521 #endif /* USE_WDS */
522 #endif /* HCF_AP */
523
524 VALID_PARAM( !PARM_DESIRED_SSID || ( strlen( PARM_DESIRED_SSID ) <= PARM_MAX_NAME_LEN ));
525 VALID_PARAM( !PARM_OWN_SSID || ( strlen( PARM_OWN_SSID ) <= PARM_MAX_NAME_LEN ));
526 VALID_PARAM(( PARM_OWN_CHANNEL <= PARM_MAX_OWN_CHANNEL ));
527 VALID_PARAM(( PARM_SYSTEM_SCALE >= PARM_MIN_SYSTEM_SCALE ) && ( PARM_SYSTEM_SCALE <= PARM_MAX_SYSTEM_SCALE ));
528 VALID_PARAM(( PARM_TX_RATE >= PARM_MIN_TX_RATE ) && ( PARM_TX_RATE <= PARM_MAX_TX_RATE ));
529 VALID_PARAM(( PARM_RTS_THRESHOLD <= PARM_MAX_RTS_THRESHOLD ));
530 VALID_PARAM( !PARM_MICROWAVE_ROBUSTNESS || strchr( "NnYy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL );
531 VALID_PARAM( !PARM_OWN_NAME || ( strlen( PARM_NAME_OWN_NAME ) <= PARM_MAX_NAME_LEN ));
532 VALID_PARAM(( PARM_ENABLE_ENCRYPTION <= PARM_MAX_ENABLE_ENCRYPTION ));
533 VALID_PARAM( is_valid_key_string( PARM_KEY1 ));
534 VALID_PARAM( is_valid_key_string( PARM_KEY2 ));
535 VALID_PARAM( is_valid_key_string( PARM_KEY3 ));
536 VALID_PARAM( is_valid_key_string( PARM_KEY4 ));
537 VALID_PARAM(( PARM_TX_KEY >= PARM_MIN_TX_KEY ) && ( PARM_TX_KEY <= PARM_MAX_TX_KEY ));
538
539 VALID_PARAM(( PARM_MULTICAST_RATE >= PARM_MIN_MULTICAST_RATE ) &&
540 ( PARM_MULTICAST_RATE <= PARM_MAX_MULTICAST_RATE ));
541
542 VALID_PARAM( !PARM_DOWNLOAD_FIRMWARE || ( strlen( PARM_DOWNLOAD_FIRMWARE ) <= 255 /*;?*/ ));
543 VALID_PARAM(( PARM_AUTH_KEY_MGMT_SUITE < PARM_MAX_AUTH_KEY_MGMT_SUITE ));
544
545 VALID_PARAM( !PARM_LOAD_BALANCING || strchr( "NnYy", PARM_LOAD_BALANCING[0] ) != NULL );
546 VALID_PARAM( !PARM_MEDIUM_DISTRIBUTION || strchr( "NnYy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL );
547 VALID_PARAM(( PARM_TX_POW_LEVEL <= PARM_MAX_TX_POW_LEVEL ));
548
549 VALID_PARAM(( PARM_PORT_TYPE >= PARM_MIN_PORT_TYPE ) && ( PARM_PORT_TYPE <= PARM_MAX_PORT_TYPE ));
550 VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
551 ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
552 VALID_PARAM( !PARM_CREATE_IBSS || strchr( "NnYy", PARM_CREATE_IBSS[0] ) != NULL );
553 VALID_PARAM( !PARM_MULTICAST_RX || strchr( "NnYy", PARM_MULTICAST_RX[0] ) != NULL );
554 VALID_PARAM(( PARM_MAX_SLEEP <= PARM_MAX_MAX_PM_SLEEP ));
555 VALID_PARAM(( PARM_AUTHENTICATION <= PARM_MAX_AUTHENTICATION ));
556 VALID_PARAM(( PARM_OWN_ATIM_WINDOW <= PARM_MAX_OWN_ATIM_WINDOW ));
557 VALID_PARAM(( PARM_PM_HOLDOVER_DURATION <= PARM_MAX_PM_HOLDOVER_DURATION ));
558 VALID_PARAM( !PARM_PROMISCUOUS_MODE || strchr( "NnYy", PARM_PROMISCUOUS_MODE[0] ) != NULL );
559 VALID_PARAM(( PARM_CONNECTION_CONTROL <= PARM_MAX_CONNECTION_CONTROL ));
560
561 VALID_PARAM(( PARM_OWN_DTIM_PERIOD >= PARM_MIN_OWN_DTIM_PERIOD ));
562 VALID_PARAM( !PARM_REJECT_ANY || strchr( "NnYy", PARM_REJECT_ANY[0] ) != NULL );
563 VALID_PARAM( !PARM_EXCLUDE_UNENCRYPTED || strchr( "NnYy", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL );
564 VALID_PARAM( !PARM_MULTICAST_PM_BUFFERING || strchr( "NnYy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL );
565 VALID_PARAM( !PARM_INTRA_BSS_RELAY || strchr( "NnYy", PARM_INTRA_BSS_RELAY[0] ) != NULL );
566 #ifdef USE_WDS
567 VALID_PARAM(( PARM_RTS_THRESHOLD1 <= PARM_MAX_RTS_THRESHOLD ));
568 VALID_PARAM(( PARM_RTS_THRESHOLD2 <= PARM_MAX_RTS_THRESHOLD ));
569 VALID_PARAM(( PARM_RTS_THRESHOLD3 <= PARM_MAX_RTS_THRESHOLD ));
570 VALID_PARAM(( PARM_RTS_THRESHOLD4 <= PARM_MAX_RTS_THRESHOLD ));
571 VALID_PARAM(( PARM_RTS_THRESHOLD5 <= PARM_MAX_RTS_THRESHOLD ));
572 VALID_PARAM(( PARM_RTS_THRESHOLD6 <= PARM_MAX_RTS_THRESHOLD ));
573 VALID_PARAM(( PARM_TX_RATE1 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE1 <= PARM_MAX_TX_RATE ));
574 VALID_PARAM(( PARM_TX_RATE2 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE2 <= PARM_MAX_TX_RATE ));
575 VALID_PARAM(( PARM_TX_RATE3 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE3 <= PARM_MAX_TX_RATE ));
576 VALID_PARAM(( PARM_TX_RATE4 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE4 <= PARM_MAX_TX_RATE ));
577 VALID_PARAM(( PARM_TX_RATE5 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE5 <= PARM_MAX_TX_RATE ));
578 VALID_PARAM(( PARM_TX_RATE6 >= PARM_MIN_TX_RATE ) && (PARM_TX_RATE6 <= PARM_MAX_TX_RATE ));
579 #endif /* USE_WDS */
580
581 VALID_PARAM(( PARM_OWN_BEACON_INTERVAL >= PARM_MIN_OWN_BEACON_INTERVAL ) && ( PARM_OWN_BEACON_INTERVAL <= PARM_MAX_OWN_BEACON_INTERVAL ));
582 VALID_PARAM(( PARM_COEXISTENCE <= PARM_COEXISTENCE ));
583
584 /* Set the driver parameters from the passed in parameters. */
585
586 /* THESE MODULE PARAMETERS ARE TO BE DEPRECATED IN FAVOR OF A NAMING CONVENTION
587 WHICH IS INLINE WITH THE FORTHCOMING WAVELAN API */
588
589 /* START NEW PARAMETERS */
590
591 lp->Channel = PARM_OWN_CHANNEL;
592 lp->DistanceBetweenAPs = PARM_SYSTEM_SCALE;
593
594 /* Need to determine how to handle the new bands for 5GHz */
595 lp->TxRateControl[0] = PARM_DEFAULT_TX_RATE_2GHZ;
596 lp->TxRateControl[1] = PARM_DEFAULT_TX_RATE_5GHZ;
597
598 lp->RTSThreshold = PARM_RTS_THRESHOLD;
599
600 /* Need to determine how to handle the new bands for 5GHz */
601 lp->MulticastRate[0] = PARM_DEFAULT_MULTICAST_RATE_2GHZ;
602 lp->MulticastRate[1] = PARM_DEFAULT_MULTICAST_RATE_5GHZ;
603
604 if ( strchr( "Yy", PARM_MICROWAVE_ROBUSTNESS[0] ) != NULL ) {
605 lp->MicrowaveRobustness = 1;
606 } else {
607 lp->MicrowaveRobustness = 0;
608 }
609 if ( PARM_DESIRED_SSID && ( strlen( PARM_DESIRED_SSID ) <= HCF_MAX_NAME_LEN )) {
610 strcpy( lp->NetworkName, PARM_DESIRED_SSID );
611 }
612 if ( PARM_OWN_SSID && ( strlen( PARM_OWN_SSID ) <= HCF_MAX_NAME_LEN )) {
613 strcpy( lp->NetworkName, PARM_OWN_SSID );
614 }
615 if ( PARM_OWN_NAME && ( strlen( PARM_OWN_NAME ) <= HCF_MAX_NAME_LEN )) {
616 strcpy( lp->StationName, PARM_OWN_NAME );
617 }
618 lp->EnableEncryption = PARM_ENABLE_ENCRYPTION;
619 if ( PARM_KEY1 && ( strlen( PARM_KEY1 ) <= MAX_KEY_LEN )) {
620 strcpy( lp->Key1, PARM_KEY1 );
621 }
622 if ( PARM_KEY2 && ( strlen( PARM_KEY2 ) <= MAX_KEY_LEN )) {
623 strcpy( lp->Key2, PARM_KEY2 );
624 }
625 if ( PARM_KEY3 && ( strlen( PARM_KEY3 ) <= MAX_KEY_LEN )) {
626 strcpy( lp->Key3, PARM_KEY3 );
627 }
628 if ( PARM_KEY4 && ( strlen( PARM_KEY4 ) <= MAX_KEY_LEN )) {
629 strcpy( lp->Key4, PARM_KEY4 );
630 }
631
632 lp->TransmitKeyID = PARM_TX_KEY;
633
634 key_string2key( lp->Key1, &(lp->DefaultKeys.key[0] ));
635 key_string2key( lp->Key2, &(lp->DefaultKeys.key[1] ));
636 key_string2key( lp->Key3, &(lp->DefaultKeys.key[2] ));
637 key_string2key( lp->Key4, &(lp->DefaultKeys.key[3] ));
638
639 lp->DownloadFirmware = 1 ; //;?to be upgraded PARM_DOWNLOAD_FIRMWARE;
640 lp->AuthKeyMgmtSuite = PARM_AUTH_KEY_MGMT_SUITE;
641
642 if ( strchr( "Yy", PARM_LOAD_BALANCING[0] ) != NULL ) {
643 lp->loadBalancing = 1;
644 } else {
645 lp->loadBalancing = 0;
646 }
647
648 if ( strchr( "Yy", PARM_MEDIUM_DISTRIBUTION[0] ) != NULL ) {
649 lp->mediumDistribution = 1;
650 } else {
651 lp->mediumDistribution = 0;
652 }
653
654 lp->txPowLevel = PARM_TX_POW_LEVEL;
655
656 lp->srsc[0] = PARM_SRSC_2GHZ;
657 lp->srsc[1] = PARM_SRSC_5GHZ;
658 lp->brsc[0] = PARM_BRSC_2GHZ;
659 lp->brsc[1] = PARM_BRSC_5GHZ;
660 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA
661 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
662 lp->PortType = PARM_PORT_TYPE;
663 lp->MaxSleepDuration = PARM_MAX_SLEEP;
664 lp->authentication = PARM_AUTHENTICATION;
665 lp->atimWindow = PARM_OWN_ATIM_WINDOW;
666 lp->holdoverDuration = PARM_PM_HOLDOVER_DURATION;
667 lp->PMEnabled = PARM_PM_ENABLED; //;?
668 if ( strchr( "Yy", PARM_CREATE_IBSS[0] ) != NULL ) {
669 lp->CreateIBSS = 1;
670 } else {
671 lp->CreateIBSS = 0;
672 }
673 if ( strchr( "Nn", PARM_MULTICAST_RX[0] ) != NULL ) {
674 lp->MulticastReceive = 0;
675 } else {
676 lp->MulticastReceive = 1;
677 }
678 if ( strchr( "Yy", PARM_PROMISCUOUS_MODE[0] ) != NULL ) {
679 lp->promiscuousMode = 1;
680 } else {
681 lp->promiscuousMode = 0;
682 }
683 for( i = 0; i < ETH_ALEN; i++ ) {
684 lp->MACAddress[i] = PARM_NETWORK_ADDR[i];
685 }
686
687 lp->connectionControl = PARM_CONNECTION_CONTROL;
688
689 #endif /* HCF_STA */
690 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
691 //;?should we restore this to allow smaller memory footprint
692 lp->DTIMPeriod = PARM_OWN_DTIM_PERIOD;
693
694 if ( strchr( "Yy", PARM_REJECT_ANY[0] ) != NULL ) {
695 lp->RejectAny = 1;
696 } else {
697 lp->RejectAny = 0;
698 }
699 if ( strchr( "Nn", PARM_EXCLUDE_UNENCRYPTED[0] ) != NULL ) {
700 lp->ExcludeUnencrypted = 0;
701 } else {
702 lp->ExcludeUnencrypted = 1;
703 }
704 if ( strchr( "Yy", PARM_MULTICAST_PM_BUFFERING[0] ) != NULL ) {
705 lp->multicastPMBuffering = 1;
706 } else {
707 lp->multicastPMBuffering = 0;
708 }
709 if ( strchr( "Yy", PARM_INTRA_BSS_RELAY[0] ) != NULL ) {
710 lp->intraBSSRelay = 1;
711 } else {
712 lp->intraBSSRelay = 0;
713 }
714
715 lp->ownBeaconInterval = PARM_OWN_BEACON_INTERVAL;
716 lp->coexistence = PARM_COEXISTENCE;
717
718 #ifdef USE_WDS
719 lp->wds_port[0].rtsThreshold = PARM_RTS_THRESHOLD1;
720 lp->wds_port[1].rtsThreshold = PARM_RTS_THRESHOLD2;
721 lp->wds_port[2].rtsThreshold = PARM_RTS_THRESHOLD3;
722 lp->wds_port[3].rtsThreshold = PARM_RTS_THRESHOLD4;
723 lp->wds_port[4].rtsThreshold = PARM_RTS_THRESHOLD5;
724 lp->wds_port[5].rtsThreshold = PARM_RTS_THRESHOLD6;
725 lp->wds_port[0].txRateCntl = PARM_TX_RATE1;
726 lp->wds_port[1].txRateCntl = PARM_TX_RATE2;
727 lp->wds_port[2].txRateCntl = PARM_TX_RATE3;
728 lp->wds_port[3].txRateCntl = PARM_TX_RATE4;
729 lp->wds_port[4].txRateCntl = PARM_TX_RATE5;
730 lp->wds_port[5].txRateCntl = PARM_TX_RATE6;
731
732 for( i = 0; i < ETH_ALEN; i++ ) {
733 lp->wds_port[0].wdsAddress[i] = PARM_WDS_ADDRESS1[i];
734 }
735 for( i = 0; i < ETH_ALEN; i++ ) {
736 lp->wds_port[1].wdsAddress[i] = PARM_WDS_ADDRESS2[i];
737 }
738 for( i = 0; i < ETH_ALEN; i++ ) {
739 lp->wds_port[2].wdsAddress[i] = PARM_WDS_ADDRESS3[i];
740 }
741 for( i = 0; i < ETH_ALEN; i++ ) {
742 lp->wds_port[3].wdsAddress[i] = PARM_WDS_ADDRESS4[i];
743 }
744 for( i = 0; i < ETH_ALEN; i++ ) {
745 lp->wds_port[4].wdsAddress[i] = PARM_WDS_ADDRESS5[i];
746 }
747 for( i = 0; i < ETH_ALEN; i++ ) {
748 lp->wds_port[5].wdsAddress[i] = PARM_WDS_ADDRESS6[i];
749 }
750 #endif /* USE_WDS */
751 #endif /* HCF_AP */
752 #ifdef USE_RTS
753 if ( strchr( "Yy", useRTS[0] ) != NULL ) {
754 lp->useRTS = 1;
755 } else {
756 lp->useRTS = 0;
757 }
758 #endif /* USE_RTS */
759
760
761 /* END NEW PARAMETERS */
762
763
764 wl_lock( lp, &flags );
765
766 /* Initialize the portState variable */
767 lp->portState = WVLAN_PORT_STATE_DISABLED;
768
769 /* Initialize the ScanResult struct */
770 memset( &( lp->scan_results ), 0, sizeof( lp->scan_results ));
771 lp->scan_results.scan_complete = FALSE;
772
773 /* Initialize the ProbeResult struct */
774 memset( &( lp->probe_results ), 0, sizeof( lp->probe_results ));
775 lp->probe_results.scan_complete = FALSE;
776 lp->probe_num_aps = 0;
777
778
779 /* Initialize Tx queue stuff */
780 memset( lp->txList, 0, sizeof( lp->txList ));
781
782 INIT_LIST_HEAD( &( lp->txFree ));
783
784 lp->txF.skb = NULL;
785 lp->txF.port = 0;
786
787
788 for( i = 0; i < DEFAULT_NUM_TX_FRAMES; i++ ) {
789 list_add_tail( &( lp->txList[i].node ), &( lp->txFree ));
790 }
791
792
793 for( i = 0; i < WVLAN_MAX_TX_QUEUES; i++ ) {
794 INIT_LIST_HEAD( &( lp->txQ[i] ));
795 }
796
797 lp->netif_queue_on = TRUE;
798 lp->txQ_count = 0;
799 /* Initialize the use_dma element in the adapter structure. Not sure if
800 this should be a compile-time or run-time configurable. So for now,
801 implement as run-time and just define here */
802 #ifdef WARP
803 #ifdef ENABLE_DMA
804 DBG_TRACE( DbgInfo, "HERMES 2.5 BUSMASTER DMA MODE\n" );
805 lp->use_dma = 1;
806 #else
807 DBG_TRACE( DbgInfo, "HERMES 2.5 PORT I/O MODE\n" );
808 lp->use_dma = 0;
809 #endif // ENABLE_DMA
810 #endif // WARP
811
812 /* Register the ISR handler information here, so that it's not done
813 repeatedly in the ISR */
814 tasklet_init(&lp->task, wl_isr_handler, (unsigned long)lp);
815
816 /* Connect to the adapter */
817 DBG_TRACE( DbgInfo, "Calling hcf_connect()...\n" );
818 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
819 //HCF_ERR_INCOMP_FW is acceptable, because download must still take place
820 //HCF_ERR_INCOMP_PRI is not acceptable
821 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
822 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
823 wl_unlock( lp, &flags );
824 goto hcf_failed;
825 }
826
827 //;?should set HCF_version and how about driver_stat
828 lp->driverInfo.IO_address = dev->base_addr;
829 lp->driverInfo.IO_range = HCF_NUM_IO_PORTS; //;?conditionally 0x40 or 0x80 seems better
830 lp->driverInfo.IRQ_number = dev->irq;
831 lp->driverInfo.card_stat = lp->hcfCtx.IFB_CardStat;
832 //;? what happened to frame_type
833
834 /* Fill in the driver identity structure */
835 lp->driverIdentity.len = ( sizeof( lp->driverIdentity ) / sizeof( hcf_16 )) - 1;
836 lp->driverIdentity.typ = CFG_DRV_IDENTITY;
837 lp->driverIdentity.comp_id = DRV_IDENTITY;
838 lp->driverIdentity.variant = DRV_VARIANT;
839 lp->driverIdentity.version_major = DRV_MAJOR_VERSION;
840 lp->driverIdentity.version_minor = DRV_MINOR_VERSION;
841
842
843 /* Start the card here - This needs to be done in order to get the
844 MAC address for the network layer */
845 DBG_TRACE( DbgInfo, "Calling wvlan_go() to perform a card reset...\n" );
846 hcf_status = wl_go( lp );
847
848 if ( hcf_status != HCF_SUCCESS ) {
849 DBG_ERROR( DbgInfo, "wl_go() failed\n" );
850 wl_unlock( lp, &flags );
851 goto hcf_failed;
852 }
853
854 /* Certain RIDs must be set before enabling the ports */
855 wl_put_ltv_init( lp );
856
857 #if 0 //;?why was this already commented out in wl_lkm_720
858 /* Enable the ports */
859 if ( wl_adapter_is_open( lp->dev )) {
860 /* Enable the ports */
861 DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
862 hcf_status = wl_enable( lp );
863
864 if ( hcf_status != HCF_SUCCESS ) {
865 DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", hcf_status );
866 }
867
868 #if (HCF_TYPE) & HCF_TYPE_AP
869 DBG_TRACE( DbgInfo, "Enabling WDS Ports\n" );
870 //wl_enable_wds_ports( lp );
871 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
872
873 }
874 #endif
875
876 /* Fill out the MAC address information in the net_device struct */
877 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN );
878 dev->addr_len = ETH_ALEN;
879
880 lp->is_registered = TRUE;
881
882 #ifdef USE_PROFILE
883 /* Parse the config file for the sake of creating WDS ports if WDS is
884 configured there but not in the module options */
885 parse_config( dev );
886 #endif /* USE_PROFILE */
887
888 /* If we're going into AP Mode, register the "virtual" ethernet devices
889 needed for WDS */
890 WL_WDS_NETDEV_REGISTER( lp );
891
892 /* Reset the DownloadFirmware variable in the private struct. If the
893 config file is not used, this will not matter; if it is used, it
894 will be reparsed in wl_open(). This is done because logic in wl_open
895 used to check if a firmware download is needed is broken by parsing
896 the file here; however, this parsing is needed to register WDS ports
897 in AP mode, if they are configured */
898 lp->DownloadFirmware = WVLAN_DRV_MODE_STA; //;?download_firmware;
899
900 #ifdef USE_RTS
901 if ( lp->useRTS == 1 ) {
902 DBG_TRACE( DbgInfo, "ENTERING RTS MODE...\n" );
903 wl_act_int_off( lp );
904 lp->is_handling_int = WL_NOT_HANDLING_INT; // Not handling interrupts anymore
905
906 wl_disable( lp );
907
908 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT);
909 }
910 #endif /* USE_RTS */
911
912 wl_unlock( lp, &flags );
913
914 DBG_TRACE( DbgInfo, "%s: Wireless, io_addr %#03lx, irq %d, ""mac_address ",
915 dev->name, dev->base_addr, dev->irq );
916
917 for( i = 0; i < ETH_ALEN; i++ ) {
918 printk( "%02X%c", dev->dev_addr[i], (( i < ( ETH_ALEN-1 )) ? ':' : '\n' ));
919 }
920
921 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
922 create_proc_read_entry( "wlags", 0, NULL, scull_read_procmem, dev );
923 proc_mkdir("driver/wlags49", 0);
924 proc_write("driver/wlags49/wlags49_type", write_int, &lp->wlags49_type);
925 #endif /* SCULL_USE_PROC */
926
927 DBG_LEAVE( DbgInfo );
928 return result;
929
930 hcf_failed:
931 wl_hcf_error( dev, hcf_status );
932
933 failed:
934
935 DBG_ERROR( DbgInfo, "wl_insert() FAILED\n" );
936
937 if ( lp->is_registered == TRUE ) {
938 lp->is_registered = FALSE;
939 }
940
941 WL_WDS_NETDEV_DEREGISTER( lp );
942
943 result = -EFAULT;
944
945
946 DBG_LEAVE( DbgInfo );
947 return result;
948 } // wl_insert
949 /*============================================================================*/
950
951
952 /*******************************************************************************
953 * wl_reset()
954 *******************************************************************************
955 *
956 * DESCRIPTION:
957 *
958 * Reset the adapter.
959 *
960 * PARAMETERS:
961 *
962 * dev - a pointer to the net_device struct of the wireless device
963 *
964 * RETURNS:
965 *
966 * an HCF status code
967 *
968 ******************************************************************************/
969 int wl_reset(struct net_device *dev)
970 {
971 struct wl_private *lp = wl_priv(dev);
972 int hcf_status = HCF_SUCCESS;
973 /*------------------------------------------------------------------------*/
974 DBG_FUNC( "wl_reset" );
975 DBG_ENTER( DbgInfo );
976 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
977 DBG_PARAM( DbgInfo, "dev->base_addr", "(%#03lx)", dev->base_addr );
978
979 /*
980 * The caller should already have a lock and
981 * disable the interrupts, we do not lock here,
982 * nor do we enable/disable interrupts!
983 */
984
985 DBG_TRACE( DbgInfo, "Device Base Address: %#03lx\n", dev->base_addr );
986 if ( dev->base_addr ) {
987 /* Shutdown the adapter. */
988 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
989
990 /* Reset the driver information. */
991 lp->txBytes = 0;
992
993 /* Connect to the adapter. */
994 hcf_status = hcf_connect( &lp->hcfCtx, dev->base_addr );
995 if ( hcf_status != HCF_SUCCESS && hcf_status != HCF_ERR_INCOMP_FW ) {
996 DBG_ERROR( DbgInfo, "hcf_connect() failed, status: 0x%x\n", hcf_status );
997 goto out;
998 }
999
1000 /* Check if firmware is present, if not change state */
1001 if ( hcf_status == HCF_ERR_INCOMP_FW ) {
1002 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1003 }
1004
1005 /* Initialize the portState variable */
1006 lp->portState = WVLAN_PORT_STATE_DISABLED;
1007
1008 /* Restart the adapter. */
1009 hcf_status = wl_go( lp );
1010 if ( hcf_status != HCF_SUCCESS ) {
1011 DBG_ERROR( DbgInfo, "wl_go() failed, status: 0x%x\n", hcf_status );
1012 goto out;
1013 }
1014
1015 /* Certain RIDs must be set before enabling the ports */
1016 wl_put_ltv_init( lp );
1017 } else {
1018 DBG_ERROR( DbgInfo, "Device Base Address INVALID!!!\n" );
1019 }
1020
1021 out:
1022 DBG_LEAVE( DbgInfo );
1023 return hcf_status;
1024 } // wl_reset
1025 /*============================================================================*/
1026
1027
1028 /*******************************************************************************
1029 * wl_go()
1030 *******************************************************************************
1031 *
1032 * DESCRIPTION:
1033 *
1034 * Reset the adapter.
1035 *
1036 * PARAMETERS:
1037 *
1038 * dev - a pointer to the net_device struct of the wireless device
1039 *
1040 * RETURNS:
1041 *
1042 * an HCF status code
1043 *
1044 ******************************************************************************/
1045 int wl_go( struct wl_private *lp )
1046 {
1047 int hcf_status = HCF_SUCCESS;
1048 char *cp = NULL; //fw_image
1049 int retries = 0;
1050 /*------------------------------------------------------------------------*/
1051 DBG_FUNC( "wl_go" );
1052 DBG_ENTER( DbgInfo );
1053
1054 hcf_status = wl_disable( lp );
1055 if ( hcf_status != HCF_SUCCESS ) {
1056 DBG_TRACE( DbgInfo, "Disable port 0 failed: 0x%x\n", hcf_status );
1057
1058 while (( hcf_status != HCF_SUCCESS ) && (retries < 10)) {
1059 retries++;
1060 hcf_status = wl_disable( lp );
1061 }
1062 if ( hcf_status == HCF_SUCCESS ) {
1063 DBG_TRACE( DbgInfo, "Disable port 0 succes : %d retries\n", retries );
1064 } else {
1065 DBG_TRACE( DbgInfo, "Disable port 0 failed after: %d retries\n", retries );
1066 }
1067 }
1068
1069 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
1070 //DBG_TRACE( DbgInfo, "Disabling WDS Ports\n" );
1071 //wl_disable_wds_ports( lp );
1072 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1073
1074 //;?what was the purpose of this
1075 // /* load the appropriate firmware image, depending on driver mode */
1076 // lp->ltvRecord.len = ( sizeof( CFG_RANGE20_STRCT ) / sizeof( hcf_16 )) - 1;
1077 // lp->ltvRecord.typ = CFG_DRV_ACT_RANGES_PRI;
1078 // hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1079
1080 #if BIN_DL
1081 if ( strlen( lp->fw_image_filename ) ) {
1082 mm_segment_t fs;
1083 int file_desc;
1084 int rc;
1085
1086 DBG_TRACE( DbgInfo, "F/W image:%s:\n", lp->fw_image_filename );
1087 /* Obtain a user-space process context, storing the original context */
1088 fs = get_fs( );
1089 set_fs( get_ds( ));
1090 file_desc = open( lp->fw_image_filename, O_RDONLY, 0 );
1091 if ( file_desc == -1 ) {
1092 DBG_ERROR( DbgInfo, "No image file found\n" );
1093 } else {
1094 DBG_TRACE( DbgInfo, "F/W image file found\n" );
1095 #define DHF_ALLOC_SIZE 96000 //just below 96K, let's hope it suffices for now and for the future
1096 cp = (char*)vmalloc( DHF_ALLOC_SIZE );
1097 if ( cp == NULL ) {
1098 DBG_ERROR( DbgInfo, "error in vmalloc\n" );
1099 } else {
1100 rc = read( file_desc, cp, DHF_ALLOC_SIZE );
1101 if ( rc == DHF_ALLOC_SIZE ) {
1102 DBG_ERROR( DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE );
1103 } else if ( rc > 0 ) {
1104 DBG_TRACE( DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp );
1105 rc = read( file_desc, &cp[rc], 1 );
1106 if ( rc == 0 ) { //;/change to an until-loop at rc<=0
1107 DBG_TRACE( DbgInfo, "no more to read\n" );
1108 }
1109 }
1110 if ( rc != 0 ) {
1111 DBG_ERROR( DbgInfo, "file not read in one swoop or other error"\
1112 ", give up, too complicated, rc = %0X\n", rc );
1113 DBG_ERROR( DbgInfo, "still have to change code to get a real download now !!!!!!!!\n" );
1114 } else {
1115 DBG_TRACE( DbgInfo, "before dhf_download_binary\n" );
1116 hcf_status = dhf_download_binary( (memimage *)cp );
1117 DBG_TRACE( DbgInfo, "after dhf_download_binary, before dhf_download_fw\n" );
1118 //;?improve error flow/handling
1119 hcf_status = dhf_download_fw( &lp->hcfCtx, (memimage *)cp );
1120 DBG_TRACE( DbgInfo, "after dhf_download_fw\n" );
1121 }
1122 vfree( cp );
1123 }
1124 close( file_desc );
1125 }
1126 set_fs( fs ); /* Return to the original context */
1127 }
1128 #endif // BIN_DL
1129
1130 /* If firmware is present but the type is unknown then download anyway */
1131 if ( (lp->firmware_present == WL_FRIMWARE_PRESENT)
1132 &&
1133 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_STA )
1134 &&
1135 ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) != COMP_ID_FW_AP ) ) {
1136 /* Unknown type, download needed. */
1137 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
1138 }
1139
1140 if(lp->firmware_present == WL_FRIMWARE_NOT_PRESENT)
1141 {
1142 if ( cp == NULL ) {
1143 DBG_TRACE( DbgInfo, "Downloading STA firmware...\n" );
1144 // hcf_status = dhf_download_fw( &lp->hcfCtx, &station );
1145 hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image );
1146 }
1147 if ( hcf_status != HCF_SUCCESS ) {
1148 DBG_ERROR( DbgInfo, "Firmware Download failed\n" );
1149 DBG_LEAVE( DbgInfo );
1150 return hcf_status;
1151 }
1152 }
1153 /* Report the FW versions */
1154 //;?obsolete, use the available IFB info:: wl_get_pri_records( lp );
1155 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1156 DBG_TRACE( DbgInfo, "downloaded station F/W\n" );
1157 } else if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1158 DBG_TRACE( DbgInfo, "downloaded AP F/W\n" );
1159 } else {
1160 DBG_ERROR( DbgInfo, "unknown F/W type\n" );
1161 }
1162
1163 /*
1164 * Downloaded, no need to repeat this next time, assume the
1165 * contents stays in the card until it is powered off. Note we
1166 * do not switch firmware on the fly, the firmware is fixed in
1167 * the driver for now.
1168 */
1169 lp->firmware_present = WL_FRIMWARE_PRESENT;
1170
1171 DBG_TRACE( DbgInfo, "ComponentID:%04x variant:%04x major:%04x minor:%04x\n",
1172 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ),
1173 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.variant ),
1174 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_major ),
1175 CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.version_minor ));
1176
1177 /* now we wil get the MAC address of the card */
1178 lp->ltvRecord.len = 4;
1179 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1180 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1181 } else
1182 {
1183 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1184 }
1185 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1186 if ( hcf_status != HCF_SUCCESS ) {
1187 DBG_ERROR( DbgInfo, "Could not retrieve MAC address\n" );
1188 DBG_LEAVE( DbgInfo );
1189 return hcf_status;
1190 }
1191 memcpy( lp->MACAddress, &lp->ltvRecord.u.u8[0], ETH_ALEN );
1192 DBG_TRACE( DbgInfo, "Card MAC Address: %s\n", DbgHwAddr( lp->MACAddress ));
1193
1194 /* Write out configuration to the device, enable, and reconnect. However,
1195 only reconnect if in AP mode. For STA mode, need to wait for passive scan
1196 completion before a connect can be issued */
1197 wl_put_ltv( lp );
1198 /* Enable the ports */
1199 hcf_status = wl_enable( lp );
1200
1201 if ( lp->DownloadFirmware == WVLAN_DRV_MODE_AP ) {
1202 #ifdef USE_WDS
1203 wl_enable_wds_ports( lp );
1204 #endif // USE_WDS
1205 hcf_status = wl_connect( lp );
1206 }
1207 DBG_LEAVE( DbgInfo );
1208 return hcf_status;
1209 } // wl_go
1210 /*============================================================================*/
1211
1212
1213 /*******************************************************************************
1214 * wl_set_wep_keys()
1215 *******************************************************************************
1216 *
1217 * DESCRIPTION:
1218 *
1219 * Write TxKeyID and WEP keys to the adapter. This is separated from
1220 * wl_apply() to allow dynamic WEP key updates through the wireless
1221 * extensions.
1222 *
1223 * PARAMETERS:
1224 *
1225 * lp - a pointer to the wireless adapter's private structure
1226 *
1227 * RETURNS:
1228 *
1229 * N/A
1230 *
1231 ******************************************************************************/
1232 void wl_set_wep_keys( struct wl_private *lp )
1233 {
1234 int count = 0;
1235 /*------------------------------------------------------------------------*/
1236 DBG_FUNC( "wl_set_wep_keys" );
1237 DBG_ENTER( DbgInfo );
1238 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1239 if ( lp->EnableEncryption ) {
1240 /* NOTE: CFG_CNF_ENCRYPTION is set in wl_put_ltv() as it's a static
1241 RID */
1242
1243 /* set TxKeyID */
1244 lp->ltvRecord.len = 2;
1245 lp->ltvRecord.typ = CFG_TX_KEY_ID;
1246 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE(lp->TransmitKeyID - 1);
1247
1248 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1249
1250 DBG_TRACE( DbgInfo, "Key 1 len: %d\n", lp->DefaultKeys.key[0].len );
1251 DBG_TRACE( DbgInfo, "Key 2 len: %d\n", lp->DefaultKeys.key[1].len );
1252 DBG_TRACE( DbgInfo, "Key 3 len: %d\n", lp->DefaultKeys.key[2].len );
1253 DBG_TRACE( DbgInfo, "Key 4 len: %d\n", lp->DefaultKeys.key[3].len );
1254
1255 /* write keys */
1256 lp->DefaultKeys.len = sizeof( lp->DefaultKeys ) / sizeof( hcf_16 ) - 1;
1257 lp->DefaultKeys.typ = CFG_DEFAULT_KEYS;
1258
1259 /* endian translate the appropriate key information */
1260 for( count = 0; count < MAX_KEYS; count++ ) {
1261 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1262 }
1263
1264 hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->DefaultKeys ));
1265
1266 /* Reverse the above endian translation, since these keys are accessed
1267 elsewhere */
1268 for( count = 0; count < MAX_KEYS; count++ ) {
1269 lp->DefaultKeys.key[count].len = CNV_INT_TO_LITTLE( lp->DefaultKeys.key[count].len );
1270 }
1271
1272 DBG_NOTICE( DbgInfo, "encrypt: %d, ID: %d\n", lp->EnableEncryption, lp->TransmitKeyID );
1273 DBG_NOTICE( DbgInfo, "set key: %s(%d) [%d]\n", lp->DefaultKeys.key[lp->TransmitKeyID-1].key, lp->DefaultKeys.key[lp->TransmitKeyID-1].len, lp->TransmitKeyID-1 );
1274 }
1275
1276 DBG_LEAVE( DbgInfo );
1277 } // wl_set_wep_keys
1278 /*============================================================================*/
1279
1280
1281 /*******************************************************************************
1282 * wl_apply()
1283 *******************************************************************************
1284 *
1285 * DESCRIPTION:
1286 *
1287 * Write the parameters to the adapter. (re-)enables the card if device is
1288 * open. Returns hcf_status of hcf_enable().
1289 *
1290 * PARAMETERS:
1291 *
1292 * lp - a pointer to the wireless adapter's private structure
1293 *
1294 * RETURNS:
1295 *
1296 * an HCF status code
1297 *
1298 ******************************************************************************/
1299 int wl_apply(struct wl_private *lp)
1300 {
1301 int hcf_status = HCF_SUCCESS;
1302 /*------------------------------------------------------------------------*/
1303 DBG_FUNC( "wl_apply" );
1304 DBG_ENTER( DbgInfo );
1305 DBG_ASSERT( lp != NULL);
1306 DBG_PARAM( DbgInfo, "lp", "%s (0x%p)", lp->dev->name, lp );
1307
1308 if ( !( lp->flags & WVLAN2_UIL_BUSY )) {
1309 /* The adapter parameters have changed:
1310 disable card
1311 reload parameters
1312 enable card
1313 */
1314
1315 if ( wl_adapter_is_open( lp->dev )) {
1316 /* Disconnect and disable if necessary */
1317 hcf_status = wl_disconnect( lp );
1318 if ( hcf_status != HCF_SUCCESS ) {
1319 DBG_ERROR( DbgInfo, "Disconnect failed\n" );
1320 DBG_LEAVE( DbgInfo );
1321 return -1;
1322 }
1323 hcf_status = wl_disable( lp );
1324 if ( hcf_status != HCF_SUCCESS ) {
1325 DBG_ERROR( DbgInfo, "Disable failed\n" );
1326 DBG_LEAVE( DbgInfo );
1327 return -1;
1328 } else {
1329 /* Write out configuration to the device, enable, and reconnect.
1330 However, only reconnect if in AP mode. For STA mode, need to
1331 wait for passive scan completion before a connect can be
1332 issued */
1333 hcf_status = wl_put_ltv( lp );
1334
1335 if ( hcf_status == HCF_SUCCESS ) {
1336 hcf_status = wl_enable( lp );
1337
1338 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1339 hcf_status = wl_connect( lp );
1340 }
1341 } else {
1342 DBG_WARNING( DbgInfo, "wl_put_ltv() failed\n" );
1343 }
1344 }
1345 }
1346 }
1347
1348 DBG_LEAVE( DbgInfo );
1349 return hcf_status;
1350 } // wl_apply
1351 /*============================================================================*/
1352
1353
1354 /*******************************************************************************
1355 * wl_put_ltv_init()
1356 *******************************************************************************
1357 *
1358 * DESCRIPTION:
1359 *
1360 * Used to set basic parameters for card initialization.
1361 *
1362 * PARAMETERS:
1363 *
1364 * lp - a pointer to the wireless adapter's private structure
1365 *
1366 * RETURNS:
1367 *
1368 * an HCF status code
1369 *
1370 ******************************************************************************/
1371 int wl_put_ltv_init( struct wl_private *lp )
1372 {
1373 int i;
1374 int hcf_status;
1375 CFG_RID_LOG_STRCT *RidLog;
1376 /*------------------------------------------------------------------------*/
1377 DBG_FUNC( "wl_put_ltv_init" );
1378 DBG_ENTER( DbgInfo );
1379 if ( lp == NULL ) {
1380 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1381 DBG_LEAVE( DbgInfo );
1382 return -1;
1383 }
1384 /* DMA/IO */
1385 lp->ltvRecord.len = 2;
1386 lp->ltvRecord.typ = CFG_CNTL_OPT;
1387
1388 /* The Card Services build must ALWAYS configure for 16-bit I/O. PCI or
1389 CardBus can be set to either 16/32 bit I/O, or Bus Master DMA, but only
1390 for Hermes-2.5 */
1391 #ifdef BUS_PCMCIA
1392 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_16BIT );
1393 #else
1394 if ( lp->use_dma ) {
1395 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( USE_DMA );
1396 } else {
1397 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1398 }
1399
1400 #endif
1401 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1402 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT : 0x%04x\n",
1403 lp->ltvRecord.u.u16[0] );
1404 DBG_TRACE( DbgInfo, "CFG_CNTL_OPT result : 0x%04x\n",
1405 hcf_status );
1406
1407 /* Register the list of RIDs on which asynchronous notification is
1408 required. Note that this mechanism replaces the mailbox, so the mailbox
1409 can be queried by the host (if desired) without contention from us */
1410 i=0;
1411
1412 lp->RidList[i].len = sizeof( lp->ProbeResp );
1413 lp->RidList[i].typ = CFG_ACS_SCAN;
1414 lp->RidList[i].bufp = (wci_recordp)&lp->ProbeResp;
1415 //lp->ProbeResp.infoType = 0xFFFF;
1416 i++;
1417
1418 lp->RidList[i].len = sizeof( lp->assoc_stat );
1419 lp->RidList[i].typ = CFG_ASSOC_STAT;
1420 lp->RidList[i].bufp = (wci_recordp)&lp->assoc_stat;
1421 lp->assoc_stat.len = 0xFFFF;
1422 i++;
1423
1424 lp->RidList[i].len = 4;
1425 lp->RidList[i].typ = CFG_UPDATED_INFO_RECORD;
1426 lp->RidList[i].bufp = (wci_recordp)&lp->updatedRecord;
1427 lp->updatedRecord.len = 0xFFFF;
1428 i++;
1429
1430 lp->RidList[i].len = sizeof( lp->sec_stat );
1431 lp->RidList[i].typ = CFG_SECURITY_STAT;
1432 lp->RidList[i].bufp = (wci_recordp)&lp->sec_stat;
1433 lp->sec_stat.len = 0xFFFF;
1434 i++;
1435
1436 lp->RidList[i].typ = 0; // Terminate List
1437
1438 RidLog = (CFG_RID_LOG_STRCT *)&lp->ltvRecord;
1439 RidLog->len = 3;
1440 RidLog->typ = CFG_REG_INFO_LOG;
1441 RidLog->recordp = (RID_LOGP)&lp->RidList[0];
1442
1443 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1444 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG\n" );
1445 DBG_TRACE( DbgInfo, "CFG_REG_INFO_LOG result : 0x%04x\n",
1446 hcf_status );
1447 DBG_LEAVE( DbgInfo );
1448 return hcf_status;
1449 } // wl_put_ltv_init
1450 /*============================================================================*/
1451
1452
1453 /*******************************************************************************
1454 * wl_put_ltv()
1455 *******************************************************************************
1456 *
1457 * DESCRIPTION:
1458 *
1459 * Used by wvlan_apply() and wvlan_go to set the card's configuration.
1460 *
1461 * PARAMETERS:
1462 *
1463 * lp - a pointer to the wireless adapter's private structure
1464 *
1465 * RETURNS:
1466 *
1467 * an HCF status code
1468 *
1469 ******************************************************************************/
1470 int wl_put_ltv( struct wl_private *lp )
1471 {
1472 int len;
1473 int hcf_status;
1474 /*------------------------------------------------------------------------*/
1475 DBG_FUNC( "wl_put_ltv" );
1476 DBG_ENTER( DbgInfo );
1477
1478 if ( lp == NULL ) {
1479 DBG_ERROR( DbgInfo, "lp pointer is NULL\n" );
1480 return -1;
1481 }
1482 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1483 lp->maxPort = 6; //;?why set this here and not as part of download process
1484 } else {
1485 lp->maxPort = 0;
1486 }
1487
1488 /* Send our configuration to the card. Perform any endian translation
1489 necessary */
1490 /* Register the Mailbox; VxWorks does this elsewhere; why;? */
1491 lp->ltvRecord.len = 4;
1492 lp->ltvRecord.typ = CFG_REG_MB;
1493 lp->ltvRecord.u.u32[0] = (u_long)&( lp->mailbox );
1494 lp->ltvRecord.u.u16[2] = ( MB_SIZE / sizeof( hcf_16 ));
1495 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1496
1497 /* Max Data Length */
1498 lp->ltvRecord.len = 2;
1499 lp->ltvRecord.typ = CFG_CNF_MAX_DATA_LEN;
1500 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( HCF_MAX_PACKET_SIZE );
1501 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1502
1503 /* System Scale / Distance between APs */
1504 lp->ltvRecord.len = 2;
1505 lp->ltvRecord.typ = CFG_CNF_SYSTEM_SCALE;
1506 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DistanceBetweenAPs );
1507 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1508
1509 /* Channel */
1510 if ( lp->CreateIBSS && ( lp->Channel == 0 )) {
1511 DBG_TRACE( DbgInfo, "Create IBSS" );
1512 lp->Channel = 10;
1513 }
1514 lp->ltvRecord.len = 2;
1515 lp->ltvRecord.typ = CFG_CNF_OWN_CHANNEL;
1516 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->Channel );
1517 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1518
1519 /* Microwave Robustness */
1520 lp->ltvRecord.len = 2;
1521 lp->ltvRecord.typ = CFG_CNF_MICRO_WAVE;
1522 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MicrowaveRobustness );
1523 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1524
1525 /* Load Balancing */
1526 lp->ltvRecord.len = 2;
1527 lp->ltvRecord.typ = CFG_CNF_LOAD_BALANCING;
1528 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->loadBalancing );
1529 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1530
1531 /* Medium Distribution */
1532 lp->ltvRecord.len = 2;
1533 lp->ltvRecord.typ = CFG_CNF_MEDIUM_DISTRIBUTION;
1534 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->mediumDistribution );
1535 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1536 /* Country Code */
1537
1538 #ifdef WARP
1539 /* Tx Power Level (for supported cards) */
1540 lp->ltvRecord.len = 2;
1541 lp->ltvRecord.typ = CFG_CNF_TX_POW_LVL;
1542 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->txPowLevel );
1543 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1544
1545 /* Short Retry Limit */
1546 /*lp->ltvRecord.len = 2;
1547 lp->ltvRecord.typ = 0xFC32;
1548 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->shortRetryLimit );
1549 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1550 */
1551
1552 /* Long Retry Limit */
1553 /*lp->ltvRecord.len = 2;
1554 lp->ltvRecord.typ = 0xFC33;
1555 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->longRetryLimit );
1556 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1557 */
1558
1559 /* Supported Rate Set Control */
1560 lp->ltvRecord.len = 3;
1561 lp->ltvRecord.typ = CFG_SUPPORTED_RATE_SET_CNTL; //0xFC88;
1562 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->srsc[0] );
1563 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->srsc[1] );
1564 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1565
1566 /* Basic Rate Set Control */
1567 lp->ltvRecord.len = 3;
1568 lp->ltvRecord.typ = CFG_BASIC_RATE_SET_CNTL; //0xFC89;
1569 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->brsc[0] );
1570 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->brsc[1] );
1571 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1572
1573 /* Frame Burst Limit */
1574 /* Defined, but not currently available in Firmware */
1575
1576 #endif // WARP
1577
1578 #ifdef WARP
1579 /* Multicast Rate */
1580 lp->ltvRecord.len = 3;
1581 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1582 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1583 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->MulticastRate[1] );
1584 #else
1585 lp->ltvRecord.len = 2;
1586 lp->ltvRecord.typ = CFG_CNF_MCAST_RATE;
1587 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastRate[0] );
1588 #endif // WARP
1589 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1590
1591 /* Own Name (Station Nickname) */
1592 if (( len = ( strlen( lp->StationName ) + 1 ) & ~0x01 ) != 0 ) {
1593 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : %s\n",
1594 // lp->StationName );
1595
1596 lp->ltvRecord.len = 2 + ( len / sizeof( hcf_16 ));
1597 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1598 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->StationName ));
1599
1600 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->StationName, len );
1601 } else {
1602 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME : EMPTY\n" );
1603
1604 lp->ltvRecord.len = 2;
1605 lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1606 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1607 }
1608
1609 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1610
1611 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_NAME result : 0x%04x\n",
1612 // hcf_status );
1613
1614 /* The following are set in STA mode only */
1615 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1616
1617 /* RTS Threshold */
1618 lp->ltvRecord.len = 2;
1619 lp->ltvRecord.typ = CFG_RTS_THRH;
1620 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1621 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1622
1623 /* Port Type */
1624 lp->ltvRecord.len = 2;
1625 lp->ltvRecord.typ = CFG_CNF_PORT_TYPE;
1626 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PortType );
1627 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1628
1629 /* Tx Rate Control */
1630 #ifdef WARP
1631 lp->ltvRecord.len = 3;
1632 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1633 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1634 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1635 #else
1636 lp->ltvRecord.len = 2;
1637 lp->ltvRecord.typ = CFG_TX_RATE_CNTL;
1638 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1639 #endif // WARP
1640
1641 //;?skip temporarily to see whether the RID or something else is the probelm hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1642
1643 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 2.4GHz : 0x%04x\n",
1644 lp->TxRateControl[0] );
1645 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL 5.0GHz : 0x%04x\n",
1646 lp->TxRateControl[1] );
1647 DBG_TRACE( DbgInfo, "CFG_TX_RATE_CNTL result : 0x%04x\n",
1648 hcf_status );
1649 /* Power Management */
1650 lp->ltvRecord.len = 2;
1651 lp->ltvRecord.typ = CFG_CNF_PM_ENABLED;
1652 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->PMEnabled );
1653 // lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0x8001 );
1654 DBG_TRACE( DbgInfo, "CFG_CNF_PM_ENABLED : 0x%04x\n", lp->PMEnabled );
1655 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1656 /* Multicast Receive */
1657 lp->ltvRecord.len = 2;
1658 lp->ltvRecord.typ = CFG_CNF_MCAST_RX;
1659 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MulticastReceive );
1660 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1661
1662 /* Max Sleep Duration */
1663 lp->ltvRecord.len = 2;
1664 lp->ltvRecord.typ = CFG_CNF_MAX_SLEEP_DURATION;
1665 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->MaxSleepDuration );
1666 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1667
1668 /* Create IBSS */
1669 lp->ltvRecord.len = 2;
1670 lp->ltvRecord.typ = CFG_CREATE_IBSS;
1671 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->CreateIBSS );
1672 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1673
1674 /* Desired SSID */
1675 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1676 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1677 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1678 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : %s\n",
1679 // lp->NetworkName );
1680
1681 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1682 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1683 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1684
1685 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1686 } else {
1687 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID : ANY\n" );
1688
1689 lp->ltvRecord.len = 2;
1690 lp->ltvRecord.typ = CFG_DESIRED_SSID;
1691 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1692 }
1693
1694 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1695
1696 //DBG_TRACE( DbgInfo, "CFG_DESIRED_SSID result : 0x%04x\n",
1697 // hcf_status );
1698 /* Own ATIM window */
1699 lp->ltvRecord.len = 2;
1700 lp->ltvRecord.typ = CFG_CNF_OWN_ATIM_WINDOW;
1701 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->atimWindow );
1702 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1703
1704
1705 /* Holdover Duration */
1706 lp->ltvRecord.len = 2;
1707 lp->ltvRecord.typ = CFG_CNF_HOLDOVER_DURATION;
1708 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->holdoverDuration );
1709 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1710
1711 /* Promiscuous Mode */
1712 lp->ltvRecord.len = 2;
1713 lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
1714 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->promiscuousMode );
1715 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1716
1717 /* Authentication */
1718 lp->ltvRecord.len = 2;
1719 lp->ltvRecord.typ = CFG_CNF_AUTHENTICATION;
1720 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->authentication );
1721 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1722 #ifdef WARP
1723 /* Connection Control */
1724 lp->ltvRecord.len = 2;
1725 lp->ltvRecord.typ = CFG_CNF_CONNECTION_CNTL;
1726 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->connectionControl );
1727 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1728
1729
1730
1731 /* Probe data rate */
1732 /*lp->ltvRecord.len = 3;
1733 lp->ltvRecord.typ = CFG_PROBE_DATA_RATE;
1734 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->probeDataRates[0] );
1735 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->probeDataRates[1] );
1736 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1737
1738 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 2.4GHz : 0x%04x\n",
1739 lp->probeDataRates[0] );
1740 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE 5.0GHz : 0x%04x\n",
1741 lp->probeDataRates[1] );
1742 DBG_TRACE( DbgInfo, "CFG_PROBE_DATA_RATE result : 0x%04x\n",
1743 hcf_status );*/
1744 #endif // WARP
1745 } else {
1746 /* The following are set in AP mode only */
1747 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
1748 //;?should we restore this to allow smaller memory footprint
1749
1750 /* DTIM Period */
1751 lp->ltvRecord.len = 2;
1752 lp->ltvRecord.typ = CFG_CNF_OWN_DTIM_PERIOD;
1753 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->DTIMPeriod );
1754 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1755
1756 /* Multicast PM Buffering */
1757 lp->ltvRecord.len = 2;
1758 lp->ltvRecord.typ = CFG_CNF_MCAST_PM_BUF;
1759 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->multicastPMBuffering );
1760 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1761
1762 /* Reject ANY - Closed System */
1763 lp->ltvRecord.len = 2;
1764 lp->ltvRecord.typ = CFG_CNF_REJECT_ANY;
1765 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RejectAny );
1766
1767 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1768
1769 /* Exclude Unencrypted */
1770 lp->ltvRecord.len = 2;
1771 lp->ltvRecord.typ = CFG_CNF_EXCL_UNENCRYPTED;
1772 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ExcludeUnencrypted );
1773
1774 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1775
1776 /* IntraBSS Relay */
1777 lp->ltvRecord.len = 2;
1778 lp->ltvRecord.typ = CFG_CNF_INTRA_BSS_RELAY;
1779 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->intraBSSRelay );
1780 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1781
1782 /* RTS Threshold 0 */
1783 lp->ltvRecord.len = 2;
1784 lp->ltvRecord.typ = CFG_RTS_THRH0;
1785 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->RTSThreshold );
1786
1787 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1788
1789 /* Tx Rate Control 0 */
1790 #ifdef WARP
1791 lp->ltvRecord.len = 3;
1792 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1793 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1794 lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->TxRateControl[1] );
1795 #else
1796 lp->ltvRecord.len = 2;
1797 lp->ltvRecord.typ = CFG_TX_RATE_CNTL0;
1798 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->TxRateControl[0] );
1799 #endif // WARP
1800
1801 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1802
1803 /* Own Beacon Interval */
1804 lp->ltvRecord.len = 2;
1805 lp->ltvRecord.typ = 0xFC31;
1806 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ownBeaconInterval );
1807 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1808
1809 /* Co-Existence Behavior */
1810 lp->ltvRecord.len = 2;
1811 lp->ltvRecord.typ = 0xFCC7;
1812 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->coexistence );
1813 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1814
1815 #ifdef USE_WDS
1816
1817 /* RTS Threshold 1 */
1818 lp->ltvRecord.len = 2;
1819 lp->ltvRecord.typ = CFG_RTS_THRH1;
1820 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].rtsThreshold );
1821 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1822
1823 /* RTS Threshold 2 */
1824 lp->ltvRecord.len = 2;
1825 lp->ltvRecord.typ = CFG_RTS_THRH2;
1826 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].rtsThreshold );
1827 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1828
1829
1830 /* RTS Threshold 3 */
1831 lp->ltvRecord.len = 2;
1832 lp->ltvRecord.typ = CFG_RTS_THRH3;
1833 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].rtsThreshold );
1834 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1835
1836
1837 /* RTS Threshold 4 */
1838 lp->ltvRecord.len = 2;
1839 lp->ltvRecord.typ = CFG_RTS_THRH4;
1840 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].rtsThreshold );
1841 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1842
1843
1844 /* RTS Threshold 5 */
1845 lp->ltvRecord.len = 2;
1846 lp->ltvRecord.typ = CFG_RTS_THRH5;
1847 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].rtsThreshold );
1848 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1849
1850 /* RTS Threshold 6 */
1851 lp->ltvRecord.len = 2;
1852 lp->ltvRecord.typ = CFG_RTS_THRH6;
1853 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].rtsThreshold );
1854 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1855 #if 0
1856 /* TX Rate Control 1 */
1857 lp->ltvRecord.len = 2;
1858 lp->ltvRecord.typ = CFG_TX_RATE_CNTL1;
1859 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[0].txRateCntl );
1860 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1861
1862 /* TX Rate Control 2 */
1863 lp->ltvRecord.len = 2;
1864 lp->ltvRecord.typ = CFG_TX_RATE_CNTL2;
1865 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[1].txRateCntl );
1866 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1867
1868 /* TX Rate Control 3 */
1869 lp->ltvRecord.len = 2;
1870 lp->ltvRecord.typ = CFG_TX_RATE_CNTL3;
1871 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[2].txRateCntl );
1872 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1873
1874 /* TX Rate Control 4 */
1875 lp->ltvRecord.len = 2;
1876 lp->ltvRecord.typ = CFG_TX_RATE_CNTL4;
1877 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[3].txRateCntl );
1878 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1879
1880 /* TX Rate Control 5 */
1881 lp->ltvRecord.len = 2;
1882 lp->ltvRecord.typ = CFG_TX_RATE_CNTL5;
1883 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[4].txRateCntl );
1884 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1885
1886 /* TX Rate Control 6 */
1887 lp->ltvRecord.len = 2;
1888 lp->ltvRecord.typ = CFG_TX_RATE_CNTL6;
1889 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->wds_port[5].txRateCntl );
1890 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1891
1892 #endif
1893
1894 /* WDS addresses. It's okay to blindly send these parameters, because
1895 the port needs to be enabled, before anything is done with it. */
1896
1897 /* WDS Address 1 */
1898 lp->ltvRecord.len = 4;
1899 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR1;
1900
1901 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[0].wdsAddress, ETH_ALEN );
1902 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1903
1904 /* WDS Address 2 */
1905 lp->ltvRecord.len = 4;
1906 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR2;
1907
1908 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[1].wdsAddress, ETH_ALEN );
1909 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1910
1911 /* WDS Address 3 */
1912 lp->ltvRecord.len = 4;
1913 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR3;
1914
1915 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[2].wdsAddress, ETH_ALEN );
1916 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1917
1918 /* WDS Address 4 */
1919 lp->ltvRecord.len = 4;
1920 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR4;
1921
1922 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[3].wdsAddress, ETH_ALEN );
1923 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1924
1925 /* WDS Address 5 */
1926 lp->ltvRecord.len = 4;
1927 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR5;
1928
1929 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[4].wdsAddress, ETH_ALEN );
1930 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1931
1932 /* WDS Address 6 */
1933 lp->ltvRecord.len = 4;
1934 lp->ltvRecord.typ = CFG_CNF_WDS_ADDR6;
1935
1936 memcpy( &lp->ltvRecord.u.u8[0], lp->wds_port[5].wdsAddress, ETH_ALEN );
1937 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1938 #endif /* USE_WDS */
1939 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
1940 }
1941
1942 /* Own MAC Address */
1943 //DBG_TRACE( DbgInfo, "MAC Address : %s\n",
1944 // DbgHwAddr( lp->MACAddress ));
1945
1946 if ( WVLAN_VALID_MAC_ADDRESS( lp->MACAddress )) {
1947 /* Make the MAC address valid by:
1948 Clearing the multicast bit
1949 Setting the local MAC address bit
1950 */
1951 //lp->MACAddress[0] &= ~0x03; //;?why is this commented out already in 720
1952 //lp->MACAddress[0] |= 0x02;
1953
1954 lp->ltvRecord.len = 1 + ( ETH_ALEN / sizeof( hcf_16 ));
1955 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
1956 //DBG_TRACE( DbgInfo, "CFG_NIC_MAC_ADDR\n" );
1957 lp->ltvRecord.typ = CFG_NIC_MAC_ADDR;
1958 } else {
1959 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_MAC_ADDR\n" );
1960 lp->ltvRecord.typ = CFG_CNF_OWN_MAC_ADDR;
1961 }
1962 /* MAC address is byte aligned, no endian conversion needed */
1963 memcpy( &( lp->ltvRecord.u.u8[0] ), lp->MACAddress, ETH_ALEN );
1964 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1965 //DBG_TRACE( DbgInfo, "CFG_XXX_MAC_ADDR result : 0x%04x\n",
1966 // hcf_status );
1967
1968 /* Update the MAC address in the netdevice struct */
1969 memcpy( lp->dev->dev_addr, lp->MACAddress, ETH_ALEN ); //;?what is the purpose of this seemingly complex logic
1970 }
1971 /* Own SSID */
1972 if ((( len = ( strlen( lp->NetworkName ) + 1 ) & ~0x01 ) != 0 ) &&
1973 ( strcmp( lp->NetworkName, "ANY" ) != 0 ) &&
1974 ( strcmp( lp->NetworkName, "any" ) != 0 )) {
1975 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : %s\n",
1976 // lp->NetworkName );
1977 lp->ltvRecord.len = 2 + (len / sizeof(hcf_16));
1978 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1979 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( strlen( lp->NetworkName ));
1980
1981 memcpy( &( lp->ltvRecord.u.u8[2] ), lp->NetworkName, len );
1982 } else {
1983 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID : ANY\n" );
1984 lp->ltvRecord.len = 2;
1985 lp->ltvRecord.typ = CFG_CNF_OWN_SSID;
1986 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1987 }
1988
1989 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1990
1991 //DBG_TRACE( DbgInfo, "CFG_CNF_OWN_SSID result : 0x%04x\n",
1992 // hcf_status );
1993 /* enable/disable encryption */
1994 lp->ltvRecord.len = 2;
1995 lp->ltvRecord.typ = CFG_CNF_ENCRYPTION;
1996 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->EnableEncryption );
1997 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
1998
1999 /* Set the Authentication Key Management Suite */
2000 lp->ltvRecord.len = 2;
2001 lp->ltvRecord.typ = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
2002 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->AuthKeyMgmtSuite );
2003 hcf_status = hcf_put_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2004 /* WEP Keys */
2005 wl_set_wep_keys( lp );
2006
2007 /* Country Code */
2008 /* countryInfo, ltvCountryInfo, CFG_CNF_COUNTRY_INFO */
2009
2010 DBG_LEAVE( DbgInfo );
2011 return hcf_status;
2012 } // wl_put_ltv
2013 /*============================================================================*/
2014
2015
2016 /*******************************************************************************
2017 * init_module()
2018 *******************************************************************************
2019 *
2020 * DESCRIPTION:
2021 *
2022 * Load the kernel module.
2023 *
2024 * PARAMETERS:
2025 *
2026 * N/A
2027 *
2028 * RETURNS:
2029 *
2030 * 0 on success
2031 * an errno value otherwise
2032 *
2033 ******************************************************************************/
2034 static int __init wl_module_init( void )
2035 {
2036 int result;
2037 /*------------------------------------------------------------------------*/
2038
2039 DBG_FUNC( "wl_module_init" );
2040
2041 #if DBG
2042 /* Convert "standard" PCMCIA parameter pc_debug to a reasonable DebugFlag value.
2043 * NOTE: The values all fall through to the lower values. */
2044 DbgInfo->DebugFlag = 0;
2045 DbgInfo->DebugFlag = DBG_TRACE_ON; //;?get this mess resolved one day
2046 if ( pc_debug ) switch( pc_debug ) {
2047 case 8:
2048 DbgInfo->DebugFlag |= DBG_DS_ON;
2049 case 7:
2050 DbgInfo->DebugFlag |= DBG_RX_ON | DBG_TX_ON;
2051 case 6:
2052 DbgInfo->DebugFlag |= DBG_PARAM_ON;
2053 case 5:
2054 DbgInfo->DebugFlag |= DBG_TRACE_ON;
2055 case 4:
2056 DbgInfo->DebugFlag |= DBG_VERBOSE_ON;
2057 case 1:
2058 DbgInfo->DebugFlag |= DBG_DEFAULTS;
2059 default:
2060 break;
2061 }
2062 #endif /* DBG */
2063
2064 DBG_ENTER( DbgInfo );
2065 printk(KERN_INFO "%s\n", VERSION_INFO);
2066 printk(KERN_INFO "*** Modified for kernel 2.6 by Henk de Groot <pe1dnn@amsat.org>\n");
2067 printk(KERN_INFO "*** Based on 7.18 version by Andrey Borzenkov <arvidjaar@mail.ru> $Revision: 39 $\n");
2068
2069
2070 // ;?#if (HCF_TYPE) & HCF_TYPE_AP
2071 // DBG_PRINT( "Access Point Mode (AP) Support: YES\n" );
2072 // #else
2073 // DBG_PRINT( "Access Point Mode (AP) Support: NO\n" );
2074 // #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2075
2076 result = wl_adapter_init_module( );
2077 DBG_LEAVE( DbgInfo );
2078 return result;
2079 } // init_module
2080 /*============================================================================*/
2081
2082
2083 /*******************************************************************************
2084 * cleanup_module()
2085 *******************************************************************************
2086 *
2087 * DESCRIPTION:
2088 *
2089 * Unload the kernel module.
2090 *
2091 * PARAMETERS:
2092 *
2093 * N/A
2094 *
2095 * RETURNS:
2096 *
2097 * N/A
2098 *
2099 ******************************************************************************/
2100 static void __exit wl_module_exit( void )
2101 {
2102 DBG_FUNC( "wl_module_exit" );
2103 DBG_ENTER(DbgInfo);
2104
2105 wl_adapter_cleanup_module( );
2106 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
2107 remove_proc_entry( "wlags", NULL ); //;?why so a-symmetric compared to location of create_proc_read_entry
2108 #endif
2109
2110 DBG_LEAVE( DbgInfo );
2111 return;
2112 } // cleanup_module
2113 /*============================================================================*/
2114
2115 module_init(wl_module_init);
2116 module_exit(wl_module_exit);
2117
2118 /*******************************************************************************
2119 * wl_isr()
2120 *******************************************************************************
2121 *
2122 * DESCRIPTION:
2123 *
2124 * The Interrupt Service Routine for the driver.
2125 *
2126 * PARAMETERS:
2127 *
2128 * irq - the irq the interrupt came in on
2129 * dev_id - a buffer containing information about the request
2130 * regs -
2131 *
2132 * RETURNS:
2133 *
2134 * N/A
2135 *
2136 ******************************************************************************/
2137 irqreturn_t wl_isr( int irq, void *dev_id, struct pt_regs *regs )
2138 {
2139 int events;
2140 struct net_device *dev = (struct net_device *) dev_id;
2141 struct wl_private *lp = NULL;
2142 /*------------------------------------------------------------------------*/
2143 if (( dev == NULL ) || ( !netif_device_present( dev ))) {
2144 return IRQ_NONE;
2145 }
2146
2147 /* Set the wl_private pointer (lp), now that we know that dev is non-null */
2148 lp = wl_priv(dev);
2149
2150 #ifdef USE_RTS
2151 if ( lp->useRTS == 1 ) {
2152 DBG_PRINT( "EXITING ISR, IN RTS MODE...\n" );
2153 return;
2154 }
2155 #endif /* USE_RTS */
2156
2157 /* If we have interrupts pending, then put them on a system task
2158 queue. Otherwise turn interrupts back on */
2159 events = hcf_action( &lp->hcfCtx, HCF_ACT_INT_OFF );
2160
2161 if ( events == HCF_INT_PENDING ) {
2162 /* Schedule the ISR handler as a bottom-half task in the
2163 tq_immediate queue */
2164 tasklet_schedule(&lp->task);
2165 } else {
2166 //DBG_PRINT( "NOT OUR INTERRUPT\n" );
2167 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2168 }
2169
2170 return IRQ_RETVAL(events == HCF_INT_PENDING);
2171 } // wl_isr
2172 /*============================================================================*/
2173
2174
2175 /*******************************************************************************
2176 * wl_isr_handler()
2177 *******************************************************************************
2178 *
2179 * DESCRIPTION:
2180 *
2181 * The ISR handler, scheduled to run in a deferred context by the ISR. This
2182 * is where the ISR's work actually gets done.
2183 *
2184 * PARAMETERS:
2185 *
2186 * lp - a pointer to the device's private adapter structure
2187 *
2188 * RETURNS:
2189 *
2190 * N/A
2191 *
2192 ******************************************************************************/
2193 #define WVLAN_MAX_INT_SERVICES 50
2194
2195 void wl_isr_handler( unsigned long p )
2196 {
2197 struct net_device *dev;
2198 unsigned long flags;
2199 bool_t stop = TRUE;
2200 int count;
2201 int result;
2202 struct wl_private *lp = (struct wl_private *)p;
2203 /*------------------------------------------------------------------------*/
2204
2205 if ( lp == NULL ) {
2206 DBG_PRINT( "wl_isr_handler lp adapter pointer is NULL!!!\n" );
2207 } else {
2208 wl_lock( lp, &flags );
2209
2210 dev = (struct net_device *)lp->dev;
2211 if ( dev != NULL && netif_device_present( dev ) ) stop = FALSE;
2212 for( count = 0; stop == FALSE && count < WVLAN_MAX_INT_SERVICES; count++ ) {
2213 stop = TRUE;
2214 result = hcf_service_nic( &lp->hcfCtx,
2215 (wci_bufp)lp->lookAheadBuf,
2216 sizeof( lp->lookAheadBuf ));
2217 if ( result == HCF_ERR_MIC ) {
2218 wl_wext_event_mic_failed( dev ); /* Send an event that MIC failed */
2219 //;?this seems wrong if HCF_ERR_MIC coincides with another event, stop gets FALSE
2220 //so why not do it always ;?
2221 }
2222
2223 #ifndef USE_MBOX_SYNC
2224 if ( lp->hcfCtx.IFB_MBInfoLen != 0 ) { /* anything in the mailbox */
2225 wl_mbx( lp );
2226 stop = FALSE;
2227 }
2228 #endif
2229 /* Check for a Link status event */
2230 if ( ( lp->hcfCtx.IFB_LinkStat & CFG_LINK_STAT_FW ) != 0 ) {
2231 wl_process_link_status( lp );
2232 stop = FALSE;
2233 }
2234 /* Check for probe response events */
2235 if ( lp->ProbeResp.infoType != 0 &&
2236 lp->ProbeResp.infoType != 0xFFFF ) {
2237 wl_process_probe_response( lp );
2238 memset( &lp->ProbeResp, 0, sizeof( lp->ProbeResp ));
2239 lp->ProbeResp.infoType = 0xFFFF;
2240 stop = FALSE;
2241 }
2242 /* Check for updated record events */
2243 if ( lp->updatedRecord.len != 0xFFFF ) {
2244 wl_process_updated_record( lp );
2245 lp->updatedRecord.len = 0xFFFF;
2246 stop = FALSE;
2247 }
2248 /* Check for association status events */
2249 if ( lp->assoc_stat.len != 0xFFFF ) {
2250 wl_process_assoc_status( lp );
2251 lp->assoc_stat.len = 0xFFFF;
2252 stop = FALSE;
2253 }
2254 /* Check for security status events */
2255 if ( lp->sec_stat.len != 0xFFFF ) {
2256 wl_process_security_status( lp );
2257 lp->sec_stat.len = 0xFFFF;
2258 stop = FALSE;
2259 }
2260
2261 #ifdef ENABLE_DMA
2262 if ( lp->use_dma ) {
2263 /* Check for DMA Rx packets */
2264 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_RDMAD ) {
2265 wl_rx_dma( dev );
2266 stop = FALSE;
2267 }
2268 /* Return Tx DMA descriptors to host */
2269 if ( lp->hcfCtx.IFB_DmaPackets & HREG_EV_TDMAD ) {
2270 wl_pci_dma_hcf_reclaim_tx( lp );
2271 stop = FALSE;
2272 }
2273 }
2274 else
2275 #endif // ENABLE_DMA
2276 {
2277 /* Check for Rx packets */
2278 if ( lp->hcfCtx.IFB_RxLen != 0 ) {
2279 wl_rx( dev );
2280 stop = FALSE;
2281 }
2282 /* Make sure that queued frames get sent */
2283 if ( wl_send( lp )) {
2284 stop = FALSE;
2285 }
2286 }
2287 }
2288 /* We're done, so turn interrupts which were turned off in wl_isr, back on */
2289 hcf_action( &lp->hcfCtx, HCF_ACT_INT_ON );
2290 wl_unlock( lp, &flags );
2291 }
2292 return;
2293 } // wl_isr_handler
2294 /*============================================================================*/
2295
2296
2297 /*******************************************************************************
2298 * wl_remove()
2299 *******************************************************************************
2300 *
2301 * DESCRIPTION:
2302 *
2303 * Notify the adapter that it has been removed. Since the adapter is gone,
2304 * we should no longer try to talk to it.
2305 *
2306 * PARAMETERS:
2307 *
2308 * dev - a pointer to the device's net_device structure
2309 *
2310 * RETURNS:
2311 *
2312 * N/A
2313 *
2314 ******************************************************************************/
2315 void wl_remove( struct net_device *dev )
2316 {
2317 struct wl_private *lp = wl_priv(dev);
2318 unsigned long flags;
2319 /*------------------------------------------------------------------------*/
2320 DBG_FUNC( "wl_remove" );
2321 DBG_ENTER( DbgInfo );
2322
2323 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2324
2325 wl_lock( lp, &flags );
2326
2327 /* stop handling interrupts */
2328 wl_act_int_off( lp );
2329 lp->is_handling_int = WL_NOT_HANDLING_INT;
2330
2331 /*
2332 * Disable the ports: just change state: since the
2333 * card is gone it is useless to talk to it and at
2334 * disconnect all state information is lost anyway.
2335 */
2336 /* Reset portState */
2337 lp->portState = WVLAN_PORT_STATE_DISABLED;
2338
2339 #if 0 //;? (HCF_TYPE) & HCF_TYPE_AP
2340 #ifdef USE_WDS
2341 //wl_disable_wds_ports( lp );
2342 #endif // USE_WDS
2343 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
2344
2345 /* Mark the device as unregistered */
2346 lp->is_registered = FALSE;
2347
2348 /* Deregister the WDS ports as well */
2349 WL_WDS_NETDEV_DEREGISTER( lp );
2350 #ifdef USE_RTS
2351 if ( lp->useRTS == 1 ) {
2352 wl_unlock( lp, &flags );
2353
2354 DBG_LEAVE( DbgInfo );
2355 return;
2356 }
2357 #endif /* USE_RTS */
2358
2359 /* Inform the HCF that the card has been removed */
2360 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2361
2362 wl_unlock( lp, &flags );
2363
2364 DBG_LEAVE( DbgInfo );
2365 return;
2366 } // wl_remove
2367 /*============================================================================*/
2368
2369
2370 /*******************************************************************************
2371 * wl_suspend()
2372 *******************************************************************************
2373 *
2374 * DESCRIPTION:
2375 *
2376 * Power-down and halt the adapter.
2377 *
2378 * PARAMETERS:
2379 *
2380 * dev - a pointer to the device's net_device structure
2381 *
2382 * RETURNS:
2383 *
2384 * N/A
2385 *
2386 ******************************************************************************/
2387 void wl_suspend( struct net_device *dev )
2388 {
2389 struct wl_private *lp = wl_priv(dev);
2390 unsigned long flags;
2391 /*------------------------------------------------------------------------*/
2392 DBG_FUNC( "wl_suspend" );
2393 DBG_ENTER( DbgInfo );
2394
2395 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2396
2397 /* The adapter is suspended:
2398 Stop the adapter
2399 Power down
2400 */
2401 wl_lock( lp, &flags );
2402
2403 /* Disable interrupt handling */
2404 wl_act_int_off( lp );
2405
2406 /* Disconnect */
2407 wl_disconnect( lp );
2408
2409 /* Disable */
2410 wl_disable( lp );
2411
2412 /* Disconnect from the adapter */
2413 hcf_connect( &lp->hcfCtx, HCF_DISCONNECT );
2414
2415 /* Reset portState to be sure (should have been done by wl_disable */
2416 lp->portState = WVLAN_PORT_STATE_DISABLED;
2417
2418 wl_unlock( lp, &flags );
2419
2420 DBG_LEAVE( DbgInfo );
2421 return;
2422 } // wl_suspend
2423 /*============================================================================*/
2424
2425
2426 /*******************************************************************************
2427 * wl_resume()
2428 *******************************************************************************
2429 *
2430 * DESCRIPTION:
2431 *
2432 * Resume a previously suspended adapter.
2433 *
2434 * PARAMETERS:
2435 *
2436 * dev - a pointer to the device's net_device structure
2437 *
2438 * RETURNS:
2439 *
2440 * N/A
2441 *
2442 ******************************************************************************/
2443 void wl_resume(struct net_device *dev)
2444 {
2445 struct wl_private *lp = wl_priv(dev);
2446 unsigned long flags;
2447 /*------------------------------------------------------------------------*/
2448 DBG_FUNC( "wl_resume" );
2449 DBG_ENTER( DbgInfo );
2450
2451 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2452
2453 wl_lock( lp, &flags );
2454
2455 /* Connect to the adapter */
2456 hcf_connect( &lp->hcfCtx, dev->base_addr );
2457
2458 /* Reset portState */
2459 lp->portState = WVLAN_PORT_STATE_DISABLED;
2460
2461 /* Power might have been off, assume the card lost the firmware*/
2462 lp->firmware_present = WL_FRIMWARE_NOT_PRESENT;
2463
2464 /* Reload the firmware and restart */
2465 wl_reset( dev );
2466
2467 /* Resume interrupt handling */
2468 wl_act_int_on( lp );
2469
2470 wl_unlock( lp, &flags );
2471
2472 DBG_LEAVE( DbgInfo );
2473 return;
2474 } // wl_resume
2475 /*============================================================================*/
2476
2477
2478 /*******************************************************************************
2479 * wl_release()
2480 *******************************************************************************
2481 *
2482 * DESCRIPTION:
2483 *
2484 * This function perfroms a check on the device and calls wl_remove() if
2485 * necessary. This function can be used for all bus types, but exists mostly
2486 * for the benefit of the Card Services driver, as there are times when
2487 * wl_remove() does not get called.
2488 *
2489 * PARAMETERS:
2490 *
2491 * dev - a pointer to the device's net_device structure
2492 *
2493 * RETURNS:
2494 *
2495 * N/A
2496 *
2497 ******************************************************************************/
2498 void wl_release( struct net_device *dev )
2499 {
2500 struct wl_private *lp = wl_priv(dev);
2501 /*------------------------------------------------------------------------*/
2502 DBG_FUNC( "wl_release" );
2503 DBG_ENTER( DbgInfo );
2504
2505 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
2506 /* If wl_remove() hasn't been called (i.e. when Card Services is shut
2507 down with the card in the slot), then call it */
2508 if ( lp->is_registered == TRUE ) {
2509 DBG_TRACE( DbgInfo, "Calling unregister_netdev(), as it wasn't called yet\n" );
2510 wl_remove( dev );
2511
2512 lp->is_registered = FALSE;
2513 }
2514
2515 DBG_LEAVE( DbgInfo );
2516 return;
2517 } // wl_release
2518 /*============================================================================*/
2519
2520
2521 /*******************************************************************************
2522 * wl_get_irq_mask()
2523 *******************************************************************************
2524 *
2525 * DESCRIPTION:
2526 *
2527 * Accessor function to retrieve the irq_mask module parameter
2528 *
2529 * PARAMETERS:
2530 *
2531 * N/A
2532 *
2533 * RETURNS:
2534 *
2535 * The irq_mask module parameter
2536 *
2537 ******************************************************************************/
2538 p_u16 wl_get_irq_mask( void )
2539 {
2540 return irq_mask;
2541 } // wl_get_irq_mask
2542 /*============================================================================*/
2543
2544
2545 /*******************************************************************************
2546 * wl_get_irq_list()
2547 *******************************************************************************
2548 *
2549 * DESCRIPTION:
2550 *
2551 * Accessor function to retrieve the irq_list module parameter
2552 *
2553 * PARAMETERS:
2554 *
2555 * N/A
2556 *
2557 * RETURNS:
2558 *
2559 * The irq_list module parameter
2560 *
2561 ******************************************************************************/
2562 p_s8 * wl_get_irq_list( void )
2563 {
2564 return irq_list;
2565 } // wl_get_irq_list
2566 /*============================================================================*/
2567
2568
2569
2570 /*******************************************************************************
2571 * wl_enable()
2572 *******************************************************************************
2573 *
2574 * DESCRIPTION:
2575 *
2576 * Used to enable MAC ports
2577 *
2578 * PARAMETERS:
2579 *
2580 * lp - pointer to the device's private adapter structure
2581 *
2582 * RETURNS:
2583 *
2584 * N/A
2585 *
2586 ******************************************************************************/
2587 int wl_enable( struct wl_private *lp )
2588 {
2589 int hcf_status = HCF_SUCCESS;
2590 /*------------------------------------------------------------------------*/
2591 DBG_FUNC( "wl_enable" );
2592 DBG_ENTER( DbgInfo );
2593
2594 if ( lp->portState == WVLAN_PORT_STATE_ENABLED ) {
2595 DBG_TRACE( DbgInfo, "No action: Card already enabled\n" );
2596 } else if ( lp->portState == WVLAN_PORT_STATE_CONNECTED ) {
2597 //;?suspicuous logic, how can you be connected without being enabled so this is probably dead code
2598 DBG_TRACE( DbgInfo, "No action: Card already connected\n" );
2599 } else {
2600 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_ENABLE );
2601 if ( hcf_status == HCF_SUCCESS ) {
2602 /* Set the status of the NIC to enabled */
2603 lp->portState = WVLAN_PORT_STATE_ENABLED; //;?bad mnemonic, NIC iso PORT
2604 #ifdef ENABLE_DMA
2605 if ( lp->use_dma ) {
2606 wl_pci_dma_hcf_supply( lp ); //;?always succes?
2607 }
2608 #endif
2609 }
2610 }
2611 if ( hcf_status != HCF_SUCCESS ) { //;?make this an assert
2612 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2613 }
2614 DBG_LEAVE( DbgInfo );
2615 return hcf_status;
2616 } // wl_enable
2617 /*============================================================================*/
2618
2619
2620 #ifdef USE_WDS
2621 /*******************************************************************************
2622 * wl_enable_wds_ports()
2623 *******************************************************************************
2624 *
2625 * DESCRIPTION:
2626 *
2627 * Used to enable the WDS MAC ports 1-6
2628 *
2629 * PARAMETERS:
2630 *
2631 * lp - pointer to the device's private adapter structure
2632 *
2633 * RETURNS:
2634 *
2635 * N/A
2636 *
2637 ******************************************************************************/
2638 void wl_enable_wds_ports( struct wl_private * lp )
2639 {
2640
2641 DBG_FUNC( "wl_enable_wds_ports" );
2642 DBG_ENTER( DbgInfo );
2643 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2644 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2645 }
2646 DBG_LEAVE( DbgInfo );
2647 return;
2648 } // wl_enable_wds_ports
2649 #endif /* USE_WDS */
2650 /*============================================================================*/
2651
2652
2653 /*******************************************************************************
2654 * wl_connect()
2655 *******************************************************************************
2656 *
2657 * DESCRIPTION:
2658 *
2659 * Used to connect a MAC port
2660 *
2661 * PARAMETERS:
2662 *
2663 * lp - pointer to the device's private adapter structure
2664 *
2665 * RETURNS:
2666 *
2667 * N/A
2668 *
2669 ******************************************************************************/
2670 int wl_connect( struct wl_private *lp )
2671 {
2672 int hcf_status;
2673 /*------------------------------------------------------------------------*/
2674
2675 DBG_FUNC( "wl_connect" );
2676 DBG_ENTER( DbgInfo );
2677
2678 if ( lp->portState != WVLAN_PORT_STATE_ENABLED ) {
2679 DBG_TRACE( DbgInfo, "No action: Not in enabled state\n" );
2680 DBG_LEAVE( DbgInfo );
2681 return HCF_SUCCESS;
2682 }
2683 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_CONNECT );
2684 if ( hcf_status == HCF_SUCCESS ) {
2685 lp->portState = WVLAN_PORT_STATE_CONNECTED;
2686 }
2687 DBG_LEAVE( DbgInfo );
2688 return hcf_status;
2689 } // wl_connect
2690 /*============================================================================*/
2691
2692
2693 /*******************************************************************************
2694 * wl_disconnect()
2695 *******************************************************************************
2696 *
2697 * DESCRIPTION:
2698 *
2699 * Used to disconnect a MAC port
2700 *
2701 * PARAMETERS:
2702 *
2703 * lp - pointer to the device's private adapter structure
2704 *
2705 * RETURNS:
2706 *
2707 * N/A
2708 *
2709 ******************************************************************************/
2710 int wl_disconnect( struct wl_private *lp )
2711 {
2712 int hcf_status;
2713 /*------------------------------------------------------------------------*/
2714
2715 DBG_FUNC( "wl_disconnect" );
2716 DBG_ENTER( DbgInfo );
2717
2718 if ( lp->portState != WVLAN_PORT_STATE_CONNECTED ) {
2719 DBG_TRACE( DbgInfo, "No action: Not in connected state\n" );
2720 DBG_LEAVE( DbgInfo );
2721 return HCF_SUCCESS;
2722 }
2723 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISCONNECT );
2724 if ( hcf_status == HCF_SUCCESS ) {
2725 lp->portState = WVLAN_PORT_STATE_ENABLED;
2726 }
2727 DBG_LEAVE( DbgInfo );
2728 return hcf_status;
2729 } // wl_disconnect
2730 /*============================================================================*/
2731
2732
2733 /*******************************************************************************
2734 * wl_disable()
2735 *******************************************************************************
2736 *
2737 * DESCRIPTION:
2738 *
2739 * Used to disable MAC ports
2740 *
2741 * PARAMETERS:
2742 *
2743 * lp - pointer to the device's private adapter structure
2744 * port - the MAC port to disable
2745 *
2746 * RETURNS:
2747 *
2748 * N/A
2749 *
2750 ******************************************************************************/
2751 int wl_disable( struct wl_private *lp )
2752 {
2753 int hcf_status = HCF_SUCCESS;
2754 /*------------------------------------------------------------------------*/
2755 DBG_FUNC( "wl_disable" );
2756 DBG_ENTER( DbgInfo );
2757
2758 if ( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
2759 DBG_TRACE( DbgInfo, "No action: Port state is disabled\n" );
2760 } else {
2761 hcf_status = hcf_cntl( &lp->hcfCtx, HCF_CNTL_DISABLE );
2762 if ( hcf_status == HCF_SUCCESS ) {
2763 /* Set the status of the port to disabled */ //;?bad mnemonic use NIC iso PORT
2764 lp->portState = WVLAN_PORT_STATE_DISABLED;
2765
2766 #ifdef ENABLE_DMA
2767 if ( lp->use_dma ) {
2768 wl_pci_dma_hcf_reclaim( lp );
2769 }
2770 #endif
2771 }
2772 }
2773 if ( hcf_status != HCF_SUCCESS ) {
2774 DBG_TRACE( DbgInfo, "failed: 0x%x\n", hcf_status );
2775 }
2776 DBG_LEAVE( DbgInfo );
2777 return hcf_status;
2778 } // wl_disable
2779 /*============================================================================*/
2780
2781
2782 #ifdef USE_WDS
2783 /*******************************************************************************
2784 * wl_disable_wds_ports()
2785 *******************************************************************************
2786 *
2787 * DESCRIPTION:
2788 *
2789 * Used to disable the WDS MAC ports 1-6
2790 *
2791 * PARAMETERS:
2792 *
2793 * lp - pointer to the device's private adapter structure
2794 *
2795 * RETURNS:
2796 *
2797 * N/A
2798 *
2799 ******************************************************************************/
2800 void wl_disable_wds_ports( struct wl_private * lp )
2801 {
2802
2803 DBG_FUNC( "wl_disable_wds_ports" );
2804 DBG_ENTER( DbgInfo );
2805
2806 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ){
2807 DBG_ERROR( DbgInfo, "!!!!;? someone misunderstood something !!!!!\n" );
2808 }
2809 // if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
2810 // wl_disable( lp, HCF_PORT_1 );
2811 // wl_disable( lp, HCF_PORT_2 );
2812 // wl_disable( lp, HCF_PORT_3 );
2813 // wl_disable( lp, HCF_PORT_4 );
2814 // wl_disable( lp, HCF_PORT_5 );
2815 // wl_disable( lp, HCF_PORT_6 );
2816 // }
2817 DBG_LEAVE( DbgInfo );
2818 return;
2819 } // wl_disable_wds_ports
2820 #endif // USE_WDS
2821 /*============================================================================*/
2822
2823
2824 #ifndef USE_MBOX_SYNC
2825 /*******************************************************************************
2826 * wl_mbx()
2827 *******************************************************************************
2828 *
2829 * DESCRIPTION:
2830 * This function is used to read and process a mailbox message.
2831 *
2832 *
2833 * PARAMETERS:
2834 *
2835 * lp - pointer to the device's private adapter structure
2836 *
2837 * RETURNS:
2838 *
2839 * an HCF status code
2840 *
2841 ******************************************************************************/
2842 int wl_mbx( struct wl_private *lp )
2843 {
2844 int hcf_status = HCF_SUCCESS;
2845 /*------------------------------------------------------------------------*/
2846 DBG_FUNC( "wl_mbx" );
2847 DBG_ENTER( DbgInfo );
2848 DBG_TRACE( DbgInfo, "Mailbox Info: IFB_MBInfoLen: %d\n",
2849 lp->hcfCtx.IFB_MBInfoLen );
2850
2851 memset( &( lp->ltvRecord ), 0, sizeof( ltv_t ));
2852
2853 lp->ltvRecord.len = MB_SIZE;
2854 lp->ltvRecord.typ = CFG_MB_INFO;
2855 hcf_status = hcf_get_info( &lp->hcfCtx, (LTVP)&( lp->ltvRecord ));
2856
2857 if ( hcf_status != HCF_SUCCESS ) {
2858 DBG_ERROR( DbgInfo, "hcf_get_info returned 0x%x\n", hcf_status );
2859
2860 DBG_LEAVE( DbgInfo );
2861 return hcf_status;
2862 }
2863
2864 if ( lp->ltvRecord.typ == CFG_MB_INFO ) {
2865 DBG_LEAVE( DbgInfo );
2866 return hcf_status;
2867 }
2868 /* Endian translate the mailbox data, then process the message */
2869 wl_endian_translate_mailbox( &( lp->ltvRecord ));
2870 wl_process_mailbox( lp );
2871 DBG_LEAVE( DbgInfo );
2872 return hcf_status;
2873 } // wl_mbx
2874 /*============================================================================*/
2875
2876
2877 /*******************************************************************************
2878 * wl_endian_translate_mailbox()
2879 *******************************************************************************
2880 *
2881 * DESCRIPTION:
2882 *
2883 * This function will perform the tedious task of endian translating all
2884 * fields withtin a mailbox message which need translating.
2885 *
2886 * PARAMETERS:
2887 *
2888 * ltv - pointer to the LTV to endian translate
2889 *
2890 * RETURNS:
2891 *
2892 * none
2893 *
2894 ******************************************************************************/
2895 void wl_endian_translate_mailbox( ltv_t *ltv )
2896 {
2897
2898 DBG_FUNC( "wl_endian_translate_mailbox" );
2899 DBG_ENTER( DbgInfo );
2900 switch( ltv->typ ) {
2901 case CFG_TALLIES:
2902 break;
2903
2904 case CFG_SCAN:
2905 {
2906 int num_aps;
2907 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)&ltv->u.u8[0];
2908
2909 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
2910 ( sizeof( SCAN_RS_STRCT )));
2911
2912 while( num_aps >= 1 ) {
2913 num_aps--;
2914
2915 aps[num_aps].channel_id =
2916 CNV_LITTLE_TO_INT( aps[num_aps].channel_id );
2917
2918 aps[num_aps].noise_level =
2919 CNV_LITTLE_TO_INT( aps[num_aps].noise_level );
2920
2921 aps[num_aps].signal_level =
2922 CNV_LITTLE_TO_INT( aps[num_aps].signal_level );
2923
2924 aps[num_aps].beacon_interval_time =
2925 CNV_LITTLE_TO_INT( aps[num_aps].beacon_interval_time );
2926
2927 aps[num_aps].capability =
2928 CNV_LITTLE_TO_INT( aps[num_aps].capability );
2929
2930 aps[num_aps].ssid_len =
2931 CNV_LITTLE_TO_INT( aps[num_aps].ssid_len );
2932
2933 aps[num_aps].ssid_val[aps[num_aps].ssid_len] = 0;
2934 }
2935 }
2936 break;
2937
2938 case CFG_ACS_SCAN:
2939 {
2940 PROBE_RESP *probe_resp = (PROBE_RESP *)ltv;
2941
2942 probe_resp->frameControl = CNV_LITTLE_TO_INT( probe_resp->frameControl );
2943 probe_resp->durID = CNV_LITTLE_TO_INT( probe_resp->durID );
2944 probe_resp->sequence = CNV_LITTLE_TO_INT( probe_resp->sequence );
2945 probe_resp->dataLength = CNV_LITTLE_TO_INT( probe_resp->dataLength );
2946 #ifndef WARP
2947 probe_resp->lenType = CNV_LITTLE_TO_INT( probe_resp->lenType );
2948 #endif // WARP
2949 probe_resp->beaconInterval = CNV_LITTLE_TO_INT( probe_resp->beaconInterval );
2950 probe_resp->capability = CNV_LITTLE_TO_INT( probe_resp->capability );
2951 probe_resp->flags = CNV_LITTLE_TO_INT( probe_resp->flags );
2952 }
2953 break;
2954
2955 case CFG_LINK_STAT:
2956 #define ls ((LINK_STATUS_STRCT *)ltv)
2957 ls->linkStatus = CNV_LITTLE_TO_INT( ls->linkStatus );
2958 break;
2959 #undef ls
2960
2961 case CFG_ASSOC_STAT:
2962 {
2963 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
2964
2965 as->assocStatus = CNV_LITTLE_TO_INT( as->assocStatus );
2966 }
2967 break;
2968
2969 case CFG_SECURITY_STAT:
2970 {
2971 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
2972
2973 ss->securityStatus = CNV_LITTLE_TO_INT( ss->securityStatus );
2974 ss->reason = CNV_LITTLE_TO_INT( ss->reason );
2975 }
2976 break;
2977
2978 case CFG_WMP:
2979 break;
2980
2981 case CFG_NULL:
2982 break;
2983
2984 default:
2985 break;
2986 }
2987
2988 DBG_LEAVE( DbgInfo );
2989 return;
2990 } // wl_endian_translate_mailbox
2991 /*============================================================================*/
2992
2993 /*******************************************************************************
2994 * wl_process_mailbox()
2995 *******************************************************************************
2996 *
2997 * DESCRIPTION:
2998 *
2999 * This function will process the mailbox data.
3000 *
3001 * PARAMETERS:
3002 *
3003 * ltv - pointer to the LTV to be processed.
3004 *
3005 * RETURNS:
3006 *
3007 * none
3008 *
3009 ******************************************************************************/
3010 void wl_process_mailbox( struct wl_private *lp )
3011 {
3012 ltv_t *ltv;
3013 hcf_16 ltv_val = 0xFFFF;
3014 /*------------------------------------------------------------------------*/
3015 DBG_FUNC( "wl_process_mailbox" );
3016 DBG_ENTER( DbgInfo );
3017 ltv = &( lp->ltvRecord );
3018
3019 switch( ltv->typ ) {
3020
3021 case CFG_TALLIES:
3022 DBG_TRACE( DbgInfo, "CFG_TALLIES\n" );
3023 break;
3024 case CFG_SCAN:
3025 DBG_TRACE( DbgInfo, "CFG_SCAN\n" );
3026
3027 {
3028 int num_aps;
3029 SCAN_RS_STRCT *aps = (SCAN_RS_STRCT *)&ltv->u.u8[0];
3030
3031 num_aps = (hcf_16)(( (size_t)(ltv->len - 1 ) * 2 ) /
3032 ( sizeof( SCAN_RS_STRCT )));
3033
3034 lp->scan_results.num_aps = num_aps;
3035
3036 DBG_TRACE( DbgInfo, "Number of APs: %d\n", num_aps );
3037
3038 while( num_aps >= 1 ) {
3039 num_aps--;
3040
3041 DBG_TRACE( DbgInfo, "AP : %d\n", num_aps );
3042 DBG_TRACE( DbgInfo, "=========================\n" );
3043 DBG_TRACE( DbgInfo, "Channel ID : 0x%04x\n",
3044 aps[num_aps].channel_id );
3045 DBG_TRACE( DbgInfo, "Noise Level : 0x%04x\n",
3046 aps[num_aps].noise_level );
3047 DBG_TRACE( DbgInfo, "Signal Level : 0x%04x\n",
3048 aps[num_aps].signal_level );
3049 DBG_TRACE( DbgInfo, "Beacon Interval : 0x%04x\n",
3050 aps[num_aps].beacon_interval_time );
3051 DBG_TRACE( DbgInfo, "Capability : 0x%04x\n",
3052 aps[num_aps].capability );
3053 DBG_TRACE( DbgInfo, "SSID Length : 0x%04x\n",
3054 aps[num_aps].ssid_len );
3055 DBG_TRACE( DbgInfo, "BSSID : %s\n",
3056 DbgHwAddr( aps[num_aps].bssid ));
3057
3058 if ( aps[num_aps].ssid_len != 0 ) {
3059 DBG_TRACE( DbgInfo, "SSID : %s.\n",
3060 aps[num_aps].ssid_val );
3061 } else {
3062 DBG_TRACE( DbgInfo, "SSID : %s.\n", "ANY" );
3063 }
3064
3065 DBG_TRACE( DbgInfo, "\n" );
3066
3067 /* Copy the info to the ScanResult structure in the private
3068 adapter struct */
3069 memcpy( &( lp->scan_results.APTable[num_aps]), &( aps[num_aps] ),
3070 sizeof( SCAN_RS_STRCT ));
3071 }
3072
3073 /* Set scan result to true so that any scan requests will
3074 complete */
3075 lp->scan_results.scan_complete = TRUE;
3076 }
3077
3078 break;
3079 case CFG_ACS_SCAN:
3080 DBG_TRACE( DbgInfo, "CFG_ACS_SCAN\n" );
3081
3082 {
3083 PROBE_RESP *probe_rsp = (PROBE_RESP *)ltv;
3084 hcf_8 *wpa_ie = NULL;
3085 hcf_16 wpa_ie_len = 0;
3086
3087 DBG_TRACE( DbgInfo, "(%s) =========================\n",
3088 lp->dev->name );
3089
3090 DBG_TRACE( DbgInfo, "(%s) length : 0x%04x.\n",
3091 lp->dev->name, probe_rsp->length );
3092
3093 if ( probe_rsp->length > 1 ) {
3094 DBG_TRACE( DbgInfo, "(%s) infoType : 0x%04x.\n",
3095 lp->dev->name, probe_rsp->infoType );
3096
3097 DBG_TRACE( DbgInfo, "(%s) signal : 0x%02x.\n",
3098 lp->dev->name, probe_rsp->signal );
3099
3100 DBG_TRACE( DbgInfo, "(%s) silence : 0x%02x.\n",
3101 lp->dev->name, probe_rsp->silence );
3102
3103 DBG_TRACE( DbgInfo, "(%s) rxFlow : 0x%02x.\n",
3104 lp->dev->name, probe_rsp->rxFlow );
3105
3106 DBG_TRACE( DbgInfo, "(%s) rate : 0x%02x.\n",
3107 lp->dev->name, probe_rsp->rate );
3108
3109 DBG_TRACE( DbgInfo, "(%s) frame cntl : 0x%04x.\n",
3110 lp->dev->name, probe_rsp->frameControl );
3111
3112 DBG_TRACE( DbgInfo, "(%s) durID : 0x%04x.\n",
3113 lp->dev->name, probe_rsp->durID );
3114
3115 DBG_TRACE( DbgInfo, "(%s) address1 : %s\n",
3116 lp->dev->name, DbgHwAddr( probe_rsp->address1 ));
3117
3118 DBG_TRACE( DbgInfo, "(%s) address2 : %s\n",
3119 lp->dev->name, DbgHwAddr( probe_rsp->address2 ));
3120
3121 DBG_TRACE( DbgInfo, "(%s) BSSID : %s\n",
3122 lp->dev->name, DbgHwAddr( probe_rsp->BSSID ));
3123
3124 DBG_TRACE( DbgInfo, "(%s) sequence : 0x%04x.\n",
3125 lp->dev->name, probe_rsp->sequence );
3126
3127 DBG_TRACE( DbgInfo, "(%s) address4 : %s\n",
3128 lp->dev->name, DbgHwAddr( probe_rsp->address4 ));
3129
3130 DBG_TRACE( DbgInfo, "(%s) datalength : 0x%04x.\n",
3131 lp->dev->name, probe_rsp->dataLength );
3132
3133 DBG_TRACE( DbgInfo, "(%s) DA : %s\n",
3134 lp->dev->name, DbgHwAddr( probe_rsp->DA ));
3135
3136 DBG_TRACE( DbgInfo, "(%s) SA : %s\n",
3137 lp->dev->name, DbgHwAddr( probe_rsp->SA ));
3138
3139 //DBG_TRACE( DbgInfo, "(%s) lenType : 0x%04x.\n",
3140 // lp->dev->name, probe_rsp->lenType );
3141
3142 DBG_TRACE( DbgInfo, "(%s) timeStamp : %s\n",
3143 lp->dev->name, DbgHwAddr( probe_rsp->timeStamp ));
3144
3145 DBG_TRACE( DbgInfo, "(%s) beaconInt : 0x%04x.\n",
3146 lp->dev->name, probe_rsp->beaconInterval );
3147
3148 DBG_TRACE( DbgInfo, "(%s) capability : 0x%04x.\n",
3149 lp->dev->name, probe_rsp->capability );
3150
3151 DBG_TRACE( DbgInfo, "(%s) SSID len : 0x%04x.\n",
3152 lp->dev->name, probe_rsp->rawData[1] );
3153
3154 if ( probe_rsp->rawData[1] > 0 ) {
3155 char ssid[HCF_MAX_NAME_LEN];
3156
3157 memset( ssid, 0, sizeof( ssid ));
3158 strncpy( ssid, &probe_rsp->rawData[2],
3159 probe_rsp->rawData[1] );
3160
3161 DBG_TRACE( DbgInfo, "(%s) SSID : %s\n",
3162 lp->dev->name, ssid );
3163 }
3164
3165 /* Parse out the WPA-IE, if one exists */
3166 wpa_ie = wl_parse_wpa_ie( probe_rsp, &wpa_ie_len );
3167 if ( wpa_ie != NULL ) {
3168 DBG_TRACE( DbgInfo, "(%s) WPA-IE : %s\n",
3169 lp->dev->name, wl_print_wpa_ie( wpa_ie, wpa_ie_len ));
3170 }
3171
3172 DBG_TRACE( DbgInfo, "(%s) flags : 0x%04x.\n",
3173 lp->dev->name, probe_rsp->flags );
3174 }
3175
3176 DBG_TRACE( DbgInfo, "\n\n" );
3177 /* If probe response length is 1, then the scan is complete */
3178 if ( probe_rsp->length == 1 ) {
3179 DBG_TRACE( DbgInfo, "SCAN COMPLETE\n" );
3180 lp->probe_results.num_aps = lp->probe_num_aps;
3181 lp->probe_results.scan_complete = TRUE;
3182
3183 /* Reset the counter for the next scan request */
3184 lp->probe_num_aps = 0;
3185
3186 /* Send a wireless extensions event that the scan completed */
3187 wl_wext_event_scan_complete( lp->dev );
3188 } else {
3189 /* Only copy to the table if the entry is unique; APs sometimes
3190 respond more than once to a probe */
3191 if ( lp->probe_num_aps == 0 ) {
3192 /* Copy the info to the ScanResult structure in the private
3193 adapter struct */
3194 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3195 probe_rsp, sizeof( PROBE_RESP ));
3196
3197 /* Increment the number of APs detected */
3198 lp->probe_num_aps++;
3199 } else {
3200 int count;
3201 int unique = 1;
3202
3203 for( count = 0; count < lp->probe_num_aps; count++ ) {
3204 if ( memcmp( &( probe_rsp->BSSID ),
3205 lp->probe_results.ProbeTable[count].BSSID,
3206 ETH_ALEN ) == 0 ) {
3207 unique = 0;
3208 }
3209 }
3210
3211 if ( unique ) {
3212 /* Copy the info to the ScanResult structure in the
3213 private adapter struct. Only copy if there's room in the
3214 table */
3215 if ( lp->probe_num_aps < MAX_NAPS )
3216 {
3217 memcpy( &( lp->probe_results.ProbeTable[lp->probe_num_aps] ),
3218 probe_rsp, sizeof( PROBE_RESP ));
3219 }
3220 else
3221 {
3222 DBG_WARNING( DbgInfo, "Num of scan results exceeds storage, truncating\n" );
3223 }
3224
3225 /* Increment the number of APs detected. Note I do this
3226 here even when I don't copy the probe response to the
3227 buffer in order to detect the overflow condition */
3228 lp->probe_num_aps++;
3229 }
3230 }
3231 }
3232 }
3233
3234 break;
3235
3236 case CFG_LINK_STAT:
3237 #define ls ((LINK_STATUS_STRCT *)ltv)
3238 DBG_TRACE( DbgInfo, "CFG_LINK_STAT\n" );
3239
3240 switch( ls->linkStatus ) {
3241 case 1:
3242 DBG_TRACE( DbgInfo, "Link Status : Connected\n" );
3243 wl_wext_event_ap( lp->dev );
3244 break;
3245
3246 case 2:
3247 DBG_TRACE( DbgInfo, "Link Status : Disconnected\n" );
3248 break;
3249
3250 case 3:
3251 DBG_TRACE( DbgInfo, "Link Status : Access Point Change\n" );
3252 break;
3253
3254 case 4:
3255 DBG_TRACE( DbgInfo, "Link Status : Access Point Out of Range\n" );
3256 break;
3257
3258 case 5:
3259 DBG_TRACE( DbgInfo, "Link Status : Access Point In Range\n" );
3260 break;
3261
3262 default:
3263 DBG_TRACE( DbgInfo, "Link Status : UNKNOWN (0x%04x)\n",
3264 ls->linkStatus );
3265 break;
3266 }
3267
3268 break;
3269 #undef ls
3270
3271 case CFG_ASSOC_STAT:
3272 DBG_TRACE( DbgInfo, "CFG_ASSOC_STAT\n" );
3273
3274 {
3275 ASSOC_STATUS_STRCT *as = (ASSOC_STATUS_STRCT *)ltv;
3276
3277 switch( as->assocStatus ) {
3278 case 1:
3279 DBG_TRACE( DbgInfo, "Association Status : STA Associated\n" );
3280 break;
3281
3282 case 2:
3283 DBG_TRACE( DbgInfo, "Association Status : STA Reassociated\n" );
3284 break;
3285
3286 case 3:
3287 DBG_TRACE( DbgInfo, "Association Status : STA Disassociated\n" );
3288 break;
3289
3290 default:
3291 DBG_TRACE( DbgInfo, "Association Status : UNKNOWN (0x%04x)\n",
3292 as->assocStatus );
3293 break;
3294 }
3295
3296 DBG_TRACE( DbgInfo, "STA Address : %s\n",
3297 DbgHwAddr( as->staAddr ));
3298
3299 if (( as->assocStatus == 2 ) && ( as->len == 8 )) {
3300 DBG_TRACE( DbgInfo, "Old AP Address : %s\n",
3301 DbgHwAddr( as->oldApAddr ));
3302 }
3303 }
3304
3305 break;
3306
3307 case CFG_SECURITY_STAT:
3308 DBG_TRACE( DbgInfo, "CFG_SECURITY_STAT\n" );
3309
3310 {
3311 SECURITY_STATUS_STRCT *ss = (SECURITY_STATUS_STRCT *)ltv;
3312
3313 switch( ss->securityStatus ) {
3314 case 1:
3315 DBG_TRACE( DbgInfo, "Security Status : Dissassociate [AP]\n" );
3316 break;
3317
3318 case 2:
3319 DBG_TRACE( DbgInfo, "Security Status : Deauthenticate [AP]\n" );
3320 break;
3321
3322 case 3:
3323 DBG_TRACE( DbgInfo, "Security Status : Authenticate Fail [STA] or [AP]\n" );
3324 break;
3325
3326 case 4:
3327 DBG_TRACE( DbgInfo, "Security Status : MIC Fail\n" );
3328 break;
3329
3330 case 5:
3331 DBG_TRACE( DbgInfo, "Security Status : Associate Fail\n" );
3332 break;
3333
3334 default:
3335 DBG_TRACE( DbgInfo, "Security Status : UNKNOWN %d\n",
3336 ss->securityStatus );
3337 break;
3338 }
3339
3340 DBG_TRACE( DbgInfo, "STA Address : %s\n", DbgHwAddr( ss->staAddr ));
3341
3342 DBG_TRACE( DbgInfo, "Reason : 0x%04x \n", ss->reason );
3343 }
3344
3345 break;
3346
3347 case CFG_WMP:
3348 DBG_TRACE( DbgInfo, "CFG_WMP, size is %d bytes\n", ltv->len );
3349 {
3350 WMP_RSP_STRCT *wmp_rsp = (WMP_RSP_STRCT *)ltv;
3351
3352 DBG_TRACE( DbgInfo, "CFG_WMP, pdu type is 0x%x\n",
3353 wmp_rsp->wmpRsp.wmpHdr.type );
3354
3355 switch( wmp_rsp->wmpRsp.wmpHdr.type ) {
3356 case WVLAN_WMP_PDU_TYPE_LT_RSP:
3357 {
3358 #if DBG
3359 LINKTEST_RSP_STRCT *lt_rsp = (LINKTEST_RSP_STRCT *)ltv;
3360 #endif // DBG
3361 DBG_TRACE( DbgInfo, "LINK TEST RESULT\n" );
3362 DBG_TRACE( DbgInfo, "================\n" );
3363 DBG_TRACE( DbgInfo, "Length : %d.\n", lt_rsp->len );
3364
3365 DBG_TRACE( DbgInfo, "Name : %s.\n", lt_rsp->ltRsp.ltRsp.name );
3366 DBG_TRACE( DbgInfo, "Signal Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.signal );
3367 DBG_TRACE( DbgInfo, "Noise Level : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.noise );
3368 DBG_TRACE( DbgInfo, "Receive Flow : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.rxFlow );
3369 DBG_TRACE( DbgInfo, "Data Rate : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRate );
3370 DBG_TRACE( DbgInfo, "Protocol : 0x%04x.\n", lt_rsp->ltRsp.ltRsp.protocol );
3371 DBG_TRACE( DbgInfo, "Station : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.station );
3372 DBG_TRACE( DbgInfo, "Data Rate Cap : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.dataRateCap );
3373
3374 DBG_TRACE( DbgInfo, "Power Mgmt : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3375 lt_rsp->ltRsp.ltRsp.powerMgmt[0],
3376 lt_rsp->ltRsp.ltRsp.powerMgmt[1],
3377 lt_rsp->ltRsp.ltRsp.powerMgmt[2],
3378 lt_rsp->ltRsp.ltRsp.powerMgmt[3] );
3379
3380 DBG_TRACE( DbgInfo, "Robustness : 0x%02x 0x%02x 0x%02x 0x%02x.\n",
3381 lt_rsp->ltRsp.ltRsp.robustness[0],
3382 lt_rsp->ltRsp.ltRsp.robustness[1],
3383 lt_rsp->ltRsp.ltRsp.robustness[2],
3384 lt_rsp->ltRsp.ltRsp.robustness[3] );
3385
3386 DBG_TRACE( DbgInfo, "Scaling : 0x%02x.\n", lt_rsp->ltRsp.ltRsp.scaling );
3387 }
3388
3389 break;
3390
3391 default:
3392 break;
3393 }
3394 }
3395
3396 break;
3397
3398 case CFG_NULL:
3399 DBG_TRACE( DbgInfo, "CFG_NULL\n" );
3400 break;
3401
3402 case CFG_UPDATED_INFO_RECORD: // Updated Information Record
3403 DBG_TRACE( DbgInfo, "UPDATED INFORMATION RECORD\n" );
3404
3405 ltv_val = CNV_INT_TO_LITTLE( ltv->u.u16[0] );
3406
3407 /* Check and see which RID was updated */
3408 switch( ltv_val ) {
3409 case CFG_CUR_COUNTRY_INFO: // Indicate Passive Scan Completion
3410 DBG_TRACE( DbgInfo, "Updated country info\n" );
3411
3412 /* Do I need to hold off on updating RIDs until the process is
3413 complete? */
3414 wl_connect( lp );
3415 break;
3416
3417 case CFG_PORT_STAT: // Wait for Connect Event
3418 //wl_connect( lp );
3419
3420 break;
3421
3422 default:
3423 DBG_WARNING( DbgInfo, "Unknown RID: 0x%04x\n", ltv_val );
3424 }
3425
3426 break;
3427
3428 default:
3429 DBG_TRACE( DbgInfo, "UNKNOWN MESSAGE: 0x%04x\n", ltv->typ );
3430 break;
3431 }
3432 DBG_LEAVE( DbgInfo );
3433 return;
3434 } // wl_process_mailbox
3435 /*============================================================================*/
3436 #endif /* ifndef USE_MBOX_SYNC */
3437
3438 #ifdef USE_WDS
3439 /*******************************************************************************
3440 * wl_wds_netdev_register()
3441 *******************************************************************************
3442 *
3443 * DESCRIPTION:
3444 *
3445 * This function registers net_device structures with the system's network
3446 * layer for use with the WDS ports.
3447 *
3448 *
3449 * PARAMETERS:
3450 *
3451 * lp - pointer to the device's private adapter structure
3452 *
3453 * RETURNS:
3454 *
3455 * N/A
3456 *
3457 ******************************************************************************/
3458 void wl_wds_netdev_register( struct wl_private *lp )
3459 {
3460 int count;
3461 /*------------------------------------------------------------------------*/
3462 DBG_FUNC( "wl_wds_netdev_register" );
3463 DBG_ENTER( DbgInfo );
3464 //;?why is there no USE_WDS clause like in wl_enable_wds_ports
3465 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3466 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3467 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3468 if ( register_netdev( lp->wds_port[count].dev ) != 0 ) {
3469 DBG_WARNING( DbgInfo, "net device for WDS port %d could not be registered\n",
3470 ( count + 1 ));
3471 }
3472 lp->wds_port[count].is_registered = TRUE;
3473
3474 /* Fill out the net_device structs with the MAC addr */
3475 memcpy( lp->wds_port[count].dev->dev_addr, lp->MACAddress, ETH_ALEN );
3476 lp->wds_port[count].dev->addr_len = ETH_ALEN;
3477 }
3478 }
3479 }
3480 DBG_LEAVE( DbgInfo );
3481 return;
3482 } // wl_wds_netdev_register
3483 /*============================================================================*/
3484
3485
3486 /*******************************************************************************
3487 * wl_wds_netdev_deregister()
3488 *******************************************************************************
3489 *
3490 * DESCRIPTION:
3491 *
3492 * This function deregisters the WDS net_device structures used by the
3493 * system's network layer.
3494 *
3495 *
3496 * PARAMETERS:
3497 *
3498 * lp - pointer to the device's private adapter structure
3499 *
3500 * RETURNS:
3501 *
3502 * N/A
3503 *
3504 ******************************************************************************/
3505 void wl_wds_netdev_deregister( struct wl_private *lp )
3506 {
3507 int count;
3508 /*------------------------------------------------------------------------*/
3509 DBG_FUNC( "wl_wds_netdev_deregister" );
3510 DBG_ENTER( DbgInfo );
3511 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP ) {
3512 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
3513 if ( WVLAN_VALID_MAC_ADDRESS( lp->wds_port[count].wdsAddress )) {
3514 unregister_netdev( lp->wds_port[count].dev );
3515 }
3516 lp->wds_port[count].is_registered = FALSE;
3517 }
3518 }
3519 DBG_LEAVE( DbgInfo );
3520 return;
3521 } // wl_wds_netdev_deregister
3522 /*============================================================================*/
3523 #endif /* USE_WDS */
3524
3525
3526 #if 0 //SCULL_USE_PROC /* don't waste space if unused */
3527 /*
3528 * The proc filesystem: function to read and entry
3529 */
3530 int printf_hcf_16( char *s, char *buf, hcf_16* p, int n );
3531 int printf_hcf_16( char *s, char *buf, hcf_16* p, int n ) {
3532
3533 int i, len;
3534
3535 len = sprintf(buf, "%s", s );
3536 while ( len < 20 ) len += sprintf(buf+len, " " );
3537 len += sprintf(buf+len,": " );
3538 for ( i = 0; i < n; i++ ) {
3539 if ( len % 80 > 75 ) {
3540 len += sprintf(buf+len,"\n" );
3541 }
3542 len += sprintf(buf+len,"%04X ", p[i] );
3543 }
3544 len += sprintf(buf+len,"\n" );
3545 return len;
3546 } // printf_hcf_16
3547
3548 int printf_hcf_8( char *s, char *buf, hcf_8* p, int n );
3549 int printf_hcf_8( char *s, char *buf, hcf_8* p, int n ) {
3550
3551 int i, len;
3552
3553 len = sprintf(buf, "%s", s );
3554 while ( len < 20 ) len += sprintf(buf+len, " " );
3555 len += sprintf(buf+len,": " );
3556 for ( i = 0; i <= n; i++ ) {
3557 if ( len % 80 > 77 ) {
3558 len += sprintf(buf+len,"\n" );
3559 }
3560 len += sprintf(buf+len,"%02X ", p[i] );
3561 }
3562 len += sprintf(buf+len,"\n" );
3563 return len;
3564 } // printf_hcf8
3565
3566 int printf_strct( char *s, char *buf, hcf_16* p );
3567 int printf_strct( char *s, char *buf, hcf_16* p ) {
3568
3569 int i, len;
3570
3571 len = sprintf(buf, "%s", s );
3572 while ( len < 20 ) len += sprintf(buf+len, " " );
3573 len += sprintf(buf+len,": " );
3574 for ( i = 0; i <= *p; i++ ) {
3575 if ( len % 80 > 75 ) {
3576 len += sprintf(buf+len,"\n" );
3577 }
3578 len += sprintf(buf+len,"%04X ", p[i] );
3579 }
3580 len += sprintf(buf+len,"\n" );
3581 return len;
3582 } // printf_strct
3583
3584 int scull_read_procmem(char *buf, char **start, off_t offset, int len, int *eof, void *data )
3585 {
3586 struct wl_private *lp = NULL;
3587 IFBP ifbp;
3588 CFG_HERMES_TALLIES_STRCT *p;
3589
3590 #define LIMIT (PAGE_SIZE-80) /* don't print any more after this size */
3591
3592 len=0;
3593
3594 lp = ((struct net_device *)data)->priv;
3595 if (lp == NULL) {
3596 len += sprintf(buf+len,"No wl_private in scull_read_procmem\n" );
3597 } else if ( lp->wlags49_type == 0 ){
3598 ifbp = &lp->hcfCtx;
3599 len += sprintf(buf+len,"Magic: 0x%04X\n", ifbp->IFB_Magic );
3600 len += sprintf(buf+len,"IOBase: 0x%04X\n", ifbp->IFB_IOBase );
3601 len += sprintf(buf+len,"LinkStat: 0x%04X\n", ifbp->IFB_LinkStat );
3602 len += sprintf(buf+len,"DSLinkStat: 0x%04X\n", ifbp->IFB_DSLinkStat );
3603 len += sprintf(buf+len,"TickIni: 0x%08lX\n", ifbp->IFB_TickIni );
3604 len += sprintf(buf+len,"TickCnt: 0x%04X\n", ifbp->IFB_TickCnt );
3605 len += sprintf(buf+len,"IntOffCnt: 0x%04X\n", ifbp->IFB_IntOffCnt );
3606 len += printf_hcf_16( "IFB_FWIdentity", &buf[len],
3607 &ifbp->IFB_FWIdentity.len, ifbp->IFB_FWIdentity.len + 1 );
3608 } else if ( lp->wlags49_type == 1 ) {
3609 len += sprintf(buf+len,"Channel: 0x%04X\n", lp->Channel );
3610 /****** len += sprintf(buf+len,"slock: %d\n", lp->slock ); */
3611 //x struct tq_struct "task: 0x%04X\n", lp->task );
3612 //x struct net_device_stats "stats: 0x%04X\n", lp->stats );
3613 #ifdef WIRELESS_EXT
3614 //x struct iw_statistics "wstats: 0x%04X\n", lp->wstats );
3615 //x len += sprintf(buf+len,"spy_number: 0x%04X\n", lp->spy_number );
3616 //x u_char spy_address[IW_MAX_SPY][ETH_ALEN];
3617 //x struct iw_quality spy_stat[IW_MAX_SPY];
3618 #endif // WIRELESS_EXT
3619 len += sprintf(buf+len,"IFB: 0x%p\n", &lp->hcfCtx );
3620 len += sprintf(buf+len,"flags: %#.8lX\n", lp->flags ); //;?use this format from now on
3621 len += sprintf(buf+len,"DebugFlag(wl_private) 0x%04X\n", lp->DebugFlag );
3622 #if DBG
3623 len += sprintf(buf+len,"DebugFlag (DbgInfo): 0x%08lX\n", DbgInfo->DebugFlag );
3624 #endif // DBG
3625 len += sprintf(buf+len,"is_registered: 0x%04X\n", lp->is_registered );
3626 //x CFG_DRV_INFO_STRCT "driverInfo: 0x%04X\n", lp->driverInfo );
3627 len += printf_strct( "driverInfo", &buf[len], (hcf_16*)&lp->driverInfo );
3628 //x CFG_IDENTITY_STRCT "driverIdentity: 0x%04X\n", lp->driverIdentity );
3629 len += printf_strct( "driverIdentity", &buf[len], (hcf_16*)&lp->driverIdentity );
3630 //x CFG_FW_IDENTITY_STRCT "StationIdentity: 0x%04X\n", lp->StationIdentity );
3631 len += printf_strct( "StationIdentity", &buf[len], (hcf_16*)&lp->StationIdentity );
3632 //x CFG_PRI_IDENTITY_STRCT "PrimaryIdentity: 0x%04X\n", lp->PrimaryIdentity );
3633 len += printf_strct( "PrimaryIdentity", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRIIdentity );
3634 len += printf_strct( "PrimarySupplier", &buf[len], (hcf_16*)&lp->hcfCtx.IFB_PRISup );
3635 //x CFG_PRI_IDENTITY_STRCT "NICIdentity: 0x%04X\n", lp->NICIdentity );
3636 len += printf_strct( "NICIdentity", &buf[len], (hcf_16*)&lp->NICIdentity );
3637 //x ltv_t "ltvRecord: 0x%04X\n", lp->ltvRecord );
3638 len += sprintf(buf+len,"txBytes: 0x%08lX\n", lp->txBytes );
3639 len += sprintf(buf+len,"maxPort: 0x%04X\n", lp->maxPort ); /* 0 for STA, 6 for AP */
3640 /* Elements used for async notification from hardware */
3641 //x RID_LOG_STRCT RidList[10];
3642 //x ltv_t "updatedRecord: 0x%04X\n", lp->updatedRecord );
3643 //x PROBE_RESP "ProbeResp: 0x%04X\n", lp->ProbeResp );
3644 //x ASSOC_STATUS_STRCT "assoc_stat: 0x%04X\n", lp->assoc_stat );
3645 //x SECURITY_STATUS_STRCT "sec_stat: 0x%04X\n", lp->sec_stat );
3646 //x u_char lookAheadBuf[WVLAN_MAX_LOOKAHEAD];
3647 len += sprintf(buf+len,"PortType: 0x%04X\n", lp->PortType ); // 1 - 3 (1 [Normal] | 3 [AdHoc])
3648 len += sprintf(buf+len,"Channel: 0x%04X\n", lp->Channel ); // 0 - 14 (0)
3649 //x hcf_16 TxRateControl[2];
3650 len += sprintf(buf+len,"TxRateControl[2]: 0x%04X 0x%04X\n",
3651 lp->TxRateControl[0], lp->TxRateControl[1] );
3652 len += sprintf(buf+len,"DistanceBetweenAPs: 0x%04X\n", lp->DistanceBetweenAPs ); // 1 - 3 (1)
3653 len += sprintf(buf+len,"RTSThreshold: 0x%04X\n", lp->RTSThreshold ); // 0 - 2347 (2347)
3654 len += sprintf(buf+len,"PMEnabled: 0x%04X\n", lp->PMEnabled ); // 0 - 2, 8001 - 8002 (0)
3655 len += sprintf(buf+len,"MicrowaveRobustness: 0x%04X\n", lp->MicrowaveRobustness );// 0 - 1 (0)
3656 len += sprintf(buf+len,"CreateIBSS: 0x%04X\n", lp->CreateIBSS ); // 0 - 1 (0)
3657 len += sprintf(buf+len,"MulticastReceive: 0x%04X\n", lp->MulticastReceive ); // 0 - 1 (1)
3658 len += sprintf(buf+len,"MaxSleepDuration: 0x%04X\n", lp->MaxSleepDuration ); // 0 - 65535 (100)
3659 //x hcf_8 MACAddress[ETH_ALEN];
3660 len += printf_hcf_8( "MACAddress", &buf[len], lp->MACAddress, ETH_ALEN );
3661 //x char NetworkName[HCF_MAX_NAME_LEN+1];
3662 len += sprintf(buf+len,"NetworkName: %.32s\n", lp->NetworkName );
3663 //x char StationName[HCF_MAX_NAME_LEN+1];
3664 len += sprintf(buf+len,"EnableEncryption: 0x%04X\n", lp->EnableEncryption ); // 0 - 1 (0)
3665 //x char Key1[MAX_KEY_LEN+1];
3666 len += printf_hcf_8( "Key1", &buf[len], lp->Key1, MAX_KEY_LEN );
3667 //x char Key2[MAX_KEY_LEN+1];
3668 //x char Key3[MAX_KEY_LEN+1];
3669 //x char Key4[MAX_KEY_LEN+1];
3670 len += sprintf(buf+len,"TransmitKeyID: 0x%04X\n", lp->TransmitKeyID ); // 1 - 4 (1)
3671 //x CFG_DEFAULT_KEYS_STRCT "DefaultKeys: 0x%04X\n", lp->DefaultKeys );
3672 //x u_char mailbox[MB_SIZE];
3673 //x char szEncryption[MAX_ENC_LEN];
3674 len += sprintf(buf+len,"driverEnable: 0x%04X\n", lp->driverEnable );
3675 len += sprintf(buf+len,"wolasEnable: 0x%04X\n", lp->wolasEnable );
3676 len += sprintf(buf+len,"atimWindow: 0x%04X\n", lp->atimWindow );
3677 len += sprintf(buf+len,"holdoverDuration: 0x%04X\n", lp->holdoverDuration );
3678 //x hcf_16 MulticastRate[2];
3679 len += sprintf(buf+len,"authentication: 0x%04X\n", lp->authentication ); // is this AP specific?
3680 len += sprintf(buf+len,"promiscuousMode: 0x%04X\n", lp->promiscuousMode );
3681 len += sprintf(buf+len,"DownloadFirmware: 0x%04X\n", lp->DownloadFirmware ); // 0 - 2 (0 [None] | 1 [STA] | 2 [AP])
3682 len += sprintf(buf+len,"AuthKeyMgmtSuite: 0x%04X\n", lp->AuthKeyMgmtSuite );
3683 len += sprintf(buf+len,"loadBalancing: 0x%04X\n", lp->loadBalancing );
3684 len += sprintf(buf+len,"mediumDistribution: 0x%04X\n", lp->mediumDistribution );
3685 len += sprintf(buf+len,"txPowLevel: 0x%04X\n", lp->txPowLevel );
3686 // len += sprintf(buf+len,"shortRetryLimit: 0x%04X\n", lp->shortRetryLimit );
3687 // len += sprintf(buf+len,"longRetryLimit: 0x%04X\n", lp->longRetryLimit );
3688 //x hcf_16 srsc[2];
3689 //x hcf_16 brsc[2];
3690 len += sprintf(buf+len,"connectionControl: 0x%04X\n", lp->connectionControl );
3691 //x //hcf_16 probeDataRates[2];
3692 len += sprintf(buf+len,"ownBeaconInterval: 0x%04X\n", lp->ownBeaconInterval );
3693 len += sprintf(buf+len,"coexistence: 0x%04X\n", lp->coexistence );
3694 //x WVLAN_FRAME "txF: 0x%04X\n", lp->txF );
3695 //x WVLAN_LFRAME txList[DEFAULT_NUM_TX_FRAMES];
3696 //x struct list_head "txFree: 0x%04X\n", lp->txFree );
3697 //x struct list_head txQ[WVLAN_MAX_TX_QUEUES];
3698 len += sprintf(buf+len,"netif_queue_on: 0x%04X\n", lp->netif_queue_on );
3699 len += sprintf(buf+len,"txQ_count: 0x%04X\n", lp->txQ_count );
3700 //x DESC_STRCT "desc_rx: 0x%04X\n", lp->desc_rx );
3701 //x DESC_STRCT "desc_tx: 0x%04X\n", lp->desc_tx );
3702 //x WVLAN_PORT_STATE "portState: 0x%04X\n", lp->portState );
3703 //x ScanResult "scan_results: 0x%04X\n", lp->scan_results );
3704 //x ProbeResult "probe_results: 0x%04X\n", lp->probe_results );
3705 len += sprintf(buf+len,"probe_num_aps: 0x%04X\n", lp->probe_num_aps );
3706 len += sprintf(buf+len,"use_dma: 0x%04X\n", lp->use_dma );
3707 //x DMA_STRCT "dma: 0x%04X\n", lp->dma );
3708 #ifdef USE_RTS
3709 len += sprintf(buf+len,"useRTS: 0x%04X\n", lp->useRTS );
3710 #endif // USE_RTS
3711 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
3712 //;?should we restore this to allow smaller memory footprint
3713 //;?I guess not. This should be brought under Debug mode only
3714 len += sprintf(buf+len,"DTIMPeriod: 0x%04X\n", lp->DTIMPeriod ); // 1 - 255 (1)
3715 len += sprintf(buf+len,"multicastPMBuffering: 0x%04X\n", lp->multicastPMBuffering );
3716 len += sprintf(buf+len,"RejectAny: 0x%04X\n", lp->RejectAny ); // 0 - 1 (0)
3717 len += sprintf(buf+len,"ExcludeUnencrypted: 0x%04X\n", lp->ExcludeUnencrypted ); // 0 - 1 (1)
3718 len += sprintf(buf+len,"intraBSSRelay: 0x%04X\n", lp->intraBSSRelay );
3719 len += sprintf(buf+len,"wlags49_type: 0x%08lX\n", lp->wlags49_type );
3720 #ifdef USE_WDS
3721 //x WVLAN_WDS_IF wds_port[NUM_WDS_PORTS];
3722 #endif // USE_WDS
3723 #endif // HCF_AP
3724 } else if ( lp->wlags49_type == 2 ){
3725 len += sprintf(buf+len,"tallies to be added\n" );
3726 //Hermes Tallies (IFB substructure) {
3727 p = &lp->hcfCtx.IFB_NIC_Tallies;
3728 len += sprintf(buf+len,"TxUnicastFrames: %08lX\n", p->TxUnicastFrames );
3729 len += sprintf(buf+len,"TxMulticastFrames: %08lX\n", p->TxMulticastFrames );
3730 len += sprintf(buf+len,"TxFragments: %08lX\n", p->TxFragments );
3731 len += sprintf(buf+len,"TxUnicastOctets: %08lX\n", p->TxUnicastOctets );
3732 len += sprintf(buf+len,"TxMulticastOctets: %08lX\n", p->TxMulticastOctets );
3733 len += sprintf(buf+len,"TxDeferredTransmissions: %08lX\n", p->TxDeferredTransmissions );
3734 len += sprintf(buf+len,"TxSingleRetryFrames: %08lX\n", p->TxSingleRetryFrames );
3735 len += sprintf(buf+len,"TxMultipleRetryFrames: %08lX\n", p->TxMultipleRetryFrames );
3736 len += sprintf(buf+len,"TxRetryLimitExceeded: %08lX\n", p->TxRetryLimitExceeded );
3737 len += sprintf(buf+len,"TxDiscards: %08lX\n", p->TxDiscards );
3738 len += sprintf(buf+len,"RxUnicastFrames: %08lX\n", p->RxUnicastFrames );
3739 len += sprintf(buf+len,"RxMulticastFrames: %08lX\n", p->RxMulticastFrames );
3740 len += sprintf(buf+len,"RxFragments: %08lX\n", p->RxFragments );
3741 len += sprintf(buf+len,"RxUnicastOctets: %08lX\n", p->RxUnicastOctets );
3742 len += sprintf(buf+len,"RxMulticastOctets: %08lX\n", p->RxMulticastOctets );
3743 len += sprintf(buf+len,"RxFCSErrors: %08lX\n", p->RxFCSErrors );
3744 len += sprintf(buf+len,"RxDiscardsNoBuffer: %08lX\n", p->RxDiscardsNoBuffer );
3745 len += sprintf(buf+len,"TxDiscardsWrongSA: %08lX\n", p->TxDiscardsWrongSA );
3746 len += sprintf(buf+len,"RxWEPUndecryptable: %08lX\n", p->RxWEPUndecryptable );
3747 len += sprintf(buf+len,"RxMsgInMsgFragments: %08lX\n", p->RxMsgInMsgFragments );
3748 len += sprintf(buf+len,"RxMsgInBadMsgFragments: %08lX\n", p->RxMsgInBadMsgFragments );
3749 len += sprintf(buf+len,"RxDiscardsWEPICVError: %08lX\n", p->RxDiscardsWEPICVError );
3750 len += sprintf(buf+len,"RxDiscardsWEPExcluded: %08lX\n", p->RxDiscardsWEPExcluded );
3751 #if (HCF_EXT) & HCF_EXT_TALLIES_FW
3752 //to be added ;?
3753 #endif // HCF_EXT_TALLIES_FW
3754 } else if ( lp->wlags49_type & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3755 #if DBG
3756 DbgInfo->DebugFlag = lp->wlags49_type & 0x7FFF;
3757 #endif // DBG
3758 lp->wlags49_type = 0; //default to IFB again ;?
3759 } else {
3760 len += sprintf(buf+len,"unknown value for wlags49_type: 0x%08lX\n", lp->wlags49_type );
3761 len += sprintf(buf+len,"0x0000 - IFB\n" );
3762 len += sprintf(buf+len,"0x0001 - wl_private\n" );
3763 len += sprintf(buf+len,"0x0002 - Tallies\n" );
3764 len += sprintf(buf+len,"0x8xxx - Change debufflag\n" );
3765 len += sprintf(buf+len,"ERROR 0001\nWARNING 0002\nNOTICE 0004\nTRACE 0008\n" );
3766 len += sprintf(buf+len,"VERBOSE 0010\nPARAM 0020\nBREAK 0040\nRX 0100\n" );
3767 len += sprintf(buf+len,"TX 0200\nDS 0400\n" );
3768 }
3769 return len;
3770 } // scull_read_procmem
3771
3772 static void proc_write(const char *name, write_proc_t *w, void *data)
3773 {
3774 struct proc_dir_entry * entry = create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
3775 if (entry) {
3776 entry->write_proc = w;
3777 entry->data = data;
3778 }
3779 } // proc_write
3780
3781 static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
3782 {
3783 static char proc_number[11];
3784 unsigned int nr = 0;
3785
3786 DBG_FUNC( "write_int" );
3787 DBG_ENTER( DbgInfo );
3788
3789 if (count > 9) {
3790 count = -EINVAL;
3791 } else if ( copy_from_user(proc_number, buffer, count) ) {
3792 count = -EFAULT;
3793 }
3794 if (count > 0 ) {
3795 proc_number[count] = 0;
3796 nr = simple_strtoul(proc_number , NULL, 0);
3797 *(unsigned int *)data = nr;
3798 if ( nr & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3799 #if DBG
3800 DbgInfo->DebugFlag = nr & 0x7FFF;
3801 #endif // DBG
3802 }
3803 }
3804 DBG_PRINT( "value: %08X\n", nr );
3805 DBG_LEAVE( DbgInfo );
3806 return count;
3807 } // write_int
3808
3809 #endif /* SCULL_USE_PROC */
3810
3811 #ifdef DN554
3812 #define RUN_AT(x) (jiffies+(x)) //"borrowed" from include/pcmcia/k_compat.h
3813 #define DS_OOR 0x8000 //Deepsleep OutOfRange Status
3814
3815 lp->timer_oor_cnt = DS_OOR;
3816 init_timer( &lp->timer_oor );
3817 lp->timer_oor.function = timer_oor;
3818 lp->timer_oor.data = (unsigned long)lp;
3819 lp->timer_oor.expires = RUN_AT( 3 * HZ );
3820 add_timer( &lp->timer_oor );
3821 printk( "<5>wl_enable: %ld\n", jiffies ); //;?remove me 1 day
3822 #endif //DN554
3823 #ifdef DN554
3824 /*******************************************************************************
3825 * timer_oor()
3826 *******************************************************************************
3827 *
3828 * DESCRIPTION:
3829 *
3830 *
3831 * PARAMETERS:
3832 *
3833 * arg - a u_long representing a pointer to a dev_link_t structure for the
3834 * device to be released.
3835 *
3836 * RETURNS:
3837 *
3838 * N/A
3839 *
3840 ******************************************************************************/
3841 void timer_oor( u_long arg )
3842 {
3843 struct wl_private *lp = (struct wl_private *)arg;
3844
3845 /*------------------------------------------------------------------------*/
3846
3847 DBG_FUNC( "timer_oor" );
3848 DBG_ENTER( DbgInfo );
3849 DBG_PARAM( DbgInfo, "arg", "0x%08lx", arg );
3850
3851 printk( "<5>timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt ); //;?remove me 1 day
3852 lp->timer_oor_cnt += 10;
3853 if ( (lp->timer_oor_cnt & ~DS_OOR) > 300 ) {
3854 lp->timer_oor_cnt = 300;
3855 }
3856 lp->timer_oor_cnt |= DS_OOR;
3857 init_timer( &lp->timer_oor );
3858 lp->timer_oor.function = timer_oor;
3859 lp->timer_oor.data = (unsigned long)lp;
3860 lp->timer_oor.expires = RUN_AT( (lp->timer_oor_cnt & ~DS_OOR) * HZ );
3861 add_timer( &lp->timer_oor );
3862
3863 DBG_LEAVE( DbgInfo );
3864 } // timer_oor
3865 #endif //DN554
3866
3867 MODULE_LICENSE("Dual BSD/GPL");