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 thanks 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
->length
> 0) {
63 u32
* tkey
= (u32
*) key
;
64 priv
->key0
[0] = tkey
[0];
65 priv
->key0
[1] = tkey
[1];
66 priv
->key0
[2] = tkey
[2];
67 priv
->key0
[3] = tkey
[3] & 0xff;
68 DMESG("Setting wep key to %x %x %x %x",
69 tkey
[0], tkey
[1], tkey
[2], tkey
[3]);
70 rtl8180_set_hw_wep(dev
);
76 static int r8180_wx_set_beaconinterval(struct net_device
*dev
, struct iw_request_info
*aa
,
77 union iwreq_data
*wrqu
, char *b
)
79 int *parms
= (int *)b
;
82 struct r8180_priv
*priv
= ieee80211_priv(dev
);
84 if (priv
->ieee80211
->bHwRadioOff
)
88 DMESG("setting beacon interval to %x", bi
);
90 priv
->ieee80211
->current_network
.beacon_interval
= bi
;
99 static int r8180_wx_get_mode(struct net_device
*dev
, struct iw_request_info
*a
,
100 union iwreq_data
*wrqu
, char *b
)
102 struct r8180_priv
*priv
= ieee80211_priv(dev
);
103 return ieee80211_wx_get_mode(priv
->ieee80211
, a
, wrqu
, b
);
108 static int r8180_wx_get_rate(struct net_device
*dev
,
109 struct iw_request_info
*info
,
110 union iwreq_data
*wrqu
, char *extra
)
112 struct r8180_priv
*priv
= ieee80211_priv(dev
);
113 return ieee80211_wx_get_rate(priv
->ieee80211
, info
, wrqu
, extra
);
118 static int r8180_wx_set_rate(struct net_device
*dev
,
119 struct iw_request_info
*info
,
120 union iwreq_data
*wrqu
, char *extra
)
123 struct r8180_priv
*priv
= ieee80211_priv(dev
);
126 if (priv
->ieee80211
->bHwRadioOff
)
131 ret
= ieee80211_wx_set_rate(priv
->ieee80211
, info
, wrqu
, extra
);
139 static int r8180_wx_set_crcmon(struct net_device
*dev
,
140 struct iw_request_info
*info
,
141 union iwreq_data
*wrqu
, char *extra
)
143 struct r8180_priv
*priv
= ieee80211_priv(dev
);
144 int *parms
= (int *)extra
;
145 int enable
= (parms
[0] > 0);
146 short prev
= priv
->crcmon
;
149 if (priv
->ieee80211
->bHwRadioOff
)
159 DMESG("bad CRC in monitor mode are %s",
160 priv
->crcmon
? "accepted" : "rejected");
162 if (prev
!= priv
->crcmon
&& priv
->up
) {
173 static int r8180_wx_set_mode(struct net_device
*dev
, struct iw_request_info
*a
,
174 union iwreq_data
*wrqu
, char *b
)
176 struct r8180_priv
*priv
= ieee80211_priv(dev
);
180 if (priv
->ieee80211
->bHwRadioOff
)
184 if (priv
->bInactivePs
) {
185 if (wrqu
->mode
== IW_MODE_ADHOC
)
188 ret
= ieee80211_wx_set_mode(priv
->ieee80211
, a
, wrqu
, b
);
194 /* YJ,add,080819,for hidden ap */
195 struct iw_range_with_scan_capa
{
196 /* Informative stuff (to choose between different interface) */
198 __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 int *val
= (int *)extra
;
1021 printk("-----in fun %s\n", __func__
);
1023 if (priv
->ieee80211
->bHwRadioOff
)
1026 /* unsigned long flags; */
1027 down(&priv
->wx_sem
);
1028 if (DefaultChannelPlan
[*val
].Len
!= 0) {
1029 priv
->channel_plan
= *val
;
1030 /* Clear old channel map 8 */
1031 for (i
= 1; i
<= MAX_CHANNEL_NUMBER
; i
++)
1032 GET_DOT11D_INFO(priv
->ieee80211
)->channel_map
[i
] = 0;
1034 /* Set new channel map */
1035 for (i
= 1; i
<= DefaultChannelPlan
[*val
].Len
; i
++)
1036 GET_DOT11D_INFO(priv
->ieee80211
)->channel_map
[DefaultChannelPlan
[*val
].Channel
[i
-1]] = 1;
1044 static int r8180_wx_get_version(struct net_device
*dev
,
1045 struct iw_request_info
*info
,
1046 union iwreq_data
*wrqu
, char *extra
)
1048 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1049 /* struct ieee80211_device *ieee; */
1051 down(&priv
->wx_sem
);
1052 strcpy(extra
, "1020.0808");
1058 /* added by amy 080818 */
1059 /*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
1060 static int r8180_wx_set_forcerate(struct net_device
*dev
,
1061 struct iw_request_info
*info
,
1062 union iwreq_data
*wrqu
, char *extra
)
1064 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1065 u8 forcerate
= *extra
;
1067 down(&priv
->wx_sem
);
1069 printk("==============>%s(): forcerate is %d\n", __func__
, forcerate
);
1070 if ((forcerate
== 2) || (forcerate
== 4) || (forcerate
== 11) || (forcerate
== 22) || (forcerate
== 12) ||
1071 (forcerate
== 18) || (forcerate
== 24) || (forcerate
== 36) || (forcerate
== 48) || (forcerate
== 72) ||
1072 (forcerate
== 96) || (forcerate
== 108))
1074 priv
->ForcedDataRate
= 1;
1075 priv
->ieee80211
->rate
= forcerate
* 5;
1076 } else if (forcerate
== 0) {
1077 priv
->ForcedDataRate
= 0;
1078 printk("OK! return rate adaptive\n");
1080 printk("ERR: wrong rate\n");
1085 static int r8180_wx_set_enc_ext(struct net_device
*dev
,
1086 struct iw_request_info
*info
,
1087 union iwreq_data
*wrqu
, char *extra
)
1090 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1094 if (priv
->ieee80211
->bHwRadioOff
)
1097 down(&priv
->wx_sem
);
1098 ret
= ieee80211_wx_set_encode_ext(priv
->ieee80211
, info
, wrqu
, extra
);
1103 static int r8180_wx_set_auth(struct net_device
*dev
,
1104 struct iw_request_info
*info
,
1105 union iwreq_data
*wrqu
, char *extra
)
1107 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1110 if (priv
->ieee80211
->bHwRadioOff
)
1113 down(&priv
->wx_sem
);
1114 ret
= ieee80211_wx_set_auth(priv
->ieee80211
, info
, &wrqu
->param
, extra
);
1119 static int r8180_wx_set_mlme(struct net_device
*dev
,
1120 struct iw_request_info
*info
,
1121 union iwreq_data
*wrqu
, char *extra
)
1124 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1127 if (priv
->ieee80211
->bHwRadioOff
)
1131 down(&priv
->wx_sem
);
1133 ret
= ieee80211_wx_set_mlme(priv
->ieee80211
, info
, wrqu
, extra
);
1138 static int r8180_wx_set_gen_ie(struct net_device
*dev
,
1139 struct iw_request_info
*info
,
1140 union iwreq_data
*wrqu
, char *extra
)
1143 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1146 if (priv
->ieee80211
->bHwRadioOff
)
1149 down(&priv
->wx_sem
);
1151 ret
= ieee80211_wx_set_gen_ie(priv
->ieee80211
, extra
, wrqu
->data
.length
);
1158 static iw_handler r8180_wx_handlers
[] = {
1159 NULL
, /* SIOCSIWCOMMIT */
1160 r8180_wx_get_name
, /* SIOCGIWNAME */
1161 dummy
, /* SIOCSIWNWID */
1162 dummy
, /* SIOCGIWNWID */
1163 r8180_wx_set_freq
, /* SIOCSIWFREQ */
1164 r8180_wx_get_freq
, /* SIOCGIWFREQ */
1165 r8180_wx_set_mode
, /* SIOCSIWMODE */
1166 r8180_wx_get_mode
, /* SIOCGIWMODE */
1167 r8180_wx_set_sens
, /* SIOCSIWSENS */
1168 r8180_wx_get_sens
, /* SIOCGIWSENS */
1169 NULL
, /* SIOCSIWRANGE */
1170 rtl8180_wx_get_range
, /* SIOCGIWRANGE */
1171 NULL
, /* SIOCSIWPRIV */
1172 NULL
, /* SIOCGIWPRIV */
1173 NULL
, /* SIOCSIWSTATS */
1174 NULL
, /* SIOCGIWSTATS */
1175 dummy
, /* SIOCSIWSPY */
1176 dummy
, /* SIOCGIWSPY */
1177 NULL
, /* SIOCGIWTHRSPY */
1178 NULL
, /* SIOCWIWTHRSPY */
1179 r8180_wx_set_wap
, /* SIOCSIWAP */
1180 r8180_wx_get_wap
, /* SIOCGIWAP */
1181 r8180_wx_set_mlme
, /* SIOCSIWMLME*/
1182 dummy
, /* SIOCGIWAPLIST -- deprecated */
1183 r8180_wx_set_scan
, /* SIOCSIWSCAN */
1184 r8180_wx_get_scan
, /* SIOCGIWSCAN */
1185 r8180_wx_set_essid
, /* SIOCSIWESSID */
1186 r8180_wx_get_essid
, /* SIOCGIWESSID */
1187 dummy
, /* SIOCSIWNICKN */
1188 dummy
, /* SIOCGIWNICKN */
1189 NULL
, /* -- hole -- */
1190 NULL
, /* -- hole -- */
1191 r8180_wx_set_rate
, /* SIOCSIWRATE */
1192 r8180_wx_get_rate
, /* SIOCGIWRATE */
1193 r8180_wx_set_rts
, /* SIOCSIWRTS */
1194 r8180_wx_get_rts
, /* SIOCGIWRTS */
1195 r8180_wx_set_frag
, /* SIOCSIWFRAG */
1196 r8180_wx_get_frag
, /* SIOCGIWFRAG */
1197 dummy
, /* SIOCSIWTXPOW */
1198 dummy
, /* SIOCGIWTXPOW */
1199 r8180_wx_set_retry
, /* SIOCSIWRETRY */
1200 r8180_wx_get_retry
, /* SIOCGIWRETRY */
1201 r8180_wx_set_enc
, /* SIOCSIWENCODE */
1202 r8180_wx_get_enc
, /* SIOCGIWENCODE */
1203 r8180_wx_set_power
, /* SIOCSIWPOWER */
1204 r8180_wx_get_power
, /* SIOCGIWPOWER */
1205 NULL
, /*---hole---*/
1206 NULL
, /*---hole---*/
1207 r8180_wx_set_gen_ie
, /* SIOCSIWGENIE */
1208 NULL
, /* SIOCSIWGENIE */
1209 r8180_wx_set_auth
, /* SIOCSIWAUTH */
1210 NULL
, /* SIOCSIWAUTH */
1211 r8180_wx_set_enc_ext
, /* SIOCSIWENCODEEXT */
1212 NULL
, /* SIOCSIWENCODEEXT */
1213 NULL
, /* SIOCSIWPMKSA */
1214 NULL
, /*---hole---*/
1218 static const struct iw_priv_args r8180_private_args
[] = {
1220 SIOCIWFIRSTPRIV
+ 0x0,
1221 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "badcrc"
1223 { SIOCIWFIRSTPRIV
+ 0x1,
1228 SIOCIWFIRSTPRIV
+ 0x2,
1229 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "beaconint"
1231 { SIOCIWFIRSTPRIV
+ 0x3,
1236 SIOCIWFIRSTPRIV
+ 0x4,
1237 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "activescan"
1240 { SIOCIWFIRSTPRIV
+ 0x5,
1245 SIOCIWFIRSTPRIV
+ 0x6,
1246 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "rawtx"
1249 { SIOCIWFIRSTPRIV
+ 0x7,
1254 SIOCIWFIRSTPRIV
+ 0x8,
1255 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "setiwmode"
1258 SIOCIWFIRSTPRIV
+ 0x9,
1259 0, IW_PRIV_TYPE_CHAR
| IW_PRIV_SIZE_FIXED
| 32, "getiwmode"
1262 SIOCIWFIRSTPRIV
+ 0xA,
1263 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "setpreamble"
1266 SIOCIWFIRSTPRIV
+ 0xB,
1267 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "getpreamble"
1269 { SIOCIWFIRSTPRIV
+ 0xC,
1273 SIOCIWFIRSTPRIV
+ 0xD,
1274 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "getrssi"
1276 { SIOCIWFIRSTPRIV
+ 0xE,
1280 SIOCIWFIRSTPRIV
+ 0xF,
1281 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "getlinkqual"
1284 SIOCIWFIRSTPRIV
+ 0x10,
1288 SIOCIWFIRSTPRIV
+ 0x11,
1292 SIOCIWFIRSTPRIV
+ 0x12,
1296 SIOCIWFIRSTPRIV
+ 0x13,
1300 SIOCIWFIRSTPRIV
+ 0x14,
1301 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "setchannel"
1304 SIOCIWFIRSTPRIV
+ 0x15,
1305 0, IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "getchannel"
1308 SIOCIWFIRSTPRIV
+ 0x16,
1312 SIOCIWFIRSTPRIV
+ 0x17,
1313 0, IW_PRIV_TYPE_CHAR
| IW_PRIV_SIZE_FIXED
| 32, "getversion"
1316 SIOCIWFIRSTPRIV
+ 0x18,
1317 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, 0, "setrate"
1322 static iw_handler r8180_private_handler
[] = {
1323 r8180_wx_set_crcmon
, /*SIOCIWSECONDPRIV*/
1325 r8180_wx_set_beaconinterval
,
1327 /* r8180_wx_set_monitor_type, */
1328 r8180_wx_set_scan_type
,
1332 r8180_wx_set_iwmode
,
1333 r8180_wx_get_iwmode
,
1334 r8180_wx_set_preamble
,
1335 r8180_wx_get_preamble
,
1337 r8180_wx_get_siglevel
,
1339 r8180_wx_get_sigqual
,
1340 r8180_wx_reset_stats
,
1341 dummy
,/* r8180_wx_get_stats */
1344 r8180_wx_set_channelplan
,
1345 r8180_wx_get_channelplan
,
1347 r8180_wx_get_version
,
1348 r8180_wx_set_forcerate
,
1351 static inline int is_same_network(struct ieee80211_network
*src
,
1352 struct ieee80211_network
*dst
,
1353 struct ieee80211_device
*ieee
)
1355 /* A network is only a duplicate if the channel, BSSID, ESSID
1356 * and the capability field (in particular IBSS and BSS) all match.
1357 * We treat all <hidden> with the same BSSID and channel
1360 return (((src
->ssid_len
== dst
->ssid_len
) || (ieee
->iw_mode
== IW_MODE_INFRA
)) && /* YJ,mod, 080819,for hidden ap */
1361 (src
->channel
== dst
->channel
) &&
1362 !memcmp(src
->bssid
, dst
->bssid
, ETH_ALEN
) &&
1363 (!memcmp(src
->ssid
, dst
->ssid
, src
->ssid_len
) || (ieee
->iw_mode
== IW_MODE_INFRA
)) && /* YJ,mod, 080819,for hidden ap */
1364 ((src
->capability
& WLAN_CAPABILITY_IBSS
) ==
1365 (dst
->capability
& WLAN_CAPABILITY_IBSS
)) &&
1366 ((src
->capability
& WLAN_CAPABILITY_BSS
) ==
1367 (dst
->capability
& WLAN_CAPABILITY_BSS
)));
1370 /* WB modified to show signal to GUI on 18-01-2008 */
1371 static struct iw_statistics
*r8180_get_wireless_stats(struct net_device
*dev
)
1373 struct r8180_priv
*priv
= ieee80211_priv(dev
);
1374 struct ieee80211_device
* ieee
= priv
->ieee80211
;
1375 struct iw_statistics
* wstats
= &priv
->wstats
;
1380 if (ieee
->state
< IEEE80211_LINKED
) {
1381 wstats
->qual
.qual
= 0;
1382 wstats
->qual
.level
= 0;
1383 wstats
->qual
.noise
= 0;
1384 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1388 tmp_level
= (&ieee
->current_network
)->stats
.signal
;
1389 tmp_qual
= (&ieee
->current_network
)->stats
.signalstrength
;
1390 tmp_noise
= (&ieee
->current_network
)->stats
.noise
;
1392 wstats
->qual
.level
= tmp_level
;
1393 wstats
->qual
.qual
= tmp_qual
;
1394 wstats
->qual
.noise
= tmp_noise
;
1395 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
1399 struct iw_handler_def r8180_wx_handlers_def
= {
1400 .standard
= r8180_wx_handlers
,
1401 .num_standard
= ARRAY_SIZE(r8180_wx_handlers
),
1402 .private = r8180_private_handler
,
1403 .num_private
= ARRAY_SIZE(r8180_private_handler
),
1404 .num_private_args
= sizeof(r8180_private_args
) / sizeof(struct iw_priv_args
),
1405 .get_wireless_stats
= r8180_get_wireless_stats
,
1406 .private_args
= (struct iw_priv_args
*)r8180_private_args
,