1
2
3
4#define _IOCTL_LINUX_C_
5
6#include "../include/osdep_service.h"
7#include "../include/drv_types.h"
8#include "../include/wlan_bssdef.h"
9#include "../include/rtw_debug.h"
10#include "../include/wifi.h"
11#include "../include/rtw_mlme.h"
12#include "../include/rtw_mlme_ext.h"
13#include "../include/rtw_ioctl.h"
14#include "../include/rtw_ioctl_set.h"
15#include "../include/usb_ops.h"
16#include "../include/rtl8188e_hal.h"
17#include "../include/rtl8188e_led.h"
18
19#include "../include/rtw_iol.h"
20
21#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30)
22
23#define SCAN_ITEM_SIZE 768
24#define MAX_CUSTOM_LEN 64
25#define RATE_COUNT 4
26
27
28#define WEXT_CSCAN_AMOUNT 9
29#define WEXT_CSCAN_BUF_LEN 360
30#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
31#define WEXT_CSCAN_HEADER_SIZE 12
32#define WEXT_CSCAN_SSID_SECTION 'S'
33#define WEXT_CSCAN_CHANNEL_SECTION 'C'
34#define WEXT_CSCAN_NPROBE_SECTION 'N'
35#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
36#define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
37#define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
38#define WEXT_CSCAN_TYPE_SECTION 'T'
39
40static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
41 6000000, 9000000, 12000000, 18000000, 24000000, 36000000,
42 48000000, 54000000};
43
44void indicate_wx_scan_complete_event(struct adapter *padapter)
45{
46 union iwreq_data wrqu;
47
48 memset(&wrqu, 0, sizeof(union iwreq_data));
49 wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
50}
51
52void rtw_indicate_wx_assoc_event(struct adapter *padapter)
53{
54 union iwreq_data wrqu;
55 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
56
57 memset(&wrqu, 0, sizeof(union iwreq_data));
58
59 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
60
61 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
62
63 DBG_88E_LEVEL(_drv_always_, "assoc success\n");
64 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
65}
66
67void rtw_indicate_wx_disassoc_event(struct adapter *padapter)
68{
69 union iwreq_data wrqu;
70
71 memset(&wrqu, 0, sizeof(union iwreq_data));
72
73 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
74 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
75
76 DBG_88E_LEVEL(_drv_always_, "indicate disassoc\n");
77 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
78}
79
80static char *translate_scan(struct adapter *padapter,
81 struct iw_request_info *info,
82 struct wlan_network *pnetwork,
83 char *start, char *stop)
84{
85 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
86 struct iw_event iwe;
87 u16 cap;
88 __le16 le_tmp;
89 u32 ht_ielen = 0;
90 char *custom;
91 char *p;
92 u16 max_rate = 0, rate, ht_cap = false;
93 u32 i = 0;
94 u8 bw_40MHz = 0, short_GI = 0;
95 u16 mcs_rate = 0;
96 u8 ss, sq;
97 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
98
99 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
100 u32 blnGotP2PIE = false;
101
102
103
104
105
106
107 if (!memcmp(pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN)) {
108 u32 p2pielen = 0;
109
110 if (pnetwork->network.Reserved[0] == 2) {
111
112 if (rtw_get_p2p_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &p2pielen))
113 blnGotP2PIE = true;
114 } else {
115
116 if (rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen))
117 blnGotP2PIE = true;
118 }
119 }
120
121 if (!blnGotP2PIE)
122 return start;
123 }
124
125
126 iwe.cmd = SIOCGIWAP;
127 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
128
129 memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
130 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
131
132
133 iwe.cmd = SIOCGIWESSID;
134 iwe.u.data.flags = 1;
135 iwe.u.data.length = min_t(u16, pnetwork->network.Ssid.SsidLength, 32);
136 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
137
138
139 p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - 12);
140
141 if (p && ht_ielen > 0) {
142 struct ieee80211_ht_cap *pht_capie;
143
144 ht_cap = true;
145 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
146 memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2);
147 bw_40MHz = (le16_to_cpu(pht_capie->cap_info) &
148 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
149 short_GI = (le16_to_cpu(pht_capie->cap_info) &
150 (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
151 }
152
153
154 iwe.cmd = SIOCGIWNAME;
155 if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates))) {
156 if (ht_cap)
157 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
158 else
159 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
160 } else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates))) {
161 if (ht_cap)
162 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
163 else
164 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
165 } else {
166 if (ht_cap)
167 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
168 else
169 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
170 }
171
172 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
173
174
175 iwe.cmd = SIOCGIWMODE;
176 memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
177
178 cap = le16_to_cpu(le_tmp);
179
180 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
181 if (cap & WLAN_CAPABILITY_BSS)
182 iwe.u.mode = IW_MODE_MASTER;
183 else
184 iwe.u.mode = IW_MODE_ADHOC;
185
186 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
187 }
188
189 if (pnetwork->network.Configuration.DSConfig < 1)
190 pnetwork->network.Configuration.DSConfig = 1;
191
192
193 iwe.cmd = SIOCGIWFREQ;
194 iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
195 iwe.u.freq.e = 1;
196 iwe.u.freq.i = pnetwork->network.Configuration.DSConfig;
197 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
198
199
200 iwe.cmd = SIOCGIWENCODE;
201 if (cap & WLAN_CAPABILITY_PRIVACY)
202 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
203 else
204 iwe.u.data.flags = IW_ENCODE_DISABLED;
205 iwe.u.data.length = 0;
206 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
207
208
209 max_rate = 0;
210 custom = kzalloc(MAX_CUSTOM_LEN, GFP_ATOMIC);
211 if (!custom)
212 return start;
213 p = custom;
214 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
215 while (pnetwork->network.SupportedRates[i] != 0) {
216 rate = pnetwork->network.SupportedRates[i] & 0x7F;
217 if (rate > max_rate)
218 max_rate = rate;
219 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
220 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
221 i++;
222 }
223
224 if (ht_cap) {
225 if (mcs_rate & 0x8000)
226 max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130);
227 else if (mcs_rate & 0x0080)
228 ;
229 else
230 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
231
232 max_rate = max_rate * 2;
233 }
234
235 iwe.cmd = SIOCGIWRATE;
236 iwe.u.bitrate.fixed = 0;
237 iwe.u.bitrate.disabled = 0;
238 iwe.u.bitrate.value = max_rate * 500000;
239 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
240
241
242 {
243 u8 *buf;
244 u8 *wpa_ie, *rsn_ie;
245 u16 wpa_len = 0, rsn_len = 0;
246 u8 *p;
247
248 buf = kzalloc(MAX_WPA_IE_LEN, GFP_ATOMIC);
249 if (!buf)
250 goto exit;
251 wpa_ie = kzalloc(255, GFP_ATOMIC);
252 if (!wpa_ie) {
253 kfree(buf);
254 goto exit;
255 }
256 rsn_ie = kzalloc(255, GFP_ATOMIC);
257 if (!rsn_ie) {
258 kfree(buf);
259 kfree(wpa_ie);
260 goto exit;
261 }
262 rtw_get_sec_ie(pnetwork->network.IEs, pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
263
264 if (wpa_len > 0) {
265 p = buf;
266 memset(buf, 0, MAX_WPA_IE_LEN);
267 p += sprintf(p, "wpa_ie =");
268 for (i = 0; i < wpa_len; i++)
269 p += sprintf(p, "%02x", wpa_ie[i]);
270
271 memset(&iwe, 0, sizeof(iwe));
272 iwe.cmd = IWEVCUSTOM;
273 iwe.u.data.length = strlen(buf);
274 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
275
276 memset(&iwe, 0, sizeof(iwe));
277 iwe.cmd = IWEVGENIE;
278 iwe.u.data.length = wpa_len;
279 start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie);
280 }
281 if (rsn_len > 0) {
282 p = buf;
283 memset(buf, 0, MAX_WPA_IE_LEN);
284 p += sprintf(p, "rsn_ie =");
285 for (i = 0; i < rsn_len; i++)
286 p += sprintf(p, "%02x", rsn_ie[i]);
287 memset(&iwe, 0, sizeof(iwe));
288 iwe.cmd = IWEVCUSTOM;
289 iwe.u.data.length = strlen(buf);
290 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
291
292 memset(&iwe, 0, sizeof(iwe));
293 iwe.cmd = IWEVGENIE;
294 iwe.u.data.length = rsn_len;
295 start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
296 }
297 kfree(buf);
298 kfree(wpa_ie);
299 kfree(rsn_ie);
300 }
301
302 {
303 uint cnt = 0, total_ielen;
304 u8 *wpsie_ptr = NULL;
305 uint wps_ielen = 0;
306
307 u8 *ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
308 total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
309
310 while (cnt < total_ielen) {
311 if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) {
312 wpsie_ptr = &ie_ptr[cnt];
313 iwe.cmd = IWEVGENIE;
314 iwe.u.data.length = (u16)wps_ielen;
315 start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr);
316 }
317 cnt += ie_ptr[cnt + 1] + 2;
318 }
319 }
320
321
322 iwe.cmd = IWEVQUAL;
323 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID;
324
325 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
326 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) {
327 ss = padapter->recvpriv.signal_strength;
328 sq = padapter->recvpriv.signal_qual;
329 } else {
330 ss = pnetwork->network.PhyInfo.SignalStrength;
331 sq = pnetwork->network.PhyInfo.SignalQuality;
332 }
333
334 iwe.u.qual.level = (u8)ss;
335 iwe.u.qual.qual = (u8)sq;
336 iwe.u.qual.noise = 0;
337 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
338exit:
339 kfree(custom);
340 return start;
341}
342
343static int wpa_set_auth_algs(struct net_device *dev, u32 value)
344{
345 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
346 int ret = 0;
347
348 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
349 DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value);
350 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
351 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
352 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
353 } else if (value & AUTH_ALG_SHARED_KEY) {
354 DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n", value);
355 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
356
357 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
358 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
359 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
360 DBG_88E("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
361 if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
362 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
363 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
364 }
365 } else if (value & AUTH_ALG_LEAP) {
366 DBG_88E("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
367 } else {
368 DBG_88E("wpa_set_auth_algs, error!\n");
369 ret = -EINVAL;
370 }
371 return ret;
372}
373
374static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
375{
376 int ret = 0;
377 u32 wep_key_idx, wep_key_len, wep_total_len;
378 struct ndis_802_11_wep *pwep = NULL;
379 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
380 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
381 struct security_priv *psecuritypriv = &padapter->securitypriv;
382 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
383
384 param->u.crypt.err = 0;
385 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
386
387 if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) {
388 ret = -EINVAL;
389 goto exit;
390 }
391
392 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
393 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
394 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
395 if (param->u.crypt.idx >= WEP_KEYS) {
396 ret = -EINVAL;
397 goto exit;
398 }
399 } else {
400 ret = -EINVAL;
401 goto exit;
402 }
403
404 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
405 DBG_88E("wpa_set_encryption, crypt.alg = WEP\n");
406
407 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
408 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
409 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
410
411 wep_key_idx = param->u.crypt.idx;
412 wep_key_len = param->u.crypt.key_len;
413
414 DBG_88E("(1)wep_key_idx =%d\n", wep_key_idx);
415
416 if (wep_key_idx > WEP_KEYS)
417 return -EINVAL;
418
419 if (wep_key_len > 0) {
420 wep_key_len = wep_key_len <= 5 ? 5 : 13;
421 wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
422 pwep = kzalloc(wep_total_len, GFP_KERNEL);
423 if (!pwep)
424 goto exit;
425
426 pwep->KeyLength = wep_key_len;
427 pwep->Length = wep_total_len;
428 if (wep_key_len == 13) {
429 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
430 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
431 }
432 } else {
433 ret = -EINVAL;
434 goto exit;
435 }
436 pwep->KeyIndex = wep_key_idx;
437 pwep->KeyIndex |= 0x80000000;
438 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
439 if (param->u.crypt.set_tx) {
440 DBG_88E("wep, set_tx = 1\n");
441 if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
442 ret = -EOPNOTSUPP;
443 } else {
444 DBG_88E("wep, set_tx = 0\n");
445 if (wep_key_idx >= WEP_KEYS) {
446 ret = -EOPNOTSUPP;
447 goto exit;
448 }
449 memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0], pwep->KeyMaterial, pwep->KeyLength);
450 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
451 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0);
452 }
453 goto exit;
454 }
455
456 if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
457 struct sta_info *psta, *pbcmc_sta;
458 struct sta_priv *pstapriv = &padapter->stapriv;
459
460 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE)) {
461 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
462 if (!psta) {
463 ;
464 } else {
465 if (strcmp(param->u.crypt.alg, "none") != 0)
466 psta->ieee8021x_blocked = false;
467
468 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
469 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
470 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
471
472 if (param->u.crypt.set_tx == 1) {
473 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
474
475 if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
476 memcpy(psta->dot11tkiptxmickey.skey, ¶m->u.crypt.key[16], 8);
477 memcpy(psta->dot11tkiprxmickey.skey, ¶m->u.crypt.key[24], 8);
478 padapter->securitypriv.busetkipkey = false;
479 }
480
481 DBG_88E(" ~~~~set sta key:unicastkey\n");
482
483 rtw_setstakey_cmd(padapter, (unsigned char *)psta, true);
484 } else {
485 memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
486 memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[16], 8);
487 memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[24], 8);
488 padapter->securitypriv.binstallGrpkey = true;
489 DBG_88E(" ~~~~set sta key:groupkey\n");
490
491 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
492
493 rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1);
494 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
495 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
496 }
497 }
498 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
499 if (!pbcmc_sta) {
500 ;
501 } else {
502
503 if (strcmp(param->u.crypt.alg, "none") != 0)
504 pbcmc_sta->ieee8021x_blocked = false;
505
506 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
507 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
508 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
509 }
510 }
511 }
512
513exit:
514
515 kfree(pwep);
516
517 return ret;
518}
519
520static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ielen)
521{
522 u8 *buf = NULL;
523 int group_cipher = 0, pairwise_cipher = 0;
524 int ret = 0;
525 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
526
527 if (ielen > MAX_WPA_IE_LEN || !pie) {
528 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
529 if (!pie)
530 return ret;
531 else
532 return -EINVAL;
533 }
534
535 if (ielen) {
536 buf = kmemdup(pie, ielen, GFP_KERNEL);
537 if (!buf) {
538 ret = -ENOMEM;
539 goto exit;
540 }
541
542
543 {
544 int i;
545 DBG_88E("\n wpa_ie(length:%d):\n", ielen);
546 for (i = 0; i < ielen; i += 8)
547 DBG_88E("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", buf[i], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]);
548 }
549
550 if (ielen < RSN_HEADER_LEN) {
551 ret = -1;
552 goto exit;
553 }
554
555 if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
556 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
557 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
558 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
559 }
560
561 if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
562 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
563 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
564 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
565 }
566
567 switch (group_cipher) {
568 case WPA_CIPHER_NONE:
569 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
570 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
571 break;
572 case WPA_CIPHER_WEP40:
573 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
574 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
575 break;
576 case WPA_CIPHER_TKIP:
577 padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
578 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
579 break;
580 case WPA_CIPHER_CCMP:
581 padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
582 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
583 break;
584 case WPA_CIPHER_WEP104:
585 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
586 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
587 break;
588 }
589
590 switch (pairwise_cipher) {
591 case WPA_CIPHER_NONE:
592 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
593 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
594 break;
595 case WPA_CIPHER_WEP40:
596 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
597 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
598 break;
599 case WPA_CIPHER_TKIP:
600 padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
601 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
602 break;
603 case WPA_CIPHER_CCMP:
604 padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
605 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
606 break;
607 case WPA_CIPHER_WEP104:
608 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
609 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
610 break;
611 }
612
613 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
614 {
615 u16 cnt = 0;
616 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
617
618 while (cnt < ielen) {
619 eid = buf[cnt];
620 if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&buf[cnt + 2], wps_oui, 4))) {
621 DBG_88E("SET WPS_IE\n");
622
623 padapter->securitypriv.wps_ie_len = ((buf[cnt + 1] + 2) < (MAX_WPA_IE_LEN << 2)) ? (buf[cnt + 1] + 2) : (MAX_WPA_IE_LEN << 2);
624
625 memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
626
627 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
628 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
629 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING);
630 cnt += buf[cnt + 1] + 2;
631 break;
632 } else {
633 cnt += buf[cnt + 1] + 2;
634 }
635 }
636 }
637 }
638
639exit:
640 kfree(buf);
641 return ret;
642}
643
644typedef unsigned char NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];
645
646static int rtw_wx_get_name(struct net_device *dev,
647 struct iw_request_info *info,
648 union iwreq_data *wrqu, char *extra)
649{
650 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
651 u32 ht_ielen = 0;
652 char *p;
653 u8 ht_cap = false;
654 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
655 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
656 NDIS_802_11_RATES_EX *prates = NULL;
657
658 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
659
660 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12);
661 if (p && ht_ielen > 0)
662 ht_cap = true;
663
664 prates = &pcur_bss->SupportedRates;
665
666 if (rtw_is_cckratesonly_included((u8 *)prates)) {
667 if (ht_cap)
668 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
669 else
670 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
671 } else if (rtw_is_cckrates_included((u8 *)prates)) {
672 if (ht_cap)
673 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
674 else
675 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
676 } else {
677 if (ht_cap)
678 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
679 else
680 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
681 }
682 } else {
683 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
684 }
685
686
687
688 return 0;
689}
690
691static int rtw_wx_get_freq(struct net_device *dev,
692 struct iw_request_info *info,
693 union iwreq_data *wrqu, char *extra)
694{
695 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
696 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
697 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
698
699 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
700
701 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
702 wrqu->freq.e = 1;
703 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
704 } else {
705 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
706 wrqu->freq.e = 1;
707 wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
708 }
709
710 return 0;
711}
712
713static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
714 union iwreq_data *wrqu, char *b)
715{
716 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
717 enum ndis_802_11_network_infra networkType;
718 int ret = 0;
719
720
721
722 if (_FAIL == rtw_pwr_wakeup(padapter)) {
723 ret = -EPERM;
724 goto exit;
725 }
726
727 if (!padapter->hw_init_completed) {
728 ret = -EPERM;
729 goto exit;
730 }
731
732 switch (wrqu->mode) {
733 case IW_MODE_AUTO:
734 networkType = Ndis802_11AutoUnknown;
735 DBG_88E("set_mode = IW_MODE_AUTO\n");
736 break;
737 case IW_MODE_ADHOC:
738 networkType = Ndis802_11IBSS;
739 DBG_88E("set_mode = IW_MODE_ADHOC\n");
740 break;
741 case IW_MODE_MASTER:
742 networkType = Ndis802_11APMode;
743 DBG_88E("set_mode = IW_MODE_MASTER\n");
744 break;
745 case IW_MODE_INFRA:
746 networkType = Ndis802_11Infrastructure;
747 DBG_88E("set_mode = IW_MODE_INFRA\n");
748 break;
749 default:
750 ret = -EINVAL;
751 goto exit;
752 }
753 if (!rtw_set_802_11_infrastructure_mode(padapter, networkType)) {
754 ret = -EPERM;
755 goto exit;
756 }
757 rtw_setopmode_cmd(padapter, networkType);
758exit:
759
760 return ret;
761}
762
763static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
764 union iwreq_data *wrqu, char *b)
765{
766 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
767 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
768
769 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
770 wrqu->mode = IW_MODE_INFRA;
771 else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
772 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)))
773 wrqu->mode = IW_MODE_ADHOC;
774 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
775 wrqu->mode = IW_MODE_MASTER;
776 else
777 wrqu->mode = IW_MODE_AUTO;
778
779
780
781 return 0;
782}
783
784static int rtw_wx_set_pmkid(struct net_device *dev,
785 struct iw_request_info *a,
786 union iwreq_data *wrqu, char *extra)
787{
788 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
789 u8 j, blInserted = false;
790 int ret = false;
791 struct security_priv *psecuritypriv = &padapter->securitypriv;
792 struct iw_pmksa *pPMK = (struct iw_pmksa *)extra;
793 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
794 u8 strIssueBssid[ETH_ALEN] = {0x00};
795
796 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
797 if (pPMK->cmd == IW_PMKSA_ADD) {
798 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
799 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
800 return ret;
801 else
802 ret = true;
803 blInserted = false;
804
805
806 for (j = 0; j < NUM_PMKID_CACHE; j++) {
807 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
808
809 DBG_88E("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n");
810 memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
811 psecuritypriv->PMKIDList[j].bUsed = true;
812 psecuritypriv->PMKIDIndex = j + 1;
813 blInserted = true;
814 break;
815 }
816 }
817
818 if (!blInserted) {
819
820 DBG_88E("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
821 psecuritypriv->PMKIDIndex);
822
823 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
824 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
825
826 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = true;
827 psecuritypriv->PMKIDIndex++;
828 if (psecuritypriv->PMKIDIndex == 16)
829 psecuritypriv->PMKIDIndex = 0;
830 }
831 } else if (pPMK->cmd == IW_PMKSA_REMOVE) {
832 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n");
833 ret = true;
834 for (j = 0; j < NUM_PMKID_CACHE; j++) {
835 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
836
837 memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN);
838 psecuritypriv->PMKIDList[j].bUsed = false;
839 break;
840 }
841 }
842 } else if (pPMK->cmd == IW_PMKSA_FLUSH) {
843 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");
844 memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
845 psecuritypriv->PMKIDIndex = 0;
846 ret = true;
847 }
848 return ret;
849}
850
851static int rtw_wx_get_sens(struct net_device *dev,
852 struct iw_request_info *info,
853 union iwreq_data *wrqu, char *extra)
854{
855 wrqu->sens.value = 0;
856 wrqu->sens.fixed = 0;
857 wrqu->sens.disabled = 1;
858 return 0;
859}
860
861static int rtw_wx_get_range(struct net_device *dev,
862 struct iw_request_info *info,
863 union iwreq_data *wrqu, char *extra)
864{
865 struct iw_range *range = (struct iw_range *)extra;
866 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
867 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
868
869 u16 val;
870 int i;
871
872 wrqu->data.length = sizeof(*range);
873 memset(range, 0, sizeof(*range));
874
875
876
877
878
879
880
881
882
883
884 range->throughput = 5 * 1000 * 1000;
885
886
887
888
889 range->max_qual.qual = 100;
890 range->max_qual.level = 100;
891 range->max_qual.noise = 100;
892 range->max_qual.updated = 7;
893
894 range->avg_qual.qual = 92;
895
896 range->avg_qual.level = 178;
897 range->avg_qual.noise = 0;
898 range->avg_qual.updated = 7;
899
900 range->num_bitrates = RATE_COUNT;
901
902 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
903 range->bitrate[i] = rtw_rates[i];
904
905 range->min_frag = MIN_FRAG_THRESHOLD;
906 range->max_frag = MAX_FRAG_THRESHOLD;
907
908 range->pm_capa = 0;
909
910 range->we_version_compiled = WIRELESS_EXT;
911 range->we_version_source = 16;
912
913 for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
914
915 if (pmlmeext->channel_set[i].ChannelNum != 0) {
916 range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
917 range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
918 range->freq[val].e = 1;
919 val++;
920 }
921
922 if (val == IW_MAX_FREQUENCIES)
923 break;
924 }
925
926 range->num_channels = val;
927 range->num_frequency = val;
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
945 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
946
947 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |
948 IW_SCAN_CAPA_BSSID | IW_SCAN_CAPA_CHANNEL |
949 IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE;
950
951
952 return 0;
953}
954
955
956
957
958
959
960static int rtw_wx_set_wap(struct net_device *dev,
961 struct iw_request_info *info,
962 union iwreq_data *awrq,
963 char *extra)
964{
965 uint ret = 0;
966 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
967 struct sockaddr *temp = (struct sockaddr *)awrq;
968 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
969 struct list_head *phead;
970 u8 *dst_bssid, *src_bssid;
971 struct __queue *queue = &pmlmepriv->scanned_queue;
972 struct wlan_network *pnetwork = NULL;
973 enum ndis_802_11_auth_mode authmode;
974
975
976
977 if (_FAIL == rtw_pwr_wakeup(padapter)) {
978 ret = -1;
979 goto exit;
980 }
981
982 if (!padapter->bup) {
983 ret = -1;
984 goto exit;
985 }
986
987 if (temp->sa_family != ARPHRD_ETHER) {
988 ret = -EINVAL;
989 goto exit;
990 }
991
992 authmode = padapter->securitypriv.ndisauthtype;
993 spin_lock_bh(&queue->lock);
994 phead = get_list_head(queue);
995 pmlmepriv->pscanned = phead->next;
996
997 while (phead != pmlmepriv->pscanned) {
998
999 pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
1000
1001 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1002
1003 dst_bssid = pnetwork->network.MacAddress;
1004
1005 src_bssid = temp->sa_data;
1006
1007 if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) {
1008 if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
1009 ret = -1;
1010 spin_unlock_bh(&queue->lock);
1011 goto exit;
1012 }
1013
1014 break;
1015 }
1016 }
1017 spin_unlock_bh(&queue->lock);
1018
1019 rtw_set_802_11_authentication_mode(padapter, authmode);
1020
1021 if (!rtw_set_802_11_bssid(padapter, temp->sa_data)) {
1022 ret = -1;
1023 goto exit;
1024 }
1025
1026exit:
1027
1028
1029
1030 return ret;
1031}
1032
1033static int rtw_wx_get_wap(struct net_device *dev,
1034 struct iw_request_info *info,
1035 union iwreq_data *wrqu, char *extra)
1036{
1037 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1038 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1039 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1040
1041 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1042
1043 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1044
1045 if (check_fwstate(pmlmepriv, _FW_LINKED) ||
1046 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1047 check_fwstate(pmlmepriv, WIFI_AP_STATE))
1048 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1049 else
1050 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1051
1052
1053
1054 return 0;
1055}
1056
1057static int rtw_wx_set_mlme(struct net_device *dev,
1058 struct iw_request_info *info,
1059 union iwreq_data *wrqu, char *extra)
1060{
1061 int ret = 0;
1062 u16 reason;
1063 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1064 struct iw_mlme *mlme = (struct iw_mlme *)extra;
1065
1066 if (!mlme)
1067 return -1;
1068
1069 DBG_88E("%s\n", __func__);
1070
1071 reason = mlme->reason_code;
1072
1073 DBG_88E("%s, cmd =%d, reason =%d\n", __func__, mlme->cmd, reason);
1074
1075 switch (mlme->cmd) {
1076 case IW_MLME_DEAUTH:
1077 if (!rtw_set_802_11_disassociate(padapter))
1078 ret = -1;
1079 break;
1080 case IW_MLME_DISASSOC:
1081 if (!rtw_set_802_11_disassociate(padapter))
1082 ret = -1;
1083 break;
1084 default:
1085 return -EOPNOTSUPP;
1086 }
1087 return ret;
1088}
1089
1090static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
1091 union iwreq_data *wrqu, char *extra)
1092{
1093 u8 _status = false;
1094 int ret = 0;
1095 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1096 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1097 struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
1098 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1099
1100 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1101 ret = -1;
1102 goto exit;
1103 }
1104
1105 if (padapter->bDriverStopped) {
1106 DBG_88E("bDriverStopped =%d\n", padapter->bDriverStopped);
1107 ret = -1;
1108 goto exit;
1109 }
1110
1111 if (!padapter->bup) {
1112 ret = -1;
1113 goto exit;
1114 }
1115
1116 if (!padapter->hw_init_completed) {
1117 ret = -1;
1118 goto exit;
1119 }
1120
1121
1122
1123
1124 if (pmlmepriv->LinkDetectInfo.bBusyTraffic) {
1125 indicate_wx_scan_complete_event(padapter);
1126 goto exit;
1127 }
1128
1129 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) {
1130 indicate_wx_scan_complete_event(padapter);
1131 goto exit;
1132 }
1133
1134
1135
1136
1137
1138 if (pwdinfo->p2p_state != P2P_STATE_NONE) {
1139 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
1140 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
1141 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL);
1142 rtw_free_network_queue(padapter, true);
1143 }
1144
1145 memset(ssid, 0, sizeof(struct ndis_802_11_ssid) * RTW_SSID_SCAN_AMOUNT);
1146
1147 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1148 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1149
1150 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1151 int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
1152
1153 memcpy(ssid[0].Ssid, req->essid, len);
1154 ssid[0].SsidLength = len;
1155
1156 DBG_88E("IW_SCAN_THIS_ESSID, ssid =%s, len =%d\n", req->essid, req->essid_len);
1157
1158 spin_lock_bh(&pmlmepriv->lock);
1159
1160 _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0);
1161
1162 spin_unlock_bh(&pmlmepriv->lock);
1163 } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) {
1164 DBG_88E("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
1165 }
1166 } else {
1167 if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE &&
1168 !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
1169 int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE;
1170 char *pos = extra + WEXT_CSCAN_HEADER_SIZE;
1171 char section;
1172 char sec_len;
1173 int ssid_index = 0;
1174
1175 while (len >= 1) {
1176 section = *(pos++);
1177 len -= 1;
1178
1179 switch (section) {
1180 case WEXT_CSCAN_SSID_SECTION:
1181 if (len < 1) {
1182 len = 0;
1183 break;
1184 }
1185 sec_len = *(pos++); len -= 1;
1186 if (sec_len > 0 && sec_len <= len) {
1187 ssid[ssid_index].SsidLength = sec_len;
1188 memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength);
1189 ssid_index++;
1190 }
1191 pos += sec_len;
1192 len -= sec_len;
1193 break;
1194 case WEXT_CSCAN_TYPE_SECTION:
1195 case WEXT_CSCAN_CHANNEL_SECTION:
1196 pos += 1;
1197 len -= 1;
1198 break;
1199 case WEXT_CSCAN_PASV_DWELL_SECTION:
1200 case WEXT_CSCAN_HOME_DWELL_SECTION:
1201 case WEXT_CSCAN_ACTV_DWELL_SECTION:
1202 pos += 2;
1203 len -= 2;
1204 break;
1205 default:
1206 len = 0;
1207 }
1208 }
1209
1210
1211 _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
1212 } else {
1213 _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
1214 }
1215 }
1216
1217 if (!_status)
1218 ret = -1;
1219
1220exit:
1221
1222 return ret;
1223}
1224
1225static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
1226 union iwreq_data *wrqu, char *extra)
1227{
1228 struct list_head *plist, *phead;
1229 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1230 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1231 struct __queue *queue = &pmlmepriv->scanned_queue;
1232 struct wlan_network *pnetwork = NULL;
1233 char *ev = extra;
1234 char *stop = ev + wrqu->data.length;
1235 u32 ret = 0;
1236 u32 cnt = 0;
1237 u32 wait_for_surveydone;
1238 int wait_status;
1239 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1240
1241 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
1242
1243 wait_for_surveydone = 200;
1244 } else {
1245
1246 wait_for_surveydone = 100;
1247 }
1248
1249 wait_status = _FW_UNDER_SURVEY | _FW_UNDER_LINKING;
1250
1251 while (check_fwstate(pmlmepriv, wait_status)) {
1252 msleep(30);
1253 cnt++;
1254 if (cnt > wait_for_surveydone)
1255 break;
1256 }
1257
1258 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1259
1260 phead = get_list_head(queue);
1261 plist = phead->next;
1262
1263 while (phead != plist) {
1264 if ((stop - ev) < SCAN_ITEM_SIZE) {
1265 ret = -E2BIG;
1266 break;
1267 }
1268
1269 pnetwork = container_of(plist, struct wlan_network, list);
1270
1271
1272 if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0)
1273 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1274
1275 plist = plist->next;
1276 }
1277
1278 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1279
1280 wrqu->data.length = ev - extra;
1281 wrqu->data.flags = 0;
1282
1283 return ret;
1284}
1285
1286
1287
1288
1289
1290
1291static int rtw_wx_set_essid(struct net_device *dev,
1292 struct iw_request_info *a,
1293 union iwreq_data *wrqu, char *extra)
1294{
1295 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1296 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1297 struct __queue *queue = &pmlmepriv->scanned_queue;
1298 struct list_head *phead;
1299 struct wlan_network *pnetwork = NULL;
1300 enum ndis_802_11_auth_mode authmode;
1301 struct ndis_802_11_ssid ndis_ssid;
1302 u8 *dst_ssid, *src_ssid;
1303
1304 uint ret = 0, len;
1305
1306 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1307 ret = -1;
1308 goto exit;
1309 }
1310
1311 if (!padapter->bup) {
1312 ret = -1;
1313 goto exit;
1314 }
1315
1316 if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
1317 ret = -E2BIG;
1318 goto exit;
1319 }
1320
1321 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1322 ret = -1;
1323 goto exit;
1324 }
1325
1326 authmode = padapter->securitypriv.ndisauthtype;
1327 DBG_88E("=>%s\n", __func__);
1328 if (wrqu->essid.flags && wrqu->essid.length) {
1329 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
1330
1331 if (wrqu->essid.length != 33)
1332 DBG_88E("ssid =%s, len =%d\n", extra, wrqu->essid.length);
1333
1334 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1335 ndis_ssid.SsidLength = len;
1336 memcpy(ndis_ssid.Ssid, extra, len);
1337 src_ssid = ndis_ssid.Ssid;
1338
1339 spin_lock_bh(&queue->lock);
1340 phead = get_list_head(queue);
1341 pmlmepriv->pscanned = phead->next;
1342
1343 while (phead != pmlmepriv->pscanned) {
1344 pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
1345
1346 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1347
1348 dst_ssid = pnetwork->network.Ssid.Ssid;
1349
1350 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) &&
1351 (pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) {
1352
1353 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1354 if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
1355 continue;
1356 }
1357
1358 if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
1359 ret = -1;
1360 spin_unlock_bh(&queue->lock);
1361 goto exit;
1362 }
1363
1364 break;
1365 }
1366 }
1367 spin_unlock_bh(&queue->lock);
1368 rtw_set_802_11_authentication_mode(padapter, authmode);
1369 if (!rtw_set_802_11_ssid(padapter, &ndis_ssid)) {
1370 ret = -1;
1371 goto exit;
1372 }
1373 }
1374
1375exit:
1376
1377 DBG_88E("<=%s, ret %d\n", __func__, ret);
1378
1379
1380
1381 return ret;
1382}
1383
1384static int rtw_wx_get_essid(struct net_device *dev,
1385 struct iw_request_info *a,
1386 union iwreq_data *wrqu, char *extra)
1387{
1388 u32 len, ret = 0;
1389 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1390 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1391 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1392
1393 if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
1394 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) {
1395 len = pcur_bss->Ssid.SsidLength;
1396 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1397 } else {
1398 len = 0;
1399 *extra = 0;
1400 }
1401 wrqu->essid.length = len;
1402 wrqu->essid.flags = 1;
1403
1404 return ret;
1405}
1406
1407static int rtw_wx_set_rate(struct net_device *dev,
1408 struct iw_request_info *a,
1409 union iwreq_data *wrqu, char *extra)
1410{
1411 int i, ret = 0;
1412 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1413 u8 datarates[NumRates];
1414 u32 target_rate = wrqu->bitrate.value;
1415 u32 fixed = wrqu->bitrate.fixed;
1416 u32 ratevalue = 0;
1417 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1418
1419 if (target_rate == -1) {
1420 ratevalue = 11;
1421 goto set_rate;
1422 }
1423 target_rate = target_rate / 100000;
1424
1425 switch (target_rate) {
1426 case 10:
1427 ratevalue = 0;
1428 break;
1429 case 20:
1430 ratevalue = 1;
1431 break;
1432 case 55:
1433 ratevalue = 2;
1434 break;
1435 case 60:
1436 ratevalue = 3;
1437 break;
1438 case 90:
1439 ratevalue = 4;
1440 break;
1441 case 110:
1442 ratevalue = 5;
1443 break;
1444 case 120:
1445 ratevalue = 6;
1446 break;
1447 case 180:
1448 ratevalue = 7;
1449 break;
1450 case 240:
1451 ratevalue = 8;
1452 break;
1453 case 360:
1454 ratevalue = 9;
1455 break;
1456 case 480:
1457 ratevalue = 10;
1458 break;
1459 case 540:
1460 ratevalue = 11;
1461 break;
1462 default:
1463 ratevalue = 11;
1464 break;
1465 }
1466
1467set_rate:
1468
1469 for (i = 0; i < NumRates; i++) {
1470 if (ratevalue == mpdatarate[i]) {
1471 datarates[i] = mpdatarate[i];
1472 if (fixed == 0)
1473 break;
1474 } else {
1475 datarates[i] = 0xff;
1476 }
1477 }
1478
1479 if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1480 ret = -1;
1481
1482 return ret;
1483}
1484
1485static int rtw_wx_get_rate(struct net_device *dev,
1486 struct iw_request_info *info,
1487 union iwreq_data *wrqu, char *extra)
1488{
1489 u16 max_rate = 0;
1490
1491 max_rate = rtw_get_cur_max_rate((struct adapter *)rtw_netdev_priv(dev));
1492
1493 if (max_rate == 0)
1494 return -EPERM;
1495
1496 wrqu->bitrate.fixed = 0;
1497 wrqu->bitrate.value = max_rate * 100000;
1498
1499 return 0;
1500}
1501
1502static int rtw_wx_set_rts(struct net_device *dev,
1503 struct iw_request_info *info,
1504 union iwreq_data *wrqu, char *extra)
1505{
1506 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1507
1508
1509
1510 if (wrqu->rts.disabled) {
1511 padapter->registrypriv.rts_thresh = 2347;
1512 } else {
1513 if (wrqu->rts.value < 0 ||
1514 wrqu->rts.value > 2347)
1515 return -EINVAL;
1516
1517 padapter->registrypriv.rts_thresh = wrqu->rts.value;
1518 }
1519
1520 DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh);
1521
1522
1523
1524 return 0;
1525}
1526
1527static int rtw_wx_get_rts(struct net_device *dev,
1528 struct iw_request_info *info,
1529 union iwreq_data *wrqu, char *extra)
1530{
1531 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1532
1533
1534
1535 DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh);
1536
1537 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1538 wrqu->rts.fixed = 0;
1539
1540
1541
1542
1543 return 0;
1544}
1545
1546static int rtw_wx_set_frag(struct net_device *dev,
1547 struct iw_request_info *info,
1548 union iwreq_data *wrqu, char *extra)
1549{
1550 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1551
1552
1553
1554 if (wrqu->frag.disabled) {
1555 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1556 } else {
1557 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1558 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1559 return -EINVAL;
1560
1561 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1562 }
1563
1564 DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len);
1565
1566
1567
1568 return 0;
1569}
1570
1571static int rtw_wx_get_frag(struct net_device *dev,
1572 struct iw_request_info *info,
1573 union iwreq_data *wrqu, char *extra)
1574{
1575 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1576
1577
1578
1579 DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len);
1580
1581 wrqu->frag.value = padapter->xmitpriv.frag_len;
1582 wrqu->frag.fixed = 0;
1583
1584
1585
1586 return 0;
1587}
1588
1589static int rtw_wx_get_retry(struct net_device *dev,
1590 struct iw_request_info *info,
1591 union iwreq_data *wrqu, char *extra)
1592{
1593 wrqu->retry.value = 7;
1594 wrqu->retry.fixed = 0;
1595 wrqu->retry.disabled = 1;
1596
1597 return 0;
1598}
1599
1600static int rtw_wx_set_enc(struct net_device *dev,
1601 struct iw_request_info *info,
1602 union iwreq_data *wrqu, char *keybuf)
1603{
1604 u32 key, ret = 0;
1605 u32 keyindex_provided;
1606 struct ndis_802_11_wep wep;
1607 enum ndis_802_11_auth_mode authmode;
1608
1609 struct iw_point *erq = &wrqu->encoding;
1610 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1611 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
1612 DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq->flags);
1613
1614 memset(&wep, 0, sizeof(struct ndis_802_11_wep));
1615
1616 key = erq->flags & IW_ENCODE_INDEX;
1617
1618
1619
1620 if (erq->flags & IW_ENCODE_DISABLED) {
1621 DBG_88E("EncryptionDisabled\n");
1622 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1623 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1624 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1625 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1626 authmode = Ndis802_11AuthModeOpen;
1627 padapter->securitypriv.ndisauthtype = authmode;
1628
1629 goto exit;
1630 }
1631
1632 if (key) {
1633 if (key > WEP_KEYS)
1634 return -EINVAL;
1635 key--;
1636 keyindex_provided = 1;
1637 } else {
1638 keyindex_provided = 0;
1639 key = padapter->securitypriv.dot11PrivacyKeyIndex;
1640 DBG_88E("rtw_wx_set_enc, key =%d\n", key);
1641 }
1642
1643
1644 if (erq->flags & IW_ENCODE_OPEN) {
1645 DBG_88E("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
1646 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1647 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1648 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1649 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1650 authmode = Ndis802_11AuthModeOpen;
1651 padapter->securitypriv.ndisauthtype = authmode;
1652 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1653 DBG_88E("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
1654 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1655 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1656 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1657 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1658 authmode = Ndis802_11AuthModeShared;
1659 padapter->securitypriv.ndisauthtype = authmode;
1660 } else {
1661 DBG_88E("rtw_wx_set_enc():erq->flags = 0x%x\n", erq->flags);
1662
1663 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1664 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1665 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1666 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1667 authmode = Ndis802_11AuthModeOpen;
1668 padapter->securitypriv.ndisauthtype = authmode;
1669 }
1670
1671 wep.KeyIndex = key;
1672 if (erq->length > 0) {
1673 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1674
1675 wep.Length = wep.KeyLength + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
1676 } else {
1677 wep.KeyLength = 0;
1678
1679 if (keyindex_provided == 1) {
1680
1681 padapter->securitypriv.dot11PrivacyKeyIndex = key;
1682
1683 DBG_88E("(keyindex_provided == 1), keyid =%d, key_len =%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
1684
1685 switch (padapter->securitypriv.dot11DefKeylen[key]) {
1686 case 5:
1687 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1688 break;
1689 case 13:
1690 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
1691 break;
1692 default:
1693 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1694 break;
1695 }
1696
1697 goto exit;
1698 }
1699 }
1700
1701 wep.KeyIndex |= 0x80000000;
1702
1703 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1704
1705 if (!rtw_set_802_11_add_wep(padapter, &wep)) {
1706 if (rf_on == pwrpriv->rf_pwrstate)
1707 ret = -EOPNOTSUPP;
1708 goto exit;
1709 }
1710
1711exit:
1712
1713
1714
1715 return ret;
1716}
1717
1718static int rtw_wx_get_enc(struct net_device *dev,
1719 struct iw_request_info *info,
1720 union iwreq_data *wrqu, char *keybuf)
1721{
1722 uint key, ret = 0;
1723 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1724 struct iw_point *erq = &wrqu->encoding;
1725 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1726
1727
1728
1729 if (check_fwstate(pmlmepriv, _FW_LINKED) != true) {
1730 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1731 erq->length = 0;
1732 erq->flags |= IW_ENCODE_DISABLED;
1733 return 0;
1734 }
1735 }
1736
1737 key = erq->flags & IW_ENCODE_INDEX;
1738
1739 if (key) {
1740 if (key > WEP_KEYS)
1741 return -EINVAL;
1742 key--;
1743 } else {
1744 key = padapter->securitypriv.dot11PrivacyKeyIndex;
1745 }
1746
1747 erq->flags = key + 1;
1748
1749 switch (padapter->securitypriv.ndisencryptstatus) {
1750 case Ndis802_11EncryptionNotSupported:
1751 case Ndis802_11EncryptionDisabled:
1752 erq->length = 0;
1753 erq->flags |= IW_ENCODE_DISABLED;
1754 break;
1755 case Ndis802_11Encryption1Enabled:
1756 erq->length = padapter->securitypriv.dot11DefKeylen[key];
1757 if (erq->length) {
1758 memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
1759
1760 erq->flags |= IW_ENCODE_ENABLED;
1761
1762 if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
1763 erq->flags |= IW_ENCODE_OPEN;
1764 else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
1765 erq->flags |= IW_ENCODE_RESTRICTED;
1766 } else {
1767 erq->length = 0;
1768 erq->flags |= IW_ENCODE_DISABLED;
1769 }
1770 break;
1771 case Ndis802_11Encryption2Enabled:
1772 case Ndis802_11Encryption3Enabled:
1773 erq->length = 16;
1774 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
1775 break;
1776 default:
1777 erq->length = 0;
1778 erq->flags |= IW_ENCODE_DISABLED;
1779 break;
1780 }
1781
1782
1783 return ret;
1784}
1785
1786static int rtw_wx_get_power(struct net_device *dev,
1787 struct iw_request_info *info,
1788 union iwreq_data *wrqu, char *extra)
1789{
1790 wrqu->power.value = 0;
1791 wrqu->power.fixed = 0;
1792 wrqu->power.disabled = 1;
1793
1794 return 0;
1795}
1796
1797static int rtw_wx_set_gen_ie(struct net_device *dev,
1798 struct iw_request_info *info,
1799 union iwreq_data *wrqu, char *extra)
1800{
1801 int ret;
1802 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1803
1804 ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
1805 return ret;
1806}
1807
1808static int rtw_wx_set_auth(struct net_device *dev,
1809 struct iw_request_info *info,
1810 union iwreq_data *wrqu, char *extra)
1811{
1812 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1813 struct iw_param *param = (struct iw_param *)&wrqu->param;
1814 int ret = 0;
1815
1816 switch (param->flags & IW_AUTH_INDEX) {
1817 case IW_AUTH_WPA_VERSION:
1818 break;
1819 case IW_AUTH_CIPHER_PAIRWISE:
1820
1821 break;
1822 case IW_AUTH_CIPHER_GROUP:
1823
1824 break;
1825 case IW_AUTH_KEY_MGMT:
1826
1827
1828
1829 break;
1830 case IW_AUTH_TKIP_COUNTERMEASURES:
1831 if (param->value) {
1832
1833 padapter->securitypriv.btkip_countermeasure = true;
1834 } else {
1835
1836 padapter->securitypriv.btkip_countermeasure = false;
1837 }
1838 break;
1839 case IW_AUTH_DROP_UNENCRYPTED:
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852 if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
1853 break;
1854
1855
1856 if (param->value) {
1857 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1858 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1859 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1860 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1861 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
1862 }
1863
1864 break;
1865 case IW_AUTH_80211_AUTH_ALG:
1866
1867
1868
1869 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
1870 LeaveAllPowerSaveMode(padapter);
1871 rtw_disassoc_cmd(padapter, 500, false);
1872 DBG_88E("%s...call rtw_indicate_disconnect\n ", __func__);
1873 rtw_indicate_disconnect(padapter);
1874 rtw_free_assoc_resources(padapter, 1);
1875 }
1876 ret = wpa_set_auth_algs(dev, (u32)param->value);
1877 break;
1878 case IW_AUTH_WPA_ENABLED:
1879 break;
1880 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1881 break;
1882 case IW_AUTH_PRIVACY_INVOKED:
1883 break;
1884 default:
1885 return -EOPNOTSUPP;
1886 }
1887
1888 return ret;
1889}
1890
1891static int rtw_wx_set_enc_ext(struct net_device *dev,
1892 struct iw_request_info *info,
1893 union iwreq_data *wrqu, char *extra)
1894{
1895 char *alg_name;
1896 u32 param_len;
1897 struct ieee_param *param = NULL;
1898 struct iw_point *pencoding = &wrqu->encoding;
1899 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1900 int ret = -1;
1901
1902 param_len = sizeof(struct ieee_param) + pext->key_len;
1903 param = kzalloc(param_len, GFP_KERNEL);
1904 if (!param)
1905 return -ENOMEM;
1906
1907 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1908 memset(param->sta_addr, 0xff, ETH_ALEN);
1909
1910 switch (pext->alg) {
1911 case IW_ENCODE_ALG_NONE:
1912
1913
1914 alg_name = "none";
1915 break;
1916 case IW_ENCODE_ALG_WEP:
1917 alg_name = "WEP";
1918 break;
1919 case IW_ENCODE_ALG_TKIP:
1920 alg_name = "TKIP";
1921 break;
1922 case IW_ENCODE_ALG_CCMP:
1923 alg_name = "CCMP";
1924 break;
1925 default:
1926 goto out;
1927 }
1928
1929 strlcpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1930
1931 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1932 param->u.crypt.set_tx = 1;
1933
1934
1935
1936
1937 if ((pext->alg != IW_ENCODE_ALG_WEP) &&
1938 (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
1939 param->u.crypt.set_tx = 0;
1940
1941 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
1942
1943 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1944 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
1945
1946 if (pext->key_len) {
1947 param->u.crypt.key_len = pext->key_len;
1948 memcpy(param->u.crypt.key, pext + 1, pext->key_len);
1949 }
1950
1951 ret = wpa_set_encryption(dev, param, param_len);
1952
1953out:
1954 kfree(param);
1955 return ret;
1956}
1957
1958static int rtw_wx_get_nick(struct net_device *dev,
1959 struct iw_request_info *info,
1960 union iwreq_data *wrqu, char *extra)
1961{
1962 if (extra) {
1963 wrqu->data.length = 14;
1964 wrqu->data.flags = 1;
1965 memcpy(extra, "<WIFI@REALTEK>", 14);
1966 }
1967
1968
1969 return 0;
1970}
1971
1972static int rtw_wx_read32(struct net_device *dev,
1973 struct iw_request_info *info,
1974 union iwreq_data *wrqu, char *extra)
1975{
1976 struct adapter *padapter;
1977 struct iw_point *p;
1978 u16 len;
1979 u32 addr;
1980 u32 data32;
1981 u32 bytes;
1982 u8 *ptmp;
1983 int ret;
1984
1985 padapter = (struct adapter *)rtw_netdev_priv(dev);
1986 p = &wrqu->data;
1987 len = p->length;
1988 ptmp = memdup_user(p->pointer, len);
1989 if (IS_ERR(ptmp))
1990 return PTR_ERR(ptmp);
1991
1992 bytes = 0;
1993 addr = 0;
1994 sscanf(ptmp, "%d,%x", &bytes, &addr);
1995
1996 switch (bytes) {
1997 case 1:
1998 data32 = rtw_read8(padapter, addr);
1999 sprintf(extra, "0x%02X", data32);
2000 break;
2001 case 2:
2002 data32 = rtw_read16(padapter, addr);
2003 sprintf(extra, "0x%04X", data32);
2004 break;
2005 case 4:
2006 data32 = rtw_read32(padapter, addr);
2007 sprintf(extra, "0x%08X", data32);
2008 break;
2009 default:
2010 DBG_88E(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__);
2011 ret = -EINVAL;
2012 goto err_free_ptmp;
2013 }
2014 DBG_88E(KERN_INFO "%s: addr = 0x%08X data =%s\n", __func__, addr, extra);
2015
2016 kfree(ptmp);
2017 return 0;
2018
2019err_free_ptmp:
2020 kfree(ptmp);
2021 return ret;
2022}
2023
2024static int rtw_wx_write32(struct net_device *dev,
2025 struct iw_request_info *info,
2026 union iwreq_data *wrqu, char *extra)
2027{
2028 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2029
2030 u32 addr;
2031 u32 data32;
2032 u32 bytes;
2033
2034 bytes = 0;
2035 addr = 0;
2036 data32 = 0;
2037 sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
2038
2039 switch (bytes) {
2040 case 1:
2041 rtw_write8(padapter, addr, (u8)data32);
2042 DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%02X\n", __func__, addr, (u8)data32);
2043 break;
2044 case 2:
2045 rtw_write16(padapter, addr, (u16)data32);
2046 DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%04X\n", __func__, addr, (u16)data32);
2047 break;
2048 case 4:
2049 rtw_write32(padapter, addr, data32);
2050 DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%08X\n", __func__, addr, data32);
2051 break;
2052 default:
2053 DBG_88E(KERN_INFO "%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);
2054 return -EINVAL;
2055 }
2056
2057 return 0;
2058}
2059
2060static int rtw_wx_read_rf(struct net_device *dev,
2061 struct iw_request_info *info,
2062 union iwreq_data *wrqu, char *extra)
2063{
2064 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2065 u32 path, addr, data32;
2066
2067 path = *(u32 *)extra;
2068 addr = *((u32 *)extra + 1);
2069 data32 = rtl8188e_PHY_QueryRFReg(padapter, path, addr, 0xFFFFF);
2070
2071
2072
2073
2074
2075 sprintf(extra, "0x%05x", data32);
2076
2077 return 0;
2078}
2079
2080static int rtw_wx_write_rf(struct net_device *dev,
2081 struct iw_request_info *info,
2082 union iwreq_data *wrqu, char *extra)
2083{
2084 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2085 u32 path, addr, data32;
2086
2087 path = *(u32 *)extra;
2088 addr = *((u32 *)extra + 1);
2089 data32 = *((u32 *)extra + 2);
2090 rtl8188e_PHY_SetRFReg(padapter, path, addr, 0xFFFFF, data32);
2091
2092 return 0;
2093}
2094
2095static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
2096 union iwreq_data *wrqu, char *b)
2097{
2098 return -1;
2099}
2100
2101static int dummy(struct net_device *dev, struct iw_request_info *a,
2102 union iwreq_data *wrqu, char *b)
2103{
2104 return -1;
2105}
2106
2107static int rtw_wx_set_channel_plan(struct net_device *dev,
2108 struct iw_request_info *info,
2109 union iwreq_data *wrqu, char *extra)
2110{
2111 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2112 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2113 u8 channel_plan_req = (u8)(*((int *)wrqu));
2114
2115 if (_SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1))
2116 DBG_88E("%s set channel_plan = 0x%02X\n", __func__, pmlmepriv->ChannelPlan);
2117 else
2118 return -EPERM;
2119
2120 return 0;
2121}
2122
2123static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
2124 struct iw_request_info *a,
2125 union iwreq_data *wrqu, char *b)
2126{
2127 return 0;
2128}
2129
2130static int rtw_wx_get_sensitivity(struct net_device *dev,
2131 struct iw_request_info *info,
2132 union iwreq_data *wrqu, char *buf)
2133{
2134 return 0;
2135}
2136
2137static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
2138 struct iw_request_info *info,
2139 union iwreq_data *wrqu, char *extra)
2140{
2141 return 0;
2142}
2143
2144
2145
2146
2147
2148static int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info,
2149 union iwreq_data *wrqu, char *extra)
2150{
2151 return 0;
2152}
2153
2154static int rtw_get_ap_info(struct net_device *dev,
2155 struct iw_request_info *info,
2156 union iwreq_data *wrqu, char *extra)
2157{
2158 int ret = 0;
2159 u32 cnt = 0, wpa_ielen;
2160 struct list_head *plist, *phead;
2161 unsigned char *pbuf;
2162 u8 bssid[ETH_ALEN];
2163 char data[32];
2164 struct wlan_network *pnetwork = NULL;
2165 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2166 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2167 struct __queue *queue = &pmlmepriv->scanned_queue;
2168 struct iw_point *pdata = &wrqu->data;
2169
2170 DBG_88E("+rtw_get_aplist_info\n");
2171
2172 if (padapter->bDriverStopped || !pdata) {
2173 ret = -EINVAL;
2174 goto exit;
2175 }
2176
2177 while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING)))) {
2178 msleep(30);
2179 cnt++;
2180 if (cnt > 100)
2181 break;
2182 }
2183 pdata->flags = 0;
2184 if (pdata->length >= 32) {
2185 if (copy_from_user(data, pdata->pointer, 32)) {
2186 ret = -EINVAL;
2187 goto exit;
2188 }
2189 } else {
2190 ret = -EINVAL;
2191 goto exit;
2192 }
2193
2194 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
2195
2196 phead = get_list_head(queue);
2197 plist = phead->next;
2198
2199 while (phead != plist) {
2200 pnetwork = container_of(plist, struct wlan_network, list);
2201
2202 if (!mac_pton(data, bssid)) {
2203 DBG_88E("Invalid BSSID '%s'.\n", (u8 *)data);
2204 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
2205 return -EINVAL;
2206 }
2207
2208 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
2209
2210 DBG_88E("BSSID:%pM\n", (bssid));
2211
2212 pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
2213 if (pbuf && (wpa_ielen > 0)) {
2214 pdata->flags = 1;
2215 break;
2216 }
2217
2218 pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
2219 if (pbuf && (wpa_ielen > 0)) {
2220 pdata->flags = 2;
2221 break;
2222 }
2223 }
2224
2225 plist = plist->next;
2226 }
2227
2228 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
2229
2230 if (pdata->length >= 34) {
2231 if (copy_to_user(pdata->pointer + 32, (u8 *)&pdata->flags, 1)) {
2232 ret = -EINVAL;
2233 goto exit;
2234 }
2235 }
2236
2237exit:
2238
2239 return ret;
2240}
2241
2242static int rtw_set_pid(struct net_device *dev,
2243 struct iw_request_info *info,
2244 union iwreq_data *wrqu, char *extra)
2245{
2246 int ret = 0;
2247 struct adapter *padapter = rtw_netdev_priv(dev);
2248 int *pdata = (int *)wrqu;
2249 int selector;
2250
2251 if (padapter->bDriverStopped || !pdata) {
2252 ret = -EINVAL;
2253 goto exit;
2254 }
2255
2256 selector = *pdata;
2257 if (selector < 3 && selector >= 0) {
2258 padapter->pid[selector] = *(pdata + 1);
2259 ui_pid[selector] = *(pdata + 1);
2260 DBG_88E("%s set pid[%d] =%d\n", __func__, selector, padapter->pid[selector]);
2261 } else {
2262 DBG_88E("%s selector %d error\n", __func__, selector);
2263 }
2264exit:
2265 return ret;
2266}
2267
2268static int rtw_wps_start(struct net_device *dev,
2269 struct iw_request_info *info,
2270 union iwreq_data *wrqu, char *extra)
2271{
2272 int ret = 0;
2273 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2274 struct iw_point *pdata = &wrqu->data;
2275 u32 u32wps_start = 0;
2276
2277 if (!pdata)
2278 return -EINVAL;
2279 ret = copy_from_user((void *)&u32wps_start, pdata->pointer, 4);
2280 if (ret) {
2281 ret = -EINVAL;
2282 goto exit;
2283 }
2284
2285 if (padapter->bDriverStopped) {
2286 ret = -EINVAL;
2287 goto exit;
2288 }
2289
2290 if (u32wps_start == 0)
2291 u32wps_start = *extra;
2292
2293 DBG_88E("[%s] wps_start = %d\n", __func__, u32wps_start);
2294
2295 if (u32wps_start == 1)
2296 rtw_led_control(padapter, LED_CTL_START_WPS);
2297 else if (u32wps_start == 2)
2298 rtw_led_control(padapter, LED_CTL_STOP_WPS);
2299 else if (u32wps_start == 3)
2300 rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);
2301
2302exit:
2303 return ret;
2304}
2305
2306static int rtw_wext_p2p_enable(struct net_device *dev,
2307 struct iw_request_info *info,
2308 union iwreq_data *wrqu, char *extra)
2309{
2310 int ret = 0;
2311 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2312 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2313 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2314 enum P2P_ROLE init_role = P2P_ROLE_DISABLE;
2315
2316 if (*extra == '0')
2317 init_role = P2P_ROLE_DISABLE;
2318 else if (*extra == '1')
2319 init_role = P2P_ROLE_DEVICE;
2320 else if (*extra == '2')
2321 init_role = P2P_ROLE_CLIENT;
2322 else if (*extra == '3')
2323 init_role = P2P_ROLE_GO;
2324
2325 if (_FAIL == rtw_p2p_enable(padapter, init_role)) {
2326 ret = -EFAULT;
2327 goto exit;
2328 }
2329
2330
2331 if (init_role != P2P_ROLE_DISABLE) {
2332 u8 channel, ch_offset;
2333 u16 bwmode;
2334
2335 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) {
2336
2337 channel = pwdinfo->listen_channel;
2338 pwdinfo->operating_channel = pwdinfo->listen_channel;
2339 ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2340 bwmode = HT_CHANNEL_WIDTH_20;
2341 } else {
2342 pwdinfo->operating_channel = pmlmeext->cur_channel;
2343
2344 channel = pwdinfo->operating_channel;
2345 ch_offset = pmlmeext->cur_ch_offset;
2346 bwmode = pmlmeext->cur_bwmode;
2347 }
2348
2349 set_channel_bwmode(padapter, channel, ch_offset, bwmode);
2350 }
2351
2352exit:
2353 return ret;
2354}
2355
2356static int rtw_p2p_set_go_nego_ssid(struct net_device *dev,
2357 struct iw_request_info *info,
2358 union iwreq_data *wrqu, char *extra)
2359{
2360 int ret = 0;
2361 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2362 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2363
2364 DBG_88E("[%s] ssid = %s, len = %zu\n", __func__, extra, strlen(extra));
2365 memcpy(pwdinfo->nego_ssid, extra, strlen(extra));
2366 pwdinfo->nego_ssidlen = strlen(extra);
2367
2368 return ret;
2369}
2370
2371static int rtw_p2p_set_intent(struct net_device *dev,
2372 struct iw_request_info *info,
2373 union iwreq_data *wrqu, char *extra)
2374{
2375 int ret = 0;
2376 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2377 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2378 u8 intent = pwdinfo->intent;
2379
2380 switch (wrqu->data.length) {
2381 case 1:
2382 intent = extra[0] - '0';
2383 break;
2384 case 2:
2385 intent = str_2char2num(extra[0], extra[1]);
2386 break;
2387 }
2388 if (intent <= 15)
2389 pwdinfo->intent = intent;
2390 else
2391 ret = -1;
2392 DBG_88E("[%s] intent = %d\n", __func__, intent);
2393 return ret;
2394}
2395
2396static int rtw_p2p_set_listen_ch(struct net_device *dev,
2397 struct iw_request_info *info,
2398 union iwreq_data *wrqu, char *extra)
2399{
2400 int ret = 0;
2401 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2402 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2403 u8 listen_ch = pwdinfo->listen_channel;
2404
2405 switch (wrqu->data.length) {
2406 case 1:
2407 listen_ch = extra[0] - '0';
2408 break;
2409 case 2:
2410 listen_ch = str_2char2num(extra[0], extra[1]);
2411 break;
2412 }
2413
2414 if ((listen_ch == 1) || (listen_ch == 6) || (listen_ch == 11)) {
2415 pwdinfo->listen_channel = listen_ch;
2416 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
2417 } else {
2418 ret = -1;
2419 }
2420
2421 DBG_88E("[%s] listen_ch = %d\n", __func__, pwdinfo->listen_channel);
2422
2423 return ret;
2424}
2425
2426static int rtw_p2p_set_op_ch(struct net_device *dev,
2427 struct iw_request_info *info,
2428 union iwreq_data *wrqu, char *extra)
2429{
2430
2431
2432
2433 int ret = 0;
2434 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2435 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2436 u8 op_ch = pwdinfo->operating_channel;
2437
2438 switch (wrqu->data.length) {
2439 case 1:
2440 op_ch = extra[0] - '0';
2441 break;
2442 case 2:
2443 op_ch = str_2char2num(extra[0], extra[1]);
2444 break;
2445 }
2446
2447 if (op_ch > 0)
2448 pwdinfo->operating_channel = op_ch;
2449 else
2450 ret = -1;
2451
2452 DBG_88E("[%s] op_ch = %d\n", __func__, pwdinfo->operating_channel);
2453
2454 return ret;
2455}
2456
2457static int rtw_p2p_profilefound(struct net_device *dev,
2458 struct iw_request_info *info,
2459 union iwreq_data *wrqu, char *extra)
2460{
2461 int ret = 0;
2462 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2463 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475 DBG_88E("[%s] In value = %s, len = %d\n", __func__, extra, wrqu->data.length - 1);
2476
2477
2478 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
2479 if (extra[0] == '0') {
2480
2481 memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM);
2482 pwdinfo->profileindex = 0;
2483 } else {
2484 if (pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM) {
2485 ret = -1;
2486 } else {
2487 int jj, kk;
2488
2489
2490
2491 for (jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3)
2492 pwdinfo->profileinfo[pwdinfo->profileindex].peermac[jj] = key_2char2num(extra[kk], extra[kk + 1]);
2493
2494 pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen = (extra[18] - '0') * 10 + (extra[19] - '0');
2495 memcpy(pwdinfo->profileinfo[pwdinfo->profileindex].ssid, &extra[20], pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen);
2496 pwdinfo->profileindex++;
2497 }
2498 }
2499 }
2500
2501 return ret;
2502}
2503
2504static int rtw_p2p_setDN(struct net_device *dev,
2505 struct iw_request_info *info,
2506 union iwreq_data *wrqu, char *extra)
2507{
2508 int ret = 0;
2509 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2510 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2511
2512 DBG_88E("[%s] %s %d\n", __func__, extra, wrqu->data.length - 1);
2513 memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN);
2514 memcpy(pwdinfo->device_name, extra, wrqu->data.length - 1);
2515 pwdinfo->device_name_len = wrqu->data.length - 1;
2516
2517 return ret;
2518}
2519
2520static int rtw_p2p_get_status(struct net_device *dev,
2521 struct iw_request_info *info,
2522 union iwreq_data *wrqu, char *extra)
2523{
2524 int ret = 0;
2525 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2526 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2527
2528 if (padapter->bShowGetP2PState)
2529 DBG_88E("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
2530 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
2531 pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
2532
2533
2534
2535
2536 sprintf(extra, "\n\nStatus =%.2d\n", rtw_p2p_state(pwdinfo));
2537 wrqu->data.length = strlen(extra);
2538
2539 return ret;
2540}
2541
2542
2543
2544
2545
2546
2547static int rtw_p2p_get_req_cm(struct net_device *dev,
2548 struct iw_request_info *info,
2549 union iwreq_data *wrqu, char *extra)
2550{
2551 int ret = 0;
2552 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2553 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2554
2555 sprintf(extra, "\n\nCM =%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);
2556 wrqu->data.length = strlen(extra);
2557 return ret;
2558}
2559
2560static int rtw_p2p_get_role(struct net_device *dev,
2561 struct iw_request_info *info,
2562 union iwreq_data *wrqu, char *extra)
2563{
2564 int ret = 0;
2565 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2566 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2567
2568 DBG_88E("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
2569 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
2570 pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
2571
2572 sprintf(extra, "\n\nRole =%.2d\n", rtw_p2p_role(pwdinfo));
2573 wrqu->data.length = strlen(extra);
2574 return ret;
2575}
2576
2577static int rtw_p2p_get_peer_ifaddr(struct net_device *dev,
2578 struct iw_request_info *info,
2579 union iwreq_data *wrqu, char *extra)
2580{
2581 int ret = 0;
2582 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2583 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2584
2585 DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n", __func__,
2586 rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
2587 pwdinfo->p2p_peer_interface_addr);
2588 sprintf(extra, "\nMAC %pM",
2589 pwdinfo->p2p_peer_interface_addr);
2590 wrqu->data.length = strlen(extra);
2591 return ret;
2592}
2593
2594static int rtw_p2p_get_peer_devaddr(struct net_device *dev,
2595 struct iw_request_info *info,
2596 union iwreq_data *wrqu, char *extra)
2597
2598{
2599 int ret = 0;
2600 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2601 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2602
2603 DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n", __func__,
2604 rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
2605 pwdinfo->rx_prov_disc_info.peerDevAddr);
2606 sprintf(extra, "\n%pM",
2607 pwdinfo->rx_prov_disc_info.peerDevAddr);
2608 wrqu->data.length = strlen(extra);
2609 return ret;
2610}
2611
2612static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev,
2613 struct iw_request_info *info,
2614 union iwreq_data *wrqu, char *extra)
2615
2616{
2617 int ret = 0;
2618 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2619 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2620
2621 DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n",
2622 __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
2623 pwdinfo->p2p_peer_device_addr);
2624 sprintf(extra, "\nMAC %pM",
2625 pwdinfo->p2p_peer_device_addr);
2626 wrqu->data.length = strlen(extra);
2627 return ret;
2628}
2629
2630static int rtw_p2p_get_groupid(struct net_device *dev,
2631 struct iw_request_info *info,
2632 union iwreq_data *wrqu, char *extra)
2633
2634{
2635 int ret = 0;
2636 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2637 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2638
2639 sprintf(extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s",
2640 pwdinfo->groupid_info.go_device_addr[0], pwdinfo->groupid_info.go_device_addr[1],
2641 pwdinfo->groupid_info.go_device_addr[2], pwdinfo->groupid_info.go_device_addr[3],
2642 pwdinfo->groupid_info.go_device_addr[4], pwdinfo->groupid_info.go_device_addr[5],
2643 pwdinfo->groupid_info.ssid);
2644 wrqu->data.length = strlen(extra);
2645 return ret;
2646}
2647
2648static int rtw_p2p_get_op_ch(struct net_device *dev,
2649 struct iw_request_info *info,
2650 union iwreq_data *wrqu, char *extra)
2651
2652{
2653 int ret = 0;
2654 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2655 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2656
2657 DBG_88E("[%s] Op_ch = %02x\n", __func__, pwdinfo->operating_channel);
2658
2659 sprintf(extra, "\n\nOp_ch =%.2d\n", pwdinfo->operating_channel);
2660 wrqu->data.length = strlen(extra);
2661 return ret;
2662}
2663
2664static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
2665 struct iw_request_info *info,
2666 union iwreq_data *wrqu, char *extra)
2667{
2668 int ret = 0;
2669 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2670 u8 peerMAC[ETH_ALEN] = {0x00};
2671 int jj, kk;
2672 u8 peerMACStr[17] = {0x00};
2673 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2674 struct list_head *plist, *phead;
2675 struct __queue *queue = &pmlmepriv->scanned_queue;
2676 struct wlan_network *pnetwork = NULL;
2677 u8 blnMatch = 0;
2678 u16 attr_content = 0;
2679 uint attr_contentlen = 0;
2680
2681 u8 attr_content_str[6 + 17] = {0x00};
2682
2683
2684
2685
2686
2687
2688 DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
2689 if (copy_from_user(peerMACStr, wrqu->data.pointer + 6, 17))
2690 return -EFAULT;
2691
2692 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
2693 peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
2694
2695 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
2696
2697 phead = get_list_head(queue);
2698 plist = phead->next;
2699
2700 while (phead != plist) {
2701 pnetwork = container_of(plist, struct wlan_network, list);
2702 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
2703 u8 *wpsie;
2704 uint wpsie_len = 0;
2705 __be16 be_tmp;
2706
2707
2708 wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len);
2709 if (wpsie) {
2710 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&be_tmp, &attr_contentlen);
2711 if (attr_contentlen) {
2712 attr_content = be16_to_cpu(be_tmp);
2713 sprintf(attr_content_str, "\n\nM =%.4d", attr_content);
2714 blnMatch = 1;
2715 }
2716 }
2717 break;
2718 }
2719 plist = plist->next;
2720 }
2721
2722 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
2723
2724 if (!blnMatch)
2725 sprintf(attr_content_str, "\n\nM = 0000");
2726
2727 if (copy_to_user(wrqu->data.pointer, attr_content_str, 6 + 17))
2728 return -EFAULT;
2729 return ret;
2730}
2731
2732static int rtw_p2p_get_go_device_address(struct net_device *dev,
2733 struct iw_request_info *info,
2734 union iwreq_data *wrqu, char *extra)
2735{
2736 int ret = 0;
2737 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2738 u8 peerMAC[ETH_ALEN] = {0x00};
2739 int jj, kk;
2740 u8 peerMACStr[17] = {0x00};
2741 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2742 struct list_head *plist, *phead;
2743 struct __queue *queue = &pmlmepriv->scanned_queue;
2744 struct wlan_network *pnetwork = NULL;
2745 u8 blnMatch = 0;
2746 u8 *p2pie;
2747 uint p2pielen = 0, attr_contentlen = 0;
2748 u8 attr_content[100] = {0x00};
2749
2750 u8 go_devadd_str[100 + 10] = {0x00};
2751
2752
2753
2754
2755
2756
2757 DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
2758 if (copy_from_user(peerMACStr, wrqu->data.pointer + 10, 17))
2759 return -EFAULT;
2760
2761 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
2762 peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
2763
2764 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
2765
2766 phead = get_list_head(queue);
2767 plist = phead->next;
2768
2769 while (phead != plist) {
2770 pnetwork = container_of(plist, struct wlan_network, list);
2771 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
2772
2773
2774
2775
2776 p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
2777 if (p2pie) {
2778 while (p2pie) {
2779
2780
2781
2782 memset(attr_content, 0x00, 100);
2783 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
2784
2785 blnMatch = 1;
2786 break;
2787 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
2788
2789 blnMatch = 1;
2790 break;
2791 }
2792
2793
2794 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
2795 }
2796 }
2797 }
2798
2799 plist = plist->next;
2800 }
2801
2802 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
2803
2804 if (!blnMatch)
2805 sprintf(go_devadd_str, "\n\ndev_add = NULL");
2806 else
2807 sprintf(go_devadd_str, "\ndev_add =%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
2808 attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
2809
2810 if (copy_to_user(wrqu->data.pointer, go_devadd_str, 10 + 17))
2811 return -EFAULT;
2812 return ret;
2813}
2814
2815static int rtw_p2p_get_device_type(struct net_device *dev,
2816 struct iw_request_info *info,
2817 union iwreq_data *wrqu, char *extra)
2818{
2819 int ret = 0;
2820 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2821 u8 peerMAC[ETH_ALEN] = {0x00};
2822 int jj, kk;
2823 u8 peerMACStr[17] = {0x00};
2824 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2825 struct list_head *plist, *phead;
2826 struct __queue *queue = &pmlmepriv->scanned_queue;
2827 struct wlan_network *pnetwork = NULL;
2828 u8 blnMatch = 0;
2829 u8 dev_type[8] = {0x00};
2830 uint dev_type_len = 0;
2831 u8 dev_type_str[17 + 9] = {0x00};
2832
2833
2834
2835
2836
2837
2838 DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
2839 if (copy_from_user(peerMACStr, wrqu->data.pointer + 9, 17))
2840 return -EFAULT;
2841
2842 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
2843 peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
2844
2845 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
2846
2847 phead = get_list_head(queue);
2848 plist = phead->next;
2849
2850 while (phead != plist) {
2851 pnetwork = container_of(plist, struct wlan_network, list);
2852 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
2853 u8 *wpsie;
2854 uint wpsie_len = 0;
2855
2856
2857
2858 wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12],
2859 pnetwork->network.IELength - 12,
2860 NULL, &wpsie_len);
2861 if (wpsie) {
2862 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len);
2863 if (dev_type_len) {
2864 u16 type = 0;
2865 __be16 be_tmp;
2866
2867 memcpy(&be_tmp, dev_type, 2);
2868 type = be16_to_cpu(be_tmp);
2869 sprintf(dev_type_str, "\n\nN =%.2d", type);
2870 blnMatch = 1;
2871 }
2872 }
2873 break;
2874 }
2875
2876 plist = plist->next;
2877 }
2878
2879 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
2880
2881 if (!blnMatch)
2882 sprintf(dev_type_str, "\n\nN = 00");
2883
2884 if (copy_to_user(wrqu->data.pointer, dev_type_str, 9 + 17)) {
2885 return -EFAULT;
2886 }
2887
2888 return ret;
2889}
2890
2891static int rtw_p2p_get_device_name(struct net_device *dev,
2892 struct iw_request_info *info,
2893 union iwreq_data *wrqu, char *extra)
2894{
2895 int ret = 0;
2896 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2897 u8 peerMAC[ETH_ALEN] = {0x00};
2898 int jj, kk;
2899 u8 peerMACStr[17] = {0x00};
2900 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2901 struct list_head *plist, *phead;
2902 struct __queue *queue = &pmlmepriv->scanned_queue;
2903 struct wlan_network *pnetwork = NULL;
2904 u8 blnMatch = 0;
2905 u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = {0x00};
2906 uint dev_len = 0;
2907 u8 dev_name_str[WPS_MAX_DEVICE_NAME_LEN + 5] = {0x00};
2908
2909
2910
2911
2912
2913
2914 DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
2915 if (copy_from_user(peerMACStr, wrqu->data.pointer + 5, 17))
2916 return -EFAULT;
2917
2918 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
2919 peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
2920
2921 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
2922
2923 phead = get_list_head(queue);
2924 plist = phead->next;
2925
2926 while (phead != plist) {
2927 pnetwork = container_of(plist, struct wlan_network, list);
2928 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
2929 u8 *wpsie;
2930 uint wpsie_len = 0;
2931
2932
2933 wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len);
2934 if (wpsie) {
2935 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
2936 if (dev_len) {
2937 sprintf(dev_name_str, "\n\nN =%s", dev_name);
2938 blnMatch = 1;
2939 }
2940 }
2941 break;
2942 }
2943
2944 plist = plist->next;
2945 }
2946
2947 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
2948
2949 if (!blnMatch)
2950 sprintf(dev_name_str, "\n\nN = 0000");
2951
2952 if (copy_to_user(wrqu->data.pointer, dev_name_str, 5 + ((dev_len > 17) ? dev_len : 17)))
2953 return -EFAULT;
2954 return ret;
2955}
2956
2957static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
2958 struct iw_request_info *info,
2959 union iwreq_data *wrqu, char *extra)
2960{
2961 int ret = 0;
2962 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2963 u8 peerMAC[ETH_ALEN] = {0x00};
2964 int jj, kk;
2965 u8 peerMACStr[17] = {0x00};
2966 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2967 struct list_head *plist, *phead;
2968 struct __queue *queue = &pmlmepriv->scanned_queue;
2969 struct wlan_network *pnetwork = NULL;
2970 u8 blnMatch = 0;
2971 u8 *p2pie;
2972 uint p2pielen = 0, attr_contentlen = 0;
2973 u8 attr_content[2] = {0x00};
2974
2975 u8 inv_proc_str[17 + 8] = {0x00};
2976
2977
2978
2979
2980
2981
2982 DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
2983 if (copy_from_user(peerMACStr, wrqu->data.pointer + 8, 17))
2984 return -EFAULT;
2985
2986 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
2987 peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
2988
2989 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
2990
2991 phead = get_list_head(queue);
2992 plist = phead->next;
2993
2994 while (phead != plist) {
2995 pnetwork = container_of(plist, struct wlan_network, list);
2996 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
2997
2998
2999
3000
3001 p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
3002 if (p2pie) {
3003 while (p2pie) {
3004 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen)) {
3005
3006 blnMatch = 1;
3007 break;
3008 }
3009
3010
3011 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
3012 }
3013 }
3014 }
3015 plist = plist->next;
3016 }
3017
3018 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
3019
3020 if (!blnMatch) {
3021 sprintf(inv_proc_str, "\nIP =-1");
3022 } else {
3023 if (attr_content[0] & 0x20)
3024 sprintf(inv_proc_str, "\nIP = 1");
3025 else
3026 sprintf(inv_proc_str, "\nIP = 0");
3027 }
3028 if (copy_to_user(wrqu->data.pointer, inv_proc_str, 8 + 17))
3029 return -EFAULT;
3030 return ret;
3031}
3032
3033static int rtw_p2p_connect(struct net_device *dev,
3034 struct iw_request_info *info,
3035 union iwreq_data *wrqu, char *extra)
3036{
3037 int ret = 0;
3038 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3039 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3040 u8 peerMAC[ETH_ALEN] = {0x00};
3041 int jj, kk;
3042 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3043 struct list_head *plist, *phead;
3044 struct __queue *queue = &pmlmepriv->scanned_queue;
3045 struct wlan_network *pnetwork = NULL;
3046 uint uintPeerChannel = 0;
3047
3048
3049
3050
3051
3052
3053
3054
3055 DBG_88E("[%s] data = %s\n", __func__, extra);
3056
3057 if (pwdinfo->p2p_state == P2P_STATE_NONE) {
3058 DBG_88E("[%s] WiFi Direct is disable!\n", __func__);
3059 return ret;
3060 }
3061
3062 if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO)
3063 return -1;
3064
3065 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
3066 peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
3067
3068 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
3069
3070 phead = get_list_head(queue);
3071 plist = phead->next;
3072
3073 while (phead != plist) {
3074 pnetwork = container_of(plist, struct wlan_network, list);
3075 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
3076 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
3077 break;
3078 }
3079
3080 plist = plist->next;
3081 }
3082
3083 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
3084
3085 if (uintPeerChannel) {
3086 memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info));
3087 memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
3088
3089 pwdinfo->nego_req_info.peer_channel_num[0] = uintPeerChannel;
3090 memcpy(pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN);
3091 pwdinfo->nego_req_info.benable = true;
3092
3093 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
3094 if (rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK) {
3095
3096 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
3097 }
3098
3099 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
3100 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
3101
3102 DBG_88E("[%s] Start PreTx Procedure!\n", __func__);
3103 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
3104 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT);
3105 } else {
3106 DBG_88E("[%s] Not Found in Scanning Queue~\n", __func__);
3107 ret = -1;
3108 }
3109 return ret;
3110}
3111
3112static int rtw_p2p_invite_req(struct net_device *dev,
3113 struct iw_request_info *info,
3114 union iwreq_data *wrqu, char *extra)
3115{
3116 int ret = 0;
3117 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3118 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3119 int jj, kk;
3120 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3121 struct list_head *plist, *phead;
3122 struct __queue *queue = &pmlmepriv->scanned_queue;
3123 struct wlan_network *pnetwork = NULL;
3124 uint uintPeerChannel = 0;
3125 u8 attr_content[50] = {0x00};
3126 u8 *p2pie;
3127 uint p2pielen = 0, attr_contentlen = 0;
3128 struct tx_invite_req_info *pinvite_req_info = &pwdinfo->invitereq_info;
3129
3130
3131
3132
3133
3134
3135
3136 DBG_88E("[%s] data = %s\n", __func__, extra);
3137
3138 if (wrqu->data.length <= 37) {
3139 DBG_88E("[%s] Wrong format!\n", __func__);
3140 return ret;
3141 }
3142
3143 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
3144 DBG_88E("[%s] WiFi Direct is disable!\n", __func__);
3145 return ret;
3146 } else {
3147
3148 pinvite_req_info->benable = false;
3149 memset(pinvite_req_info->go_bssid, 0x00, ETH_ALEN);
3150 memset(pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN);
3151 pinvite_req_info->ssidlen = 0x00;
3152 pinvite_req_info->operating_ch = pwdinfo->operating_channel;
3153 memset(pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN);
3154 pinvite_req_info->token = 3;
3155 }
3156
3157 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
3158 pinvite_req_info->peer_macaddr[jj] = key_2char2num(extra[kk], extra[kk + 1]);
3159
3160 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
3161
3162 phead = get_list_head(queue);
3163 plist = phead->next;
3164
3165 while (phead != plist) {
3166 pnetwork = container_of(plist, struct wlan_network, list);
3167
3168
3169
3170
3171
3172 p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
3173 if (p2pie) {
3174
3175
3176
3177 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
3178
3179 if (!memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
3180 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
3181 break;
3182 }
3183 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
3184
3185 if (!memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
3186 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
3187 break;
3188 }
3189 }
3190 }
3191 plist = plist->next;
3192 }
3193
3194 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
3195
3196 if (uintPeerChannel) {
3197
3198 for (jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3)
3199 pinvite_req_info->go_bssid[jj] = key_2char2num(extra[kk], extra[kk + 1]);
3200
3201
3202 pinvite_req_info->ssidlen = wrqu->data.length - 36;
3203 memcpy(pinvite_req_info->go_ssid, &extra[36], (u32)pinvite_req_info->ssidlen);
3204 pinvite_req_info->benable = true;
3205 pinvite_req_info->peer_ch = uintPeerChannel;
3206
3207 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
3208 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ);
3209
3210 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
3211
3212 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
3213
3214 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT);
3215 } else {
3216 DBG_88E("[%s] NOT Found in the Scanning Queue!\n", __func__);
3217 }
3218 return ret;
3219}
3220
3221static int rtw_p2p_set_persistent(struct net_device *dev,
3222 struct iw_request_info *info,
3223 union iwreq_data *wrqu, char *extra)
3224{
3225 int ret = 0;
3226 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3227 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3228
3229
3230
3231
3232
3233 DBG_88E("[%s] data = %s\n", __func__, extra);
3234
3235 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
3236 DBG_88E("[%s] WiFi Direct is disable!\n", __func__);
3237 return ret;
3238 } else {
3239 if (extra[0] == '0')
3240 pwdinfo->persistent_supported = false;
3241 else if (extra[0] == '1')
3242 pwdinfo->persistent_supported = true;
3243 else
3244 pwdinfo->persistent_supported = false;
3245 }
3246 pr_info("[%s] persistent_supported = %d\n", __func__, pwdinfo->persistent_supported);
3247 return ret;
3248}
3249
3250static int rtw_p2p_prov_disc(struct net_device *dev,
3251 struct iw_request_info *info,
3252 union iwreq_data *wrqu, char *extra)
3253{
3254 int ret = 0;
3255 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3256 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3257 u8 peerMAC[ETH_ALEN] = {0x00};
3258 int jj, kk;
3259 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3260 struct list_head *plist, *phead;
3261 struct __queue *queue = &pmlmepriv->scanned_queue;
3262 struct wlan_network *pnetwork = NULL;
3263 uint uintPeerChannel = 0;
3264 u8 attr_content[100] = {0x00};
3265 u8 *p2pie;
3266 uint p2pielen = 0, attr_contentlen = 0;
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276 DBG_88E("[%s] data = %s\n", __func__, extra);
3277
3278 if (pwdinfo->p2p_state == P2P_STATE_NONE) {
3279 DBG_88E("[%s] WiFi Direct is disable!\n", __func__);
3280 return ret;
3281 } else {
3282
3283 memset(pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN);
3284 memset(pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN);
3285 memset(&pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof(struct ndis_802_11_ssid));
3286 pwdinfo->tx_prov_disc_info.peer_channel_num[0] = 0;
3287 pwdinfo->tx_prov_disc_info.peer_channel_num[1] = 0;
3288 pwdinfo->tx_prov_disc_info.benable = false;
3289 }
3290
3291 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
3292 peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
3293
3294 if (!memcmp(&extra[18], "display", 7)) {
3295 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
3296 } else if (!memcmp(&extra[18], "keypad", 7)) {
3297 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
3298 } else if (!memcmp(&extra[18], "pbc", 3)) {
3299 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
3300 } else if (!memcmp(&extra[18], "label", 5)) {
3301 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
3302 } else {
3303 DBG_88E("[%s] Unknown WPS config methodn", __func__);
3304 return ret;
3305 }
3306
3307 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
3308
3309 phead = get_list_head(queue);
3310 plist = phead->next;
3311
3312 while (phead != plist) {
3313 if (uintPeerChannel != 0)
3314 break;
3315
3316 pnetwork = container_of(plist, struct wlan_network, list);
3317
3318
3319
3320
3321
3322 p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
3323 if (p2pie) {
3324 while (p2pie) {
3325
3326
3327
3328 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
3329
3330 if (!memcmp(attr_content, peerMAC, ETH_ALEN)) {
3331 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
3332 break;
3333 }
3334 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
3335
3336 if (!memcmp(attr_content, peerMAC, ETH_ALEN)) {
3337 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
3338 break;
3339 }
3340 }
3341
3342
3343 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
3344 }
3345 }
3346
3347 plist = plist->next;
3348 }
3349
3350 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
3351
3352 if (uintPeerChannel) {
3353 DBG_88E("[%s] peer channel: %d!\n", __func__, uintPeerChannel);
3354 memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN);
3355 memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN);
3356 pwdinfo->tx_prov_disc_info.peer_channel_num[0] = (u16)uintPeerChannel;
3357 pwdinfo->tx_prov_disc_info.benable = true;
3358 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
3359 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ);
3360
3361 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
3362 memcpy(&pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof(struct ndis_802_11_ssid));
3363 } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
3364 memcpy(pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN);
3365 pwdinfo->tx_prov_disc_info.ssid.SsidLength = P2P_WILDCARD_SSID_LEN;
3366 }
3367
3368 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
3369
3370 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
3371
3372 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
3373 } else {
3374 DBG_88E("[%s] NOT Found in the Scanning Queue!\n", __func__);
3375 }
3376 return ret;
3377}
3378
3379
3380
3381
3382static int rtw_p2p_got_wpsinfo(struct net_device *dev,
3383 struct iw_request_info *info,
3384 union iwreq_data *wrqu, char *extra)
3385{
3386 int ret = 0;
3387 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3388 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3389
3390 DBG_88E("[%s] data = %s\n", __func__, extra);
3391
3392
3393
3394
3395
3396
3397 if (*extra == '0')
3398 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
3399 else if (*extra == '1')
3400 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN;
3401 else if (*extra == '2')
3402 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN;
3403 else if (*extra == '3')
3404 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC;
3405 else
3406 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
3407 return ret;
3408}
3409
3410static int rtw_p2p_set(struct net_device *dev,
3411 struct iw_request_info *info,
3412 union iwreq_data *wrqu, char *extra)
3413{
3414 int ret = 0;
3415
3416 DBG_88E("[%s] extra = %s\n", __func__, extra);
3417 if (!memcmp(extra, "enable =", 7)) {
3418 rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]);
3419 } else if (!memcmp(extra, "setDN =", 6)) {
3420 wrqu->data.length -= 6;
3421 rtw_p2p_setDN(dev, info, wrqu, &extra[6]);
3422 } else if (!memcmp(extra, "profilefound =", 13)) {
3423 wrqu->data.length -= 13;
3424 rtw_p2p_profilefound(dev, info, wrqu, &extra[13]);
3425 } else if (!memcmp(extra, "prov_disc =", 10)) {
3426 wrqu->data.length -= 10;
3427 rtw_p2p_prov_disc(dev, info, wrqu, &extra[10]);
3428 } else if (!memcmp(extra, "nego =", 5)) {
3429 wrqu->data.length -= 5;
3430 rtw_p2p_connect(dev, info, wrqu, &extra[5]);
3431 } else if (!memcmp(extra, "intent =", 7)) {
3432
3433
3434
3435 wrqu->data.length -= 8;
3436 rtw_p2p_set_intent(dev, info, wrqu, &extra[7]);
3437 } else if (!memcmp(extra, "ssid =", 5)) {
3438 wrqu->data.length -= 5;
3439 rtw_p2p_set_go_nego_ssid(dev, info, wrqu, &extra[5]);
3440 } else if (!memcmp(extra, "got_wpsinfo =", 12)) {
3441 wrqu->data.length -= 12;
3442 rtw_p2p_got_wpsinfo(dev, info, wrqu, &extra[12]);
3443 } else if (!memcmp(extra, "listen_ch =", 10)) {
3444
3445
3446
3447 wrqu->data.length -= 11;
3448 rtw_p2p_set_listen_ch(dev, info, wrqu, &extra[10]);
3449 } else if (!memcmp(extra, "op_ch =", 6)) {
3450
3451
3452
3453 wrqu->data.length -= 7;
3454 rtw_p2p_set_op_ch(dev, info, wrqu, &extra[6]);
3455 } else if (!memcmp(extra, "invite =", 7)) {
3456 wrqu->data.length -= 8;
3457 rtw_p2p_invite_req(dev, info, wrqu, &extra[7]);
3458 } else if (!memcmp(extra, "persistent =", 11)) {
3459 wrqu->data.length -= 11;
3460 rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]);
3461 }
3462
3463 return ret;
3464}
3465
3466static int rtw_p2p_get(struct net_device *dev,
3467 struct iw_request_info *info,
3468 union iwreq_data *wrqu, char *extra)
3469{
3470 int ret = 0;
3471
3472 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3473
3474 if (padapter->bShowGetP2PState)
3475 DBG_88E("[%s] extra = %s\n", __func__, (char *)wrqu->data.pointer);
3476 if (!memcmp(wrqu->data.pointer, "status", 6)) {
3477 rtw_p2p_get_status(dev, info, wrqu, extra);
3478 } else if (!memcmp(wrqu->data.pointer, "role", 4)) {
3479 rtw_p2p_get_role(dev, info, wrqu, extra);
3480 } else if (!memcmp(wrqu->data.pointer, "peer_ifa", 8)) {
3481 rtw_p2p_get_peer_ifaddr(dev, info, wrqu, extra);
3482 } else if (!memcmp(wrqu->data.pointer, "req_cm", 6)) {
3483 rtw_p2p_get_req_cm(dev, info, wrqu, extra);
3484 } else if (!memcmp(wrqu->data.pointer, "peer_deva", 9)) {
3485
3486 rtw_p2p_get_peer_devaddr(dev, info, wrqu, extra);
3487 } else if (!memcmp(wrqu->data.pointer, "group_id", 8)) {
3488 rtw_p2p_get_groupid(dev, info, wrqu, extra);
3489 } else if (!memcmp(wrqu->data.pointer, "peer_deva_inv", 9)) {
3490
3491 rtw_p2p_get_peer_devaddr_by_invitation(dev, info, wrqu, extra);
3492 } else if (!memcmp(wrqu->data.pointer, "op_ch", 5)) {
3493 rtw_p2p_get_op_ch(dev, info, wrqu, extra);
3494 }
3495 return ret;
3496}
3497
3498static int rtw_p2p_get2(struct net_device *dev,
3499 struct iw_request_info *info,
3500 union iwreq_data *wrqu, char *extra)
3501{
3502 int ret = 0;
3503
3504 DBG_88E("[%s] extra = %s\n", __func__, (char *)wrqu->data.pointer);
3505 if (!memcmp(extra, "wpsCM =", 6)) {
3506 wrqu->data.length -= 6;
3507 rtw_p2p_get_wps_configmethod(dev, info, wrqu, &extra[6]);
3508 } else if (!memcmp(extra, "devN =", 5)) {
3509 wrqu->data.length -= 5;
3510 rtw_p2p_get_device_name(dev, info, wrqu, &extra[5]);
3511 } else if (!memcmp(extra, "dev_type =", 9)) {
3512 wrqu->data.length -= 9;
3513 rtw_p2p_get_device_type(dev, info, wrqu, &extra[9]);
3514 } else if (!memcmp(extra, "go_devadd =", 10)) {
3515 wrqu->data.length -= 10;
3516 rtw_p2p_get_go_device_address(dev, info, wrqu, &extra[10]);
3517 } else if (!memcmp(extra, "InvProc =", 8)) {
3518 wrqu->data.length -= 8;
3519 rtw_p2p_get_invitation_procedure(dev, info, wrqu, &extra[8]);
3520 }
3521
3522 return ret;
3523}
3524
3525static int rtw_rereg_nd_name(struct net_device *dev,
3526 struct iw_request_info *info,
3527 union iwreq_data *wrqu, char *extra)
3528{
3529 int ret = 0;
3530 struct adapter *padapter = rtw_netdev_priv(dev);
3531 struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;
3532 char new_ifname[IFNAMSIZ];
3533
3534 if (rereg_priv->old_ifname[0] == 0) {
3535 char *reg_ifname;
3536 reg_ifname = padapter->registrypriv.if2name;
3537
3538 strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);
3539 rereg_priv->old_ifname[IFNAMSIZ - 1] = 0;
3540 }
3541
3542 if (wrqu->data.length > IFNAMSIZ)
3543 return -EFAULT;
3544
3545 if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ))
3546 return -EFAULT;
3547
3548 if (0 == strcmp(rereg_priv->old_ifname, new_ifname))
3549 return ret;
3550
3551 DBG_88E("%s new_ifname:%s\n", __func__, new_ifname);
3552 ret = rtw_change_ifname(padapter, new_ifname);
3553 if (0 != ret)
3554 goto exit;
3555
3556 if (!memcmp(rereg_priv->old_ifname, "disable%d", 9)) {
3557 padapter->ledpriv.bRegUseLed = rereg_priv->old_bRegUseLed;
3558 rtl8188eu_InitSwLeds(padapter);
3559 rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode);
3560 }
3561
3562 strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
3563 rereg_priv->old_ifname[IFNAMSIZ - 1] = 0;
3564
3565 if (!memcmp(new_ifname, "disable%d", 9)) {
3566 DBG_88E("%s disable\n", __func__);
3567
3568 rtw_free_network_queue(padapter, true);
3569
3570
3571 rtw_led_control(padapter, LED_CTL_POWER_OFF);
3572 rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed;
3573 padapter->ledpriv.bRegUseLed = false;
3574 rtl8188eu_DeInitSwLeds(padapter);
3575
3576
3577 rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv);
3578 rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL);
3579 }
3580exit:
3581 return ret;
3582}
3583
3584static void mac_reg_dump(struct adapter *padapter)
3585{
3586 int i, j = 1;
3587 pr_info("\n ======= MAC REG =======\n");
3588 for (i = 0x0; i < 0x300; i += 4) {
3589 if (j % 4 == 1)
3590 pr_info("0x%02x", i);
3591 pr_info(" 0x%08x ", rtw_read32(padapter, i));
3592 if ((j++) % 4 == 0)
3593 pr_info("\n");
3594 }
3595 for (i = 0x400; i < 0x800; i += 4) {
3596 if (j % 4 == 1)
3597 pr_info("0x%02x", i);
3598 pr_info(" 0x%08x ", rtw_read32(padapter, i));
3599 if ((j++) % 4 == 0)
3600 pr_info("\n");
3601 }
3602}
3603
3604static void bb_reg_dump(struct adapter *padapter)
3605{
3606 int i, j = 1;
3607 pr_info("\n ======= BB REG =======\n");
3608 for (i = 0x800; i < 0x1000; i += 4) {
3609 if (j % 4 == 1)
3610 pr_info("0x%02x", i);
3611
3612 pr_info(" 0x%08x ", rtw_read32(padapter, i));
3613 if ((j++) % 4 == 0)
3614 pr_info("\n");
3615 }
3616}
3617
3618static void rf_reg_dump(struct adapter *padapter)
3619{
3620 int i, j = 1, path;
3621 u32 value;
3622 u8 rf_type, path_nums = 0;
3623 GetHwReg8188EU(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
3624
3625 pr_info("\n ======= RF REG =======\n");
3626 if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type))
3627 path_nums = 1;
3628 else
3629 path_nums = 2;
3630
3631 for (path = 0; path < path_nums; path++) {
3632 pr_info("\nRF_Path(%x)\n", path);
3633 for (i = 0; i < 0x100; i++) {
3634 value = rtl8188e_PHY_QueryRFReg(padapter, path, i, 0xffffffff);
3635 if (j % 4 == 1)
3636 pr_info("0x%02x ", i);
3637 pr_info(" 0x%08x ", value);
3638 if ((j++) % 4 == 0)
3639 pr_info("\n");
3640 }
3641 }
3642}
3643
3644static int rtw_dbg_port(struct net_device *dev,
3645 struct iw_request_info *info,
3646 union iwreq_data *wrqu, char *extra)
3647{
3648 int ret = 0;
3649 u8 major_cmd, minor_cmd;
3650 u16 arg;
3651 s32 extra_arg;
3652 u32 *pdata, val32;
3653 struct sta_info *psta;
3654 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3655 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3656 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3657 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3658 struct security_priv *psecuritypriv = &padapter->securitypriv;
3659 struct wlan_network *cur_network = &pmlmepriv->cur_network;
3660 struct sta_priv *pstapriv = &padapter->stapriv;
3661
3662 pdata = (u32 *)&wrqu->data;
3663
3664 val32 = *pdata;
3665 arg = (u16)(val32 & 0x0000ffff);
3666 major_cmd = (u8)(val32 >> 24);
3667 minor_cmd = (u8)((val32 >> 16) & 0x00ff);
3668
3669 extra_arg = *(pdata + 1);
3670
3671 switch (major_cmd) {
3672 case 0x70:
3673 switch (minor_cmd) {
3674 case 1:
3675 DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
3676 break;
3677 case 2:
3678 DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
3679 break;
3680 case 4:
3681 DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
3682 break;
3683 }
3684 break;
3685 case 0x71:
3686 switch (minor_cmd) {
3687 case 1:
3688 rtw_write8(padapter, arg, extra_arg);
3689 DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
3690 break;
3691 case 2:
3692 rtw_write16(padapter, arg, extra_arg);
3693 DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
3694 break;
3695 case 4:
3696 rtw_write32(padapter, arg, extra_arg);
3697 DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
3698 break;
3699 }
3700 break;
3701 case 0x72:
3702 DBG_88E("read_bbreg(0x%x) = 0x%x\n", arg, rtl8188e_PHY_QueryBBReg(padapter, arg, 0xffffffff));
3703 break;
3704 case 0x73:
3705 rtl8188e_PHY_SetBBReg(padapter, arg, 0xffffffff, extra_arg);
3706 DBG_88E("write_bbreg(0x%x) = 0x%x\n", arg, rtl8188e_PHY_QueryBBReg(padapter, arg, 0xffffffff));
3707 break;
3708 case 0x74:
3709 DBG_88E("read RF_reg path(0x%02x), offset(0x%x), value(0x%08x)\n", minor_cmd, arg, rtl8188e_PHY_QueryRFReg(padapter, minor_cmd, arg, 0xffffffff));
3710 break;
3711 case 0x75:
3712 rtl8188e_PHY_SetRFReg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
3713 DBG_88E("write RF_reg path(0x%02x), offset(0x%x), value(0x%08x)\n", minor_cmd, arg, rtl8188e_PHY_QueryRFReg(padapter, minor_cmd, arg, 0xffffffff));
3714 break;
3715
3716 case 0x76:
3717 switch (minor_cmd) {
3718 case 0x00:
3719 padapter->recvpriv.is_signal_dbg = 0;
3720 break;
3721 case 0x01:
3722 padapter->recvpriv.is_signal_dbg = 1;
3723 extra_arg = extra_arg > 100 ? 100 : extra_arg;
3724 extra_arg = extra_arg < 0 ? 0 : extra_arg;
3725 padapter->recvpriv.signal_strength_dbg = extra_arg;
3726 break;
3727 }
3728 break;
3729 case 0x78:
3730 switch (minor_cmd) {
3731 case 0x04:
3732 {
3733 struct xmit_frame *xmit_frame;
3734
3735 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
3736 if (!xmit_frame) {
3737 ret = -ENOMEM;
3738 break;
3739 }
3740
3741 if (rtl8188e_IOL_exec_cmds_sync(padapter, xmit_frame, 500, 0) != _SUCCESS)
3742 ret = -EPERM;
3743 }
3744 break;
3745 case 0x05:
3746 {
3747 u16 reg = 0x4c;
3748 u32 blink_num = 50;
3749 u32 blink_delay_ms = 200;
3750 int i;
3751 struct xmit_frame *xmit_frame;
3752
3753 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
3754 if (!xmit_frame) {
3755 ret = -ENOMEM;
3756 break;
3757 }
3758
3759 for (i = 0; i < blink_num; i++) {
3760 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00, 0xff);
3761 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
3762 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08, 0xff);
3763 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
3764 }
3765 if (rtl8188e_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms * blink_num * 2) + 200, 0) != _SUCCESS)
3766 ret = -EPERM;
3767 }
3768 break;
3769
3770 case 0x06:
3771 {
3772 u16 reg = arg;
3773 u16 start_value = 0;
3774 u32 write_num = extra_arg;
3775 int i;
3776 u8 final;
3777 struct xmit_frame *xmit_frame;
3778
3779 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
3780 if (!xmit_frame) {
3781 ret = -ENOMEM;
3782 break;
3783 }
3784
3785 for (i = 0; i < write_num; i++)
3786 rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value, 0xFF);
3787 if (rtl8188e_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0) != _SUCCESS)
3788 ret = -EPERM;
3789
3790 final = rtw_read8(padapter, reg);
3791 if (start_value + write_num - 1 == final)
3792 DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
3793 else
3794 DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
3795 }
3796 break;
3797
3798 case 0x07:
3799 {
3800 u16 reg = arg;
3801 u16 start_value = 200;
3802 u32 write_num = extra_arg;
3803
3804 int i;
3805 u16 final;
3806 struct xmit_frame *xmit_frame;
3807
3808 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
3809 if (!xmit_frame) {
3810 ret = -ENOMEM;
3811 break;
3812 }
3813
3814 for (i = 0; i < write_num; i++)
3815 rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value, 0xFFFF);
3816 if (rtl8188e_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0) != _SUCCESS)
3817 ret = -EPERM;
3818
3819 final = rtw_read16(padapter, reg);
3820 if (start_value + write_num - 1 == final)
3821 DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
3822 else
3823 DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
3824 }
3825 break;
3826 case 0x08:
3827 {
3828 u16 reg = arg;
3829 u32 start_value = 0x110000c7;
3830 u32 write_num = extra_arg;
3831
3832 int i;
3833 u32 final;
3834 struct xmit_frame *xmit_frame;
3835
3836 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
3837 if (!xmit_frame) {
3838 ret = -ENOMEM;
3839 break;
3840 }
3841
3842 for (i = 0; i < write_num; i++)
3843 rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value, 0xFFFFFFFF);
3844 if (rtl8188e_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0) != _SUCCESS)
3845 ret = -EPERM;
3846
3847 final = rtw_read32(padapter, reg);
3848 if (start_value + write_num - 1 == final)
3849 DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n",
3850 reg, write_num, start_value, final);
3851 else
3852 DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n",
3853 reg, write_num, start_value, final);
3854 }
3855 break;
3856 }
3857 break;
3858 case 0x79:
3859 {
3860
3861
3862
3863
3864 u8 value = extra_arg & 0x0f;
3865 u8 sign = minor_cmd;
3866 u16 write_value = 0;
3867
3868 DBG_88E("%s set RESP_TXAGC to %s %u\n", __func__, sign ? "minus" : "plus", value);
3869
3870 if (sign)
3871 value = value | 0x10;
3872
3873 write_value = value | (value << 5);
3874 rtw_write16(padapter, 0x6d9, write_value);
3875 }
3876 break;
3877 case 0x7a:
3878 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
3879 , WLAN_REASON_EXPIRATION_CHK);
3880 break;
3881 case 0x7F:
3882 switch (minor_cmd) {
3883 case 0x0:
3884 DBG_88E("fwstate = 0x%x\n", get_fwstate(pmlmepriv));
3885 break;
3886 case 0x01:
3887 DBG_88E("auth_alg = 0x%x, enc_alg = 0x%x, auth_type = 0x%x, enc_type = 0x%x\n",
3888 psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
3889 psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
3890 break;
3891 case 0x02:
3892 DBG_88E("pmlmeinfo->state = 0x%x\n", pmlmeinfo->state);
3893 break;
3894 case 0x03:
3895 DBG_88E("qos_option =%d\n", pmlmepriv->qospriv.qos_option);
3896 DBG_88E("ht_option =%d\n", pmlmepriv->htpriv.ht_option);
3897 break;
3898 case 0x04:
3899 DBG_88E("cur_ch =%d\n", pmlmeext->cur_channel);
3900 DBG_88E("cur_bw =%d\n", pmlmeext->cur_bwmode);
3901 DBG_88E("cur_ch_off =%d\n", pmlmeext->cur_ch_offset);
3902 break;
3903 case 0x05:
3904 psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
3905 if (psta) {
3906 int i;
3907 struct recv_reorder_ctrl *preorder_ctrl;
3908
3909 DBG_88E("SSID =%s\n", cur_network->network.Ssid.Ssid);
3910 DBG_88E("sta's macaddr: %pM\n", psta->hwaddr);
3911 DBG_88E("cur_channel =%d, cur_bwmode =%d, cur_ch_offset =%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
3912 DBG_88E("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self);
3913 DBG_88E("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
3914 DBG_88E("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
3915 DBG_88E("bwmode =%d, ch_offset =%d, sgi =%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
3916 DBG_88E("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
3917 DBG_88E("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
3918 for (i = 0; i < 16; i++) {
3919 preorder_ctrl = &psta->recvreorder_ctrl[i];
3920 if (preorder_ctrl->enable)
3921 DBG_88E("tid =%d, indicate_seq =%d\n", i, preorder_ctrl->indicate_seq);
3922 }
3923 } else {
3924 DBG_88E("can't get sta's macaddr, cur_network's macaddr:%pM\n", (cur_network->network.MacAddress));
3925 }
3926 break;
3927 case 0x06:
3928 {
3929 u32 ODMFlag;
3930 GetHwReg8188EU(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
3931 DBG_88E("(B)DMFlag = 0x%x, arg = 0x%x\n", ODMFlag, arg);
3932 ODMFlag = (u32)(0x0f & arg);
3933 DBG_88E("(A)DMFlag = 0x%x\n", ODMFlag);
3934 SetHwReg8188EU(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
3935 }
3936 break;
3937 case 0x07:
3938 DBG_88E("bSurpriseRemoved =%d, bDriverStopped =%d\n",
3939 padapter->bSurpriseRemoved, padapter->bDriverStopped);
3940 break;
3941 case 0x08:
3942 {
3943 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3944 struct recv_priv *precvpriv = &padapter->recvpriv;
3945
3946 DBG_88E("free_xmitbuf_cnt =%d, free_xmitframe_cnt =%d, free_xmit_extbuf_cnt =%d\n",
3947 pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmit_extbuf_cnt);
3948 DBG_88E("rx_urb_pending_cn =%d\n", precvpriv->rx_pending_cnt);
3949 }
3950 break;
3951 case 0x09:
3952 {
3953 int i, j;
3954 struct list_head *plist, *phead;
3955 struct recv_reorder_ctrl *preorder_ctrl;
3956
3957 DBG_88E("sta_dz_bitmap = 0x%x, tim_bitmap = 0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
3958 spin_lock_bh(&pstapriv->sta_hash_lock);
3959
3960 for (i = 0; i < NUM_STA; i++) {
3961 phead = &pstapriv->sta_hash[i];
3962 plist = phead->next;
3963
3964 while (phead != plist) {
3965 psta = container_of(plist, struct sta_info, hash_list);
3966
3967 plist = plist->next;
3968
3969 if (extra_arg == psta->aid) {
3970 DBG_88E("sta's macaddr:%pM\n", (psta->hwaddr));
3971 DBG_88E("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self);
3972 DBG_88E("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
3973 DBG_88E("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
3974 DBG_88E("bwmode =%d, ch_offset =%d, sgi =%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
3975 DBG_88E("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
3976 DBG_88E("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
3977
3978 DBG_88E("capability = 0x%x\n", psta->capability);
3979 DBG_88E("flags = 0x%x\n", psta->flags);
3980 DBG_88E("wpa_psk = 0x%x\n", psta->wpa_psk);
3981 DBG_88E("wpa2_group_cipher = 0x%x\n", psta->wpa2_group_cipher);
3982 DBG_88E("wpa2_pairwise_cipher = 0x%x\n", psta->wpa2_pairwise_cipher);
3983 DBG_88E("qos_info = 0x%x\n", psta->qos_info);
3984 DBG_88E("dot118021XPrivacy = 0x%x\n", psta->dot118021XPrivacy);
3985
3986 for (j = 0; j < 16; j++) {
3987 preorder_ctrl = &psta->recvreorder_ctrl[j];
3988 if (preorder_ctrl->enable)
3989 DBG_88E("tid =%d, indicate_seq =%d\n", j, preorder_ctrl->indicate_seq);
3990 }
3991 }
3992 }
3993 }
3994 spin_unlock_bh(&pstapriv->sta_hash_lock);
3995 }
3996 break;
3997 case 0x0c:
3998 if (arg == 0) {
3999 DBG_88E("dump rx packet (%d)\n", extra_arg);
4000 SetHalDefVar8188EUsb(padapter, HAL_DEF_DBG_DUMP_RXPKT, &extra_arg);
4001 } else if (arg == 1) {
4002 DBG_88E("dump tx packet (%d)\n", extra_arg);
4003 SetHalDefVar8188EUsb(padapter, HAL_DEF_DBG_DUMP_TXPKT, &extra_arg);
4004 }
4005 break;
4006 case 0x15:
4007 {
4008 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
4009 DBG_88E("==>silent resete cnts:%d\n", pwrpriv->ips_enter_cnts);
4010 }
4011 break;
4012 case 0x10:
4013 DBG_88E("rtw driver version =%s\n", DRIVERVERSION);
4014 break;
4015 case 0x11:
4016 DBG_88E("turn %s Rx RSSI display function\n", (extra_arg == 1) ? "on" : "off");
4017 padapter->bRxRSSIDisplay = extra_arg;
4018 break;
4019 case 0x12:
4020 {
4021 struct registry_priv *pregpriv = &padapter->registrypriv;
4022
4023
4024 if (extra_arg == 0 ||
4025 extra_arg == 1 ||
4026 extra_arg == 2 ||
4027 extra_arg == 3) {
4028 pregpriv->rx_stbc = extra_arg;
4029 DBG_88E("set rx_stbc =%d\n", pregpriv->rx_stbc);
4030 } else {
4031 DBG_88E("get rx_stbc =%d\n", pregpriv->rx_stbc);
4032 }
4033 }
4034 break;
4035 case 0x13:
4036 {
4037 struct registry_priv *pregpriv = &padapter->registrypriv;
4038
4039 if (extra_arg >= 0 && extra_arg < 3) {
4040 pregpriv->ampdu_enable = extra_arg;
4041 DBG_88E("set ampdu_enable =%d\n", pregpriv->ampdu_enable);
4042 } else {
4043 DBG_88E("get ampdu_enable =%d\n", pregpriv->ampdu_enable);
4044 }
4045 }
4046 break;
4047 case 0x14:
4048 {
4049 struct registry_priv *pregpriv = &padapter->registrypriv;
4050 DBG_88E("get wifi_spec =%d\n", pregpriv->wifi_spec);
4051 }
4052 break;
4053 case 0x23:
4054 DBG_88E("turn %s the bNotifyChannelChange Variable\n", (extra_arg == 1) ? "on" : "off");
4055 padapter->bNotifyChannelChange = extra_arg;
4056 break;
4057 case 0x24:
4058 DBG_88E("turn %s the bShowGetP2PState Variable\n", (extra_arg == 1) ? "on" : "off");
4059 padapter->bShowGetP2PState = extra_arg;
4060 break;
4061 case 0xaa:
4062 if (extra_arg > 0x13)
4063 extra_arg = 0xFF;
4064 DBG_88E("chang data rate to :0x%02x\n", extra_arg);
4065 padapter->fix_rate = extra_arg;
4066 break;
4067 case 0xdd:
4068 if (extra_arg == 0)
4069 mac_reg_dump(padapter);
4070 else if (extra_arg == 1)
4071 bb_reg_dump(padapter);
4072 else if (extra_arg == 2)
4073 rf_reg_dump(padapter);
4074 break;
4075 case 0xee:
4076 {
4077 u32 odm_flag;
4078
4079 if (0xf == extra_arg) {
4080 GetHalDefVar8188EUsb(padapter, HAL_DEF_DBG_DM_FUNC, &odm_flag);
4081 DBG_88E(" === DMFlag(0x%08x) ===\n", odm_flag);
4082 DBG_88E("extra_arg = 0 - disable all dynamic func\n");
4083 DBG_88E("extra_arg = 1 - disable DIG- BIT(0)\n");
4084 DBG_88E("extra_arg = 2 - disable High power - BIT(1)\n");
4085 DBG_88E("extra_arg = 3 - disable tx power tracking - BIT(2)\n");
4086 DBG_88E("extra_arg = 4 - disable BT coexistence - BIT(3)\n");
4087 DBG_88E("extra_arg = 5 - disable antenna diversity - BIT(4)\n");
4088 DBG_88E("extra_arg = 6 - enable all dynamic func\n");
4089 } else {
4090
4091
4092
4093
4094
4095 SetHalDefVar8188EUsb(padapter, HAL_DEF_DBG_DM_FUNC, &extra_arg);
4096 GetHalDefVar8188EUsb(padapter, HAL_DEF_DBG_DM_FUNC, &odm_flag);
4097 DBG_88E(" === DMFlag(0x%08x) ===\n", odm_flag);
4098 }
4099 }
4100 break;
4101
4102 case 0xfd:
4103 rtw_write8(padapter, 0xc50, arg);
4104 DBG_88E("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
4105 rtw_write8(padapter, 0xc58, arg);
4106 DBG_88E("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
4107 break;
4108 case 0xfe:
4109 DBG_88E("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
4110 DBG_88E("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
4111 break;
4112 case 0xff:
4113 DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
4114 DBG_88E("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608));
4115 DBG_88E("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280));
4116 DBG_88E("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284));
4117 DBG_88E("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288));
4118
4119 DBG_88E("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664));
4120
4121 DBG_88E("\n");
4122
4123 DBG_88E("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430));
4124 DBG_88E("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438));
4125
4126 DBG_88E("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440));
4127
4128 DBG_88E("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458));
4129
4130 DBG_88E("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484));
4131 DBG_88E("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488));
4132
4133 DBG_88E("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444));
4134 DBG_88E("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448));
4135 DBG_88E("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c));
4136 DBG_88E("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450));
4137 break;
4138 }
4139 break;
4140 default:
4141 DBG_88E("error dbg cmd!\n");
4142 break;
4143 }
4144 return ret;
4145}
4146
4147static int rtw_wx_set_priv(struct net_device *dev,
4148 struct iw_request_info *info,
4149 union iwreq_data *awrq,
4150 char *extra)
4151{
4152 int ret = 0;
4153 int len = 0;
4154 char *ext;
4155 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4156 struct iw_point *dwrq = (struct iw_point *)awrq;
4157
4158 if (dwrq->length == 0)
4159 return -EFAULT;
4160
4161 len = dwrq->length;
4162 ext = vmalloc(len);
4163 if (!ext)
4164 return -ENOMEM;
4165
4166 if (copy_from_user(ext, dwrq->pointer, len)) {
4167 vfree(ext);
4168 return -EFAULT;
4169 }
4170
4171
4172 if (dwrq->flags == 0x8766 && len > 8) {
4173 u32 cp_sz;
4174 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4175 u8 *probereq_wpsie = ext;
4176 int probereq_wpsie_len = len;
4177 u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
4178
4179 if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
4180 (!memcmp(&probereq_wpsie[2], wps_oui, 4))) {
4181 cp_sz = probereq_wpsie_len > MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN : probereq_wpsie_len;
4182
4183 pmlmepriv->wps_probe_req_ie_len = 0;
4184 kfree(pmlmepriv->wps_probe_req_ie);
4185 pmlmepriv->wps_probe_req_ie = NULL;
4186
4187 pmlmepriv->wps_probe_req_ie = kmemdup(probereq_wpsie, cp_sz, GFP_KERNEL);
4188 if (!pmlmepriv->wps_probe_req_ie) {
4189 ret = -EINVAL;
4190 goto FREE_EXT;
4191 }
4192 pmlmepriv->wps_probe_req_ie_len = cp_sz;
4193 }
4194 goto FREE_EXT;
4195 }
4196
4197 if (len >= WEXT_CSCAN_HEADER_SIZE &&
4198 !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
4199 ret = rtw_wx_set_scan(dev, info, awrq, ext);
4200 goto FREE_EXT;
4201 }
4202
4203FREE_EXT:
4204
4205 vfree(ext);
4206
4207 return ret;
4208}
4209
4210static int rtw_pm_set(struct net_device *dev,
4211 struct iw_request_info *info,
4212 union iwreq_data *wrqu, char *extra)
4213{
4214 int ret = 0;
4215 unsigned mode = 0;
4216 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4217
4218 DBG_88E("[%s] extra = %s\n", __func__, extra);
4219
4220 if (!memcmp(extra, "lps =", 4)) {
4221 sscanf(extra + 4, "%u", &mode);
4222 ret = rtw_pm_set_lps(padapter, mode);
4223 } else if (!memcmp(extra, "ips =", 4)) {
4224 sscanf(extra + 4, "%u", &mode);
4225 ret = rtw_pm_set_ips(padapter, mode);
4226 } else {
4227 ret = -EINVAL;
4228 }
4229
4230 return ret;
4231}
4232
4233extern int wifirate2_ratetbl_inx(unsigned char rate);
4234
4235static int rtw_tdls(struct net_device *dev,
4236 struct iw_request_info *info,
4237 union iwreq_data *wrqu, char *extra)
4238{
4239 return 0;
4240}
4241
4242static int rtw_tdls_get(struct net_device *dev,
4243 struct iw_request_info *info,
4244 union iwreq_data *wrqu, char *extra)
4245{
4246 return 0;
4247}
4248
4249static int rtw_test(
4250 struct net_device *dev,
4251 struct iw_request_info *info,
4252 union iwreq_data *wrqu, char *extra)
4253{
4254 u32 len;
4255 u8 *pbuf, *pch;
4256 char *ptmp;
4257 u8 *delim = ",";
4258
4259 DBG_88E("+%s\n", __func__);
4260 len = wrqu->data.length;
4261
4262 pbuf = kzalloc(len, GFP_KERNEL);
4263 if (!pbuf) {
4264 DBG_88E("%s: no memory!\n", __func__);
4265 return -ENOMEM;
4266 }
4267
4268 if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
4269 kfree(pbuf);
4270 DBG_88E("%s: copy from user fail!\n", __func__);
4271 return -EFAULT;
4272 }
4273 DBG_88E("%s: string =\"%s\"\n", __func__, pbuf);
4274
4275 ptmp = (char *)pbuf;
4276 pch = strsep(&ptmp, delim);
4277 if (!pch || strlen(pch) == 0) {
4278 kfree(pbuf);
4279 DBG_88E("%s: parameter error(level 1)!\n", __func__);
4280 return -EFAULT;
4281 }
4282 kfree(pbuf);
4283 return 0;
4284}
4285
4286static iw_handler rtw_handlers[] = {
4287 IW_HANDLER(SIOCGIWNAME, rtw_wx_get_name),
4288 IW_HANDLER(SIOCSIWNWID, dummy),
4289 IW_HANDLER(SIOCGIWNWID, dummy),
4290 IW_HANDLER(SIOCGIWFREQ, rtw_wx_get_freq),
4291 IW_HANDLER(SIOCSIWMODE, rtw_wx_set_mode),
4292 IW_HANDLER(SIOCGIWMODE, rtw_wx_get_mode),
4293 IW_HANDLER(SIOCSIWSENS, dummy),
4294 IW_HANDLER(SIOCGIWSENS, rtw_wx_get_sens),
4295 IW_HANDLER(SIOCGIWRANGE, rtw_wx_get_range),
4296 IW_HANDLER(SIOCSIWPRIV, rtw_wx_set_priv),
4297 IW_HANDLER(SIOCSIWSPY, dummy),
4298 IW_HANDLER(SIOCGIWSPY, dummy),
4299 IW_HANDLER(SIOCSIWAP, rtw_wx_set_wap),
4300 IW_HANDLER(SIOCGIWAP, rtw_wx_get_wap),
4301 IW_HANDLER(SIOCSIWMLME, rtw_wx_set_mlme),
4302 IW_HANDLER(SIOCGIWAPLIST, dummy),
4303 IW_HANDLER(SIOCSIWSCAN, rtw_wx_set_scan),
4304 IW_HANDLER(SIOCGIWSCAN, rtw_wx_get_scan),
4305 IW_HANDLER(SIOCSIWESSID, rtw_wx_set_essid),
4306 IW_HANDLER(SIOCGIWESSID, rtw_wx_get_essid),
4307 IW_HANDLER(SIOCSIWNICKN, dummy),
4308 IW_HANDLER(SIOCGIWNICKN, rtw_wx_get_nick),
4309 IW_HANDLER(SIOCSIWRATE, rtw_wx_set_rate),
4310 IW_HANDLER(SIOCGIWRATE, rtw_wx_get_rate),
4311 IW_HANDLER(SIOCSIWRTS, rtw_wx_set_rts),
4312 IW_HANDLER(SIOCGIWRTS, rtw_wx_get_rts),
4313 IW_HANDLER(SIOCSIWFRAG, rtw_wx_set_frag),
4314 IW_HANDLER(SIOCGIWFRAG, rtw_wx_get_frag),
4315 IW_HANDLER(SIOCSIWTXPOW, dummy),
4316 IW_HANDLER(SIOCGIWTXPOW, dummy),
4317 IW_HANDLER(SIOCSIWRETRY, dummy),
4318 IW_HANDLER(SIOCGIWRETRY, rtw_wx_get_retry),
4319 IW_HANDLER(SIOCSIWENCODE, rtw_wx_set_enc),
4320 IW_HANDLER(SIOCGIWENCODE, rtw_wx_get_enc),
4321 IW_HANDLER(SIOCSIWPOWER, dummy),
4322 IW_HANDLER(SIOCGIWPOWER, rtw_wx_get_power),
4323 IW_HANDLER(SIOCSIWGENIE, rtw_wx_set_gen_ie),
4324 IW_HANDLER(SIOCSIWAUTH, rtw_wx_set_auth),
4325 IW_HANDLER(SIOCSIWENCODEEXT, rtw_wx_set_enc_ext),
4326 IW_HANDLER(SIOCSIWPMKSA, rtw_wx_set_pmkid),
4327};
4328
4329static const struct iw_priv_args rtw_private_args[] = {
4330 {
4331 SIOCIWFIRSTPRIV + 0x0,
4332 IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
4333 },
4334 {
4335 SIOCIWFIRSTPRIV + 0x1,
4336 IW_PRIV_TYPE_CHAR | 0x7FF,
4337 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
4338 },
4339 {
4340 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
4341 },
4342 {
4343 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
4344 },
4345 {
4346 SIOCIWFIRSTPRIV + 0x4,
4347 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
4348 },
4349 {
4350 SIOCIWFIRSTPRIV + 0x5,
4351 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
4352 },
4353 {
4354 SIOCIWFIRSTPRIV + 0x6,
4355 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
4356 },
4357 {
4358 SIOCIWFIRSTPRIV + 0x7,
4359 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
4360 },
4361 {
4362 SIOCIWFIRSTPRIV + 0x8,
4363 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
4364 },
4365 {
4366 SIOCIWFIRSTPRIV + 0x9,
4367 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
4368 },
4369
4370 {
4371 SIOCIWFIRSTPRIV + 0xA,
4372 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
4373 },
4374
4375 {
4376 SIOCIWFIRSTPRIV + 0xB,
4377 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
4378 },
4379 {
4380 SIOCIWFIRSTPRIV + 0xC,
4381 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
4382 },
4383 {
4384 SIOCIWFIRSTPRIV + 0xD,
4385 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
4386 },
4387 {
4388 SIOCIWFIRSTPRIV + 0x10,
4389 IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, 0, "p2p_set"
4390 },
4391 {
4392 SIOCIWFIRSTPRIV + 0x11,
4393 IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN, "p2p_get"
4394 },
4395 {
4396 SIOCIWFIRSTPRIV + 0x12,
4397 IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IFNAMSIZ, "p2p_get2"
4398 },
4399 {SIOCIWFIRSTPRIV + 0x13, IW_PRIV_TYPE_CHAR | 128, 0, "NULL"},
4400 {
4401 SIOCIWFIRSTPRIV + 0x14,
4402 IW_PRIV_TYPE_CHAR | 64, 0, "tdls"
4403 },
4404 {
4405 SIOCIWFIRSTPRIV + 0x15,
4406 IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN, "tdls_get"
4407 },
4408 {
4409 SIOCIWFIRSTPRIV + 0x16,
4410 IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
4411 },
4412
4413 {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ, 0, "rereg_nd_name"},
4414
4415 {SIOCIWFIRSTPRIV + 0x1D, IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
4416 },
4417
4418 {SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0, ""},
4419 {SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, ""},
4420};
4421
4422static iw_handler rtw_private_handler[] = {
4423rtw_wx_write32,
4424rtw_wx_read32,
4425rtw_drvext_hdl,
4426NULL,
4427
4428 rtw_get_ap_info,
4429
4430 rtw_set_pid,
4431 rtw_wps_start,
4432
4433 rtw_wx_get_sensitivity,
4434 rtw_wx_set_mtk_wps_probe_ie,
4435 rtw_wx_set_mtk_wps_ie,
4436
4437
4438 rtw_wx_set_channel_plan,
4439
4440 rtw_dbg_port,
4441 rtw_wx_write_rf,
4442 rtw_wx_read_rf,
4443 NULL,
4444 NULL,
4445
4446 rtw_p2p_set,
4447 rtw_p2p_get,
4448 rtw_p2p_get2,
4449
4450 NULL,
4451 rtw_tdls,
4452 rtw_tdls_get,
4453
4454 rtw_pm_set,
4455 rtw_wx_priv_null,
4456 rtw_rereg_nd_name,
4457 rtw_wx_priv_null,
4458
4459 NULL,
4460 NULL,
4461 NULL,
4462 rtw_test,
4463};
4464
4465static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
4466{
4467 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4468 struct iw_statistics *piwstats = &padapter->iwstats;
4469 int tmp_noise = 0;
4470 int tmp;
4471
4472 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
4473 piwstats->qual.qual = 0;
4474 piwstats->qual.level = 0;
4475 piwstats->qual.noise = 0;
4476 } else {
4477 tmp_noise = padapter->recvpriv.noise;
4478
4479 piwstats->qual.level = padapter->signal_strength;
4480 tmp = 219 + 3 * padapter->signal_strength;
4481 tmp = min(100, tmp);
4482 tmp = max(0, tmp);
4483 piwstats->qual.qual = tmp;
4484 piwstats->qual.noise = tmp_noise;
4485 }
4486 piwstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
4487 return &padapter->iwstats;
4488}
4489
4490struct iw_handler_def rtw_handlers_def = {
4491 .standard = rtw_handlers,
4492 .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
4493 .private = rtw_private_handler,
4494 .private_args = (struct iw_priv_args *)rtw_private_args,
4495 .num_private = sizeof(rtw_private_handler) / sizeof(iw_handler),
4496 .num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args),
4497 .get_wireless_stats = rtw_get_wireless_stats,
4498};
4499