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