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