1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#define _RTL871X_IOCTL_LINUX_C_
30#define _RTL871X_MP_IOCTL_C_
31
32#include "osdep_service.h"
33#include "drv_types.h"
34#include "wlan_bssdef.h"
35#include "rtl871x_debug.h"
36#include "wifi.h"
37#include "rtl871x_mlme.h"
38#include "rtl871x_ioctl.h"
39#include "rtl871x_ioctl_set.h"
40#include "rtl871x_mp_ioctl.h"
41#include "mlme_osdep.h"
42#include <linux/wireless.h>
43#include <linux/module.h>
44#include <linux/kernel.h>
45#include <linux/init.h>
46#include <linux/io.h>
47#include <linux/semaphore.h>
48#include <net/iw_handler.h>
49#include <linux/if_arp.h>
50
51#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 0x1E)
52
53#define SCAN_ITEM_SIZE 768
54#define MAX_CUSTOM_LEN 64
55#define RATE_COUNT 4
56
57
58static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
59 6000000, 9000000, 12000000, 18000000,
60 24000000, 36000000, 48000000, 54000000};
61
62static const long ieee80211_wlan_frequencies[] = {
63 2412, 2417, 2422, 2427,
64 2432, 2437, 2442, 2447,
65 2452, 2457, 2462, 2467,
66 2472, 2484
67};
68
69static const char * const iw_operation_mode[] = {
70 "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary",
71 "Monitor"
72};
73
74
75
76
77
78
79
80static int hwaddr_aton_i(const char *txt, u8 *addr)
81{
82 int i;
83
84 for (i = 0; i < 6; i++) {
85 int a, b;
86
87 a = hex_to_bin(*txt++);
88 if (a < 0)
89 return -1;
90 b = hex_to_bin(*txt++);
91 if (b < 0)
92 return -1;
93 *addr++ = (a << 4) | b;
94 if (i < 5 && *txt++ != ':')
95 return -1;
96 }
97 return 0;
98}
99
100void r8712_indicate_wx_assoc_event(struct _adapter *padapter)
101{
102 union iwreq_data wrqu;
103 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
104
105 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
106 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress,
107 ETH_ALEN);
108 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
109}
110
111void r8712_indicate_wx_disassoc_event(struct _adapter *padapter)
112{
113 union iwreq_data wrqu;
114
115 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
116 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
117 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
118}
119
120static inline void handle_pairwise_key(struct sta_info *psta,
121 struct ieee_param *param,
122 struct _adapter *padapter)
123{
124
125 memcpy(psta->x_UncstKey.skey, param->u.crypt.key,
126 (param->u.crypt. key_len > 16 ? 16 : param->u.crypt.key_len));
127 if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
128 memcpy(psta->tkiptxmickey. skey, &(param->u.crypt.
129 key[16]), 8);
130 memcpy(psta->tkiprxmickey. skey, &(param->u.crypt.
131 key[24]), 8);
132 padapter->securitypriv. busetkipkey = false;
133 _set_timer(&padapter->securitypriv.tkip_timer, 50);
134 }
135 r8712_setstakey_cmd(padapter, (unsigned char *)psta, true);
136}
137
138static inline void handle_group_key(struct ieee_param *param,
139 struct _adapter *padapter)
140{
141 if (0 < param->u.crypt.idx &&
142 param->u.crypt.idx < 3) {
143
144 memcpy(padapter->securitypriv.XGrpKey[param->u.crypt.
145 idx-1].skey, param->u.crypt.key, (param->u.crypt.key_len
146 > 16 ? 16 : param->u.crypt.key_len));
147 memcpy(padapter->securitypriv.XGrptxmickey[param->
148 u.crypt.idx-1].skey, &(param->u.crypt.key[16]), 8);
149 memcpy(padapter->securitypriv. XGrprxmickey[param->
150 u.crypt.idx-1].skey, &(param->u.crypt.key[24]), 8);
151 padapter->securitypriv.binstallGrpkey = true;
152 r8712_set_key(padapter, &padapter->securitypriv,
153 param->u.crypt.idx);
154 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) {
155 if (padapter->registrypriv.power_mgnt != padapter->
156 pwrctrlpriv.pwr_mode)
157 _set_timer(&(padapter->mlmepriv.dhcp_timer),
158 60000);
159 }
160 }
161}
162
163static inline char *translate_scan(struct _adapter *padapter,
164 struct iw_request_info *info,
165 struct wlan_network *pnetwork,
166 char *start, char *stop)
167{
168 struct iw_event iwe;
169 struct ieee80211_ht_cap *pht_capie;
170 char *current_val;
171 s8 *p;
172 u32 i = 0, ht_ielen = 0;
173 u16 cap, ht_cap = false, mcs_rate;
174 u8 rssi, bw_40MHz = 0, short_GI = 0;
175
176 if ((pnetwork->network.Configuration.DSConfig < 1) ||
177 (pnetwork->network.Configuration.DSConfig > 14)) {
178 if (pnetwork->network.Configuration.DSConfig < 1)
179 pnetwork->network.Configuration.DSConfig = 1;
180 else
181 pnetwork->network.Configuration.DSConfig = 14;
182 }
183
184 iwe.cmd = SIOCGIWAP;
185 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
186 memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
187 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
188
189 iwe.cmd = SIOCGIWESSID;
190 iwe.u.data.flags = 1;
191 iwe.u.data.length = min_t(u32, pnetwork->network.Ssid.SsidLength, 32);
192 start = iwe_stream_add_point(info, start, stop, &iwe,
193 pnetwork->network.Ssid.Ssid);
194
195 p = r8712_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_,
196 &ht_ielen, pnetwork->network.IELength - 12);
197 if (p && ht_ielen > 0) {
198 ht_cap = true;
199 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
200 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
201 bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH)
202 ? 1 : 0;
203 short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20 |
204 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
205 }
206
207 iwe.cmd = SIOCGIWNAME;
208 if ((r8712_is_cckratesonly_included((u8 *)&pnetwork->network.
209 SupportedRates)) == true) {
210 if (ht_cap == true)
211 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
212 else
213 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
214 } else if ((r8712_is_cckrates_included((u8 *)&pnetwork->network.
215 SupportedRates)) == true) {
216 if (ht_cap == true)
217 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
218 else
219 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
220 } else {
221 if (ht_cap == true)
222 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
223 else
224 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
225 }
226 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
227
228 iwe.cmd = SIOCGIWMODE;
229 memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
230 2);
231 cap = le16_to_cpu(cap);
232 if (cap & (WLAN_CAPABILITY_IBSS|WLAN_CAPABILITY_BSS)) {
233 if (cap & WLAN_CAPABILITY_BSS)
234 iwe.u.mode = (u32)IW_MODE_MASTER;
235 else
236 iwe.u.mode = (u32)IW_MODE_ADHOC;
237 start = iwe_stream_add_event(info, start, stop, &iwe,
238 IW_EV_UINT_LEN);
239 }
240
241 iwe.cmd = SIOCGIWFREQ;
242 {
243
244 u8 dsconfig = pnetwork->network.Configuration.DSConfig;
245 if (dsconfig >= 1 && dsconfig <= sizeof(
246 ieee80211_wlan_frequencies) / sizeof(long))
247 iwe.u.freq.m = (s32)(ieee80211_wlan_frequencies[
248 pnetwork->network.Configuration.
249 DSConfig - 1] * 100000);
250 else
251 iwe.u.freq.m = 0;
252 }
253 iwe.u.freq.e = (s16)1;
254 iwe.u.freq.i = (u8)pnetwork->network.Configuration.DSConfig;
255 start = iwe_stream_add_event(info, start, stop, &iwe,
256 IW_EV_FREQ_LEN);
257
258 iwe.cmd = SIOCGIWENCODE;
259 if (cap & WLAN_CAPABILITY_PRIVACY)
260 iwe.u.data.flags = (u16)(IW_ENCODE_ENABLED |
261 IW_ENCODE_NOKEY);
262 else
263 iwe.u.data.flags = (u16)(IW_ENCODE_DISABLED);
264 iwe.u.data.length = (u16)0;
265 start = iwe_stream_add_point(info, start, stop, &iwe,
266 pnetwork->network.Ssid.Ssid);
267
268 current_val = start + iwe_stream_lcp_len(info);
269 iwe.cmd = SIOCGIWRATE;
270 iwe.u.bitrate.fixed = 0;
271 iwe.u.bitrate.disabled = 0;
272 iwe.u.bitrate.value = 0;
273 i = 0;
274 while (pnetwork->network.SupportedRates[i] != 0) {
275
276 iwe.u.bitrate.value = (pnetwork->network.SupportedRates[i++] &
277 0x7F) * 500000;
278 current_val = iwe_stream_add_value(info, start, current_val,
279 stop, &iwe, IW_EV_PARAM_LEN);
280 }
281
282 if ((current_val - start) > iwe_stream_lcp_len(info))
283 start = current_val;
284
285 {
286 u8 buf[MAX_WPA_IE_LEN];
287 u8 wpa_ie[255], rsn_ie[255];
288 u16 wpa_len = 0, rsn_len = 0;
289 int n;
290 sint out_len = 0;
291 out_len = r8712_get_sec_ie(pnetwork->network.IEs,
292 pnetwork->network.
293 IELength, rsn_ie, &rsn_len,
294 wpa_ie, &wpa_len);
295 if (wpa_len > 0) {
296 memset(buf, 0, MAX_WPA_IE_LEN);
297 n = sprintf(buf, "wpa_ie=");
298 for (i = 0; i < wpa_len; i++) {
299 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
300 "%02x", wpa_ie[i]);
301 if (n >= MAX_WPA_IE_LEN)
302 break;
303 }
304 memset(&iwe, 0, sizeof(iwe));
305 iwe.cmd = IWEVCUSTOM;
306 iwe.u.data.length = (u16)strlen(buf);
307 start = iwe_stream_add_point(info, start, stop,
308 &iwe, buf);
309 memset(&iwe, 0, sizeof(iwe));
310 iwe.cmd = IWEVGENIE;
311 iwe.u.data.length = (u16)wpa_len;
312 start = iwe_stream_add_point(info, start, stop,
313 &iwe, wpa_ie);
314 }
315 if (rsn_len > 0) {
316 memset(buf, 0, MAX_WPA_IE_LEN);
317 n = sprintf(buf, "rsn_ie=");
318 for (i = 0; i < rsn_len; i++) {
319 n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
320 "%02x", rsn_ie[i]);
321 if (n >= MAX_WPA_IE_LEN)
322 break;
323 }
324 memset(&iwe, 0, sizeof(iwe));
325 iwe.cmd = IWEVCUSTOM;
326 iwe.u.data.length = strlen(buf);
327 start = iwe_stream_add_point(info, start, stop,
328 &iwe, buf);
329 memset(&iwe, 0, sizeof(iwe));
330 iwe.cmd = IWEVGENIE;
331 iwe.u.data.length = rsn_len;
332 start = iwe_stream_add_point(info, start, stop, &iwe,
333 rsn_ie);
334 }
335 }
336
337 {
338 u8 wps_ie[512];
339 uint wps_ielen;
340
341 if (r8712_get_wps_ie(pnetwork->network.IEs,
342 pnetwork->network.IELength,
343 wps_ie, &wps_ielen) == true) {
344 if (wps_ielen > 2) {
345 iwe.cmd = IWEVGENIE;
346 iwe.u.data.length = (u16)wps_ielen;
347 start = iwe_stream_add_point(info, start, stop,
348 &iwe, wps_ie);
349 }
350 }
351 }
352
353 iwe.cmd = IWEVQUAL;
354 rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
355
356 iwe.u.qual.updated = (u8)(IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED |
357 IW_QUAL_NOISE_INVALID);
358 iwe.u.qual.level = rssi;
359 iwe.u.qual.qual = 0;
360 iwe.u.qual.noise = 0;
361 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
362
363 return start;
364}
365
366static int wpa_set_auth_algs(struct net_device *dev, u32 value)
367{
368 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
369 int ret = 0;
370
371 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
372 padapter->securitypriv.ndisencryptstatus =
373 Ndis802_11Encryption1Enabled;
374 padapter->securitypriv.ndisauthtype =
375 Ndis802_11AuthModeAutoSwitch;
376 padapter->securitypriv.AuthAlgrthm = 3;
377 } else if (value & AUTH_ALG_SHARED_KEY) {
378 padapter->securitypriv.ndisencryptstatus =
379 Ndis802_11Encryption1Enabled;
380 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
381 padapter->securitypriv.AuthAlgrthm = 1;
382 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
383 if (padapter->securitypriv.ndisauthtype <
384 Ndis802_11AuthModeWPAPSK) {
385 padapter->securitypriv.ndisauthtype =
386 Ndis802_11AuthModeOpen;
387 padapter->securitypriv.AuthAlgrthm = 0;
388 }
389 } else
390 ret = -EINVAL;
391 return ret;
392}
393
394static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
395 u32 param_len)
396{
397 int ret = 0;
398 u32 wep_key_idx, wep_key_len = 0;
399 struct NDIS_802_11_WEP *pwep = NULL;
400 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
401 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
402 struct security_priv *psecuritypriv = &padapter->securitypriv;
403
404 param->u.crypt.err = 0;
405 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
406 if (param_len != (u32)((u8 *) param->u.crypt.key - (u8 *)param) +
407 param->u.crypt.key_len)
408 return -EINVAL;
409 if (is_broadcast_ether_addr(param->sta_addr)) {
410 if (param->u.crypt.idx >= WEP_KEYS) {
411
412 param->u.crypt.idx = 0;
413 }
414 } else
415 return -EINVAL;
416 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
417 netdev_info(dev, "r8712u: %s: crypt.alg = WEP\n", __func__);
418 padapter->securitypriv.ndisencryptstatus =
419 Ndis802_11Encryption1Enabled;
420 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
421 padapter->securitypriv.XGrpPrivacy = _WEP40_;
422 wep_key_idx = param->u.crypt.idx;
423 wep_key_len = param->u.crypt.key_len;
424 if (wep_key_idx >= WEP_KEYS)
425 wep_key_idx = 0;
426 if (wep_key_len > 0) {
427 wep_key_len = wep_key_len <= 5 ? 5 : 13;
428 pwep = (struct NDIS_802_11_WEP *)_malloc((u32)
429 (wep_key_len +
430 FIELD_OFFSET(struct NDIS_802_11_WEP,
431 KeyMaterial)));
432 if (pwep == NULL)
433 return -ENOMEM;
434 memset(pwep, 0, sizeof(struct NDIS_802_11_WEP));
435 pwep->KeyLength = wep_key_len;
436 pwep->Length = wep_key_len +
437 FIELD_OFFSET(struct NDIS_802_11_WEP,
438 KeyMaterial);
439 if (wep_key_len == 13) {
440 padapter->securitypriv.PrivacyAlgrthm =
441 _WEP104_;
442 padapter->securitypriv.XGrpPrivacy =
443 _WEP104_;
444 }
445 } else
446 return -EINVAL;
447 pwep->KeyIndex = wep_key_idx;
448 pwep->KeyIndex |= 0x80000000;
449 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
450 if (param->u.crypt.set_tx) {
451 if (r8712_set_802_11_add_wep(padapter, pwep) ==
452 (u8)_FAIL)
453 ret = -EOPNOTSUPP;
454 } else {
455
456
457
458
459 if (wep_key_idx >= WEP_KEYS) {
460 ret = -EOPNOTSUPP;
461 goto exit;
462 }
463 memcpy(&(psecuritypriv->DefKey[wep_key_idx].
464 skey[0]), pwep->KeyMaterial,
465 pwep->KeyLength);
466 psecuritypriv->DefKeylen[wep_key_idx] =
467 pwep->KeyLength;
468 r8712_set_key(padapter, psecuritypriv, wep_key_idx);
469 }
470 goto exit;
471 }
472 if (padapter->securitypriv.AuthAlgrthm == 2) {
473 struct sta_info *psta, *pbcmc_sta;
474 struct sta_priv *pstapriv = &padapter->stapriv;
475
476 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE |
477 WIFI_MP_STATE) == true) {
478 psta = r8712_get_stainfo(pstapriv,
479 get_bssid(pmlmepriv));
480 if (psta) {
481 psta->ieee8021x_blocked = false;
482 if ((padapter->securitypriv.ndisencryptstatus ==
483 Ndis802_11Encryption2Enabled) ||
484 (padapter->securitypriv.ndisencryptstatus ==
485 Ndis802_11Encryption3Enabled))
486 psta->XPrivacy = padapter->
487 securitypriv.PrivacyAlgrthm;
488 if (param->u.crypt.set_tx == 1)
489 handle_pairwise_key(psta, param,
490 padapter);
491 else
492 handle_group_key(param, padapter);
493 }
494 pbcmc_sta = r8712_get_bcmc_stainfo(padapter);
495 if (pbcmc_sta) {
496 pbcmc_sta->ieee8021x_blocked = false;
497 if ((padapter->securitypriv.ndisencryptstatus ==
498 Ndis802_11Encryption2Enabled) ||
499 (padapter->securitypriv.ndisencryptstatus ==
500 Ndis802_11Encryption3Enabled))
501 pbcmc_sta->XPrivacy =
502 padapter->securitypriv.
503 PrivacyAlgrthm;
504 }
505 }
506 }
507exit:
508 kfree((u8 *)pwep);
509 return ret;
510}
511
512static int r871x_set_wpa_ie(struct _adapter *padapter, char *pie,
513 unsigned short ielen)
514{
515 u8 *buf = NULL, *pos = NULL;
516 int group_cipher = 0, pairwise_cipher = 0;
517 int ret = 0;
518
519 if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL))
520 return -EINVAL;
521 if (ielen) {
522 buf = _malloc(ielen);
523 if (buf == NULL)
524 return -ENOMEM;
525 memcpy(buf, pie , ielen);
526 pos = buf;
527 if (ielen < RSN_HEADER_LEN) {
528 ret = -EINVAL;
529 goto exit;
530 }
531 if (r8712_parse_wpa_ie(buf, ielen, &group_cipher,
532 &pairwise_cipher) == _SUCCESS) {
533 padapter->securitypriv.AuthAlgrthm = 2;
534 padapter->securitypriv.ndisauthtype =
535 Ndis802_11AuthModeWPAPSK;
536 }
537 if (r8712_parse_wpa2_ie(buf, ielen, &group_cipher,
538 &pairwise_cipher) == _SUCCESS) {
539 padapter->securitypriv.AuthAlgrthm = 2;
540 padapter->securitypriv.ndisauthtype =
541 Ndis802_11AuthModeWPA2PSK;
542 }
543 switch (group_cipher) {
544 case WPA_CIPHER_NONE:
545 padapter->securitypriv.XGrpPrivacy =
546 _NO_PRIVACY_;
547 padapter->securitypriv.ndisencryptstatus =
548 Ndis802_11EncryptionDisabled;
549 break;
550 case WPA_CIPHER_WEP40:
551 padapter->securitypriv.XGrpPrivacy = _WEP40_;
552 padapter->securitypriv.ndisencryptstatus =
553 Ndis802_11Encryption1Enabled;
554 break;
555 case WPA_CIPHER_TKIP:
556 padapter->securitypriv.XGrpPrivacy = _TKIP_;
557 padapter->securitypriv.ndisencryptstatus =
558 Ndis802_11Encryption2Enabled;
559 break;
560 case WPA_CIPHER_CCMP:
561 padapter->securitypriv.XGrpPrivacy = _AES_;
562 padapter->securitypriv.ndisencryptstatus =
563 Ndis802_11Encryption3Enabled;
564 break;
565 case WPA_CIPHER_WEP104:
566 padapter->securitypriv.XGrpPrivacy = _WEP104_;
567 padapter->securitypriv.ndisencryptstatus =
568 Ndis802_11Encryption1Enabled;
569 break;
570 }
571 switch (pairwise_cipher) {
572 case WPA_CIPHER_NONE:
573 padapter->securitypriv.PrivacyAlgrthm =
574 _NO_PRIVACY_;
575 padapter->securitypriv.ndisencryptstatus =
576 Ndis802_11EncryptionDisabled;
577 break;
578 case WPA_CIPHER_WEP40:
579 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
580 padapter->securitypriv.ndisencryptstatus =
581 Ndis802_11Encryption1Enabled;
582 break;
583 case WPA_CIPHER_TKIP:
584 padapter->securitypriv.PrivacyAlgrthm = _TKIP_;
585 padapter->securitypriv.ndisencryptstatus =
586 Ndis802_11Encryption2Enabled;
587 break;
588 case WPA_CIPHER_CCMP:
589 padapter->securitypriv.PrivacyAlgrthm = _AES_;
590 padapter->securitypriv.ndisencryptstatus =
591 Ndis802_11Encryption3Enabled;
592 break;
593 case WPA_CIPHER_WEP104:
594 padapter->securitypriv.PrivacyAlgrthm = _WEP104_;
595 padapter->securitypriv.ndisencryptstatus =
596 Ndis802_11Encryption1Enabled;
597 break;
598 }
599 padapter->securitypriv.wps_phase = false;
600 {
601 u16 cnt = 0;
602 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
603
604 while (cnt < ielen) {
605 eid = buf[cnt];
606
607 if ((eid == _VENDOR_SPECIFIC_IE_) &&
608 (!memcmp(&buf[cnt+2], wps_oui, 4))) {
609 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE\n");
610 padapter->securitypriv.wps_ie_len =
611 ((buf[cnt+1] + 2) <
612 (MAX_WPA_IE_LEN << 2)) ?
613 (buf[cnt + 1] + 2) :
614 (MAX_WPA_IE_LEN << 2);
615 memcpy(padapter->securitypriv.wps_ie,
616 &buf[cnt],
617 padapter->securitypriv.wps_ie_len);
618 padapter->securitypriv.wps_phase =
619 true;
620 netdev_info(padapter->pnetdev, "r8712u: SET WPS_IE, wps_phase==true\n");
621 cnt += buf[cnt+1]+2;
622 break;
623 } else
624 cnt += buf[cnt + 1] + 2;
625 }
626 }
627 }
628exit:
629 kfree(buf);
630 return ret;
631}
632
633static int r8711_wx_get_name(struct net_device *dev,
634 struct iw_request_info *info,
635 union iwreq_data *wrqu, char *extra)
636{
637 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
638 u32 ht_ielen = 0;
639 char *p;
640 u8 ht_cap = false;
641 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
642 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
643 NDIS_802_11_RATES_EX *prates = NULL;
644
645 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) ==
646 true) {
647
648 p = r8712_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_,
649 &ht_ielen, pcur_bss->IELength - 12);
650 if (p && ht_ielen > 0)
651 ht_cap = true;
652 prates = &pcur_bss->SupportedRates;
653 if (r8712_is_cckratesonly_included((u8 *)prates) == true) {
654 if (ht_cap == true)
655 snprintf(wrqu->name, IFNAMSIZ,
656 "IEEE 802.11bn");
657 else
658 snprintf(wrqu->name, IFNAMSIZ,
659 "IEEE 802.11b");
660 } else if ((r8712_is_cckrates_included((u8 *)prates)) == true) {
661 if (ht_cap == true)
662 snprintf(wrqu->name, IFNAMSIZ,
663 "IEEE 802.11bgn");
664 else
665 snprintf(wrqu->name, IFNAMSIZ,
666 "IEEE 802.11bg");
667 } else {
668 if (ht_cap == true)
669 snprintf(wrqu->name, IFNAMSIZ,
670 "IEEE 802.11gn");
671 else
672 snprintf(wrqu->name, IFNAMSIZ,
673 "IEEE 802.11g");
674 }
675 } else
676 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
677 return 0;
678}
679
680static const long frequency_list[] = {
681 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
682 2467, 2472, 2484, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
683 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210,
684 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560,
685 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, 5765, 5785, 5805,
686 5825
687};
688
689static int r8711_wx_set_freq(struct net_device *dev,
690 struct iw_request_info *info,
691 union iwreq_data *wrqu, char *extra)
692{
693 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
694 struct iw_freq *fwrq = &wrqu->freq;
695 int rc = 0;
696
697
698 if ((fwrq->e == 1) &&
699 (fwrq->m >= (int) 2.412e8) &&
700 (fwrq->m <= (int) 2.487e8)) {
701 int f = fwrq->m / 100000;
702 int c = 0;
703 while ((c < 14) && (f != frequency_list[c]))
704 c++;
705 fwrq->e = 0;
706 fwrq->m = c + 1;
707 }
708
709 if ((fwrq->m > 14) || (fwrq->e > 0))
710 rc = -EOPNOTSUPP;
711 else {
712 int channel = fwrq->m;
713 if ((channel < 1) || (channel > 14))
714 rc = -EINVAL;
715 else {
716
717 padapter->registrypriv.channel = channel;
718 }
719 }
720 return rc;
721}
722
723static int r8711_wx_get_freq(struct net_device *dev,
724 struct iw_request_info *info,
725 union iwreq_data *wrqu, char *extra)
726{
727 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
728 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
729 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
730
731 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
732 wrqu->freq.m = ieee80211_wlan_frequencies[
733 pcur_bss->Configuration.DSConfig-1] * 100000;
734 wrqu->freq.e = 1;
735 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
736 } else {
737 return -ENOLINK;
738 }
739 return 0;
740}
741
742static int r8711_wx_set_mode(struct net_device *dev,
743 struct iw_request_info *a,
744 union iwreq_data *wrqu, char *b)
745{
746 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
747 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
748
749 switch (wrqu->mode) {
750 case IW_MODE_AUTO:
751 networkType = Ndis802_11AutoUnknown;
752 break;
753 case IW_MODE_ADHOC:
754 networkType = Ndis802_11IBSS;
755 break;
756 case IW_MODE_MASTER:
757 networkType = Ndis802_11APMode;
758 break;
759 case IW_MODE_INFRA:
760 networkType = Ndis802_11Infrastructure;
761 break;
762 default:
763 return -EINVAL;
764 }
765 if (Ndis802_11APMode == networkType)
766 r8712_setopmode_cmd(padapter, networkType);
767 else
768 r8712_setopmode_cmd(padapter, Ndis802_11AutoUnknown);
769
770 r8712_set_802_11_infrastructure_mode(padapter, networkType);
771 return 0;
772}
773
774static int r8711_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
775 union iwreq_data *wrqu, char *b)
776{
777 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
778 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
779
780 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
781 wrqu->mode = IW_MODE_INFRA;
782 else if (check_fwstate(pmlmepriv,
783 WIFI_ADHOC_MASTER_STATE|WIFI_ADHOC_STATE) == true)
784 wrqu->mode = IW_MODE_ADHOC;
785 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
786 wrqu->mode = IW_MODE_MASTER;
787 else
788 wrqu->mode = IW_MODE_AUTO;
789 return 0;
790}
791
792static int r871x_wx_set_pmkid(struct net_device *dev,
793 struct iw_request_info *a,
794 union iwreq_data *wrqu, char *extra)
795{
796 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
797 struct security_priv *psecuritypriv = &padapter->securitypriv;
798 struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
799 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
800 u8 strIssueBssid[ETH_ALEN] = {0x00};
801 u8 j, blInserted = false;
802 int intReturn = false;
803
804
805
806
807
808
809
810
811
812 if (pPMK == NULL)
813 return -EINVAL;
814 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
815 switch (pPMK->cmd) {
816 case IW_PMKSA_ADD:
817 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
818 return intReturn;
819 else
820 intReturn = true;
821 blInserted = false;
822
823 for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
824 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
825 strIssueBssid, ETH_ALEN)) {
826
827
828 netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n",
829 __func__);
830 memcpy(psecuritypriv->PMKIDList[j].PMKID,
831 pPMK->pmkid, IW_PMKID_LEN);
832 psecuritypriv->PMKIDList[j].bUsed = true;
833 psecuritypriv->PMKIDIndex = j + 1;
834 blInserted = true;
835 break;
836 }
837 }
838 if (!blInserted) {
839
840 netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n",
841 __func__, psecuritypriv->PMKIDIndex);
842 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
843 PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
844 memcpy(psecuritypriv->PMKIDList[psecuritypriv->
845 PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
846 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
847 bUsed = true;
848 psecuritypriv->PMKIDIndex++ ;
849 if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
850 psecuritypriv->PMKIDIndex = 0;
851 }
852 break;
853 case IW_PMKSA_REMOVE:
854 intReturn = true;
855 for (j = 0; j < NUM_PMKID_CACHE; j++) {
856 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
857 strIssueBssid, ETH_ALEN)) {
858
859
860 memset(psecuritypriv->PMKIDList[j].Bssid,
861 0x00, ETH_ALEN);
862 psecuritypriv->PMKIDList[j].bUsed = false;
863 break;
864 }
865 }
866 break;
867 case IW_PMKSA_FLUSH:
868 memset(psecuritypriv->PMKIDList, 0,
869 sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
870 psecuritypriv->PMKIDIndex = 0;
871 intReturn = true;
872 break;
873 default:
874 netdev_info(dev, "r8712u: %s: unknown Command\n", __func__);
875 intReturn = false;
876 break;
877 }
878 return intReturn;
879}
880
881static int r8711_wx_get_sens(struct net_device *dev,
882 struct iw_request_info *info,
883 union iwreq_data *wrqu, char *extra)
884{
885 wrqu->sens.value = 0;
886 wrqu->sens.fixed = 0;
887 wrqu->sens.disabled = 1;
888 return 0;
889}
890
891static int r8711_wx_get_range(struct net_device *dev,
892 struct iw_request_info *info,
893 union iwreq_data *wrqu, char *extra)
894{
895 struct iw_range *range = (struct iw_range *)extra;
896 u16 val;
897 int i;
898
899 wrqu->data.length = sizeof(*range);
900 memset(range, 0, sizeof(*range));
901
902
903
904
905
906
907
908
909 range->throughput = 5 * 1000 * 1000;
910
911
912
913 range->max_qual.qual = 100;
914 range->max_qual.level = 100;
915 range->max_qual.noise = 100;
916 range->max_qual.updated = 7;
917 range->avg_qual.qual = 92;
918
919 range->avg_qual.level = 20 + -98;
920 range->avg_qual.noise = 0;
921 range->avg_qual.updated = 7;
922 range->num_bitrates = RATE_COUNT;
923 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
924 range->bitrate[i] = rtl8180_rates[i];
925 range->min_frag = MIN_FRAG_THRESHOLD;
926 range->max_frag = MAX_FRAG_THRESHOLD;
927 range->pm_capa = 0;
928 range->we_version_compiled = WIRELESS_EXT;
929 range->we_version_source = 16;
930 range->num_channels = 14;
931 for (i = 0, val = 0; i < 14; i++) {
932
933 range->freq[val].i = i + 1;
934 range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
935 range->freq[val].e = 1;
936 val++;
937 if (val == IW_MAX_FREQUENCIES)
938 break;
939 }
940 range->num_frequency = val;
941 range->enc_capa = IW_ENC_CAPA_WPA |
942 IW_ENC_CAPA_WPA2 |
943 IW_ENC_CAPA_CIPHER_TKIP |
944 IW_ENC_CAPA_CIPHER_CCMP;
945 return 0;
946}
947
948static int r8711_wx_get_rate(struct net_device *dev,
949 struct iw_request_info *info,
950 union iwreq_data *wrqu, char *extra);
951
952static int r871x_wx_set_priv(struct net_device *dev,
953 struct iw_request_info *info,
954 union iwreq_data *awrq,
955 char *extra)
956{
957 int ret = 0, len = 0;
958 char *ext;
959 struct _adapter *padapter = netdev_priv(dev);
960 struct iw_point *dwrq = (struct iw_point *)awrq;
961
962 len = dwrq->length;
963 ext = _malloc(len);
964 if (!ext)
965 return -ENOMEM;
966 if (copy_from_user(ext, dwrq->pointer, len)) {
967 kfree(ext);
968 return -EFAULT;
969 }
970
971 if (0 == strcasecmp(ext, "RSSI")) {
972
973
974
975 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
976 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
977
978 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
979 sprintf(ext, "%s rssi %d",
980 pcur_network->network.Ssid.Ssid,
981
982 ((padapter->recvpriv.fw_rssi)>>1)-95
983
984 );
985 } else {
986 sprintf(ext, "OK");
987 }
988 } else if (0 == strcasecmp(ext, "LINKSPEED")) {
989
990
991 union iwreq_data wrqd;
992 int ret_inner;
993 int mbps;
994
995 ret_inner = r8711_wx_get_rate(dev, info, &wrqd, extra);
996 if (0 != ret_inner)
997 mbps = 0;
998 else
999 mbps = wrqd.bitrate.value / 1000000;
1000 sprintf(ext, "LINKSPEED %d", mbps);
1001 } else if (0 == strcasecmp(ext, "MACADDR")) {
1002
1003
1004 sprintf(ext,
1005 "MACADDR = %02x.%02x.%02x.%02x.%02x.%02x",
1006 *(dev->dev_addr), *(dev->dev_addr+1),
1007 *(dev->dev_addr+2), *(dev->dev_addr+3),
1008 *(dev->dev_addr+4), *(dev->dev_addr+5));
1009 } else if (0 == strcasecmp(ext, "SCAN-ACTIVE")) {
1010
1011
1012 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1013 pmlmepriv->passive_mode = 1;
1014 sprintf(ext, "OK");
1015 } else if (0 == strcasecmp(ext, "SCAN-PASSIVE")) {
1016
1017
1018 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1019 pmlmepriv->passive_mode = 0;
1020 sprintf(ext, "OK");
1021 } else if (0 == strncmp(ext, "DCE-E", 5)) {
1022
1023
1024 r8712_disconnectCtrlEx_cmd(padapter
1025 , 1
1026 , 5
1027 , 100
1028 , 5000
1029 );
1030 sprintf(ext, "OK");
1031 } else if (0 == strncmp(ext, "DCE-D", 5)) {
1032
1033
1034 r8712_disconnectCtrlEx_cmd(padapter
1035 , 0
1036 , 5
1037 , 100
1038 , 5000
1039 );
1040 sprintf(ext, "OK");
1041 } else {
1042 netdev_info(dev, "r8712u: %s: unknown Command %s.\n",
1043 __func__, ext);
1044 goto FREE_EXT;
1045 }
1046 if (copy_to_user(dwrq->pointer, ext,
1047 min(dwrq->length, (__u16)(strlen(ext)+1))))
1048 ret = -EFAULT;
1049
1050FREE_EXT:
1051 kfree(ext);
1052 return ret;
1053}
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068static int r8711_wx_set_wap(struct net_device *dev,
1069 struct iw_request_info *info,
1070 union iwreq_data *awrq,
1071 char *extra)
1072{
1073 int ret = -EINPROGRESS;
1074 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
1075 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1076 struct __queue *queue = &pmlmepriv->scanned_queue;
1077 struct sockaddr *temp = (struct sockaddr *)awrq;
1078 unsigned long irqL;
1079 struct list_head *phead;
1080 u8 *dst_bssid;
1081 struct wlan_network *pnetwork = NULL;
1082 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1083
1084 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true)
1085 return -EBUSY;
1086 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
1087 return ret;
1088 if (temp->sa_family != ARPHRD_ETHER)
1089 return -EINVAL;
1090 authmode = padapter->securitypriv.ndisauthtype;
1091 spin_lock_irqsave(&queue->lock, irqL);
1092 phead = get_list_head(queue);
1093 pmlmepriv->pscanned = get_next(phead);
1094 while (1) {
1095 if (end_of_queue_search(phead, pmlmepriv->pscanned) == true)
1096 break;
1097 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1098 struct wlan_network, list);
1099 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1100 dst_bssid = pnetwork->network.MacAddress;
1101 if (!memcmp(dst_bssid, temp->sa_data, ETH_ALEN)) {
1102 r8712_set_802_11_infrastructure_mode(padapter,
1103 pnetwork->network.InfrastructureMode);
1104 break;
1105 }
1106 }
1107 spin_unlock_irqrestore(&queue->lock, irqL);
1108 if (!ret) {
1109 if (!r8712_set_802_11_authentication_mode(padapter, authmode))
1110 ret = -ENOMEM;
1111 else {
1112 if (!r8712_set_802_11_bssid(padapter, temp->sa_data))
1113 ret = -1;
1114 }
1115 }
1116 return ret;
1117}
1118
1119static int r8711_wx_get_wap(struct net_device *dev,
1120 struct iw_request_info *info,
1121 union iwreq_data *wrqu, char *extra)
1122{
1123 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1124 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1125 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1126
1127 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1128 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE |
1129 WIFI_AP_STATE))
1130 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1131 else
1132 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1133 return 0;
1134}
1135
1136static int r871x_wx_set_mlme(struct net_device *dev,
1137 struct iw_request_info *info,
1138 union iwreq_data *wrqu, char *extra)
1139{
1140 int ret = 0;
1141 u16 reason;
1142 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1143 struct iw_mlme *mlme = (struct iw_mlme *) extra;
1144
1145 if (mlme == NULL)
1146 return -1;
1147 reason = cpu_to_le16(mlme->reason_code);
1148 switch (mlme->cmd) {
1149 case IW_MLME_DEAUTH:
1150 if (!r8712_set_802_11_disassociate(padapter))
1151 ret = -1;
1152 break;
1153 case IW_MLME_DISASSOC:
1154 if (!r8712_set_802_11_disassociate(padapter))
1155 ret = -1;
1156 break;
1157 default:
1158 return -EOPNOTSUPP;
1159 }
1160 return ret;
1161}
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171static int r8711_wx_set_scan(struct net_device *dev,
1172 struct iw_request_info *a,
1173 union iwreq_data *wrqu, char *extra)
1174{
1175 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1176 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1177 u8 status = true;
1178
1179 if (padapter->bDriverStopped == true) {
1180 netdev_info(dev, "In %s: bDriverStopped=%d\n",
1181 __func__, padapter->bDriverStopped);
1182 return -1;
1183 }
1184 if (padapter->bup == false)
1185 return -ENETDOWN;
1186 if (padapter->hw_init_completed == false)
1187 return -1;
1188 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) ||
1189 (pmlmepriv->sitesurveyctrl.traffic_busy == true))
1190 return 0;
1191 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1192 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1193 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1194 struct ndis_802_11_ssid ssid;
1195 unsigned long irqL;
1196 u32 len = min_t(u8, req->essid_len, IW_ESSID_MAX_SIZE);
1197 memset((unsigned char *)&ssid, 0,
1198 sizeof(struct ndis_802_11_ssid));
1199 memcpy(ssid.Ssid, req->essid, len);
1200 ssid.SsidLength = len;
1201 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1202 if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY |
1203 _FW_UNDER_LINKING)) ||
1204 (pmlmepriv->sitesurveyctrl.traffic_busy == true)) {
1205 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1206 status = false;
1207 } else
1208 status = r8712_sitesurvey_cmd(padapter, &ssid);
1209 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1210 }
1211 } else
1212 status = r8712_set_802_11_bssid_list_scan(padapter);
1213 if (status == false)
1214 return -1;
1215 return 0;
1216}
1217
1218static int r8711_wx_get_scan(struct net_device *dev,
1219 struct iw_request_info *a,
1220 union iwreq_data *wrqu, char *extra)
1221{
1222 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1223 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1224 struct __queue *queue = &pmlmepriv->scanned_queue;
1225 struct wlan_network *pnetwork = NULL;
1226 unsigned long irqL;
1227 struct list_head *plist, *phead;
1228 char *ev = extra;
1229 char *stop = ev + wrqu->data.length;
1230 u32 ret = 0, cnt = 0;
1231
1232 if (padapter->bDriverStopped)
1233 return -EINVAL;
1234 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
1235 msleep(30);
1236 cnt++;
1237 if (cnt > 100)
1238 break;
1239 }
1240 spin_lock_irqsave(&queue->lock, irqL);
1241 phead = get_list_head(queue);
1242 plist = get_next(phead);
1243 while (1) {
1244 if (end_of_queue_search(phead, plist) == true)
1245 break;
1246 if ((stop - ev) < SCAN_ITEM_SIZE) {
1247 ret = -E2BIG;
1248 break;
1249 }
1250 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1251 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1252 plist = get_next(plist);
1253 }
1254 spin_unlock_irqrestore(&queue->lock, irqL);
1255 wrqu->data.length = ev - extra;
1256 wrqu->data.flags = 0;
1257 return ret;
1258}
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272static int r8711_wx_set_essid(struct net_device *dev,
1273 struct iw_request_info *a,
1274 union iwreq_data *wrqu, char *extra)
1275{
1276 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1277 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1278 struct __queue *queue = &pmlmepriv->scanned_queue;
1279 struct wlan_network *pnetwork = NULL;
1280 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1281 struct ndis_802_11_ssid ndis_ssid;
1282 u8 *dst_ssid, *src_ssid;
1283 struct list_head *phead;
1284 u32 len;
1285
1286 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1287 return -EBUSY;
1288 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
1289 return 0;
1290 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1291 return -E2BIG;
1292 authmode = padapter->securitypriv.ndisauthtype;
1293 if (wrqu->essid.flags && wrqu->essid.length) {
1294 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ?
1295 wrqu->essid.length : IW_ESSID_MAX_SIZE;
1296 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1297 ndis_ssid.SsidLength = len;
1298 memcpy(ndis_ssid.Ssid, extra, len);
1299 src_ssid = ndis_ssid.Ssid;
1300 phead = get_list_head(queue);
1301 pmlmepriv->pscanned = get_next(phead);
1302 while (1) {
1303 if (end_of_queue_search(phead, pmlmepriv->pscanned))
1304 break;
1305 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned,
1306 struct wlan_network, list);
1307 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1308 dst_ssid = pnetwork->network.Ssid.Ssid;
1309 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength))
1310 && (pnetwork->network.Ssid.SsidLength ==
1311 ndis_ssid.SsidLength)) {
1312 if (check_fwstate(pmlmepriv,
1313 WIFI_ADHOC_STATE)) {
1314 if (pnetwork->network.
1315 InfrastructureMode
1316 !=
1317 padapter->mlmepriv.
1318 cur_network.network.
1319 InfrastructureMode)
1320 continue;
1321 }
1322
1323 r8712_set_802_11_infrastructure_mode(
1324 padapter,
1325 pnetwork->network.InfrastructureMode);
1326 break;
1327 }
1328 }
1329 r8712_set_802_11_authentication_mode(padapter, authmode);
1330 r8712_set_802_11_ssid(padapter, &ndis_ssid);
1331 }
1332 return -EINPROGRESS;
1333}
1334
1335static int r8711_wx_get_essid(struct net_device *dev,
1336 struct iw_request_info *a,
1337 union iwreq_data *wrqu, char *extra)
1338{
1339 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1340 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1341 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1342 u32 len, ret = 0;
1343
1344 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1345 len = pcur_bss->Ssid.SsidLength;
1346 wrqu->essid.length = len;
1347 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1348 wrqu->essid.flags = 1;
1349 } else {
1350 ret = -ENOLINK;
1351 }
1352 return ret;
1353}
1354
1355static int r8711_wx_set_rate(struct net_device *dev,
1356 struct iw_request_info *a,
1357 union iwreq_data *wrqu, char *extra)
1358{
1359 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1360 u32 target_rate = wrqu->bitrate.value;
1361 u32 fixed = wrqu->bitrate.fixed;
1362 u32 ratevalue = 0;
1363 u8 datarates[NumRates];
1364 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1365 int i, ret = 0;
1366
1367 if (target_rate == -1) {
1368 ratevalue = 11;
1369 goto set_rate;
1370 }
1371 target_rate = target_rate / 100000;
1372 switch (target_rate) {
1373 case 10:
1374 ratevalue = 0;
1375 break;
1376 case 20:
1377 ratevalue = 1;
1378 break;
1379 case 55:
1380 ratevalue = 2;
1381 break;
1382 case 60:
1383 ratevalue = 3;
1384 break;
1385 case 90:
1386 ratevalue = 4;
1387 break;
1388 case 110:
1389 ratevalue = 5;
1390 break;
1391 case 120:
1392 ratevalue = 6;
1393 break;
1394 case 180:
1395 ratevalue = 7;
1396 break;
1397 case 240:
1398 ratevalue = 8;
1399 break;
1400 case 360:
1401 ratevalue = 9;
1402 break;
1403 case 480:
1404 ratevalue = 10;
1405 break;
1406 case 540:
1407 ratevalue = 11;
1408 break;
1409 default:
1410 ratevalue = 11;
1411 break;
1412 }
1413set_rate:
1414 for (i = 0; i < NumRates; i++) {
1415 if (ratevalue == mpdatarate[i]) {
1416 datarates[i] = mpdatarate[i];
1417 if (fixed == 0)
1418 break;
1419 } else
1420 datarates[i] = 0xff;
1421 }
1422 if (r8712_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1423 ret = -ENOMEM;
1424 return ret;
1425}
1426
1427static int r8711_wx_get_rate(struct net_device *dev,
1428 struct iw_request_info *info,
1429 union iwreq_data *wrqu, char *extra)
1430{
1431 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1432 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1433 struct ndis_wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1434 struct ieee80211_ht_cap *pht_capie;
1435 unsigned char rf_type = padapter->registrypriv.rf_config;
1436 int i;
1437 u8 *p;
1438 u16 rate, max_rate = 0, ht_cap = false;
1439 u32 ht_ielen = 0;
1440 u8 bw_40MHz = 0, short_GI = 0;
1441 u16 mcs_rate = 0;
1442
1443 i = 0;
1444 if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1445 p = r8712_get_ie(&pcur_bss->IEs[12],
1446 _HT_CAPABILITY_IE_, &ht_ielen,
1447 pcur_bss->IELength - 12);
1448 if (p && ht_ielen > 0) {
1449 ht_cap = true;
1450 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
1451 memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
1452 bw_40MHz = (pht_capie->cap_info &
1453 IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
1454 short_GI = (pht_capie->cap_info &
1455 (IEEE80211_HT_CAP_SGI_20 |
1456 IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
1457 }
1458 while ((pcur_bss->SupportedRates[i] != 0) &&
1459 (pcur_bss->SupportedRates[i] != 0xFF)) {
1460 rate = pcur_bss->SupportedRates[i] & 0x7F;
1461 if (rate > max_rate)
1462 max_rate = rate;
1463 wrqu->bitrate.fixed = 0;
1464 wrqu->bitrate.value = rate*500000;
1465 i++;
1466 }
1467 if (ht_cap == true) {
1468 if (mcs_rate & 0x8000
1469 &&
1470 RTL8712_RF_2T2R == rf_type)
1471 max_rate = (bw_40MHz) ? ((short_GI) ? 300 :
1472 270) : ((short_GI) ? 144 : 130);
1473 else if (mcs_rate & 0x0080)
1474 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1475 135) : ((short_GI) ? 72 : 65);
1476 else
1477 max_rate = (bw_40MHz) ? ((short_GI) ? 150 :
1478 135) : ((short_GI) ? 72 : 65);
1479 max_rate *= 2;
1480 wrqu->bitrate.value = max_rate * 500000;
1481 } else {
1482 wrqu->bitrate.value = max_rate * 500000;
1483 }
1484 } else
1485 return -ENOLINK;
1486 return 0;
1487}
1488
1489static int r8711_wx_get_rts(struct net_device *dev,
1490 struct iw_request_info *info,
1491 union iwreq_data *wrqu, char *extra)
1492{
1493 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1494
1495 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1496 wrqu->rts.fixed = 0;
1497 return 0;
1498}
1499
1500static int r8711_wx_set_frag(struct net_device *dev,
1501 struct iw_request_info *info,
1502 union iwreq_data *wrqu, char *extra)
1503{
1504 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1505
1506 if (wrqu->frag.disabled)
1507 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1508 else {
1509 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1510 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1511 return -EINVAL;
1512 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1513 }
1514 return 0;
1515}
1516
1517static int r8711_wx_get_frag(struct net_device *dev,
1518 struct iw_request_info *info,
1519 union iwreq_data *wrqu, char *extra)
1520{
1521 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
1522
1523 wrqu->frag.value = padapter->xmitpriv.frag_len;
1524 wrqu->frag.fixed = 0;
1525 return 0;
1526}
1527
1528static int r8711_wx_get_retry(struct net_device *dev,
1529 struct iw_request_info *info,
1530 union iwreq_data *wrqu, char *extra)
1531{
1532 wrqu->retry.value = 7;
1533 wrqu->retry.fixed = 0;
1534 wrqu->retry.disabled = 1;
1535 return 0;
1536}
1537
1538static int r8711_wx_set_enc(struct net_device *dev,
1539 struct iw_request_info *info,
1540 union iwreq_data *wrqu, char *keybuf)
1541{
1542 u32 key;
1543 u32 keyindex_provided;
1544 struct NDIS_802_11_WEP wep;
1545 enum NDIS_802_11_AUTHENTICATION_MODE authmode;
1546 struct iw_point *erq = &(wrqu->encoding);
1547 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
1548
1549 key = erq->flags & IW_ENCODE_INDEX;
1550 memset(&wep, 0, sizeof(struct NDIS_802_11_WEP));
1551 if (erq->flags & IW_ENCODE_DISABLED) {
1552 netdev_info(dev, "r8712u: %s: EncryptionDisabled\n", __func__);
1553 padapter->securitypriv.ndisencryptstatus =
1554 Ndis802_11EncryptionDisabled;
1555 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1556 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1557 padapter->securitypriv.AuthAlgrthm = 0;
1558 authmode = Ndis802_11AuthModeOpen;
1559 padapter->securitypriv.ndisauthtype = authmode;
1560 return 0;
1561 }
1562 if (key) {
1563 if (key > WEP_KEYS)
1564 return -EINVAL;
1565 key--;
1566 keyindex_provided = 1;
1567 } else {
1568 keyindex_provided = 0;
1569 key = padapter->securitypriv.PrivacyKeyIndex;
1570 }
1571
1572 if (erq->flags & IW_ENCODE_OPEN) {
1573 netdev_info(dev, "r8712u: %s: IW_ENCODE_OPEN\n", __func__);
1574 padapter->securitypriv.ndisencryptstatus =
1575 Ndis802_11Encryption1Enabled;
1576 padapter->securitypriv.AuthAlgrthm = 0;
1577 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1578 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1579 authmode = Ndis802_11AuthModeOpen;
1580 padapter->securitypriv.ndisauthtype = authmode;
1581 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1582 netdev_info(dev, "r8712u: %s: IW_ENCODE_RESTRICTED\n", __func__);
1583 padapter->securitypriv.ndisencryptstatus =
1584 Ndis802_11Encryption1Enabled;
1585 padapter->securitypriv.AuthAlgrthm = 1;
1586 padapter->securitypriv.PrivacyAlgrthm = _WEP40_;
1587 padapter->securitypriv.XGrpPrivacy = _WEP40_;
1588 authmode = Ndis802_11AuthModeShared;
1589 padapter->securitypriv.ndisauthtype = authmode;
1590 } else {
1591 padapter->securitypriv.ndisencryptstatus =
1592 Ndis802_11Encryption1Enabled;
1593 padapter->securitypriv.AuthAlgrthm = 0;
1594 padapter->securitypriv.PrivacyAlgrthm = _NO_PRIVACY_;
1595 padapter->securitypriv.XGrpPrivacy = _NO_PRIVACY_;
1596 authmode = Ndis802_11AuthModeOpen;
1597 padapter->securitypriv.ndisauthtype = authmode;
1598 }
1599 wep.KeyIndex = key;
1600 if (erq->length > 0) {
1601 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1602 wep.Length = wep.KeyLength +
1603 FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
1604 } else {
1605 wep.KeyLength = 0 ;
1606 if (keyindex_provided == 1) {
1607
1608 padapter->securitypriv.PrivacyKeyIndex = key;
1609 switch (padapter->securitypriv.DefKeylen[key]) {
1610 case 5:
1611 padapter->securitypriv.PrivacyAlgrthm =
1612 _WEP40_;
1613 break;
1614 case 13:
1615 padapter->securitypriv.PrivacyAlgrthm =
1616 _WEP104_;
1617 break;
1618 default:
1619 padapter->securitypriv.PrivacyAlgrthm =
1620 _NO_PRIVACY_;
1621 break;
1622 }
1623 return 0;
1624 }
1625 }
1626 wep.KeyIndex |= 0x80000000;
1627 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1628 if (r8712_set_802_11_add_wep(padapter, &wep) == _FAIL)
1629 return -EOPNOTSUPP;
1630 return 0;
1631}
1632
1633static int r8711_wx_get_enc(struct net_device *dev,
1634 struct iw_request_info *info,
1635 union iwreq_data *wrqu, char *keybuf)
1636{
1637 uint key, ret = 0;
1638 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
1639 struct iw_point *erq = &(wrqu->encoding);
1640 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1641
1642 if (check_fwstate(pmlmepriv, _FW_LINKED) == false) {
1643 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1644 erq->length = 0;
1645 erq->flags |= IW_ENCODE_DISABLED;
1646 return 0;
1647 }
1648 }
1649 key = erq->flags & IW_ENCODE_INDEX;
1650 if (key) {
1651 if (key > WEP_KEYS)
1652 return -EINVAL;
1653 key--;
1654 } else {
1655 key = padapter->securitypriv.PrivacyKeyIndex;
1656 }
1657 erq->flags = key + 1;
1658 switch (padapter->securitypriv.ndisencryptstatus) {
1659 case Ndis802_11EncryptionNotSupported:
1660 case Ndis802_11EncryptionDisabled:
1661 erq->length = 0;
1662 erq->flags |= IW_ENCODE_DISABLED;
1663 break;
1664 case Ndis802_11Encryption1Enabled:
1665 erq->length = padapter->securitypriv.DefKeylen[key];
1666 if (erq->length) {
1667 memcpy(keybuf, padapter->securitypriv.DefKey[
1668 key].skey, padapter->securitypriv.
1669 DefKeylen[key]);
1670 erq->flags |= IW_ENCODE_ENABLED;
1671 if (padapter->securitypriv.ndisauthtype ==
1672 Ndis802_11AuthModeOpen)
1673 erq->flags |= IW_ENCODE_OPEN;
1674 else if (padapter->securitypriv.ndisauthtype ==
1675 Ndis802_11AuthModeShared)
1676 erq->flags |= IW_ENCODE_RESTRICTED;
1677 } else {
1678 erq->length = 0;
1679 erq->flags |= IW_ENCODE_DISABLED;
1680 }
1681 break;
1682 case Ndis802_11Encryption2Enabled:
1683 case Ndis802_11Encryption3Enabled:
1684 erq->length = 16;
1685 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN |
1686 IW_ENCODE_NOKEY);
1687 break;
1688 default:
1689 erq->length = 0;
1690 erq->flags |= IW_ENCODE_DISABLED;
1691 break;
1692 }
1693 return ret;
1694}
1695
1696static int r8711_wx_get_power(struct net_device *dev,
1697 struct iw_request_info *info,
1698 union iwreq_data *wrqu, char *extra)
1699{
1700 wrqu->power.value = 0;
1701 wrqu->power.fixed = 0;
1702 wrqu->power.disabled = 1;
1703 return 0;
1704}
1705
1706static int r871x_wx_set_gen_ie(struct net_device *dev,
1707 struct iw_request_info *info,
1708 union iwreq_data *wrqu, char *extra)
1709{
1710 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1711
1712 return r871x_set_wpa_ie(padapter, extra, wrqu->data.length);
1713}
1714
1715static int r871x_wx_set_auth(struct net_device *dev,
1716 struct iw_request_info *info,
1717 union iwreq_data *wrqu, char *extra)
1718{
1719 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1720 struct iw_param *param = (struct iw_param *)&(wrqu->param);
1721 int paramid;
1722 int paramval;
1723 int ret = 0;
1724
1725 paramid = param->flags & IW_AUTH_INDEX;
1726 paramval = param->value;
1727 switch (paramid) {
1728 case IW_AUTH_WPA_VERSION:
1729 break;
1730 case IW_AUTH_CIPHER_PAIRWISE:
1731 break;
1732 case IW_AUTH_CIPHER_GROUP:
1733 break;
1734 case IW_AUTH_KEY_MGMT:
1735
1736
1737
1738 break;
1739 case IW_AUTH_TKIP_COUNTERMEASURES:
1740 if (paramval) {
1741
1742 padapter->securitypriv.btkip_countermeasure = true;
1743 } else {
1744
1745 padapter->securitypriv.btkip_countermeasure = false;
1746 }
1747 break;
1748 case IW_AUTH_DROP_UNENCRYPTED:
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760 if (padapter->securitypriv.ndisencryptstatus ==
1761 Ndis802_11Encryption1Enabled) {
1762
1763
1764
1765
1766
1767 break;
1768 }
1769
1770 if (paramval) {
1771 padapter->securitypriv.ndisencryptstatus =
1772 Ndis802_11EncryptionDisabled;
1773 padapter->securitypriv.PrivacyAlgrthm =
1774 _NO_PRIVACY_;
1775 padapter->securitypriv.XGrpPrivacy =
1776 _NO_PRIVACY_;
1777 padapter->securitypriv.AuthAlgrthm = 0;
1778 padapter->securitypriv.ndisauthtype =
1779 Ndis802_11AuthModeOpen;
1780 }
1781 break;
1782 case IW_AUTH_80211_AUTH_ALG:
1783 ret = wpa_set_auth_algs(dev, (u32)paramval);
1784 break;
1785 case IW_AUTH_WPA_ENABLED:
1786 break;
1787 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1788 break;
1789 case IW_AUTH_PRIVACY_INVOKED:
1790 break;
1791 default:
1792 return -EOPNOTSUPP;
1793 }
1794
1795 return ret;
1796}
1797
1798static int r871x_wx_set_enc_ext(struct net_device *dev,
1799 struct iw_request_info *info,
1800 union iwreq_data *wrqu, char *extra)
1801{
1802 struct iw_point *pencoding = &wrqu->encoding;
1803 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1804 struct ieee_param *param = NULL;
1805 char *alg_name;
1806 u32 param_len;
1807 int ret = 0;
1808
1809 param_len = sizeof(struct ieee_param) + pext->key_len;
1810 param = (struct ieee_param *)_malloc(param_len);
1811 if (param == NULL)
1812 return -ENOMEM;
1813 memset(param, 0, param_len);
1814 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1815 memset(param->sta_addr, 0xff, ETH_ALEN);
1816 switch (pext->alg) {
1817 case IW_ENCODE_ALG_NONE:
1818 alg_name = "none";
1819 break;
1820 case IW_ENCODE_ALG_WEP:
1821 alg_name = "WEP";
1822 break;
1823 case IW_ENCODE_ALG_TKIP:
1824 alg_name = "TKIP";
1825 break;
1826 case IW_ENCODE_ALG_CCMP:
1827 alg_name = "CCMP";
1828 break;
1829 default:
1830 return -EINVAL;
1831 }
1832 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1833 if (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
1834 param->u.crypt.set_tx = 0;
1835 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1836 param->u.crypt.set_tx = 1;
1837 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1838 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1839 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1840 if (pext->key_len) {
1841 param->u.crypt.key_len = pext->key_len;
1842 memcpy(param + 1, pext + 1, pext->key_len);
1843 }
1844 ret = wpa_set_encryption(dev, param, param_len);
1845 kfree(param);
1846 return ret;
1847}
1848
1849static int r871x_wx_get_nick(struct net_device *dev,
1850 struct iw_request_info *info,
1851 union iwreq_data *wrqu, char *extra)
1852{
1853 if (extra) {
1854 wrqu->data.length = 8;
1855 wrqu->data.flags = 1;
1856 memcpy(extra, "rtl_wifi", 8);
1857 }
1858 return 0;
1859}
1860
1861static int r8711_wx_read32(struct net_device *dev,
1862 struct iw_request_info *info,
1863 union iwreq_data *wrqu, char *keybuf)
1864{
1865 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
1866 u32 addr;
1867 u32 data32;
1868
1869 get_user(addr, (u32 __user *)wrqu->data.pointer);
1870 data32 = r8712_read32(padapter, addr);
1871 put_user(data32, (u32 __user *)wrqu->data.pointer);
1872 wrqu->data.length = (data32 & 0xffff0000) >> 16;
1873 wrqu->data.flags = data32 & 0xffff;
1874 get_user(addr, (u32 __user *)wrqu->data.pointer);
1875 return 0;
1876}
1877
1878static int r8711_wx_write32(struct net_device *dev,
1879 struct iw_request_info *info,
1880 union iwreq_data *wrqu, char *keybuf)
1881{
1882 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
1883 u32 addr;
1884 u32 data32;
1885
1886 get_user(addr, (u32 __user *)wrqu->data.pointer);
1887 data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags ;
1888 r8712_write32(padapter, addr, data32);
1889 return 0;
1890}
1891
1892static int dummy(struct net_device *dev,
1893 struct iw_request_info *a,
1894 union iwreq_data *wrqu, char *b)
1895{
1896 return -ENOSYS;
1897}
1898
1899static int r8711_drvext_hdl(struct net_device *dev,
1900 struct iw_request_info *info,
1901 union iwreq_data *wrqu, char *extra)
1902{
1903 return 0;
1904}
1905
1906static int r871x_mp_ioctl_hdl(struct net_device *dev,
1907 struct iw_request_info *info,
1908 union iwreq_data *wrqu, char *extra)
1909{
1910 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1911 struct iw_point *p = &wrqu->data;
1912 struct oid_par_priv oid_par;
1913 struct mp_ioctl_handler *phandler;
1914 struct mp_ioctl_param *poidparam;
1915 unsigned long BytesRead, BytesWritten, BytesNeeded;
1916 u8 *pparmbuf = NULL, bset;
1917 u16 len;
1918 uint status;
1919 int ret = 0;
1920
1921 if ((!p->length) || (!p->pointer)) {
1922 ret = -EINVAL;
1923 goto _r871x_mp_ioctl_hdl_exit;
1924 }
1925 bset = (u8)(p->flags & 0xFFFF);
1926 len = p->length;
1927 pparmbuf = NULL;
1928 pparmbuf = (u8 *)_malloc(len);
1929 if (pparmbuf == NULL) {
1930 ret = -ENOMEM;
1931 goto _r871x_mp_ioctl_hdl_exit;
1932 }
1933 if (copy_from_user(pparmbuf, p->pointer, len)) {
1934 ret = -EFAULT;
1935 goto _r871x_mp_ioctl_hdl_exit;
1936 }
1937 poidparam = (struct mp_ioctl_param *)pparmbuf;
1938 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
1939 ret = -EINVAL;
1940 goto _r871x_mp_ioctl_hdl_exit;
1941 }
1942 phandler = mp_ioctl_hdl + poidparam->subcode;
1943 if ((phandler->paramsize != 0) &&
1944 (poidparam->len < phandler->paramsize)) {
1945 ret = -EINVAL;
1946 goto _r871x_mp_ioctl_hdl_exit;
1947 }
1948 if (phandler->oid == 0 && phandler->handler)
1949 status = phandler->handler(&oid_par);
1950 else if (phandler->handler) {
1951 oid_par.adapter_context = padapter;
1952 oid_par.oid = phandler->oid;
1953 oid_par.information_buf = poidparam->data;
1954 oid_par.information_buf_len = poidparam->len;
1955 oid_par.dbg = 0;
1956 BytesWritten = 0;
1957 BytesNeeded = 0;
1958 if (bset) {
1959 oid_par.bytes_rw = &BytesRead;
1960 oid_par.bytes_needed = &BytesNeeded;
1961 oid_par.type_of_oid = SET_OID;
1962 } else {
1963 oid_par.bytes_rw = &BytesWritten;
1964 oid_par.bytes_needed = &BytesNeeded;
1965 oid_par.type_of_oid = QUERY_OID;
1966 }
1967 status = phandler->handler(&oid_par);
1968
1969 } else {
1970 netdev_info(dev, "r8712u: %s: err!, subcode=%d, oid=%d, handler=%p\n",
1971 __func__, poidparam->subcode, phandler->oid,
1972 phandler->handler);
1973 ret = -EFAULT;
1974 goto _r871x_mp_ioctl_hdl_exit;
1975 }
1976 if (bset == 0x00) {
1977 if (copy_to_user(p->pointer, pparmbuf, len))
1978 ret = -EFAULT;
1979 }
1980 if (status) {
1981 ret = -EFAULT;
1982 goto _r871x_mp_ioctl_hdl_exit;
1983 }
1984_r871x_mp_ioctl_hdl_exit:
1985 kfree(pparmbuf);
1986 return ret;
1987}
1988
1989static int r871x_get_ap_info(struct net_device *dev,
1990 struct iw_request_info *info,
1991 union iwreq_data *wrqu, char *extra)
1992{
1993 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
1994 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1995 struct __queue *queue = &pmlmepriv->scanned_queue;
1996 struct iw_point *pdata = &wrqu->data;
1997 struct wlan_network *pnetwork = NULL;
1998 u32 cnt = 0, wpa_ielen;
1999 unsigned long irqL;
2000 struct list_head *plist, *phead;
2001 unsigned char *pbuf;
2002 u8 bssid[ETH_ALEN];
2003 char data[32];
2004
2005 if (padapter->bDriverStopped || (pdata == NULL))
2006 return -EINVAL;
2007 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) {
2008 msleep(30);
2009 cnt++;
2010 if (cnt > 100)
2011 break;
2012 }
2013 pdata->flags = 0;
2014 if (pdata->length >= 32) {
2015 if (copy_from_user(data, pdata->pointer, 32))
2016 return -EINVAL;
2017 } else
2018 return -EINVAL;
2019 spin_lock_irqsave(&(pmlmepriv->scanned_queue.lock), irqL);
2020 phead = get_list_head(queue);
2021 plist = get_next(phead);
2022 while (1) {
2023 if (end_of_queue_search(phead, plist) == true)
2024 break;
2025 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2026 if (hwaddr_aton_i(data, bssid)) {
2027 netdev_info(dev, "r8712u: Invalid BSSID '%s'.\n",
2028 (u8 *)data);
2029 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock),
2030 irqL);
2031 return -EINVAL;
2032 }
2033 netdev_info(dev, "r8712u: BSSID:%pM\n", bssid);
2034 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
2035
2036 pbuf = r8712_get_wpa_ie(&pnetwork->network.IEs[12],
2037 &wpa_ielen, pnetwork->network.IELength-12);
2038 if (pbuf && (wpa_ielen > 0)) {
2039 pdata->flags = 1;
2040 break;
2041 }
2042 pbuf = r8712_get_wpa2_ie(&pnetwork->network.IEs[12],
2043 &wpa_ielen, pnetwork->network.IELength-12);
2044 if (pbuf && (wpa_ielen > 0)) {
2045 pdata->flags = 2;
2046 break;
2047 }
2048 }
2049 plist = get_next(plist);
2050 }
2051 spin_unlock_irqrestore(&(pmlmepriv->scanned_queue.lock), irqL);
2052 if (pdata->length >= 34) {
2053 if (copy_to_user((u8 __user *)pdata->pointer + 32,
2054 (u8 *)&pdata->flags, 1))
2055 return -EINVAL;
2056 }
2057 return 0;
2058}
2059
2060static int r871x_set_pid(struct net_device *dev,
2061 struct iw_request_info *info,
2062 union iwreq_data *wrqu, char *extra)
2063{
2064 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
2065 struct iw_point *pdata = &wrqu->data;
2066
2067 if ((padapter->bDriverStopped) || (pdata == NULL))
2068 return -EINVAL;
2069 if (copy_from_user(&padapter->pid, pdata->pointer, sizeof(int)))
2070 return -EINVAL;
2071 return 0;
2072}
2073
2074static int r871x_set_chplan(struct net_device *dev,
2075 struct iw_request_info *info,
2076 union iwreq_data *wrqu, char *extra)
2077{
2078 int ret = 0;
2079 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
2080 struct iw_point *pdata = &wrqu->data;
2081 int ch_plan = -1;
2082
2083 if ((padapter->bDriverStopped) || (pdata == NULL)) {
2084 ret = -EINVAL;
2085 goto exit;
2086 }
2087 ch_plan = (int)*extra;
2088 r8712_set_chplan_cmd(padapter, ch_plan);
2089
2090exit:
2091
2092 return ret;
2093}
2094
2095static int r871x_wps_start(struct net_device *dev,
2096 struct iw_request_info *info,
2097 union iwreq_data *wrqu, char *extra)
2098{
2099 struct _adapter *padapter = (struct _adapter *)netdev_priv(dev);
2100 struct iw_point *pdata = &wrqu->data;
2101 u32 u32wps_start = 0;
2102
2103 if ((padapter->bDriverStopped) || (pdata == NULL))
2104 return -EINVAL;
2105 if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4))
2106 return -EFAULT;
2107 if (u32wps_start == 0)
2108 u32wps_start = *extra;
2109 if (u32wps_start == 1)
2110 padapter->ledpriv.LedControlHandler(padapter,
2111 LED_CTL_START_WPS);
2112 else if (u32wps_start == 2)
2113 padapter->ledpriv.LedControlHandler(padapter,
2114 LED_CTL_STOP_WPS);
2115 else if (u32wps_start == 3)
2116 padapter->ledpriv.LedControlHandler(padapter,
2117 LED_CTL_STOP_WPS_FAIL);
2118 return 0;
2119}
2120
2121static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
2122{
2123 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
2124
2125 switch (name) {
2126 case IEEE_PARAM_WPA_ENABLED:
2127 padapter->securitypriv.AuthAlgrthm = 2;
2128 switch ((value)&0xff) {
2129 case 1:
2130 padapter->securitypriv.ndisauthtype =
2131 Ndis802_11AuthModeWPAPSK;
2132 padapter->securitypriv.ndisencryptstatus =
2133 Ndis802_11Encryption2Enabled;
2134 break;
2135 case 2:
2136 padapter->securitypriv.ndisauthtype =
2137 Ndis802_11AuthModeWPA2PSK;
2138 padapter->securitypriv.ndisencryptstatus =
2139 Ndis802_11Encryption3Enabled;
2140 break;
2141 }
2142 break;
2143 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2144 break;
2145 case IEEE_PARAM_DROP_UNENCRYPTED:
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157 break;
2158 case IEEE_PARAM_PRIVACY_INVOKED:
2159 break;
2160 case IEEE_PARAM_AUTH_ALGS:
2161 return wpa_set_auth_algs(dev, value);
2162 break;
2163 case IEEE_PARAM_IEEE_802_1X:
2164 break;
2165 case IEEE_PARAM_WPAX_SELECT:
2166
2167 break;
2168 default:
2169 return -EOPNOTSUPP;
2170 }
2171 return 0;
2172}
2173
2174static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
2175{
2176 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
2177
2178 switch (command) {
2179 case IEEE_MLME_STA_DEAUTH:
2180 if (!r8712_set_802_11_disassociate(padapter))
2181 return -1;
2182 break;
2183 case IEEE_MLME_STA_DISASSOC:
2184 if (!r8712_set_802_11_disassociate(padapter))
2185 return -1;
2186 break;
2187 default:
2188 return -EOPNOTSUPP;
2189 }
2190 return 0;
2191}
2192
2193static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
2194{
2195 struct ieee_param *param;
2196 int ret = 0;
2197 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
2198
2199 if (p->length < sizeof(struct ieee_param) || !p->pointer)
2200 return -EINVAL;
2201 param = (struct ieee_param *)_malloc(p->length);
2202 if (param == NULL)
2203 return -ENOMEM;
2204 if (copy_from_user(param, p->pointer, p->length)) {
2205 kfree((u8 *)param);
2206 return -EFAULT;
2207 }
2208 switch (param->cmd) {
2209 case IEEE_CMD_SET_WPA_PARAM:
2210 ret = wpa_set_param(dev, param->u.wpa_param.name,
2211 param->u.wpa_param.value);
2212 break;
2213 case IEEE_CMD_SET_WPA_IE:
2214 ret = r871x_set_wpa_ie(padapter, (char *)param->u.wpa_ie.data,
2215 (u16)param->u.wpa_ie.len);
2216 break;
2217 case IEEE_CMD_SET_ENCRYPTION:
2218 ret = wpa_set_encryption(dev, param, p->length);
2219 break;
2220 case IEEE_CMD_MLME:
2221 ret = wpa_mlme(dev, param->u.mlme.command,
2222 param->u.mlme.reason_code);
2223 break;
2224 default:
2225 ret = -EOPNOTSUPP;
2226 break;
2227 }
2228 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2229 ret = -EFAULT;
2230 kfree((u8 *)param);
2231 return ret;
2232}
2233
2234
2235int r871x_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2236{
2237 struct iwreq *wrq = (struct iwreq *)rq;
2238
2239 switch (cmd) {
2240 case RTL_IOCTL_WPA_SUPPLICANT:
2241 return wpa_supplicant_ioctl(dev, &wrq->u.data);
2242 default:
2243 return -EOPNOTSUPP;
2244 }
2245 return 0;
2246}
2247
2248static iw_handler r8711_handlers[] = {
2249 NULL,
2250 r8711_wx_get_name,
2251 dummy,
2252 dummy,
2253 r8711_wx_set_freq,
2254 r8711_wx_get_freq,
2255 r8711_wx_set_mode,
2256 r8711_wx_get_mode,
2257 dummy,
2258 r8711_wx_get_sens,
2259 NULL,
2260 r8711_wx_get_range,
2261 r871x_wx_set_priv,
2262 NULL,
2263 NULL,
2264 NULL,
2265 dummy,
2266 dummy,
2267 NULL,
2268 NULL,
2269 r8711_wx_set_wap,
2270 r8711_wx_get_wap,
2271 r871x_wx_set_mlme,
2272
2273 dummy,
2274 r8711_wx_set_scan,
2275 r8711_wx_get_scan,
2276 r8711_wx_set_essid,
2277 r8711_wx_get_essid,
2278 dummy,
2279 r871x_wx_get_nick,
2280 NULL,
2281 NULL,
2282 r8711_wx_set_rate,
2283 r8711_wx_get_rate,
2284 dummy,
2285 r8711_wx_get_rts,
2286 r8711_wx_set_frag,
2287 r8711_wx_get_frag,
2288 dummy,
2289 dummy,
2290 dummy,
2291 r8711_wx_get_retry,
2292 r8711_wx_set_enc,
2293 r8711_wx_get_enc,
2294 dummy,
2295 r8711_wx_get_power,
2296 NULL,
2297 NULL,
2298 r871x_wx_set_gen_ie,
2299 NULL,
2300 r871x_wx_set_auth,
2301 NULL,
2302 r871x_wx_set_enc_ext,
2303 NULL,
2304 r871x_wx_set_pmkid,
2305 NULL,
2306};
2307
2308static const struct iw_priv_args r8711_private_args[] = {
2309 {
2310 SIOCIWFIRSTPRIV + 0x0,
2311 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "read32"
2312 },
2313 {
2314 SIOCIWFIRSTPRIV + 0x1,
2315 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "write32"
2316 },
2317 {
2318 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
2319 },
2320 {
2321 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
2322 },
2323 {
2324 SIOCIWFIRSTPRIV + 0x4,
2325 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
2326 },
2327 {
2328 SIOCIWFIRSTPRIV + 0x5,
2329 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpid"
2330 },
2331 {
2332 SIOCIWFIRSTPRIV + 0x6,
2333 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
2334 },
2335 {
2336 SIOCIWFIRSTPRIV + 0x7,
2337 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "chplan"
2338 }
2339};
2340
2341static iw_handler r8711_private_handler[] = {
2342 r8711_wx_read32,
2343 r8711_wx_write32,
2344 r8711_drvext_hdl,
2345 r871x_mp_ioctl_hdl,
2346 r871x_get_ap_info,
2347 r871x_set_pid,
2348 r871x_wps_start,
2349 r871x_set_chplan
2350};
2351
2352static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
2353{
2354 struct _adapter *padapter = (struct _adapter *) netdev_priv(dev);
2355 struct iw_statistics *piwstats = &padapter->iwstats;
2356 int tmp_level = 0;
2357 int tmp_qual = 0;
2358 int tmp_noise = 0;
2359
2360 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != true) {
2361 piwstats->qual.qual = 0;
2362 piwstats->qual.level = 0;
2363 piwstats->qual.noise = 0;
2364 } else {
2365
2366 tmp_level = padapter->recvpriv.fw_rssi;
2367 tmp_qual = padapter->recvpriv.signal;
2368 tmp_noise = padapter->recvpriv.noise;
2369 piwstats->qual.level = tmp_level;
2370 piwstats->qual.qual = tmp_qual;
2371 piwstats->qual.noise = tmp_noise;
2372 }
2373 piwstats->qual.updated = IW_QUAL_ALL_UPDATED;
2374 return &padapter->iwstats;
2375}
2376
2377struct iw_handler_def r871x_handlers_def = {
2378 .standard = r8711_handlers,
2379 .num_standard = ARRAY_SIZE(r8711_handlers),
2380 .private = r8711_private_handler,
2381 .private_args = (struct iw_priv_args *)r8711_private_args,
2382 .num_private = ARRAY_SIZE(r8711_private_handler),
2383 .num_private_args = sizeof(r8711_private_args) /
2384 sizeof(struct iw_priv_args),
2385 .get_wireless_stats = r871x_get_wireless_stats
2386};
2387