Staging: rtl8192u: r8192U_wx.c Added {} braces and newlines
[linux-2.6/btrfs-unstable.git] / drivers / staging / rtl8192u / r8192U_wx.c
blob1af7c5d5bb558b8d9cbda7bee91acae5dbbb5f38
1 /*
2 This file contains wireless extension handlers.
4 This is part of rtl8180 OpenSource driver.
5 Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
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 thank the Authors of those projects and the Ndiswrapper
17 project Authors.
20 #include <linux/string.h>
21 #include "r8192U.h"
22 #include "r8192U_hw.h"
24 #include "dot11d.h"
26 #define RATE_COUNT 12
27 u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
28 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
31 #ifndef ENETDOWN
32 #define ENETDOWN 1
33 #endif
35 static int r8192_wx_get_freq(struct net_device *dev,
36 struct iw_request_info *a,
37 union iwreq_data *wrqu, char *b)
39 struct r8192_priv *priv = ieee80211_priv(dev);
41 return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
45 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
46 union iwreq_data *wrqu, char *b)
48 struct r8192_priv *priv = ieee80211_priv(dev);
50 return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
55 static int r8192_wx_get_rate(struct net_device *dev,
56 struct iw_request_info *info,
57 union iwreq_data *wrqu, char *extra)
59 struct r8192_priv *priv = ieee80211_priv(dev);
60 return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
65 static int r8192_wx_set_rate(struct net_device *dev,
66 struct iw_request_info *info,
67 union iwreq_data *wrqu, char *extra)
69 int ret;
70 struct r8192_priv *priv = ieee80211_priv(dev);
72 down(&priv->wx_sem);
74 ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
76 up(&priv->wx_sem);
78 return ret;
82 static int r8192_wx_set_rts(struct net_device *dev,
83 struct iw_request_info *info,
84 union iwreq_data *wrqu, char *extra)
86 int ret;
87 struct r8192_priv *priv = ieee80211_priv(dev);
89 down(&priv->wx_sem);
91 ret = ieee80211_wx_set_rts(priv->ieee80211, info, wrqu, extra);
93 up(&priv->wx_sem);
95 return ret;
98 static int r8192_wx_get_rts(struct net_device *dev,
99 struct iw_request_info *info,
100 union iwreq_data *wrqu, char *extra)
102 struct r8192_priv *priv = ieee80211_priv(dev);
103 return ieee80211_wx_get_rts(priv->ieee80211, info, wrqu, extra);
106 static int r8192_wx_set_power(struct net_device *dev,
107 struct iw_request_info *info,
108 union iwreq_data *wrqu, char *extra)
110 int ret;
111 struct r8192_priv *priv = ieee80211_priv(dev);
113 down(&priv->wx_sem);
115 ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
117 up(&priv->wx_sem);
119 return ret;
122 static int r8192_wx_get_power(struct net_device *dev,
123 struct iw_request_info *info,
124 union iwreq_data *wrqu, char *extra)
126 struct r8192_priv *priv = ieee80211_priv(dev);
127 return ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
130 static int r8192_wx_force_reset(struct net_device *dev,
131 struct iw_request_info *info,
132 union iwreq_data *wrqu, char *extra)
134 struct r8192_priv *priv = ieee80211_priv(dev);
136 down(&priv->wx_sem);
138 printk("%s(): force reset ! extra is %d\n", __func__, *extra);
139 priv->force_reset = *extra;
140 up(&priv->wx_sem);
141 return 0;
146 static int r8192_wx_set_rawtx(struct net_device *dev,
147 struct iw_request_info *info,
148 union iwreq_data *wrqu, char *extra)
150 struct r8192_priv *priv = ieee80211_priv(dev);
151 int ret;
153 down(&priv->wx_sem);
155 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
157 up(&priv->wx_sem);
159 return ret;
163 static int r8192_wx_set_crcmon(struct net_device *dev,
164 struct iw_request_info *info,
165 union iwreq_data *wrqu, char *extra)
167 struct r8192_priv *priv = ieee80211_priv(dev);
168 int *parms = (int *)extra;
169 int enable = (parms[0] > 0);
170 short prev = priv->crcmon;
172 down(&priv->wx_sem);
174 if (enable)
175 priv->crcmon = 1;
176 else
177 priv->crcmon = 0;
179 DMESG("bad CRC in monitor mode are %s",
180 priv->crcmon ? "accepted" : "rejected");
182 if (prev != priv->crcmon && priv->up) {
183 //rtl8180_down(dev);
184 //rtl8180_up(dev);
187 up(&priv->wx_sem);
189 return 0;
192 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
193 union iwreq_data *wrqu, char *b)
195 struct r8192_priv *priv = ieee80211_priv(dev);
196 int ret;
197 down(&priv->wx_sem);
199 ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
201 rtl8192_set_rxconf(dev);
203 up(&priv->wx_sem);
204 return ret;
207 struct iw_range_with_scan_capa {
208 /* Informative stuff (to choose between different interface) */
209 __u32 throughput; /* To give an idea... */
210 /* In theory this value should be the maximum benchmarked
211 * TCP/IP throughput, because with most of these devices the
212 * bit rate is meaningless (overhead an co) to estimate how
213 * fast the connection will go and pick the fastest one.
214 * I suggest people to play with Netperf or any benchmark...
217 /* NWID (or domain id) */
218 __u32 min_nwid; /* Minimal NWID we are able to set */
219 __u32 max_nwid; /* Maximal NWID we are able to set */
221 /* Old Frequency (backward compat - moved lower ) */
222 __u16 old_num_channels;
223 __u8 old_num_frequency;
225 /* Scan capabilities */
226 __u8 scan_capa;
228 static int rtl8180_wx_get_range(struct net_device *dev,
229 struct iw_request_info *info,
230 union iwreq_data *wrqu, char *extra)
232 struct iw_range *range = (struct iw_range *)extra;
233 struct iw_range_with_scan_capa *tmp = (struct iw_range_with_scan_capa *)range;
234 struct r8192_priv *priv = ieee80211_priv(dev);
235 u16 val;
236 int i;
238 wrqu->data.length = sizeof(*range);
239 memset(range, 0, sizeof(*range));
241 /* Let's try to keep this struct in the same order as in
242 * linux/include/wireless.h
245 /* TODO: See what values we can set, and remove the ones we can't
246 * set, or fill them with some default data.
249 /* ~5 Mb/s real (802.11b) */
250 range->throughput = 5 * 1000 * 1000;
252 // TODO: Not used in 802.11b?
253 // range->min_nwid; /* Minimal NWID we are able to set */
254 // TODO: Not used in 802.11b?
255 // range->max_nwid; /* Maximal NWID we are able to set */
257 /* Old Frequency (backward compat - moved lower ) */
258 // range->old_num_channels;
259 // range->old_num_frequency;
260 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
261 if (priv->rf_set_sens != NULL)
262 range->sensitivity = priv->max_sens; /* signal level threshold range */
264 range->max_qual.qual = 100;
265 /* TODO: Find real max RSSI and stick here */
266 range->max_qual.level = 0;
267 range->max_qual.noise = -98;
268 range->max_qual.updated = 7; /* Updated all three */
270 range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
271 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
272 range->avg_qual.level = 20 + -98;
273 range->avg_qual.noise = 0;
274 range->avg_qual.updated = 7; /* Updated all three */
276 range->num_bitrates = RATE_COUNT;
278 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
279 range->bitrate[i] = rtl8180_rates[i];
281 range->min_frag = MIN_FRAG_THRESHOLD;
282 range->max_frag = MAX_FRAG_THRESHOLD;
284 range->min_pmp = 0;
285 range->max_pmp = 5000000;
286 range->min_pmt = 0;
287 range->max_pmt = 65535*1000;
288 range->pmp_flags = IW_POWER_PERIOD;
289 range->pmt_flags = IW_POWER_TIMEOUT;
290 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
292 range->we_version_compiled = WIRELESS_EXT;
293 range->we_version_source = 16;
295 // range->retry_capa; /* What retry options are supported */
296 // range->retry_flags; /* How to decode max/min retry limit */
297 // range->r_time_flags; /* How to decode max/min retry life */
298 // range->min_retry; /* Minimal number of retries */
299 // range->max_retry; /* Maximal number of retries */
300 // range->min_r_time; /* Minimal retry lifetime */
301 // range->max_r_time; /* Maximal retry lifetime */
304 for (i = 0, val = 0; i < 14; i++) {
306 // Include only legal frequencies for some countries
307 if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
308 range->freq[val].i = i + 1;
309 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
310 range->freq[val].e = 1;
311 val++;
312 } else {
313 // FIXME: do we need to set anything for channels
314 // we don't use ?
317 if (val == IW_MAX_FREQUENCIES)
318 break;
320 range->num_frequency = val;
321 range->num_channels = val;
322 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
323 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
324 tmp->scan_capa = 0x01;
325 return 0;
329 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
330 union iwreq_data *wrqu, char *b)
332 struct r8192_priv *priv = ieee80211_priv(dev);
333 struct ieee80211_device *ieee = priv->ieee80211;
334 int ret = 0;
336 if (!priv->up)
337 return -ENETDOWN;
339 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
340 return -EAGAIN;
341 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
342 struct iw_scan_req *req = (struct iw_scan_req *)b;
343 if (req->essid_len) {
344 //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
345 ieee->current_network.ssid_len = req->essid_len;
346 memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
347 //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
351 down(&priv->wx_sem);
352 if (priv->ieee80211->state != IEEE80211_LINKED) {
353 priv->ieee80211->scanning = 0;
354 ieee80211_softmac_scan_syncro(priv->ieee80211);
355 ret = 0;
356 } else {
357 ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
359 up(&priv->wx_sem);
360 return ret;
364 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
365 union iwreq_data *wrqu, char *b)
368 int ret;
369 struct r8192_priv *priv = ieee80211_priv(dev);
371 if (!priv->up)
372 return -ENETDOWN;
374 down(&priv->wx_sem);
376 ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
378 up(&priv->wx_sem);
380 return ret;
383 static int r8192_wx_set_essid(struct net_device *dev,
384 struct iw_request_info *a,
385 union iwreq_data *wrqu, char *b)
387 struct r8192_priv *priv = ieee80211_priv(dev);
388 int ret;
389 down(&priv->wx_sem);
391 ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
393 up(&priv->wx_sem);
395 return ret;
401 static int r8192_wx_get_essid(struct net_device *dev,
402 struct iw_request_info *a,
403 union iwreq_data *wrqu, char *b)
405 int ret;
406 struct r8192_priv *priv = ieee80211_priv(dev);
408 down(&priv->wx_sem);
410 ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
412 up(&priv->wx_sem);
414 return ret;
418 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
419 union iwreq_data *wrqu, char *b)
421 int ret;
422 struct r8192_priv *priv = ieee80211_priv(dev);
424 down(&priv->wx_sem);
426 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
428 up(&priv->wx_sem);
429 return ret;
432 static int r8192_wx_get_name(struct net_device *dev,
433 struct iw_request_info *info,
434 union iwreq_data *wrqu, char *extra)
436 struct r8192_priv *priv = ieee80211_priv(dev);
437 return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
441 static int r8192_wx_set_frag(struct net_device *dev,
442 struct iw_request_info *info,
443 union iwreq_data *wrqu, char *extra)
445 struct r8192_priv *priv = ieee80211_priv(dev);
447 if (wrqu->frag.disabled)
448 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
449 else {
450 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
451 wrqu->frag.value > MAX_FRAG_THRESHOLD)
452 return -EINVAL;
454 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
457 return 0;
461 static int r8192_wx_get_frag(struct net_device *dev,
462 struct iw_request_info *info,
463 union iwreq_data *wrqu, char *extra)
465 struct r8192_priv *priv = ieee80211_priv(dev);
467 wrqu->frag.value = priv->ieee80211->fts;
468 wrqu->frag.fixed = 0; /* no auto select */
469 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
471 return 0;
475 static int r8192_wx_set_wap(struct net_device *dev,
476 struct iw_request_info *info,
477 union iwreq_data *awrq,
478 char *extra)
481 int ret;
482 struct r8192_priv *priv = ieee80211_priv(dev);
483 // struct sockaddr *temp = (struct sockaddr *)awrq;
484 down(&priv->wx_sem);
486 ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
488 up(&priv->wx_sem);
490 return ret;
495 static int r8192_wx_get_wap(struct net_device *dev,
496 struct iw_request_info *info,
497 union iwreq_data *wrqu, char *extra)
499 struct r8192_priv *priv = ieee80211_priv(dev);
501 return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
505 static int r8192_wx_get_enc(struct net_device *dev,
506 struct iw_request_info *info,
507 union iwreq_data *wrqu, char *key)
509 struct r8192_priv *priv = ieee80211_priv(dev);
511 return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
514 static int r8192_wx_set_enc(struct net_device *dev,
515 struct iw_request_info *info,
516 union iwreq_data *wrqu, char *key)
518 struct r8192_priv *priv = ieee80211_priv(dev);
519 struct ieee80211_device *ieee = priv->ieee80211;
520 int ret;
522 //u32 TargetContent;
523 u32 hwkey[4] = {0, 0, 0, 0};
524 u8 mask = 0xff;
525 u32 key_idx = 0;
526 //u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
527 u8 zero_addr[4][6] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
528 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
529 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
530 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
531 int i;
533 if (!priv->up)
534 return -ENETDOWN;
536 down(&priv->wx_sem);
538 RT_TRACE(COMP_SEC, "Setting SW wep key");
539 ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
541 up(&priv->wx_sem);
545 //sometimes, the length is zero while we do not type key value
546 if (wrqu->encoding.length != 0) {
548 for (i = 0; i < 4; i++) {
549 hwkey[i] |= key[4*i+0]&mask;
550 if (i == 1 && (4*i+1) == wrqu->encoding.length)
551 mask = 0x00;
552 if (i == 3 && (4*i+1) == wrqu->encoding.length)
553 mask = 0x00;
554 hwkey[i] |= (key[4*i+1]&mask)<<8;
555 hwkey[i] |= (key[4*i+2]&mask)<<16;
556 hwkey[i] |= (key[4*i+3]&mask)<<24;
559 #define CONF_WEP40 0x4
560 #define CONF_WEP104 0x14
562 switch (wrqu->encoding.flags & IW_ENCODE_INDEX) {
563 case 0:
564 key_idx = ieee->tx_keyidx;
565 break;
566 case 1:
567 key_idx = 0;
568 break;
569 case 2:
570 key_idx = 1;
571 break;
572 case 3:
573 key_idx = 2;
574 break;
575 case 4:
576 key_idx = 3;
577 break;
578 default:
579 break;
582 if (wrqu->encoding.length == 0x5) {
583 ieee->pairwise_key_type = KEY_TYPE_WEP40;
584 EnableHWSecurityConfig8192(dev);
586 setKey(dev,
587 key_idx, //EntryNo
588 key_idx, //KeyIndex
589 KEY_TYPE_WEP40, //KeyType
590 zero_addr[key_idx],
591 0, //DefaultKey
592 hwkey); //KeyContent
596 else if (wrqu->encoding.length == 0xd) {
597 ieee->pairwise_key_type = KEY_TYPE_WEP104;
598 EnableHWSecurityConfig8192(dev);
600 setKey(dev,
601 key_idx, //EntryNo
602 key_idx, //KeyIndex
603 KEY_TYPE_WEP104, //KeyType
604 zero_addr[key_idx],
605 0, //DefaultKey
606 hwkey); //KeyContent
608 } else {
609 printk("wrong type in WEP, not WEP40 and WEP104\n");
614 return ret;
618 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa,
619 union iwreq_data *wrqu, char *p){
621 struct r8192_priv *priv = ieee80211_priv(dev);
622 int *parms = (int *)p;
623 int mode = parms[0];
625 priv->ieee80211->active_scan = mode;
627 return 1;
632 static int r8192_wx_set_retry(struct net_device *dev,
633 struct iw_request_info *info,
634 union iwreq_data *wrqu, char *extra)
636 struct r8192_priv *priv = ieee80211_priv(dev);
637 int err = 0;
639 down(&priv->wx_sem);
641 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
642 wrqu->retry.disabled){
643 err = -EINVAL;
644 goto exit;
646 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
647 err = -EINVAL;
648 goto exit;
651 if (wrqu->retry.value > R8180_MAX_RETRY) {
652 err = -EINVAL;
653 goto exit;
655 if (wrqu->retry.flags & IW_RETRY_MAX) {
656 priv->retry_rts = wrqu->retry.value;
657 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
659 } else {
660 priv->retry_data = wrqu->retry.value;
661 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
664 /* FIXME !
665 * We might try to write directly the TX config register
666 * or to restart just the (R)TX process.
667 * I'm unsure if whole reset is really needed
670 rtl8192_commit(dev);
672 if(priv->up){
673 rtl8180_rtx_disable(dev);
674 rtl8180_rx_enable(dev);
675 rtl8180_tx_enable(dev);
679 exit:
680 up(&priv->wx_sem);
682 return err;
685 static int r8192_wx_get_retry(struct net_device *dev,
686 struct iw_request_info *info,
687 union iwreq_data *wrqu, char *extra)
689 struct r8192_priv *priv = ieee80211_priv(dev);
692 wrqu->retry.disabled = 0; /* can't be disabled */
694 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
695 IW_RETRY_LIFETIME)
696 return -EINVAL;
698 if (wrqu->retry.flags & IW_RETRY_MAX) {
699 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
700 wrqu->retry.value = priv->retry_rts;
701 } else {
702 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
703 wrqu->retry.value = priv->retry_data;
705 //printk("returning %d",wrqu->retry.value);
708 return 0;
711 static int r8192_wx_get_sens(struct net_device *dev,
712 struct iw_request_info *info,
713 union iwreq_data *wrqu, char *extra)
715 struct r8192_priv *priv = ieee80211_priv(dev);
716 if (priv->rf_set_sens == NULL)
717 return -1; /* we have not this support for this radio */
718 wrqu->sens.value = priv->sens;
719 return 0;
723 static int r8192_wx_set_sens(struct net_device *dev,
724 struct iw_request_info *info,
725 union iwreq_data *wrqu, char *extra)
728 struct r8192_priv *priv = ieee80211_priv(dev);
730 short err = 0;
731 down(&priv->wx_sem);
732 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
733 if (priv->rf_set_sens == NULL) {
734 err = -1; /* we have not this support for this radio */
735 goto exit;
737 if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
738 priv->sens = wrqu->sens.value;
739 else
740 err = -EINVAL;
742 exit:
743 up(&priv->wx_sem);
745 return err;
748 //hw security need to reorganized.
749 static int r8192_wx_set_enc_ext(struct net_device *dev,
750 struct iw_request_info *info,
751 union iwreq_data *wrqu, char *extra)
753 int ret = 0;
754 struct r8192_priv *priv = ieee80211_priv(dev);
755 struct ieee80211_device *ieee = priv->ieee80211;
756 //printk("===>%s()\n", __func__);
759 down(&priv->wx_sem);
760 ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
763 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
764 u8 zero[6] = {0};
765 u32 key[4] = {0};
766 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
767 struct iw_point *encoding = &wrqu->encoding;
768 u8 idx = 0, alg = 0, group = 0;
769 if ((encoding->flags & IW_ENCODE_DISABLED) || ext->alg == IW_ENCODE_ALG_NONE)
770 //none is not allowed to use hwsec WB 2008.07.01
771 goto end_hw_sec;
773 // as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4;
774 alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg;
775 idx = encoding->flags & IW_ENCODE_INDEX;
776 if (idx)
777 idx--;
778 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
780 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40)) {
781 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
782 alg = KEY_TYPE_WEP104;
783 ieee->pairwise_key_type = alg;
784 EnableHWSecurityConfig8192(dev);
786 memcpy((u8 *)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
788 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
790 setKey(dev,
791 idx,//EntryNo
792 idx, //KeyIndex
793 alg, //KeyType
794 zero, //MacAddr
795 0, //DefaultKey
796 key); //KeyContent
797 } else if (group) {
798 ieee->group_key_type = alg;
799 setKey(dev,
800 idx,//EntryNo
801 idx, //KeyIndex
802 alg, //KeyType
803 broadcast_addr, //MacAddr
804 0, //DefaultKey
805 key); //KeyContent
806 } else {//pairwise key
807 setKey(dev,
808 4,//EntryNo
809 idx, //KeyIndex
810 alg, //KeyType
811 (u8 *)ieee->ap_mac_addr, //MacAddr
812 0, //DefaultKey
813 key); //KeyContent
819 end_hw_sec:
821 up(&priv->wx_sem);
822 return ret;
825 static int r8192_wx_set_auth(struct net_device *dev,
826 struct iw_request_info *info,
827 union iwreq_data *data, char *extra)
829 int ret = 0;
830 //printk("====>%s()\n", __func__);
831 struct r8192_priv *priv = ieee80211_priv(dev);
832 down(&priv->wx_sem);
833 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
834 up(&priv->wx_sem);
835 return ret;
838 static int r8192_wx_set_mlme(struct net_device *dev,
839 struct iw_request_info *info,
840 union iwreq_data *wrqu, char *extra)
842 //printk("====>%s()\n", __func__);
844 int ret = 0;
845 struct r8192_priv *priv = ieee80211_priv(dev);
846 down(&priv->wx_sem);
847 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
849 up(&priv->wx_sem);
850 return ret;
853 static int r8192_wx_set_gen_ie(struct net_device *dev,
854 struct iw_request_info *info,
855 union iwreq_data *data, char *extra)
857 //printk("====>%s(), len:%d\n", __func__, data->length);
858 int ret = 0;
859 struct r8192_priv *priv = ieee80211_priv(dev);
860 down(&priv->wx_sem);
861 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
862 up(&priv->wx_sem);
863 //printk("<======%s(), ret:%d\n", __func__, ret);
864 return ret;
869 static int dummy(struct net_device *dev, struct iw_request_info *a,
870 union iwreq_data *wrqu, char *b)
872 return -1;
876 static iw_handler r8192_wx_handlers[] = {
877 NULL, /* SIOCSIWCOMMIT */
878 r8192_wx_get_name, /* SIOCGIWNAME */
879 dummy, /* SIOCSIWNWID */
880 dummy, /* SIOCGIWNWID */
881 r8192_wx_set_freq, /* SIOCSIWFREQ */
882 r8192_wx_get_freq, /* SIOCGIWFREQ */
883 r8192_wx_set_mode, /* SIOCSIWMODE */
884 r8192_wx_get_mode, /* SIOCGIWMODE */
885 r8192_wx_set_sens, /* SIOCSIWSENS */
886 r8192_wx_get_sens, /* SIOCGIWSENS */
887 NULL, /* SIOCSIWRANGE */
888 rtl8180_wx_get_range, /* SIOCGIWRANGE */
889 NULL, /* SIOCSIWPRIV */
890 NULL, /* SIOCGIWPRIV */
891 NULL, /* SIOCSIWSTATS */
892 NULL, /* SIOCGIWSTATS */
893 dummy, /* SIOCSIWSPY */
894 dummy, /* SIOCGIWSPY */
895 NULL, /* SIOCGIWTHRSPY */
896 NULL, /* SIOCWIWTHRSPY */
897 r8192_wx_set_wap, /* SIOCSIWAP */
898 r8192_wx_get_wap, /* SIOCGIWAP */
899 r8192_wx_set_mlme, /* MLME-- */
900 dummy, /* SIOCGIWAPLIST -- deprecated */
901 r8192_wx_set_scan, /* SIOCSIWSCAN */
902 r8192_wx_get_scan, /* SIOCGIWSCAN */
903 r8192_wx_set_essid, /* SIOCSIWESSID */
904 r8192_wx_get_essid, /* SIOCGIWESSID */
905 dummy, /* SIOCSIWNICKN */
906 dummy, /* SIOCGIWNICKN */
907 NULL, /* -- hole -- */
908 NULL, /* -- hole -- */
909 r8192_wx_set_rate, /* SIOCSIWRATE */
910 r8192_wx_get_rate, /* SIOCGIWRATE */
911 r8192_wx_set_rts, /* SIOCSIWRTS */
912 r8192_wx_get_rts, /* SIOCGIWRTS */
913 r8192_wx_set_frag, /* SIOCSIWFRAG */
914 r8192_wx_get_frag, /* SIOCGIWFRAG */
915 dummy, /* SIOCSIWTXPOW */
916 dummy, /* SIOCGIWTXPOW */
917 r8192_wx_set_retry, /* SIOCSIWRETRY */
918 r8192_wx_get_retry, /* SIOCGIWRETRY */
919 r8192_wx_set_enc, /* SIOCSIWENCODE */
920 r8192_wx_get_enc, /* SIOCGIWENCODE */
921 r8192_wx_set_power, /* SIOCSIWPOWER */
922 r8192_wx_get_power, /* SIOCGIWPOWER */
923 NULL, /*---hole---*/
924 NULL, /*---hole---*/
925 r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
926 NULL, /* SIOCSIWGENIE */
928 r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
929 NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
930 r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
931 NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
932 NULL, /* SIOCSIWPMKSA */
933 NULL, /*---hole---*/
938 static const struct iw_priv_args r8192_private_args[] = {
941 SIOCIWFIRSTPRIV + 0x0,
942 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
946 SIOCIWFIRSTPRIV + 0x1,
947 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
951 SIOCIWFIRSTPRIV + 0x2,
952 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
955 SIOCIWFIRSTPRIV + 0x3,
956 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
963 static iw_handler r8192_private_handler[] = {
964 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
965 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
966 // r8192_wx_set_forceassociate,
967 // r8192_wx_set_beaconinterval,
968 // r8192_wx_set_monitor_type,
969 r8192_wx_set_scan_type,
970 r8192_wx_set_rawtx,
971 //r8192_wx_null,
972 r8192_wx_force_reset,
975 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
977 struct r8192_priv *priv = ieee80211_priv(dev);
978 struct ieee80211_device *ieee = priv->ieee80211;
979 struct iw_statistics *wstats = &priv->wstats;
980 int tmp_level = 0;
981 int tmp_qual = 0;
982 int tmp_noise = 0;
983 if (ieee->state < IEEE80211_LINKED) {
984 wstats->qual.qual = 0;
985 wstats->qual.level = 0;
986 wstats->qual.noise = 0;
987 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
988 return wstats;
991 tmp_level = (&ieee->current_network)->stats.rssi;
992 tmp_qual = (&ieee->current_network)->stats.signal;
993 tmp_noise = (&ieee->current_network)->stats.noise;
994 //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
996 wstats->qual.level = tmp_level;
997 wstats->qual.qual = tmp_qual;
998 wstats->qual.noise = tmp_noise;
999 wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1000 return wstats;
1004 struct iw_handler_def r8192_wx_handlers_def = {
1005 .standard = r8192_wx_handlers,
1006 .num_standard = ARRAY_SIZE(r8192_wx_handlers),
1007 .private = r8192_private_handler,
1008 .num_private = ARRAY_SIZE(r8192_private_handler),
1009 .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1010 .get_wireless_stats = r8192_get_wireless_stats,
1011 .private_args = (struct iw_priv_args *)r8192_private_args,