Staging: rtl8187se: r8180_wx.c: Removed old comments
[linux-2.6.git] / drivers / staging / rtl8187se / r8180_wx.c
blob9d03cfb3e9ab365a768294d6c07ce3370731a675
1 /*
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
17 project Authors.
21 #include "r8180.h"
22 #include "r8180_hw.h"
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)
60 return 0;
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);
74 return 0;
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;
82 int bi = parms[0];
84 struct r8180_priv *priv = ieee80211_priv(dev);
86 if (priv->ieee80211->bHwRadioOff)
87 return 0;
89 down(&priv->wx_sem);
90 DMESG("setting beacon interval to %x", bi);
92 priv->ieee80211->current_network.beacon_interval = bi;
93 rtl8180_commit(dev);
94 up(&priv->wx_sem);
96 return 0;
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)
124 int ret;
125 struct r8180_priv *priv = ieee80211_priv(dev);
128 if (priv->ieee80211->bHwRadioOff)
129 return 0;
131 down(&priv->wx_sem);
133 ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
135 up(&priv->wx_sem);
137 return ret;
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)
152 return 0;
154 down(&priv->wx_sem);
156 if (enable)
157 priv->crcmon = 1;
158 else
159 priv->crcmon = 0;
161 DMESG("bad CRC in monitor mode are %s",
162 priv->crcmon ? "accepted" : "rejected");
164 if (prev != priv->crcmon && priv->up) {
165 rtl8180_down(dev);
166 rtl8180_up(dev);
169 up(&priv->wx_sem);
171 return 0;
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);
179 int ret;
182 if (priv->ieee80211->bHwRadioOff)
183 return 0;
185 down(&priv->wx_sem);
186 if (priv->bInactivePs) {
187 if (wrqu->mode == IW_MODE_ADHOC)
188 IPSLeave(dev);
190 ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
192 up(&priv->wx_sem);
193 return ret;
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 */
216 __u8 scan_capa;
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);
227 u16 val;
228 int i;
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;
276 range->pm_capa = 0;
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;
290 val++;
291 } else {
292 /* FIXME: do we need to set anything for channels */
293 /* we don't use ? */
296 if (val == IW_MAX_FREQUENCIES)
297 break;
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;
304 return 0;
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);
312 int ret;
313 struct ieee80211_device* ieee = priv->ieee80211;
316 if (priv->ieee80211->bHwRadioOff)
317 return 0;
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);
327 down(&priv->wx_sem);
328 if (priv->up) {
329 priv->ieee80211->actscanning = true;
330 if (priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)) {
331 IPSLeave(dev);
332 ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
333 ret = 0;
334 } else {
335 /* prevent scan in BusyTraffic */
336 /* FIXME: Need to consider last scan time */
337 if ((priv->link_detect.bBusyTraffic) && (true)) {
338 ret = 0;
339 printk("Now traffic is busy, please try later!\n");
340 } else
341 /* prevent scan in BusyTraffic,end */
342 ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
344 } else
345 ret = -1;
347 up(&priv->wx_sem);
349 return ret;
353 static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
354 union iwreq_data *wrqu, char *b)
357 int ret;
358 struct r8180_priv *priv = ieee80211_priv(dev);
360 down(&priv->wx_sem);
361 if (priv->up)
362 ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
363 else
364 ret = -1;
366 up(&priv->wx_sem);
367 return ret;
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);
377 int ret;
379 if (priv->ieee80211->bHwRadioOff)
380 return 0;
382 down(&priv->wx_sem);
383 if (priv->bInactivePs)
384 IPSLeave(dev);
386 ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
388 up(&priv->wx_sem);
389 return ret;
393 static int r8180_wx_get_essid(struct net_device *dev,
394 struct iw_request_info *a,
395 union iwreq_data *wrqu, char *b)
397 int ret;
398 struct r8180_priv *priv = ieee80211_priv(dev);
400 down(&priv->wx_sem);
402 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
404 up(&priv->wx_sem);
406 return ret;
410 static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
411 union iwreq_data *wrqu, char *b)
413 int ret;
414 struct r8180_priv *priv = ieee80211_priv(dev);
417 if (priv->ieee80211->bHwRadioOff)
418 return 0;
420 down(&priv->wx_sem);
422 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
424 up(&priv->wx_sem);
425 return ret;
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)
444 return 0;
446 if (wrqu->frag.disabled)
447 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
448 else {
449 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
450 wrqu->frag.value > MAX_FRAG_THRESHOLD)
451 return -EINVAL;
453 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
456 return 0;
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);
470 return 0;
474 static int r8180_wx_set_wap(struct net_device *dev,
475 struct iw_request_info *info,
476 union iwreq_data *awrq,
477 char *extra)
479 int ret;
480 struct r8180_priv *priv = ieee80211_priv(dev);
482 if (priv->ieee80211->bHwRadioOff)
483 return 0;
485 down(&priv->wx_sem);
487 ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
489 up(&priv->wx_sem);
490 return ret;
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);
510 int ret;
512 if (priv->ieee80211->bHwRadioOff)
513 return 0;
516 down(&priv->wx_sem);
518 if (priv->hw_wep) ret = r8180_wx_set_key(dev, info, wrqu, key);
519 else {
520 DMESG("Setting SW wep key");
521 ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
524 up(&priv->wx_sem);
525 return ret;
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;
544 int mode = parms[0];
546 if (priv->ieee80211->bHwRadioOff)
547 return 0;
549 priv->ieee80211->active_scan = mode;
551 return 1;
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);
559 int err = 0;
561 if (priv->ieee80211->bHwRadioOff)
562 return 0;
564 down(&priv->wx_sem);
566 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
567 wrqu->retry.disabled) {
568 err = -EINVAL;
569 goto exit;
571 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
572 err = -EINVAL;
573 goto exit;
576 if (wrqu->retry.value > R8180_MAX_RETRY) {
577 err = -EINVAL;
578 goto exit;
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);
584 } else {
585 priv->retry_data = wrqu->retry.value;
586 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
589 /* FIXME !
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
595 rtl8180_commit(dev);
596 exit:
597 up(&priv->wx_sem);
599 return err;
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) ==
612 IW_RETRY_LIFETIME)
613 return -EINVAL;
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;
618 } else {
619 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
620 wrqu->retry.value = priv->retry_data;
623 return 0;
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;
634 return 0;
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);
645 short err = 0;
647 if (priv->ieee80211->bHwRadioOff)
648 return 0;
650 down(&priv->wx_sem);
651 if (priv->rf_set_sens == NULL) {
652 err = -1; /* we have not this support for this radio */
653 goto exit;
655 if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
656 priv->sens = wrqu->sens.value;
657 else
658 err = -EINVAL;
660 exit:
661 up(&priv->wx_sem);
663 return err;
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);
672 int ret;
674 if (priv->ieee80211->bHwRadioOff)
675 return 0;
677 down(&priv->wx_sem);
679 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
681 up(&priv->wx_sem);
683 return ret;
687 static int r8180_wx_get_power(struct net_device *dev,
688 struct iw_request_info *info,
689 union iwreq_data *wrqu, char *extra)
691 int ret;
692 struct r8180_priv *priv = ieee80211_priv(dev);
694 down(&priv->wx_sem);
696 ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
698 up(&priv->wx_sem);
700 return ret;
703 static int r8180_wx_set_power(struct net_device *dev,
704 struct iw_request_info *info,
705 union iwreq_data *wrqu, char *extra)
707 int ret;
708 struct r8180_priv *priv = ieee80211_priv(dev);
711 if (priv->ieee80211->bHwRadioOff)
712 return 0;
714 down(&priv->wx_sem);
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);
724 up(&priv->wx_sem);
726 return ret;
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)
737 return 0;
739 if (wrqu->rts.disabled)
740 priv->rts = DEFAULT_RTS_THRESHOLD;
741 else {
742 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
743 wrqu->rts.value > MAX_RTS_THRESHOLD)
744 return -EINVAL;
746 priv->rts = wrqu->rts.value;
749 return 0;
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);
763 return 0;
765 static int dummy(struct net_device *dev, struct iw_request_info *a,
766 union iwreq_data *wrqu, char *b)
768 return -1;
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;
777 int ret = 0;
781 down(&priv->wx_sem);
783 ieee = priv->ieee80211;
785 strcpy(extra, "802.11");
786 if (ieee->modulation & IEEE80211_CCK_MODULATION) {
787 strcat(extra, "b");
788 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
789 strcat(extra, "/g");
790 } else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
791 strcat(extra, "g");
793 up(&priv->wx_sem);
795 return ret;
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;
804 int ret = 0;
805 int modulation = 0, mode = 0;
808 if (priv->ieee80211->bHwRadioOff)
809 return 0;
811 down(&priv->wx_sem);
813 if (*param == 1) {
814 modulation |= IEEE80211_CCK_MODULATION;
815 mode = IEEE_B;
816 printk(KERN_INFO "B mode!\n");
817 } else if (*param == 2) {
818 modulation |= IEEE80211_OFDM_MODULATION;
819 mode = IEEE_G;
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);
830 ieee->mode = mode;
831 ieee->modulation = modulation;
832 ieee80211_start_protocol(ieee);
833 } else {
834 ieee->mode = mode;
835 ieee->modulation = modulation;
838 up(&priv->wx_sem);
840 return ret;
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);
850 down(&priv->wx_sem);
854 *extra = (char) priv->plcp_preamble_mode; /* 0:auto 1:short 2:long */
855 up(&priv->wx_sem);
857 return 0;
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);
864 int ret = 0;
867 if (priv->ieee80211->bHwRadioOff)
868 return 0;
870 down(&priv->wx_sem);
871 if (*extra < 0 || *extra > 2)
872 ret = -1;
873 else
874 priv->plcp_preamble_mode = *((short *)extra) ;
878 up(&priv->wx_sem);
880 return ret;
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);
887 int ret = 0;
891 down(&priv->wx_sem);
892 /* Modify by hikaru 6.5 */
893 *((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */
897 up(&priv->wx_sem);
899 return ret;
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);
906 int ret = 0;
910 down(&priv->wx_sem);
911 /* Modify by hikaru 6.5 */
912 *((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */
916 up(&priv->wx_sem);
918 return ret;
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);
925 down(&priv->wx_sem);
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;
955 up(&priv->wx_sem);
957 return 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)
967 return 0;
970 down(&priv->wx_sem);
971 priv->rf_wakeup(dev);
973 up(&priv->wx_sem);
975 return 0;
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)
986 return 0;
989 down(&priv->wx_sem);
990 priv->rf_sleep(dev);
992 up(&priv->wx_sem);
994 return 0;
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;
1010 up(&priv->wx_sem);
1012 return 0;
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;
1021 int i;
1022 printk("-----in fun %s\n", __func__);
1024 if (priv->ieee80211->bHwRadioOff)
1025 return 0;
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;
1040 up(&priv->wx_sem);
1042 return 0;
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");
1054 up(&priv->wx_sem);
1056 return 0;
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");
1080 } else
1081 printk("ERR: wrong rate\n");
1082 up(&priv->wx_sem);
1083 return 0;
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);
1093 int ret = 0;
1095 if (priv->ieee80211->bHwRadioOff)
1096 return 0;
1098 down(&priv->wx_sem);
1099 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
1100 up(&priv->wx_sem);
1101 return ret;
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);
1110 int ret = 0;
1112 if (priv->ieee80211->bHwRadioOff)
1113 return 0;
1115 down(&priv->wx_sem);
1116 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
1117 up(&priv->wx_sem);
1118 return ret;
1121 static int r8180_wx_set_mlme(struct net_device *dev,
1122 struct iw_request_info *info,
1123 union iwreq_data *wrqu, char *extra)
1125 int ret = 0;
1126 struct r8180_priv *priv = ieee80211_priv(dev);
1129 if (priv->ieee80211->bHwRadioOff)
1130 return 0;
1133 down(&priv->wx_sem);
1134 #if 1
1135 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1136 #endif
1137 up(&priv->wx_sem);
1138 return ret;
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)
1144 int ret = 0;
1145 struct r8180_priv *priv = ieee80211_priv(dev);
1148 if (priv->ieee80211->bHwRadioOff)
1149 return 0;
1151 down(&priv->wx_sem);
1152 #if 1
1153 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
1154 #endif
1155 up(&priv->wx_sem);
1156 return ret;
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,
1226 0, 0, "dummy"
1230 SIOCIWFIRSTPRIV + 0x2,
1231 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
1233 { SIOCIWFIRSTPRIV + 0x3,
1234 0, 0, "dummy"
1238 SIOCIWFIRSTPRIV + 0x4,
1239 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1242 { SIOCIWFIRSTPRIV + 0x5,
1243 0, 0, "dummy"
1247 SIOCIWFIRSTPRIV + 0x6,
1248 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1251 { SIOCIWFIRSTPRIV + 0x7,
1252 0, 0, "dummy"
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,
1272 0, 0, "dummy"
1275 SIOCIWFIRSTPRIV + 0xD,
1276 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
1278 { SIOCIWFIRSTPRIV + 0xE,
1279 0, 0, "dummy"
1282 SIOCIWFIRSTPRIV + 0xF,
1283 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
1286 SIOCIWFIRSTPRIV + 0x10,
1287 0, 0, "resetstats"
1290 SIOCIWFIRSTPRIV + 0x11,
1291 0, 0, "dummy"
1294 SIOCIWFIRSTPRIV + 0x12,
1295 0, 0, "radioon"
1298 SIOCIWFIRSTPRIV + 0x13,
1299 0, 0, "radiooff"
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,
1311 0, 0, "dummy"
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*/
1326 dummy,
1327 r8180_wx_set_beaconinterval,
1328 dummy,
1329 /* r8180_wx_set_monitor_type, */
1330 r8180_wx_set_scan_type,
1331 dummy,
1332 r8180_wx_set_rawtx,
1333 dummy,
1334 r8180_wx_set_iwmode,
1335 r8180_wx_get_iwmode,
1336 r8180_wx_set_preamble,
1337 r8180_wx_get_preamble,
1338 dummy,
1339 r8180_wx_get_siglevel,
1340 dummy,
1341 r8180_wx_get_sigqual,
1342 r8180_wx_reset_stats,
1343 dummy,/* r8180_wx_get_stats */
1344 r8180_wx_radio_on,
1345 r8180_wx_radio_off,
1346 r8180_wx_set_channelplan,
1347 r8180_wx_get_channelplan,
1348 dummy,
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
1360 * as one network */
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; */
1380 int tmp_level = 0;
1381 int tmp_qual = 0;
1382 int tmp_noise = 0;
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;
1390 return wstats;
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;
1401 return wstats;
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,