2 This file contains wireless extension handlers.
4 This is part of rtl8180 OpenSource driver.
5 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
6 Released under the terms of GPL (General Public Licence)
8 Parts of this driver are based on the GPL part
9 of the official realtek driver.
11 Parts of this driver are based on the rtl8180 driver skeleton
12 from Patric Schenke & Andres Salomon.
14 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
16 We want to tanks the Authors of those projects and the Ndiswrapper
24 #include "ieee80211/dot11d.h"
26 u32 rtl8180_rates
[] = {1000000, 2000000, 5500000, 11000000,
27 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
29 #define RATE_COUNT ARRAY_SIZE(rtl8180_rates)
31 static CHANNEL_LIST DefaultChannelPlan
[] = {
32 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19}, /*FCC */
33 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /*IC */
34 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /*ETSI */
35 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /*Spain. Change to ETSI. */
36 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /*France. Change to ETSI. */
37 {{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9}, /*MKK */
38 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22},/*MKK1 */
39 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /*Israel. */
40 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17}, /*For 11a , TELEC */
41 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14} /*For Global Domain. 1-11:active scan, 12-14 passive scan.*/ /* +YJ, 080626 */
43 static int r8180_wx_get_freq(struct net_device
*dev
,
44 struct iw_request_info
*a
,
45 union iwreq_data
*wrqu
, char *b
)
47 struct r8180_priv
*priv
= ieee80211_priv(dev
);
49 return ieee80211_wx_get_freq(priv
->ieee80211
, a
, wrqu
, b
);
53 int r8180_wx_set_key(struct net_device
*dev
, struct iw_request_info
*info
,
54 union iwreq_data
*wrqu
, char *key
)
56 struct r8180_priv
*priv
= ieee80211_priv(dev
);
57 struct iw_point
*erq
= &(wrqu
->encoding
);
59 if (priv
->ieee80211
->bHwRadioOff
)
62 if (erq
->flags
& IW_ENCODE_DISABLED
)
64 if (erq
->length
> 0) {
65 u32
* tkey
= (u32
*) key
;
66 priv
->key0
[0] = tkey
[0];
67 priv
->key0
[1] = tkey
[1];
68 priv
->key0
[2] = tkey
[2];
69 priv
->key0
[3] = tkey
[3] & 0xff;
70 DMESG("Setting wep key to %x %x %x %x",
71 tkey
[0], tkey
[1], tkey
[2], tkey
[3]);
72 rtl8180_set_hw_wep(dev
);
78 static int r8180_wx_set_beaconinterval(struct net_device
*dev
, struct iw_request_info
*aa
,
79 union iwreq_data
*wrqu
, char *b
)
81 int *parms
= (int *)b
;
84 struct r8180_priv
*priv
= ieee80211_priv(dev
);
86 if (priv
->ieee80211
->bHwRadioOff
)
90 DMESG("setting beacon interval to %x", bi
);
92 priv
->ieee80211
->current_network
.beacon_interval
= bi
;
101 static int r8180_wx_get_mode(struct net_device
*dev
, struct iw_request_info
*a
,
102 union iwreq_data
*wrqu
, char *b
)
104 struct r8180_priv
*priv
= ieee80211_priv(dev
);
105 return ieee80211_wx_get_mode(priv
->ieee80211
, a
, wrqu
, b
);
110 static int r8180_wx_get_rate(struct net_device
*dev
,
111 struct iw_request_info
*info
,
112 union iwreq_data
*wrqu
, char *extra
)
114 struct r8180_priv
*priv
= ieee80211_priv(dev
);
115 return ieee80211_wx_get_rate(priv
->ieee80211
, info
, wrqu
, extra
);
120 static int r8180_wx_set_rate(struct net_device
*dev
,
121 struct iw_request_info
*info
,
122 union iwreq_data
*wrqu
, char *extra
)
125 struct r8180_priv
*priv
= ieee80211_priv(dev
);
128 if (priv
->ieee80211
->bHwRadioOff
)
133 ret
= ieee80211_wx_set_rate(priv
->ieee80211
, info
, wrqu
, extra
);
141 static int r8180_wx_set_crcmon(struct net_device
*dev
,
142 struct iw_request_info
*info
,
143 union iwreq_data
*wrqu
, char *extra
)
145 struct r8180_priv
*priv
= ieee80211_priv(dev
);
146 int *parms
= (int *)extra
;
147 int enable
= (parms
[0] > 0);
148 short prev
= priv
->crcmon
;
151 if (priv
->ieee80211
->bHwRadioOff
)
161 DMESG("bad CRC in monitor mode are %s",
162 priv
->crcmon
? "accepted" : "rejected");
164 if (prev
!= priv
->crcmon
&& priv
->up
) {
175 static int r8180_wx_set_mode(struct net_device
*dev
, struct iw_request_info
*a
,
176 union iwreq_data
*wrqu
, char *b
)
178 struct r8180_priv
*priv
= ieee80211_priv(dev
);
182 if (priv
->ieee80211
->bHwRadioOff
)
186 if (priv
->bInactivePs
) {
187 if (wrqu
->mode
== IW_MODE_ADHOC
)
190 ret
= ieee80211_wx_set_mode(priv
->ieee80211
, a
, wrqu
, b
);
196 /* YJ,add,080819,for hidden ap */
197 struct iw_range_with_scan_capa
{
198 /* Informative stuff (to choose between different interface) */
199 __u32 throughput
; /* To give an idea... */
200 /* In theory this value should be the maximum benchmarked
201 * TCP/IP throughput, because with most of these devices the
202 * bit rate is meaningless (overhead an co) to estimate how
203 * fast the connection will go and pick the fastest one.
204 * I suggest people to play with Netperf or any benchmark...
207 /* NWID (or domain id) */
208 __u32 min_nwid
; /* Minimal NWID we are able to set */
209 __u32 max_nwid
; /* Maximal NWID we are able to set */
211 /* Old Frequency (backward compat - moved lower ) */
212 __u16 old_num_channels
;
213 __u8 old_num_frequency
;
215 /* Scan capabilities */
218 /* YJ,add,080819,for hidden ap */
221 static int rtl8180_wx_get_range(struct net_device
*dev
,
222 struct iw_request_info
*info
,
223 union iwreq_data
*wrqu
, char *extra
)
225 struct iw_range
*range
= (struct iw_range
*)extra
;
226 struct r8180_priv
*priv
= ieee80211_priv(dev
);
230 wrqu
->data
.length
= sizeof(*range
);
231 memset(range
, 0, sizeof(*range
));
233 /* Let's try to keep this struct in the same order as in
234 * linux/include/wireless.h
237 /* TODO: See what values we can set, and remove the ones we can't
238 * set, or fill them with some default data.
241 /* ~5 Mb/s real (802.11b) */
242 range
->throughput
= 5 * 1000 * 1000;
244 /* TODO: Not used in 802.11b? */
245 /* range->min_nwid; */ /* Minimal NWID we are able to set */
246 /* TODO: Not used in 802.11b? */
247 /* range->max_nwid; */ /* Maximal NWID we are able to set */
249 /* Old Frequency (backward compat - moved lower ) */
250 /* range->old_num_channels; */
251 /* range->old_num_frequency; */
252 /* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */
253 if (priv
->rf_set_sens
!= NULL
)
254 range
->sensitivity
= priv
->max_sens
; /* signal level threshold range */
256 range
->max_qual
.qual
= 100;
257 /* TODO: Find real max RSSI and stick here */
258 range
->max_qual
.level
= 0;
259 range
->max_qual
.noise
= -98;
260 range
->max_qual
.updated
= 7; /* Updated all three */
262 range
->avg_qual
.qual
= 92; /* > 8% missed beacons is 'bad' */
263 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
264 range
->avg_qual
.level
= 20 + -98;
265 range
->avg_qual
.noise
= 0;
266 range
->avg_qual
.updated
= 7; /* Updated all three */
268 range
->num_bitrates
= RATE_COUNT
;
270 for (i
= 0; i
< RATE_COUNT
&& i
< IW_MAX_BITRATES
; i
++)
271 range
->bitrate
[i
] = rtl8180_rates
[i
];
273 range
->min_frag
= MIN_FRAG_THRESHOLD
;
274 range
->max_frag
= MAX_FRAG_THRESHOLD
;
278 range
->we_version_compiled
= WIRELESS_EXT
;
279 range
->we_version_source
= 16;
281 range
->num_channels
= 14;
283 for (i
= 0, val
= 0; i
< 14; i
++) {
285 /* Include only legal frequencies for some countries */
286 if ((GET_DOT11D_INFO(priv
->ieee80211
)->channel_map
)[i
+1]) {
287 range
->freq
[val
].i
= i
+ 1;
288 range
->freq
[val
].m
= ieee80211_wlan_frequencies
[i
] * 100000;
289 range
->freq
[val
].e
= 1;
292 /* FIXME: do we need to set anything for channels */
296 if (val
== IW_MAX_FREQUENCIES
)
300 range
->num_frequency
= val
;
301 range
->enc_capa
= IW_ENC_CAPA_WPA
| IW_ENC_CAPA_WPA2
|
302 IW_ENC_CAPA_CIPHER_TKIP
| IW_ENC_CAPA_CIPHER_CCMP
;
308 static int r8180_wx_set_scan(struct net_device
*dev
, struct iw_request_info
*a
,
309 union iwreq_data
*wrqu
, char *b
)
311 struct r8180_priv
*priv
= ieee80211_priv(dev
);
313 struct ieee80211_device
* ieee
= priv
->ieee80211
;
316 if (priv
->ieee80211
->bHwRadioOff
)
319 if (wrqu
->data
.flags
& IW_SCAN_THIS_ESSID
) {
320 struct iw_scan_req
* req
= (struct iw_scan_req
*)b
;
321 if (req
->essid_len
) {
322 ieee
->current_network
.ssid_len
= req
->essid_len
;
323 memcpy(ieee
->current_network
.ssid
, req
->essid
, req
->essid_len
);
329 priv
->ieee80211
->actscanning
= true;
330 if (priv
->bInactivePs
&& (priv
->ieee80211
->state
!= IEEE80211_LINKED
)) {
332 ieee80211_softmac_ips_scan_syncro(priv
->ieee80211
);
335 /* prevent scan in BusyTraffic */
336 /* FIXME: Need to consider last scan time */
337 if ((priv
->link_detect
.bBusyTraffic
) && (true)) {
339 printk("Now traffic is busy, please try later!\n");
341 /* prevent scan in BusyTraffic,end */
342 ret
= ieee80211_wx_set_scan(priv
->ieee80211
, a
, wrqu
, b
);
353 static int r8180_wx_get_scan(struct net_device
*dev
, struct iw_request_info
*a
,
354 union iwreq_data
*wrqu
, char *b
)
358 struct r8180_priv
*priv
= ieee80211_priv(dev
);
362 ret
= ieee80211_wx_get_scan(priv
->ieee80211
, a
, wrqu
, b
);
371 static int r8180_wx_set_essid(struct net_device
*dev
,
372 struct iw_request_info
*a
,
373 union iwreq_data
*wrqu
, char *b
)
375 struct r8180_priv
*priv
= ieee80211_priv(dev
);
379 if (priv
->ieee80211
->bHwRadioOff
)
383 if (priv
->bInactivePs
)
386 ret
= ieee80211_wx_set_essid(priv
->ieee80211
, a
, wrqu
, b
);
393 static int r8180_wx_get_essid(struct net_device
*dev
,
394 struct iw_request_info
*a
,
395 union iwreq_data
*wrqu
, char *b
)
398 struct r8180_priv
*priv
= ieee80211_priv(dev
);
402 ret
= ieee80211_wx_get_essid(priv
->ieee80211
, a
, wrqu
, b
);
410 static int r8180_wx_set_freq(struct net_device
*dev
, struct iw_request_info
*a
,
411 union iwreq_data
*wrqu
, char *b
)
414 struct r8180_priv
*priv
= ieee80211_priv(dev
);
417 if (priv
->ieee80211
->bHwRadioOff
)
422 ret
= ieee80211_wx_set_freq(priv
->ieee80211
, a
, wrqu
, b
);
429 static int r8180_wx_get_name(struct net_device
*dev
,
430 struct iw_request_info
*info
,
431 union iwreq_data
*wrqu
, char *extra
)
433 struct r8180_priv
*priv
= ieee80211_priv(dev
);
434 return ieee80211_wx_get_name(priv
->ieee80211
, info
, wrqu
, extra
);
437 static int r8180_wx_set_frag(struct net_device
*dev
,
438 struct iw_request_info
*info
,
439 union iwreq_data
*wrqu
, char *extra
)
441 struct r8180_priv
*priv
= ieee80211_priv(dev
);
443 if (priv
->ieee80211
->bHwRadioOff
)
446 if (wrqu
->frag
.disabled
)
447 priv
->ieee80211
->fts
= DEFAULT_FRAG_THRESHOLD
;
449 if (wrqu
->frag
.value
< MIN_FRAG_THRESHOLD
||
450 wrqu
->frag
.value
> MAX_FRAG_THRESHOLD
)
453 priv
->ieee80211
->fts
= wrqu
->frag
.value
& ~0x1;
460 static int r8180_wx_get_frag(struct net_device
*dev
,
461 struct iw_request_info
*info
,
462 union iwreq_data
*wrqu
, char *extra
)
464 struct r8180_priv
*priv
= ieee80211_priv(dev
);
466 wrqu
->frag
.value
= priv
->ieee80211
->fts
;
467 wrqu
->frag
.fixed
= 0; /* no auto select */
468 wrqu
->frag
.disabled
= (wrqu
->frag
.value
== DEFAULT_FRAG_THRESHOLD
);
474 static int r8180_wx_set_wap(struct net_device
*dev
,
475 struct iw_request_info
*info
,
476 union iwreq_data
*awrq
,
480 struct r8180_priv
*priv
= ieee80211_priv(dev
);
482 if (priv
->ieee80211
->bHwRadioOff
)
487 ret
= ieee80211_wx_set_wap(priv
->ieee80211
, info
, awrq
, extra
);
495 static int r8180_wx_get_wap(struct net_device
*dev
,
496 struct iw_request_info
*info
,
497 union iwreq_data
*wrqu
, char *extra
)
499 struct r8180_priv
*priv
= ieee80211_priv(dev
);
501 return ieee80211_wx_get_wap(priv
->ieee80211
, info
, wrqu
, extra
);
505 static int r8180_wx_set_enc(struct net_device
*dev
,
506 struct iw_request_info
*info
,
507 union iwreq_data
*wrqu
, char *key
)
509 struct r8180_priv
*priv
= ieee80211_priv(dev
);
512 if (priv
->ieee80211
->bHwRadioOff
)
518 if (priv
->hw_wep
) ret
= r8180_wx_set_key(dev
, info
, wrqu
, key
);
520 DMESG("Setting SW wep key");
521 ret
= ieee80211_wx_set_encode(priv
->ieee80211
, info
, wrqu
, key
);
529 static int r8180_wx_get_enc(struct net_device
*dev
,
530 struct iw_request_info
*info
,
531 union iwreq_data
*wrqu
, char *key
)
533 struct r8180_priv
*priv
= ieee80211_priv(dev
);
535 return ieee80211_wx_get_encode(priv
->ieee80211
, info
, wrqu
, key
);
539 static int r8180_wx_set_scan_type(struct net_device
*dev
, struct iw_request_info
*aa
, union
540 iwreq_data
*wrqu
, char *p
) {
542 struct r8180_priv
*priv
= ieee80211_priv(dev
);
543 int *parms
= (int*)p
;
546 if (priv
->ieee80211
->bHwRadioOff
)
549 priv
->ieee80211
->active_scan
= mode
;
554 static int r8180_wx_set_retry(struct net_device
*dev
,
555 struct iw_request_info
*info
,
556 union iwreq_data
*wrqu
, char *extra
)
558 struct r8180_priv
*priv
= ieee80211_priv(dev
);
561 if (priv
->ieee80211
->bHwRadioOff
)
566 if (wrqu
->retry
.flags
& IW_RETRY_LIFETIME
||
567 wrqu
->retry
.disabled
) {
571 if (!(wrqu
->retry
.flags
& IW_RETRY_LIMIT
)) {
576 if (wrqu
->retry
.value
> R8180_MAX_RETRY
) {
580 if (wrqu
->retry
.flags
& IW_RETRY_MAX
) {
581 priv
->retry_rts
= wrqu
->retry
.value
;
582 DMESG("Setting retry for RTS/CTS data to %d", wrqu
->retry
.value
);
585 priv
->retry_data
= wrqu
->retry
.value
;
586 DMESG("Setting retry for non RTS/CTS data to %d", wrqu
->retry
.value
);
590 * We might try to write directly the TX config register
591 * or to restart just the (R)TX process.
592 * I'm unsure if whole reset is really needed
602 static int r8180_wx_get_retry(struct net_device
*dev
,
603 struct iw_request_info
*info
,
604 union iwreq_data
*wrqu
, char *extra
)
606 struct r8180_priv
*priv
= ieee80211_priv(dev
);
609 wrqu
->retry
.disabled
= 0; /* can't be disabled */
611 if ((wrqu
->retry
.flags
& IW_RETRY_TYPE
) ==
615 if (wrqu
->retry
.flags
& IW_RETRY_MAX
) {
616 wrqu
->retry
.flags
= IW_RETRY_LIMIT
& IW_RETRY_MAX
;
617 wrqu
->retry
.value
= priv
->retry_rts
;
619 wrqu
->retry
.flags
= IW_RETRY_LIMIT
& IW_RETRY_MIN
;
620 wrqu
->retry
.value
= priv
->retry_data
;
626 static int r8180_wx_get_sens(struct net_device
*dev
,
627 struct iw_request_info
*info
,
628 union iwreq_data
*wrqu
, char *extra
)
630 struct r8180_priv
*priv
= ieee80211_priv(dev
);
631 if (priv
->rf_set_sens
== NULL
)
632 return -1; /* we have not this support for this radio */
633 wrqu
->sens
.value
= priv
->sens
;
638 static int r8180_wx_set_sens(struct net_device
*dev
,
639 struct iw_request_info
*info
,
640 union iwreq_data
*wrqu
, char *extra
)
643 struct r8180_priv
*priv
= ieee80211_priv(dev
);
647 if (priv
->ieee80211
->bHwRadioOff
)
651 if (priv
->rf_set_sens
== NULL
) {
652 err
= -1; /* we have not this support for this radio */
655 if (priv
->rf_set_sens(dev
, wrqu
->sens
.value
) == 0)
656 priv
->sens
= wrqu
->sens
.value
;
667 static int r8180_wx_set_rawtx(struct net_device
*dev
,
668 struct iw_request_info
*info
,
669 union iwreq_data
*wrqu
, char *extra
)
671 struct r8180_priv
*priv
= ieee80211_priv(dev
);
674 if (priv
->ieee80211
->bHwRadioOff
)
679 ret
= ieee80211_wx_set_rawtx(priv
->ieee80211
, info
, wrqu
, extra
);
687 static int r8180_wx_get_power(struct net_device
*dev
,
688 struct iw_request_info
*info
,
689 union iwreq_data
*wrqu
, char *extra
)
692 struct r8180_priv
*priv
= ieee80211_priv(dev
);
696 ret
= ieee80211_wx_get_power(priv
->ieee80211
, info
, wrqu
, extra
);
703 static int r8180_wx_set_power(struct net_device
*dev
,
704 struct iw_request_info
*info
,
705 union iwreq_data
*wrqu
, char *extra
)
708 struct r8180_priv
*priv
= ieee80211_priv(dev
);
711 if (priv
->ieee80211
->bHwRadioOff
)
715 printk("=>>>>>>>>>>=============================>set power:%d, %d!\n", wrqu
->power
.disabled
, wrqu
->power
.flags
);
716 if (wrqu
->power
.disabled
== 0) {
717 wrqu
->power
.flags
|= IW_POWER_ALL_R
;
718 wrqu
->power
.flags
|= IW_POWER_TIMEOUT
;
719 wrqu
->power
.value
= 1000;
722 ret
= ieee80211_wx_set_power(priv
->ieee80211
, info
, wrqu
, extra
);
729 static int r8180_wx_set_rts(struct net_device
*dev
,
730 struct iw_request_info
*info
,
731 union iwreq_data
*wrqu
, char *extra
)
733 struct r8180_priv
*priv
= ieee80211_priv(dev
);
736 if (priv
->ieee80211
->bHwRadioOff
)
739 if (wrqu
->rts
.disabled
)
740 priv
->rts
= DEFAULT_RTS_THRESHOLD
;
742 if (wrqu
->rts
.value
< MIN_RTS_THRESHOLD
||
743 wrqu
->rts
.value
> MAX_RTS_THRESHOLD
)
746 priv
->rts
= wrqu
->rts
.value
;
751 static int r8180_wx_get_rts(struct net_device
*dev
,
752 struct iw_request_info
*info
,
753 union iwreq_data
*wrqu
, char *extra
)
755 struct r8180_priv
*priv
= ieee80211_priv(dev
);
759 wrqu
->rts
.value
= priv
->rts
;
760 wrqu
->rts
.fixed
= 0; /* no auto select */
761 wrqu
->rts
.disabled
= (wrqu
->rts
.value
== 0);
765 static int dummy(struct net_device
*dev
, struct iw_request_info
*a
,
766 union iwreq_data
*wrqu
, char *b
)
771 static int r8180_wx_get_iwmode(struct net_device
*dev
,
772 struct iw_request_info
*info
,
773 union iwreq_data
*wrqu
, char *extra
)
775 struct r8180_priv
*priv
= ieee80211_priv(dev
);
776 struct ieee80211_device
*ieee
;
783 ieee
= priv
->ieee80211
;
785 strcpy(extra
, "802.11");
786 if (ieee
->modulation
& IEEE80211_CCK_MODULATION
) {
788 if (ieee
->modulation
& IEEE80211_OFDM_MODULATION
)
790 } else if (ieee
->modulation
& IEEE80211_OFDM_MODULATION
)
797 static int r8180_wx_set_iwmode(struct net_device
*dev
,
798 struct iw_request_info
*info
,
799 union iwreq_data
*wrqu
, char *extra
)
801 struct r8180_priv
*priv
= ieee80211_priv(dev
);
802 struct ieee80211_device
*ieee
= priv
->ieee80211
;
803 int *param
= (int *)extra
;
805 int modulation
= 0, mode
= 0;
808 if (priv
->ieee80211
->bHwRadioOff
)
814 modulation
|= IEEE80211_CCK_MODULATION
;
816 printk(KERN_INFO
"B mode!\n");
817 } else if (*param
== 2) {
818 modulation
|= IEEE80211_OFDM_MODULATION
;
820 printk(KERN_INFO
"G mode!\n");
821 } else if (*param
== 3) {
822 modulation
|= IEEE80211_CCK_MODULATION
;
823 modulation
|= IEEE80211_OFDM_MODULATION
;
824 mode
= IEEE_B
|IEEE_G
;
825 printk(KERN_INFO
"B/G mode!\n");
828 if (ieee
->proto_started
) {
829 ieee80211_stop_protocol(ieee
);
831 ieee
->modulation
= modulation
;
832 ieee80211_start_protocol(ieee
);
835 ieee
->modulation
= modulation
;
842 static int r8180_wx_get_preamble(struct net_device
*dev
,
843 struct iw_request_info
*info
,
844 union iwreq_data
*wrqu
, char *extra
)
846 struct r8180_priv
*priv
= ieee80211_priv(dev
);
854 *extra
= (char) priv
->plcp_preamble_mode
; /* 0:auto 1:short 2:long */
859 static int r8180_wx_set_preamble(struct net_device
*dev
,
860 struct iw_request_info
*info
,
861 union iwreq_data
*wrqu
, char *extra
)
863 struct r8180_priv
*priv
= ieee80211_priv(dev
);
867 if (priv
->ieee80211
->bHwRadioOff
)
871 if (*extra
< 0 || *extra
> 2)
874 priv
->plcp_preamble_mode
= *((short *)extra
) ;
882 static int r8180_wx_get_siglevel(struct net_device
*dev
,
883 struct iw_request_info
*info
,
884 union iwreq_data
*wrqu
, char *extra
)
886 struct r8180_priv
*priv
= ieee80211_priv(dev
);
892 /* Modify by hikaru 6.5 */
893 *((int *)extra
) = priv
->wstats
.qual
.level
;/*for interface test ,it should be the priv->wstats.qual.level; */
901 static int r8180_wx_get_sigqual(struct net_device
*dev
,
902 struct iw_request_info
*info
,
903 union iwreq_data
*wrqu
, char *extra
)
905 struct r8180_priv
*priv
= ieee80211_priv(dev
);
911 /* Modify by hikaru 6.5 */
912 *((int *)extra
) = priv
->wstats
.qual
.qual
;/* for interface test ,it should be the priv->wstats.qual.qual; */
920 static int r8180_wx_reset_stats(struct net_device
*dev
,
921 struct iw_request_info
*info
,
922 union iwreq_data
*wrqu
, char *extra
)
924 struct r8180_priv
*priv
= ieee80211_priv(dev
);
927 priv
->stats
.txrdu
= 0;
928 priv
->stats
.rxrdu
= 0;
929 priv
->stats
.rxnolast
= 0;
930 priv
->stats
.rxnodata
= 0;
931 priv
->stats
.rxnopointer
= 0;
932 priv
->stats
.txnperr
= 0;
933 priv
->stats
.txresumed
= 0;
934 priv
->stats
.rxerr
= 0;
935 priv
->stats
.rxoverflow
= 0;
936 priv
->stats
.rxint
= 0;
938 priv
->stats
.txnpokint
= 0;
939 priv
->stats
.txhpokint
= 0;
940 priv
->stats
.txhperr
= 0;
941 priv
->stats
.ints
= 0;
942 priv
->stats
.shints
= 0;
943 priv
->stats
.txoverflow
= 0;
944 priv
->stats
.rxdmafail
= 0;
945 priv
->stats
.txbeacon
= 0;
946 priv
->stats
.txbeaconerr
= 0;
947 priv
->stats
.txlpokint
= 0;
948 priv
->stats
.txlperr
= 0;
949 priv
->stats
.txretry
= 0;/* 20060601 */
950 priv
->stats
.rxcrcerrmin
= 0 ;
951 priv
->stats
.rxcrcerrmid
= 0;
952 priv
->stats
.rxcrcerrmax
= 0;
953 priv
->stats
.rxicverr
= 0;
960 static int r8180_wx_radio_on(struct net_device
*dev
,
961 struct iw_request_info
*info
,
962 union iwreq_data
*wrqu
, char *extra
)
964 struct r8180_priv
*priv
= ieee80211_priv(dev
);
966 if (priv
->ieee80211
->bHwRadioOff
)
971 priv
->rf_wakeup(dev
);
979 static int r8180_wx_radio_off(struct net_device
*dev
,
980 struct iw_request_info
*info
,
981 union iwreq_data
*wrqu
, char *extra
)
983 struct r8180_priv
*priv
= ieee80211_priv(dev
);
985 if (priv
->ieee80211
->bHwRadioOff
)
997 static int r8180_wx_get_channelplan(struct net_device
*dev
,
998 struct iw_request_info
*info
,
999 union iwreq_data
*wrqu
, char *extra
)
1001 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1005 down(&priv
->wx_sem
);
1006 *extra
= priv
->channel_plan
;
1014 static int r8180_wx_set_channelplan(struct net_device
*dev
,
1015 struct iw_request_info
*info
,
1016 union iwreq_data
*wrqu
, char *extra
)
1018 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1019 /* struct ieee80211_device *ieee = netdev_priv(dev); */
1020 int *val
= (int *)extra
;
1022 printk("-----in fun %s\n", __func__
);
1024 if (priv
->ieee80211
->bHwRadioOff
)
1027 /* unsigned long flags; */
1028 down(&priv
->wx_sem
);
1029 if (DefaultChannelPlan
[*val
].Len
!= 0) {
1030 priv
->channel_plan
= *val
;
1031 /* Clear old channel map 8 */
1032 for (i
= 1; i
<= MAX_CHANNEL_NUMBER
; i
++)
1033 GET_DOT11D_INFO(priv
->ieee80211
)->channel_map
[i
] = 0;
1035 /* Set new channel map */
1036 for (i
= 1; i
<= DefaultChannelPlan
[*val
].Len
; i
++)
1037 GET_DOT11D_INFO(priv
->ieee80211
)->channel_map
[DefaultChannelPlan
[*val
].Channel
[i
-1]] = 1;
1045 static int r8180_wx_get_version(struct net_device
*dev
,
1046 struct iw_request_info
*info
,
1047 union iwreq_data
*wrqu
, char *extra
)
1049 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1050 /* struct ieee80211_device *ieee; */
1052 down(&priv
->wx_sem
);
1053 strcpy(extra
, "1020.0808");
1059 /* added by amy 080818 */
1060 /*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
1061 static int r8180_wx_set_forcerate(struct net_device
*dev
,
1062 struct iw_request_info
*info
,
1063 union iwreq_data
*wrqu
, char *extra
)
1065 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1066 u8 forcerate
= *extra
;
1068 down(&priv
->wx_sem
);
1070 printk("==============>%s(): forcerate is %d\n", __func__
, forcerate
);
1071 if ((forcerate
== 2) || (forcerate
== 4) || (forcerate
== 11) || (forcerate
== 22) || (forcerate
== 12) ||
1072 (forcerate
== 18) || (forcerate
== 24) || (forcerate
== 36) || (forcerate
== 48) || (forcerate
== 72) ||
1073 (forcerate
== 96) || (forcerate
== 108))
1075 priv
->ForcedDataRate
= 1;
1076 priv
->ieee80211
->rate
= forcerate
* 5;
1077 } else if (forcerate
== 0) {
1078 priv
->ForcedDataRate
= 0;
1079 printk("OK! return rate adaptive\n");
1081 printk("ERR: wrong rate\n");
1086 static int r8180_wx_set_enc_ext(struct net_device
*dev
,
1087 struct iw_request_info
*info
,
1088 union iwreq_data
*wrqu
, char *extra
)
1091 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1095 if (priv
->ieee80211
->bHwRadioOff
)
1098 down(&priv
->wx_sem
);
1099 ret
= ieee80211_wx_set_encode_ext(priv
->ieee80211
, info
, wrqu
, extra
);
1104 static int r8180_wx_set_auth(struct net_device
*dev
,
1105 struct iw_request_info
*info
,
1106 union iwreq_data
*wrqu
, char *extra
)
1108 /* printk("====>%s()\n", __func__); */
1109 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1112 if (priv
->ieee80211
->bHwRadioOff
)
1115 down(&priv
->wx_sem
);
1116 ret
= ieee80211_wx_set_auth(priv
->ieee80211
, info
, &wrqu
->param
, extra
);
1121 static int r8180_wx_set_mlme(struct net_device
*dev
,
1122 struct iw_request_info
*info
,
1123 union iwreq_data
*wrqu
, char *extra
)
1126 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1129 if (priv
->ieee80211
->bHwRadioOff
)
1133 down(&priv
->wx_sem
);
1135 ret
= ieee80211_wx_set_mlme(priv
->ieee80211
, info
, wrqu
, extra
);
1140 static int r8180_wx_set_gen_ie(struct net_device
*dev
,
1141 struct iw_request_info
*info
,
1142 union iwreq_data
*wrqu
, char *extra
)
1145 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1148 if (priv
->ieee80211
->bHwRadioOff
)
1151 down(&priv
->wx_sem
);
1153 ret
= ieee80211_wx_set_gen_ie(priv
->ieee80211
, extra
, wrqu
->data
.length
);
1160 static iw_handler r8180_wx_handlers
[] = {
1161 NULL
, /* SIOCSIWCOMMIT */
1162 r8180_wx_get_name
, /* SIOCGIWNAME */
1163 dummy
, /* SIOCSIWNWID */
1164 dummy
, /* SIOCGIWNWID */
1165 r8180_wx_set_freq
, /* SIOCSIWFREQ */
1166 r8180_wx_get_freq
, /* SIOCGIWFREQ */
1167 r8180_wx_set_mode
, /* SIOCSIWMODE */
1168 r8180_wx_get_mode
, /* SIOCGIWMODE */
1169 r8180_wx_set_sens
, /* SIOCSIWSENS */
1170 r8180_wx_get_sens
, /* SIOCGIWSENS */
1171 NULL
, /* SIOCSIWRANGE */
1172 rtl8180_wx_get_range
, /* SIOCGIWRANGE */
1173 NULL
, /* SIOCSIWPRIV */
1174 NULL
, /* SIOCGIWPRIV */
1175 NULL
, /* SIOCSIWSTATS */
1176 NULL
, /* SIOCGIWSTATS */
1177 dummy
, /* SIOCSIWSPY */
1178 dummy
, /* SIOCGIWSPY */
1179 NULL
, /* SIOCGIWTHRSPY */
1180 NULL
, /* SIOCWIWTHRSPY */
1181 r8180_wx_set_wap
, /* SIOCSIWAP */
1182 r8180_wx_get_wap
, /* SIOCGIWAP */
1183 r8180_wx_set_mlme
, /* SIOCSIWMLME*/
1184 dummy
, /* SIOCGIWAPLIST -- depricated */
1185 r8180_wx_set_scan
, /* SIOCSIWSCAN */
1186 r8180_wx_get_scan
, /* SIOCGIWSCAN */
1187 r8180_wx_set_essid
, /* SIOCSIWESSID */
1188 r8180_wx_get_essid
, /* SIOCGIWESSID */
1189 dummy
, /* SIOCSIWNICKN */
1190 dummy
, /* SIOCGIWNICKN */
1191 NULL
, /* -- hole -- */
1192 NULL
, /* -- hole -- */
1193 r8180_wx_set_rate
, /* SIOCSIWRATE */
1194 r8180_wx_get_rate
, /* SIOCGIWRATE */
1195 r8180_wx_set_rts
, /* SIOCSIWRTS */
1196 r8180_wx_get_rts
, /* SIOCGIWRTS */
1197 r8180_wx_set_frag
, /* SIOCSIWFRAG */
1198 r8180_wx_get_frag
, /* SIOCGIWFRAG */
1199 dummy
, /* SIOCSIWTXPOW */
1200 dummy
, /* SIOCGIWTXPOW */
1201 r8180_wx_set_retry
, /* SIOCSIWRETRY */
1202 r8180_wx_get_retry
, /* SIOCGIWRETRY */
1203 r8180_wx_set_enc
, /* SIOCSIWENCODE */
1204 r8180_wx_get_enc
, /* SIOCGIWENCODE */
1205 r8180_wx_set_power
, /* SIOCSIWPOWER */
1206 r8180_wx_get_power
, /* SIOCGIWPOWER */
1207 NULL
, /*---hole---*/
1208 NULL
, /*---hole---*/
1209 r8180_wx_set_gen_ie
, /* SIOCSIWGENIE */
1210 NULL
, /* SIOCSIWGENIE */
1211 r8180_wx_set_auth
, /* SIOCSIWAUTH */
1212 NULL
, /* SIOCSIWAUTH */
1213 r8180_wx_set_enc_ext
, /* SIOCSIWENCODEEXT */
1214 NULL
, /* SIOCSIWENCODEEXT */
1215 NULL
, /* SIOCSIWPMKSA */
1216 NULL
, /*---hole---*/
1220 static const struct iw_priv_args r8180_private_args
[] = {
1222 SIOCIWFIRSTPRIV
+ 0x0,
1223 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "badcrc"
1225 { SIOCIWFIRSTPRIV
+ 0x1,
1230 SIOCIWFIRSTPRIV
+ 0x2,
1231 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "beaconint"
1233 { SIOCIWFIRSTPRIV
+ 0x3,
1238 SIOCIWFIRSTPRIV
+ 0x4,
1239 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "activescan"
1242 { SIOCIWFIRSTPRIV
+ 0x5,
1247 SIOCIWFIRSTPRIV
+ 0x6,
1248 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "rawtx"
1251 { SIOCIWFIRSTPRIV
+ 0x7,
1256 SIOCIWFIRSTPRIV
+ 0x8,
1257 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "setiwmode"
1260 SIOCIWFIRSTPRIV
+ 0x9,
1261 0, IW_PRIV_TYPE_CHAR
| IW_PRIV_SIZE_FIXED
| 32, "getiwmode"
1264 SIOCIWFIRSTPRIV
+ 0xA,
1265 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "setpreamble"
1268 SIOCIWFIRSTPRIV
+ 0xB,
1269 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "getpreamble"
1271 { SIOCIWFIRSTPRIV
+ 0xC,
1275 SIOCIWFIRSTPRIV
+ 0xD,
1276 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "getrssi"
1278 { SIOCIWFIRSTPRIV
+ 0xE,
1282 SIOCIWFIRSTPRIV
+ 0xF,
1283 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "getlinkqual"
1286 SIOCIWFIRSTPRIV
+ 0x10,
1290 SIOCIWFIRSTPRIV
+ 0x11,
1294 SIOCIWFIRSTPRIV
+ 0x12,
1298 SIOCIWFIRSTPRIV
+ 0x13,
1302 SIOCIWFIRSTPRIV
+ 0x14,
1303 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "setchannel"
1306 SIOCIWFIRSTPRIV
+ 0x15,
1307 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "getchannel"
1310 SIOCIWFIRSTPRIV
+ 0x16,
1314 SIOCIWFIRSTPRIV
+ 0x17,
1315 0, IW_PRIV_TYPE_CHAR
| IW_PRIV_SIZE_FIXED
| 32, "getversion"
1318 SIOCIWFIRSTPRIV
+ 0x18,
1319 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "setrate"
1324 static iw_handler r8180_private_handler
[] = {
1325 r8180_wx_set_crcmon
, /*SIOCIWSECONDPRIV*/
1327 r8180_wx_set_beaconinterval
,
1329 /* r8180_wx_set_monitor_type, */
1330 r8180_wx_set_scan_type
,
1334 r8180_wx_set_iwmode
,
1335 r8180_wx_get_iwmode
,
1336 r8180_wx_set_preamble
,
1337 r8180_wx_get_preamble
,
1339 r8180_wx_get_siglevel
,
1341 r8180_wx_get_sigqual
,
1342 r8180_wx_reset_stats
,
1343 dummy
,/* r8180_wx_get_stats */
1346 r8180_wx_set_channelplan
,
1347 r8180_wx_get_channelplan
,
1349 r8180_wx_get_version
,
1350 r8180_wx_set_forcerate
,
1353 static inline int is_same_network(struct ieee80211_network
*src
,
1354 struct ieee80211_network
*dst
,
1355 struct ieee80211_device
*ieee
)
1357 /* A network is only a duplicate if the channel, BSSID, ESSID
1358 * and the capability field (in particular IBSS and BSS) all match.
1359 * We treat all <hidden> with the same BSSID and channel
1361 return (((src
->ssid_len
== dst
->ssid_len
) || (ieee
->iw_mode
== IW_MODE_INFRA
)) && /* YJ,mod, 080819,for hidden ap */
1362 /* ((src->ssid_len == dst->ssid_len) && */
1363 (src
->channel
== dst
->channel
) &&
1364 !memcmp(src
->bssid
, dst
->bssid
, ETH_ALEN
) &&
1365 (!memcmp(src
->ssid
, dst
->ssid
, src
->ssid_len
) || (ieee
->iw_mode
== IW_MODE_INFRA
)) && /* YJ,mod, 080819,for hidden ap */
1366 /*!memcmp(src->ssid, dst->ssid, src->ssid_len) && */
1367 ((src
->capability
& WLAN_CAPABILITY_IBSS
) ==
1368 (dst
->capability
& WLAN_CAPABILITY_IBSS
)) &&
1369 ((src
->capability
& WLAN_CAPABILITY_BSS
) ==
1370 (dst
->capability
& WLAN_CAPABILITY_BSS
)));
1373 /* WB modefied to show signal to GUI on 18-01-2008 */
1374 static struct iw_statistics
*r8180_get_wireless_stats(struct net_device
*dev
)
1376 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1377 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1378 struct iw_statistics
* wstats
= &priv
->wstats
;
1379 /* struct ieee80211_network* target = NULL; */
1383 /* unsigned long flag; */
1385 if (ieee
->state
< IEEE80211_LINKED
) {
1386 wstats
->qual
.qual
= 0;
1387 wstats
->qual
.level
= 0;
1388 wstats
->qual
.noise
= 0;
1389 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1393 tmp_level
= (&ieee
->current_network
)->stats
.signal
;
1394 tmp_qual
= (&ieee
->current_network
)->stats
.signalstrength
;
1395 tmp_noise
= (&ieee
->current_network
)->stats
.noise
;
1397 wstats
->qual
.level
= tmp_level
;
1398 wstats
->qual
.qual
= tmp_qual
;
1399 wstats
->qual
.noise
= tmp_noise
;
1400 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1404 struct iw_handler_def r8180_wx_handlers_def
= {
1405 .standard
= r8180_wx_handlers
,
1406 .num_standard
= ARRAY_SIZE(r8180_wx_handlers
),
1407 .private = r8180_private_handler
,
1408 .num_private
= ARRAY_SIZE(r8180_private_handler
),
1409 .num_private_args
= sizeof(r8180_private_args
) / sizeof(struct iw_priv_args
),
1410 .get_wireless_stats
= r8180_get_wireless_stats
,
1411 .private_args
= (struct iw_priv_args
*)r8180_private_args
,