]> Git Repo - linux.git/blob - drivers/staging/rtl8192u/r8192U_wx.c
selinux: Remove security_ops extern
[linux.git] / drivers / staging / rtl8192u / r8192U_wx.c
1 /*
2    This file contains wireless extension handlers.
3
4    This is part of rtl8180 OpenSource driver.
5    Copyright (C) Andrea Merello 2004-2005  <[email protected]>
6    Released under the terms of GPL (General Public Licence)
7
8    Parts of this driver are based on the GPL part
9    of the official realtek driver.
10
11    Parts of this driver are based on the rtl8180 driver skeleton
12    from Patric Schenke & Andres Salomon.
13
14    Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
15
16    We want to thank the Authors of those projects and the Ndiswrapper
17    project Authors.
18 */
19
20 #include <linux/string.h>
21 #include "r8192U.h"
22 #include "r8192U_hw.h"
23
24 #include "dot11d.h"
25
26 #define RATE_COUNT 12
27 u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
28         6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
29
30
31 #ifndef ENETDOWN
32 #define ENETDOWN 1
33 #endif
34
35 static int r8192_wx_get_freq(struct net_device *dev,
36                              struct iw_request_info *a,
37                              union iwreq_data *wrqu, char *b)
38 {
39         struct r8192_priv *priv = ieee80211_priv(dev);
40
41         return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
42 }
43
44
45 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
46                              union iwreq_data *wrqu, char *b)
47 {
48         struct r8192_priv *priv = ieee80211_priv(dev);
49
50         return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
51 }
52
53
54
55 static int r8192_wx_get_rate(struct net_device *dev,
56                              struct iw_request_info *info,
57                              union iwreq_data *wrqu, char *extra)
58 {
59         struct r8192_priv *priv = ieee80211_priv(dev);
60         return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
61 }
62
63
64
65 static int r8192_wx_set_rate(struct net_device *dev,
66                              struct iw_request_info *info,
67                              union iwreq_data *wrqu, char *extra)
68 {
69         int ret;
70         struct r8192_priv *priv = ieee80211_priv(dev);
71
72         down(&priv->wx_sem);
73
74         ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
75
76         up(&priv->wx_sem);
77
78         return ret;
79 }
80
81
82 static int r8192_wx_set_rts(struct net_device *dev,
83                              struct iw_request_info *info,
84                              union iwreq_data *wrqu, char *extra)
85 {
86         int ret;
87         struct r8192_priv *priv = ieee80211_priv(dev);
88
89         down(&priv->wx_sem);
90
91         ret = ieee80211_wx_set_rts(priv->ieee80211, info, wrqu, extra);
92
93         up(&priv->wx_sem);
94
95         return ret;
96 }
97
98 static int r8192_wx_get_rts(struct net_device *dev,
99                              struct iw_request_info *info,
100                              union iwreq_data *wrqu, char *extra)
101 {
102         struct r8192_priv *priv = ieee80211_priv(dev);
103         return ieee80211_wx_get_rts(priv->ieee80211, info, wrqu, extra);
104 }
105
106 static int r8192_wx_set_power(struct net_device *dev,
107                              struct iw_request_info *info,
108                              union iwreq_data *wrqu, char *extra)
109 {
110         int ret;
111         struct r8192_priv *priv = ieee80211_priv(dev);
112
113         down(&priv->wx_sem);
114
115         ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
116
117         up(&priv->wx_sem);
118
119         return ret;
120 }
121
122 static int r8192_wx_get_power(struct net_device *dev,
123                              struct iw_request_info *info,
124                              union iwreq_data *wrqu, char *extra)
125 {
126         struct r8192_priv *priv = ieee80211_priv(dev);
127         return ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
128 }
129
130 static int r8192_wx_force_reset(struct net_device *dev,
131                 struct iw_request_info *info,
132                 union iwreq_data *wrqu, char *extra)
133 {
134         struct r8192_priv *priv = ieee80211_priv(dev);
135
136         down(&priv->wx_sem);
137
138         printk("%s(): force reset ! extra is %d\n", __func__, *extra);
139         priv->force_reset = *extra;
140         up(&priv->wx_sem);
141         return 0;
142
143 }
144
145
146 static int r8192_wx_set_rawtx(struct net_device *dev,
147                                struct iw_request_info *info,
148                                union iwreq_data *wrqu, char *extra)
149 {
150         struct r8192_priv *priv = ieee80211_priv(dev);
151         int ret;
152
153         down(&priv->wx_sem);
154
155         ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
156
157         up(&priv->wx_sem);
158
159         return ret;
160
161 }
162
163 static int r8192_wx_set_crcmon(struct net_device *dev,
164                                struct iw_request_info *info,
165                                union iwreq_data *wrqu, char *extra)
166 {
167         struct r8192_priv *priv = ieee80211_priv(dev);
168         int *parms = (int *)extra;
169         int enable = (parms[0] > 0);
170         short prev = priv->crcmon;
171
172         down(&priv->wx_sem);
173
174         if (enable)
175                 priv->crcmon = 1;
176         else
177                 priv->crcmon = 0;
178
179         DMESG("bad CRC in monitor mode are %s",
180               priv->crcmon ? "accepted" : "rejected");
181
182         if (prev != priv->crcmon && priv->up) {
183                 //rtl8180_down(dev);
184                 //rtl8180_up(dev);
185         }
186
187         up(&priv->wx_sem);
188
189         return 0;
190 }
191
192 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
193                              union iwreq_data *wrqu, char *b)
194 {
195         struct r8192_priv *priv = ieee80211_priv(dev);
196         int ret;
197         down(&priv->wx_sem);
198
199         ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
200
201         rtl8192_set_rxconf(dev);
202
203         up(&priv->wx_sem);
204         return ret;
205 }
206
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...
215          */
216
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 */
220
221         /* Old Frequency (backward compat - moved lower ) */
222         __u16           old_num_channels;
223         __u8            old_num_frequency;
224
225         /* Scan capabilities */
226         __u8            scan_capa;
227 };
228 static int rtl8180_wx_get_range(struct net_device *dev,
229                                 struct iw_request_info *info,
230                                 union iwreq_data *wrqu, char *extra)
231 {
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;
237
238         wrqu->data.length = sizeof(*range);
239         memset(range, 0, sizeof(*range));
240
241         /* Let's try to keep this struct in the same order as in
242          * linux/include/wireless.h
243          */
244
245         /* TODO: See what values we can set, and remove the ones we can't
246          * set, or fill them with some default data.
247          */
248
249         /* ~5 Mb/s real (802.11b) */
250         range->throughput = 5 * 1000 * 1000;
251
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 */
256
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 */
263
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 */
269
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 */
275
276         range->num_bitrates = RATE_COUNT;
277
278         for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
279                 range->bitrate[i] = rtl8180_rates[i];
280
281         range->min_frag = MIN_FRAG_THRESHOLD;
282         range->max_frag = MAX_FRAG_THRESHOLD;
283
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;
291
292         range->we_version_compiled = WIRELESS_EXT;
293         range->we_version_source = 16;
294
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 */
302
303
304         for (i = 0, val = 0; i < 14; i++) {
305
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 ?
315                 }
316
317                 if (val == IW_MAX_FREQUENCIES)
318                         break;
319         }
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;
326 }
327
328
329 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
330                              union iwreq_data *wrqu, char *b)
331 {
332         struct r8192_priv *priv = ieee80211_priv(dev);
333         struct ieee80211_device *ieee = priv->ieee80211;
334         int ret = 0;
335
336         if (!priv->up)
337                 return -ENETDOWN;
338
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);
348                 }
349         }
350
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);
358         }
359         up(&priv->wx_sem);
360         return ret;
361 }
362
363
364 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
365                              union iwreq_data *wrqu, char *b)
366 {
367
368         int ret;
369         struct r8192_priv *priv = ieee80211_priv(dev);
370
371         if (!priv->up)
372                 return -ENETDOWN;
373
374         down(&priv->wx_sem);
375
376         ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
377
378         up(&priv->wx_sem);
379
380         return ret;
381 }
382
383 static int r8192_wx_set_essid(struct net_device *dev,
384                               struct iw_request_info *a,
385                               union iwreq_data *wrqu, char *b)
386 {
387         struct r8192_priv *priv = ieee80211_priv(dev);
388         int ret;
389         down(&priv->wx_sem);
390
391         ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
392
393         up(&priv->wx_sem);
394
395         return ret;
396 }
397
398
399
400
401 static int r8192_wx_get_essid(struct net_device *dev,
402                               struct iw_request_info *a,
403                               union iwreq_data *wrqu, char *b)
404 {
405         int ret;
406         struct r8192_priv *priv = ieee80211_priv(dev);
407
408         down(&priv->wx_sem);
409
410         ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
411
412         up(&priv->wx_sem);
413
414         return ret;
415 }
416
417
418 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
419                              union iwreq_data *wrqu, char *b)
420 {
421         int ret;
422         struct r8192_priv *priv = ieee80211_priv(dev);
423
424         down(&priv->wx_sem);
425
426         ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
427
428         up(&priv->wx_sem);
429         return ret;
430 }
431
432 static int r8192_wx_get_name(struct net_device *dev,
433                              struct iw_request_info *info,
434                              union iwreq_data *wrqu, char *extra)
435 {
436         struct r8192_priv *priv = ieee80211_priv(dev);
437         return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
438 }
439
440
441 static int r8192_wx_set_frag(struct net_device *dev,
442                              struct iw_request_info *info,
443                              union iwreq_data *wrqu, char *extra)
444 {
445         struct r8192_priv *priv = ieee80211_priv(dev);
446
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;
453
454                 priv->ieee80211->fts = wrqu->frag.value & ~0x1;
455         }
456
457         return 0;
458 }
459
460
461 static int r8192_wx_get_frag(struct net_device *dev,
462                              struct iw_request_info *info,
463                              union iwreq_data *wrqu, char *extra)
464 {
465         struct r8192_priv *priv = ieee80211_priv(dev);
466
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);
470
471         return 0;
472 }
473
474
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)
479 {
480
481         int ret;
482         struct r8192_priv *priv = ieee80211_priv(dev);
483 //        struct sockaddr *temp = (struct sockaddr *)awrq;
484         down(&priv->wx_sem);
485
486         ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
487
488         up(&priv->wx_sem);
489
490         return ret;
491
492 }
493
494
495 static int r8192_wx_get_wap(struct net_device *dev,
496                             struct iw_request_info *info,
497                             union iwreq_data *wrqu, char *extra)
498 {
499         struct r8192_priv *priv = ieee80211_priv(dev);
500
501         return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
502 }
503
504
505 static int r8192_wx_get_enc(struct net_device *dev,
506                             struct iw_request_info *info,
507                             union iwreq_data *wrqu, char *key)
508 {
509         struct r8192_priv *priv = ieee80211_priv(dev);
510
511         return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
512 }
513
514 static int r8192_wx_set_enc(struct net_device *dev,
515                             struct iw_request_info *info,
516                             union iwreq_data *wrqu, char *key)
517 {
518         struct r8192_priv *priv = ieee80211_priv(dev);
519         struct ieee80211_device *ieee = priv->ieee80211;
520         int ret;
521
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;
532
533         if (!priv->up)
534                 return -ENETDOWN;
535
536         down(&priv->wx_sem);
537
538         RT_TRACE(COMP_SEC, "Setting SW wep key");
539         ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
540
541         up(&priv->wx_sem);
542
543
544
545         //sometimes, the length is zero while we do not type key value
546         if (wrqu->encoding.length != 0) {
547
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;
557                 }
558
559                 #define CONF_WEP40  0x4
560                 #define CONF_WEP104 0x14
561
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;
580                 }
581
582                 if (wrqu->encoding.length == 0x5) {
583                                 ieee->pairwise_key_type = KEY_TYPE_WEP40;
584                         EnableHWSecurityConfig8192(dev);
585
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
593
594                 }
595
596                 else if (wrqu->encoding.length == 0xd) {
597                                 ieee->pairwise_key_type = KEY_TYPE_WEP104;
598                                 EnableHWSecurityConfig8192(dev);
599
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
607
608                 } else {
609                         printk("wrong type in WEP, not WEP40 and WEP104\n");
610                 }
611
612         }
613
614         return ret;
615 }
616
617
618 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa,
619                                         union iwreq_data *wrqu, char *p)
620 {
621
622         struct r8192_priv *priv = ieee80211_priv(dev);
623         int *parms = (int *)p;
624         int mode = parms[0];
625
626         priv->ieee80211->active_scan = mode;
627
628         return 1;
629 }
630
631
632
633 static int r8192_wx_set_retry(struct net_device *dev,
634                                 struct iw_request_info *info,
635                                 union iwreq_data *wrqu, char *extra)
636 {
637         struct r8192_priv *priv = ieee80211_priv(dev);
638         int err = 0;
639
640         down(&priv->wx_sem);
641
642         if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
643             wrqu->retry.disabled){
644                 err = -EINVAL;
645                 goto exit;
646         }
647         if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
648                 err = -EINVAL;
649                 goto exit;
650         }
651
652         if (wrqu->retry.value > R8180_MAX_RETRY) {
653                 err = -EINVAL;
654                 goto exit;
655         }
656         if (wrqu->retry.flags & IW_RETRY_MAX) {
657                 priv->retry_rts = wrqu->retry.value;
658                 DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
659
660         } else {
661                 priv->retry_data = wrqu->retry.value;
662                 DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
663         }
664
665         /* FIXME !
666          * We might try to write directly the TX config register
667          * or to restart just the (R)TX process.
668          * I'm unsure if whole reset is really needed
669          */
670
671         rtl8192_commit(dev);
672         /*
673         if(priv->up){
674                 rtl8180_rtx_disable(dev);
675                 rtl8180_rx_enable(dev);
676                 rtl8180_tx_enable(dev);
677
678         }
679         */
680 exit:
681         up(&priv->wx_sem);
682
683         return err;
684 }
685
686 static int r8192_wx_get_retry(struct net_device *dev,
687                                 struct iw_request_info *info,
688                                 union iwreq_data *wrqu, char *extra)
689 {
690         struct r8192_priv *priv = ieee80211_priv(dev);
691
692
693         wrqu->retry.disabled = 0; /* can't be disabled */
694
695         if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
696             IW_RETRY_LIFETIME)
697                 return -EINVAL;
698
699         if (wrqu->retry.flags & IW_RETRY_MAX) {
700                 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
701                 wrqu->retry.value = priv->retry_rts;
702         } else {
703                 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
704                 wrqu->retry.value = priv->retry_data;
705         }
706         //printk("returning %d",wrqu->retry.value);
707
708
709         return 0;
710 }
711
712 static int r8192_wx_get_sens(struct net_device *dev,
713                                 struct iw_request_info *info,
714                                 union iwreq_data *wrqu, char *extra)
715 {
716         struct r8192_priv *priv = ieee80211_priv(dev);
717         if (priv->rf_set_sens == NULL)
718                 return -1; /* we have not this support for this radio */
719         wrqu->sens.value = priv->sens;
720         return 0;
721 }
722
723
724 static int r8192_wx_set_sens(struct net_device *dev,
725                                 struct iw_request_info *info,
726                                 union iwreq_data *wrqu, char *extra)
727 {
728
729         struct r8192_priv *priv = ieee80211_priv(dev);
730
731         short err = 0;
732         down(&priv->wx_sem);
733         //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
734         if (priv->rf_set_sens == NULL) {
735                 err = -1; /* we have not this support for this radio */
736                 goto exit;
737         }
738         if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
739                 priv->sens = wrqu->sens.value;
740         else
741                 err = -EINVAL;
742
743 exit:
744         up(&priv->wx_sem);
745
746         return err;
747 }
748
749 //hw security need to reorganized.
750 static int r8192_wx_set_enc_ext(struct net_device *dev,
751                                         struct iw_request_info *info,
752                                         union iwreq_data *wrqu, char *extra)
753 {
754         int ret = 0;
755         struct r8192_priv *priv = ieee80211_priv(dev);
756         struct ieee80211_device *ieee = priv->ieee80211;
757         //printk("===>%s()\n", __func__);
758
759
760         down(&priv->wx_sem);
761         ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
762
763         {
764                 u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
765                 u8 zero[6] = {0};
766                 u32 key[4] = {0};
767                 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
768                 struct iw_point *encoding = &wrqu->encoding;
769                 u8 idx = 0, alg = 0, group = 0;
770                 if ((encoding->flags & IW_ENCODE_DISABLED) || ext->alg == IW_ENCODE_ALG_NONE)
771                         //none is not allowed to use hwsec WB 2008.07.01
772                         goto end_hw_sec;
773
774                 // as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4;
775                 alg =  (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg;
776                 idx = encoding->flags & IW_ENCODE_INDEX;
777                 if (idx)
778                         idx--;
779                 group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
780
781                 if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg ==  KEY_TYPE_WEP40)) {
782                         if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40))
783                                 alg = KEY_TYPE_WEP104;
784                         ieee->pairwise_key_type = alg;
785                         EnableHWSecurityConfig8192(dev);
786                 }
787                 memcpy((u8 *)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
788
789                 if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) {
790
791                         setKey(dev,
792                                         idx,//EntryNo
793                                         idx, //KeyIndex
794                                         alg,  //KeyType
795                                         zero, //MacAddr
796                                         0,              //DefaultKey
797                                         key);           //KeyContent
798                 } else if (group) {
799                         ieee->group_key_type = alg;
800                         setKey(dev,
801                                         idx,//EntryNo
802                                         idx, //KeyIndex
803                                         alg,  //KeyType
804                                         broadcast_addr, //MacAddr
805                                         0,              //DefaultKey
806                                         key);           //KeyContent
807                 } else {//pairwise key
808                         setKey(dev,
809                                         4,//EntryNo
810                                         idx, //KeyIndex
811                                         alg,  //KeyType
812                                         (u8 *)ieee->ap_mac_addr, //MacAddr
813                                         0,              //DefaultKey
814                                         key);           //KeyContent
815                 }
816
817
818         }
819
820 end_hw_sec:
821
822         up(&priv->wx_sem);
823         return ret;
824
825 }
826 static int r8192_wx_set_auth(struct net_device *dev,
827                                         struct iw_request_info *info,
828                                         union iwreq_data *data, char *extra)
829 {
830         int ret = 0;
831         //printk("====>%s()\n", __func__);
832         struct r8192_priv *priv = ieee80211_priv(dev);
833         down(&priv->wx_sem);
834         ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
835         up(&priv->wx_sem);
836         return ret;
837 }
838
839 static int r8192_wx_set_mlme(struct net_device *dev,
840                                         struct iw_request_info *info,
841                                         union iwreq_data *wrqu, char *extra)
842 {
843         //printk("====>%s()\n", __func__);
844
845         int ret = 0;
846         struct r8192_priv *priv = ieee80211_priv(dev);
847         down(&priv->wx_sem);
848         ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
849
850         up(&priv->wx_sem);
851         return ret;
852 }
853
854 static int r8192_wx_set_gen_ie(struct net_device *dev,
855                                         struct iw_request_info *info,
856                                         union iwreq_data *data, char *extra)
857 {
858            //printk("====>%s(), len:%d\n", __func__, data->length);
859         int ret = 0;
860         struct r8192_priv *priv = ieee80211_priv(dev);
861         down(&priv->wx_sem);
862         ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
863         up(&priv->wx_sem);
864         //printk("<======%s(), ret:%d\n", __func__, ret);
865         return ret;
866
867
868 }
869
870 static int dummy(struct net_device *dev, struct iw_request_info *a,
871                  union iwreq_data *wrqu, char *b)
872 {
873         return -1;
874 }
875
876
877 static iw_handler r8192_wx_handlers[] = {
878         NULL,                     /* SIOCSIWCOMMIT */
879         r8192_wx_get_name,        /* SIOCGIWNAME */
880         dummy,                    /* SIOCSIWNWID */
881         dummy,                    /* SIOCGIWNWID */
882         r8192_wx_set_freq,        /* SIOCSIWFREQ */
883         r8192_wx_get_freq,        /* SIOCGIWFREQ */
884         r8192_wx_set_mode,        /* SIOCSIWMODE */
885         r8192_wx_get_mode,        /* SIOCGIWMODE */
886         r8192_wx_set_sens,        /* SIOCSIWSENS */
887         r8192_wx_get_sens,        /* SIOCGIWSENS */
888         NULL,                     /* SIOCSIWRANGE */
889         rtl8180_wx_get_range,     /* SIOCGIWRANGE */
890         NULL,                     /* SIOCSIWPRIV */
891         NULL,                     /* SIOCGIWPRIV */
892         NULL,                     /* SIOCSIWSTATS */
893         NULL,                     /* SIOCGIWSTATS */
894         dummy,                    /* SIOCSIWSPY */
895         dummy,                    /* SIOCGIWSPY */
896         NULL,                     /* SIOCGIWTHRSPY */
897         NULL,                     /* SIOCWIWTHRSPY */
898         r8192_wx_set_wap,         /* SIOCSIWAP */
899         r8192_wx_get_wap,         /* SIOCGIWAP */
900         r8192_wx_set_mlme,                     /* MLME-- */
901         dummy,                     /* SIOCGIWAPLIST -- deprecated */
902         r8192_wx_set_scan,        /* SIOCSIWSCAN */
903         r8192_wx_get_scan,        /* SIOCGIWSCAN */
904         r8192_wx_set_essid,       /* SIOCSIWESSID */
905         r8192_wx_get_essid,       /* SIOCGIWESSID */
906         dummy,                    /* SIOCSIWNICKN */
907         dummy,                    /* SIOCGIWNICKN */
908         NULL,                     /* -- hole -- */
909         NULL,                     /* -- hole -- */
910         r8192_wx_set_rate,        /* SIOCSIWRATE */
911         r8192_wx_get_rate,        /* SIOCGIWRATE */
912         r8192_wx_set_rts,                    /* SIOCSIWRTS */
913         r8192_wx_get_rts,                    /* SIOCGIWRTS */
914         r8192_wx_set_frag,        /* SIOCSIWFRAG */
915         r8192_wx_get_frag,        /* SIOCGIWFRAG */
916         dummy,                    /* SIOCSIWTXPOW */
917         dummy,                    /* SIOCGIWTXPOW */
918         r8192_wx_set_retry,       /* SIOCSIWRETRY */
919         r8192_wx_get_retry,       /* SIOCGIWRETRY */
920         r8192_wx_set_enc,         /* SIOCSIWENCODE */
921         r8192_wx_get_enc,         /* SIOCGIWENCODE */
922         r8192_wx_set_power,                    /* SIOCSIWPOWER */
923         r8192_wx_get_power,                    /* SIOCGIWPOWER */
924         NULL,                   /*---hole---*/
925         NULL,                   /*---hole---*/
926         r8192_wx_set_gen_ie,//NULL,                     /* SIOCSIWGENIE */
927         NULL,                   /* SIOCSIWGENIE */
928
929         r8192_wx_set_auth,//NULL,                       /* SIOCSIWAUTH */
930         NULL,//r8192_wx_get_auth,//NULL,                        /* SIOCSIWAUTH */
931         r8192_wx_set_enc_ext,                   /* SIOCSIWENCODEEXT */
932         NULL,//r8192_wx_get_enc_ext,//NULL,                     /* SIOCSIWENCODEEXT */
933         NULL,                   /* SIOCSIWPMKSA */
934         NULL,                    /*---hole---*/
935
936 };
937
938
939 static const struct iw_priv_args r8192_private_args[] = {
940
941         {
942                 SIOCIWFIRSTPRIV + 0x0,
943                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
944         },
945
946         {
947                 SIOCIWFIRSTPRIV + 0x1,
948                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
949
950         },
951         {
952                 SIOCIWFIRSTPRIV + 0x2,
953                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
954         },
955         {
956                 SIOCIWFIRSTPRIV + 0x3,
957                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
958
959         }
960
961 };
962
963
964 static iw_handler r8192_private_handler[] = {
965 //      r8192_wx_set_monitor,  /* SIOCIWFIRSTPRIV */
966         r8192_wx_set_crcmon,   /*SIOCIWSECONDPRIV*/
967 //      r8192_wx_set_forceassociate,
968 //      r8192_wx_set_beaconinterval,
969 //      r8192_wx_set_monitor_type,
970         r8192_wx_set_scan_type,
971         r8192_wx_set_rawtx,
972         //r8192_wx_null,
973         r8192_wx_force_reset,
974 };
975
976 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
977 {
978         struct r8192_priv *priv = ieee80211_priv(dev);
979         struct ieee80211_device *ieee = priv->ieee80211;
980         struct iw_statistics *wstats = &priv->wstats;
981         int tmp_level = 0;
982         int tmp_qual = 0;
983         int tmp_noise = 0;
984         if (ieee->state < IEEE80211_LINKED) {
985                 wstats->qual.qual = 0;
986                 wstats->qual.level = 0;
987                 wstats->qual.noise = 0;
988                 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
989                 return wstats;
990         }
991
992         tmp_level = (&ieee->current_network)->stats.rssi;
993         tmp_qual = (&ieee->current_network)->stats.signal;
994         tmp_noise = (&ieee->current_network)->stats.noise;
995         //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
996
997         wstats->qual.level = tmp_level;
998         wstats->qual.qual = tmp_qual;
999         wstats->qual.noise = tmp_noise;
1000         wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1001         return wstats;
1002 }
1003
1004
1005 struct iw_handler_def  r8192_wx_handlers_def = {
1006         .standard = r8192_wx_handlers,
1007         .num_standard = ARRAY_SIZE(r8192_wx_handlers),
1008         .private = r8192_private_handler,
1009         .num_private = ARRAY_SIZE(r8192_private_handler),
1010         .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1011         .get_wireless_stats = r8192_get_wireless_stats,
1012         .private_args = (struct iw_priv_args *)r8192_private_args,
1013 };
This page took 0.097209 seconds and 4 git commands to generate.