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