Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
r8192U_wx.c
Go to the documentation of this file.
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 #ifdef JOHN_IOCTL
131 u16 read_rtl8225(struct net_device *dev, u8 addr);
132 void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
133 u32 john_read_rtl8225(struct net_device *dev, u8 adr);
134 void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
135 
136 static int r8192_wx_read_regs(struct net_device *dev,
137  struct iw_request_info *info,
138  union iwreq_data *wrqu, char *extra)
139 {
140  struct r8192_priv *priv = ieee80211_priv(dev);
141  u8 addr;
142  u16 data1;
143 
144  down(&priv->wx_sem);
145 
146 
147  get_user(addr,(u8*)wrqu->data.pointer);
148  data1 = read_rtl8225(dev, addr);
149  wrqu->data.length = data1;
150 
151  up(&priv->wx_sem);
152  return 0;
153 
154 }
155 
156 static int r8192_wx_write_regs(struct net_device *dev,
157  struct iw_request_info *info,
158  union iwreq_data *wrqu, char *extra)
159 {
160  struct r8192_priv *priv = ieee80211_priv(dev);
161  u8 addr;
162 
163  down(&priv->wx_sem);
164 
165  get_user(addr, (u8*)wrqu->data.pointer);
166  write_rtl8225(dev, addr, wrqu->data.length);
167 
168  up(&priv->wx_sem);
169  return 0;
170 
171 }
172 
173 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
174 u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
175 
176 static int r8192_wx_read_bb(struct net_device *dev,
177  struct iw_request_info *info,
178  union iwreq_data *wrqu, char *extra)
179 {
180  struct r8192_priv *priv = ieee80211_priv(dev);
181  u8 databb;
182 
183  down(&priv->wx_sem);
184 
185  databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
186  wrqu->data.length = databb;
187 
188  up(&priv->wx_sem);
189  return 0;
190 }
191 
192 void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
193 static int r8192_wx_write_bb(struct net_device *dev,
194  struct iw_request_info *info,
195  union iwreq_data *wrqu, char *extra)
196 {
197  struct r8192_priv *priv = ieee80211_priv(dev);
198  u8 databb;
199 
200  down(&priv->wx_sem);
201 
202  get_user(databb, (u8*)wrqu->data.pointer);
203  rtl8187_write_phy(dev, wrqu->data.length, databb);
204 
205  up(&priv->wx_sem);
206  return 0;
207 
208 }
209 
210 
211 static int r8192_wx_write_nicb(struct net_device *dev,
212  struct iw_request_info *info,
213  union iwreq_data *wrqu, char *extra)
214 {
215  struct r8192_priv *priv = ieee80211_priv(dev);
216  u32 addr;
217 
218  down(&priv->wx_sem);
219 
220  get_user(addr, (u32*)wrqu->data.pointer);
221  write_nic_byte(dev, addr, wrqu->data.length);
222 
223  up(&priv->wx_sem);
224  return 0;
225 
226 }
227 static int r8192_wx_read_nicb(struct net_device *dev,
228  struct iw_request_info *info,
229  union iwreq_data *wrqu, char *extra)
230 {
231  struct r8192_priv *priv = ieee80211_priv(dev);
232  u32 addr;
233  u16 data1;
234 
235  down(&priv->wx_sem);
236 
237  get_user(addr,(u32*)wrqu->data.pointer);
238  data1 = read_nic_byte(dev, addr);
239  wrqu->data.length = data1;
240 
241  up(&priv->wx_sem);
242  return 0;
243 }
244 
245 static int r8192_wx_get_ap_status(struct net_device *dev,
246  struct iw_request_info *info,
247  union iwreq_data *wrqu, char *extra)
248 {
249  struct r8192_priv *priv = ieee80211_priv(dev);
250  struct ieee80211_device *ieee = priv->ieee80211;
251  struct ieee80211_network *target;
252  int name_len;
253 
254  down(&priv->wx_sem);
255 
256  //count the length of input ssid
257  for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
258 
259  //search for the corresponding info which is received
260  list_for_each_entry(target, &ieee->network_list, list) {
261  if ( (target->ssid_len == name_len) &&
262  (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
263  if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
264  //set flags=1 to indicate this ap is WPA
265  wrqu->data.flags = 1;
266  else wrqu->data.flags = 0;
267 
268 
269  break;
270  }
271  }
272 
273  up(&priv->wx_sem);
274  return 0;
275 }
276 
277 
278 
279 #endif
280 static int r8192_wx_force_reset(struct net_device *dev,
281  struct iw_request_info *info,
282  union iwreq_data *wrqu, char *extra)
283 {
284  struct r8192_priv *priv = ieee80211_priv(dev);
285 
286  down(&priv->wx_sem);
287 
288  printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
289  priv->force_reset = *extra;
290  up(&priv->wx_sem);
291  return 0;
292 
293 }
294 
295 
296 static int r8192_wx_set_rawtx(struct net_device *dev,
297  struct iw_request_info *info,
298  union iwreq_data *wrqu, char *extra)
299 {
300  struct r8192_priv *priv = ieee80211_priv(dev);
301  int ret;
302 
303  down(&priv->wx_sem);
304 
305  ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
306 
307  up(&priv->wx_sem);
308 
309  return ret;
310 
311 }
312 
313 static int r8192_wx_set_crcmon(struct net_device *dev,
314  struct iw_request_info *info,
315  union iwreq_data *wrqu, char *extra)
316 {
317  struct r8192_priv *priv = ieee80211_priv(dev);
318  int *parms = (int *)extra;
319  int enable = (parms[0] > 0);
320  short prev = priv->crcmon;
321 
322  down(&priv->wx_sem);
323 
324  if(enable)
325  priv->crcmon=1;
326  else
327  priv->crcmon=0;
328 
329  DMESG("bad CRC in monitor mode are %s",
330  priv->crcmon ? "accepted" : "rejected");
331 
332  if(prev != priv->crcmon && priv->up){
333  //rtl8180_down(dev);
334  //rtl8180_up(dev);
335  }
336 
337  up(&priv->wx_sem);
338 
339  return 0;
340 }
341 
342 static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
343  union iwreq_data *wrqu, char *b)
344 {
345  struct r8192_priv *priv = ieee80211_priv(dev);
346  int ret;
347  down(&priv->wx_sem);
348 
349  ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
350 
351  rtl8192_set_rxconf(dev);
352 
353  up(&priv->wx_sem);
354  return ret;
355 }
356 
358 {
359  /* Informative stuff (to choose between different interface) */
360  __u32 throughput; /* To give an idea... */
361  /* In theory this value should be the maximum benchmarked
362  * TCP/IP throughput, because with most of these devices the
363  * bit rate is meaningless (overhead an co) to estimate how
364  * fast the connection will go and pick the fastest one.
365  * I suggest people to play with Netperf or any benchmark...
366  */
367 
368  /* NWID (or domain id) */
369  __u32 min_nwid; /* Minimal NWID we are able to set */
370  __u32 max_nwid; /* Maximal NWID we are able to set */
371 
372  /* Old Frequency (backward compat - moved lower ) */
375 
376  /* Scan capabilities */
377  __u8 scan_capa;
378 };
379 static int rtl8180_wx_get_range(struct net_device *dev,
380  struct iw_request_info *info,
381  union iwreq_data *wrqu, char *extra)
382 {
383  struct iw_range *range = (struct iw_range *)extra;
384  struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
385  struct r8192_priv *priv = ieee80211_priv(dev);
386  u16 val;
387  int i;
388 
389  wrqu->data.length = sizeof(*range);
390  memset(range, 0, sizeof(*range));
391 
392  /* Let's try to keep this struct in the same order as in
393  * linux/include/wireless.h
394  */
395 
396  /* TODO: See what values we can set, and remove the ones we can't
397  * set, or fill them with some default data.
398  */
399 
400  /* ~5 Mb/s real (802.11b) */
401  range->throughput = 5 * 1000 * 1000;
402 
403  // TODO: Not used in 802.11b?
404 // range->min_nwid; /* Minimal NWID we are able to set */
405  // TODO: Not used in 802.11b?
406 // range->max_nwid; /* Maximal NWID we are able to set */
407 
408  /* Old Frequency (backward compat - moved lower ) */
409 // range->old_num_channels;
410 // range->old_num_frequency;
411 // range->old_freq[6]; /* Filler to keep "version" at the same offset */
412  if(priv->rf_set_sens != NULL)
413  range->sensitivity = priv->max_sens; /* signal level threshold range */
414 
415  range->max_qual.qual = 100;
416  /* TODO: Find real max RSSI and stick here */
417  range->max_qual.level = 0;
418  range->max_qual.noise = -98;
419  range->max_qual.updated = 7; /* Updated all three */
420 
421  range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
422  /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
423  range->avg_qual.level = 20 + -98;
424  range->avg_qual.noise = 0;
425  range->avg_qual.updated = 7; /* Updated all three */
426 
427  range->num_bitrates = RATE_COUNT;
428 
429  for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
430  range->bitrate[i] = rtl8180_rates[i];
431  }
432 
433  range->min_frag = MIN_FRAG_THRESHOLD;
434  range->max_frag = MAX_FRAG_THRESHOLD;
435 
436  range->min_pmp=0;
437  range->max_pmp = 5000000;
438  range->min_pmt = 0;
439  range->max_pmt = 65535*1000;
440  range->pmp_flags = IW_POWER_PERIOD;
441  range->pmt_flags = IW_POWER_TIMEOUT;
443 
445  range->we_version_source = 16;
446 
447 // range->retry_capa; /* What retry options are supported */
448 // range->retry_flags; /* How to decode max/min retry limit */
449 // range->r_time_flags; /* How to decode max/min retry life */
450 // range->min_retry; /* Minimal number of retries */
451 // range->max_retry; /* Maximal number of retries */
452 // range->min_r_time; /* Minimal retry lifetime */
453 // range->max_r_time; /* Maximal retry lifetime */
454 
455 
456  for (i = 0, val = 0; i < 14; i++) {
457 
458  // Include only legal frequencies for some countries
459  if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
460  range->freq[val].i = i + 1;
461  range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
462  range->freq[val].e = 1;
463  val++;
464  } else {
465  // FIXME: do we need to set anything for channels
466  // we don't use ?
467  }
468 
469  if (val == IW_MAX_FREQUENCIES)
470  break;
471  }
472  range->num_frequency = val;
473  range->num_channels = val;
474 #if WIRELESS_EXT > 17
477 #endif
478  tmp->scan_capa = 0x01;
479  return 0;
480 }
481 
482 
483 static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
484  union iwreq_data *wrqu, char *b)
485 {
486  struct r8192_priv *priv = ieee80211_priv(dev);
487  struct ieee80211_device* ieee = priv->ieee80211;
488  int ret = 0;
489 
490  if(!priv->up) return -ENETDOWN;
491 
492  if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
493  return -EAGAIN;
494  if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
495  {
496  struct iw_scan_req* req = (struct iw_scan_req*)b;
497  if (req->essid_len)
498  {
499  //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
500  ieee->current_network.ssid_len = req->essid_len;
501  memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
502  //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
503  }
504  }
505 
506  down(&priv->wx_sem);
507  if(priv->ieee80211->state != IEEE80211_LINKED){
508  priv->ieee80211->scanning = 0;
510  ret = 0;
511  }
512  else
513  ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
514  up(&priv->wx_sem);
515  return ret;
516 }
517 
518 
519 static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
520  union iwreq_data *wrqu, char *b)
521 {
522 
523  int ret;
524  struct r8192_priv *priv = ieee80211_priv(dev);
525 
526  if(!priv->up) return -ENETDOWN;
527 
528  down(&priv->wx_sem);
529 
530  ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
531 
532  up(&priv->wx_sem);
533 
534  return ret;
535 }
536 
537 static int r8192_wx_set_essid(struct net_device *dev,
538  struct iw_request_info *a,
539  union iwreq_data *wrqu, char *b)
540 {
541  struct r8192_priv *priv = ieee80211_priv(dev);
542  int ret;
543  down(&priv->wx_sem);
544 
545  ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
546 
547  up(&priv->wx_sem);
548 
549  return ret;
550 }
551 
552 
553 
554 
555 static int r8192_wx_get_essid(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 = ieee80211_priv(dev);
561 
562  down(&priv->wx_sem);
563 
564  ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
565 
566  up(&priv->wx_sem);
567 
568  return ret;
569 }
570 
571 
572 static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
573  union iwreq_data *wrqu, char *b)
574 {
575  int ret;
576  struct r8192_priv *priv = ieee80211_priv(dev);
577 
578  down(&priv->wx_sem);
579 
580  ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
581 
582  up(&priv->wx_sem);
583  return ret;
584 }
585 
586 static int r8192_wx_get_name(struct net_device *dev,
587  struct iw_request_info *info,
588  union iwreq_data *wrqu, char *extra)
589 {
590  struct r8192_priv *priv = ieee80211_priv(dev);
591  return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
592 }
593 
594 
595 static int r8192_wx_set_frag(struct net_device *dev,
596  struct iw_request_info *info,
597  union iwreq_data *wrqu, char *extra)
598 {
599  struct r8192_priv *priv = ieee80211_priv(dev);
600 
601  if (wrqu->frag.disabled)
602  priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
603  else {
604  if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
605  wrqu->frag.value > MAX_FRAG_THRESHOLD)
606  return -EINVAL;
607 
608  priv->ieee80211->fts = wrqu->frag.value & ~0x1;
609  }
610 
611  return 0;
612 }
613 
614 
615 static int r8192_wx_get_frag(struct net_device *dev,
616  struct iw_request_info *info,
617  union iwreq_data *wrqu, char *extra)
618 {
619  struct r8192_priv *priv = ieee80211_priv(dev);
620 
621  wrqu->frag.value = priv->ieee80211->fts;
622  wrqu->frag.fixed = 0; /* no auto select */
623  wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
624 
625  return 0;
626 }
627 
628 
629 static int r8192_wx_set_wap(struct net_device *dev,
630  struct iw_request_info *info,
631  union iwreq_data *awrq,
632  char *extra)
633 {
634 
635  int ret;
636  struct r8192_priv *priv = ieee80211_priv(dev);
637 // struct sockaddr *temp = (struct sockaddr *)awrq;
638  down(&priv->wx_sem);
639 
640  ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
641 
642  up(&priv->wx_sem);
643 
644  return ret;
645 
646 }
647 
648 
649 static int r8192_wx_get_wap(struct net_device *dev,
650  struct iw_request_info *info,
651  union iwreq_data *wrqu, char *extra)
652 {
653  struct r8192_priv *priv = ieee80211_priv(dev);
654 
655  return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
656 }
657 
658 
659 static int r8192_wx_get_enc(struct net_device *dev,
660  struct iw_request_info *info,
661  union iwreq_data *wrqu, char *key)
662 {
663  struct r8192_priv *priv = ieee80211_priv(dev);
664 
665  return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
666 }
667 
668 static int r8192_wx_set_enc(struct net_device *dev,
669  struct iw_request_info *info,
670  union iwreq_data *wrqu, char *key)
671 {
672  struct r8192_priv *priv = ieee80211_priv(dev);
673  struct ieee80211_device *ieee = priv->ieee80211;
674  int ret;
675 
676  //u32 TargetContent;
677  u32 hwkey[4]={0,0,0,0};
678  u8 mask=0xff;
679  u32 key_idx=0;
680  //u8 broadcast_addr[6] ={ 0xff,0xff,0xff,0xff,0xff,0xff};
681  u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00},
682  {0x00,0x00,0x00,0x00,0x00,0x01},
683  {0x00,0x00,0x00,0x00,0x00,0x02},
684  {0x00,0x00,0x00,0x00,0x00,0x03} };
685  int i;
686 
687  if(!priv->up) return -ENETDOWN;
688 
689  down(&priv->wx_sem);
690 
691  RT_TRACE(COMP_SEC, "Setting SW wep key");
692  ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
693 
694  up(&priv->wx_sem);
695 
696 
697 
698  //sometimes, the length is zero while we do not type key value
699  if(wrqu->encoding.length!=0){
700 
701  for(i=0 ; i<4 ; i++){
702  hwkey[i] |= key[4*i+0]&mask;
703  if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
704  if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
705  hwkey[i] |= (key[4*i+1]&mask)<<8;
706  hwkey[i] |= (key[4*i+2]&mask)<<16;
707  hwkey[i] |= (key[4*i+3]&mask)<<24;
708  }
709 
710  #define CONF_WEP40 0x4
711  #define CONF_WEP104 0x14
712 
713  switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
714  case 0: key_idx = ieee->tx_keyidx; break;
715  case 1: key_idx = 0; break;
716  case 2: key_idx = 1; break;
717  case 3: key_idx = 2; break;
718  case 4: key_idx = 3; break;
719  default: break;
720  }
721 
722  if(wrqu->encoding.length==0x5){
725 
726  setKey( dev,
727  key_idx, //EntryNo
728  key_idx, //KeyIndex
729  KEY_TYPE_WEP40, //KeyType
730  zero_addr[key_idx],
731  0, //DefaultKey
732  hwkey); //KeyContent
733 
734  }
735 
736  else if(wrqu->encoding.length==0xd){
739 
740  setKey( dev,
741  key_idx, //EntryNo
742  key_idx, //KeyIndex
743  KEY_TYPE_WEP104, //KeyType
744  zero_addr[key_idx],
745  0, //DefaultKey
746  hwkey); //KeyContent
747 
748  }
749  else printk("wrong type in WEP, not WEP40 and WEP104\n");
750 
751  }
752 
753  return ret;
754 }
755 
756 
757 static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
758  iwreq_data *wrqu, char *p){
759 
760  struct r8192_priv *priv = ieee80211_priv(dev);
761  int *parms=(int*)p;
762  int mode=parms[0];
763 
764  priv->ieee80211->active_scan = mode;
765 
766  return 1;
767 }
768 
769 
770 
771 static int r8192_wx_set_retry(struct net_device *dev,
772  struct iw_request_info *info,
773  union iwreq_data *wrqu, char *extra)
774 {
775  struct r8192_priv *priv = ieee80211_priv(dev);
776  int err = 0;
777 
778  down(&priv->wx_sem);
779 
780  if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
781  wrqu->retry.disabled){
782  err = -EINVAL;
783  goto exit;
784  }
785  if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
786  err = -EINVAL;
787  goto exit;
788  }
789 
790  if(wrqu->retry.value > R8180_MAX_RETRY){
791  err= -EINVAL;
792  goto exit;
793  }
794  if (wrqu->retry.flags & IW_RETRY_MAX) {
795  priv->retry_rts = wrqu->retry.value;
796  DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
797 
798  }else {
799  priv->retry_data = wrqu->retry.value;
800  DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
801  }
802 
803  /* FIXME !
804  * We might try to write directly the TX config register
805  * or to restart just the (R)TX process.
806  * I'm unsure if whole reset is really needed
807  */
808 
809  rtl8192_commit(dev);
810  /*
811  if(priv->up){
812  rtl8180_rtx_disable(dev);
813  rtl8180_rx_enable(dev);
814  rtl8180_tx_enable(dev);
815 
816  }
817  */
818 exit:
819  up(&priv->wx_sem);
820 
821  return err;
822 }
823 
824 static int r8192_wx_get_retry(struct net_device *dev,
825  struct iw_request_info *info,
826  union iwreq_data *wrqu, char *extra)
827 {
828  struct r8192_priv *priv = ieee80211_priv(dev);
829 
830 
831  wrqu->retry.disabled = 0; /* can't be disabled */
832 
833  if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
835  return -EINVAL;
836 
837  if (wrqu->retry.flags & IW_RETRY_MAX) {
838  wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
839  wrqu->retry.value = priv->retry_rts;
840  } else {
841  wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
842  wrqu->retry.value = priv->retry_data;
843  }
844  //printk("returning %d",wrqu->retry.value);
845 
846 
847  return 0;
848 }
849 
850 static int r8192_wx_get_sens(struct net_device *dev,
851  struct iw_request_info *info,
852  union iwreq_data *wrqu, char *extra)
853 {
854  struct r8192_priv *priv = ieee80211_priv(dev);
855  if(priv->rf_set_sens == NULL)
856  return -1; /* we have not this support for this radio */
857  wrqu->sens.value = priv->sens;
858  return 0;
859 }
860 
861 
862 static int r8192_wx_set_sens(struct net_device *dev,
863  struct iw_request_info *info,
864  union iwreq_data *wrqu, char *extra)
865 {
866 
867  struct r8192_priv *priv = ieee80211_priv(dev);
868 
869  short err = 0;
870  down(&priv->wx_sem);
871  //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
872  if(priv->rf_set_sens == NULL) {
873  err= -1; /* we have not this support for this radio */
874  goto exit;
875  }
876  if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
877  priv->sens = wrqu->sens.value;
878  else
879  err= -EINVAL;
880 
881 exit:
882  up(&priv->wx_sem);
883 
884  return err;
885 }
886 
887 #if (WIRELESS_EXT >= 18)
888 //hw security need to reorganized.
889 static int r8192_wx_set_enc_ext(struct net_device *dev,
890  struct iw_request_info *info,
891  union iwreq_data *wrqu, char *extra)
892 {
893  int ret=0;
894  struct r8192_priv *priv = ieee80211_priv(dev);
895  struct ieee80211_device* ieee = priv->ieee80211;
896  //printk("===>%s()\n", __FUNCTION__);
897 
898 
899  down(&priv->wx_sem);
900  ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
901 
902  {
903  u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
904  u8 zero[6] = {0};
905  u32 key[4] = {0};
906  struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
907  struct iw_point *encoding = &wrqu->encoding;
908  u8 idx = 0, alg = 0, group = 0;
909  if ((encoding->flags & IW_ENCODE_DISABLED) ||
910  ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
911  goto end_hw_sec;
912 
913  alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg; // as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4;
914  idx = encoding->flags & IW_ENCODE_INDEX;
915  if (idx)
916  idx --;
918 
919  if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40))
920  {
921  if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
922  alg = KEY_TYPE_WEP104;
923  ieee->pairwise_key_type = alg;
925  }
926  memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
927 
928  if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
929  {
930 
931  setKey( dev,
932  idx,//EntryNo
933  idx, //KeyIndex
934  alg, //KeyType
935  zero, //MacAddr
936  0, //DefaultKey
937  key); //KeyContent
938  }
939  else if (group)
940  {
941  ieee->group_key_type = alg;
942  setKey( dev,
943  idx,//EntryNo
944  idx, //KeyIndex
945  alg, //KeyType
946  broadcast_addr, //MacAddr
947  0, //DefaultKey
948  key); //KeyContent
949  }
950  else //pairwise key
951  {
952  setKey( dev,
953  4,//EntryNo
954  idx, //KeyIndex
955  alg, //KeyType
956  (u8*)ieee->ap_mac_addr, //MacAddr
957  0, //DefaultKey
958  key); //KeyContent
959  }
960 
961 
962  }
963 
964 end_hw_sec:
965 
966  up(&priv->wx_sem);
967  return ret;
968 
969 }
970 static int r8192_wx_set_auth(struct net_device *dev,
971  struct iw_request_info *info,
972  union iwreq_data *data, char *extra)
973 {
974  int ret=0;
975  //printk("====>%s()\n", __FUNCTION__);
976  struct r8192_priv *priv = ieee80211_priv(dev);
977  down(&priv->wx_sem);
978  ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
979  up(&priv->wx_sem);
980  return ret;
981 }
982 
983 static int r8192_wx_set_mlme(struct net_device *dev,
984  struct iw_request_info *info,
985  union iwreq_data *wrqu, char *extra)
986 {
987  //printk("====>%s()\n", __FUNCTION__);
988 
989  int ret=0;
990  struct r8192_priv *priv = ieee80211_priv(dev);
991  down(&priv->wx_sem);
992  ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
993 
994  up(&priv->wx_sem);
995  return ret;
996 }
997 #endif
998 static int r8192_wx_set_gen_ie(struct net_device *dev,
999  struct iw_request_info *info,
1000  union iwreq_data *data, char *extra)
1001 {
1002  //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1003  int ret=0;
1004  struct r8192_priv *priv = ieee80211_priv(dev);
1005  down(&priv->wx_sem);
1006  ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1007  up(&priv->wx_sem);
1008  //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
1009  return ret;
1010 
1011 
1012 }
1013 
1014 static int dummy(struct net_device *dev, struct iw_request_info *a,
1015  union iwreq_data *wrqu,char *b)
1016 {
1017  return -1;
1018 }
1019 
1020 
1021 static iw_handler r8192_wx_handlers[] =
1022 {
1023  NULL, /* SIOCSIWCOMMIT */
1024  r8192_wx_get_name, /* SIOCGIWNAME */
1025  dummy, /* SIOCSIWNWID */
1026  dummy, /* SIOCGIWNWID */
1027  r8192_wx_set_freq, /* SIOCSIWFREQ */
1028  r8192_wx_get_freq, /* SIOCGIWFREQ */
1029  r8192_wx_set_mode, /* SIOCSIWMODE */
1030  r8192_wx_get_mode, /* SIOCGIWMODE */
1031  r8192_wx_set_sens, /* SIOCSIWSENS */
1032  r8192_wx_get_sens, /* SIOCGIWSENS */
1033  NULL, /* SIOCSIWRANGE */
1034  rtl8180_wx_get_range, /* SIOCGIWRANGE */
1035  NULL, /* SIOCSIWPRIV */
1036  NULL, /* SIOCGIWPRIV */
1037  NULL, /* SIOCSIWSTATS */
1038  NULL, /* SIOCGIWSTATS */
1039  dummy, /* SIOCSIWSPY */
1040  dummy, /* SIOCGIWSPY */
1041  NULL, /* SIOCGIWTHRSPY */
1042  NULL, /* SIOCWIWTHRSPY */
1043  r8192_wx_set_wap, /* SIOCSIWAP */
1044  r8192_wx_get_wap, /* SIOCGIWAP */
1045 #if (WIRELESS_EXT >= 18)
1046  r8192_wx_set_mlme, /* MLME-- */
1047 #else
1048  NULL,
1049 #endif
1050  dummy, /* SIOCGIWAPLIST -- deprecated */
1051  r8192_wx_set_scan, /* SIOCSIWSCAN */
1052  r8192_wx_get_scan, /* SIOCGIWSCAN */
1053  r8192_wx_set_essid, /* SIOCSIWESSID */
1054  r8192_wx_get_essid, /* SIOCGIWESSID */
1055  dummy, /* SIOCSIWNICKN */
1056  dummy, /* SIOCGIWNICKN */
1057  NULL, /* -- hole -- */
1058  NULL, /* -- hole -- */
1059  r8192_wx_set_rate, /* SIOCSIWRATE */
1060  r8192_wx_get_rate, /* SIOCGIWRATE */
1061  r8192_wx_set_rts, /* SIOCSIWRTS */
1062  r8192_wx_get_rts, /* SIOCGIWRTS */
1063  r8192_wx_set_frag, /* SIOCSIWFRAG */
1064  r8192_wx_get_frag, /* SIOCGIWFRAG */
1065  dummy, /* SIOCSIWTXPOW */
1066  dummy, /* SIOCGIWTXPOW */
1067  r8192_wx_set_retry, /* SIOCSIWRETRY */
1068  r8192_wx_get_retry, /* SIOCGIWRETRY */
1069  r8192_wx_set_enc, /* SIOCSIWENCODE */
1070  r8192_wx_get_enc, /* SIOCGIWENCODE */
1071  r8192_wx_set_power, /* SIOCSIWPOWER */
1072  r8192_wx_get_power, /* SIOCGIWPOWER */
1073  NULL, /*---hole---*/
1074  NULL, /*---hole---*/
1075  r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */
1076  NULL, /* SIOCSIWGENIE */
1077 
1078 #if (WIRELESS_EXT >= 18)
1079  r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */
1080  NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
1081  r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
1082  NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
1083 #else
1084  NULL,
1085  NULL,
1086  NULL,
1087  NULL,
1088 #endif
1089  NULL, /* SIOCSIWPMKSA */
1090  NULL, /*---hole---*/
1091 
1092 };
1093 
1094 
1095 static const struct iw_priv_args r8192_private_args[] = {
1096 
1097  {
1098  SIOCIWFIRSTPRIV + 0x0,
1099  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
1100  },
1101 
1102  {
1103  SIOCIWFIRSTPRIV + 0x1,
1104  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
1105 
1106  },
1107  {
1108  SIOCIWFIRSTPRIV + 0x2,
1109  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1110  }
1111 #ifdef JOHN_IOCTL
1112  ,
1113  {
1114  SIOCIWFIRSTPRIV + 0x3,
1115  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
1116  }
1117  ,
1118  {
1119  SIOCIWFIRSTPRIV + 0x4,
1120  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
1121  }
1122  ,
1123  {
1124  SIOCIWFIRSTPRIV + 0x5,
1125  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
1126  }
1127  ,
1128  {
1129  SIOCIWFIRSTPRIV + 0x6,
1130  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
1131  }
1132  ,
1133  {
1134  SIOCIWFIRSTPRIV + 0x7,
1135  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
1136  }
1137  ,
1138  {
1139  SIOCIWFIRSTPRIV + 0x8,
1140  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
1141  }
1142  ,
1143  {
1144  SIOCIWFIRSTPRIV + 0x9,
1145  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
1146  }
1147 
1148 #endif
1149  ,
1150  {
1151  SIOCIWFIRSTPRIV + 0x3,
1152  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1153 
1154  }
1155 
1156 };
1157 
1158 
1159 static iw_handler r8192_private_handler[] = {
1160 // r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1161  r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1162 // r8192_wx_set_forceassociate,
1163 // r8192_wx_set_beaconinterval,
1164 // r8192_wx_set_monitor_type,
1165  r8192_wx_set_scan_type,
1166  r8192_wx_set_rawtx,
1167 #ifdef JOHN_IOCTL
1168  r8192_wx_read_regs,
1169  r8192_wx_write_regs,
1170  r8192_wx_read_bb,
1171  r8192_wx_write_bb,
1172  r8192_wx_read_nicb,
1173  r8192_wx_write_nicb,
1174  r8192_wx_get_ap_status,
1175 #endif
1176  //r8192_wx_null,
1177  r8192_wx_force_reset,
1178 };
1179 
1180 //#if WIRELESS_EXT >= 17
1182 {
1183  struct r8192_priv *priv = ieee80211_priv(dev);
1184  struct ieee80211_device* ieee = priv->ieee80211;
1185  struct iw_statistics* wstats = &priv->wstats;
1186  int tmp_level = 0;
1187  int tmp_qual = 0;
1188  int tmp_noise = 0;
1189  if(ieee->state < IEEE80211_LINKED)
1190  {
1191  wstats->qual.qual = 0;
1192  wstats->qual.level = 0;
1193  wstats->qual.noise = 0;
1194  wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
1195  return wstats;
1196  }
1197 
1198  tmp_level = (&ieee->current_network)->stats.rssi;
1199  tmp_qual = (&ieee->current_network)->stats.signal;
1200  tmp_noise = (&ieee->current_network)->stats.noise;
1201  //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
1202 
1203  wstats->qual.level = tmp_level;
1204  wstats->qual.qual = tmp_qual;
1205  wstats->qual.noise = tmp_noise;
1206  wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
1207  return wstats;
1208 }
1209 //#endif
1210 
1211 
1213  .standard = r8192_wx_handlers,
1214  .num_standard = ARRAY_SIZE(r8192_wx_handlers),
1215  .private = r8192_private_handler,
1216  .num_private = ARRAY_SIZE(r8192_private_handler),
1217  .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
1218 #if WIRELESS_EXT >= 17
1219  .get_wireless_stats = r8192_get_wireless_stats,
1220 #endif
1221  .private_args = (struct iw_priv_args *)r8192_private_args,
1222 };