]>
Commit | Line | Data |
---|---|---|
68c0bdff HG |
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 | * | |
d36b6910 | 26 | * Copyright © 2003 Agere Systems Inc. |
68c0bdff HG |
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 | * | |
d36b6910 | 47 | * THIS SOFTWARE IS PROVIDED \93AS IS\94 AND ANY EXPRESS OR IMPLIED WARRANTIES, |
68c0bdff HG |
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 | ||
68c0bdff HG |
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> | |
9ffc93f2 | 89 | // // #include <asm/bitops.h> |
68c0bdff HG |
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 defintions | |
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 | ||
68c0bdff HG |
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 | ||
9b0131cb | 433 | /* Initialize states */ |
68c0bdff HG |
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 ); | |
2b6d83d6 AS |
468 | /* |
469 | DBG_PARAM(DbgInfo, PARM_NAME_NETWORK_ADDR, "\"%pM\"", | |
470 | PARM_NETWORK_ADDR); | |
471 | */ | |
68c0bdff HG |
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 ); | |
2b6d83d6 AS |
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); | |
68c0bdff HG |
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 ); | |
2b6d83d6 | 1181 | DBG_TRACE(DbgInfo, "Card MAC Address: %pM\n", lp->MACAddress); |
68c0bdff HG |
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 probelm 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 */ | |
2b6d83d6 AS |
1932 | /* |
1933 | DBG_TRACE(DbgInfo, "MAC Address : %pM\n", | |
1934 | lp->MACAddress); | |
1935 | */ | |
68c0bdff HG |
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 )); | |
9ef02300 DK |
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); | |
68c0bdff HG |
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 *)<v->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 *)<v->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 ); | |
2b6d83d6 AS |
3048 | DBG_TRACE(DbgInfo, "BSSID : %pM\n", |
3049 | aps[num_aps].bssid); | |
68c0bdff HG |
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 | ||
2b6d83d6 AS |
3108 | DBG_TRACE(DbgInfo, "(%s) address1 : %pM\n", |
3109 | lp->dev->name, probe_rsp->address1); | |
68c0bdff | 3110 | |
2b6d83d6 AS |
3111 | DBG_TRACE(DbgInfo, "(%s) address2 : %pM\n", |
3112 | lp->dev->name, probe_rsp->address2); | |
68c0bdff | 3113 | |
2b6d83d6 AS |
3114 | DBG_TRACE(DbgInfo, "(%s) BSSID : %pM\n", |
3115 | lp->dev->name, probe_rsp->BSSID); | |
68c0bdff HG |
3116 | |
3117 | DBG_TRACE( DbgInfo, "(%s) sequence : 0x%04x.\n", | |
3118 | lp->dev->name, probe_rsp->sequence ); | |
3119 | ||
2b6d83d6 AS |
3120 | DBG_TRACE(DbgInfo, "(%s) address4 : %pM\n", |
3121 | lp->dev->name, probe_rsp->address4); | |
68c0bdff HG |
3122 | |
3123 | DBG_TRACE( DbgInfo, "(%s) datalength : 0x%04x.\n", | |
3124 | lp->dev->name, probe_rsp->dataLength ); | |
3125 | ||
2b6d83d6 AS |
3126 | DBG_TRACE(DbgInfo, "(%s) DA : %pM\n", |
3127 | lp->dev->name, probe_rsp->DA); | |
68c0bdff | 3128 | |
2b6d83d6 AS |
3129 | DBG_TRACE(DbgInfo, "(%s) SA : %pM\n", |
3130 | lp->dev->name, probe_rsp->SA); | |
68c0bdff HG |
3131 | |
3132 | //DBG_TRACE( DbgInfo, "(%s) lenType : 0x%04x.\n", | |
3133 | // lp->dev->name, probe_rsp->lenType ); | |
3134 | ||
a113af9a AS |
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]); | |
68c0bdff HG |
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 | ||
2b6d83d6 AS |
3298 | DBG_TRACE(DbgInfo, "STA Address : %pM\n", |
3299 | as->staAddr); | |
68c0bdff HG |
3300 | |
3301 | if (( as->assocStatus == 2 ) && ( as->len == 8 )) { | |
2b6d83d6 AS |
3302 | DBG_TRACE(DbgInfo, "Old AP Address : %pM\n", |
3303 | as->oldApAddr); | |
68c0bdff HG |
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 | ||
2b6d83d6 AS |
3342 | DBG_TRACE(DbgInfo, "STA Address : %pM\n", |
3343 | ss->staAddr); | |
68c0bdff | 3344 | |
2b6d83d6 AS |
3345 | DBG_TRACE(DbgInfo, "Reason : 0x%04x\n", |
3346 | ss->reason); | |
68c0bdff HG |
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 | ||
491dbc8d JP |
3598 | lp = ((struct net_device *)data)->priv; |
3599 | if (lp == NULL) { | |
68c0bdff HG |
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; | |
9f648592 | 3800 | nr = simple_strtoul(proc_number , NULL, 0); |
68c0bdff HG |
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 ); | |
9b754b17 | 3825 | printk(KERN_NOTICE "wl_enable: %ld\n", jiffies ); //;?remove me 1 day |
68c0bdff HG |
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 | ||
9b754b17 | 3855 | printk(KERN_NOTICE "timer_oor: %ld 0x%04X\n", jiffies, lp->timer_oor_cnt ); //;?remove me 1 day |
68c0bdff HG |
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"); |