1 | /* |
2 | * Driver for KeyStream 11b/g wireless LAN |
3 | * |
4 | * ks_wlan_net.c |
5 | * $Id: ks_wlan_net.c 1020 2009-09-28 05:48:31Z sekine $ |
6 | * |
7 | * Copyright (C) 2005-2008 KeyStream Corp. |
8 | * Copyright (C) 2009 Renesas Technology Corp. |
9 | * |
10 | * This program is free software; you can redistribute it and/or modify |
11 | * it undr the terms of the GNU General Public License version 2 as |
12 | * published by the Free Sotware Foundation. |
13 | */ |
14 | |
15 | #include <linux/version.h> |
16 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) |
17 | #include <linux/config.h> |
18 | #endif |
19 | #include <linux/module.h> |
20 | #include <linux/kernel.h> |
21 | #include <linux/compiler.h> |
22 | #include <linux/init.h> |
23 | #include <linux/ioport.h> |
24 | #include <linux/netdevice.h> |
25 | #include <linux/etherdevice.h> |
26 | #include <linux/if_arp.h> |
27 | #include <linux/rtnetlink.h> |
28 | #include <linux/delay.h> |
29 | #include <linux/completion.h> |
30 | #include <linux/mii.h> |
31 | #include <linux/pci.h> |
32 | #include <linux/ctype.h> |
33 | #include <linux/timer.h> |
34 | #include <asm/atomic.h> |
35 | #include <linux/io.h> |
36 | #include <asm/uaccess.h> |
37 | |
38 | static int wep_on_off; |
39 | #define WEP_OFF 0 |
40 | #define WEP_ON_64BIT 1 |
41 | #define WEP_ON_128BIT 2 |
42 | |
43 | #include "ks_wlan.h" |
44 | #include "ks_hostif.h" |
45 | #include "ks_wlan_ioctl.h" |
46 | #include "ks_debug.h" |
47 | |
48 | /* Include Wireless Extension definition and check version */ |
49 | #include <linux/wireless.h> |
50 | #define WIRELESS_SPY /* enable iwspy support */ |
51 | #include <net/iw_handler.h> /* New driver API */ |
52 | |
53 | #ifdef WIRELESS_EXT |
54 | /* Frequency list (map channels to frequencies) */ |
55 | static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, |
56 | 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; |
57 | |
58 | /* A few details needed for WEP (Wireless Equivalent Privacy) */ |
59 | #define MAX_KEY_SIZE 13 /* 128 (?) bits */ |
60 | #define MIN_KEY_SIZE 5 /* 40 bits RC4 - WEP */ |
61 | typedef struct wep_key_t { |
62 | u16 len; |
63 | u8 key[16]; /* 40-bit and 104-bit keys */ |
64 | } wep_key_t; |
65 | |
66 | /* Backward compatibility */ |
67 | #ifndef IW_ENCODE_NOKEY |
68 | #define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */ |
69 | #define IW_ENCODE_MODE (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN) |
70 | #endif /* IW_ENCODE_NOKEY */ |
71 | |
72 | /* List of Wireless Handlers (new API) */ |
73 | static const struct iw_handler_def ks_wlan_handler_def; |
74 | |
75 | #define KSC_OPNOTSUPP /* Operation Not Support*/ |
76 | |
77 | #endif /* WIRELESS_EXT */ |
78 | |
79 | /* |
80 | * function prototypes |
81 | */ |
82 | extern int ks_wlan_hw_tx(ks_wlan_private *priv, void *p, unsigned long size, |
83 | void (*complete_handler)(void *arg1, void *arg2), |
84 | void *arg1, |
85 | void *arg2 ); |
86 | static int ks_wlan_open (struct net_device *dev); |
87 | static void ks_wlan_tx_timeout (struct net_device *dev); |
88 | static int ks_wlan_start_xmit (struct sk_buff *skb, struct net_device *dev); |
89 | static int ks_wlan_close (struct net_device *dev); |
90 | static void ks_wlan_set_multicast_list (struct net_device *dev); |
91 | static struct net_device_stats *ks_wlan_get_stats (struct net_device *dev); |
92 | static int ks_wlan_set_mac_address(struct net_device *dev, void *addr); |
93 | static int ks_wlan_netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
94 | |
95 | static atomic_t update_phyinfo; |
96 | static struct timer_list update_phyinfo_timer; |
97 | static |
98 | int ks_wlan_update_phy_information(ks_wlan_private *priv) |
99 | { |
100 | struct iw_statistics *wstats = &priv->wstats; |
101 | |
102 | DPRINTK(4, "in_interrupt = %ld\n", in_interrupt()); |
103 | |
104 | if (priv->dev_state < DEVICE_STATE_READY) { |
105 | return -1; /* not finished initialize */ |
106 | } |
107 | if(atomic_read(&update_phyinfo)) |
108 | return 1; |
109 | |
110 | /* The status */ |
111 | wstats->status = priv->reg.operation_mode; /* Operation mode */ |
112 | |
113 | /* Signal quality and co. But where is the noise level ??? */ |
114 | hostif_sme_enqueue(priv, SME_PHY_INFO_REQUEST); |
115 | |
116 | /* interruptible_sleep_on_timeout(&priv->confirm_wait, HZ/2); */ |
117 | if(!wait_for_completion_interruptible_timeout(&priv->confirm_wait,HZ/2)){ |
118 | DPRINTK(1,"wait time out!!\n"); |
119 | } |
120 | |
121 | atomic_inc(&update_phyinfo); |
122 | update_phyinfo_timer.expires = jiffies + HZ; /* 1sec */ |
123 | add_timer(&update_phyinfo_timer); |
124 | |
125 | return 0; |
126 | } |
127 | |
128 | static |
129 | void ks_wlan_update_phyinfo_timeout(unsigned long ptr) |
130 | { |
131 | DPRINTK(4, "in_interrupt = %ld\n", in_interrupt()); |
132 | atomic_set(&update_phyinfo,0); |
133 | } |
134 | |
135 | int ks_wlan_setup_parameter(ks_wlan_private *priv, unsigned int commit_flag) |
136 | { |
137 | DPRINTK(2,"\n"); |
138 | |
139 | hostif_sme_enqueue(priv, SME_STOP_REQUEST); |
140 | |
141 | if(commit_flag & SME_RTS) |
142 | hostif_sme_enqueue(priv, SME_RTS_THRESHOLD_REQUEST); |
143 | if(commit_flag & SME_FRAG) |
144 | hostif_sme_enqueue(priv, SME_FRAGMENTATION_THRESHOLD_REQUEST); |
145 | |
146 | if(commit_flag & SME_WEP_INDEX) |
147 | hostif_sme_enqueue(priv, SME_WEP_INDEX_REQUEST); |
148 | if(commit_flag & SME_WEP_VAL1) |
149 | hostif_sme_enqueue(priv, SME_WEP_KEY1_REQUEST); |
150 | if(commit_flag & SME_WEP_VAL2) |
151 | hostif_sme_enqueue(priv, SME_WEP_KEY2_REQUEST); |
152 | if(commit_flag & SME_WEP_VAL3) |
153 | hostif_sme_enqueue(priv, SME_WEP_KEY3_REQUEST); |
154 | if(commit_flag & SME_WEP_VAL4) |
155 | hostif_sme_enqueue(priv, SME_WEP_KEY4_REQUEST); |
156 | if(commit_flag & SME_WEP_FLAG) |
157 | hostif_sme_enqueue(priv, SME_WEP_FLAG_REQUEST); |
158 | |
159 | if(commit_flag & SME_RSN){ |
160 | hostif_sme_enqueue(priv, SME_RSN_ENABLED_REQUEST); |
161 | hostif_sme_enqueue(priv, SME_RSN_MODE_REQUEST); |
162 | } |
163 | if(commit_flag & SME_RSN_MULTICAST) |
164 | hostif_sme_enqueue(priv, SME_RSN_MCAST_REQUEST); |
165 | if(commit_flag & SME_RSN_UNICAST) |
166 | hostif_sme_enqueue(priv, SME_RSN_UCAST_REQUEST); |
167 | if(commit_flag & SME_RSN_AUTH) |
168 | hostif_sme_enqueue(priv, SME_RSN_AUTH_REQUEST); |
169 | |
170 | hostif_sme_enqueue(priv, SME_MODE_SET_REQUEST); |
171 | |
172 | hostif_sme_enqueue(priv, SME_START_REQUEST); |
173 | |
174 | return 0; |
175 | } |
176 | |
177 | #ifdef WIRELESS_EXT |
178 | /* |
179 | * Initial Wireless Extension code for Ks_Wlannet driver by : |
180 | * Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00 |
181 | * Conversion to new driver API by : |
182 | * Jean Tourrilhes <jt@hpl.hp.com> - HPL - 26 March 02 |
183 | * Javier also did a good amount of work here, adding some new extensions |
184 | * and fixing my code. Let's just say that without him this code just |
185 | * would not work at all... - Jean II |
186 | */ |
187 | |
188 | /*------------------------------------------------------------------*/ |
189 | /* Wireless Handler : get protocol name */ |
190 | static int ks_wlan_get_name(struct net_device *dev, struct iw_request_info *info, |
191 | char *cwrq, char *extra) |
192 | { |
193 | ks_wlan_private *priv = (ks_wlan_private *) netdev_priv(dev); |
194 | |
195 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
196 | |
197 | if (priv->dev_state < DEVICE_STATE_READY) { |
198 | strcpy(cwrq, "NOT READY!"); |
199 | } |
200 | else if(priv->reg.phy_type == D_11B_ONLY_MODE){ |
201 | strcpy(cwrq, "IEEE 802.11b"); |
202 | } |
203 | else if(priv->reg.phy_type == D_11G_ONLY_MODE){ |
204 | strcpy(cwrq, "IEEE 802.11g"); |
205 | } |
206 | else { |
207 | strcpy(cwrq, "IEEE 802.11b/g"); |
208 | } |
209 | |
210 | return 0; |
211 | } |
212 | |
213 | /*------------------------------------------------------------------*/ |
214 | /* Wireless Handler : set frequency */ |
215 | static int ks_wlan_set_freq(struct net_device *dev, struct iw_request_info *info, |
216 | struct iw_freq *fwrq, char *extra) |
217 | { |
218 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
219 | int rc = -EINPROGRESS; /* Call commit handler */ |
220 | |
221 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
222 | |
223 | /* If setting by frequency, convert to a channel */ |
224 | if((fwrq->e == 1) && |
225 | (fwrq->m >= (int) 2.412e8) && |
226 | (fwrq->m <= (int) 2.487e8)) { |
227 | int f = fwrq->m / 100000; |
228 | int c = 0; |
229 | while((c < 14) && (f != frequency_list[c])) |
230 | c++; |
231 | /* Hack to fall through... */ |
232 | fwrq->e = 0; |
233 | fwrq->m = c + 1; |
234 | } |
235 | /* Setting by channel number */ |
236 | if((fwrq->m > 1000) || (fwrq->e > 0)) |
237 | rc = -EOPNOTSUPP; |
238 | else { |
239 | int channel = fwrq->m; |
240 | /* We should do a better check than that, |
241 | * based on the card capability !!! */ |
242 | if((channel < 1) || (channel > 14)) { |
243 | printk(KERN_DEBUG "%s: New channel value of %d is invalid!\n", dev->name, fwrq->m); |
244 | rc = -EINVAL; |
245 | } else { |
246 | /* Yes ! We can set it !!! */ |
247 | priv->reg.channel = (u8)(channel); |
248 | priv->need_commit |= SME_MODE_SET; |
249 | } |
250 | } |
251 | |
252 | return rc; |
253 | } |
254 | |
255 | /*------------------------------------------------------------------*/ |
256 | /* Wireless Handler : get frequency */ |
257 | static int ks_wlan_get_freq(struct net_device *dev, struct iw_request_info *info, |
258 | struct iw_freq *fwrq, char *extra) |
259 | { |
260 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
261 | int f; |
262 | |
263 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
264 | |
265 | if((priv->connect_status & CONNECT_STATUS_MASK) == CONNECT_STATUS){ |
266 | f = (int)priv->current_ap.channel; |
267 | } |
268 | else |
269 | f = (int)priv->reg.channel; |
270 | fwrq->m = frequency_list[f-1] * 100000; |
271 | fwrq->e = 1; |
272 | |
273 | return 0; |
274 | } |
275 | |
276 | /*------------------------------------------------------------------*/ |
277 | /* Wireless Handler : set ESSID */ |
278 | static int ks_wlan_set_essid(struct net_device *dev, struct iw_request_info *info, |
279 | struct iw_point *dwrq, char *extra) |
280 | { |
281 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
282 | size_t len; |
283 | |
284 | DPRINTK(2," %d\n", dwrq->flags); |
285 | |
286 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
287 | |
288 | /* Check if we asked for `any' */ |
289 | if(dwrq->flags == 0) { |
290 | /* Just send an empty SSID list */ |
291 | memset(priv->reg.ssid.body, 0, sizeof(priv->reg.ssid.body)); |
292 | priv->reg.ssid.size = 0; |
293 | } else { |
294 | #if 1 |
295 | len = dwrq->length; |
296 | /* iwconfig uses nul termination in SSID.. */ |
297 | if (len > 0 && extra[len - 1] == '\0') |
298 | len--; |
299 | |
300 | /* Check the size of the string */ |
301 | if(len > IW_ESSID_MAX_SIZE) { |
302 | return -EINVAL; |
303 | } |
304 | #else |
305 | /* Check the size of the string */ |
306 | if(dwrq->length > IW_ESSID_MAX_SIZE+1) { |
307 | return -E2BIG ; |
308 | } |
309 | #endif |
310 | |
311 | /* Set the SSID */ |
312 | memset(priv->reg.ssid.body, 0, sizeof(priv->reg.ssid.body)); |
313 | |
314 | #if 1 |
315 | memcpy(priv->reg.ssid.body, extra, len); |
316 | priv->reg.ssid.size = len; |
317 | #else |
318 | memcpy(priv->reg.ssid.body, extra, dwrq->length); |
319 | priv->reg.ssid.size = dwrq->length; |
320 | #endif |
321 | } |
322 | /* Write it to the card */ |
323 | priv->need_commit |= SME_MODE_SET; |
324 | |
325 | // return -EINPROGRESS; /* Call commit handler */ |
326 | ks_wlan_setup_parameter(priv, priv->need_commit); |
327 | priv->need_commit=0; |
328 | return 0; |
329 | } |
330 | |
331 | /*------------------------------------------------------------------*/ |
332 | /* Wireless Handler : get ESSID */ |
333 | static int ks_wlan_get_essid(struct net_device *dev, struct iw_request_info *info, |
334 | struct iw_point *dwrq, char *extra) |
335 | { |
336 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
337 | |
338 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
339 | |
340 | /* Note : if dwrq->flags != 0, we should |
341 | * get the relevant SSID from the SSID list... */ |
342 | |
343 | if(priv->reg.ssid.size){ |
344 | /* Get the current SSID */ |
345 | memcpy(extra, priv->reg.ssid.body, priv->reg.ssid.size); |
346 | #if 0 |
347 | extra[priv->reg.ssid.size] = '\0'; |
348 | #endif |
349 | /* If none, we may want to get the one that was set */ |
350 | |
351 | /* Push it out ! */ |
352 | #if 1 |
353 | dwrq->length = priv->reg.ssid.size; |
354 | #else |
355 | dwrq->length = priv->reg.ssid.size+1; |
356 | #endif |
357 | dwrq->flags = 1; /* active */ |
358 | }else{ |
359 | #if 1 |
360 | dwrq->length = 0; |
361 | #else |
362 | extra[0] = '\0'; |
363 | dwrq->length = 1; |
364 | #endif |
365 | dwrq->flags = 0; /* ANY */ |
366 | } |
367 | |
368 | return 0; |
369 | } |
370 | |
371 | /*------------------------------------------------------------------*/ |
372 | /* Wireless Handler : set AP address */ |
373 | static int ks_wlan_set_wap(struct net_device *dev, struct iw_request_info *info, |
374 | struct sockaddr *ap_addr, char *extra) |
375 | { |
376 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
377 | |
378 | DPRINTK(2,"\n"); |
379 | |
380 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
381 | |
382 | if (priv->reg.operation_mode == MODE_ADHOC || |
383 | priv->reg.operation_mode == MODE_INFRASTRUCTURE) { |
384 | memcpy(priv->reg.bssid, (u8 *)&ap_addr->sa_data, ETH_ALEN); |
385 | |
386 | if (is_valid_ether_addr((u8 *)priv->reg.bssid)) { |
387 | priv->need_commit |= SME_MODE_SET; |
388 | } |
389 | } |
390 | else { |
391 | memset(priv->reg.bssid, 0x0, ETH_ALEN); |
392 | return -EOPNOTSUPP; |
393 | } |
394 | |
395 | DPRINTK(2, "bssid = %02x:%02x:%02x:%02x:%02x:%02x\n", |
396 | priv->reg.bssid[0],priv->reg.bssid[1],priv->reg.bssid[2], |
397 | priv->reg.bssid[3],priv->reg.bssid[4],priv->reg.bssid[5]); |
398 | |
399 | /* Write it to the card */ |
400 | if (priv->need_commit) { |
401 | priv->need_commit |= SME_MODE_SET; |
402 | return -EINPROGRESS; /* Call commit handler */ |
403 | } |
404 | return 0; |
405 | } |
406 | |
407 | /*------------------------------------------------------------------*/ |
408 | /* Wireless Handler : get AP address */ |
409 | static int ks_wlan_get_wap(struct net_device *dev, struct iw_request_info *info, |
410 | struct sockaddr *awrq, char *extra) |
411 | { |
412 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
413 | |
414 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
415 | |
416 | if((priv->connect_status & CONNECT_STATUS_MASK) == CONNECT_STATUS){ |
417 | memcpy(awrq->sa_data, &(priv->current_ap.bssid[0]), ETH_ALEN); |
418 | } |
419 | else{ |
420 | memset(awrq->sa_data, 0, ETH_ALEN); |
421 | } |
422 | |
423 | awrq->sa_family = ARPHRD_ETHER; |
424 | |
425 | return 0; |
426 | } |
427 | |
428 | /*------------------------------------------------------------------*/ |
429 | /* Wireless Handler : set Nickname */ |
430 | static int ks_wlan_set_nick(struct net_device *dev, struct iw_request_info *info, |
431 | struct iw_point *dwrq, char *extra) |
432 | { |
433 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
434 | |
435 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
436 | |
437 | /* Check the size of the string */ |
438 | if(dwrq->length > 16 + 1) { |
439 | return -E2BIG; |
440 | } |
441 | memset(priv->nick, 0, sizeof(priv->nick)); |
442 | memcpy(priv->nick, extra, dwrq->length); |
443 | |
444 | return -EINPROGRESS; /* Call commit handler */ |
445 | } |
446 | |
447 | /*------------------------------------------------------------------*/ |
448 | /* Wireless Handler : get Nickname */ |
449 | static int ks_wlan_get_nick(struct net_device *dev, struct iw_request_info *info, |
450 | struct iw_point *dwrq, char *extra) |
451 | { |
452 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
453 | |
454 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
455 | |
456 | strncpy(extra, priv->nick, 16); |
457 | extra[16] = '\0'; |
458 | dwrq->length = strlen(extra) + 1; |
459 | |
460 | return 0; |
461 | } |
462 | |
463 | /*------------------------------------------------------------------*/ |
464 | /* Wireless Handler : set Bit-Rate */ |
465 | static int ks_wlan_set_rate(struct net_device *dev, struct iw_request_info *info, |
466 | struct iw_param *vwrq, char *extra) |
467 | { |
468 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
469 | int i = 0; |
470 | |
471 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
472 | |
473 | if(priv->reg.phy_type == D_11B_ONLY_MODE){ |
474 | if(vwrq->fixed == 1) { |
475 | switch(vwrq->value){ |
476 | case 11000000: |
477 | case 5500000: |
478 | priv->reg.rate_set.body[0] = (uint8_t)(vwrq->value/500000); |
479 | break; |
480 | case 2000000: |
481 | case 1000000: |
482 | priv->reg.rate_set.body[0] = ((uint8_t)(vwrq->value/500000))|BASIC_RATE; |
483 | break; |
484 | default: |
485 | return -EINVAL; |
486 | } |
487 | priv->reg.tx_rate = TX_RATE_FIXED; |
488 | priv->reg.rate_set.size = 1; |
489 | }else{ /* vwrq->fixed == 0 */ |
490 | if(vwrq->value > 0){ |
491 | switch(vwrq->value){ |
492 | case 11000000: |
493 | priv->reg.rate_set.body[3] = TX_RATE_11M; i++; |
494 | case 5500000: |
495 | priv->reg.rate_set.body[2] = TX_RATE_5M; i++; |
496 | case 2000000: |
497 | priv->reg.rate_set.body[1] = TX_RATE_2M|BASIC_RATE; i++; |
498 | case 1000000: |
499 | priv->reg.rate_set.body[0] = TX_RATE_1M|BASIC_RATE; i++; |
500 | break; |
501 | default: |
502 | return -EINVAL; |
503 | } |
504 | priv->reg.tx_rate = TX_RATE_MANUAL_AUTO; |
505 | priv->reg.rate_set.size = i; |
506 | }else{ |
507 | priv->reg.rate_set.body[3] = TX_RATE_11M; |
508 | priv->reg.rate_set.body[2] = TX_RATE_5M; |
509 | priv->reg.rate_set.body[1] = TX_RATE_2M|BASIC_RATE; |
510 | priv->reg.rate_set.body[0] = TX_RATE_1M|BASIC_RATE; |
511 | priv->reg.tx_rate = TX_RATE_FULL_AUTO; |
512 | priv->reg.rate_set.size = 4; |
513 | } |
514 | } |
515 | }else{ /* D_11B_ONLY_MODE or D_11BG_COMPATIBLE_MODE */ |
516 | if(vwrq->fixed == 1) { |
517 | switch(vwrq->value){ |
518 | case 54000000: |
519 | case 48000000: |
520 | case 36000000: |
521 | case 18000000: |
522 | case 9000000: |
523 | priv->reg.rate_set.body[0] = (uint8_t)(vwrq->value/500000); |
524 | break; |
525 | case 24000000: |
526 | case 12000000: |
527 | case 11000000: |
528 | case 6000000: |
529 | case 5500000: |
530 | case 2000000: |
531 | case 1000000: |
532 | priv->reg.rate_set.body[0] = ((uint8_t)(vwrq->value/500000))|BASIC_RATE; |
533 | break; |
534 | default: |
535 | return -EINVAL; |
536 | } |
537 | priv->reg.tx_rate = TX_RATE_FIXED; |
538 | priv->reg.rate_set.size = 1; |
539 | }else{ /* vwrq->fixed == 0 */ |
540 | if(vwrq->value > 0){ |
541 | switch(vwrq->value){ |
542 | case 54000000: |
543 | priv->reg.rate_set.body[11] = TX_RATE_54M; i++; |
544 | case 48000000: |
545 | priv->reg.rate_set.body[10] = TX_RATE_48M; i++; |
546 | case 36000000: |
547 | priv->reg.rate_set.body[9] = TX_RATE_36M; i++; |
548 | case 24000000: case 18000000: case 12000000: |
549 | case 11000000: case 9000000: case 6000000: |
550 | if(vwrq->value == 24000000){ |
551 | priv->reg.rate_set.body[8] = TX_RATE_18M; i++; |
552 | priv->reg.rate_set.body[7] = TX_RATE_9M; i++; |
553 | priv->reg.rate_set.body[6] = TX_RATE_24M|BASIC_RATE; i++; |
554 | priv->reg.rate_set.body[5] = TX_RATE_12M|BASIC_RATE; i++; |
555 | priv->reg.rate_set.body[4] = TX_RATE_6M|BASIC_RATE; i++; |
556 | priv->reg.rate_set.body[3] = TX_RATE_11M|BASIC_RATE; i++; |
557 | }else if(vwrq->value == 18000000){ |
558 | priv->reg.rate_set.body[7] = TX_RATE_18M; i++; |
559 | priv->reg.rate_set.body[6] = TX_RATE_9M; i++; |
560 | priv->reg.rate_set.body[5] = TX_RATE_12M|BASIC_RATE; i++; |
561 | priv->reg.rate_set.body[4] = TX_RATE_6M|BASIC_RATE; i++; |
562 | priv->reg.rate_set.body[3] = TX_RATE_11M|BASIC_RATE; i++; |
563 | }else if(vwrq->value == 12000000){ |
564 | priv->reg.rate_set.body[6] = TX_RATE_9M; i++; |
565 | priv->reg.rate_set.body[5] = TX_RATE_12M|BASIC_RATE; i++; |
566 | priv->reg.rate_set.body[4] = TX_RATE_6M|BASIC_RATE; i++; |
567 | priv->reg.rate_set.body[3] = TX_RATE_11M|BASIC_RATE; i++; |
568 | }else if(vwrq->value == 11000000){ |
569 | priv->reg.rate_set.body[5] = TX_RATE_9M; i++; |
570 | priv->reg.rate_set.body[4] = TX_RATE_6M|BASIC_RATE; i++; |
571 | priv->reg.rate_set.body[3] = TX_RATE_11M|BASIC_RATE; i++; |
572 | }else if(vwrq->value == 9000000){ |
573 | priv->reg.rate_set.body[4] = TX_RATE_9M; i++; |
574 | priv->reg.rate_set.body[3] = TX_RATE_6M|BASIC_RATE; i++; |
575 | }else{ /* vwrq->value == 6000000 */ |
576 | priv->reg.rate_set.body[3] = TX_RATE_6M|BASIC_RATE; i++; |
577 | } |
578 | case 5500000: |
579 | priv->reg.rate_set.body[2] = TX_RATE_5M|BASIC_RATE; i++; |
580 | case 2000000: |
581 | priv->reg.rate_set.body[1] = TX_RATE_2M|BASIC_RATE; i++; |
582 | case 1000000: |
583 | priv->reg.rate_set.body[0] = TX_RATE_1M|BASIC_RATE; i++; |
584 | break; |
585 | default: |
586 | return -EINVAL; |
587 | } |
588 | priv->reg.tx_rate = TX_RATE_MANUAL_AUTO; |
589 | priv->reg.rate_set.size = i; |
590 | }else{ |
591 | priv->reg.rate_set.body[11] = TX_RATE_54M; |
592 | priv->reg.rate_set.body[10] = TX_RATE_48M; |
593 | priv->reg.rate_set.body[9] = TX_RATE_36M; |
594 | priv->reg.rate_set.body[8] = TX_RATE_18M; |
595 | priv->reg.rate_set.body[7] = TX_RATE_9M; |
596 | priv->reg.rate_set.body[6] = TX_RATE_24M|BASIC_RATE; |
597 | priv->reg.rate_set.body[5] = TX_RATE_12M|BASIC_RATE; |
598 | priv->reg.rate_set.body[4] = TX_RATE_6M|BASIC_RATE; |
599 | priv->reg.rate_set.body[3] = TX_RATE_11M|BASIC_RATE; |
600 | priv->reg.rate_set.body[2] = TX_RATE_5M|BASIC_RATE; |
601 | priv->reg.rate_set.body[1] = TX_RATE_2M|BASIC_RATE; |
602 | priv->reg.rate_set.body[0] = TX_RATE_1M|BASIC_RATE; |
603 | priv->reg.tx_rate = TX_RATE_FULL_AUTO; |
604 | priv->reg.rate_set.size = 12; |
605 | } |
606 | } |
607 | } |
608 | |
609 | priv->need_commit |= SME_MODE_SET; |
610 | |
611 | return -EINPROGRESS; /* Call commit handler */ |
612 | } |
613 | |
614 | /*------------------------------------------------------------------*/ |
615 | /* Wireless Handler : get Bit-Rate */ |
616 | static int ks_wlan_get_rate(struct net_device *dev, struct iw_request_info *info, |
617 | struct iw_param *vwrq, char *extra) |
618 | { |
619 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
620 | |
621 | DPRINTK(2, "in_interrupt = %ld update_phyinfo = %d\n", |
622 | in_interrupt(),atomic_read(&update_phyinfo)); |
623 | |
624 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
625 | |
626 | if(!atomic_read(&update_phyinfo)){ |
627 | ks_wlan_update_phy_information(priv); |
628 | } |
629 | vwrq->value = ((priv->current_rate) & RATE_MASK) * 500000; |
630 | if(priv->reg.tx_rate == TX_RATE_FIXED) |
631 | vwrq->fixed = 1; |
632 | else |
633 | vwrq->fixed = 0; |
634 | |
635 | return 0; |
636 | } |
637 | |
638 | /*------------------------------------------------------------------*/ |
639 | /* Wireless Handler : set RTS threshold */ |
640 | static int ks_wlan_set_rts(struct net_device *dev, struct iw_request_info *info, |
641 | struct iw_param *vwrq, char *extra) |
642 | { |
643 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
644 | int rthr = vwrq->value; |
645 | |
646 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
647 | |
648 | if(vwrq->disabled) |
649 | rthr = 2347; |
650 | if((rthr < 0) || (rthr > 2347)) { |
651 | return -EINVAL; |
652 | } |
653 | priv->reg.rts = rthr; |
654 | priv->need_commit |= SME_RTS; |
655 | |
656 | return -EINPROGRESS; /* Call commit handler */ |
657 | } |
658 | |
659 | /*------------------------------------------------------------------*/ |
660 | /* Wireless Handler : get RTS threshold */ |
661 | static int ks_wlan_get_rts(struct net_device *dev, struct iw_request_info *info, |
662 | struct iw_param *vwrq, char *extra) |
663 | { |
664 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
665 | |
666 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
667 | |
668 | vwrq->value = priv->reg.rts; |
669 | vwrq->disabled = (vwrq->value >= 2347); |
670 | vwrq->fixed = 1; |
671 | |
672 | return 0; |
673 | } |
674 | |
675 | /*------------------------------------------------------------------*/ |
676 | /* Wireless Handler : set Fragmentation threshold */ |
677 | static int ks_wlan_set_frag(struct net_device *dev, struct iw_request_info *info, |
678 | struct iw_param *vwrq, char *extra) |
679 | { |
680 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
681 | int fthr = vwrq->value; |
682 | |
683 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
684 | |
685 | if(vwrq->disabled) |
686 | fthr = 2346; |
687 | if((fthr < 256) || (fthr > 2346)) { |
688 | return -EINVAL; |
689 | } |
690 | fthr &= ~0x1; /* Get an even value - is it really needed ??? */ |
691 | priv->reg.fragment = fthr; |
692 | priv->need_commit |= SME_FRAG; |
693 | |
694 | return -EINPROGRESS; /* Call commit handler */ |
695 | } |
696 | |
697 | /*------------------------------------------------------------------*/ |
698 | /* Wireless Handler : get Fragmentation threshold */ |
699 | static int ks_wlan_get_frag(struct net_device *dev, struct iw_request_info *info, |
700 | struct iw_param *vwrq, char *extra) |
701 | { |
702 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
703 | |
704 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
705 | |
706 | vwrq->value = priv->reg.fragment; |
707 | vwrq->disabled = (vwrq->value >= 2346); |
708 | vwrq->fixed = 1; |
709 | |
710 | return 0; |
711 | } |
712 | |
713 | /*------------------------------------------------------------------*/ |
714 | /* Wireless Handler : set Mode of Operation */ |
715 | static int ks_wlan_set_mode(struct net_device *dev, struct iw_request_info *info, |
716 | __u32 *uwrq, char *extra) |
717 | { |
718 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
719 | |
720 | DPRINTK(2,"mode=%d\n",*uwrq); |
721 | |
722 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
723 | |
724 | switch(*uwrq) { |
725 | case IW_MODE_ADHOC: |
726 | priv->reg.operation_mode = MODE_ADHOC; |
727 | priv->need_commit |= SME_MODE_SET; |
728 | break; |
729 | case IW_MODE_INFRA: |
730 | priv->reg.operation_mode = MODE_INFRASTRUCTURE; |
731 | priv->need_commit |= SME_MODE_SET; |
732 | break; |
733 | case IW_MODE_AUTO: |
734 | case IW_MODE_MASTER: |
735 | case IW_MODE_REPEAT: |
736 | case IW_MODE_SECOND: |
737 | case IW_MODE_MONITOR: |
738 | default: |
739 | return -EINVAL; |
740 | } |
741 | |
742 | return -EINPROGRESS; /* Call commit handler */ |
743 | } |
744 | |
745 | /*------------------------------------------------------------------*/ |
746 | /* Wireless Handler : get Mode of Operation */ |
747 | static int ks_wlan_get_mode(struct net_device *dev, struct iw_request_info *info, |
748 | __u32 *uwrq, char *extra) |
749 | { |
750 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
751 | |
752 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
753 | |
754 | /* If not managed, assume it's ad-hoc */ |
755 | switch (priv->reg.operation_mode) { |
756 | case MODE_INFRASTRUCTURE: |
757 | *uwrq = IW_MODE_INFRA; |
758 | break; |
759 | case MODE_ADHOC: |
760 | *uwrq = IW_MODE_ADHOC; |
761 | break; |
762 | default: |
763 | *uwrq = IW_MODE_ADHOC; |
764 | } |
765 | |
766 | return 0; |
767 | } |
768 | |
769 | /*------------------------------------------------------------------*/ |
770 | /* Wireless Handler : set Encryption Key */ |
771 | static int ks_wlan_set_encode(struct net_device *dev, struct iw_request_info *info, |
772 | struct iw_point *dwrq, char *extra) |
773 | { |
774 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
775 | |
776 | wep_key_t key; |
777 | int index = (dwrq->flags & IW_ENCODE_INDEX); |
778 | int current_index = priv->reg.wep_index; |
779 | int i; |
780 | |
781 | DPRINTK(2,"flags=%04X\n",dwrq->flags); |
782 | |
783 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
784 | |
785 | /* index check */ |
786 | if((index<0) || (index>4)) |
787 | return -EINVAL; |
788 | else if (index==0) |
789 | index = current_index; |
790 | else |
791 | index--; |
792 | |
793 | /* Is WEP supported ? */ |
794 | /* Basic checking: do we have a key to set ? */ |
795 | if (dwrq->length > 0) { |
796 | if (dwrq->length > MAX_KEY_SIZE) { /* Check the size of the key */ |
797 | return -EINVAL; |
798 | } |
799 | if (dwrq->length > MIN_KEY_SIZE) { /* Set the length */ |
800 | key.len = MAX_KEY_SIZE; |
801 | priv->reg.privacy_invoked = 0x01; |
802 | priv->need_commit |= SME_WEP_FLAG; |
803 | wep_on_off = WEP_ON_128BIT; |
804 | } else { |
805 | if (dwrq->length > 0) { |
806 | key.len = MIN_KEY_SIZE; |
807 | priv->reg.privacy_invoked = 0x01; |
808 | priv->need_commit |= SME_WEP_FLAG; |
809 | wep_on_off = WEP_ON_64BIT; |
810 | } else { /* Disable the key */ |
811 | key.len = 0; |
812 | } |
813 | } |
814 | /* Check if the key is not marked as invalid */ |
815 | if(!(dwrq->flags & IW_ENCODE_NOKEY)) { |
816 | /* Cleanup */ |
817 | memset(key.key, 0, MAX_KEY_SIZE); |
818 | /* Copy the key in the driver */ |
819 | if(copy_from_user(key.key,dwrq->pointer,dwrq->length)) { |
820 | key.len = 0; |
821 | return -EFAULT; |
822 | } |
823 | /* Send the key to the card */ |
824 | priv->reg.wep_key[index].size = key.len; |
825 | for (i=0; i<(priv->reg.wep_key[index].size); i++) { |
826 | priv->reg.wep_key[index].val[i] = key.key[i]; |
827 | } |
828 | priv->need_commit |= (SME_WEP_VAL1<<index); |
829 | priv->reg.wep_index = index; |
830 | priv->need_commit |= SME_WEP_INDEX; |
831 | } |
832 | } else { |
833 | if(dwrq->flags & IW_ENCODE_DISABLED){ |
834 | priv->reg.wep_key[0].size = 0; |
835 | priv->reg.wep_key[1].size = 0; |
836 | priv->reg.wep_key[2].size = 0; |
837 | priv->reg.wep_key[3].size = 0; |
838 | priv->reg.privacy_invoked = 0x00; |
839 | if(priv->reg.authenticate_type == AUTH_TYPE_SHARED_KEY){ |
840 | priv->need_commit |= SME_MODE_SET; |
841 | } |
842 | priv->reg.authenticate_type = AUTH_TYPE_OPEN_SYSTEM; |
843 | wep_on_off = WEP_OFF; |
844 | priv->need_commit |= SME_WEP_FLAG; |
845 | }else{ |
846 | /* Do we want to just set the transmit key index ? */ |
847 | if ((index>=0) && (index<4)) { |
848 | /* set_wep_key(priv, index, 0, 0, 1); xxx */ |
849 | if(priv->reg.wep_key[index].size){ |
850 | priv->reg.wep_index = index; |
851 | priv->need_commit |= SME_WEP_INDEX; |
852 | } |
853 | else |
854 | return -EINVAL; |
855 | } |
856 | } |
857 | } |
858 | |
859 | /* Commit the changes if needed */ |
860 | if(dwrq->flags & IW_ENCODE_MODE) |
861 | priv->need_commit |= SME_WEP_FLAG; |
862 | |
863 | if(dwrq->flags & IW_ENCODE_OPEN) { |
864 | if(priv->reg.authenticate_type == AUTH_TYPE_SHARED_KEY){ |
865 | priv->need_commit |= SME_MODE_SET; |
866 | } |
867 | priv->reg.authenticate_type = AUTH_TYPE_OPEN_SYSTEM; |
868 | } else if(dwrq->flags & IW_ENCODE_RESTRICTED) { |
869 | if(priv->reg.authenticate_type == AUTH_TYPE_OPEN_SYSTEM){ |
870 | priv->need_commit |= SME_MODE_SET; |
871 | } |
872 | priv->reg.authenticate_type = AUTH_TYPE_SHARED_KEY; |
873 | } |
874 | |
875 | // return -EINPROGRESS; /* Call commit handler */ |
876 | if(priv->need_commit){ |
877 | ks_wlan_setup_parameter(priv, priv->need_commit); |
878 | priv->need_commit=0; |
879 | } |
880 | return 0; |
881 | } |
882 | |
883 | /*------------------------------------------------------------------*/ |
884 | /* Wireless Handler : get Encryption Key */ |
885 | static int ks_wlan_get_encode(struct net_device *dev, struct iw_request_info *info, |
886 | struct iw_point *dwrq, char *extra) |
887 | { |
888 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
889 | char zeros[16]; |
890 | int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; |
891 | |
892 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
893 | |
894 | dwrq->flags = IW_ENCODE_DISABLED; |
895 | |
896 | /* Check encryption mode */ |
897 | switch(priv->reg.authenticate_type) { |
898 | case AUTH_TYPE_OPEN_SYSTEM: |
899 | dwrq->flags = IW_ENCODE_OPEN; |
900 | break; |
901 | case AUTH_TYPE_SHARED_KEY: |
902 | dwrq->flags = IW_ENCODE_RESTRICTED; |
903 | break; |
904 | } |
905 | |
906 | memset(zeros,0, sizeof(zeros)); |
907 | |
908 | /* Which key do we want ? -1 -> tx index */ |
909 | if((index < 0) || (index >= 4)) |
910 | index = priv->reg.wep_index; |
911 | if (priv->reg.privacy_invoked){ |
912 | dwrq->flags &= ~IW_ENCODE_DISABLED; |
913 | /* dwrq->flags |= IW_ENCODE_NOKEY; */ |
914 | } |
915 | dwrq->flags |= index + 1; |
916 | DPRINTK(2,"encoding flag = 0x%04X\n",dwrq->flags); |
917 | /* Copy the key to the user buffer */ |
918 | if((index >= 0) && (index < 4)) |
919 | dwrq->length = priv->reg.wep_key[index].size; |
920 | if (dwrq->length > 16) { |
921 | dwrq->length=0; |
922 | } |
923 | #if 1 /* IW_ENCODE_NOKEY; */ |
924 | if (dwrq->length) { |
925 | if((index >= 0) && (index < 4)) |
926 | memcpy(extra,priv->reg.wep_key[index].val,dwrq->length); |
927 | } else |
928 | memcpy(extra,zeros,dwrq->length); |
929 | #endif |
930 | return 0; |
931 | } |
932 | |
933 | #ifndef KSC_OPNOTSUPP |
934 | /*------------------------------------------------------------------*/ |
935 | /* Wireless Handler : set Tx-Power */ |
936 | static int ks_wlan_set_txpow(struct net_device *dev, struct iw_request_info *info, |
937 | struct iw_param *vwrq, char *extra) |
938 | { |
939 | return -EOPNOTSUPP; /* Not Support */ |
940 | } |
941 | |
942 | /*------------------------------------------------------------------*/ |
943 | /* Wireless Handler : get Tx-Power */ |
944 | static int ks_wlan_get_txpow(struct net_device *dev, struct iw_request_info *info, |
945 | struct iw_param *vwrq, char *extra) |
946 | { |
947 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
948 | |
949 | /* Not Support */ |
950 | vwrq->value = 0; |
951 | vwrq->disabled = (vwrq->value == 0); |
952 | vwrq->fixed = 1; |
953 | return 0; |
954 | } |
955 | |
956 | /*------------------------------------------------------------------*/ |
957 | /* Wireless Handler : set Retry limits */ |
958 | static int ks_wlan_set_retry(struct net_device *dev, struct iw_request_info *info, |
959 | struct iw_param *vwrq, char *extra) |
960 | { |
961 | return -EOPNOTSUPP; /* Not Support */ |
962 | } |
963 | |
964 | /*------------------------------------------------------------------*/ |
965 | /* Wireless Handler : get Retry limits */ |
966 | static int ks_wlan_get_retry(struct net_device *dev, struct iw_request_info *info, |
967 | struct iw_param *vwrq, char *extra) |
968 | { |
969 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
970 | |
971 | /* Not Support */ |
972 | vwrq->value = 0; |
973 | vwrq->disabled = (vwrq->value == 0); |
974 | vwrq->fixed = 1; |
975 | return 0; |
976 | } |
977 | #endif /* KSC_OPNOTSUPP */ |
978 | |
979 | /*------------------------------------------------------------------*/ |
980 | /* Wireless Handler : get range info */ |
981 | static int ks_wlan_get_range(struct net_device *dev, struct iw_request_info *info, |
982 | struct iw_point *dwrq, char *extra) |
983 | { |
984 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
985 | struct iw_range *range = (struct iw_range *) extra; |
986 | int i,k; |
987 | |
988 | DPRINTK(2,"\n"); |
989 | |
990 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
991 | |
992 | dwrq->length = sizeof(struct iw_range); |
993 | memset(range, 0, sizeof(*range)); |
994 | range->min_nwid = 0x0000; |
995 | range->max_nwid = 0x0000; |
996 | range->num_channels = 14; |
997 | /* Should be based on cap_rid.country to give only |
998 | * what the current card support */ |
999 | k = 0; |
1000 | for(i = 0; i < 13; i++) { /* channel 1 -- 13*/ |
1001 | range->freq[k].i = i + 1; /* List index */ |
1002 | range->freq[k].m = frequency_list[i] * 100000; |
1003 | range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */ |
1004 | } |
1005 | range->num_frequency = k; |
1006 | if(priv->reg.phy_type == D_11B_ONLY_MODE || |
1007 | priv->reg.phy_type == D_11BG_COMPATIBLE_MODE){ /* channel 14 */ |
1008 | range->freq[13].i = 14; /* List index */ |
1009 | range->freq[13].m = frequency_list[13] * 100000; |
1010 | range->freq[13].e = 1; /* Values in table in MHz -> * 10^5 * 10 */ |
1011 | range->num_frequency = 14; |
1012 | } |
1013 | |
1014 | /* Hum... Should put the right values there */ |
1015 | range->max_qual.qual = 100; |
1016 | range->max_qual.level = 256 - 128; /* 0 dBm? */ |
1017 | range->max_qual.noise = 256 - 128; |
1018 | range->sensitivity = 1; |
1019 | |
1020 | if(priv->reg.phy_type == D_11B_ONLY_MODE){ |
1021 | range->bitrate[0] = 1e6; |
1022 | range->bitrate[1] = 2e6; |
1023 | range->bitrate[2] = 5.5e6; |
1024 | range->bitrate[3] = 11e6; |
1025 | range->num_bitrates = 4; |
1026 | } |
1027 | else{ /* D_11G_ONLY_MODE or D_11BG_COMPATIBLE_MODE */ |
1028 | range->bitrate[0] = 1e6; |
1029 | range->bitrate[1] = 2e6; |
1030 | range->bitrate[2] = 5.5e6; |
1031 | range->bitrate[3] = 11e6; |
1032 | |
1033 | range->bitrate[4] = 6e6; |
1034 | range->bitrate[5] = 9e6; |
1035 | range->bitrate[6] = 12e6; |
1036 | if(IW_MAX_BITRATES < 9){ |
1037 | range->bitrate[7] = 54e6; |
1038 | range->num_bitrates = 8; |
1039 | }else{ |
1040 | range->bitrate[7] = 18e6; |
1041 | range->bitrate[8] = 24e6; |
1042 | range->bitrate[9] = 36e6; |
1043 | range->bitrate[10] = 48e6; |
1044 | range->bitrate[11] = 54e6; |
1045 | |
1046 | range->num_bitrates = 12; |
1047 | } |
1048 | } |
1049 | |
1050 | /* Set an indication of the max TCP throughput |
1051 | * in bit/s that we can expect using this interface. |
1052 | * May be use for QoS stuff... Jean II */ |
1053 | if(i > 2) |
1054 | range->throughput = 5000 * 1000; |
1055 | else |
1056 | range->throughput = 1500 * 1000; |
1057 | |
1058 | range->min_rts = 0; |
1059 | range->max_rts = 2347; |
1060 | range->min_frag = 256; |
1061 | range->max_frag = 2346; |
1062 | |
1063 | range->encoding_size[0] = 5; /* WEP: RC4 40 bits */ |
1064 | range->encoding_size[1] = 13; /* WEP: RC4 ~128 bits */ |
1065 | range->num_encoding_sizes = 2; |
1066 | range->max_encoding_tokens = 4; |
1067 | |
1068 | /* power management not support */ |
1069 | range->pmp_flags = IW_POWER_ON; |
1070 | range->pmt_flags = IW_POWER_ON; |
1071 | range->pm_capa = 0; |
1072 | |
1073 | /* Transmit Power - values are in dBm( or mW) */ |
1074 | range->txpower[0]=-256; |
1075 | range->num_txpower = 1; |
1076 | range->txpower_capa = IW_TXPOW_DBM; |
1077 | /* range->txpower_capa = IW_TXPOW_MWATT; */ |
1078 | |
1079 | range->we_version_source = 21; |
1080 | range->we_version_compiled = WIRELESS_EXT; |
1081 | |
1082 | range->retry_capa = IW_RETRY_ON; |
1083 | range->retry_flags = IW_RETRY_ON; |
1084 | range->r_time_flags = IW_RETRY_ON; |
1085 | |
1086 | /* Experimental measurements - boundary 11/5.5 Mb/s */ |
1087 | /* Note : with or without the (local->rssi), results |
1088 | * are somewhat different. - Jean II */ |
1089 | range->avg_qual.qual = 50; |
1090 | range->avg_qual.level = 186; /* -70 dBm */ |
1091 | range->avg_qual.noise = 0; |
1092 | |
1093 | #if defined(WIRELESS_EXT) |
1094 | /* Event capability (kernel + driver) */ |
1095 | range->event_capa[0] = (IW_EVENT_CAPA_K_0 | |
1096 | IW_EVENT_CAPA_MASK(SIOCGIWAP) | |
1097 | IW_EVENT_CAPA_MASK(SIOCGIWSCAN)); |
1098 | range->event_capa[1] = IW_EVENT_CAPA_K_1; |
1099 | range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVCUSTOM) | |
1100 | IW_EVENT_CAPA_MASK(IWEVMICHAELMICFAILURE)); |
1101 | |
1102 | /* encode extension (WPA) capability */ |
1103 | range->enc_capa = (IW_ENC_CAPA_WPA | |
1104 | IW_ENC_CAPA_WPA2 | |
1105 | IW_ENC_CAPA_CIPHER_TKIP | |
1106 | IW_ENC_CAPA_CIPHER_CCMP); |
1107 | #endif |
1108 | return 0; |
1109 | } |
1110 | |
1111 | |
1112 | /*------------------------------------------------------------------*/ |
1113 | /* Wireless Handler : set Power Management */ |
1114 | static int ks_wlan_set_power(struct net_device *dev, struct iw_request_info *info, |
1115 | struct iw_param *vwrq, char *extra) |
1116 | { |
1117 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1118 | short enabled; |
1119 | |
1120 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1121 | |
1122 | enabled = vwrq->disabled ? 0 : 1; |
1123 | if(enabled == 0 ){ /* 0 */ |
1124 | priv->reg.powermgt = POWMGT_ACTIVE_MODE; |
1125 | }else if(enabled){ /* 1 */ |
1126 | if(priv->reg.operation_mode == MODE_INFRASTRUCTURE) |
1127 | priv->reg.powermgt = POWMGT_SAVE1_MODE; |
1128 | else |
1129 | return -EINVAL; |
1130 | }else if(enabled){ /* 2 */ |
1131 | if(priv->reg.operation_mode == MODE_INFRASTRUCTURE) |
1132 | priv->reg.powermgt = POWMGT_SAVE2_MODE; |
1133 | else |
1134 | return -EINVAL; |
1135 | }else |
1136 | return -EINVAL; |
1137 | |
1138 | hostif_sme_enqueue(priv, SME_POW_MNGMT_REQUEST); |
1139 | |
1140 | return 0; |
1141 | } |
1142 | |
1143 | /*------------------------------------------------------------------*/ |
1144 | /* Wireless Handler : get Power Management */ |
1145 | static int ks_wlan_get_power(struct net_device *dev, struct iw_request_info *info, |
1146 | struct iw_param *vwrq, char *extra) |
1147 | { |
1148 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1149 | |
1150 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1151 | |
1152 | if(priv->reg.powermgt > 0) |
1153 | vwrq->disabled = 0; |
1154 | else |
1155 | vwrq->disabled = 1; |
1156 | |
1157 | return 0; |
1158 | } |
1159 | |
1160 | /*------------------------------------------------------------------*/ |
1161 | /* Wireless Handler : get wirless statistics */ |
1162 | static int ks_wlan_get_iwstats(struct net_device *dev, struct iw_request_info *info, |
1163 | struct iw_quality *vwrq, char *extra) |
1164 | { |
1165 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1166 | |
1167 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1168 | |
1169 | vwrq->qual = 0; /* not supported */ |
1170 | vwrq->level = priv->wstats.qual.level; |
1171 | vwrq->noise = 0; /* not supported */ |
1172 | vwrq->updated = 0; |
1173 | |
1174 | return 0; |
1175 | } |
1176 | |
1177 | #ifndef KSC_OPNOTSUPP |
1178 | /*------------------------------------------------------------------*/ |
1179 | /* Wireless Handler : set Sensitivity */ |
1180 | static int ks_wlan_set_sens(struct net_device *dev, struct iw_request_info *info, |
1181 | struct iw_param *vwrq, char *extra) |
1182 | { |
1183 | return -EOPNOTSUPP; /* Not Support */ |
1184 | } |
1185 | |
1186 | /*------------------------------------------------------------------*/ |
1187 | /* Wireless Handler : get Sensitivity */ |
1188 | static int ks_wlan_get_sens(struct net_device *dev, struct iw_request_info *info, |
1189 | struct iw_param *vwrq, char *extra) |
1190 | { |
1191 | /* Not Support */ |
1192 | vwrq->value = 0; |
1193 | vwrq->disabled = (vwrq->value == 0); |
1194 | vwrq->fixed = 1; |
1195 | return 0; |
1196 | } |
1197 | #endif /* KSC_OPNOTSUPP */ |
1198 | |
1199 | |
1200 | /*------------------------------------------------------------------*/ |
1201 | /* Wireless Handler : get AP List */ |
1202 | /* Note : this is deprecated in favor of IWSCAN */ |
1203 | static int ks_wlan_get_aplist(struct net_device *dev, struct iw_request_info *info, |
1204 | struct iw_point *dwrq, char *extra) |
1205 | { |
1206 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1207 | struct sockaddr *address = (struct sockaddr *) extra; |
1208 | struct iw_quality qual[LOCAL_APLIST_MAX]; |
1209 | |
1210 | int i; |
1211 | |
1212 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1213 | |
1214 | for (i = 0; i < priv->aplist.size; i++) { |
1215 | memcpy(address[i].sa_data, &(priv->aplist.ap[i].bssid[0]), ETH_ALEN); |
1216 | address[i].sa_family = ARPHRD_ETHER; |
1217 | qual[i].level = 256 - priv->aplist.ap[i].rssi; |
1218 | qual[i].qual = priv->aplist.ap[i].sq; |
1219 | qual[i].noise = 0; /* invalid noise value */ |
1220 | qual[i].updated = 7; |
1221 | } |
1222 | if (i){ |
1223 | dwrq->flags = 1; /* Should be define'd */ |
1224 | memcpy(extra + sizeof(struct sockaddr)*i, |
1225 | &qual, sizeof(struct iw_quality)*i); |
1226 | } |
1227 | dwrq->length = i; |
1228 | |
1229 | return 0; |
1230 | } |
1231 | |
1232 | #if defined(WIRELESS_EXT) |
1233 | /*------------------------------------------------------------------*/ |
1234 | /* Wireless Handler : Initiate Scan */ |
1235 | static int ks_wlan_set_scan(struct net_device *dev, struct iw_request_info *info, |
1236 | union iwreq_data *wrqu, char *extra) |
1237 | { |
1238 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1239 | struct iw_scan_req *req = NULL; |
1240 | DPRINTK(2,"\n"); |
1241 | |
1242 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1243 | |
1244 | /* specified SSID SCAN */ |
1245 | if(wrqu->data.length == sizeof(struct iw_scan_req) && wrqu->data.flags & IW_SCAN_THIS_ESSID){ |
1246 | req = (struct iw_scan_req *) extra; |
1247 | priv->scan_ssid_len = req->essid_len; |
1248 | memcpy(priv->scan_ssid, req->essid, priv->scan_ssid_len); |
1249 | }else{ |
1250 | priv->scan_ssid_len = 0; |
1251 | } |
1252 | |
1253 | |
1254 | priv->sme_i.sme_flag |= SME_AP_SCAN; |
1255 | hostif_sme_enqueue(priv, SME_BSS_SCAN_REQUEST); |
1256 | |
1257 | /* At this point, just return to the user. */ |
1258 | |
1259 | return 0; |
1260 | } |
1261 | |
1262 | /*------------------------------------------------------------------*/ |
1263 | /* |
1264 | * Translate scan data returned from the card to a card independent |
1265 | * format that the Wireless Tools will understand - Jean II |
1266 | */ |
1267 | static inline char *ks_wlan_translate_scan(struct net_device *dev, struct iw_request_info *info, char *current_ev, |
1268 | char *end_buf, struct local_ap_t *ap) |
1269 | { |
1270 | /* ks_wlan_private *priv = (ks_wlan_private *)dev->priv; */ |
1271 | struct iw_event iwe; /* Temporary buffer */ |
1272 | u16 capabilities; |
1273 | char *current_val; /* For rates */ |
1274 | int i; |
1275 | static const char rsn_leader[] = "rsn_ie="; |
1276 | static const char wpa_leader[] = "wpa_ie="; |
1277 | char buf0[RSN_IE_BODY_MAX*2 + 30]; |
1278 | char buf1[RSN_IE_BODY_MAX*2 + 30]; |
1279 | char *pbuf; |
1280 | /* First entry *MUST* be the AP MAC address */ |
1281 | iwe.cmd = SIOCGIWAP; |
1282 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
1283 | memcpy(iwe.u.ap_addr.sa_data, ap->bssid, ETH_ALEN); |
1284 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); |
1285 | |
1286 | /* Other entries will be displayed in the order we give them */ |
1287 | |
1288 | /* Add the ESSID */ |
1289 | iwe.u.data.length = ap->ssid.size; |
1290 | if(iwe.u.data.length > 32) |
1291 | iwe.u.data.length = 32; |
1292 | iwe.cmd = SIOCGIWESSID; |
1293 | iwe.u.data.flags = 1; |
1294 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, &(ap->ssid.body[0])); |
1295 | |
1296 | /* Add mode */ |
1297 | iwe.cmd = SIOCGIWMODE; |
1298 | capabilities = le16_to_cpu(ap->capability); |
1299 | if(capabilities & (BSS_CAP_ESS | BSS_CAP_IBSS)) { |
1300 | if(capabilities & BSS_CAP_ESS) |
1301 | iwe.u.mode = IW_MODE_INFRA; |
1302 | else |
1303 | iwe.u.mode = IW_MODE_ADHOC; |
1304 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN); |
1305 | } |
1306 | |
1307 | /* Add frequency */ |
1308 | iwe.cmd = SIOCGIWFREQ; |
1309 | iwe.u.freq.m = ap->channel; |
1310 | iwe.u.freq.m = frequency_list[iwe.u.freq.m-1] * 100000; |
1311 | iwe.u.freq.e = 1; |
1312 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); |
1313 | |
1314 | /* Add quality statistics */ |
1315 | iwe.cmd = IWEVQUAL; |
1316 | iwe.u.qual.level = 256 - ap->rssi; |
1317 | iwe.u.qual.qual = ap->sq; |
1318 | iwe.u.qual.noise = 0; /* invalid noise value */ |
1319 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); |
1320 | |
1321 | /* Add encryption capability */ |
1322 | iwe.cmd = SIOCGIWENCODE; |
1323 | if(capabilities & BSS_CAP_PRIVACY) |
1324 | iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; |
1325 | else |
1326 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
1327 | iwe.u.data.length = 0; |
1328 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, &(ap->ssid.body[0])); |
1329 | |
1330 | /* Rate : stuffing multiple values in a single event require a bit |
1331 | * more of magic - Jean II */ |
1332 | current_val = current_ev + IW_EV_LCP_LEN; |
1333 | |
1334 | iwe.cmd = SIOCGIWRATE; |
1335 | /* Those two flags are ignored... */ |
1336 | iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; |
1337 | |
1338 | /* Max 16 values */ |
1339 | for(i = 0 ; i < 16 ; i++) { |
1340 | /* NULL terminated */ |
1341 | if(i >= ap->rate_set.size) |
1342 | break; |
1343 | /* Bit rate given in 500 kb/s units (+ 0x80) */ |
1344 | iwe.u.bitrate.value = ((ap->rate_set.body[i] & 0x7f) * 500000); |
1345 | /* Add new value to event */ |
1346 | current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); |
1347 | } |
1348 | /* Check if we added any event */ |
1349 | if((current_val - current_ev) > IW_EV_LCP_LEN) |
1350 | current_ev = current_val; |
1351 | |
1352 | #define GENERIC_INFO_ELEM_ID 0xdd |
1353 | #define RSN_INFO_ELEM_ID 0x30 |
1354 | if (ap->rsn_ie.id == RSN_INFO_ELEM_ID && ap->rsn_ie.size != 0) { |
1355 | pbuf = &buf0[0]; |
1356 | memset(&iwe, 0, sizeof(iwe)); |
1357 | iwe.cmd = IWEVCUSTOM; |
1358 | memcpy(buf0,rsn_leader,sizeof(rsn_leader)-1); |
1359 | iwe.u.data.length += sizeof(rsn_leader)-1; |
1360 | pbuf += sizeof(rsn_leader)-1; |
1361 | |
1362 | pbuf += sprintf(pbuf, "%02x", ap->rsn_ie.id); |
1363 | pbuf += sprintf(pbuf, "%02x", ap->rsn_ie.size); |
1364 | iwe.u.data.length += 4; |
1365 | |
1366 | for (i = 0; i < ap->rsn_ie.size; i++) |
1367 | pbuf += sprintf(pbuf, "%02x", ap->rsn_ie.body[i]); |
1368 | iwe.u.data.length += (ap->rsn_ie.size)*2; |
1369 | |
1370 | DPRINTK(4,"ap->rsn.size=%d\n",ap->rsn_ie.size); |
1371 | |
1372 | current_ev = iwe_stream_add_point(info, current_ev, end_buf,&iwe, &buf0[0]); |
1373 | } |
1374 | if (ap->wpa_ie.id == GENERIC_INFO_ELEM_ID && ap->wpa_ie.size != 0) { |
1375 | pbuf = &buf1[0]; |
1376 | memset(&iwe, 0, sizeof(iwe)); |
1377 | iwe.cmd = IWEVCUSTOM; |
1378 | memcpy(buf1,wpa_leader,sizeof(wpa_leader)-1); |
1379 | iwe.u.data.length += sizeof(wpa_leader)-1; |
1380 | pbuf += sizeof(wpa_leader)-1; |
1381 | |
1382 | pbuf += sprintf(pbuf, "%02x", ap->wpa_ie.id); |
1383 | pbuf += sprintf(pbuf, "%02x", ap->wpa_ie.size); |
1384 | iwe.u.data.length += 4; |
1385 | |
1386 | for (i = 0; i < ap->wpa_ie.size; i++) |
1387 | pbuf += sprintf(pbuf, "%02x", ap->wpa_ie.body[i]); |
1388 | iwe.u.data.length += (ap->wpa_ie.size)*2; |
1389 | |
1390 | DPRINTK(4,"ap->rsn.size=%d\n",ap->wpa_ie.size); |
1391 | DPRINTK(4,"iwe.u.data.length=%d\n",iwe.u.data.length); |
1392 | |
1393 | current_ev = iwe_stream_add_point(info, current_ev, end_buf,&iwe, &buf1[0]); |
1394 | } |
1395 | |
1396 | /* The other data in the scan result are not really |
1397 | * interesting, so for now drop it - Jean II */ |
1398 | return current_ev; |
1399 | } |
1400 | |
1401 | /*------------------------------------------------------------------*/ |
1402 | /* Wireless Handler : Read Scan Results */ |
1403 | static int ks_wlan_get_scan(struct net_device *dev, struct iw_request_info *info, |
1404 | struct iw_point *dwrq, char *extra) |
1405 | { |
1406 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1407 | int i; |
1408 | char *current_ev = extra; |
1409 | DPRINTK(2,"\n"); |
1410 | |
1411 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1412 | |
1413 | if(priv->sme_i.sme_flag & SME_AP_SCAN) { |
1414 | DPRINTK(2,"flag AP_SCAN\n"); |
1415 | return -EAGAIN; |
1416 | } |
1417 | |
1418 | if(priv->aplist.size == 0) { |
1419 | /* Client error, no scan results... |
1420 | * The caller need to restart the scan. */ |
1421 | DPRINTK(2,"aplist 0\n"); |
1422 | return -ENODATA; |
1423 | } |
1424 | #if 0 |
1425 | /* current connect ap */ |
1426 | if((priv->connect_status & CONNECT_STATUS_MASK)== CONNECT_STATUS){ |
1427 | if ((extra + dwrq->length) - current_ev <= IW_EV_ADDR_LEN) { |
1428 | dwrq->length = 0; |
1429 | return -E2BIG; |
1430 | } |
1431 | current_ev = ks_wlan_translate_scan(dev, current_ev, |
1432 | // extra + IW_SCAN_MAX_DATA, |
1433 | extra + dwrq->length, |
1434 | &(priv->current_ap)); |
1435 | } |
1436 | #endif |
1437 | /* Read and parse all entries */ |
1438 | for(i=0; i < priv->aplist.size; i++) { |
1439 | if ((extra + dwrq->length) - current_ev <= IW_EV_ADDR_LEN) { |
1440 | dwrq->length = 0; |
1441 | return -E2BIG; |
1442 | } |
1443 | /* Translate to WE format this entry */ |
1444 | current_ev = ks_wlan_translate_scan(dev, info, current_ev, |
1445 | // extra + IW_SCAN_MAX_DATA, |
1446 | extra + dwrq->length, |
1447 | &(priv->aplist.ap[i])); |
1448 | } |
1449 | /* Length of data */ |
1450 | dwrq->length = (current_ev - extra); |
1451 | dwrq->flags = 0; |
1452 | |
1453 | return 0; |
1454 | } |
1455 | #endif /* WIRELESS_EXT */ |
1456 | |
1457 | /*------------------------------------------------------------------*/ |
1458 | /* Commit handler : called after a bunch of SET operations */ |
1459 | static int ks_wlan_config_commit(struct net_device *dev, struct iw_request_info *info, |
1460 | void *zwrq, char *extra) |
1461 | { |
1462 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1463 | |
1464 | if (!priv->need_commit) |
1465 | return 0; |
1466 | |
1467 | ks_wlan_setup_parameter(priv, priv->need_commit); |
1468 | priv->need_commit=0; |
1469 | return 0; |
1470 | } |
1471 | |
1472 | #ifdef WIRELESS_EXT |
1473 | /*------------------------------------------------------------------*/ |
1474 | /* Wireless handler : set association ie params */ |
1475 | static int ks_wlan_set_genie(struct net_device *dev, struct iw_request_info *info, |
1476 | struct iw_point *dwrq, char *extra) |
1477 | { |
1478 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1479 | |
1480 | DPRINTK(2, "\n"); |
1481 | |
1482 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1483 | |
1484 | return 0; |
1485 | // return -EOPNOTSUPP; |
1486 | } |
1487 | |
1488 | /*------------------------------------------------------------------*/ |
1489 | /* Wireless handler : set authentication mode params */ |
1490 | static int ks_wlan_set_auth_mode(struct net_device *dev, struct iw_request_info *info, |
1491 | struct iw_param *vwrq, char *extra) |
1492 | { |
1493 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1494 | int index = (vwrq->flags & IW_AUTH_INDEX); |
1495 | int value = vwrq->value; |
1496 | |
1497 | DPRINTK(2,"index=%d:value=%08X\n",index,value); |
1498 | |
1499 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1500 | |
1501 | switch(index){ |
1502 | case IW_AUTH_WPA_VERSION: /* 0 */ |
1503 | switch(value){ |
1504 | case IW_AUTH_WPA_VERSION_DISABLED: |
1505 | priv->wpa.version = value; |
1506 | if(priv->wpa.rsn_enabled){ |
1507 | priv->wpa.rsn_enabled = 0; |
1508 | } |
1509 | priv->need_commit |= SME_RSN; |
1510 | break; |
1511 | case IW_AUTH_WPA_VERSION_WPA: |
1512 | case IW_AUTH_WPA_VERSION_WPA2: |
1513 | priv->wpa.version = value; |
1514 | if(!(priv->wpa.rsn_enabled)){ |
1515 | priv->wpa.rsn_enabled = 1; |
1516 | } |
1517 | priv->need_commit |= SME_RSN; |
1518 | break; |
1519 | default: |
1520 | return -EOPNOTSUPP; |
1521 | } |
1522 | break; |
1523 | case IW_AUTH_CIPHER_PAIRWISE: /* 1 */ |
1524 | switch(value){ |
1525 | case IW_AUTH_CIPHER_NONE: |
1526 | if(priv->reg.privacy_invoked){ |
1527 | priv->reg.privacy_invoked = 0x00; |
1528 | priv->need_commit |= SME_WEP_FLAG; |
1529 | } |
1530 | break; |
1531 | case IW_AUTH_CIPHER_WEP40: |
1532 | case IW_AUTH_CIPHER_TKIP: |
1533 | case IW_AUTH_CIPHER_CCMP: |
1534 | case IW_AUTH_CIPHER_WEP104: |
1535 | if(!priv->reg.privacy_invoked){ |
1536 | priv->reg.privacy_invoked = 0x01; |
1537 | priv->need_commit |= SME_WEP_FLAG; |
1538 | } |
1539 | priv->wpa.pairwise_suite = value; |
1540 | priv->need_commit |= SME_RSN_UNICAST; |
1541 | break; |
1542 | default: |
1543 | return -EOPNOTSUPP; |
1544 | } |
1545 | break; |
1546 | case IW_AUTH_CIPHER_GROUP: /* 2 */ |
1547 | switch(value){ |
1548 | case IW_AUTH_CIPHER_NONE: |
1549 | if(priv->reg.privacy_invoked){ |
1550 | priv->reg.privacy_invoked = 0x00; |
1551 | priv->need_commit |= SME_WEP_FLAG; |
1552 | } |
1553 | break; |
1554 | case IW_AUTH_CIPHER_WEP40: |
1555 | case IW_AUTH_CIPHER_TKIP: |
1556 | case IW_AUTH_CIPHER_CCMP: |
1557 | case IW_AUTH_CIPHER_WEP104: |
1558 | if(!priv->reg.privacy_invoked){ |
1559 | priv->reg.privacy_invoked = 0x01; |
1560 | priv->need_commit |= SME_WEP_FLAG; |
1561 | } |
1562 | priv->wpa.group_suite = value; |
1563 | priv->need_commit |= SME_RSN_MULTICAST; |
1564 | break; |
1565 | default: |
1566 | return -EOPNOTSUPP; |
1567 | } |
1568 | break; |
1569 | case IW_AUTH_KEY_MGMT: /* 3 */ |
1570 | switch(value){ |
1571 | case IW_AUTH_KEY_MGMT_802_1X: |
1572 | case IW_AUTH_KEY_MGMT_PSK: |
1573 | case 0: /* NONE or 802_1X_NO_WPA */ |
1574 | case 4: /* WPA_NONE */ |
1575 | priv->wpa.key_mgmt_suite = value; |
1576 | priv->need_commit |= SME_RSN_AUTH; |
1577 | break; |
1578 | default: |
1579 | return -EOPNOTSUPP; |
1580 | } |
1581 | break; |
1582 | case IW_AUTH_80211_AUTH_ALG: /* 6 */ |
1583 | switch(value){ |
1584 | case IW_AUTH_ALG_OPEN_SYSTEM: |
1585 | priv->wpa.auth_alg = value; |
1586 | priv->reg.authenticate_type = AUTH_TYPE_OPEN_SYSTEM; |
1587 | break; |
1588 | case IW_AUTH_ALG_SHARED_KEY: |
1589 | priv->wpa.auth_alg = value; |
1590 | priv->reg.authenticate_type = AUTH_TYPE_SHARED_KEY; |
1591 | break; |
1592 | case IW_AUTH_ALG_LEAP: |
1593 | default: |
1594 | return -EOPNOTSUPP; |
1595 | } |
1596 | priv->need_commit |= SME_MODE_SET; |
1597 | break; |
1598 | case IW_AUTH_WPA_ENABLED: /* 7 */ |
1599 | priv->wpa.wpa_enabled = value; |
1600 | break; |
1601 | case IW_AUTH_PRIVACY_INVOKED: /* 10 */ |
1602 | if((value && !priv->reg.privacy_invoked)|| |
1603 | (!value && priv->reg.privacy_invoked)){ |
1604 | priv->reg.privacy_invoked = value?0x01:0x00; |
1605 | priv->need_commit |= SME_WEP_FLAG; |
1606 | } |
1607 | break; |
1608 | case IW_AUTH_RX_UNENCRYPTED_EAPOL: /* 4 */ |
1609 | case IW_AUTH_TKIP_COUNTERMEASURES: /* 5 */ |
1610 | case IW_AUTH_DROP_UNENCRYPTED: /* 8 */ |
1611 | case IW_AUTH_ROAMING_CONTROL: /* 9 */ |
1612 | default: |
1613 | break; |
1614 | } |
1615 | |
1616 | /* return -EINPROGRESS; */ |
1617 | if(priv->need_commit){ |
1618 | ks_wlan_setup_parameter(priv, priv->need_commit); |
1619 | priv->need_commit=0; |
1620 | } |
1621 | return 0; |
1622 | } |
1623 | |
1624 | /*------------------------------------------------------------------*/ |
1625 | /* Wireless handler : get authentication mode params */ |
1626 | static int ks_wlan_get_auth_mode(struct net_device *dev, struct iw_request_info *info, |
1627 | struct iw_param *vwrq, char *extra) |
1628 | { |
1629 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1630 | int index = (vwrq->flags & IW_AUTH_INDEX); |
1631 | DPRINTK(2,"index=%d\n",index); |
1632 | |
1633 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1634 | |
1635 | /* WPA (not used ?? wpa_supplicant) */ |
1636 | switch(index){ |
1637 | case IW_AUTH_WPA_VERSION: |
1638 | vwrq->value = priv->wpa.version; |
1639 | break; |
1640 | case IW_AUTH_CIPHER_PAIRWISE: |
1641 | vwrq->value = priv->wpa.pairwise_suite; |
1642 | break; |
1643 | case IW_AUTH_CIPHER_GROUP: |
1644 | vwrq->value = priv->wpa.group_suite; |
1645 | break; |
1646 | case IW_AUTH_KEY_MGMT: |
1647 | vwrq->value = priv->wpa.key_mgmt_suite; |
1648 | break; |
1649 | case IW_AUTH_80211_AUTH_ALG: |
1650 | vwrq->value = priv->wpa.auth_alg; |
1651 | break; |
1652 | case IW_AUTH_WPA_ENABLED: |
1653 | vwrq->value = priv->wpa.rsn_enabled; |
1654 | break; |
1655 | case IW_AUTH_RX_UNENCRYPTED_EAPOL: /* OK??? */ |
1656 | case IW_AUTH_TKIP_COUNTERMEASURES: |
1657 | case IW_AUTH_DROP_UNENCRYPTED: |
1658 | default: |
1659 | /* return -EOPNOTSUPP; */ |
1660 | break; |
1661 | } |
1662 | return 0; |
1663 | } |
1664 | |
1665 | /*------------------------------------------------------------------*/ |
1666 | /* Wireless Handler : set encoding token & mode (WPA)*/ |
1667 | static int ks_wlan_set_encode_ext(struct net_device *dev, struct iw_request_info *info, |
1668 | struct iw_point *dwrq, char *extra) |
1669 | { |
1670 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1671 | struct iw_encode_ext *enc; |
1672 | int index = dwrq->flags & IW_ENCODE_INDEX; |
1673 | unsigned int commit=0; |
1674 | |
1675 | enc = (struct iw_encode_ext *)extra; |
1676 | |
1677 | DPRINTK(2,"flags=%04X:: ext_flags=%08X\n",dwrq->flags, enc->ext_flags); |
1678 | |
1679 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1680 | |
1681 | if(index<1||index>4) |
1682 | return -EINVAL; |
1683 | else |
1684 | index--; |
1685 | |
1686 | if(dwrq->flags & IW_ENCODE_DISABLED){ |
1687 | priv->wpa.key[index].key_len=0; |
1688 | } |
1689 | |
1690 | if(enc){ |
1691 | priv->wpa.key[index].ext_flags=enc->ext_flags; |
1692 | if(enc->ext_flags&IW_ENCODE_EXT_SET_TX_KEY){ |
1693 | priv->wpa.txkey=index; |
1694 | commit |= SME_WEP_INDEX; |
1695 | }else if(enc->ext_flags&IW_ENCODE_EXT_RX_SEQ_VALID){ |
1696 | if(enc->rx_seq) |
1697 | memcpy(&priv->wpa.key[index].rx_seq[0], |
1698 | enc->rx_seq, IW_ENCODE_SEQ_MAX_SIZE); |
1699 | else |
1700 | return -EINVAL; |
1701 | } |
1702 | |
1703 | memcpy(&priv->wpa.key[index].addr.sa_data[0], |
1704 | &enc->addr.sa_data[0], ETH_ALEN); |
1705 | |
1706 | switch (enc->alg) { |
1707 | case IW_ENCODE_ALG_NONE: |
1708 | if(priv->reg.privacy_invoked){ |
1709 | priv->reg.privacy_invoked = 0x00; |
1710 | commit |= SME_WEP_FLAG; |
1711 | } |
1712 | priv->wpa.key[index].key_len = 0; |
1713 | |
1714 | break; |
1715 | case IW_ENCODE_ALG_WEP: |
1716 | case IW_ENCODE_ALG_CCMP: |
1717 | if(!priv->reg.privacy_invoked){ |
1718 | priv->reg.privacy_invoked = 0x01; |
1719 | commit |= SME_WEP_FLAG; |
1720 | } |
1721 | if(enc->key && enc->key_len){ |
1722 | memcpy(&priv->wpa.key[index].key_val[0], |
1723 | &enc->key[0], enc->key_len); |
1724 | priv->wpa.key[index].key_len = enc->key_len; |
1725 | commit |= (SME_WEP_VAL1 << index); |
1726 | } |
1727 | break; |
1728 | case IW_ENCODE_ALG_TKIP: |
1729 | if(!priv->reg.privacy_invoked){ |
1730 | priv->reg.privacy_invoked = 0x01; |
1731 | commit |= SME_WEP_FLAG; |
1732 | } |
1733 | if(enc->key && enc->key_len == 32){ |
1734 | memcpy(&priv->wpa.key[index].key_val[0], |
1735 | &enc->key[0], enc->key_len-16); |
1736 | priv->wpa.key[index].key_len = enc->key_len-16; |
1737 | if(priv->wpa.key_mgmt_suite==4){ /* WPA_NONE */ |
1738 | memcpy(&priv->wpa.key[index].tx_mic_key[0], |
1739 | &enc->key[16],8); |
1740 | memcpy(&priv->wpa.key[index].rx_mic_key[0], |
1741 | &enc->key[16],8); |
1742 | }else{ |
1743 | memcpy(&priv->wpa.key[index].tx_mic_key[0], |
1744 | &enc->key[16],8); |
1745 | memcpy(&priv->wpa.key[index].rx_mic_key[0], |
1746 | &enc->key[24],8); |
1747 | } |
1748 | commit |= (SME_WEP_VAL1 << index); |
1749 | } |
1750 | break; |
1751 | default: |
1752 | return -EINVAL; |
1753 | } |
1754 | priv->wpa.key[index].alg=enc->alg; |
1755 | } |
1756 | else |
1757 | return -EINVAL; |
1758 | |
1759 | if(commit){ |
1760 | if(commit&SME_WEP_INDEX) |
1761 | hostif_sme_enqueue(priv, SME_SET_TXKEY); |
1762 | if(commit&SME_WEP_VAL_MASK) |
1763 | hostif_sme_enqueue(priv, SME_SET_KEY1+index); |
1764 | if(commit&SME_WEP_FLAG) |
1765 | hostif_sme_enqueue(priv, SME_WEP_FLAG_REQUEST); |
1766 | } |
1767 | |
1768 | return 0; |
1769 | } |
1770 | |
1771 | /*------------------------------------------------------------------*/ |
1772 | /* Wireless Handler : get encoding token & mode (WPA)*/ |
1773 | static int ks_wlan_get_encode_ext(struct net_device *dev, struct iw_request_info *info, |
1774 | struct iw_point *dwrq, char *extra) |
1775 | { |
1776 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1777 | |
1778 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1779 | |
1780 | /* WPA (not used ?? wpa_supplicant) |
1781 | ks_wlan_private *priv = (ks_wlan_private *)dev->priv; |
1782 | struct iw_encode_ext *enc; |
1783 | enc = (struct iw_encode_ext *)extra; |
1784 | int index = dwrq->flags & IW_ENCODE_INDEX; |
1785 | WPA (not used ?? wpa_supplicant) */ |
1786 | return 0; |
1787 | } |
1788 | |
1789 | /*------------------------------------------------------------------*/ |
1790 | /* Wireless Handler : PMKSA cache operation (WPA2) */ |
1791 | static int ks_wlan_set_pmksa(struct net_device *dev, struct iw_request_info *info, |
1792 | struct iw_point *dwrq, char *extra) |
1793 | { |
1794 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1795 | struct iw_pmksa *pmksa ; |
1796 | int i; |
1797 | struct pmk_t *pmk; |
1798 | struct list_head *ptr; |
1799 | |
1800 | DPRINTK(2,"\n"); |
1801 | |
1802 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1803 | |
1804 | if(!extra){ |
1805 | return -EINVAL; |
1806 | } |
1807 | pmksa = (struct iw_pmksa *)extra; |
1808 | DPRINTK(2,"cmd=%d\n",pmksa->cmd); |
1809 | |
1810 | switch(pmksa->cmd){ |
1811 | case IW_PMKSA_ADD: |
1812 | if(list_empty(&priv->pmklist.head)){ /* new list */ |
1813 | for(i=0;i<PMK_LIST_MAX;i++){ |
1814 | pmk = &priv->pmklist.pmk[i]; |
1815 | if(!memcmp("\x00\x00\x00\x00\x00\x00",pmk->bssid,ETH_ALEN)) |
1816 | break; |
1817 | } |
1818 | memcpy(pmk->bssid, pmksa->bssid.sa_data, ETH_ALEN); |
1819 | memcpy(pmk->pmkid, pmksa->pmkid, IW_PMKID_LEN); |
1820 | list_add(&pmk->list,&priv->pmklist.head); |
1821 | priv->pmklist.size++; |
1822 | } |
1823 | else { /* search cache data */ |
1824 | list_for_each(ptr, &priv->pmklist.head){ |
1825 | pmk = list_entry(ptr, struct pmk_t, list); |
1826 | if(!memcmp(pmksa->bssid.sa_data, pmk->bssid, ETH_ALEN)){ /* match address! list move to head. */ |
1827 | memcpy(pmk->pmkid, pmksa->pmkid, IW_PMKID_LEN); |
1828 | list_move(&pmk->list, &priv->pmklist.head); |
1829 | break; |
1830 | } |
1831 | } |
1832 | if(ptr == &priv->pmklist.head){ /* not find address. */ |
1833 | if(PMK_LIST_MAX > priv->pmklist.size){ /* new cache data */ |
1834 | for(i=0;i<PMK_LIST_MAX;i++){ |
1835 | pmk = &priv->pmklist.pmk[i]; |
1836 | if(!memcmp("\x00\x00\x00\x00\x00\x00",pmk->bssid,ETH_ALEN)) |
1837 | break; |
1838 | } |
1839 | memcpy(pmk->bssid, pmksa->bssid.sa_data, ETH_ALEN); |
1840 | memcpy(pmk->pmkid, pmksa->pmkid, IW_PMKID_LEN); |
1841 | list_add(&pmk->list,&priv->pmklist.head); |
1842 | priv->pmklist.size++; |
1843 | } |
1844 | else{ /* overwrite old cache data */ |
1845 | pmk = list_entry(priv->pmklist.head.prev, struct pmk_t, list); |
1846 | memcpy(pmk->bssid, pmksa->bssid.sa_data, ETH_ALEN); |
1847 | memcpy(pmk->pmkid, pmksa->pmkid, IW_PMKID_LEN); |
1848 | list_move(&pmk->list,&priv->pmklist.head); |
1849 | } |
1850 | } |
1851 | } |
1852 | break; |
1853 | case IW_PMKSA_REMOVE: |
1854 | if(list_empty(&priv->pmklist.head)){ /* list empty */ |
1855 | return -EINVAL; |
1856 | } |
1857 | else{ /* search cache data */ |
1858 | list_for_each(ptr, &priv->pmklist.head){ |
1859 | pmk = list_entry(ptr, struct pmk_t, list); |
1860 | if(!memcmp(pmksa->bssid.sa_data, pmk->bssid, ETH_ALEN)){ /* match address! list del. */ |
1861 | memset(pmk->bssid, 0, ETH_ALEN); |
1862 | memset(pmk->pmkid, 0, IW_PMKID_LEN); |
1863 | list_del_init(&pmk->list); |
1864 | break; |
1865 | } |
1866 | } |
1867 | if(ptr == &priv->pmklist.head){ /* not find address. */ |
1868 | return 0; |
1869 | } |
1870 | } |
1871 | break; |
1872 | case IW_PMKSA_FLUSH: |
1873 | memset(&(priv->pmklist), 0, sizeof(priv->pmklist)); |
1874 | INIT_LIST_HEAD(&priv->pmklist.head); |
1875 | for(i=0;i<PMK_LIST_MAX;i++) |
1876 | INIT_LIST_HEAD(&priv->pmklist.pmk[i].list); |
1877 | break; |
1878 | default: |
1879 | return -EINVAL; |
1880 | } |
1881 | |
1882 | hostif_sme_enqueue(priv, SME_SET_PMKSA); |
1883 | return 0; |
1884 | } |
1885 | |
1886 | static struct iw_statistics *ks_get_wireless_stats(struct net_device *dev) |
1887 | { |
1888 | |
1889 | ks_wlan_private *priv = (ks_wlan_private *) netdev_priv(dev); |
1890 | struct iw_statistics *wstats = &priv->wstats; |
1891 | |
1892 | if(!atomic_read(&update_phyinfo)){ |
1893 | if (priv->dev_state < DEVICE_STATE_READY) |
1894 | return NULL; /* not finished initialize */ |
1895 | else |
1896 | return wstats; |
1897 | } |
1898 | |
1899 | /* Packets discarded in the wireless adapter due to wireless |
1900 | * specific problems */ |
1901 | wstats->discard.nwid = 0; /* Rx invalid nwid */ |
1902 | wstats->discard.code = 0; /* Rx invalid crypt */ |
1903 | wstats->discard.fragment = 0; /* Rx invalid frag */ |
1904 | wstats->discard.retries = 0; /* Tx excessive retries */ |
1905 | wstats->discard.misc = 0; /* Invalid misc */ |
1906 | wstats->miss.beacon = 0; /* Missed beacon */ |
1907 | |
1908 | return wstats; |
1909 | } |
1910 | |
1911 | /*------------------------------------------------------------------*/ |
1912 | /* Private handler : set stop request */ |
1913 | static int ks_wlan_set_stop_request(struct net_device *dev, struct iw_request_info *info, |
1914 | __u32 *uwrq, char *extra) |
1915 | { |
1916 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1917 | DPRINTK(2,"\n"); |
1918 | |
1919 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1920 | |
1921 | if(!(*uwrq)) |
1922 | return -EINVAL; |
1923 | |
1924 | hostif_sme_enqueue(priv, SME_STOP_REQUEST); |
1925 | return 0; |
1926 | } |
1927 | |
1928 | /*------------------------------------------------------------------*/ |
1929 | /* Wireless Handler : set MLME */ |
1930 | #include <linux/ieee80211.h> |
1931 | static int ks_wlan_set_mlme(struct net_device *dev, struct iw_request_info *info, |
1932 | struct iw_point *dwrq, char *extra) |
1933 | { |
1934 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1935 | struct iw_mlme *mlme = (struct iw_mlme *)extra; |
1936 | __u32 mode; |
1937 | |
1938 | DPRINTK(2, ":%d :%d\n", mlme->cmd, mlme->reason_code); |
1939 | |
1940 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1941 | |
1942 | switch (mlme->cmd) { |
1943 | case IW_MLME_DEAUTH: |
1944 | if (mlme->reason_code == WLAN_REASON_MIC_FAILURE) { |
1945 | return 0; |
1946 | } |
1947 | case IW_MLME_DISASSOC: |
1948 | mode = 1; |
1949 | return ks_wlan_set_stop_request(dev, NULL, &mode, NULL); |
1950 | default: |
1951 | return -EOPNOTSUPP; /* Not Support */ |
1952 | } |
1953 | } |
1954 | #endif /* WIRELESS_EXT */ |
1955 | |
1956 | /*------------------------------------------------------------------*/ |
1957 | /* Private handler : get driver version */ |
1958 | static int ks_wlan_get_driver_version(struct net_device *dev, struct iw_request_info *info, |
1959 | struct iw_point *dwrq, char *extra) |
1960 | { |
1961 | strcpy(extra, KS_WLAN_DRIVER_VERSION_INFO); |
1962 | dwrq->length = strlen(KS_WLAN_DRIVER_VERSION_INFO)+1; |
1963 | return 0; |
1964 | } |
1965 | |
1966 | /*------------------------------------------------------------------*/ |
1967 | /* Private handler : get firemware version */ |
1968 | static int ks_wlan_get_firmware_version(struct net_device *dev, struct iw_request_info *info, |
1969 | struct iw_point *dwrq, char *extra) |
1970 | { |
1971 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
1972 | strcpy(extra, &(priv->firmware_version[0])); |
1973 | dwrq->length = priv->version_size+1; |
1974 | return 0; |
1975 | } |
1976 | |
1977 | #if 0 |
1978 | /*------------------------------------------------------------------*/ |
1979 | /* Private handler : set force disconnect status */ |
1980 | static int ks_wlan_set_detach(struct net_device *dev, struct iw_request_info *info, |
1981 | __u32 *uwrq, char *extra) |
1982 | { |
1983 | ks_wlan_private *priv = (ks_wlan_private *)dev->priv; |
1984 | |
1985 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
1986 | |
1987 | if(*uwrq == CONNECT_STATUS){ /* 0 */ |
1988 | priv->connect_status &= ~FORCE_DISCONNECT; |
1989 | if((priv->connect_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) |
1990 | netif_carrier_on(dev); |
1991 | }else if(*uwrq == DISCONNECT_STATUS){ /* 1 */ |
1992 | priv->connect_status |= FORCE_DISCONNECT; |
1993 | netif_carrier_off(dev); |
1994 | }else |
1995 | return -EINVAL; |
1996 | return 0; |
1997 | } |
1998 | |
1999 | /*------------------------------------------------------------------*/ |
2000 | /* Private handler : get force disconnect status */ |
2001 | static int ks_wlan_get_detach(struct net_device *dev, struct iw_request_info *info, |
2002 | __u32 *uwrq, char *extra) |
2003 | { |
2004 | ks_wlan_private *priv = (ks_wlan_private *)dev->priv; |
2005 | |
2006 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2007 | |
2008 | *uwrq = ((priv->connect_status & FORCE_DISCONNECT) ? 1 : 0 ); |
2009 | return 0; |
2010 | } |
2011 | |
2012 | /*------------------------------------------------------------------*/ |
2013 | /* Private handler : get connect status */ |
2014 | static int ks_wlan_get_connect(struct net_device *dev, struct iw_request_info *info, |
2015 | __u32 *uwrq, char *extra) |
2016 | { |
2017 | ks_wlan_private *priv = (ks_wlan_private *)dev->priv; |
2018 | |
2019 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2020 | |
2021 | *uwrq = (priv->connect_status & CONNECT_STATUS_MASK); |
2022 | return 0; |
2023 | } |
2024 | #endif |
2025 | |
2026 | /*------------------------------------------------------------------*/ |
2027 | /* Private handler : set preamble */ |
2028 | static int ks_wlan_set_preamble(struct net_device *dev, struct iw_request_info *info, |
2029 | __u32 *uwrq, char *extra) |
2030 | { |
2031 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2032 | |
2033 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2034 | |
2035 | if(*uwrq == LONG_PREAMBLE){ /* 0 */ |
2036 | priv->reg.preamble = LONG_PREAMBLE; |
2037 | }else if(*uwrq == SHORT_PREAMBLE){ /* 1 */ |
2038 | priv->reg.preamble = SHORT_PREAMBLE; |
2039 | }else |
2040 | return -EINVAL; |
2041 | |
2042 | priv->need_commit |= SME_MODE_SET; |
2043 | return -EINPROGRESS; /* Call commit handler */ |
2044 | |
2045 | } |
2046 | |
2047 | /*------------------------------------------------------------------*/ |
2048 | /* Private handler : get preamble */ |
2049 | static int ks_wlan_get_preamble(struct net_device *dev, struct iw_request_info *info, |
2050 | __u32 *uwrq, char *extra) |
2051 | { |
2052 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2053 | |
2054 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2055 | |
2056 | *uwrq = priv->reg.preamble; |
2057 | return 0; |
2058 | } |
2059 | |
2060 | /*------------------------------------------------------------------*/ |
2061 | /* Private handler : set power save mode */ |
2062 | static int ks_wlan_set_powermgt(struct net_device *dev, struct iw_request_info *info, |
2063 | __u32 *uwrq, char *extra) |
2064 | { |
2065 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2066 | |
2067 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2068 | |
2069 | if(*uwrq == POWMGT_ACTIVE_MODE){ /* 0 */ |
2070 | priv->reg.powermgt = POWMGT_ACTIVE_MODE; |
2071 | }else if(*uwrq == POWMGT_SAVE1_MODE){ /* 1 */ |
2072 | if(priv->reg.operation_mode == MODE_INFRASTRUCTURE) |
2073 | priv->reg.powermgt = POWMGT_SAVE1_MODE; |
2074 | else |
2075 | return -EINVAL; |
2076 | }else if(*uwrq == POWMGT_SAVE2_MODE){ /* 2 */ |
2077 | if(priv->reg.operation_mode == MODE_INFRASTRUCTURE) |
2078 | priv->reg.powermgt = POWMGT_SAVE2_MODE; |
2079 | else |
2080 | return -EINVAL; |
2081 | }else |
2082 | return -EINVAL; |
2083 | |
2084 | hostif_sme_enqueue(priv, SME_POW_MNGMT_REQUEST); |
2085 | |
2086 | return 0; |
2087 | } |
2088 | |
2089 | /*------------------------------------------------------------------*/ |
2090 | /* Private handler : get power save made */ |
2091 | static int ks_wlan_get_powermgt(struct net_device *dev, struct iw_request_info *info, |
2092 | __u32 *uwrq, char *extra) |
2093 | { |
2094 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2095 | |
2096 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2097 | |
2098 | *uwrq = priv->reg.powermgt; |
2099 | return 0; |
2100 | } |
2101 | |
2102 | /*------------------------------------------------------------------*/ |
2103 | /* Private handler : set scan type */ |
2104 | static int ks_wlan_set_scan_type(struct net_device *dev, struct iw_request_info *info, |
2105 | __u32 *uwrq, char *extra) |
2106 | { |
2107 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2108 | |
2109 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2110 | |
2111 | if(*uwrq == ACTIVE_SCAN){ /* 0 */ |
2112 | priv->reg.scan_type = ACTIVE_SCAN; |
2113 | }else if(*uwrq == PASSIVE_SCAN){ /* 1 */ |
2114 | priv->reg.scan_type = PASSIVE_SCAN; |
2115 | }else |
2116 | return -EINVAL; |
2117 | |
2118 | return 0; |
2119 | } |
2120 | |
2121 | /*------------------------------------------------------------------*/ |
2122 | /* Private handler : get scan type */ |
2123 | static int ks_wlan_get_scan_type(struct net_device *dev, struct iw_request_info *info, |
2124 | __u32 *uwrq, char *extra) |
2125 | { |
2126 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2127 | |
2128 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2129 | |
2130 | *uwrq = priv->reg.scan_type; |
2131 | return 0; |
2132 | } |
2133 | #if 0 |
2134 | /*------------------------------------------------------------------*/ |
2135 | /* Private handler : write raw data to device */ |
2136 | static int ks_wlan_data_write(struct net_device *dev, struct iw_request_info *info, |
2137 | struct iw_point *dwrq, char *extra) |
2138 | { |
2139 | ks_wlan_private *priv = (ks_wlan_private *)dev->priv; |
2140 | unsigned char *wbuff = NULL; |
2141 | |
2142 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2143 | |
2144 | wbuff = (unsigned char *)kmalloc(dwrq->length, GFP_ATOMIC); |
2145 | if(!wbuff) |
2146 | return -EFAULT; |
2147 | memcpy(wbuff, extra, dwrq->length); |
2148 | |
2149 | /* write to device */ |
2150 | ks_wlan_hw_tx( priv, wbuff, dwrq->length, NULL, NULL, NULL); |
2151 | |
2152 | return 0; |
2153 | } |
2154 | |
2155 | /*------------------------------------------------------------------*/ |
2156 | /* Private handler : read raw data form device */ |
2157 | static int ks_wlan_data_read(struct net_device *dev, struct iw_request_info *info, |
2158 | struct iw_point *dwrq, char *extra) |
2159 | { |
2160 | ks_wlan_private *priv = (ks_wlan_private *)dev->priv; |
2161 | unsigned short read_length; |
2162 | |
2163 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2164 | |
2165 | if(!atomic_read(&priv->event_count)){ |
2166 | if (priv->dev_state < DEVICE_STATE_BOOT) { /* Remove device */ |
2167 | read_length = 4; |
2168 | memset(extra,0xff,read_length); |
2169 | dwrq->length = read_length; |
2170 | return 0; |
2171 | } |
2172 | read_length = 0; |
2173 | memset(extra,0,1); |
2174 | dwrq->length = 0; |
2175 | return 0; |
2176 | } |
2177 | |
2178 | if(atomic_read(&priv->event_count)>0) |
2179 | atomic_dec(&priv->event_count); |
2180 | |
2181 | spin_lock(&priv->dev_read_lock); /* request spin lock */ |
2182 | |
2183 | /* Copy length max size 0x07ff */ |
2184 | if(priv->dev_size[priv->dev_count] > 2047) |
2185 | read_length = 2047; |
2186 | else |
2187 | read_length = priv->dev_size[priv->dev_count]; |
2188 | |
2189 | /* Copy data */ |
2190 | memcpy(extra, &(priv->dev_data[priv->dev_count][0]), read_length); |
2191 | |
2192 | spin_unlock(&priv->dev_read_lock); /* release spin lock */ |
2193 | |
2194 | /* Initialize */ |
2195 | priv->dev_data[priv->dev_count] = 0; |
2196 | priv->dev_size[priv->dev_count] = 0; |
2197 | |
2198 | priv->dev_count++; |
2199 | if(priv->dev_count == DEVICE_STOCK_COUNT) |
2200 | priv->dev_count=0; |
2201 | |
2202 | /* Set read size */ |
2203 | dwrq->length = read_length; |
2204 | |
2205 | return 0; |
2206 | } |
2207 | #endif |
2208 | |
2209 | #if 0 |
2210 | /*------------------------------------------------------------------*/ |
2211 | /* Private handler : get wep string */ |
2212 | #define WEP_ASCII_BUFF_SIZE (17+64*4+1) |
2213 | static int ks_wlan_get_wep_ascii(struct net_device *dev, struct iw_request_info *info, |
2214 | struct iw_point *dwrq, char *extra) |
2215 | { |
2216 | ks_wlan_private *priv = (ks_wlan_private *)dev->priv; |
2217 | int i,j,len=0; |
2218 | char tmp[WEP_ASCII_BUFF_SIZE]; |
2219 | |
2220 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2221 | |
2222 | strcpy(tmp," WEP keys ASCII \n"); |
2223 | len+=strlen(" WEP keys ASCII \n"); |
2224 | |
2225 | for(i=0;i<4;i++){ |
2226 | strcpy(tmp+len,"\t["); |
2227 | len+=strlen("\t["); |
2228 | tmp[len] = '1'+i; |
2229 | len++; |
2230 | strcpy(tmp+len,"] "); |
2231 | len+=strlen("] "); |
2232 | if(priv->reg.wep_key[i].size){ |
2233 | strcpy(tmp+len,(priv->reg.wep_key[i].size < 6 ? "(40bits) [" : "(104bits) [")); |
2234 | len+=strlen((priv->reg.wep_key[i].size < 6 ? "(40bits) [" : "(104bits) [")); |
2235 | for(j=0;j<priv->reg.wep_key[i].size;j++,len++) |
2236 | tmp[len]=(isprint(priv->reg.wep_key[i].val[j]) ? priv->reg.wep_key[i].val[j] : ' '); |
2237 | |
2238 | strcpy(tmp+len,"]\n"); |
2239 | len+=strlen("]\n"); |
2240 | } |
2241 | else{ |
2242 | strcpy(tmp+len,"off\n"); |
2243 | len+=strlen("off\n"); |
2244 | } |
2245 | } |
2246 | |
2247 | memcpy(extra, tmp, len); |
2248 | dwrq->length = len+1; |
2249 | return 0; |
2250 | } |
2251 | #endif |
2252 | |
2253 | /*------------------------------------------------------------------*/ |
2254 | /* Private handler : set beacon lost count */ |
2255 | static int ks_wlan_set_beacon_lost(struct net_device *dev, struct iw_request_info *info, |
2256 | __u32 *uwrq, char *extra) |
2257 | { |
2258 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2259 | |
2260 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2261 | |
2262 | if(*uwrq >= BEACON_LOST_COUNT_MIN && |
2263 | *uwrq <= BEACON_LOST_COUNT_MAX){ |
2264 | priv->reg.beacon_lost_count = *uwrq; |
2265 | }else |
2266 | return -EINVAL; |
2267 | |
2268 | if(priv->reg.operation_mode == MODE_INFRASTRUCTURE){ |
2269 | priv->need_commit |= SME_MODE_SET; |
2270 | return -EINPROGRESS; /* Call commit handler */ |
2271 | } |
2272 | else |
2273 | return 0; |
2274 | } |
2275 | |
2276 | /*------------------------------------------------------------------*/ |
2277 | /* Private handler : get beacon lost count */ |
2278 | static int ks_wlan_get_beacon_lost(struct net_device *dev, struct iw_request_info *info, |
2279 | __u32 *uwrq, char *extra) |
2280 | { |
2281 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2282 | |
2283 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2284 | |
2285 | *uwrq = priv->reg.beacon_lost_count; |
2286 | return 0; |
2287 | } |
2288 | |
2289 | /*------------------------------------------------------------------*/ |
2290 | /* Private handler : set phy type */ |
2291 | static int ks_wlan_set_phy_type(struct net_device *dev, struct iw_request_info *info, |
2292 | __u32 *uwrq, char *extra) |
2293 | { |
2294 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2295 | |
2296 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2297 | |
2298 | if(*uwrq == D_11B_ONLY_MODE){ /* 0 */ |
2299 | priv->reg.phy_type = D_11B_ONLY_MODE; |
2300 | }else if(*uwrq == D_11G_ONLY_MODE){ /* 1 */ |
2301 | priv->reg.phy_type = D_11G_ONLY_MODE; |
2302 | }else if(*uwrq == D_11BG_COMPATIBLE_MODE){ /* 2 */ |
2303 | priv->reg.phy_type = D_11BG_COMPATIBLE_MODE; |
2304 | }else |
2305 | return -EINVAL; |
2306 | |
2307 | priv->need_commit |= SME_MODE_SET; |
2308 | return -EINPROGRESS; /* Call commit handler */ |
2309 | } |
2310 | |
2311 | /*------------------------------------------------------------------*/ |
2312 | /* Private handler : get phy type */ |
2313 | static int ks_wlan_get_phy_type(struct net_device *dev, struct iw_request_info *info, |
2314 | __u32 *uwrq, char *extra) |
2315 | { |
2316 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2317 | |
2318 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2319 | |
2320 | *uwrq = priv->reg.phy_type; |
2321 | return 0; |
2322 | } |
2323 | |
2324 | /*------------------------------------------------------------------*/ |
2325 | /* Private handler : set cts mode */ |
2326 | static int ks_wlan_set_cts_mode(struct net_device *dev, struct iw_request_info *info, |
2327 | __u32 *uwrq, char *extra) |
2328 | { |
2329 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2330 | |
2331 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2332 | |
2333 | if(*uwrq == CTS_MODE_FALSE){ /* 0 */ |
2334 | priv->reg.cts_mode = CTS_MODE_FALSE; |
2335 | }else if(*uwrq == CTS_MODE_TRUE){ /* 1 */ |
2336 | if(priv->reg.phy_type == D_11G_ONLY_MODE || |
2337 | priv->reg.phy_type == D_11BG_COMPATIBLE_MODE) |
2338 | priv->reg.cts_mode = CTS_MODE_TRUE; |
2339 | else |
2340 | priv->reg.cts_mode = CTS_MODE_FALSE; |
2341 | }else |
2342 | return -EINVAL; |
2343 | |
2344 | priv->need_commit |= SME_MODE_SET; |
2345 | return -EINPROGRESS; /* Call commit handler */ |
2346 | } |
2347 | |
2348 | /*------------------------------------------------------------------*/ |
2349 | /* Private handler : get cts mode */ |
2350 | static int ks_wlan_get_cts_mode(struct net_device *dev, struct iw_request_info *info, |
2351 | __u32 *uwrq, char *extra) |
2352 | { |
2353 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2354 | |
2355 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2356 | |
2357 | *uwrq = priv->reg.cts_mode; |
2358 | return 0; |
2359 | } |
2360 | |
2361 | /*------------------------------------------------------------------*/ |
2362 | /* Private handler : set sleep mode */ |
2363 | static int ks_wlan_set_sleep_mode(struct net_device *dev, |
2364 | struct iw_request_info *info, |
2365 | __u32 *uwrq, char *extra) |
2366 | { |
2367 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2368 | |
2369 | DPRINTK(2,"\n"); |
2370 | |
2371 | if(*uwrq == SLP_SLEEP){ |
2372 | priv->sleep_mode = *uwrq; |
2373 | printk("SET_SLEEP_MODE %d\n", priv->sleep_mode); |
2374 | |
2375 | hostif_sme_enqueue(priv, SME_STOP_REQUEST); |
2376 | hostif_sme_enqueue(priv, SME_SLEEP_REQUEST); |
2377 | |
2378 | }else if(*uwrq == SLP_ACTIVE) { |
2379 | priv->sleep_mode = *uwrq; |
2380 | printk("SET_SLEEP_MODE %d\n", priv->sleep_mode); |
2381 | hostif_sme_enqueue(priv, SME_SLEEP_REQUEST); |
2382 | }else{ |
2383 | printk("SET_SLEEP_MODE %d errror\n", *uwrq); |
2384 | return -EINVAL; |
2385 | } |
2386 | |
2387 | return 0; |
2388 | } |
2389 | /*------------------------------------------------------------------*/ |
2390 | /* Private handler : get sleep mode */ |
2391 | static int ks_wlan_get_sleep_mode(struct net_device *dev, |
2392 | struct iw_request_info *info, |
2393 | __u32 *uwrq, char *extra) |
2394 | { |
2395 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2396 | |
2397 | DPRINTK(2, "GET_SLEEP_MODE %d\n", priv->sleep_mode); |
2398 | *uwrq = priv->sleep_mode; |
2399 | |
2400 | return 0; |
2401 | } |
2402 | |
2403 | #if 0 |
2404 | /*------------------------------------------------------------------*/ |
2405 | /* Private handler : set phy information timer */ |
2406 | static int ks_wlan_set_phy_information_timer(struct net_device *dev, struct iw_request_info *info, |
2407 | __u32 *uwrq, char *extra) |
2408 | { |
2409 | ks_wlan_private *priv = (ks_wlan_private *)dev->priv; |
2410 | |
2411 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2412 | |
2413 | if(*uwrq >= 0 && *uwrq <= 0xFFFF) /* 0-65535 */ |
2414 | priv->reg.phy_info_timer = (uint16_t)*uwrq; |
2415 | else |
2416 | return -EINVAL; |
2417 | |
2418 | hostif_sme_enqueue(priv, SME_PHY_INFO_REQUEST); |
2419 | |
2420 | return 0; |
2421 | } |
2422 | |
2423 | /*------------------------------------------------------------------*/ |
2424 | /* Private handler : get phy information timer */ |
2425 | static int ks_wlan_get_phy_information_timer(struct net_device *dev, struct iw_request_info *info, |
2426 | __u32 *uwrq, char *extra) |
2427 | { |
2428 | ks_wlan_private *priv = (ks_wlan_private *)dev->priv; |
2429 | |
2430 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2431 | |
2432 | *uwrq = priv->reg.phy_info_timer; |
2433 | return 0; |
2434 | } |
2435 | #endif |
2436 | |
2437 | #ifdef WPS |
2438 | /*------------------------------------------------------------------*/ |
2439 | /* Private handler : set WPS enable */ |
2440 | static int ks_wlan_set_wps_enable(struct net_device *dev, struct iw_request_info *info, |
2441 | __u32 *uwrq, char *extra) |
2442 | { |
2443 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2444 | DPRINTK(2,"\n"); |
2445 | |
2446 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2447 | |
2448 | if(*uwrq == 0 || *uwrq == 1) |
2449 | priv->wps.wps_enabled = *uwrq; |
2450 | else |
2451 | return -EINVAL; |
2452 | |
2453 | hostif_sme_enqueue(priv, SME_WPS_ENABLE_REQUEST); |
2454 | |
2455 | return 0; |
2456 | } |
2457 | /*------------------------------------------------------------------*/ |
2458 | /* Private handler : get WPS enable */ |
2459 | static int ks_wlan_get_wps_enable(struct net_device *dev, struct iw_request_info *info, |
2460 | __u32 *uwrq, char *extra) |
2461 | { |
2462 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2463 | DPRINTK(2,"\n"); |
2464 | |
2465 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2466 | |
2467 | *uwrq = priv->wps.wps_enabled; |
2468 | printk("return=%d\n", *uwrq); |
2469 | |
2470 | return 0; |
2471 | } |
2472 | /*------------------------------------------------------------------*/ |
2473 | /* Private handler : set WPS probe req */ |
2474 | static int ks_wlan_set_wps_probe_req(struct net_device *dev, |
2475 | struct iw_request_info *info, |
2476 | struct iw_point *dwrq, char *extra) |
2477 | { |
2478 | uint8_t *p = extra; |
2479 | unsigned char len; |
2480 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2481 | |
2482 | DPRINTK(2,"\n"); |
2483 | |
2484 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2485 | |
2486 | DPRINTK(2,"dwrq->length=%d\n", dwrq->length); |
2487 | |
2488 | /* length check */ |
2489 | if(p[1] + 2 != dwrq->length || dwrq->length > 256 ){ |
2490 | return -EINVAL; |
2491 | } |
2492 | |
2493 | priv->wps.ielen = p[1] + 2 + 1; /* IE header + IE + sizeof(len) */ |
2494 | len = p[1] + 2; /* IE header + IE */ |
2495 | |
2496 | memcpy(priv->wps.ie, &len, sizeof(len)); |
2497 | p = memcpy(priv->wps.ie+1, p, len); |
2498 | |
2499 | DPRINTK(2,"%d(%#x): %02X %02X %02X %02X ... %02X %02X %02X\n", |
2500 | priv->wps.ielen, priv->wps.ielen, p[0], p[1], p[2], p[3], |
2501 | p[priv->wps.ielen-3], p[priv->wps.ielen-2], p[priv->wps.ielen-1]); |
2502 | |
2503 | hostif_sme_enqueue(priv, SME_WPS_PROBE_REQUEST); |
2504 | |
2505 | return 0; |
2506 | } |
2507 | #if 0 |
2508 | /*------------------------------------------------------------------*/ |
2509 | /* Private handler : get WPS probe req */ |
2510 | static int ks_wlan_get_wps_probe_req(struct net_device *dev, |
2511 | struct iw_request_info *info, |
2512 | __u32 *uwrq, char *extra) |
2513 | { |
2514 | ks_wlan_private *priv = (ks_wlan_private *)dev->priv; |
2515 | DPRINTK(2,"\n"); |
2516 | |
2517 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2518 | |
2519 | return 0; |
2520 | } |
2521 | #endif |
2522 | #endif /* WPS */ |
2523 | |
2524 | /*------------------------------------------------------------------*/ |
2525 | /* Private handler : set tx gain control value */ |
2526 | static int ks_wlan_set_tx_gain(struct net_device *dev, struct iw_request_info *info, |
2527 | __u32 *uwrq, char *extra) |
2528 | { |
2529 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2530 | |
2531 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2532 | |
2533 | if(*uwrq >= 0 && *uwrq <= 0xFF) /* 0-255 */ |
2534 | priv->gain.TxGain = (uint8_t)*uwrq; |
2535 | else |
2536 | return -EINVAL; |
2537 | |
2538 | if(priv->gain.TxGain < 0xFF) |
2539 | priv->gain.TxMode = 1; |
2540 | else |
2541 | priv->gain.TxMode = 0; |
2542 | |
2543 | |
2544 | hostif_sme_enqueue(priv, SME_SET_GAIN); |
2545 | return 0; |
2546 | } |
2547 | |
2548 | /*------------------------------------------------------------------*/ |
2549 | /* Private handler : get tx gain control value */ |
2550 | static int ks_wlan_get_tx_gain(struct net_device *dev, struct iw_request_info *info, |
2551 | __u32 *uwrq, char *extra) |
2552 | { |
2553 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2554 | |
2555 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2556 | |
2557 | *uwrq = priv->gain.TxGain; |
2558 | hostif_sme_enqueue(priv, SME_GET_GAIN); |
2559 | return 0; |
2560 | } |
2561 | |
2562 | /*------------------------------------------------------------------*/ |
2563 | /* Private handler : set rx gain control value */ |
2564 | static int ks_wlan_set_rx_gain(struct net_device *dev, struct iw_request_info *info, |
2565 | __u32 *uwrq, char *extra) |
2566 | { |
2567 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2568 | |
2569 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2570 | |
2571 | if(*uwrq >= 0 && *uwrq <= 0xFF) /* 0-255 */ |
2572 | priv->gain.RxGain = (uint8_t)*uwrq; |
2573 | else |
2574 | return -EINVAL; |
2575 | |
2576 | if(priv->gain.RxGain < 0xFF) |
2577 | priv->gain.RxMode = 1; |
2578 | else |
2579 | priv->gain.RxMode = 0; |
2580 | |
2581 | hostif_sme_enqueue(priv, SME_SET_GAIN); |
2582 | return 0; |
2583 | } |
2584 | |
2585 | /*------------------------------------------------------------------*/ |
2586 | /* Private handler : get rx gain control value */ |
2587 | static int ks_wlan_get_rx_gain(struct net_device *dev, struct iw_request_info *info, |
2588 | __u32 *uwrq, char *extra) |
2589 | { |
2590 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2591 | |
2592 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2593 | |
2594 | *uwrq = priv->gain.RxGain; |
2595 | hostif_sme_enqueue(priv, SME_GET_GAIN); |
2596 | return 0; |
2597 | } |
2598 | #if 0 |
2599 | /*------------------------------------------------------------------*/ |
2600 | /* Private handler : set region value */ |
2601 | static int ks_wlan_set_region(struct net_device *dev, struct iw_request_info *info, |
2602 | __u32 *uwrq, char *extra) |
2603 | { |
2604 | ks_wlan_private *priv = (ks_wlan_private *)dev->priv; |
2605 | |
2606 | if (priv->sleep_mode == SLP_SLEEP){ return -EPERM; } /* for SLEEP MODE */ |
2607 | |
2608 | if(*uwrq >= 0x9 && *uwrq <= 0xF) /* 0x9-0xf */ |
2609 | priv->region = (uint8_t)*uwrq; |
2610 | else |
2611 | return -EINVAL; |
2612 | |
2613 | hostif_sme_enqueue(priv, SME_SET_REGION); |
2614 | return 0; |
2615 | } |
2616 | #endif |
2617 | |
2618 | /*------------------------------------------------------------------*/ |
2619 | /* Private handler : get eeprom checksum result */ |
2620 | static int ks_wlan_get_eeprom_cksum(struct net_device *dev, struct iw_request_info *info, |
2621 | __u32 *uwrq, char *extra) |
2622 | { |
2623 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2624 | |
2625 | *uwrq = priv->eeprom_checksum; |
2626 | return 0; |
2627 | } |
2628 | |
2629 | static void print_hif_event(int event){ |
2630 | |
2631 | switch(event){ |
2632 | case HIF_DATA_REQ : |
2633 | printk("HIF_DATA_REQ\n"); |
2634 | break; |
2635 | case HIF_DATA_IND : |
2636 | printk("HIF_DATA_IND\n"); |
2637 | break; |
2638 | case HIF_MIB_GET_REQ : |
2639 | printk("HIF_MIB_GET_REQ\n"); |
2640 | break; |
2641 | case HIF_MIB_GET_CONF : |
2642 | printk("HIF_MIB_GET_CONF\n"); |
2643 | break; |
2644 | case HIF_MIB_SET_REQ : |
2645 | printk("HIF_MIB_SET_REQ\n"); |
2646 | break; |
2647 | case HIF_MIB_SET_CONF : |
2648 | printk("HIF_MIB_SET_CONF\n"); |
2649 | break; |
2650 | case HIF_POWERMGT_REQ : |
2651 | printk("HIF_POWERMGT_REQ\n"); |
2652 | break; |
2653 | case HIF_POWERMGT_CONF : |
2654 | printk("HIF_POWERMGT_CONF\n"); |
2655 | break; |
2656 | case HIF_START_REQ : |
2657 | printk("HIF_START_REQ\n"); |
2658 | break; |
2659 | case HIF_START_CONF : |
2660 | printk("HIF_START_CONF\n"); |
2661 | break; |
2662 | case HIF_CONNECT_IND : |
2663 | printk("HIF_CONNECT_IND\n"); |
2664 | break; |
2665 | case HIF_STOP_REQ : |
2666 | printk("HIF_STOP_REQ\n"); |
2667 | break; |
2668 | case HIF_STOP_CONF : |
2669 | printk("HIF_STOP_CONF\n"); |
2670 | break; |
2671 | case HIF_PS_ADH_SET_REQ : |
2672 | printk("HIF_PS_ADH_SET_REQ\n"); |
2673 | break; |
2674 | case HIF_PS_ADH_SET_CONF: |
2675 | printk("HIF_PS_ADH_SET_CONF\n"); |
2676 | break; |
2677 | case HIF_INFRA_SET_REQ : |
2678 | printk("HIF_INFRA_SET_REQ\n"); |
2679 | break; |
2680 | case HIF_INFRA_SET_CONF : |
2681 | printk("HIF_INFRA_SET_CONF\n"); |
2682 | break; |
2683 | case HIF_ADH_SET_REQ : |
2684 | printk("HIF_ADH_SET_REQ\n"); |
2685 | break; |
2686 | case HIF_ADH_SET_CONF : |
2687 | printk("HIF_ADH_SET_CONF\n"); |
2688 | break; |
2689 | case HIF_AP_SET_REQ : |
2690 | printk("HIF_AP_SET_REQ\n"); |
2691 | break; |
2692 | case HIF_AP_SET_CONF : |
2693 | printk("HIF_AP_SET_CONF\n"); |
2694 | break; |
2695 | case HIF_ASSOC_INFO_IND : |
2696 | printk("HIF_ASSOC_INFO_IND\n"); |
2697 | break; |
2698 | case HIF_MIC_FAILURE_REQ: |
2699 | printk("HIF_MIC_FAILURE_REQ\n"); |
2700 | break; |
2701 | case HIF_MIC_FAILURE_CONF : |
2702 | printk("HIF_MIC_FAILURE_CONF\n"); |
2703 | break; |
2704 | case HIF_SCAN_REQ : |
2705 | printk("HIF_SCAN_REQ\n"); |
2706 | break; |
2707 | case HIF_SCAN_CONF : |
2708 | printk("HIF_SCAN_CONF\n"); |
2709 | break; |
2710 | case HIF_PHY_INFO_REQ : |
2711 | printk("HIF_PHY_INFO_REQ\n"); |
2712 | break; |
2713 | case HIF_PHY_INFO_CONF : |
2714 | printk("HIF_PHY_INFO_CONF\n"); |
2715 | break; |
2716 | case HIF_SLEEP_REQ : |
2717 | printk("HIF_SLEEP_REQ\n"); |
2718 | break; |
2719 | case HIF_SLEEP_CONF : |
2720 | printk("HIF_SLEEP_CONF\n"); |
2721 | break; |
2722 | case HIF_PHY_INFO_IND : |
2723 | printk("HIF_PHY_INFO_IND\n"); |
2724 | break; |
2725 | case HIF_SCAN_IND : |
2726 | printk("HIF_SCAN_IND\n"); |
2727 | break; |
2728 | case HIF_INFRA_SET2_REQ : |
2729 | printk("HIF_INFRA_SET2_REQ\n"); |
2730 | break; |
2731 | case HIF_INFRA_SET2_CONF: |
2732 | printk("HIF_INFRA_SET2_CONF\n"); |
2733 | break; |
2734 | case HIF_ADH_SET2_REQ : |
2735 | printk("HIF_ADH_SET2_REQ\n"); |
2736 | break; |
2737 | case HIF_ADH_SET2_CONF : |
2738 | printk("HIF_ADH_SET2_CONF\n"); |
2739 | } |
2740 | } |
2741 | |
2742 | /*------------------------------------------------------------------*/ |
2743 | /* Private handler : get host command history */ |
2744 | static int ks_wlan_hostt(struct net_device *dev, struct iw_request_info *info, |
2745 | __u32 *uwrq, char *extra) |
2746 | { |
2747 | int i,event; |
2748 | ks_wlan_private *priv = (ks_wlan_private *)netdev_priv(dev); |
2749 | |
2750 | for(i = 63; i >= 0; i--){ |
2751 | event = priv->hostt.buff[(priv->hostt.qtail -1 -i)%SME_EVENT_BUFF_SIZE] ; |
2752 | print_hif_event(event); |
2753 | } |
2754 | return 0; |
2755 | } |
2756 | |
2757 | /* Structures to export the Wireless Handlers */ |
2758 | |
2759 | static const struct iw_priv_args ks_wlan_private_args[] = { |
2760 | /*{ cmd, set_args, get_args, name[16] } */ |
2761 | { KS_WLAN_GET_DRIVER_VERSION, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_CHAR | (128+1), "GetDriverVer" }, |
2762 | { KS_WLAN_GET_FIRM_VERSION, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_CHAR | (128+1), "GetFirmwareVer" }, |
2763 | #ifdef WPS |
2764 | { KS_WLAN_SET_WPS_ENABLE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, "SetWPSEnable" }, |
2765 | { KS_WLAN_GET_WPS_ENABLE, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "GetW" }, |
2766 | { KS_WLAN_SET_WPS_PROBE_REQ, IW_PRIV_TYPE_BYTE | 2047, IW_PRIV_TYPE_NONE, "SetWPSProbeReq" }, |
2767 | #endif /* WPS */ |
2768 | { KS_WLAN_SET_PREAMBLE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, "SetPreamble" }, |
2769 | { KS_WLAN_GET_PREAMBLE, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "GetPreamble" }, |
2770 | { KS_WLAN_SET_POWER_SAVE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, "SetPowerSave" }, |
2771 | { KS_WLAN_GET_POWER_SAVE, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "GetPowerSave" }, |
2772 | { KS_WLAN_SET_SCAN_TYPE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, "SetScanType" }, |
2773 | { KS_WLAN_GET_SCAN_TYPE, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "GetScanType" }, |
2774 | { KS_WLAN_SET_RX_GAIN, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, "SetRxGain" }, |
2775 | { KS_WLAN_GET_RX_GAIN, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "GetRxGain" }, |
2776 | { KS_WLAN_HOSTT, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_CHAR | (128+1), "hostt" }, |
2777 | { KS_WLAN_SET_BEACON_LOST, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, "SetBeaconLost" }, |
2778 | { KS_WLAN_GET_BEACON_LOST, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "GetBeaconLost" }, |
2779 | { KS_WLAN_SET_SLEEP_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, "SetSleepMode" }, |
2780 | { KS_WLAN_GET_SLEEP_MODE, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "GetSleepMode" }, |
2781 | { KS_WLAN_SET_TX_GAIN, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, "SetTxGain" }, |
2782 | { KS_WLAN_GET_TX_GAIN, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "GetTxGain" }, |
2783 | { KS_WLAN_SET_PHY_TYPE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, "SetPhyType" }, |
2784 | { KS_WLAN_GET_PHY_TYPE, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "GetPhyType" }, |
2785 | { KS_WLAN_SET_CTS_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_NONE, "SetCtsMode" }, |
2786 | { KS_WLAN_GET_CTS_MODE, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "GetCtsMode" }, |
2787 | { KS_WLAN_GET_EEPROM_CKSUM, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "GetChecksum" }, |
2788 | }; |
2789 | static const iw_handler ks_wlan_handler[] = |
2790 | { |
2791 | (iw_handler) ks_wlan_config_commit, /* SIOCSIWCOMMIT */ |
2792 | (iw_handler) ks_wlan_get_name, /* SIOCGIWNAME */ |
2793 | (iw_handler) NULL, /* SIOCSIWNWID */ |
2794 | (iw_handler) NULL, /* SIOCGIWNWID */ |
2795 | (iw_handler) ks_wlan_set_freq, /* SIOCSIWFREQ */ |
2796 | (iw_handler) ks_wlan_get_freq, /* SIOCGIWFREQ */ |
2797 | (iw_handler) ks_wlan_set_mode, /* SIOCSIWMODE */ |
2798 | (iw_handler) ks_wlan_get_mode, /* SIOCGIWMODE */ |
2799 | #ifndef KSC_OPNOTSUPP |
2800 | (iw_handler) ks_wlan_set_sens, /* SIOCSIWSENS */ |
2801 | (iw_handler) ks_wlan_get_sens, /* SIOCGIWSENS */ |
2802 | #else /* KSC_OPNOTSUPP */ |
2803 | (iw_handler) NULL, /* SIOCSIWSENS */ |
2804 | (iw_handler) NULL, /* SIOCGIWSENS */ |
2805 | #endif /* KSC_OPNOTSUPP */ |
2806 | (iw_handler) NULL, /* SIOCSIWRANGE */ |
2807 | (iw_handler) ks_wlan_get_range, /* SIOCGIWRANGE */ |
2808 | (iw_handler) NULL, /* SIOCSIWPRIV */ |
2809 | (iw_handler) NULL, /* SIOCGIWPRIV */ |
2810 | (iw_handler) NULL, /* SIOCSIWSTATS */ |
2811 | (iw_handler) ks_wlan_get_iwstats, /* SIOCGIWSTATS */ |
2812 | (iw_handler) NULL, /* SIOCSIWSPY */ |
2813 | (iw_handler) NULL, /* SIOCGIWSPY */ |
2814 | (iw_handler) NULL, /* SIOCSIWTHRSPY */ |
2815 | (iw_handler) NULL, /* SIOCGIWTHRSPY */ |
2816 | (iw_handler) ks_wlan_set_wap, /* SIOCSIWAP */ |
2817 | (iw_handler) ks_wlan_get_wap, /* SIOCGIWAP */ |
2818 | // (iw_handler) NULL, /* SIOCSIWMLME */ |
2819 | (iw_handler) ks_wlan_set_mlme, /* SIOCSIWMLME */ |
2820 | (iw_handler) ks_wlan_get_aplist, /* SIOCGIWAPLIST */ |
2821 | (iw_handler) ks_wlan_set_scan, /* SIOCSIWSCAN */ |
2822 | (iw_handler) ks_wlan_get_scan, /* SIOCGIWSCAN */ |
2823 | (iw_handler) ks_wlan_set_essid, /* SIOCSIWESSID */ |
2824 | (iw_handler) ks_wlan_get_essid, /* SIOCGIWESSID */ |
2825 | (iw_handler) ks_wlan_set_nick, /* SIOCSIWNICKN */ |
2826 | (iw_handler) ks_wlan_get_nick, /* SIOCGIWNICKN */ |
2827 | (iw_handler) NULL, /* -- hole -- */ |
2828 | (iw_handler) NULL, /* -- hole -- */ |
2829 | (iw_handler) ks_wlan_set_rate, /* SIOCSIWRATE */ |
2830 | (iw_handler) ks_wlan_get_rate, /* SIOCGIWRATE */ |
2831 | (iw_handler) ks_wlan_set_rts, /* SIOCSIWRTS */ |
2832 | (iw_handler) ks_wlan_get_rts, /* SIOCGIWRTS */ |
2833 | (iw_handler) ks_wlan_set_frag, /* SIOCSIWFRAG */ |
2834 | (iw_handler) ks_wlan_get_frag, /* SIOCGIWFRAG */ |
2835 | #ifndef KSC_OPNOTSUPP |
2836 | (iw_handler) ks_wlan_set_txpow, /* SIOCSIWTXPOW */ |
2837 | (iw_handler) ks_wlan_get_txpow, /* SIOCGIWTXPOW */ |
2838 | (iw_handler) ks_wlan_set_retry, /* SIOCSIWRETRY */ |
2839 | (iw_handler) ks_wlan_get_retry, /* SIOCGIWRETRY */ |
2840 | #else /* KSC_OPNOTSUPP */ |
2841 | (iw_handler) NULL, /* SIOCSIWTXPOW */ |
2842 | (iw_handler) NULL, /* SIOCGIWTXPOW */ |
2843 | (iw_handler) NULL, /* SIOCSIWRETRY */ |
2844 | (iw_handler) NULL, /* SIOCGIWRETRY */ |
2845 | #endif /* KSC_OPNOTSUPP */ |
2846 | (iw_handler) ks_wlan_set_encode, /* SIOCSIWENCODE */ |
2847 | (iw_handler) ks_wlan_get_encode, /* SIOCGIWENCODE */ |
2848 | (iw_handler) ks_wlan_set_power, /* SIOCSIWPOWER */ |
2849 | (iw_handler) ks_wlan_get_power, /* SIOCGIWPOWER */ |
2850 | (iw_handler) NULL, /* -- hole -- */ |
2851 | (iw_handler) NULL, /* -- hole -- */ |
2852 | // (iw_handler) NULL, /* SIOCSIWGENIE */ |
2853 | (iw_handler) ks_wlan_set_genie, /* SIOCSIWGENIE */ |
2854 | (iw_handler) NULL, /* SIOCGIWGENIE */ |
2855 | (iw_handler) ks_wlan_set_auth_mode, /* SIOCSIWAUTH */ |
2856 | (iw_handler) ks_wlan_get_auth_mode, /* SIOCGIWAUTH */ |
2857 | (iw_handler) ks_wlan_set_encode_ext, /* SIOCSIWENCODEEXT */ |
2858 | (iw_handler) ks_wlan_get_encode_ext, /* SIOCGIWENCODEEXT */ |
2859 | (iw_handler) ks_wlan_set_pmksa, /* SIOCSIWPMKSA */ |
2860 | (iw_handler) NULL, /* -- hole -- */ |
2861 | }; |
2862 | |
2863 | /* private_handler */ |
2864 | static const iw_handler ks_wlan_private_handler[] = |
2865 | { |
2866 | (iw_handler) NULL, /* 0 */ |
2867 | (iw_handler) ks_wlan_get_driver_version, /* 1 KS_WLAN_GET_DRIVER_VERSION */ |
2868 | (iw_handler) NULL, /* 2 */ |
2869 | (iw_handler) ks_wlan_get_firmware_version, /* 3 KS_WLAN_GET_FIRM_VERSION */ |
2870 | #ifdef WPS |
2871 | (iw_handler) ks_wlan_set_wps_enable, /* 4 KS_WLAN_SET_WPS_ENABLE */ |
2872 | (iw_handler) ks_wlan_get_wps_enable, /* 5 KS_WLAN_GET_WPS_ENABLE */ |
2873 | (iw_handler) ks_wlan_set_wps_probe_req, /* 6 KS_WLAN_SET_WPS_PROBE_REQ */ |
2874 | #else |
2875 | (iw_handler) NULL, /* 4 */ |
2876 | (iw_handler) NULL, /* 5 */ |
2877 | (iw_handler) NULL, /* 6 */ |
2878 | #endif /* WPS */ |
2879 | |
2880 | (iw_handler) ks_wlan_get_eeprom_cksum, /* 7 KS_WLAN_GET_CONNECT */ |
2881 | (iw_handler) ks_wlan_set_preamble, /* 8 KS_WLAN_SET_PREAMBLE */ |
2882 | (iw_handler) ks_wlan_get_preamble, /* 9 KS_WLAN_GET_PREAMBLE */ |
2883 | (iw_handler) ks_wlan_set_powermgt, /* 10 KS_WLAN_SET_POWER_SAVE */ |
2884 | (iw_handler) ks_wlan_get_powermgt, /* 11 KS_WLAN_GET_POWER_SAVE */ |
2885 | (iw_handler) ks_wlan_set_scan_type, /* 12 KS_WLAN_SET_SCAN_TYPE */ |
2886 | (iw_handler) ks_wlan_get_scan_type, /* 13 KS_WLAN_GET_SCAN_TYPE */ |
2887 | (iw_handler) ks_wlan_set_rx_gain, /* 14 KS_WLAN_SET_RX_GAIN */ |
2888 | (iw_handler) ks_wlan_get_rx_gain, /* 15 KS_WLAN_GET_RX_GAIN */ |
2889 | (iw_handler) ks_wlan_hostt, /* 16 KS_WLAN_HOSTT */ |
2890 | (iw_handler) NULL, /* 17 */ |
2891 | (iw_handler) ks_wlan_set_beacon_lost, /* 18 KS_WLAN_SET_BECAN_LOST */ |
2892 | (iw_handler) ks_wlan_get_beacon_lost, /* 19 KS_WLAN_GET_BECAN_LOST */ |
2893 | (iw_handler) ks_wlan_set_tx_gain, /* 20 KS_WLAN_SET_TX_GAIN */ |
2894 | (iw_handler) ks_wlan_get_tx_gain, /* 21 KS_WLAN_GET_TX_GAIN */ |
2895 | (iw_handler) ks_wlan_set_phy_type, /* 22 KS_WLAN_SET_PHY_TYPE */ |
2896 | (iw_handler) ks_wlan_get_phy_type, /* 23 KS_WLAN_GET_PHY_TYPE */ |
2897 | (iw_handler) ks_wlan_set_cts_mode, /* 24 KS_WLAN_SET_CTS_MODE */ |
2898 | (iw_handler) ks_wlan_get_cts_mode, /* 25 KS_WLAN_GET_CTS_MODE */ |
2899 | (iw_handler) NULL, /* 26 */ |
2900 | (iw_handler) NULL, /* 27 */ |
2901 | (iw_handler) ks_wlan_set_sleep_mode, /* 28 KS_WLAN_SET_SLEEP_MODE */ |
2902 | (iw_handler) ks_wlan_get_sleep_mode, /* 29 KS_WLAN_GET_SLEEP_MODE */ |
2903 | (iw_handler) NULL, /* 30 */ |
2904 | (iw_handler) NULL, /* 31 */ |
2905 | }; |
2906 | |
2907 | static const struct iw_handler_def ks_wlan_handler_def = |
2908 | { |
2909 | .num_standard = sizeof(ks_wlan_handler)/sizeof(iw_handler), |
2910 | .num_private = sizeof(ks_wlan_private_handler)/sizeof(iw_handler), |
2911 | .num_private_args = sizeof(ks_wlan_private_args)/sizeof(struct iw_priv_args), |
2912 | .standard = (iw_handler *) ks_wlan_handler, |
2913 | .private = (iw_handler *) ks_wlan_private_handler, |
2914 | .private_args = (struct iw_priv_args *) ks_wlan_private_args, |
2915 | .get_wireless_stats = ks_get_wireless_stats, |
2916 | }; |
2917 | |
2918 | #endif /* WIRELESS_EXT */ |
2919 | |
2920 | static int ks_wlan_netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
2921 | { |
2922 | int rc = 0; |
2923 | #if defined(WIRELESS_EXT) |
2924 | struct iwreq *wrq = (struct iwreq *) rq; |
2925 | #endif /* WIRELESS_EXT */ |
2926 | switch (cmd) { |
2927 | #if defined(WIRELESS_EXT) |
2928 | case SIOCIWFIRSTPRIV+20: /* KS_WLAN_SET_STOP_REQ */ |
2929 | rc = ks_wlan_set_stop_request(dev, NULL, &(wrq->u.mode), NULL); |
2930 | break; |
2931 | #endif /* WIRELESS_EXT >17 */ |
2932 | // All other calls are currently unsupported |
2933 | default: |
2934 | rc = -EOPNOTSUPP; |
2935 | } |
2936 | |
2937 | DPRINTK(5,"return=%d\n",rc); |
2938 | return rc; |
2939 | } |
2940 | |
2941 | |
2942 | static |
2943 | struct net_device_stats *ks_wlan_get_stats(struct net_device *dev) |
2944 | { |
2945 | ks_wlan_private *priv = netdev_priv(dev); |
2946 | |
2947 | if (priv->dev_state < DEVICE_STATE_READY) { |
2948 | return NULL; /* not finished initialize */ |
2949 | } |
2950 | |
2951 | return &priv->nstats; |
2952 | } |
2953 | |
2954 | static |
2955 | int ks_wlan_set_mac_address(struct net_device *dev, void *addr) |
2956 | { |
2957 | ks_wlan_private *priv = netdev_priv(dev); |
2958 | struct sockaddr *mac_addr=(struct sockaddr *)addr; |
2959 | if (netif_running(dev)) |
2960 | return -EBUSY; |
2961 | memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len); |
2962 | memcpy(priv->eth_addr, mac_addr->sa_data, ETH_ALEN); |
2963 | |
2964 | priv->mac_address_valid = 0; |
2965 | hostif_sme_enqueue(priv, SME_MACADDRESS_SET_REQUEST); |
2966 | printk(KERN_INFO "ks_wlan: MAC ADDRESS = %02x:%02x:%02x:%02x:%02x:%02x\n", |
2967 | priv->eth_addr[0],priv->eth_addr[1],priv->eth_addr[2], |
2968 | priv->eth_addr[3],priv->eth_addr[4],priv->eth_addr[5]); |
2969 | return 0; |
2970 | } |
2971 | |
2972 | |
2973 | static |
2974 | void ks_wlan_tx_timeout(struct net_device *dev) |
2975 | { |
2976 | ks_wlan_private *priv = netdev_priv(dev); |
2977 | |
2978 | DPRINTK(1,"head(%d) tail(%d)!!\n",priv->tx_dev.qhead, priv->tx_dev.qtail); |
2979 | if(!netif_queue_stopped(dev)){ |
2980 | netif_stop_queue(dev); |
2981 | } |
2982 | priv->nstats.tx_errors++; |
2983 | netif_wake_queue(dev); |
2984 | |
2985 | return; |
2986 | } |
2987 | |
2988 | static |
2989 | int ks_wlan_start_xmit(struct sk_buff *skb, struct net_device *dev) |
2990 | { |
2991 | ks_wlan_private *priv = netdev_priv(dev); |
2992 | int rc = 0; |
2993 | |
2994 | DPRINTK(3,"in_interrupt()=%ld\n",in_interrupt()); |
2995 | |
2996 | if ( skb == NULL ) { |
2997 | printk( KERN_ERR "ks_wlan: skb == NULL!!!\n" ); |
2998 | return 0; |
2999 | } |
3000 | if (priv->dev_state < DEVICE_STATE_READY) { |
3001 | dev_kfree_skb(skb); |
3002 | return 0; /* not finished initialize */ |
3003 | } |
3004 | |
3005 | if(netif_running(dev)) |
3006 | netif_stop_queue(dev); |
3007 | |
3008 | rc = hostif_data_request(priv, skb); |
3009 | dev->trans_start = jiffies; |
3010 | |
3011 | DPRINTK(4,"rc=%d\n",rc); |
3012 | if (rc){ |
3013 | rc=0; |
3014 | } |
3015 | |
3016 | return rc; |
3017 | } |
3018 | |
3019 | void send_packet_complete(void *arg1, void *arg2) |
3020 | { |
3021 | ks_wlan_private *priv = (ks_wlan_private *)arg1; |
3022 | struct sk_buff *packet = (struct sk_buff *)arg2; |
3023 | |
3024 | DPRINTK(3,"\n"); |
3025 | |
3026 | priv->nstats.tx_bytes += packet->len; |
3027 | priv->nstats.tx_packets++; |
3028 | |
3029 | if(netif_queue_stopped(priv->net_dev)) |
3030 | netif_wake_queue(priv->net_dev); |
3031 | |
3032 | if(packet){ |
3033 | dev_kfree_skb(packet); |
3034 | packet=NULL; |
3035 | } |
3036 | |
3037 | } |
3038 | |
3039 | /* Set or clear the multicast filter for this adaptor. |
3040 | This routine is not state sensitive and need not be SMP locked. */ |
3041 | static |
3042 | void ks_wlan_set_multicast_list(struct net_device *dev) |
3043 | { |
3044 | ks_wlan_private *priv = netdev_priv(dev); |
3045 | |
3046 | DPRINTK(4,"\n"); |
3047 | if (priv->dev_state < DEVICE_STATE_READY) { |
3048 | return ; /* not finished initialize */ |
3049 | } |
3050 | hostif_sme_enqueue(priv, SME_MULTICAST_REQUEST); |
3051 | |
3052 | return; |
3053 | } |
3054 | |
3055 | static |
3056 | int ks_wlan_open(struct net_device *dev) |
3057 | { |
3058 | ks_wlan_private *priv = netdev_priv(dev); |
3059 | |
3060 | priv->cur_rx = 0; |
3061 | |
3062 | if(!priv->mac_address_valid){ |
3063 | printk(KERN_ERR "ks_wlan : %s Not READY !!\n", dev->name); |
3064 | return -EBUSY; |
3065 | } |
3066 | else |
3067 | netif_start_queue (dev); |
3068 | |
3069 | return 0; |
3070 | } |
3071 | |
3072 | static |
3073 | int ks_wlan_close(struct net_device *dev) |
3074 | { |
3075 | |
3076 | netif_stop_queue (dev); |
3077 | |
3078 | DPRINTK(4, "%s: Shutting down ethercard, status was 0x%4.4x.\n", |
3079 | dev->name, 0x00); |
3080 | |
3081 | return 0; |
3082 | } |
3083 | |
3084 | |
3085 | /* Operational parameters that usually are not changed. */ |
3086 | /* Time in jiffies before concluding the transmitter is hung. */ |
3087 | #define TX_TIMEOUT (3*HZ) |
3088 | static const unsigned char dummy_addr[] = {0x00,0x0b,0xe3,0x00,0x00,0x00}; |
3089 | |
3090 | static const struct net_device_ops ks_wlan_netdev_ops = { |
3091 | .ndo_start_xmit = ks_wlan_start_xmit, |
3092 | .ndo_open = ks_wlan_open, |
3093 | .ndo_stop = ks_wlan_close, |
3094 | .ndo_do_ioctl = ks_wlan_netdev_ioctl, |
3095 | .ndo_set_mac_address = ks_wlan_set_mac_address, |
3096 | .ndo_get_stats = ks_wlan_get_stats, |
3097 | .ndo_tx_timeout = ks_wlan_tx_timeout, |
3098 | .ndo_set_multicast_list = ks_wlan_set_multicast_list, |
3099 | }; |
3100 | |
3101 | int ks_wlan_net_start(struct net_device *dev) |
3102 | { |
3103 | ks_wlan_private *priv; |
3104 | /* int rc; */ |
3105 | |
3106 | priv = netdev_priv(dev); |
3107 | priv->mac_address_valid = 0; |
3108 | priv->need_commit = 0; |
3109 | |
3110 | priv->device_open_status = 1; |
3111 | |
3112 | /* phy information update timer */ |
3113 | atomic_set(&update_phyinfo,0); |
3114 | init_timer(&update_phyinfo_timer); |
3115 | update_phyinfo_timer.function=ks_wlan_update_phyinfo_timeout; |
3116 | update_phyinfo_timer.data = (unsigned long)priv; |
3117 | |
3118 | /* dummy address set */ |
3119 | memcpy(priv->eth_addr, dummy_addr, ETH_ALEN); |
3120 | dev->dev_addr[0] = priv->eth_addr[0]; |
3121 | dev->dev_addr[1] = priv->eth_addr[1]; |
3122 | dev->dev_addr[2] = priv->eth_addr[2]; |
3123 | dev->dev_addr[3] = priv->eth_addr[3]; |
3124 | dev->dev_addr[4] = priv->eth_addr[4]; |
3125 | dev->dev_addr[5] = priv->eth_addr[5]; |
3126 | dev->dev_addr[6] = 0x00; |
3127 | dev->dev_addr[7] = 0x00; |
3128 | |
3129 | /* The ks_wlan-specific entries in the device structure. */ |
3130 | dev->netdev_ops = &ks_wlan_netdev_ops; |
3131 | dev->wireless_handlers = (struct iw_handler_def *)&ks_wlan_handler_def; |
3132 | dev->watchdog_timeo = TX_TIMEOUT; |
3133 | |
3134 | netif_carrier_off(dev); |
3135 | |
3136 | return 0; |
3137 | } |
3138 | |
3139 | |
3140 | int ks_wlan_net_stop(struct net_device *dev) |
3141 | { |
3142 | ks_wlan_private *priv = netdev_priv(dev); |
3143 | |
3144 | int ret = 0; |
3145 | priv->device_open_status = 0; |
3146 | del_timer_sync(&update_phyinfo_timer); |
3147 | |
3148 | if(netif_running(dev)) |
3149 | netif_stop_queue(dev); |
3150 | |
3151 | return ret; |
3152 | } |
3153 | |
3154 | int ks_wlan_reset(struct net_device *dev) |
3155 | { |
3156 | return 0; |
3157 | } |
3158 | |