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