1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/string.h>
21#include "rtl_core.h"
22
23#define RATE_COUNT 12
24static u32 rtl8192_rates[] = {
25 1000000, 2000000, 5500000, 11000000, 6000000, 9000000, 12000000,
26 18000000, 24000000, 36000000, 48000000, 54000000
27};
28
29#ifndef ENETDOWN
30#define ENETDOWN 1
31#endif
32
33static int r8192_wx_get_freq(struct net_device *dev,
34 struct iw_request_info *a,
35 union iwreq_data *wrqu, char *b)
36{
37 struct r8192_priv *priv = rtllib_priv(dev);
38
39 return rtllib_wx_get_freq(priv->rtllib, a, wrqu, b);
40}
41
42
43static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
44 union iwreq_data *wrqu, char *b)
45{
46 struct r8192_priv *priv = rtllib_priv(dev);
47
48 return rtllib_wx_get_mode(priv->rtllib, a, wrqu, b);
49}
50
51static int r8192_wx_get_rate(struct net_device *dev,
52 struct iw_request_info *info,
53 union iwreq_data *wrqu, char *extra)
54{
55 struct r8192_priv *priv = rtllib_priv(dev);
56 return rtllib_wx_get_rate(priv->rtllib, info, wrqu, extra);
57}
58
59
60
61static int r8192_wx_set_rate(struct net_device *dev,
62 struct iw_request_info *info,
63 union iwreq_data *wrqu, char *extra)
64{
65 int ret;
66 struct r8192_priv *priv = rtllib_priv(dev);
67
68 if (priv->bHwRadioOff == true)
69 return 0;
70
71 down(&priv->wx_sem);
72
73 ret = rtllib_wx_set_rate(priv->rtllib, info, wrqu, extra);
74
75 up(&priv->wx_sem);
76
77 return ret;
78}
79
80
81static int r8192_wx_set_rts(struct net_device *dev,
82 struct iw_request_info *info,
83 union iwreq_data *wrqu, char *extra)
84{
85 int ret;
86 struct r8192_priv *priv = rtllib_priv(dev);
87
88 if (priv->bHwRadioOff == true)
89 return 0;
90
91 down(&priv->wx_sem);
92
93 ret = rtllib_wx_set_rts(priv->rtllib, info, wrqu, extra);
94
95 up(&priv->wx_sem);
96
97 return ret;
98}
99
100static int r8192_wx_get_rts(struct net_device *dev,
101 struct iw_request_info *info,
102 union iwreq_data *wrqu, char *extra)
103{
104 struct r8192_priv *priv = rtllib_priv(dev);
105 return rtllib_wx_get_rts(priv->rtllib, info, wrqu, extra);
106}
107
108static int r8192_wx_set_power(struct net_device *dev,
109 struct iw_request_info *info,
110 union iwreq_data *wrqu, char *extra)
111{
112 int ret;
113 struct r8192_priv *priv = rtllib_priv(dev);
114
115 if (priv->bHwRadioOff == true) {
116 RT_TRACE(COMP_ERR, "%s():Hw is Radio Off, we can't set "
117 "Power,return\n", __func__);
118 return 0;
119 }
120 down(&priv->wx_sem);
121
122 ret = rtllib_wx_set_power(priv->rtllib, info, wrqu, extra);
123
124 up(&priv->wx_sem);
125
126 return ret;
127}
128
129static int r8192_wx_get_power(struct net_device *dev,
130 struct iw_request_info *info,
131 union iwreq_data *wrqu, char *extra)
132{
133 struct r8192_priv *priv = rtllib_priv(dev);
134 return rtllib_wx_get_power(priv->rtllib, info, wrqu, extra);
135}
136
137static int r8192_wx_set_rawtx(struct net_device *dev,
138 struct iw_request_info *info,
139 union iwreq_data *wrqu, char *extra)
140{
141 struct r8192_priv *priv = rtllib_priv(dev);
142 int ret;
143
144 if (priv->bHwRadioOff == true)
145 return 0;
146
147 down(&priv->wx_sem);
148
149 ret = rtllib_wx_set_rawtx(priv->rtllib, info, wrqu, extra);
150
151 up(&priv->wx_sem);
152
153 return ret;
154
155}
156
157static int r8192_wx_force_reset(struct net_device *dev,
158 struct iw_request_info *info,
159 union iwreq_data *wrqu, char *extra)
160{
161 struct r8192_priv *priv = rtllib_priv(dev);
162
163 down(&priv->wx_sem);
164
165 RT_TRACE(COMP_DBG, "%s(): force reset ! extra is %d\n",
166 __func__, *extra);
167 priv->force_reset = *extra;
168 up(&priv->wx_sem);
169 return 0;
170
171}
172
173static int r8192_wx_force_mic_error(struct net_device *dev,
174 struct iw_request_info *info,
175 union iwreq_data *wrqu, char *extra)
176{
177 struct r8192_priv *priv = rtllib_priv(dev);
178 struct rtllib_device *ieee = priv->rtllib;
179
180 down(&priv->wx_sem);
181
182 RT_TRACE(COMP_DBG, "%s(): force mic error !\n", __func__);
183 ieee->force_mic_error = true;
184 up(&priv->wx_sem);
185 return 0;
186
187}
188
189#define MAX_ADHOC_PEER_NUM 64
190struct adhoc_peer_entry {
191 unsigned char MacAddr[ETH_ALEN];
192 unsigned char WirelessMode;
193 unsigned char bCurTxBW40MHz;
194};
195struct adhoc_peers_info {
196 struct adhoc_peer_entry Entry[MAX_ADHOC_PEER_NUM];
197 unsigned char num;
198};
199
200static int r8192_wx_get_adhoc_peers(struct net_device *dev,
201 struct iw_request_info *info,
202 union iwreq_data *wrqu, char *extra)
203{
204 return 0;
205}
206
207
208static int r8191se_wx_get_firm_version(struct net_device *dev,
209 struct iw_request_info *info,
210 struct iw_param *wrqu, char *extra)
211{
212 return 0;
213}
214
215static int r8192_wx_adapter_power_status(struct net_device *dev,
216 struct iw_request_info *info,
217 union iwreq_data *wrqu, char *extra)
218{
219 struct r8192_priv *priv = rtllib_priv(dev);
220 struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *)
221 (&(priv->rtllib->PowerSaveControl));
222 struct rtllib_device *ieee = priv->rtllib;
223
224 down(&priv->wx_sem);
225
226 RT_TRACE(COMP_POWER, "%s(): %s\n", __func__, (*extra == 6) ?
227 "DC power" : "AC power");
228 if (*extra || priv->force_lps) {
229 priv->ps_force = false;
230 pPSC->bLeisurePs = true;
231 } else {
232 if (priv->rtllib->state == RTLLIB_LINKED)
233 LeisurePSLeave(dev);
234
235 priv->ps_force = true;
236 pPSC->bLeisurePs = false;
237 ieee->ps = *extra;
238 }
239
240 up(&priv->wx_sem);
241
242 return 0;
243}
244
245static int r8192se_wx_set_radio(struct net_device *dev,
246 struct iw_request_info *info,
247 union iwreq_data *wrqu, char *extra)
248{
249 struct r8192_priv *priv = rtllib_priv(dev);
250
251 down(&priv->wx_sem);
252
253 printk(KERN_INFO "%s(): set radio ! extra is %d\n", __func__, *extra);
254 if ((*extra != 0) && (*extra != 1)) {
255 RT_TRACE(COMP_ERR, "%s(): set radio an err value,must 0(radio "
256 "off) or 1(radio on)\n", __func__);
257 up(&priv->wx_sem);
258 return -1;
259 }
260 priv->sw_radio_on = *extra;
261 up(&priv->wx_sem);
262 return 0;
263
264}
265
266static int r8192se_wx_set_lps_awake_interval(struct net_device *dev,
267 struct iw_request_info *info,
268 union iwreq_data *wrqu, char *extra)
269{
270 struct r8192_priv *priv = rtllib_priv(dev);
271 struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *)
272 (&(priv->rtllib->PowerSaveControl));
273
274 down(&priv->wx_sem);
275
276 printk(KERN_INFO "%s(): set lps awake interval ! extra is %d\n",
277 __func__, *extra);
278
279 pPSC->RegMaxLPSAwakeIntvl = *extra;
280 up(&priv->wx_sem);
281 return 0;
282}
283
284static int r8192se_wx_set_force_lps(struct net_device *dev,
285 struct iw_request_info *info,
286 union iwreq_data *wrqu, char *extra)
287{
288 struct r8192_priv *priv = rtllib_priv(dev);
289
290 down(&priv->wx_sem);
291
292 printk(KERN_INFO "%s(): force LPS ! extra is %d (1 is open 0 is "
293 "close)\n", __func__, *extra);
294 priv->force_lps = *extra;
295 up(&priv->wx_sem);
296 return 0;
297
298}
299
300static int r8192_wx_set_debugflag(struct net_device *dev,
301 struct iw_request_info *info,
302 union iwreq_data *wrqu, char *extra)
303{
304 struct r8192_priv *priv = rtllib_priv(dev);
305 u8 c = *extra;
306
307 if (priv->bHwRadioOff == true)
308 return 0;
309
310 printk(KERN_INFO "=====>%s(), *extra:%x, debugflag:%x\n", __func__,
311 *extra, rt_global_debug_component);
312 if (c > 0)
313 rt_global_debug_component |= (1<<c);
314 else
315 rt_global_debug_component &= BIT31;
316 return 0;
317}
318
319static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
320 union iwreq_data *wrqu, char *b)
321{
322 struct r8192_priv *priv = rtllib_priv(dev);
323 struct rtllib_device *ieee = netdev_priv_rsl(dev);
324
325 enum rt_rf_power_state rtState;
326 int ret;
327
328 if (priv->bHwRadioOff == true)
329 return 0;
330 rtState = priv->rtllib->eRFPowerState;
331 down(&priv->wx_sem);
332 if (wrqu->mode == IW_MODE_ADHOC || wrqu->mode == IW_MODE_MONITOR ||
333 ieee->bNetPromiscuousMode) {
334 if (priv->rtllib->PowerSaveControl.bInactivePs) {
335 if (rtState == eRfOff) {
336 if (priv->rtllib->RfOffReason >
337 RF_CHANGE_BY_IPS) {
338 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",
339 __func__);
340 up(&priv->wx_sem);
341 return -1;
342 } else {
343 printk(KERN_INFO "=========>%s(): "
344 "IPSLeave\n", __func__);
345 down(&priv->rtllib->ips_sem);
346 IPSLeave(dev);
347 up(&priv->rtllib->ips_sem);
348 }
349 }
350 }
351 }
352 ret = rtllib_wx_set_mode(priv->rtllib, a, wrqu, b);
353
354 up(&priv->wx_sem);
355 return ret;
356}
357
358struct iw_range_with_scan_capa {
359
360 __u32 throughput;
361
362
363
364
365
366
367
368
369 __u32 min_nwid;
370 __u32 max_nwid;
371
372
373 __u16 old_num_channels;
374 __u8 old_num_frequency;
375
376
377 __u8 scan_capa;
378};
379
380static int rtl8192_wx_get_range(struct net_device *dev,
381 struct iw_request_info *info,
382 union iwreq_data *wrqu, char *extra)
383{
384 struct iw_range *range = (struct iw_range *)extra;
385 struct r8192_priv *priv = rtllib_priv(dev);
386 u16 val;
387 int i;
388
389 wrqu->data.length = sizeof(*range);
390 memset(range, 0, sizeof(*range));
391
392
393 range->throughput = 130 * 1000 * 1000;
394
395 if (priv->rf_set_sens != NULL) {
396
397 range->sensitivity = priv->max_sens;
398 }
399
400 range->max_qual.qual = 100;
401 range->max_qual.level = 0;
402 range->max_qual.noise = 0;
403 range->max_qual.updated = 7;
404
405 range->avg_qual.qual = 70;
406 range->avg_qual.level = 0;
407 range->avg_qual.noise = 0;
408 range->avg_qual.updated = 7;
409
410 range->num_bitrates = min(RATE_COUNT, IW_MAX_BITRATES);
411
412 for (i = 0; i < range->num_bitrates; i++)
413 range->bitrate[i] = rtl8192_rates[i];
414
415 range->max_rts = DEFAULT_RTS_THRESHOLD;
416 range->min_frag = MIN_FRAG_THRESHOLD;
417 range->max_frag = MAX_FRAG_THRESHOLD;
418
419 range->min_pmp = 0;
420 range->max_pmp = 5000000;
421 range->min_pmt = 0;
422 range->max_pmt = 65535*1000;
423 range->pmp_flags = IW_POWER_PERIOD;
424 range->pmt_flags = IW_POWER_TIMEOUT;
425 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
426 range->we_version_compiled = WIRELESS_EXT;
427 range->we_version_source = 18;
428
429 for (i = 0, val = 0; i < 14; i++) {
430 if ((priv->rtllib->active_channel_map)[i+1]) {
431 range->freq[val].i = i + 1;
432 range->freq[val].m = rtllib_wlan_frequencies[i] *
433 100000;
434 range->freq[val].e = 1;
435 val++;
436 }
437
438 if (val == IW_MAX_FREQUENCIES)
439 break;
440 }
441 range->num_frequency = val;
442 range->num_channels = val;
443 range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
444 IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
445 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE;
446
447
448
449 return 0;
450}
451
452static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
453 union iwreq_data *wrqu, char *b)
454{
455 struct r8192_priv *priv = rtllib_priv(dev);
456 struct rtllib_device *ieee = priv->rtllib;
457 enum rt_rf_power_state rtState;
458 int ret;
459
460 if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) {
461 if ((ieee->state >= RTLLIB_ASSOCIATING) &&
462 (ieee->state <= RTLLIB_ASSOCIATING_AUTHENTICATED))
463 return 0;
464 if ((priv->rtllib->state == RTLLIB_LINKED) &&
465 (priv->rtllib->CntAfterLink < 2))
466 return 0;
467 }
468
469 if (priv->bHwRadioOff == true) {
470 printk(KERN_INFO "================>%s(): hwradio off\n",
471 __func__);
472 return 0;
473 }
474 rtState = priv->rtllib->eRFPowerState;
475 if (!priv->up)
476 return -ENETDOWN;
477 if (priv->rtllib->LinkDetectInfo.bBusyTraffic == true)
478 return -EAGAIN;
479
480 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
481 struct iw_scan_req *req = (struct iw_scan_req *)b;
482 if (req->essid_len) {
483 ieee->current_network.ssid_len = req->essid_len;
484 memcpy(ieee->current_network.ssid, req->essid,
485 req->essid_len);
486 }
487 }
488
489 down(&priv->wx_sem);
490
491 priv->rtllib->FirstIe_InScan = true;
492
493 if (priv->rtllib->state != RTLLIB_LINKED) {
494 if (priv->rtllib->PowerSaveControl.bInactivePs) {
495 if (rtState == eRfOff) {
496 if (priv->rtllib->RfOffReason >
497 RF_CHANGE_BY_IPS) {
498 RT_TRACE(COMP_ERR, "%s(): RF is "
499 "OFF.\n", __func__);
500 up(&priv->wx_sem);
501 return -1;
502 } else {
503 RT_TRACE(COMP_PS, "=========>%s(): "
504 "IPSLeave\n", __func__);
505 down(&priv->rtllib->ips_sem);
506 IPSLeave(dev);
507 up(&priv->rtllib->ips_sem);
508 }
509 }
510 }
511 rtllib_stop_scan(priv->rtllib);
512 if (priv->rtllib->LedControlHandler)
513 priv->rtllib->LedControlHandler(dev,
514 LED_CTL_SITE_SURVEY);
515
516 if (priv->rtllib->eRFPowerState != eRfOff) {
517 priv->rtllib->actscanning = true;
518
519 if (ieee->ScanOperationBackupHandler)
520 ieee->ScanOperationBackupHandler(ieee->dev,
521 SCAN_OPT_BACKUP);
522
523 rtllib_start_scan_syncro(priv->rtllib, 0);
524
525 if (ieee->ScanOperationBackupHandler)
526 ieee->ScanOperationBackupHandler(ieee->dev,
527 SCAN_OPT_RESTORE);
528 }
529 ret = 0;
530 } else {
531 priv->rtllib->actscanning = true;
532 ret = rtllib_wx_set_scan(priv->rtllib, a, wrqu, b);
533 }
534
535 up(&priv->wx_sem);
536 return ret;
537}
538
539
540static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
541 union iwreq_data *wrqu, char *b)
542{
543
544 int ret;
545 struct r8192_priv *priv = rtllib_priv(dev);
546
547 if (!priv->up)
548 return -ENETDOWN;
549
550 if (priv->bHwRadioOff == true)
551 return 0;
552
553
554 down(&priv->wx_sem);
555
556 ret = rtllib_wx_get_scan(priv->rtllib, a, wrqu, b);
557
558 up(&priv->wx_sem);
559
560 return ret;
561}
562
563static int r8192_wx_set_essid(struct net_device *dev,
564 struct iw_request_info *a,
565 union iwreq_data *wrqu, char *b)
566{
567 struct r8192_priv *priv = rtllib_priv(dev);
568 int ret;
569
570 if ((rtllib_act_scanning(priv->rtllib, false)) &&
571 !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) {
572 ;
573 }
574 if (priv->bHwRadioOff == true) {
575 printk(KERN_INFO "=========>%s():hw radio off,or Rf state is "
576 "eRfOff, return\n", __func__);
577 return 0;
578 }
579 down(&priv->wx_sem);
580 ret = rtllib_wx_set_essid(priv->rtllib, a, wrqu, b);
581
582 up(&priv->wx_sem);
583
584 return ret;
585}
586
587static int r8192_wx_get_essid(struct net_device *dev,
588 struct iw_request_info *a,
589 union iwreq_data *wrqu, char *b)
590{
591 int ret;
592 struct r8192_priv *priv = rtllib_priv(dev);
593
594 down(&priv->wx_sem);
595
596 ret = rtllib_wx_get_essid(priv->rtllib, a, wrqu, b);
597
598 up(&priv->wx_sem);
599
600 return ret;
601}
602
603static int r8192_wx_set_nick(struct net_device *dev,
604 struct iw_request_info *info,
605 union iwreq_data *wrqu, char *extra)
606{
607 struct r8192_priv *priv = rtllib_priv(dev);
608
609 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
610 return -E2BIG;
611 down(&priv->wx_sem);
612 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
613 memset(priv->nick, 0, sizeof(priv->nick));
614 memcpy(priv->nick, extra, wrqu->data.length);
615 up(&priv->wx_sem);
616 return 0;
617
618}
619
620static int r8192_wx_get_nick(struct net_device *dev,
621 struct iw_request_info *info,
622 union iwreq_data *wrqu, char *extra)
623{
624 struct r8192_priv *priv = rtllib_priv(dev);
625
626 down(&priv->wx_sem);
627 wrqu->data.length = strlen(priv->nick);
628 memcpy(extra, priv->nick, wrqu->data.length);
629 wrqu->data.flags = 1;
630 up(&priv->wx_sem);
631 return 0;
632}
633
634static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
635 union iwreq_data *wrqu, char *b)
636{
637 int ret;
638 struct r8192_priv *priv = rtllib_priv(dev);
639
640 if (priv->bHwRadioOff == true)
641 return 0;
642
643 down(&priv->wx_sem);
644
645 ret = rtllib_wx_set_freq(priv->rtllib, a, wrqu, b);
646
647 up(&priv->wx_sem);
648 return ret;
649}
650
651static int r8192_wx_get_name(struct net_device *dev,
652 struct iw_request_info *info,
653 union iwreq_data *wrqu, char *extra)
654{
655 struct r8192_priv *priv = rtllib_priv(dev);
656 return rtllib_wx_get_name(priv->rtllib, info, wrqu, extra);
657}
658
659
660static int r8192_wx_set_frag(struct net_device *dev,
661 struct iw_request_info *info,
662 union iwreq_data *wrqu, char *extra)
663{
664 struct r8192_priv *priv = rtllib_priv(dev);
665
666 if (priv->bHwRadioOff == true)
667 return 0;
668
669 if (wrqu->frag.disabled)
670 priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD;
671 else {
672 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
673 wrqu->frag.value > MAX_FRAG_THRESHOLD)
674 return -EINVAL;
675
676 priv->rtllib->fts = wrqu->frag.value & ~0x1;
677 }
678
679 return 0;
680}
681
682
683static int r8192_wx_get_frag(struct net_device *dev,
684 struct iw_request_info *info,
685 union iwreq_data *wrqu, char *extra)
686{
687 struct r8192_priv *priv = rtllib_priv(dev);
688
689 wrqu->frag.value = priv->rtllib->fts;
690 wrqu->frag.fixed = 0;
691 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
692
693 return 0;
694}
695
696
697static int r8192_wx_set_wap(struct net_device *dev,
698 struct iw_request_info *info,
699 union iwreq_data *awrq,
700 char *extra)
701{
702 int ret;
703 struct r8192_priv *priv = rtllib_priv(dev);
704
705 if ((rtllib_act_scanning(priv->rtllib, false)) &&
706 !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) {
707 ;
708 }
709
710 if (priv->bHwRadioOff == true)
711 return 0;
712
713 down(&priv->wx_sem);
714
715 ret = rtllib_wx_set_wap(priv->rtllib, info, awrq, extra);
716
717 up(&priv->wx_sem);
718
719 return ret;
720
721}
722
723
724static int r8192_wx_get_wap(struct net_device *dev,
725 struct iw_request_info *info,
726 union iwreq_data *wrqu, char *extra)
727{
728 struct r8192_priv *priv = rtllib_priv(dev);
729
730 return rtllib_wx_get_wap(priv->rtllib, info, wrqu, extra);
731}
732
733
734static int r8192_wx_get_enc(struct net_device *dev,
735 struct iw_request_info *info,
736 union iwreq_data *wrqu, char *key)
737{
738 struct r8192_priv *priv = rtllib_priv(dev);
739
740 return rtllib_wx_get_encode(priv->rtllib, info, wrqu, key);
741}
742
743static int r8192_wx_set_enc(struct net_device *dev,
744 struct iw_request_info *info,
745 union iwreq_data *wrqu, char *key)
746{
747 struct r8192_priv *priv = rtllib_priv(dev);
748 int ret;
749
750 struct rtllib_device *ieee = priv->rtllib;
751 u32 hwkey[4] = {0, 0, 0, 0};
752 u8 mask = 0xff;
753 u32 key_idx = 0;
754 u8 zero_addr[4][6] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
755 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
756 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
757 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} };
758 int i;
759
760 if ((rtllib_act_scanning(priv->rtllib, false)) &&
761 !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN))
762 ;
763 if (priv->bHwRadioOff == true)
764 return 0;
765
766 if (!priv->up)
767 return -ENETDOWN;
768
769 priv->rtllib->wx_set_enc = 1;
770 down(&priv->rtllib->ips_sem);
771 IPSLeave(dev);
772 up(&priv->rtllib->ips_sem);
773 down(&priv->wx_sem);
774
775 RT_TRACE(COMP_SEC, "Setting SW wep key");
776 ret = rtllib_wx_set_encode(priv->rtllib, info, wrqu, key);
777 up(&priv->wx_sem);
778
779
780 if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
781 ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
782 CamResetAllEntry(dev);
783 memset(priv->rtllib->swcamtable, 0,
784 sizeof(struct sw_cam_table) * 32);
785 goto end_hw_sec;
786 }
787 if (wrqu->encoding.length != 0) {
788
789 for (i = 0; i < 4; i++) {
790 hwkey[i] |= key[4*i+0]&mask;
791 if (i == 1 && (4 * i + 1) == wrqu->encoding.length)
792 mask = 0x00;
793 if (i == 3 && (4 * i + 1) == wrqu->encoding.length)
794 mask = 0x00;
795 hwkey[i] |= (key[4 * i + 1] & mask) << 8;
796 hwkey[i] |= (key[4 * i + 2] & mask) << 16;
797 hwkey[i] |= (key[4 * i + 3] & mask) << 24;
798 }
799
800 #define CONF_WEP40 0x4
801 #define CONF_WEP104 0x14
802
803 switch (wrqu->encoding.flags & IW_ENCODE_INDEX) {
804 case 0:
805 key_idx = ieee->crypt_info.tx_keyidx;
806 break;
807 case 1:
808 key_idx = 0;
809 break;
810 case 2:
811 key_idx = 1;
812 break;
813 case 3:
814 key_idx = 2;
815 break;
816 case 4:
817 key_idx = 3;
818 break;
819 default:
820 break;
821 }
822 if (wrqu->encoding.length == 0x5) {
823 ieee->pairwise_key_type = KEY_TYPE_WEP40;
824 EnableHWSecurityConfig8192(dev);
825 }
826
827 else if (wrqu->encoding.length == 0xd) {
828 ieee->pairwise_key_type = KEY_TYPE_WEP104;
829 EnableHWSecurityConfig8192(dev);
830 setKey(dev, key_idx, key_idx, KEY_TYPE_WEP104,
831 zero_addr[key_idx], 0, hwkey);
832 set_swcam(dev, key_idx, key_idx, KEY_TYPE_WEP104,
833 zero_addr[key_idx], 0, hwkey, 0);
834 } else {
835 printk(KERN_INFO "wrong type in WEP, not WEP40 and WEP104\n");
836 }
837 }
838
839end_hw_sec:
840 priv->rtllib->wx_set_enc = 0;
841 return ret;
842}
843
844static int r8192_wx_set_scan_type(struct net_device *dev,
845 struct iw_request_info *aa,
846 union iwreq_data *wrqu, char *p)
847{
848 struct r8192_priv *priv = rtllib_priv(dev);
849 int *parms = (int *)p;
850 int mode = parms[0];
851
852 if (priv->bHwRadioOff == true)
853 return 0;
854
855 priv->rtllib->active_scan = mode;
856
857 return 1;
858}
859
860
861
862#define R8192_MAX_RETRY 255
863static int r8192_wx_set_retry(struct net_device *dev,
864 struct iw_request_info *info,
865 union iwreq_data *wrqu, char *extra)
866{
867 struct r8192_priv *priv = rtllib_priv(dev);
868 int err = 0;
869
870 if (priv->bHwRadioOff == true)
871 return 0;
872
873 down(&priv->wx_sem);
874
875 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
876 wrqu->retry.disabled) {
877 err = -EINVAL;
878 goto exit;
879 }
880 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
881 err = -EINVAL;
882 goto exit;
883 }
884
885 if (wrqu->retry.value > R8192_MAX_RETRY) {
886 err = -EINVAL;
887 goto exit;
888 }
889 if (wrqu->retry.flags & IW_RETRY_MAX) {
890 priv->retry_rts = wrqu->retry.value;
891 DMESG("Setting retry for RTS/CTS data to %d",
892 wrqu->retry.value);
893
894 } else {
895 priv->retry_data = wrqu->retry.value;
896 DMESG("Setting retry for non RTS/CTS data to %d",
897 wrqu->retry.value);
898 }
899
900
901 rtl8192_commit(dev);
902exit:
903 up(&priv->wx_sem);
904
905 return err;
906}
907
908static int r8192_wx_get_retry(struct net_device *dev,
909 struct iw_request_info *info,
910 union iwreq_data *wrqu, char *extra)
911{
912 struct r8192_priv *priv = rtllib_priv(dev);
913
914
915 wrqu->retry.disabled = 0;
916
917 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
918 IW_RETRY_LIFETIME)
919 return -EINVAL;
920
921 if (wrqu->retry.flags & IW_RETRY_MAX) {
922 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
923 wrqu->retry.value = priv->retry_rts;
924 } else {
925 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
926 wrqu->retry.value = priv->retry_data;
927 }
928 return 0;
929}
930
931static int r8192_wx_get_sens(struct net_device *dev,
932 struct iw_request_info *info,
933 union iwreq_data *wrqu, char *extra)
934{
935 struct r8192_priv *priv = rtllib_priv(dev);
936 if (priv->rf_set_sens == NULL)
937 return -1;
938 wrqu->sens.value = priv->sens;
939 return 0;
940}
941
942
943static int r8192_wx_set_sens(struct net_device *dev,
944 struct iw_request_info *info,
945 union iwreq_data *wrqu, char *extra)
946{
947
948 struct r8192_priv *priv = rtllib_priv(dev);
949
950 short err = 0;
951
952 if (priv->bHwRadioOff == true)
953 return 0;
954
955 down(&priv->wx_sem);
956 if (priv->rf_set_sens == NULL) {
957 err = -1;
958 goto exit;
959 }
960 if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
961 priv->sens = wrqu->sens.value;
962 else
963 err = -EINVAL;
964
965exit:
966 up(&priv->wx_sem);
967
968 return err;
969}
970
971static int r8192_wx_set_enc_ext(struct net_device *dev,
972 struct iw_request_info *info,
973 union iwreq_data *wrqu, char *extra)
974{
975 int ret = 0;
976 struct r8192_priv *priv = rtllib_priv(dev);
977 struct rtllib_device *ieee = priv->rtllib;
978
979 if (priv->bHwRadioOff == true)
980 return 0;
981
982 down(&priv->wx_sem);
983
984 priv->rtllib->wx_set_enc = 1;
985 down(&priv->rtllib->ips_sem);
986 IPSLeave(dev);
987 up(&priv->rtllib->ips_sem);
988
989 ret = rtllib_wx_set_encode_ext(ieee, info, wrqu, extra);
990 {
991 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
992 u8 zero[6] = {0};
993 u32 key[4] = {0};
994 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
995 struct iw_point *encoding = &wrqu->encoding;
996 u8 idx = 0, alg = 0, group = 0;
997 if ((encoding->flags & IW_ENCODE_DISABLED) ||
998 ext->alg == IW_ENCODE_ALG_NONE) {
999 ieee->pairwise_key_type = ieee->group_key_type
1000 = KEY_TYPE_NA;
1001 CamResetAllEntry(dev);
1002 memset(priv->rtllib->swcamtable, 0,
1003 sizeof(struct sw_cam_table) * 32);
1004 goto end_hw_sec;
1005 }
1006 alg = (ext->alg == IW_ENCODE_ALG_CCMP) ? KEY_TYPE_CCMP :
1007 ext->alg;
1008 idx = encoding->flags & IW_ENCODE_INDEX;
1009 if (idx)
1010 idx--;
1011 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
1012
1013 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) ||
1014 (alg == KEY_TYPE_WEP40)) {
1015 if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
1016 alg = KEY_TYPE_WEP104;
1017 ieee->pairwise_key_type = alg;
1018 EnableHWSecurityConfig8192(dev);
1019 }
1020 memcpy((u8 *)key, ext->key, 16);
1021
1022 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
1023 if (ext->key_len == 13)
1024 ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
1025 setKey(dev, idx, idx, alg, zero, 0, key);
1026 set_swcam(dev, idx, idx, alg, zero, 0, key, 0);
1027 } else if (group) {
1028 ieee->group_key_type = alg;
1029 setKey(dev, idx, idx, alg, broadcast_addr, 0, key);
1030 set_swcam(dev, idx, idx, alg, broadcast_addr, 0,
1031 key, 0);
1032 } else {
1033 if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) &&
1034 ieee->pHTInfo->bCurrentHTSupport)
1035 write_nic_byte(dev, 0x173, 1);
1036 setKey(dev, 4, idx, alg, (u8 *)ieee->ap_mac_addr,
1037 0, key);
1038 set_swcam(dev, 4, idx, alg, (u8 *)ieee->ap_mac_addr,
1039 0, key, 0);
1040 }
1041
1042
1043 }
1044
1045end_hw_sec:
1046 priv->rtllib->wx_set_enc = 0;
1047 up(&priv->wx_sem);
1048 return ret;
1049
1050}
1051static int r8192_wx_set_auth(struct net_device *dev,
1052 struct iw_request_info *info,
1053 union iwreq_data *data, char *extra)
1054{
1055 int ret = 0;
1056
1057 struct r8192_priv *priv = rtllib_priv(dev);
1058
1059 if (priv->bHwRadioOff == true)
1060 return 0;
1061
1062 down(&priv->wx_sem);
1063 ret = rtllib_wx_set_auth(priv->rtllib, info, &(data->param), extra);
1064 up(&priv->wx_sem);
1065 return ret;
1066}
1067
1068static int r8192_wx_set_mlme(struct net_device *dev,
1069 struct iw_request_info *info,
1070 union iwreq_data *wrqu, char *extra)
1071{
1072
1073 int ret = 0;
1074
1075 struct r8192_priv *priv = rtllib_priv(dev);
1076
1077 if (priv->bHwRadioOff == true)
1078 return 0;
1079
1080 down(&priv->wx_sem);
1081 ret = rtllib_wx_set_mlme(priv->rtllib, info, wrqu, extra);
1082 up(&priv->wx_sem);
1083 return ret;
1084}
1085
1086static int r8192_wx_set_gen_ie(struct net_device *dev,
1087 struct iw_request_info *info,
1088 union iwreq_data *data, char *extra)
1089{
1090 int ret = 0;
1091
1092 struct r8192_priv *priv = rtllib_priv(dev);
1093
1094 if (priv->bHwRadioOff == true)
1095 return 0;
1096
1097 down(&priv->wx_sem);
1098 ret = rtllib_wx_set_gen_ie(priv->rtllib, extra, data->data.length);
1099 up(&priv->wx_sem);
1100 return ret;
1101}
1102
1103static int r8192_wx_get_gen_ie(struct net_device *dev,
1104 struct iw_request_info *info,
1105 union iwreq_data *data, char *extra)
1106{
1107 int ret = 0;
1108 struct r8192_priv *priv = rtllib_priv(dev);
1109 struct rtllib_device *ieee = priv->rtllib;
1110
1111 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
1112 data->data.length = 0;
1113 return 0;
1114 }
1115
1116 if (data->data.length < ieee->wpa_ie_len)
1117 return -E2BIG;
1118
1119 data->data.length = ieee->wpa_ie_len;
1120 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
1121 return ret;
1122}
1123
1124#define OID_RT_INTEL_PROMISCUOUS_MODE 0xFF0101F6
1125
1126static int r8192_wx_set_PromiscuousMode(struct net_device *dev,
1127 struct iw_request_info *info,
1128 union iwreq_data *wrqu, char *extra)
1129{
1130 struct r8192_priv *priv = rtllib_priv(dev);
1131 struct rtllib_device *ieee = priv->rtllib;
1132
1133 u32 *info_buf = (u32 *)(wrqu->data.pointer);
1134
1135 u32 oid = info_buf[0];
1136 u32 bPromiscuousOn = info_buf[1];
1137 u32 bFilterSourceStationFrame = info_buf[2];
1138
1139 if (OID_RT_INTEL_PROMISCUOUS_MODE == oid) {
1140 ieee->IntelPromiscuousModeInfo.bPromiscuousOn =
1141 (bPromiscuousOn) ? (true) : (false);
1142 ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame =
1143 (bFilterSourceStationFrame) ? (true) : (false);
1144 (bPromiscuousOn) ?
1145 (rtllib_EnableIntelPromiscuousMode(dev, false)) :
1146 (rtllib_DisableIntelPromiscuousMode(dev, false));
1147
1148 printk(KERN_INFO "=======>%s(), on = %d, filter src sta = %d\n",
1149 __func__, bPromiscuousOn, bFilterSourceStationFrame);
1150 } else {
1151 return -1;
1152 }
1153
1154 return 0;
1155}
1156
1157
1158static int r8192_wx_get_PromiscuousMode(struct net_device *dev,
1159 struct iw_request_info *info,
1160 union iwreq_data *wrqu, char *extra)
1161{
1162 struct r8192_priv *priv = rtllib_priv(dev);
1163 struct rtllib_device *ieee = priv->rtllib;
1164
1165 down(&priv->wx_sem);
1166
1167 snprintf(extra, 45, "PromiscuousMode:%d, FilterSrcSTAFrame:%d",
1168 ieee->IntelPromiscuousModeInfo.bPromiscuousOn,
1169 ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame);
1170 wrqu->data.length = strlen(extra) + 1;
1171
1172 up(&priv->wx_sem);
1173
1174 return 0;
1175}
1176
1177
1178#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
1179static iw_handler r8192_wx_handlers[] = {
1180 IW_IOCTL(SIOCGIWNAME) = r8192_wx_get_name,
1181 IW_IOCTL(SIOCSIWFREQ) = r8192_wx_set_freq,
1182 IW_IOCTL(SIOCGIWFREQ) = r8192_wx_get_freq,
1183 IW_IOCTL(SIOCSIWMODE) = r8192_wx_set_mode,
1184 IW_IOCTL(SIOCGIWMODE) = r8192_wx_get_mode,
1185 IW_IOCTL(SIOCSIWSENS) = r8192_wx_set_sens,
1186 IW_IOCTL(SIOCGIWSENS) = r8192_wx_get_sens,
1187 IW_IOCTL(SIOCGIWRANGE) = rtl8192_wx_get_range,
1188 IW_IOCTL(SIOCSIWAP) = r8192_wx_set_wap,
1189 IW_IOCTL(SIOCGIWAP) = r8192_wx_get_wap,
1190 IW_IOCTL(SIOCSIWSCAN) = r8192_wx_set_scan,
1191 IW_IOCTL(SIOCGIWSCAN) = r8192_wx_get_scan,
1192 IW_IOCTL(SIOCSIWESSID) = r8192_wx_set_essid,
1193 IW_IOCTL(SIOCGIWESSID) = r8192_wx_get_essid,
1194 IW_IOCTL(SIOCSIWNICKN) = r8192_wx_set_nick,
1195 IW_IOCTL(SIOCGIWNICKN) = r8192_wx_get_nick,
1196 IW_IOCTL(SIOCSIWRATE) = r8192_wx_set_rate,
1197 IW_IOCTL(SIOCGIWRATE) = r8192_wx_get_rate,
1198 IW_IOCTL(SIOCSIWRTS) = r8192_wx_set_rts,
1199 IW_IOCTL(SIOCGIWRTS) = r8192_wx_get_rts,
1200 IW_IOCTL(SIOCSIWFRAG) = r8192_wx_set_frag,
1201 IW_IOCTL(SIOCGIWFRAG) = r8192_wx_get_frag,
1202 IW_IOCTL(SIOCSIWRETRY) = r8192_wx_set_retry,
1203 IW_IOCTL(SIOCGIWRETRY) = r8192_wx_get_retry,
1204 IW_IOCTL(SIOCSIWENCODE) = r8192_wx_set_enc,
1205 IW_IOCTL(SIOCGIWENCODE) = r8192_wx_get_enc,
1206 IW_IOCTL(SIOCSIWPOWER) = r8192_wx_set_power,
1207 IW_IOCTL(SIOCGIWPOWER) = r8192_wx_get_power,
1208 IW_IOCTL(SIOCSIWGENIE) = r8192_wx_set_gen_ie,
1209 IW_IOCTL(SIOCGIWGENIE) = r8192_wx_get_gen_ie,
1210 IW_IOCTL(SIOCSIWMLME) = r8192_wx_set_mlme,
1211 IW_IOCTL(SIOCSIWAUTH) = r8192_wx_set_auth,
1212 IW_IOCTL(SIOCSIWENCODEEXT) = r8192_wx_set_enc_ext,
1213};
1214
1215
1216
1217
1218
1219
1220static const struct iw_priv_args r8192_private_args[] = {
1221 {
1222 SIOCIWFIRSTPRIV + 0x0,
1223 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_debugflag"
1224 }, {
1225 SIOCIWFIRSTPRIV + 0x1,
1226 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1227 }, {
1228 SIOCIWFIRSTPRIV + 0x2,
1229 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1230 }, {
1231 SIOCIWFIRSTPRIV + 0x3,
1232 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1233 }, {
1234 SIOCIWFIRSTPRIV + 0x4,
1235 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "force_mic_error"
1236 }, {
1237 SIOCIWFIRSTPRIV + 0x5,
1238 IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT|IW_PRIV_SIZE_FIXED|1,
1239 "firm_ver"
1240 }, {
1241 SIOCIWFIRSTPRIV + 0x6,
1242 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1243 "set_power"
1244 }, {
1245 SIOCIWFIRSTPRIV + 0x9,
1246 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1247 "radio"
1248 }, {
1249 SIOCIWFIRSTPRIV + 0xa,
1250 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1251 "lps_interv"
1252 }, {
1253 SIOCIWFIRSTPRIV + 0xb,
1254 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1255 "lps_force"
1256 }, {
1257 SIOCIWFIRSTPRIV + 0xc,
1258 0, IW_PRIV_TYPE_CHAR|2047, "adhoc_peer_list"
1259 }, {
1260 SIOCIWFIRSTPRIV + 0x16,
1261 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setpromisc"
1262 }, {
1263 SIOCIWFIRSTPRIV + 0x17,
1264 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 45, "getpromisc"
1265 }
1266
1267};
1268
1269static iw_handler r8192_private_handler[] = {
1270 (iw_handler)r8192_wx_set_debugflag,
1271 (iw_handler)r8192_wx_set_scan_type,
1272 (iw_handler)r8192_wx_set_rawtx,
1273 (iw_handler)r8192_wx_force_reset,
1274 (iw_handler)r8192_wx_force_mic_error,
1275 (iw_handler)r8191se_wx_get_firm_version,
1276 (iw_handler)r8192_wx_adapter_power_status,
1277 (iw_handler)NULL,
1278 (iw_handler)NULL,
1279 (iw_handler)r8192se_wx_set_radio,
1280 (iw_handler)r8192se_wx_set_lps_awake_interval,
1281 (iw_handler)r8192se_wx_set_force_lps,
1282 (iw_handler)r8192_wx_get_adhoc_peers,
1283 (iw_handler)NULL,
1284 (iw_handler)NULL,
1285 (iw_handler)NULL,
1286 (iw_handler)NULL,
1287 (iw_handler)NULL,
1288 (iw_handler)NULL,
1289 (iw_handler)NULL,
1290 (iw_handler)NULL,
1291 (iw_handler)NULL,
1292 (iw_handler)r8192_wx_set_PromiscuousMode,
1293 (iw_handler)r8192_wx_get_PromiscuousMode,
1294};
1295
1296static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
1297{
1298 struct r8192_priv *priv = rtllib_priv(dev);
1299 struct rtllib_device *ieee = priv->rtllib;
1300 struct iw_statistics *wstats = &priv->wstats;
1301 int tmp_level = 0;
1302 int tmp_qual = 0;
1303 int tmp_noise = 0;
1304 if (ieee->state < RTLLIB_LINKED) {
1305 wstats->qual.qual = 10;
1306 wstats->qual.level = 0;
1307 wstats->qual.noise = -100;
1308 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1309 return wstats;
1310 }
1311
1312 tmp_level = (&ieee->current_network)->stats.rssi;
1313 tmp_qual = (&ieee->current_network)->stats.signal;
1314 tmp_noise = (&ieee->current_network)->stats.noise;
1315
1316 wstats->qual.level = tmp_level;
1317 wstats->qual.qual = tmp_qual;
1318 wstats->qual.noise = tmp_noise;
1319 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1320 return wstats;
1321}
1322
1323struct iw_handler_def r8192_wx_handlers_def = {
1324 .standard = r8192_wx_handlers,
1325 .num_standard = ARRAY_SIZE(r8192_wx_handlers),
1326 .private = r8192_private_handler,
1327 .num_private = ARRAY_SIZE(r8192_private_handler),
1328 .num_private_args = sizeof(r8192_private_args) /
1329 sizeof(struct iw_priv_args),
1330 .get_wireless_stats = r8192_get_wireless_stats,
1331 .private_args = (struct iw_priv_args *)r8192_private_args,
1332};
1333