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