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