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