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/rtw_mp_ioctl.h"
16#include "../include/usb_ops.h"
17#include "../include/rtl8188e_hal.h"
18
19#include "../include/rtw_mp.h"
20#include "../include/rtw_iol.h"
21
22#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30)
23
24#define SCAN_ITEM_SIZE 768
25#define MAX_CUSTOM_LEN 64
26#define RATE_COUNT 4
27
28
29#define WEXT_CSCAN_AMOUNT 9
30#define WEXT_CSCAN_BUF_LEN 360
31#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
32#define WEXT_CSCAN_HEADER_SIZE 12
33#define WEXT_CSCAN_SSID_SECTION 'S'
34#define WEXT_CSCAN_CHANNEL_SECTION 'C'
35#define WEXT_CSCAN_NPROBE_SECTION 'N'
36#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
37#define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
38#define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
39#define WEXT_CSCAN_TYPE_SECTION 'T'
40
41static struct mp_ioctl_handler mp_ioctl_hdl[] = {
42 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_start_test_hdl, OID_RT_PRO_START_TEST)
43 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_stop_test_hdl, OID_RT_PRO_STOP_TEST)
44
45 GEN_HANDLER(sizeof(struct rwreg_param), rtl8188eu_oid_rt_pro_read_register_hdl, OID_RT_PRO_READ_REGISTER)
46 GEN_HANDLER(sizeof(struct rwreg_param), rtl8188eu_oid_rt_pro_write_register_hdl, OID_RT_PRO_WRITE_REGISTER)
47 GEN_HANDLER(sizeof(struct bb_reg_param), rtl8188eu_oid_rt_pro_read_bb_reg_hdl, OID_RT_PRO_READ_BB_REG)
48 GEN_HANDLER(sizeof(struct bb_reg_param), rtl8188eu_oid_rt_pro_write_bb_reg_hdl, OID_RT_PRO_WRITE_BB_REG)
49 GEN_HANDLER(sizeof(struct rf_reg_param), rtl8188eu_oid_rt_pro_read_rf_reg_hdl, OID_RT_PRO_RF_READ_REGISTRY)
50 GEN_HANDLER(sizeof(struct rf_reg_param), rtl8188eu_oid_rt_pro_write_rf_reg_hdl, OID_RT_PRO_RF_WRITE_REGISTRY)
51
52 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_channel_direct_call_hdl, OID_RT_PRO_SET_CHANNEL_DIRECT_CALL)
53 GEN_HANDLER(sizeof(struct txpower_param), rtl8188eu_oid_rt_pro_set_tx_power_control_hdl, OID_RT_PRO_SET_TX_POWER_CONTROL)
54 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_data_rate_hdl, OID_RT_PRO_SET_DATA_RATE)
55 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_set_bandwidth_hdl, OID_RT_SET_BANDWIDTH)
56 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_antenna_bb_hdl, OID_RT_PRO_SET_ANTENNA_BB)
57
58 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_continuous_tx_hdl, OID_RT_PRO_SET_CONTINUOUS_TX)
59 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_single_carrier_tx_hdl, OID_RT_PRO_SET_SINGLE_CARRIER_TX)
60 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_carrier_suppression_tx_hdl, OID_RT_PRO_SET_CARRIER_SUPPRESSION_TX)
61 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_pro_set_single_tone_tx_hdl, OID_RT_PRO_SET_SINGLE_TONE_TX)
62
63 EXT_MP_IOCTL_HANDLER(0, xmit_packet, 0)
64
65 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_set_rx_packet_type_hdl, OID_RT_SET_RX_PACKET_TYPE)
66 GEN_HANDLER(0, rtl8188eu_oid_rt_reset_phy_rx_packet_count_hdl, OID_RT_RESET_PHY_RX_PACKET_COUNT)
67 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_phy_rx_packet_received_hdl, OID_RT_GET_PHY_RX_PACKET_RECEIVED)
68 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_phy_rx_packet_crc32_error_hdl, OID_RT_GET_PHY_RX_PACKET_CRC32_ERROR)
69
70 GEN_HANDLER(sizeof(struct eeprom_rw_param), NULL, 0)
71 GEN_HANDLER(sizeof(struct eeprom_rw_param), NULL, 0)
72 GEN_HANDLER(sizeof(struct efuse_access_struct), rtl8188eu_oid_rt_pro_efuse_hdl, OID_RT_PRO_EFUSE)
73 GEN_HANDLER(0, rtl8188eu_oid_rt_pro_efuse_map_hdl, OID_RT_PRO_EFUSE_MAP)
74 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_efuse_max_size_hdl, OID_RT_GET_EFUSE_MAX_SIZE)
75 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_efuse_current_size_hdl, OID_RT_GET_EFUSE_CURRENT_SIZE)
76
77 GEN_HANDLER(sizeof(u32), rtl8188eu_oid_rt_get_thermal_meter_hdl, OID_RT_PRO_GET_THERMAL_METER)
78 GEN_HANDLER(sizeof(u8), rtl8188eu_oid_rt_pro_set_power_tracking_hdl, OID_RT_PRO_SET_POWER_TRACKING)
79 GEN_HANDLER(sizeof(u8), rtl8188eu_oid_rt_set_power_down_hdl, OID_RT_SET_POWER_DOWN)
80 GEN_HANDLER(0, rtl8188eu_oid_rt_pro_trigger_gpio_hdl, 0)
81};
82
83static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
84 6000000, 9000000, 12000000, 18000000, 24000000, 36000000,
85 48000000, 54000000};
86
87void indicate_wx_scan_complete_event(struct adapter *padapter)
88{
89 union iwreq_data wrqu;
90
91 memset(&wrqu, 0, sizeof(union iwreq_data));
92 wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
93}
94
95void rtw_indicate_wx_assoc_event(struct adapter *padapter)
96{
97 union iwreq_data wrqu;
98 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
99
100 memset(&wrqu, 0, sizeof(union iwreq_data));
101
102 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
103
104 memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
105
106 DBG_88E_LEVEL(_drv_always_, "assoc success\n");
107 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
108}
109
110void rtw_indicate_wx_disassoc_event(struct adapter *padapter)
111{
112 union iwreq_data wrqu;
113
114 memset(&wrqu, 0, sizeof(union iwreq_data));
115
116 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
117 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
118
119 DBG_88E_LEVEL(_drv_always_, "indicate disassoc\n");
120 wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
121}
122
123static char *translate_scan(struct adapter *padapter,
124 struct iw_request_info *info,
125 struct wlan_network *pnetwork,
126 char *start, char *stop)
127{
128 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
129 struct iw_event iwe;
130 u16 cap;
131 __le16 le_tmp;
132 u32 ht_ielen = 0;
133 char *custom;
134 char *p;
135 u16 max_rate = 0, rate, ht_cap = false;
136 u32 i = 0;
137 u8 bw_40MHz = 0, short_GI = 0;
138 u16 mcs_rate = 0;
139 u8 ss, sq;
140#ifdef CONFIG_88EU_P2P
141 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
142
143 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
144 u32 blnGotP2PIE = false;
145
146
147
148
149
150
151 if (!memcmp(pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN)) {
152 u32 p2pielen = 0;
153
154 if (pnetwork->network.Reserved[0] == 2) {
155
156 if (rtw_get_p2p_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &p2pielen))
157 blnGotP2PIE = true;
158 } else {
159
160 if (rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen))
161 blnGotP2PIE = true;
162 }
163 }
164
165 if (!blnGotP2PIE)
166 return start;
167 }
168#endif
169
170
171 iwe.cmd = SIOCGIWAP;
172 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
173
174 memcpy(iwe.u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
175 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
176
177
178 iwe.cmd = SIOCGIWESSID;
179 iwe.u.data.flags = 1;
180 iwe.u.data.length = min_t(u16, pnetwork->network.Ssid.SsidLength, 32);
181 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
182
183
184 p = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - 12);
185
186 if (p && ht_ielen > 0) {
187 struct ieee80211_ht_cap *pht_capie;
188
189 ht_cap = true;
190 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
191 memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2);
192 bw_40MHz = (le16_to_cpu(pht_capie->cap_info) &
193 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
194 short_GI = (le16_to_cpu(pht_capie->cap_info) &
195 (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
196 }
197
198
199 iwe.cmd = SIOCGIWNAME;
200 if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates))) {
201 if (ht_cap)
202 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bn");
203 else
204 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
205 } else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates))) {
206 if (ht_cap)
207 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bgn");
208 else
209 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11bg");
210 } else {
211 if (ht_cap)
212 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11gn");
213 else
214 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
215 }
216
217 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
218
219
220 iwe.cmd = SIOCGIWMODE;
221 memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
222
223 cap = le16_to_cpu(le_tmp);
224
225 if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
226 if (cap & WLAN_CAPABILITY_BSS)
227 iwe.u.mode = IW_MODE_MASTER;
228 else
229 iwe.u.mode = IW_MODE_ADHOC;
230
231 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
232 }
233
234 if (pnetwork->network.Configuration.DSConfig < 1)
235 pnetwork->network.Configuration.DSConfig = 1;
236
237
238 iwe.cmd = SIOCGIWFREQ;
239 iwe.u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
240 iwe.u.freq.e = 1;
241 iwe.u.freq.i = pnetwork->network.Configuration.DSConfig;
242 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
243
244
245 iwe.cmd = SIOCGIWENCODE;
246 if (cap & WLAN_CAPABILITY_PRIVACY)
247 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
248 else
249 iwe.u.data.flags = IW_ENCODE_DISABLED;
250 iwe.u.data.length = 0;
251 start = iwe_stream_add_point(info, start, stop, &iwe, pnetwork->network.Ssid.Ssid);
252
253
254 max_rate = 0;
255 custom = kzalloc(MAX_CUSTOM_LEN, GFP_ATOMIC);
256 if (!custom)
257 return start;
258 p = custom;
259 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
260 while (pnetwork->network.SupportedRates[i] != 0) {
261 rate = pnetwork->network.SupportedRates[i] & 0x7F;
262 if (rate > max_rate)
263 max_rate = rate;
264 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
265 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
266 i++;
267 }
268
269 if (ht_cap) {
270 if (mcs_rate & 0x8000)
271 max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130);
272 else if (mcs_rate & 0x0080)
273 ;
274 else
275 max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
276
277 max_rate = max_rate * 2;
278 }
279
280 iwe.cmd = SIOCGIWRATE;
281 iwe.u.bitrate.fixed = 0;
282 iwe.u.bitrate.disabled = 0;
283 iwe.u.bitrate.value = max_rate * 500000;
284 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
285
286
287 {
288 u8 *buf;
289 u8 *wpa_ie, *rsn_ie;
290 u16 wpa_len = 0, rsn_len = 0;
291 u8 *p;
292
293 buf = kzalloc(MAX_WPA_IE_LEN, GFP_ATOMIC);
294 if (!buf)
295 goto exit;
296 wpa_ie = kzalloc(255, GFP_ATOMIC);
297 if (!wpa_ie) {
298 kfree(buf);
299 goto exit;
300 }
301 rsn_ie = kzalloc(255, GFP_ATOMIC);
302 if (!rsn_ie) {
303 kfree(buf);
304 kfree(wpa_ie);
305 goto exit;
306 }
307 rtw_get_sec_ie(pnetwork->network.IEs, pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
308
309 if (wpa_len > 0) {
310 p = buf;
311 memset(buf, 0, MAX_WPA_IE_LEN);
312 p += sprintf(p, "wpa_ie =");
313 for (i = 0; i < wpa_len; i++)
314 p += sprintf(p, "%02x", wpa_ie[i]);
315
316 memset(&iwe, 0, sizeof(iwe));
317 iwe.cmd = IWEVCUSTOM;
318 iwe.u.data.length = strlen(buf);
319 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
320
321 memset(&iwe, 0, sizeof(iwe));
322 iwe.cmd = IWEVGENIE;
323 iwe.u.data.length = wpa_len;
324 start = iwe_stream_add_point(info, start, stop, &iwe, wpa_ie);
325 }
326 if (rsn_len > 0) {
327 p = buf;
328 memset(buf, 0, MAX_WPA_IE_LEN);
329 p += sprintf(p, "rsn_ie =");
330 for (i = 0; i < rsn_len; i++)
331 p += sprintf(p, "%02x", rsn_ie[i]);
332 memset(&iwe, 0, sizeof(iwe));
333 iwe.cmd = IWEVCUSTOM;
334 iwe.u.data.length = strlen(buf);
335 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
336
337 memset(&iwe, 0, sizeof(iwe));
338 iwe.cmd = IWEVGENIE;
339 iwe.u.data.length = rsn_len;
340 start = iwe_stream_add_point(info, start, stop, &iwe, rsn_ie);
341 }
342 kfree(buf);
343 kfree(wpa_ie);
344 kfree(rsn_ie);
345 }
346
347 {
348 uint cnt = 0, total_ielen;
349 u8 *wpsie_ptr = NULL;
350 uint wps_ielen = 0;
351
352 u8 *ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
353 total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
354
355 while (cnt < total_ielen) {
356 if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) {
357 wpsie_ptr = &ie_ptr[cnt];
358 iwe.cmd = IWEVGENIE;
359 iwe.u.data.length = (u16)wps_ielen;
360 start = iwe_stream_add_point(info, start, stop, &iwe, wpsie_ptr);
361 }
362 cnt += ie_ptr[cnt + 1] + 2;
363 }
364 }
365
366
367 iwe.cmd = IWEVQUAL;
368 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID;
369
370 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
371 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) {
372 ss = padapter->recvpriv.signal_strength;
373 sq = padapter->recvpriv.signal_qual;
374 } else {
375 ss = pnetwork->network.PhyInfo.SignalStrength;
376 sq = pnetwork->network.PhyInfo.SignalQuality;
377 }
378
379 iwe.u.qual.level = (u8)ss;
380 iwe.u.qual.qual = (u8)sq;
381 iwe.u.qual.noise = 0;
382 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
383exit:
384 kfree(custom);
385 return start;
386}
387
388static int wpa_set_auth_algs(struct net_device *dev, u32 value)
389{
390 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
391 int ret = 0;
392
393 if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
394 DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value);
395 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
396 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
397 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
398 } else if (value & AUTH_ALG_SHARED_KEY) {
399 DBG_88E("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n", value);
400 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
401
402 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
403 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
404 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
405 DBG_88E("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
406 if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
407 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
408 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
409 }
410 } else if (value & AUTH_ALG_LEAP) {
411 DBG_88E("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
412 } else {
413 DBG_88E("wpa_set_auth_algs, error!\n");
414 ret = -EINVAL;
415 }
416 return ret;
417}
418
419static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
420{
421 int ret = 0;
422 u32 wep_key_idx, wep_key_len, wep_total_len;
423 struct ndis_802_11_wep *pwep = NULL;
424 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
425 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
426 struct security_priv *psecuritypriv = &padapter->securitypriv;
427#ifdef CONFIG_88EU_P2P
428 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
429#endif
430
431 param->u.crypt.err = 0;
432 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
433
434 if (param_len < (u32)((u8 *)param->u.crypt.key - (u8 *)param) + param->u.crypt.key_len) {
435 ret = -EINVAL;
436 goto exit;
437 }
438
439 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
440 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
441 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
442 if (param->u.crypt.idx >= WEP_KEYS) {
443 ret = -EINVAL;
444 goto exit;
445 }
446 } else {
447 ret = -EINVAL;
448 goto exit;
449 }
450
451 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
452 DBG_88E("wpa_set_encryption, crypt.alg = WEP\n");
453
454 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
455 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
456 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
457
458 wep_key_idx = param->u.crypt.idx;
459 wep_key_len = param->u.crypt.key_len;
460
461 DBG_88E("(1)wep_key_idx =%d\n", wep_key_idx);
462
463 if (wep_key_idx > WEP_KEYS)
464 return -EINVAL;
465
466 if (wep_key_len > 0) {
467 wep_key_len = wep_key_len <= 5 ? 5 : 13;
468 wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
469 pwep = kmalloc(wep_total_len, GFP_KERNEL);
470 if (!pwep)
471 goto exit;
472
473 memset(pwep, 0, wep_total_len);
474 pwep->KeyLength = wep_key_len;
475 pwep->Length = wep_total_len;
476 if (wep_key_len == 13) {
477 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
478 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
479 }
480 } else {
481 ret = -EINVAL;
482 goto exit;
483 }
484 pwep->KeyIndex = wep_key_idx;
485 pwep->KeyIndex |= 0x80000000;
486 memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
487 if (param->u.crypt.set_tx) {
488 DBG_88E("wep, set_tx = 1\n");
489 if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
490 ret = -EOPNOTSUPP;
491 } else {
492 DBG_88E("wep, set_tx = 0\n");
493 if (wep_key_idx >= WEP_KEYS) {
494 ret = -EOPNOTSUPP;
495 goto exit;
496 }
497 memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0], pwep->KeyMaterial, pwep->KeyLength);
498 psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
499 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0);
500 }
501 goto exit;
502 }
503
504 if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
505 struct sta_info *psta, *pbcmc_sta;
506 struct sta_priv *pstapriv = &padapter->stapriv;
507
508 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE)) {
509 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
510 if (!psta) {
511 ;
512 } else {
513 if (strcmp(param->u.crypt.alg, "none") != 0)
514 psta->ieee8021x_blocked = false;
515
516 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
517 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
518 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
519
520 if (param->u.crypt.set_tx == 1) {
521 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
522
523 if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
524 memcpy(psta->dot11tkiptxmickey.skey, ¶m->u.crypt.key[16], 8);
525 memcpy(psta->dot11tkiprxmickey.skey, ¶m->u.crypt.key[24], 8);
526 padapter->securitypriv.busetkipkey = false;
527 }
528
529 DBG_88E(" ~~~~set sta key:unicastkey\n");
530
531 rtw_setstakey_cmd(padapter, (unsigned char *)psta, true);
532 } else {
533 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));
534 memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[16], 8);
535 memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, ¶m->u.crypt.key[24], 8);
536 padapter->securitypriv.binstallGrpkey = true;
537 DBG_88E(" ~~~~set sta key:groupkey\n");
538
539 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
540
541 rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1);
542#ifdef CONFIG_88EU_P2P
543 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
544 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
545#endif
546 }
547 }
548 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
549 if (!pbcmc_sta) {
550 ;
551 } else {
552
553 if (strcmp(param->u.crypt.alg, "none") != 0)
554 pbcmc_sta->ieee8021x_blocked = false;
555
556 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
557 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
558 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
559 }
560 }
561 }
562
563exit:
564
565 kfree(pwep);
566
567 return ret;
568}
569
570static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ielen)
571{
572 u8 *buf = NULL;
573 int group_cipher = 0, pairwise_cipher = 0;
574 int ret = 0;
575#ifdef CONFIG_88EU_P2P
576 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
577#endif
578
579 if (ielen > MAX_WPA_IE_LEN || !pie) {
580 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
581 if (!pie)
582 return ret;
583 else
584 return -EINVAL;
585 }
586
587 if (ielen) {
588 buf = kzalloc(ielen, GFP_KERNEL);
589 if (!buf) {
590 ret = -ENOMEM;
591 goto exit;
592 }
593
594 memcpy(buf, pie, ielen);
595
596
597 {
598 int i;
599 DBG_88E("\n wpa_ie(length:%d):\n", ielen);
600 for (i = 0; i < ielen; i += 8)
601 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]);
602 }
603
604 if (ielen < RSN_HEADER_LEN) {
605 ret = -1;
606 goto exit;
607 }
608
609 if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
610 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
611 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
612 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
613 }
614
615 if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
616 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
617 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
618 memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
619 }
620
621 switch (group_cipher) {
622 case WPA_CIPHER_NONE:
623 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
624 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
625 break;
626 case WPA_CIPHER_WEP40:
627 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
628 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
629 break;
630 case WPA_CIPHER_TKIP:
631 padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
632 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
633 break;
634 case WPA_CIPHER_CCMP:
635 padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
636 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
637 break;
638 case WPA_CIPHER_WEP104:
639 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
640 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
641 break;
642 }
643
644 switch (pairwise_cipher) {
645 case WPA_CIPHER_NONE:
646 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
647 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
648 break;
649 case WPA_CIPHER_WEP40:
650 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
651 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
652 break;
653 case WPA_CIPHER_TKIP:
654 padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
655 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
656 break;
657 case WPA_CIPHER_CCMP:
658 padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
659 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
660 break;
661 case WPA_CIPHER_WEP104:
662 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
663 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
664 break;
665 }
666
667 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
668 {
669 u16 cnt = 0;
670 u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
671
672 while (cnt < ielen) {
673 eid = buf[cnt];
674 if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&buf[cnt + 2], wps_oui, 4))) {
675 DBG_88E("SET WPS_IE\n");
676
677 padapter->securitypriv.wps_ie_len = ((buf[cnt + 1] + 2) < (MAX_WPA_IE_LEN << 2)) ? (buf[cnt + 1] + 2) : (MAX_WPA_IE_LEN << 2);
678
679 memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
680
681 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
682#ifdef CONFIG_88EU_P2P
683 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
684 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING);
685#endif
686 cnt += buf[cnt + 1] + 2;
687 break;
688 } else {
689 cnt += buf[cnt + 1] + 2;
690 }
691 }
692 }
693 }
694
695exit:
696 kfree(buf);
697 return ret;
698}
699
700typedef unsigned char NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];
701
702static int rtw_wx_get_name(struct net_device *dev,
703 struct iw_request_info *info,
704 union iwreq_data *wrqu, char *extra)
705{
706 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
707 u32 ht_ielen = 0;
708 char *p;
709 u8 ht_cap = false;
710 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
711 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
712 NDIS_802_11_RATES_EX *prates = NULL;
713
714 if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) {
715
716 p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12);
717 if (p && ht_ielen > 0)
718 ht_cap = true;
719
720 prates = &pcur_bss->SupportedRates;
721
722 if (rtw_is_cckratesonly_included((u8 *)prates)) {
723 if (ht_cap)
724 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
725 else
726 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
727 } else if (rtw_is_cckrates_included((u8 *)prates)) {
728 if (ht_cap)
729 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
730 else
731 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
732 } else {
733 if (ht_cap)
734 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
735 else
736 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
737 }
738 } else {
739 snprintf(wrqu->name, IFNAMSIZ, "unassociated");
740 }
741
742
743
744 return 0;
745}
746
747static int rtw_wx_get_freq(struct net_device *dev,
748 struct iw_request_info *info,
749 union iwreq_data *wrqu, char *extra)
750{
751 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
752 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
753 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
754
755 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
756
757 wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
758 wrqu->freq.e = 1;
759 wrqu->freq.i = pcur_bss->Configuration.DSConfig;
760 } else {
761 wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
762 wrqu->freq.e = 1;
763 wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
764 }
765
766 return 0;
767}
768
769static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
770 union iwreq_data *wrqu, char *b)
771{
772 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
773 enum ndis_802_11_network_infra networkType;
774 int ret = 0;
775
776
777
778 if (_FAIL == rtw_pwr_wakeup(padapter)) {
779 ret = -EPERM;
780 goto exit;
781 }
782
783 if (!padapter->hw_init_completed) {
784 ret = -EPERM;
785 goto exit;
786 }
787
788 switch (wrqu->mode) {
789 case IW_MODE_AUTO:
790 networkType = Ndis802_11AutoUnknown;
791 DBG_88E("set_mode = IW_MODE_AUTO\n");
792 break;
793 case IW_MODE_ADHOC:
794 networkType = Ndis802_11IBSS;
795 DBG_88E("set_mode = IW_MODE_ADHOC\n");
796 break;
797 case IW_MODE_MASTER:
798 networkType = Ndis802_11APMode;
799 DBG_88E("set_mode = IW_MODE_MASTER\n");
800 break;
801 case IW_MODE_INFRA:
802 networkType = Ndis802_11Infrastructure;
803 DBG_88E("set_mode = IW_MODE_INFRA\n");
804 break;
805 default:
806 ret = -EINVAL;
807 goto exit;
808 }
809 if (!rtw_set_802_11_infrastructure_mode(padapter, networkType)) {
810 ret = -EPERM;
811 goto exit;
812 }
813 rtw_setopmode_cmd(padapter, networkType);
814exit:
815
816 return ret;
817}
818
819static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
820 union iwreq_data *wrqu, char *b)
821{
822 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
823 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
824
825 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
826 wrqu->mode = IW_MODE_INFRA;
827 else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
828 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)))
829 wrqu->mode = IW_MODE_ADHOC;
830 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
831 wrqu->mode = IW_MODE_MASTER;
832 else
833 wrqu->mode = IW_MODE_AUTO;
834
835
836
837 return 0;
838}
839
840static int rtw_wx_set_pmkid(struct net_device *dev,
841 struct iw_request_info *a,
842 union iwreq_data *wrqu, char *extra)
843{
844 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
845 u8 j, blInserted = false;
846 int ret = false;
847 struct security_priv *psecuritypriv = &padapter->securitypriv;
848 struct iw_pmksa *pPMK = (struct iw_pmksa *)extra;
849 u8 strZeroMacAddress[ETH_ALEN] = {0x00};
850 u8 strIssueBssid[ETH_ALEN] = {0x00};
851
852 memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
853 if (pPMK->cmd == IW_PMKSA_ADD) {
854 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
855 if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
856 return ret;
857 else
858 ret = true;
859 blInserted = false;
860
861
862 for (j = 0; j < NUM_PMKID_CACHE; j++) {
863 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
864
865 DBG_88E("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n");
866 memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
867 psecuritypriv->PMKIDList[j].bUsed = true;
868 psecuritypriv->PMKIDIndex = j + 1;
869 blInserted = true;
870 break;
871 }
872 }
873
874 if (!blInserted) {
875
876 DBG_88E("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
877 psecuritypriv->PMKIDIndex);
878
879 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
880 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
881
882 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = true;
883 psecuritypriv->PMKIDIndex++;
884 if (psecuritypriv->PMKIDIndex == 16)
885 psecuritypriv->PMKIDIndex = 0;
886 }
887 } else if (pPMK->cmd == IW_PMKSA_REMOVE) {
888 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n");
889 ret = true;
890 for (j = 0; j < NUM_PMKID_CACHE; j++) {
891 if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
892
893 memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN);
894 psecuritypriv->PMKIDList[j].bUsed = false;
895 break;
896 }
897 }
898 } else if (pPMK->cmd == IW_PMKSA_FLUSH) {
899 DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");
900 memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
901 psecuritypriv->PMKIDIndex = 0;
902 ret = true;
903 }
904 return ret;
905}
906
907static int rtw_wx_get_sens(struct net_device *dev,
908 struct iw_request_info *info,
909 union iwreq_data *wrqu, char *extra)
910{
911 wrqu->sens.value = 0;
912 wrqu->sens.fixed = 0;
913 wrqu->sens.disabled = 1;
914 return 0;
915}
916
917static int rtw_wx_get_range(struct net_device *dev,
918 struct iw_request_info *info,
919 union iwreq_data *wrqu, char *extra)
920{
921 struct iw_range *range = (struct iw_range *)extra;
922 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
923 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
924
925 u16 val;
926 int i;
927
928 wrqu->data.length = sizeof(*range);
929 memset(range, 0, sizeof(*range));
930
931
932
933
934
935
936
937
938
939
940 range->throughput = 5 * 1000 * 1000;
941
942
943
944
945 range->max_qual.qual = 100;
946 range->max_qual.level = 100;
947 range->max_qual.noise = 100;
948 range->max_qual.updated = 7;
949
950 range->avg_qual.qual = 92;
951
952 range->avg_qual.level = 178;
953 range->avg_qual.noise = 0;
954 range->avg_qual.updated = 7;
955
956 range->num_bitrates = RATE_COUNT;
957
958 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
959 range->bitrate[i] = rtw_rates[i];
960
961 range->min_frag = MIN_FRAG_THRESHOLD;
962 range->max_frag = MAX_FRAG_THRESHOLD;
963
964 range->pm_capa = 0;
965
966 range->we_version_compiled = WIRELESS_EXT;
967 range->we_version_source = 16;
968
969 for (i = 0, val = 0; i < MAX_CHANNEL_NUM; i++) {
970
971 if (pmlmeext->channel_set[i].ChannelNum != 0) {
972 range->freq[val].i = pmlmeext->channel_set[i].ChannelNum;
973 range->freq[val].m = rtw_ch2freq(pmlmeext->channel_set[i].ChannelNum) * 100000;
974 range->freq[val].e = 1;
975 val++;
976 }
977
978 if (val == IW_MAX_FREQUENCIES)
979 break;
980 }
981
982 range->num_channels = val;
983 range->num_frequency = val;
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
1001 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
1002
1003 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE |
1004 IW_SCAN_CAPA_BSSID | IW_SCAN_CAPA_CHANNEL |
1005 IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE;
1006
1007
1008 return 0;
1009}
1010
1011
1012
1013
1014
1015
1016static int rtw_wx_set_wap(struct net_device *dev,
1017 struct iw_request_info *info,
1018 union iwreq_data *awrq,
1019 char *extra)
1020{
1021 uint ret = 0;
1022 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1023 struct sockaddr *temp = (struct sockaddr *)awrq;
1024 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1025 struct list_head *phead;
1026 u8 *dst_bssid, *src_bssid;
1027 struct __queue *queue = &pmlmepriv->scanned_queue;
1028 struct wlan_network *pnetwork = NULL;
1029 enum ndis_802_11_auth_mode authmode;
1030
1031
1032
1033 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1034 ret = -1;
1035 goto exit;
1036 }
1037
1038 if (!padapter->bup) {
1039 ret = -1;
1040 goto exit;
1041 }
1042
1043 if (temp->sa_family != ARPHRD_ETHER) {
1044 ret = -EINVAL;
1045 goto exit;
1046 }
1047
1048 authmode = padapter->securitypriv.ndisauthtype;
1049 spin_lock_bh(&queue->lock);
1050 phead = get_list_head(queue);
1051 pmlmepriv->pscanned = phead->next;
1052
1053 while (phead != pmlmepriv->pscanned) {
1054
1055 pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
1056
1057 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1058
1059 dst_bssid = pnetwork->network.MacAddress;
1060
1061 src_bssid = temp->sa_data;
1062
1063 if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) {
1064 if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
1065 ret = -1;
1066 spin_unlock_bh(&queue->lock);
1067 goto exit;
1068 }
1069
1070 break;
1071 }
1072 }
1073 spin_unlock_bh(&queue->lock);
1074
1075 rtw_set_802_11_authentication_mode(padapter, authmode);
1076
1077 if (!rtw_set_802_11_bssid(padapter, temp->sa_data)) {
1078 ret = -1;
1079 goto exit;
1080 }
1081
1082exit:
1083
1084
1085
1086 return ret;
1087}
1088
1089static int rtw_wx_get_wap(struct net_device *dev,
1090 struct iw_request_info *info,
1091 union iwreq_data *wrqu, char *extra)
1092{
1093 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1094 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1095 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1096
1097 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1098
1099 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1100
1101 if (check_fwstate(pmlmepriv, _FW_LINKED) ||
1102 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1103 check_fwstate(pmlmepriv, WIFI_AP_STATE))
1104 memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1105 else
1106 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1107
1108
1109
1110 return 0;
1111}
1112
1113static int rtw_wx_set_mlme(struct net_device *dev,
1114 struct iw_request_info *info,
1115 union iwreq_data *wrqu, char *extra)
1116{
1117 int ret = 0;
1118 u16 reason;
1119 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1120 struct iw_mlme *mlme = (struct iw_mlme *)extra;
1121
1122 if (!mlme)
1123 return -1;
1124
1125 DBG_88E("%s\n", __func__);
1126
1127 reason = mlme->reason_code;
1128
1129 DBG_88E("%s, cmd =%d, reason =%d\n", __func__, mlme->cmd, reason);
1130
1131 switch (mlme->cmd) {
1132 case IW_MLME_DEAUTH:
1133 if (!rtw_set_802_11_disassociate(padapter))
1134 ret = -1;
1135 break;
1136 case IW_MLME_DISASSOC:
1137 if (!rtw_set_802_11_disassociate(padapter))
1138 ret = -1;
1139 break;
1140 default:
1141 return -EOPNOTSUPP;
1142 }
1143 return ret;
1144}
1145
1146static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
1147 union iwreq_data *wrqu, char *extra)
1148{
1149 u8 _status = false;
1150 int ret = 0;
1151 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1152 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1153 struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
1154#ifdef CONFIG_88EU_P2P
1155 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1156#endif
1157
1158 if (padapter->registrypriv.mp_mode == 1) {
1159 if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
1160 ret = -1;
1161 goto exit;
1162 }
1163 }
1164 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1165 ret = -1;
1166 goto exit;
1167 }
1168
1169 if (padapter->bDriverStopped) {
1170 DBG_88E("bDriverStopped =%d\n", padapter->bDriverStopped);
1171 ret = -1;
1172 goto exit;
1173 }
1174
1175 if (!padapter->bup) {
1176 ret = -1;
1177 goto exit;
1178 }
1179
1180 if (!padapter->hw_init_completed) {
1181 ret = -1;
1182 goto exit;
1183 }
1184
1185
1186
1187
1188 if (pmlmepriv->LinkDetectInfo.bBusyTraffic) {
1189 indicate_wx_scan_complete_event(padapter);
1190 goto exit;
1191 }
1192
1193 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) {
1194 indicate_wx_scan_complete_event(padapter);
1195 goto exit;
1196 }
1197
1198
1199
1200
1201
1202#ifdef CONFIG_88EU_P2P
1203 if (pwdinfo->p2p_state != P2P_STATE_NONE) {
1204 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
1205 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
1206 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL);
1207 rtw_free_network_queue(padapter, true);
1208 }
1209#endif
1210
1211 memset(ssid, 0, sizeof(struct ndis_802_11_ssid) * RTW_SSID_SCAN_AMOUNT);
1212
1213 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
1214 struct iw_scan_req *req = (struct iw_scan_req *)extra;
1215
1216 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1217 int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
1218
1219 memcpy(ssid[0].Ssid, req->essid, len);
1220 ssid[0].SsidLength = len;
1221
1222 DBG_88E("IW_SCAN_THIS_ESSID, ssid =%s, len =%d\n", req->essid, req->essid_len);
1223
1224 spin_lock_bh(&pmlmepriv->lock);
1225
1226 _status = rtw_sitesurvey_cmd(padapter, ssid, 1, NULL, 0);
1227
1228 spin_unlock_bh(&pmlmepriv->lock);
1229 } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) {
1230 DBG_88E("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
1231 }
1232 } else {
1233 if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE &&
1234 !memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
1235 int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE;
1236 char *pos = extra + WEXT_CSCAN_HEADER_SIZE;
1237 char section;
1238 char sec_len;
1239 int ssid_index = 0;
1240
1241 while (len >= 1) {
1242 section = *(pos++);
1243 len -= 1;
1244
1245 switch (section) {
1246 case WEXT_CSCAN_SSID_SECTION:
1247 if (len < 1) {
1248 len = 0;
1249 break;
1250 }
1251 sec_len = *(pos++); len -= 1;
1252 if (sec_len > 0 && sec_len <= len) {
1253 ssid[ssid_index].SsidLength = sec_len;
1254 memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength);
1255 ssid_index++;
1256 }
1257 pos += sec_len;
1258 len -= sec_len;
1259 break;
1260 case WEXT_CSCAN_TYPE_SECTION:
1261 case WEXT_CSCAN_CHANNEL_SECTION:
1262 pos += 1;
1263 len -= 1;
1264 break;
1265 case WEXT_CSCAN_PASV_DWELL_SECTION:
1266 case WEXT_CSCAN_HOME_DWELL_SECTION:
1267 case WEXT_CSCAN_ACTV_DWELL_SECTION:
1268 pos += 2;
1269 len -= 2;
1270 break;
1271 default:
1272 len = 0;
1273 }
1274 }
1275
1276
1277 _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
1278 } else {
1279 _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
1280 }
1281 }
1282
1283 if (!_status)
1284 ret = -1;
1285
1286exit:
1287
1288 return ret;
1289}
1290
1291static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
1292 union iwreq_data *wrqu, char *extra)
1293{
1294 struct list_head *plist, *phead;
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 wlan_network *pnetwork = NULL;
1299 char *ev = extra;
1300 char *stop = ev + wrqu->data.length;
1301 u32 ret = 0;
1302 u32 cnt = 0;
1303 u32 wait_for_surveydone;
1304 int wait_status;
1305#ifdef CONFIG_88EU_P2P
1306 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1307#endif
1308
1309 if (padapter->pwrctrlpriv.brfoffbyhw && padapter->bDriverStopped) {
1310 ret = -EINVAL;
1311 goto exit;
1312 }
1313
1314#ifdef CONFIG_88EU_P2P
1315 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
1316
1317 wait_for_surveydone = 200;
1318 } else {
1319
1320 wait_for_surveydone = 100;
1321 }
1322#else
1323 {
1324 wait_for_surveydone = 100;
1325 }
1326#endif
1327
1328 wait_status = _FW_UNDER_SURVEY | _FW_UNDER_LINKING;
1329
1330 while (check_fwstate(pmlmepriv, wait_status)) {
1331 msleep(30);
1332 cnt++;
1333 if (cnt > wait_for_surveydone)
1334 break;
1335 }
1336
1337 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1338
1339 phead = get_list_head(queue);
1340 plist = phead->next;
1341
1342 while (phead != plist) {
1343 if ((stop - ev) < SCAN_ITEM_SIZE) {
1344 ret = -E2BIG;
1345 break;
1346 }
1347
1348 pnetwork = container_of(plist, struct wlan_network, list);
1349
1350
1351 if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0)
1352 ev = translate_scan(padapter, a, pnetwork, ev, stop);
1353
1354 plist = plist->next;
1355 }
1356
1357 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1358
1359 wrqu->data.length = ev - extra;
1360 wrqu->data.flags = 0;
1361
1362exit:
1363
1364 return ret;
1365}
1366
1367
1368
1369
1370
1371
1372static int rtw_wx_set_essid(struct net_device *dev,
1373 struct iw_request_info *a,
1374 union iwreq_data *wrqu, char *extra)
1375{
1376 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1377 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1378 struct __queue *queue = &pmlmepriv->scanned_queue;
1379 struct list_head *phead;
1380 struct wlan_network *pnetwork = NULL;
1381 enum ndis_802_11_auth_mode authmode;
1382 struct ndis_802_11_ssid ndis_ssid;
1383 u8 *dst_ssid, *src_ssid;
1384
1385 uint ret = 0, len;
1386
1387 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1388 ret = -1;
1389 goto exit;
1390 }
1391
1392 if (!padapter->bup) {
1393 ret = -1;
1394 goto exit;
1395 }
1396
1397 if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
1398 ret = -E2BIG;
1399 goto exit;
1400 }
1401
1402 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1403 ret = -1;
1404 goto exit;
1405 }
1406
1407 authmode = padapter->securitypriv.ndisauthtype;
1408 DBG_88E("=>%s\n", __func__);
1409 if (wrqu->essid.flags && wrqu->essid.length) {
1410 len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
1411
1412 if (wrqu->essid.length != 33)
1413 DBG_88E("ssid =%s, len =%d\n", extra, wrqu->essid.length);
1414
1415 memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1416 ndis_ssid.SsidLength = len;
1417 memcpy(ndis_ssid.Ssid, extra, len);
1418 src_ssid = ndis_ssid.Ssid;
1419
1420 spin_lock_bh(&queue->lock);
1421 phead = get_list_head(queue);
1422 pmlmepriv->pscanned = phead->next;
1423
1424 while (phead != pmlmepriv->pscanned) {
1425 pnetwork = container_of(pmlmepriv->pscanned, struct wlan_network, list);
1426
1427 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1428
1429 dst_ssid = pnetwork->network.Ssid.Ssid;
1430
1431 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) &&
1432 (pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) {
1433
1434 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1435 if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
1436 continue;
1437 }
1438
1439 if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode)) {
1440 ret = -1;
1441 spin_unlock_bh(&queue->lock);
1442 goto exit;
1443 }
1444
1445 break;
1446 }
1447 }
1448 spin_unlock_bh(&queue->lock);
1449 rtw_set_802_11_authentication_mode(padapter, authmode);
1450 if (!rtw_set_802_11_ssid(padapter, &ndis_ssid)) {
1451 ret = -1;
1452 goto exit;
1453 }
1454 }
1455
1456exit:
1457
1458 DBG_88E("<=%s, ret %d\n", __func__, ret);
1459
1460
1461
1462 return ret;
1463}
1464
1465static int rtw_wx_get_essid(struct net_device *dev,
1466 struct iw_request_info *a,
1467 union iwreq_data *wrqu, char *extra)
1468{
1469 u32 len, ret = 0;
1470 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1471 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1472 struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network;
1473
1474 if ((check_fwstate(pmlmepriv, _FW_LINKED)) ||
1475 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))) {
1476 len = pcur_bss->Ssid.SsidLength;
1477 memcpy(extra, pcur_bss->Ssid.Ssid, len);
1478 } else {
1479 len = 0;
1480 *extra = 0;
1481 }
1482 wrqu->essid.length = len;
1483 wrqu->essid.flags = 1;
1484
1485 return ret;
1486}
1487
1488static int rtw_wx_set_rate(struct net_device *dev,
1489 struct iw_request_info *a,
1490 union iwreq_data *wrqu, char *extra)
1491{
1492 int i, ret = 0;
1493 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1494 u8 datarates[NumRates];
1495 u32 target_rate = wrqu->bitrate.value;
1496 u32 fixed = wrqu->bitrate.fixed;
1497 u32 ratevalue = 0;
1498 u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
1499
1500 if (target_rate == -1) {
1501 ratevalue = 11;
1502 goto set_rate;
1503 }
1504 target_rate = target_rate / 100000;
1505
1506 switch (target_rate) {
1507 case 10:
1508 ratevalue = 0;
1509 break;
1510 case 20:
1511 ratevalue = 1;
1512 break;
1513 case 55:
1514 ratevalue = 2;
1515 break;
1516 case 60:
1517 ratevalue = 3;
1518 break;
1519 case 90:
1520 ratevalue = 4;
1521 break;
1522 case 110:
1523 ratevalue = 5;
1524 break;
1525 case 120:
1526 ratevalue = 6;
1527 break;
1528 case 180:
1529 ratevalue = 7;
1530 break;
1531 case 240:
1532 ratevalue = 8;
1533 break;
1534 case 360:
1535 ratevalue = 9;
1536 break;
1537 case 480:
1538 ratevalue = 10;
1539 break;
1540 case 540:
1541 ratevalue = 11;
1542 break;
1543 default:
1544 ratevalue = 11;
1545 break;
1546 }
1547
1548set_rate:
1549
1550 for (i = 0; i < NumRates; i++) {
1551 if (ratevalue == mpdatarate[i]) {
1552 datarates[i] = mpdatarate[i];
1553 if (fixed == 0)
1554 break;
1555 } else {
1556 datarates[i] = 0xff;
1557 }
1558 }
1559
1560 if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS)
1561 ret = -1;
1562
1563 return ret;
1564}
1565
1566static int rtw_wx_get_rate(struct net_device *dev,
1567 struct iw_request_info *info,
1568 union iwreq_data *wrqu, char *extra)
1569{
1570 u16 max_rate = 0;
1571
1572 max_rate = rtw_get_cur_max_rate((struct adapter *)rtw_netdev_priv(dev));
1573
1574 if (max_rate == 0)
1575 return -EPERM;
1576
1577 wrqu->bitrate.fixed = 0;
1578 wrqu->bitrate.value = max_rate * 100000;
1579
1580 return 0;
1581}
1582
1583static int rtw_wx_set_rts(struct net_device *dev,
1584 struct iw_request_info *info,
1585 union iwreq_data *wrqu, char *extra)
1586{
1587 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1588
1589
1590
1591 if (wrqu->rts.disabled) {
1592 padapter->registrypriv.rts_thresh = 2347;
1593 } else {
1594 if (wrqu->rts.value < 0 ||
1595 wrqu->rts.value > 2347)
1596 return -EINVAL;
1597
1598 padapter->registrypriv.rts_thresh = wrqu->rts.value;
1599 }
1600
1601 DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh);
1602
1603
1604
1605 return 0;
1606}
1607
1608static int rtw_wx_get_rts(struct net_device *dev,
1609 struct iw_request_info *info,
1610 union iwreq_data *wrqu, char *extra)
1611{
1612 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1613
1614
1615
1616 DBG_88E("%s, rts_thresh =%d\n", __func__, padapter->registrypriv.rts_thresh);
1617
1618 wrqu->rts.value = padapter->registrypriv.rts_thresh;
1619 wrqu->rts.fixed = 0;
1620
1621
1622
1623
1624 return 0;
1625}
1626
1627static int rtw_wx_set_frag(struct net_device *dev,
1628 struct iw_request_info *info,
1629 union iwreq_data *wrqu, char *extra)
1630{
1631 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1632
1633
1634
1635 if (wrqu->frag.disabled) {
1636 padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
1637 } else {
1638 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
1639 wrqu->frag.value > MAX_FRAG_THRESHOLD)
1640 return -EINVAL;
1641
1642 padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
1643 }
1644
1645 DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len);
1646
1647
1648
1649 return 0;
1650}
1651
1652static int rtw_wx_get_frag(struct net_device *dev,
1653 struct iw_request_info *info,
1654 union iwreq_data *wrqu, char *extra)
1655{
1656 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1657
1658
1659
1660 DBG_88E("%s, frag_len =%d\n", __func__, padapter->xmitpriv.frag_len);
1661
1662 wrqu->frag.value = padapter->xmitpriv.frag_len;
1663 wrqu->frag.fixed = 0;
1664
1665
1666
1667 return 0;
1668}
1669
1670static int rtw_wx_get_retry(struct net_device *dev,
1671 struct iw_request_info *info,
1672 union iwreq_data *wrqu, char *extra)
1673{
1674 wrqu->retry.value = 7;
1675 wrqu->retry.fixed = 0;
1676 wrqu->retry.disabled = 1;
1677
1678 return 0;
1679}
1680
1681static int rtw_wx_set_enc(struct net_device *dev,
1682 struct iw_request_info *info,
1683 union iwreq_data *wrqu, char *keybuf)
1684{
1685 u32 key, ret = 0;
1686 u32 keyindex_provided;
1687 struct ndis_802_11_wep wep;
1688 enum ndis_802_11_auth_mode authmode;
1689
1690 struct iw_point *erq = &wrqu->encoding;
1691 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1692 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
1693 DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq->flags);
1694
1695 memset(&wep, 0, sizeof(struct ndis_802_11_wep));
1696
1697 key = erq->flags & IW_ENCODE_INDEX;
1698
1699
1700
1701 if (erq->flags & IW_ENCODE_DISABLED) {
1702 DBG_88E("EncryptionDisabled\n");
1703 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1704 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1705 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1706 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1707 authmode = Ndis802_11AuthModeOpen;
1708 padapter->securitypriv.ndisauthtype = authmode;
1709
1710 goto exit;
1711 }
1712
1713 if (key) {
1714 if (key > WEP_KEYS)
1715 return -EINVAL;
1716 key--;
1717 keyindex_provided = 1;
1718 } else {
1719 keyindex_provided = 0;
1720 key = padapter->securitypriv.dot11PrivacyKeyIndex;
1721 DBG_88E("rtw_wx_set_enc, key =%d\n", key);
1722 }
1723
1724
1725 if (erq->flags & IW_ENCODE_OPEN) {
1726 DBG_88E("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
1727 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1728 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1729 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1730 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1731 authmode = Ndis802_11AuthModeOpen;
1732 padapter->securitypriv.ndisauthtype = authmode;
1733 } else if (erq->flags & IW_ENCODE_RESTRICTED) {
1734 DBG_88E("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
1735 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1736 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1737 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1738 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1739 authmode = Ndis802_11AuthModeShared;
1740 padapter->securitypriv.ndisauthtype = authmode;
1741 } else {
1742 DBG_88E("rtw_wx_set_enc():erq->flags = 0x%x\n", erq->flags);
1743
1744 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1745 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1746 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1747 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1748 authmode = Ndis802_11AuthModeOpen;
1749 padapter->securitypriv.ndisauthtype = authmode;
1750 }
1751
1752 wep.KeyIndex = key;
1753 if (erq->length > 0) {
1754 wep.KeyLength = erq->length <= 5 ? 5 : 13;
1755
1756 wep.Length = wep.KeyLength + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
1757 } else {
1758 wep.KeyLength = 0;
1759
1760 if (keyindex_provided == 1) {
1761
1762 padapter->securitypriv.dot11PrivacyKeyIndex = key;
1763
1764 DBG_88E("(keyindex_provided == 1), keyid =%d, key_len =%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
1765
1766 switch (padapter->securitypriv.dot11DefKeylen[key]) {
1767 case 5:
1768 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1769 break;
1770 case 13:
1771 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
1772 break;
1773 default:
1774 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1775 break;
1776 }
1777
1778 goto exit;
1779 }
1780 }
1781
1782 wep.KeyIndex |= 0x80000000;
1783
1784 memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
1785
1786 if (!rtw_set_802_11_add_wep(padapter, &wep)) {
1787 if (rf_on == pwrpriv->rf_pwrstate)
1788 ret = -EOPNOTSUPP;
1789 goto exit;
1790 }
1791
1792exit:
1793
1794
1795
1796 return ret;
1797}
1798
1799static int rtw_wx_get_enc(struct net_device *dev,
1800 struct iw_request_info *info,
1801 union iwreq_data *wrqu, char *keybuf)
1802{
1803 uint key, ret = 0;
1804 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1805 struct iw_point *erq = &wrqu->encoding;
1806 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1807
1808
1809
1810 if (check_fwstate(pmlmepriv, _FW_LINKED) != true) {
1811 if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1812 erq->length = 0;
1813 erq->flags |= IW_ENCODE_DISABLED;
1814 return 0;
1815 }
1816 }
1817
1818 key = erq->flags & IW_ENCODE_INDEX;
1819
1820 if (key) {
1821 if (key > WEP_KEYS)
1822 return -EINVAL;
1823 key--;
1824 } else {
1825 key = padapter->securitypriv.dot11PrivacyKeyIndex;
1826 }
1827
1828 erq->flags = key + 1;
1829
1830 switch (padapter->securitypriv.ndisencryptstatus) {
1831 case Ndis802_11EncryptionNotSupported:
1832 case Ndis802_11EncryptionDisabled:
1833 erq->length = 0;
1834 erq->flags |= IW_ENCODE_DISABLED;
1835 break;
1836 case Ndis802_11Encryption1Enabled:
1837 erq->length = padapter->securitypriv.dot11DefKeylen[key];
1838 if (erq->length) {
1839 memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
1840
1841 erq->flags |= IW_ENCODE_ENABLED;
1842
1843 if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
1844 erq->flags |= IW_ENCODE_OPEN;
1845 else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
1846 erq->flags |= IW_ENCODE_RESTRICTED;
1847 } else {
1848 erq->length = 0;
1849 erq->flags |= IW_ENCODE_DISABLED;
1850 }
1851 break;
1852 case Ndis802_11Encryption2Enabled:
1853 case Ndis802_11Encryption3Enabled:
1854 erq->length = 16;
1855 erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
1856 break;
1857 default:
1858 erq->length = 0;
1859 erq->flags |= IW_ENCODE_DISABLED;
1860 break;
1861 }
1862
1863
1864 return ret;
1865}
1866
1867static int rtw_wx_get_power(struct net_device *dev,
1868 struct iw_request_info *info,
1869 union iwreq_data *wrqu, char *extra)
1870{
1871 wrqu->power.value = 0;
1872 wrqu->power.fixed = 0;
1873 wrqu->power.disabled = 1;
1874
1875 return 0;
1876}
1877
1878static int rtw_wx_set_gen_ie(struct net_device *dev,
1879 struct iw_request_info *info,
1880 union iwreq_data *wrqu, char *extra)
1881{
1882 int ret;
1883 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1884
1885 ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
1886 return ret;
1887}
1888
1889static int rtw_wx_set_auth(struct net_device *dev,
1890 struct iw_request_info *info,
1891 union iwreq_data *wrqu, char *extra)
1892{
1893 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
1894 struct iw_param *param = (struct iw_param *)&wrqu->param;
1895 int ret = 0;
1896
1897 switch (param->flags & IW_AUTH_INDEX) {
1898 case IW_AUTH_WPA_VERSION:
1899 break;
1900 case IW_AUTH_CIPHER_PAIRWISE:
1901
1902 break;
1903 case IW_AUTH_CIPHER_GROUP:
1904
1905 break;
1906 case IW_AUTH_KEY_MGMT:
1907
1908
1909
1910 break;
1911 case IW_AUTH_TKIP_COUNTERMEASURES:
1912 if (param->value) {
1913
1914 padapter->securitypriv.btkip_countermeasure = true;
1915 } else {
1916
1917 padapter->securitypriv.btkip_countermeasure = false;
1918 }
1919 break;
1920 case IW_AUTH_DROP_UNENCRYPTED:
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933 if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
1934 break;
1935
1936
1937 if (param->value) {
1938 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1939 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1940 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1941 padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1942 padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
1943 }
1944
1945 break;
1946 case IW_AUTH_80211_AUTH_ALG:
1947
1948
1949
1950 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
1951 LeaveAllPowerSaveMode(padapter);
1952 rtw_disassoc_cmd(padapter, 500, false);
1953 DBG_88E("%s...call rtw_indicate_disconnect\n ", __func__);
1954 rtw_indicate_disconnect(padapter);
1955 rtw_free_assoc_resources(padapter, 1);
1956 }
1957 ret = wpa_set_auth_algs(dev, (u32)param->value);
1958 break;
1959 case IW_AUTH_WPA_ENABLED:
1960 break;
1961 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1962 break;
1963 case IW_AUTH_PRIVACY_INVOKED:
1964 break;
1965 default:
1966 return -EOPNOTSUPP;
1967 }
1968
1969 return ret;
1970}
1971
1972static int rtw_wx_set_enc_ext(struct net_device *dev,
1973 struct iw_request_info *info,
1974 union iwreq_data *wrqu, char *extra)
1975{
1976 char *alg_name;
1977 u32 param_len;
1978 struct ieee_param *param = NULL;
1979 struct iw_point *pencoding = &wrqu->encoding;
1980 struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
1981 int ret = 0;
1982
1983 param_len = sizeof(struct ieee_param) + pext->key_len;
1984 param = kzalloc(param_len, GFP_KERNEL);
1985 if (!param)
1986 return -ENOMEM;
1987
1988 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1989 memset(param->sta_addr, 0xff, ETH_ALEN);
1990
1991 switch (pext->alg) {
1992 case IW_ENCODE_ALG_NONE:
1993
1994
1995 alg_name = "none";
1996 break;
1997 case IW_ENCODE_ALG_WEP:
1998 alg_name = "WEP";
1999 break;
2000 case IW_ENCODE_ALG_TKIP:
2001 alg_name = "TKIP";
2002 break;
2003 case IW_ENCODE_ALG_CCMP:
2004 alg_name = "CCMP";
2005 break;
2006 default:
2007 return -1;
2008 }
2009
2010 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
2011
2012 if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2013 param->u.crypt.set_tx = 1;
2014
2015
2016
2017
2018 if ((pext->alg != IW_ENCODE_ALG_WEP) &&
2019 (pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
2020 param->u.crypt.set_tx = 0;
2021
2022 param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1;
2023
2024 if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
2025 memcpy(param->u.crypt.seq, pext->rx_seq, 8);
2026
2027 if (pext->key_len) {
2028 param->u.crypt.key_len = pext->key_len;
2029 memcpy(param->u.crypt.key, pext + 1, pext->key_len);
2030 }
2031
2032 ret = wpa_set_encryption(dev, param, param_len);
2033
2034 kfree(param);
2035 return ret;
2036}
2037
2038static int rtw_wx_get_nick(struct net_device *dev,
2039 struct iw_request_info *info,
2040 union iwreq_data *wrqu, char *extra)
2041{
2042 if (extra) {
2043 wrqu->data.length = 14;
2044 wrqu->data.flags = 1;
2045 memcpy(extra, "<WIFI@REALTEK>", 14);
2046 }
2047
2048
2049 return 0;
2050}
2051
2052static int rtw_wx_read32(struct net_device *dev,
2053 struct iw_request_info *info,
2054 union iwreq_data *wrqu, char *extra)
2055{
2056 struct adapter *padapter;
2057 struct iw_point *p;
2058 u16 len;
2059 u32 addr;
2060 u32 data32;
2061 u32 bytes;
2062 u8 *ptmp;
2063
2064 padapter = (struct adapter *)rtw_netdev_priv(dev);
2065 p = &wrqu->data;
2066 len = p->length;
2067 ptmp = kmalloc(len, GFP_KERNEL);
2068 if (!ptmp)
2069 return -ENOMEM;
2070
2071 if (copy_from_user(ptmp, p->pointer, len)) {
2072 kfree(ptmp);
2073 return -EFAULT;
2074 }
2075
2076 bytes = 0;
2077 addr = 0;
2078 sscanf(ptmp, "%d,%x", &bytes, &addr);
2079
2080 switch (bytes) {
2081 case 1:
2082 data32 = rtw_read8(padapter, addr);
2083 sprintf(extra, "0x%02X", data32);
2084 break;
2085 case 2:
2086 data32 = rtw_read16(padapter, addr);
2087 sprintf(extra, "0x%04X", data32);
2088 break;
2089 case 4:
2090 data32 = rtw_read32(padapter, addr);
2091 sprintf(extra, "0x%08X", data32);
2092 break;
2093 default:
2094 DBG_88E(KERN_INFO "%s: usage> read [bytes],[address(hex)]\n", __func__);
2095 return -EINVAL;
2096 }
2097 DBG_88E(KERN_INFO "%s: addr = 0x%08X data =%s\n", __func__, addr, extra);
2098
2099 kfree(ptmp);
2100 return 0;
2101}
2102
2103static int rtw_wx_write32(struct net_device *dev,
2104 struct iw_request_info *info,
2105 union iwreq_data *wrqu, char *extra)
2106{
2107 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2108
2109 u32 addr;
2110 u32 data32;
2111 u32 bytes;
2112
2113 bytes = 0;
2114 addr = 0;
2115 data32 = 0;
2116 sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
2117
2118 switch (bytes) {
2119 case 1:
2120 rtw_write8(padapter, addr, (u8)data32);
2121 DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%02X\n", __func__, addr, (u8)data32);
2122 break;
2123 case 2:
2124 rtw_write16(padapter, addr, (u16)data32);
2125 DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%04X\n", __func__, addr, (u16)data32);
2126 break;
2127 case 4:
2128 rtw_write32(padapter, addr, data32);
2129 DBG_88E(KERN_INFO "%s: addr = 0x%08X data = 0x%08X\n", __func__, addr, data32);
2130 break;
2131 default:
2132 DBG_88E(KERN_INFO "%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);
2133 return -EINVAL;
2134 }
2135
2136 return 0;
2137}
2138
2139static int rtw_wx_read_rf(struct net_device *dev,
2140 struct iw_request_info *info,
2141 union iwreq_data *wrqu, char *extra)
2142{
2143 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2144 u32 path, addr, data32;
2145
2146 path = *(u32 *)extra;
2147 addr = *((u32 *)extra + 1);
2148 data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);
2149
2150
2151
2152
2153
2154 sprintf(extra, "0x%05x", data32);
2155
2156 return 0;
2157}
2158
2159static int rtw_wx_write_rf(struct net_device *dev,
2160 struct iw_request_info *info,
2161 union iwreq_data *wrqu, char *extra)
2162{
2163 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2164 u32 path, addr, data32;
2165
2166 path = *(u32 *)extra;
2167 addr = *((u32 *)extra + 1);
2168 data32 = *((u32 *)extra + 2);
2169 rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);
2170
2171 return 0;
2172}
2173
2174static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
2175 union iwreq_data *wrqu, char *b)
2176{
2177 return -1;
2178}
2179
2180static int dummy(struct net_device *dev, struct iw_request_info *a,
2181 union iwreq_data *wrqu, char *b)
2182{
2183 return -1;
2184}
2185
2186static int rtw_wx_set_channel_plan(struct net_device *dev,
2187 struct iw_request_info *info,
2188 union iwreq_data *wrqu, char *extra)
2189{
2190 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2191 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2192 u8 channel_plan_req = (u8)(*((int *)wrqu));
2193
2194 if (_SUCCESS == rtw_set_chplan_cmd(padapter, channel_plan_req, 1))
2195 DBG_88E("%s set channel_plan = 0x%02X\n", __func__, pmlmepriv->ChannelPlan);
2196 else
2197 return -EPERM;
2198
2199 return 0;
2200}
2201
2202static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
2203 struct iw_request_info *a,
2204 union iwreq_data *wrqu, char *b)
2205{
2206 return 0;
2207}
2208
2209static int rtw_wx_get_sensitivity(struct net_device *dev,
2210 struct iw_request_info *info,
2211 union iwreq_data *wrqu, char *buf)
2212{
2213 return 0;
2214}
2215
2216static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
2217 struct iw_request_info *info,
2218 union iwreq_data *wrqu, char *extra)
2219{
2220 return 0;
2221}
2222
2223
2224
2225
2226
2227static int rtw_drvext_hdl(struct net_device *dev, struct iw_request_info *info,
2228 union iwreq_data *wrqu, char *extra)
2229{
2230 return 0;
2231}
2232
2233static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 len)
2234{
2235 struct mp_rw_reg *RegRWStruct;
2236 struct rf_reg_param *prfreg;
2237 u8 path;
2238 u8 offset;
2239 u32 value;
2240
2241 DBG_88E("%s\n", __func__);
2242
2243 switch (id) {
2244 case GEN_MP_IOCTL_SUBCODE(MP_START):
2245 DBG_88E("871x_driver is only for normal mode, can't enter mp mode\n");
2246 break;
2247 case GEN_MP_IOCTL_SUBCODE(READ_REG):
2248 RegRWStruct = (struct mp_rw_reg *)pdata;
2249 switch (RegRWStruct->width) {
2250 case 1:
2251 RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
2252 break;
2253 case 2:
2254 RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
2255 break;
2256 case 4:
2257 RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
2258 break;
2259 default:
2260 break;
2261 }
2262
2263 break;
2264 case GEN_MP_IOCTL_SUBCODE(WRITE_REG):
2265 RegRWStruct = (struct mp_rw_reg *)pdata;
2266 switch (RegRWStruct->width) {
2267 case 1:
2268 rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value);
2269 break;
2270 case 2:
2271 rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value);
2272 break;
2273 case 4:
2274 rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value);
2275 break;
2276 default:
2277 break;
2278 }
2279
2280 break;
2281 case GEN_MP_IOCTL_SUBCODE(READ_RF_REG):
2282
2283 prfreg = (struct rf_reg_param *)pdata;
2284
2285 path = (u8)prfreg->path;
2286 offset = (u8)prfreg->offset;
2287
2288 value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff);
2289
2290 prfreg->value = value;
2291
2292 break;
2293 case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG):
2294
2295 prfreg = (struct rf_reg_param *)pdata;
2296
2297 path = (u8)prfreg->path;
2298 offset = (u8)prfreg->offset;
2299 value = prfreg->value;
2300
2301 rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value);
2302
2303 break;
2304 case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO):
2305 DBG_88E("==> trigger gpio 0\n");
2306 rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, NULL);
2307 break;
2308 case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS):
2309 *pdata = rtw_hal_sreset_get_wifi_status(padapter);
2310 break;
2311 default:
2312 break;
2313 }
2314}
2315
2316static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info,
2317 union iwreq_data *wrqu, char *extra)
2318{
2319 int ret = 0;
2320 u32 BytesRead, BytesWritten, BytesNeeded;
2321 struct oid_par_priv oid_par;
2322 struct mp_ioctl_handler *phandler;
2323 struct mp_ioctl_param *poidparam;
2324 uint status = 0;
2325 u16 len;
2326 u8 *pparmbuf = NULL, bset;
2327 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2328 struct iw_point *p = &wrqu->data;
2329
2330 if ((!p->length) || (!p->pointer)) {
2331 ret = -EINVAL;
2332 goto _rtw_mp_ioctl_hdl_exit;
2333 }
2334 pparmbuf = NULL;
2335 bset = (u8)(p->flags & 0xFFFF);
2336 len = p->length;
2337 pparmbuf = kmalloc(len, GFP_KERNEL);
2338 if (!pparmbuf) {
2339 ret = -ENOMEM;
2340 goto _rtw_mp_ioctl_hdl_exit;
2341 }
2342
2343 if (copy_from_user(pparmbuf, p->pointer, len)) {
2344 ret = -EFAULT;
2345 goto _rtw_mp_ioctl_hdl_exit;
2346 }
2347
2348 poidparam = (struct mp_ioctl_param *)pparmbuf;
2349
2350 if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
2351 ret = -EINVAL;
2352 goto _rtw_mp_ioctl_hdl_exit;
2353 }
2354
2355 if (padapter->registrypriv.mp_mode == 1) {
2356 phandler = mp_ioctl_hdl + poidparam->subcode;
2357
2358 if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize)) {
2359 ret = -EINVAL;
2360 goto _rtw_mp_ioctl_hdl_exit;
2361 }
2362
2363 if (phandler->handler) {
2364 oid_par.adapter_context = padapter;
2365 oid_par.oid = phandler->oid;
2366 oid_par.information_buf = poidparam->data;
2367 oid_par.information_buf_len = poidparam->len;
2368 oid_par.dbg = 0;
2369
2370 BytesWritten = 0;
2371 BytesNeeded = 0;
2372
2373 if (bset) {
2374 oid_par.bytes_rw = &BytesRead;
2375 oid_par.bytes_needed = &BytesNeeded;
2376 oid_par.type_of_oid = SET_OID;
2377 } else {
2378 oid_par.bytes_rw = &BytesWritten;
2379 oid_par.bytes_needed = &BytesNeeded;
2380 oid_par.type_of_oid = QUERY_OID;
2381 }
2382
2383 status = phandler->handler(&oid_par);
2384 } else {
2385 DBG_88E("rtw_mp_ioctl_hdl(): err!, subcode =%d, oid =%d, handler =%p\n",
2386 poidparam->subcode, phandler->oid, phandler->handler);
2387 ret = -EFAULT;
2388 goto _rtw_mp_ioctl_hdl_exit;
2389 }
2390 } else {
2391 rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len);
2392 }
2393
2394 if (bset == 0x00) {
2395 if (copy_to_user(p->pointer, pparmbuf, len))
2396 ret = -EFAULT;
2397 }
2398
2399 if (status) {
2400 ret = -EFAULT;
2401 goto _rtw_mp_ioctl_hdl_exit;
2402 }
2403
2404_rtw_mp_ioctl_hdl_exit:
2405
2406 kfree(pparmbuf);
2407 return ret;
2408}
2409
2410static int rtw_get_ap_info(struct net_device *dev,
2411 struct iw_request_info *info,
2412 union iwreq_data *wrqu, char *extra)
2413{
2414 int ret = 0;
2415 u32 cnt = 0, wpa_ielen;
2416 struct list_head *plist, *phead;
2417 unsigned char *pbuf;
2418 u8 bssid[ETH_ALEN];
2419 char data[32];
2420 struct wlan_network *pnetwork = NULL;
2421 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2422 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2423 struct __queue *queue = &pmlmepriv->scanned_queue;
2424 struct iw_point *pdata = &wrqu->data;
2425
2426 DBG_88E("+rtw_get_aplist_info\n");
2427
2428 if (padapter->bDriverStopped || !pdata) {
2429 ret = -EINVAL;
2430 goto exit;
2431 }
2432
2433 while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING)))) {
2434 msleep(30);
2435 cnt++;
2436 if (cnt > 100)
2437 break;
2438 }
2439 pdata->flags = 0;
2440 if (pdata->length >= 32) {
2441 if (copy_from_user(data, pdata->pointer, 32)) {
2442 ret = -EINVAL;
2443 goto exit;
2444 }
2445 } else {
2446 ret = -EINVAL;
2447 goto exit;
2448 }
2449
2450 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
2451
2452 phead = get_list_head(queue);
2453 plist = phead->next;
2454
2455 while (phead != plist) {
2456 pnetwork = container_of(plist, struct wlan_network, list);
2457
2458 if (!mac_pton(data, bssid)) {
2459 DBG_88E("Invalid BSSID '%s'.\n", (u8 *)data);
2460 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
2461 return -EINVAL;
2462 }
2463
2464 if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
2465
2466 DBG_88E("BSSID:%pM\n", (bssid));
2467
2468 pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
2469 if (pbuf && (wpa_ielen > 0)) {
2470 pdata->flags = 1;
2471 break;
2472 }
2473
2474 pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
2475 if (pbuf && (wpa_ielen > 0)) {
2476 pdata->flags = 2;
2477 break;
2478 }
2479 }
2480
2481 plist = plist->next;
2482 }
2483
2484 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
2485
2486 if (pdata->length >= 34) {
2487 if (copy_to_user(pdata->pointer + 32, (u8 *)&pdata->flags, 1)) {
2488 ret = -EINVAL;
2489 goto exit;
2490 }
2491 }
2492
2493exit:
2494
2495 return ret;
2496}
2497
2498static int rtw_set_pid(struct net_device *dev,
2499 struct iw_request_info *info,
2500 union iwreq_data *wrqu, char *extra)
2501{
2502 int ret = 0;
2503 struct adapter *padapter = rtw_netdev_priv(dev);
2504 int *pdata = (int *)wrqu;
2505 int selector;
2506
2507 if (padapter->bDriverStopped || !pdata) {
2508 ret = -EINVAL;
2509 goto exit;
2510 }
2511
2512 selector = *pdata;
2513 if (selector < 3 && selector >= 0) {
2514 padapter->pid[selector] = *(pdata + 1);
2515 ui_pid[selector] = *(pdata + 1);
2516 DBG_88E("%s set pid[%d] =%d\n", __func__, selector, padapter->pid[selector]);
2517 } else {
2518 DBG_88E("%s selector %d error\n", __func__, selector);
2519 }
2520exit:
2521 return ret;
2522}
2523
2524static int rtw_wps_start(struct net_device *dev,
2525 struct iw_request_info *info,
2526 union iwreq_data *wrqu, char *extra)
2527{
2528 int ret = 0;
2529 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2530 struct iw_point *pdata = &wrqu->data;
2531 u32 u32wps_start = 0;
2532
2533 if (!pdata)
2534 return -EINVAL;
2535 ret = copy_from_user((void *)&u32wps_start, pdata->pointer, 4);
2536 if (ret) {
2537 ret = -EINVAL;
2538 goto exit;
2539 }
2540
2541 if (padapter->bDriverStopped) {
2542 ret = -EINVAL;
2543 goto exit;
2544 }
2545
2546 if (u32wps_start == 0)
2547 u32wps_start = *extra;
2548
2549 DBG_88E("[%s] wps_start = %d\n", __func__, u32wps_start);
2550
2551 if (u32wps_start == 1)
2552 rtw_led_control(padapter, LED_CTL_START_WPS);
2553 else if (u32wps_start == 2)
2554 rtw_led_control(padapter, LED_CTL_STOP_WPS);
2555 else if (u32wps_start == 3)
2556 rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);
2557
2558exit:
2559 return ret;
2560}
2561
2562#ifdef CONFIG_88EU_P2P
2563static int rtw_wext_p2p_enable(struct net_device *dev,
2564 struct iw_request_info *info,
2565 union iwreq_data *wrqu, char *extra)
2566{
2567 int ret = 0;
2568 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2569 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2570 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2571 enum P2P_ROLE init_role = P2P_ROLE_DISABLE;
2572
2573 if (*extra == '0')
2574 init_role = P2P_ROLE_DISABLE;
2575 else if (*extra == '1')
2576 init_role = P2P_ROLE_DEVICE;
2577 else if (*extra == '2')
2578 init_role = P2P_ROLE_CLIENT;
2579 else if (*extra == '3')
2580 init_role = P2P_ROLE_GO;
2581
2582 if (_FAIL == rtw_p2p_enable(padapter, init_role)) {
2583 ret = -EFAULT;
2584 goto exit;
2585 }
2586
2587
2588 if (init_role != P2P_ROLE_DISABLE) {
2589 u8 channel, ch_offset;
2590 u16 bwmode;
2591
2592 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) {
2593
2594 channel = pwdinfo->listen_channel;
2595 pwdinfo->operating_channel = pwdinfo->listen_channel;
2596 ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2597 bwmode = HT_CHANNEL_WIDTH_20;
2598 } else {
2599 pwdinfo->operating_channel = pmlmeext->cur_channel;
2600
2601 channel = pwdinfo->operating_channel;
2602 ch_offset = pmlmeext->cur_ch_offset;
2603 bwmode = pmlmeext->cur_bwmode;
2604 }
2605
2606 set_channel_bwmode(padapter, channel, ch_offset, bwmode);
2607 }
2608
2609exit:
2610 return ret;
2611}
2612
2613static int rtw_p2p_set_go_nego_ssid(struct net_device *dev,
2614 struct iw_request_info *info,
2615 union iwreq_data *wrqu, char *extra)
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] ssid = %s, len = %zu\n", __func__, extra, strlen(extra));
2622 memcpy(pwdinfo->nego_ssid, extra, strlen(extra));
2623 pwdinfo->nego_ssidlen = strlen(extra);
2624
2625 return ret;
2626}
2627
2628static int rtw_p2p_set_intent(struct net_device *dev,
2629 struct iw_request_info *info,
2630 union iwreq_data *wrqu, char *extra)
2631{
2632 int ret = 0;
2633 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2634 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2635 u8 intent = pwdinfo->intent;
2636
2637 switch (wrqu->data.length) {
2638 case 1:
2639 intent = extra[0] - '0';
2640 break;
2641 case 2:
2642 intent = str_2char2num(extra[0], extra[1]);
2643 break;
2644 }
2645 if (intent <= 15)
2646 pwdinfo->intent = intent;
2647 else
2648 ret = -1;
2649 DBG_88E("[%s] intent = %d\n", __func__, intent);
2650 return ret;
2651}
2652
2653static int rtw_p2p_set_listen_ch(struct net_device *dev,
2654 struct iw_request_info *info,
2655 union iwreq_data *wrqu, char *extra)
2656{
2657 int ret = 0;
2658 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2659 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2660 u8 listen_ch = pwdinfo->listen_channel;
2661
2662 switch (wrqu->data.length) {
2663 case 1:
2664 listen_ch = extra[0] - '0';
2665 break;
2666 case 2:
2667 listen_ch = str_2char2num(extra[0], extra[1]);
2668 break;
2669 }
2670
2671 if ((listen_ch == 1) || (listen_ch == 6) || (listen_ch == 11)) {
2672 pwdinfo->listen_channel = listen_ch;
2673 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
2674 } else {
2675 ret = -1;
2676 }
2677
2678 DBG_88E("[%s] listen_ch = %d\n", __func__, pwdinfo->listen_channel);
2679
2680 return ret;
2681}
2682
2683static int rtw_p2p_set_op_ch(struct net_device *dev,
2684 struct iw_request_info *info,
2685 union iwreq_data *wrqu, char *extra)
2686{
2687
2688
2689
2690 int ret = 0;
2691 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2692 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2693 u8 op_ch = pwdinfo->operating_channel;
2694
2695 switch (wrqu->data.length) {
2696 case 1:
2697 op_ch = extra[0] - '0';
2698 break;
2699 case 2:
2700 op_ch = str_2char2num(extra[0], extra[1]);
2701 break;
2702 }
2703
2704 if (op_ch > 0)
2705 pwdinfo->operating_channel = op_ch;
2706 else
2707 ret = -1;
2708
2709 DBG_88E("[%s] op_ch = %d\n", __func__, pwdinfo->operating_channel);
2710
2711 return ret;
2712}
2713
2714static int rtw_p2p_profilefound(struct net_device *dev,
2715 struct iw_request_info *info,
2716 union iwreq_data *wrqu, char *extra)
2717{
2718 int ret = 0;
2719 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2720 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732 DBG_88E("[%s] In value = %s, len = %d\n", __func__, extra, wrqu->data.length - 1);
2733
2734
2735 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
2736 if (extra[0] == '0') {
2737
2738 memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM);
2739 pwdinfo->profileindex = 0;
2740 } else {
2741 if (pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM) {
2742 ret = -1;
2743 } else {
2744 int jj, kk;
2745
2746
2747
2748 for (jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3)
2749 pwdinfo->profileinfo[pwdinfo->profileindex].peermac[jj] = key_2char2num(extra[kk], extra[kk + 1]);
2750
2751 pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen = (extra[18] - '0') * 10 + (extra[19] - '0');
2752 memcpy(pwdinfo->profileinfo[pwdinfo->profileindex].ssid, &extra[20], pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen);
2753 pwdinfo->profileindex++;
2754 }
2755 }
2756 }
2757
2758 return ret;
2759}
2760
2761static int rtw_p2p_setDN(struct net_device *dev,
2762 struct iw_request_info *info,
2763 union iwreq_data *wrqu, char *extra)
2764{
2765 int ret = 0;
2766 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2767 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2768
2769 DBG_88E("[%s] %s %d\n", __func__, extra, wrqu->data.length - 1);
2770 memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN);
2771 memcpy(pwdinfo->device_name, extra, wrqu->data.length - 1);
2772 pwdinfo->device_name_len = wrqu->data.length - 1;
2773
2774 return ret;
2775}
2776
2777static int rtw_p2p_get_status(struct net_device *dev,
2778 struct iw_request_info *info,
2779 union iwreq_data *wrqu, char *extra)
2780{
2781 int ret = 0;
2782 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2783 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2784
2785 if (padapter->bShowGetP2PState)
2786 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),
2787 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
2788 pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
2789
2790
2791
2792
2793 sprintf(extra, "\n\nStatus =%.2d\n", rtw_p2p_state(pwdinfo));
2794 wrqu->data.length = strlen(extra);
2795
2796 return ret;
2797}
2798
2799
2800
2801
2802
2803
2804static int rtw_p2p_get_req_cm(struct net_device *dev,
2805 struct iw_request_info *info,
2806 union iwreq_data *wrqu, char *extra)
2807{
2808 int ret = 0;
2809 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2810 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2811
2812 sprintf(extra, "\n\nCM =%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);
2813 wrqu->data.length = strlen(extra);
2814 return ret;
2815}
2816
2817static int rtw_p2p_get_role(struct net_device *dev,
2818 struct iw_request_info *info,
2819 union iwreq_data *wrqu, char *extra)
2820{
2821 int ret = 0;
2822 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2823 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2824
2825 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),
2826 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
2827 pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
2828
2829 sprintf(extra, "\n\nRole =%.2d\n", rtw_p2p_role(pwdinfo));
2830 wrqu->data.length = strlen(extra);
2831 return ret;
2832}
2833
2834static int rtw_p2p_get_peer_ifaddr(struct net_device *dev,
2835 struct iw_request_info *info,
2836 union iwreq_data *wrqu, char *extra)
2837{
2838 int ret = 0;
2839 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2840 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2841
2842 DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n", __func__,
2843 rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
2844 pwdinfo->p2p_peer_interface_addr);
2845 sprintf(extra, "\nMAC %pM",
2846 pwdinfo->p2p_peer_interface_addr);
2847 wrqu->data.length = strlen(extra);
2848 return ret;
2849}
2850
2851static int rtw_p2p_get_peer_devaddr(struct net_device *dev,
2852 struct iw_request_info *info,
2853 union iwreq_data *wrqu, char *extra)
2854
2855{
2856 int ret = 0;
2857 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2858 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2859
2860 DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n", __func__,
2861 rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
2862 pwdinfo->rx_prov_disc_info.peerDevAddr);
2863 sprintf(extra, "\n%pM",
2864 pwdinfo->rx_prov_disc_info.peerDevAddr);
2865 wrqu->data.length = strlen(extra);
2866 return ret;
2867}
2868
2869static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev,
2870 struct iw_request_info *info,
2871 union iwreq_data *wrqu, char *extra)
2872
2873{
2874 int ret = 0;
2875 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2876 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2877
2878 DBG_88E("[%s] Role = %d, Status = %d, peer addr = %pM\n",
2879 __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
2880 pwdinfo->p2p_peer_device_addr);
2881 sprintf(extra, "\nMAC %pM",
2882 pwdinfo->p2p_peer_device_addr);
2883 wrqu->data.length = strlen(extra);
2884 return ret;
2885}
2886
2887static int rtw_p2p_get_groupid(struct net_device *dev,
2888 struct iw_request_info *info,
2889 union iwreq_data *wrqu, char *extra)
2890
2891{
2892 int ret = 0;
2893 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2894 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2895
2896 sprintf(extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s",
2897 pwdinfo->groupid_info.go_device_addr[0], pwdinfo->groupid_info.go_device_addr[1],
2898 pwdinfo->groupid_info.go_device_addr[2], pwdinfo->groupid_info.go_device_addr[3],
2899 pwdinfo->groupid_info.go_device_addr[4], pwdinfo->groupid_info.go_device_addr[5],
2900 pwdinfo->groupid_info.ssid);
2901 wrqu->data.length = strlen(extra);
2902 return ret;
2903}
2904
2905static int rtw_p2p_get_op_ch(struct net_device *dev,
2906 struct iw_request_info *info,
2907 union iwreq_data *wrqu, char *extra)
2908
2909{
2910 int ret = 0;
2911 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2912 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2913
2914 DBG_88E("[%s] Op_ch = %02x\n", __func__, pwdinfo->operating_channel);
2915
2916 sprintf(extra, "\n\nOp_ch =%.2d\n", pwdinfo->operating_channel);
2917 wrqu->data.length = strlen(extra);
2918 return ret;
2919}
2920
2921static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
2922 struct iw_request_info *info,
2923 union iwreq_data *wrqu, char *extra)
2924{
2925 int ret = 0;
2926 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2927 u8 peerMAC[ETH_ALEN] = {0x00};
2928 int jj, kk;
2929 u8 peerMACStr[17] = {0x00};
2930 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2931 struct list_head *plist, *phead;
2932 struct __queue *queue = &pmlmepriv->scanned_queue;
2933 struct wlan_network *pnetwork = NULL;
2934 u8 blnMatch = 0;
2935 u16 attr_content = 0;
2936 uint attr_contentlen = 0;
2937
2938 u8 attr_content_str[6 + 17] = {0x00};
2939
2940
2941
2942
2943
2944
2945 DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
2946 if (copy_from_user(peerMACStr, wrqu->data.pointer + 6, 17))
2947 return -EFAULT;
2948
2949 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
2950 peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
2951
2952 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
2953
2954 phead = get_list_head(queue);
2955 plist = phead->next;
2956
2957 while (phead != plist) {
2958 pnetwork = container_of(plist, struct wlan_network, list);
2959 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
2960 u8 *wpsie;
2961 uint wpsie_len = 0;
2962 __be16 be_tmp;
2963
2964
2965 wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len);
2966 if (wpsie) {
2967 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&be_tmp, &attr_contentlen);
2968 if (attr_contentlen) {
2969 attr_content = be16_to_cpu(be_tmp);
2970 sprintf(attr_content_str, "\n\nM =%.4d", attr_content);
2971 blnMatch = 1;
2972 }
2973 }
2974 break;
2975 }
2976 plist = plist->next;
2977 }
2978
2979 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
2980
2981 if (!blnMatch)
2982 sprintf(attr_content_str, "\n\nM = 0000");
2983
2984 if (copy_to_user(wrqu->data.pointer, attr_content_str, 6 + 17))
2985 return -EFAULT;
2986 return ret;
2987}
2988
2989static int rtw_p2p_get_go_device_address(struct net_device *dev,
2990 struct iw_request_info *info,
2991 union iwreq_data *wrqu, char *extra)
2992{
2993 int ret = 0;
2994 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
2995 u8 peerMAC[ETH_ALEN] = {0x00};
2996 int jj, kk;
2997 u8 peerMACStr[17] = {0x00};
2998 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2999 struct list_head *plist, *phead;
3000 struct __queue *queue = &pmlmepriv->scanned_queue;
3001 struct wlan_network *pnetwork = NULL;
3002 u8 blnMatch = 0;
3003 u8 *p2pie;
3004 uint p2pielen = 0, attr_contentlen = 0;
3005 u8 attr_content[100] = {0x00};
3006
3007 u8 go_devadd_str[100 + 10] = {0x00};
3008
3009
3010
3011
3012
3013
3014 DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
3015 if (copy_from_user(peerMACStr, wrqu->data.pointer + 10, 17))
3016 return -EFAULT;
3017
3018 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
3019 peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
3020
3021 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
3022
3023 phead = get_list_head(queue);
3024 plist = phead->next;
3025
3026 while (phead != plist) {
3027 pnetwork = container_of(plist, struct wlan_network, list);
3028 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
3029
3030
3031
3032
3033 p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
3034 if (p2pie) {
3035 while (p2pie) {
3036
3037
3038
3039 memset(attr_content, 0x00, 100);
3040 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
3041
3042 blnMatch = 1;
3043 break;
3044 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
3045
3046 blnMatch = 1;
3047 break;
3048 }
3049
3050
3051 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
3052 }
3053 }
3054 }
3055
3056 plist = plist->next;
3057 }
3058
3059 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
3060
3061 if (!blnMatch)
3062 sprintf(go_devadd_str, "\n\ndev_add = NULL");
3063 else
3064 sprintf(go_devadd_str, "\ndev_add =%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
3065 attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
3066
3067 if (copy_to_user(wrqu->data.pointer, go_devadd_str, 10 + 17))
3068 return -EFAULT;
3069 return ret;
3070}
3071
3072static int rtw_p2p_get_device_type(struct net_device *dev,
3073 struct iw_request_info *info,
3074 union iwreq_data *wrqu, char *extra)
3075{
3076 int ret = 0;
3077 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3078 u8 peerMAC[ETH_ALEN] = {0x00};
3079 int jj, kk;
3080 u8 peerMACStr[17] = {0x00};
3081 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3082 struct list_head *plist, *phead;
3083 struct __queue *queue = &pmlmepriv->scanned_queue;
3084 struct wlan_network *pnetwork = NULL;
3085 u8 blnMatch = 0;
3086 u8 dev_type[8] = {0x00};
3087 uint dev_type_len = 0;
3088 u8 dev_type_str[17 + 9] = {0x00};
3089
3090
3091
3092
3093
3094
3095 DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
3096 if (copy_from_user(peerMACStr, wrqu->data.pointer + 9, 17))
3097 return -EFAULT;
3098
3099 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
3100 peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
3101
3102 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
3103
3104 phead = get_list_head(queue);
3105 plist = phead->next;
3106
3107 while (phead != plist) {
3108 pnetwork = container_of(plist, struct wlan_network, list);
3109 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
3110 u8 *wpsie;
3111 uint wpsie_len = 0;
3112
3113
3114
3115 wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12],
3116 pnetwork->network.IELength - 12,
3117 NULL, &wpsie_len);
3118 if (wpsie) {
3119 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len);
3120 if (dev_type_len) {
3121 u16 type = 0;
3122 __be16 be_tmp;
3123
3124 memcpy(&be_tmp, dev_type, 2);
3125 type = be16_to_cpu(be_tmp);
3126 sprintf(dev_type_str, "\n\nN =%.2d", type);
3127 blnMatch = 1;
3128 }
3129 }
3130 break;
3131 }
3132
3133 plist = plist->next;
3134 }
3135
3136 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
3137
3138 if (!blnMatch)
3139 sprintf(dev_type_str, "\n\nN = 00");
3140
3141 if (copy_to_user(wrqu->data.pointer, dev_type_str, 9 + 17)) {
3142 return -EFAULT;
3143 }
3144
3145 return ret;
3146}
3147
3148static int rtw_p2p_get_device_name(struct net_device *dev,
3149 struct iw_request_info *info,
3150 union iwreq_data *wrqu, char *extra)
3151{
3152 int ret = 0;
3153 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3154 u8 peerMAC[ETH_ALEN] = {0x00};
3155 int jj, kk;
3156 u8 peerMACStr[17] = {0x00};
3157 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3158 struct list_head *plist, *phead;
3159 struct __queue *queue = &pmlmepriv->scanned_queue;
3160 struct wlan_network *pnetwork = NULL;
3161 u8 blnMatch = 0;
3162 u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = {0x00};
3163 uint dev_len = 0;
3164 u8 dev_name_str[WPS_MAX_DEVICE_NAME_LEN + 5] = {0x00};
3165
3166
3167
3168
3169
3170
3171 DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
3172 if (copy_from_user(peerMACStr, wrqu->data.pointer + 5, 17))
3173 return -EFAULT;
3174
3175 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
3176 peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
3177
3178 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
3179
3180 phead = get_list_head(queue);
3181 plist = phead->next;
3182
3183 while (phead != plist) {
3184 pnetwork = container_of(plist, struct wlan_network, list);
3185 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
3186 u8 *wpsie;
3187 uint wpsie_len = 0;
3188
3189
3190 wpsie = rtw_get_wps_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &wpsie_len);
3191 if (wpsie) {
3192 rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
3193 if (dev_len) {
3194 sprintf(dev_name_str, "\n\nN =%s", dev_name);
3195 blnMatch = 1;
3196 }
3197 }
3198 break;
3199 }
3200
3201 plist = plist->next;
3202 }
3203
3204 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
3205
3206 if (!blnMatch)
3207 sprintf(dev_name_str, "\n\nN = 0000");
3208
3209 if (copy_to_user(wrqu->data.pointer, dev_name_str, 5 + ((dev_len > 17) ? dev_len : 17)))
3210 return -EFAULT;
3211 return ret;
3212}
3213
3214static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
3215 struct iw_request_info *info,
3216 union iwreq_data *wrqu, char *extra)
3217{
3218 int ret = 0;
3219 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3220 u8 peerMAC[ETH_ALEN] = {0x00};
3221 int jj, kk;
3222 u8 peerMACStr[17] = {0x00};
3223 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3224 struct list_head *plist, *phead;
3225 struct __queue *queue = &pmlmepriv->scanned_queue;
3226 struct wlan_network *pnetwork = NULL;
3227 u8 blnMatch = 0;
3228 u8 *p2pie;
3229 uint p2pielen = 0, attr_contentlen = 0;
3230 u8 attr_content[2] = {0x00};
3231
3232 u8 inv_proc_str[17 + 8] = {0x00};
3233
3234
3235
3236
3237
3238
3239 DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
3240 if (copy_from_user(peerMACStr, wrqu->data.pointer + 8, 17))
3241 return -EFAULT;
3242
3243 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
3244 peerMAC[jj] = key_2char2num(peerMACStr[kk], peerMACStr[kk + 1]);
3245
3246 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
3247
3248 phead = get_list_head(queue);
3249 plist = phead->next;
3250
3251 while (phead != plist) {
3252 pnetwork = container_of(plist, struct wlan_network, list);
3253 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
3254
3255
3256
3257
3258 p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
3259 if (p2pie) {
3260 while (p2pie) {
3261 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen)) {
3262
3263 blnMatch = 1;
3264 break;
3265 }
3266
3267
3268 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
3269 }
3270 }
3271 }
3272 plist = plist->next;
3273 }
3274
3275 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
3276
3277 if (!blnMatch) {
3278 sprintf(inv_proc_str, "\nIP =-1");
3279 } else {
3280 if (attr_content[0] & 0x20)
3281 sprintf(inv_proc_str, "\nIP = 1");
3282 else
3283 sprintf(inv_proc_str, "\nIP = 0");
3284 }
3285 if (copy_to_user(wrqu->data.pointer, inv_proc_str, 8 + 17))
3286 return -EFAULT;
3287 return ret;
3288}
3289
3290static int rtw_p2p_connect(struct net_device *dev,
3291 struct iw_request_info *info,
3292 union iwreq_data *wrqu, char *extra)
3293{
3294 int ret = 0;
3295 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3296 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3297 u8 peerMAC[ETH_ALEN] = {0x00};
3298 int jj, kk;
3299 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3300 struct list_head *plist, *phead;
3301 struct __queue *queue = &pmlmepriv->scanned_queue;
3302 struct wlan_network *pnetwork = NULL;
3303 uint uintPeerChannel = 0;
3304
3305
3306
3307
3308
3309
3310
3311
3312 DBG_88E("[%s] data = %s\n", __func__, extra);
3313
3314 if (pwdinfo->p2p_state == P2P_STATE_NONE) {
3315 DBG_88E("[%s] WiFi Direct is disable!\n", __func__);
3316 return ret;
3317 }
3318
3319 if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO)
3320 return -1;
3321
3322 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
3323 peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
3324
3325 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
3326
3327 phead = get_list_head(queue);
3328 plist = phead->next;
3329
3330 while (phead != plist) {
3331 pnetwork = container_of(plist, struct wlan_network, list);
3332 if (!memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
3333 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
3334 break;
3335 }
3336
3337 plist = plist->next;
3338 }
3339
3340 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
3341
3342 if (uintPeerChannel) {
3343 memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info));
3344 memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
3345
3346 pwdinfo->nego_req_info.peer_channel_num[0] = uintPeerChannel;
3347 memcpy(pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN);
3348 pwdinfo->nego_req_info.benable = true;
3349
3350 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
3351 if (rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK) {
3352
3353 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
3354 }
3355
3356 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
3357 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
3358
3359 DBG_88E("[%s] Start PreTx Procedure!\n", __func__);
3360 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
3361 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT);
3362 } else {
3363 DBG_88E("[%s] Not Found in Scanning Queue~\n", __func__);
3364 ret = -1;
3365 }
3366 return ret;
3367}
3368
3369static int rtw_p2p_invite_req(struct net_device *dev,
3370 struct iw_request_info *info,
3371 union iwreq_data *wrqu, char *extra)
3372{
3373 int ret = 0;
3374 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3375 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3376 int jj, kk;
3377 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3378 struct list_head *plist, *phead;
3379 struct __queue *queue = &pmlmepriv->scanned_queue;
3380 struct wlan_network *pnetwork = NULL;
3381 uint uintPeerChannel = 0;
3382 u8 attr_content[50] = {0x00};
3383 u8 *p2pie;
3384 uint p2pielen = 0, attr_contentlen = 0;
3385 struct tx_invite_req_info *pinvite_req_info = &pwdinfo->invitereq_info;
3386
3387
3388
3389
3390
3391
3392
3393 DBG_88E("[%s] data = %s\n", __func__, extra);
3394
3395 if (wrqu->data.length <= 37) {
3396 DBG_88E("[%s] Wrong format!\n", __func__);
3397 return ret;
3398 }
3399
3400 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
3401 DBG_88E("[%s] WiFi Direct is disable!\n", __func__);
3402 return ret;
3403 } else {
3404
3405 pinvite_req_info->benable = false;
3406 memset(pinvite_req_info->go_bssid, 0x00, ETH_ALEN);
3407 memset(pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN);
3408 pinvite_req_info->ssidlen = 0x00;
3409 pinvite_req_info->operating_ch = pwdinfo->operating_channel;
3410 memset(pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN);
3411 pinvite_req_info->token = 3;
3412 }
3413
3414 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
3415 pinvite_req_info->peer_macaddr[jj] = key_2char2num(extra[kk], extra[kk + 1]);
3416
3417 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
3418
3419 phead = get_list_head(queue);
3420 plist = phead->next;
3421
3422 while (phead != plist) {
3423 pnetwork = container_of(plist, struct wlan_network, list);
3424
3425
3426
3427
3428
3429 p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
3430 if (p2pie) {
3431
3432
3433
3434 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
3435
3436 if (!memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
3437 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
3438 break;
3439 }
3440 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
3441
3442 if (!memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
3443 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
3444 break;
3445 }
3446 }
3447 }
3448 plist = plist->next;
3449 }
3450
3451 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
3452
3453 if (uintPeerChannel) {
3454
3455 for (jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3)
3456 pinvite_req_info->go_bssid[jj] = key_2char2num(extra[kk], extra[kk + 1]);
3457
3458
3459 pinvite_req_info->ssidlen = wrqu->data.length - 36;
3460 memcpy(pinvite_req_info->go_ssid, &extra[36], (u32)pinvite_req_info->ssidlen);
3461 pinvite_req_info->benable = true;
3462 pinvite_req_info->peer_ch = uintPeerChannel;
3463
3464 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
3465 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ);
3466
3467 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
3468
3469 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
3470
3471 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT);
3472 } else {
3473 DBG_88E("[%s] NOT Found in the Scanning Queue!\n", __func__);
3474 }
3475 return ret;
3476}
3477
3478static int rtw_p2p_set_persistent(struct net_device *dev,
3479 struct iw_request_info *info,
3480 union iwreq_data *wrqu, char *extra)
3481{
3482 int ret = 0;
3483 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3484 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3485
3486
3487
3488
3489
3490 DBG_88E("[%s] data = %s\n", __func__, extra);
3491
3492 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
3493 DBG_88E("[%s] WiFi Direct is disable!\n", __func__);
3494 return ret;
3495 } else {
3496 if (extra[0] == '0')
3497 pwdinfo->persistent_supported = false;
3498 else if (extra[0] == '1')
3499 pwdinfo->persistent_supported = true;
3500 else
3501 pwdinfo->persistent_supported = false;
3502 }
3503 pr_info("[%s] persistent_supported = %d\n", __func__, pwdinfo->persistent_supported);
3504 return ret;
3505}
3506
3507static int rtw_p2p_prov_disc(struct net_device *dev,
3508 struct iw_request_info *info,
3509 union iwreq_data *wrqu, char *extra)
3510{
3511 int ret = 0;
3512 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3513 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3514 u8 peerMAC[ETH_ALEN] = {0x00};
3515 int jj, kk;
3516 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3517 struct list_head *plist, *phead;
3518 struct __queue *queue = &pmlmepriv->scanned_queue;
3519 struct wlan_network *pnetwork = NULL;
3520 uint uintPeerChannel = 0;
3521 u8 attr_content[100] = {0x00};
3522 u8 *p2pie;
3523 uint p2pielen = 0, attr_contentlen = 0;
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533 DBG_88E("[%s] data = %s\n", __func__, extra);
3534
3535 if (pwdinfo->p2p_state == P2P_STATE_NONE) {
3536 DBG_88E("[%s] WiFi Direct is disable!\n", __func__);
3537 return ret;
3538 } else {
3539
3540 memset(pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN);
3541 memset(pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN);
3542 memset(&pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof(struct ndis_802_11_ssid));
3543 pwdinfo->tx_prov_disc_info.peer_channel_num[0] = 0;
3544 pwdinfo->tx_prov_disc_info.peer_channel_num[1] = 0;
3545 pwdinfo->tx_prov_disc_info.benable = false;
3546 }
3547
3548 for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
3549 peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
3550
3551 if (!memcmp(&extra[18], "display", 7)) {
3552 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
3553 } else if (!memcmp(&extra[18], "keypad", 7)) {
3554 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
3555 } else if (!memcmp(&extra[18], "pbc", 3)) {
3556 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
3557 } else if (!memcmp(&extra[18], "label", 5)) {
3558 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
3559 } else {
3560 DBG_88E("[%s] Unknown WPS config methodn", __func__);
3561 return ret;
3562 }
3563
3564 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
3565
3566 phead = get_list_head(queue);
3567 plist = phead->next;
3568
3569 while (phead != plist) {
3570 if (uintPeerChannel != 0)
3571 break;
3572
3573 pnetwork = container_of(plist, struct wlan_network, list);
3574
3575
3576
3577
3578
3579 p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
3580 if (p2pie) {
3581 while (p2pie) {
3582
3583
3584
3585 if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
3586
3587 if (!memcmp(attr_content, peerMAC, ETH_ALEN)) {
3588 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
3589 break;
3590 }
3591 } else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
3592
3593 if (!memcmp(attr_content, peerMAC, ETH_ALEN)) {
3594 uintPeerChannel = pnetwork->network.Configuration.DSConfig;
3595 break;
3596 }
3597 }
3598
3599
3600 p2pie = rtw_get_p2p_ie(p2pie + p2pielen, pnetwork->network.IELength - 12 - (p2pie - &pnetwork->network.IEs[12] + p2pielen), NULL, &p2pielen);
3601 }
3602 }
3603
3604 plist = plist->next;
3605 }
3606
3607 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
3608
3609 if (uintPeerChannel) {
3610 DBG_88E("[%s] peer channel: %d!\n", __func__, uintPeerChannel);
3611 memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN);
3612 memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN);
3613 pwdinfo->tx_prov_disc_info.peer_channel_num[0] = (u16)uintPeerChannel;
3614 pwdinfo->tx_prov_disc_info.benable = true;
3615 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
3616 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ);
3617
3618 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
3619 memcpy(&pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof(struct ndis_802_11_ssid));
3620 } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
3621 memcpy(pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN);
3622 pwdinfo->tx_prov_disc_info.ssid.SsidLength = P2P_WILDCARD_SSID_LEN;
3623 }
3624
3625 set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
3626
3627 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
3628
3629 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
3630 } else {
3631 DBG_88E("[%s] NOT Found in the Scanning Queue!\n", __func__);
3632 }
3633 return ret;
3634}
3635
3636
3637
3638
3639static int rtw_p2p_got_wpsinfo(struct net_device *dev,
3640 struct iw_request_info *info,
3641 union iwreq_data *wrqu, char *extra)
3642{
3643 int ret = 0;
3644 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3645 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3646
3647 DBG_88E("[%s] data = %s\n", __func__, extra);
3648
3649
3650
3651
3652
3653
3654 if (*extra == '0')
3655 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
3656 else if (*extra == '1')
3657 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN;
3658 else if (*extra == '2')
3659 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN;
3660 else if (*extra == '3')
3661 pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC;
3662 else
3663 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
3664 return ret;
3665}
3666
3667#endif
3668
3669static int rtw_p2p_set(struct net_device *dev,
3670 struct iw_request_info *info,
3671 union iwreq_data *wrqu, char *extra)
3672{
3673 int ret = 0;
3674
3675#ifdef CONFIG_88EU_P2P
3676 DBG_88E("[%s] extra = %s\n", __func__, extra);
3677 if (!memcmp(extra, "enable =", 7)) {
3678 rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]);
3679 } else if (!memcmp(extra, "setDN =", 6)) {
3680 wrqu->data.length -= 6;
3681 rtw_p2p_setDN(dev, info, wrqu, &extra[6]);
3682 } else if (!memcmp(extra, "profilefound =", 13)) {
3683 wrqu->data.length -= 13;
3684 rtw_p2p_profilefound(dev, info, wrqu, &extra[13]);
3685 } else if (!memcmp(extra, "prov_disc =", 10)) {
3686 wrqu->data.length -= 10;
3687 rtw_p2p_prov_disc(dev, info, wrqu, &extra[10]);
3688 } else if (!memcmp(extra, "nego =", 5)) {
3689 wrqu->data.length -= 5;
3690 rtw_p2p_connect(dev, info, wrqu, &extra[5]);
3691 } else if (!memcmp(extra, "intent =", 7)) {
3692
3693
3694
3695 wrqu->data.length -= 8;
3696 rtw_p2p_set_intent(dev, info, wrqu, &extra[7]);
3697 } else if (!memcmp(extra, "ssid =", 5)) {
3698 wrqu->data.length -= 5;
3699 rtw_p2p_set_go_nego_ssid(dev, info, wrqu, &extra[5]);
3700 } else if (!memcmp(extra, "got_wpsinfo =", 12)) {
3701 wrqu->data.length -= 12;
3702 rtw_p2p_got_wpsinfo(dev, info, wrqu, &extra[12]);
3703 } else if (!memcmp(extra, "listen_ch =", 10)) {
3704
3705
3706
3707 wrqu->data.length -= 11;
3708 rtw_p2p_set_listen_ch(dev, info, wrqu, &extra[10]);
3709 } else if (!memcmp(extra, "op_ch =", 6)) {
3710
3711
3712
3713 wrqu->data.length -= 7;
3714 rtw_p2p_set_op_ch(dev, info, wrqu, &extra[6]);
3715 } else if (!memcmp(extra, "invite =", 7)) {
3716 wrqu->data.length -= 8;
3717 rtw_p2p_invite_req(dev, info, wrqu, &extra[7]);
3718 } else if (!memcmp(extra, "persistent =", 11)) {
3719 wrqu->data.length -= 11;
3720 rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]);
3721 }
3722#endif
3723
3724 return ret;
3725}
3726
3727static int rtw_p2p_get(struct net_device *dev,
3728 struct iw_request_info *info,
3729 union iwreq_data *wrqu, char *extra)
3730{
3731 int ret = 0;
3732
3733#ifdef CONFIG_88EU_P2P
3734 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3735
3736 if (padapter->bShowGetP2PState)
3737 DBG_88E("[%s] extra = %s\n", __func__, (char *)wrqu->data.pointer);
3738 if (!memcmp(wrqu->data.pointer, "status", 6)) {
3739 rtw_p2p_get_status(dev, info, wrqu, extra);
3740 } else if (!memcmp(wrqu->data.pointer, "role", 4)) {
3741 rtw_p2p_get_role(dev, info, wrqu, extra);
3742 } else if (!memcmp(wrqu->data.pointer, "peer_ifa", 8)) {
3743 rtw_p2p_get_peer_ifaddr(dev, info, wrqu, extra);
3744 } else if (!memcmp(wrqu->data.pointer, "req_cm", 6)) {
3745 rtw_p2p_get_req_cm(dev, info, wrqu, extra);
3746 } else if (!memcmp(wrqu->data.pointer, "peer_deva", 9)) {
3747
3748 rtw_p2p_get_peer_devaddr(dev, info, wrqu, extra);
3749 } else if (!memcmp(wrqu->data.pointer, "group_id", 8)) {
3750 rtw_p2p_get_groupid(dev, info, wrqu, extra);
3751 } else if (!memcmp(wrqu->data.pointer, "peer_deva_inv", 9)) {
3752
3753 rtw_p2p_get_peer_devaddr_by_invitation(dev, info, wrqu, extra);
3754 } else if (!memcmp(wrqu->data.pointer, "op_ch", 5)) {
3755 rtw_p2p_get_op_ch(dev, info, wrqu, extra);
3756 }
3757#endif
3758 return ret;
3759}
3760
3761static int rtw_p2p_get2(struct net_device *dev,
3762 struct iw_request_info *info,
3763 union iwreq_data *wrqu, char *extra)
3764{
3765 int ret = 0;
3766
3767#ifdef CONFIG_88EU_P2P
3768 DBG_88E("[%s] extra = %s\n", __func__, (char *)wrqu->data.pointer);
3769 if (!memcmp(extra, "wpsCM =", 6)) {
3770 wrqu->data.length -= 6;
3771 rtw_p2p_get_wps_configmethod(dev, info, wrqu, &extra[6]);
3772 } else if (!memcmp(extra, "devN =", 5)) {
3773 wrqu->data.length -= 5;
3774 rtw_p2p_get_device_name(dev, info, wrqu, &extra[5]);
3775 } else if (!memcmp(extra, "dev_type =", 9)) {
3776 wrqu->data.length -= 9;
3777 rtw_p2p_get_device_type(dev, info, wrqu, &extra[9]);
3778 } else if (!memcmp(extra, "go_devadd =", 10)) {
3779 wrqu->data.length -= 10;
3780 rtw_p2p_get_go_device_address(dev, info, wrqu, &extra[10]);
3781 } else if (!memcmp(extra, "InvProc =", 8)) {
3782 wrqu->data.length -= 8;
3783 rtw_p2p_get_invitation_procedure(dev, info, wrqu, &extra[8]);
3784 }
3785
3786#endif
3787
3788 return ret;
3789}
3790
3791static int rtw_cta_test_start(struct net_device *dev,
3792 struct iw_request_info *info,
3793 union iwreq_data *wrqu, char *extra)
3794{
3795 int ret = 0;
3796 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3797 DBG_88E("%s %s\n", __func__, extra);
3798 if (!strcmp(extra, "1"))
3799 padapter->in_cta_test = 1;
3800 else
3801 padapter->in_cta_test = 0;
3802
3803 if (padapter->in_cta_test) {
3804 u32 v = rtw_read32(padapter, REG_RCR);
3805 v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
3806 rtw_write32(padapter, REG_RCR, v);
3807 DBG_88E("enable RCR_ADF\n");
3808 } else {
3809 u32 v = rtw_read32(padapter, REG_RCR);
3810 v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
3811 rtw_write32(padapter, REG_RCR, v);
3812 DBG_88E("disable RCR_ADF\n");
3813 }
3814 return ret;
3815}
3816
3817static int rtw_rereg_nd_name(struct net_device *dev,
3818 struct iw_request_info *info,
3819 union iwreq_data *wrqu, char *extra)
3820{
3821 int ret = 0;
3822 struct adapter *padapter = rtw_netdev_priv(dev);
3823 struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;
3824 char new_ifname[IFNAMSIZ];
3825
3826 if (rereg_priv->old_ifname[0] == 0) {
3827 char *reg_ifname;
3828 reg_ifname = padapter->registrypriv.if2name;
3829
3830 strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);
3831 rereg_priv->old_ifname[IFNAMSIZ - 1] = 0;
3832 }
3833
3834 if (wrqu->data.length > IFNAMSIZ)
3835 return -EFAULT;
3836
3837 if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ))
3838 return -EFAULT;
3839
3840 if (0 == strcmp(rereg_priv->old_ifname, new_ifname))
3841 return ret;
3842
3843 DBG_88E("%s new_ifname:%s\n", __func__, new_ifname);
3844 ret = rtw_change_ifname(padapter, new_ifname);
3845 if (0 != ret)
3846 goto exit;
3847
3848 if (!memcmp(rereg_priv->old_ifname, "disable%d", 9)) {
3849 padapter->ledpriv.bRegUseLed = rereg_priv->old_bRegUseLed;
3850 rtw_hal_sw_led_init(padapter);
3851 rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode);
3852 }
3853
3854 strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
3855 rereg_priv->old_ifname[IFNAMSIZ - 1] = 0;
3856
3857 if (!memcmp(new_ifname, "disable%d", 9)) {
3858 DBG_88E("%s disable\n", __func__);
3859
3860 rtw_free_network_queue(padapter, true);
3861
3862
3863 rtw_led_control(padapter, LED_CTL_POWER_OFF);
3864 rereg_priv->old_bRegUseLed = padapter->ledpriv.bRegUseLed;
3865 padapter->ledpriv.bRegUseLed = false;
3866 rtw_hal_sw_led_deinit(padapter);
3867
3868
3869 rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv);
3870 rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL);
3871 }
3872exit:
3873 return ret;
3874}
3875
3876static void mac_reg_dump(struct adapter *padapter)
3877{
3878 int i, j = 1;
3879 pr_info("\n ======= MAC REG =======\n");
3880 for (i = 0x0; i < 0x300; i += 4) {
3881 if (j % 4 == 1)
3882 pr_info("0x%02x", i);
3883 pr_info(" 0x%08x ", rtw_read32(padapter, i));
3884 if ((j++) % 4 == 0)
3885 pr_info("\n");
3886 }
3887 for (i = 0x400; i < 0x800; i += 4) {
3888 if (j % 4 == 1)
3889 pr_info("0x%02x", i);
3890 pr_info(" 0x%08x ", rtw_read32(padapter, i));
3891 if ((j++) % 4 == 0)
3892 pr_info("\n");
3893 }
3894}
3895
3896static void bb_reg_dump(struct adapter *padapter)
3897{
3898 int i, j = 1;
3899 pr_info("\n ======= BB REG =======\n");
3900 for (i = 0x800; i < 0x1000; i += 4) {
3901 if (j % 4 == 1)
3902 pr_info("0x%02x", i);
3903
3904 pr_info(" 0x%08x ", rtw_read32(padapter, i));
3905 if ((j++) % 4 == 0)
3906 pr_info("\n");
3907 }
3908}
3909
3910static void rf_reg_dump(struct adapter *padapter)
3911{
3912 int i, j = 1, path;
3913 u32 value;
3914 u8 rf_type, path_nums = 0;
3915 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
3916
3917 pr_info("\n ======= RF REG =======\n");
3918 if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type))
3919 path_nums = 1;
3920 else
3921 path_nums = 2;
3922
3923 for (path = 0; path < path_nums; path++) {
3924 pr_info("\nRF_Path(%x)\n", path);
3925 for (i = 0; i < 0x100; i++) {
3926 value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
3927 if (j % 4 == 1)
3928 pr_info("0x%02x ", i);
3929 pr_info(" 0x%08x ", value);
3930 if ((j++) % 4 == 0)
3931 pr_info("\n");
3932 }
3933 }
3934}
3935
3936static int rtw_dbg_port(struct net_device *dev,
3937 struct iw_request_info *info,
3938 union iwreq_data *wrqu, char *extra)
3939{
3940 int ret = 0;
3941 u8 major_cmd, minor_cmd;
3942 u16 arg;
3943 s32 extra_arg;
3944 u32 *pdata, val32;
3945 struct sta_info *psta;
3946 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3947 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3948 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3949 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3950 struct security_priv *psecuritypriv = &padapter->securitypriv;
3951 struct wlan_network *cur_network = &pmlmepriv->cur_network;
3952 struct sta_priv *pstapriv = &padapter->stapriv;
3953
3954 pdata = (u32 *)&wrqu->data;
3955
3956 val32 = *pdata;
3957 arg = (u16)(val32 & 0x0000ffff);
3958 major_cmd = (u8)(val32 >> 24);
3959 minor_cmd = (u8)((val32 >> 16) & 0x00ff);
3960
3961 extra_arg = *(pdata + 1);
3962
3963 switch (major_cmd) {
3964 case 0x70:
3965 switch (minor_cmd) {
3966 case 1:
3967 DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
3968 break;
3969 case 2:
3970 DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
3971 break;
3972 case 4:
3973 DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
3974 break;
3975 }
3976 break;
3977 case 0x71:
3978 switch (minor_cmd) {
3979 case 1:
3980 rtw_write8(padapter, arg, extra_arg);
3981 DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
3982 break;
3983 case 2:
3984 rtw_write16(padapter, arg, extra_arg);
3985 DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
3986 break;
3987 case 4:
3988 rtw_write32(padapter, arg, extra_arg);
3989 DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
3990 break;
3991 }
3992 break;
3993 case 0x72:
3994 DBG_88E("read_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
3995 break;
3996 case 0x73:
3997 rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);
3998 DBG_88E("write_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
3999 break;
4000 case 0x74:
4001 DBG_88E("read RF_reg path(0x%02x), offset(0x%x), value(0x%08x)\n", minor_cmd, arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff));
4002 break;
4003 case 0x75:
4004 rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
4005 DBG_88E("write RF_reg path(0x%02x), offset(0x%x), value(0x%08x)\n", minor_cmd, arg, rtw_hal_read_rfreg(padapter, minor_cmd, arg, 0xffffffff));
4006 break;
4007
4008 case 0x76:
4009 switch (minor_cmd) {
4010 case 0x00:
4011 padapter->recvpriv.is_signal_dbg = 0;
4012 break;
4013 case 0x01:
4014 padapter->recvpriv.is_signal_dbg = 1;
4015 extra_arg = extra_arg > 100 ? 100 : extra_arg;
4016 extra_arg = extra_arg < 0 ? 0 : extra_arg;
4017 padapter->recvpriv.signal_strength_dbg = extra_arg;
4018 break;
4019 }
4020 break;
4021 case 0x78:
4022 switch (minor_cmd) {
4023 case 0x04:
4024 {
4025 u8 page_boundary = 0xf9;
4026 struct xmit_frame *xmit_frame;
4027
4028 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
4029 if (!xmit_frame) {
4030 ret = -ENOMEM;
4031 break;
4032 }
4033
4034 rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary);
4035
4036 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500, 0))
4037 ret = -EPERM;
4038 }
4039 break;
4040 case 0x05:
4041 {
4042 u16 reg = 0x4c;
4043 u32 blink_num = 50;
4044 u32 blink_delay_ms = 200;
4045 int i;
4046 struct xmit_frame *xmit_frame;
4047
4048 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
4049 if (!xmit_frame) {
4050 ret = -ENOMEM;
4051 break;
4052 }
4053
4054 for (i = 0; i < blink_num; i++) {
4055 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00, 0xff);
4056 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
4057 rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08, 0xff);
4058 rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
4059 }
4060 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms * blink_num * 2) + 200, 0))
4061 ret = -EPERM;
4062 }
4063 break;
4064
4065 case 0x06:
4066 {
4067 u16 reg = arg;
4068 u16 start_value = 0;
4069 u32 write_num = extra_arg;
4070 int i;
4071 u8 final;
4072 struct xmit_frame *xmit_frame;
4073
4074 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
4075 if (!xmit_frame) {
4076 ret = -ENOMEM;
4077 break;
4078 }
4079
4080 for (i = 0; i < write_num; i++)
4081 rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value, 0xFF);
4082 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
4083 ret = -EPERM;
4084
4085 final = rtw_read8(padapter, reg);
4086 if (start_value + write_num - 1 == final)
4087 DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
4088 else
4089 DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
4090 }
4091 break;
4092
4093 case 0x07:
4094 {
4095 u16 reg = arg;
4096 u16 start_value = 200;
4097 u32 write_num = extra_arg;
4098
4099 int i;
4100 u16 final;
4101 struct xmit_frame *xmit_frame;
4102
4103 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
4104 if (!xmit_frame) {
4105 ret = -ENOMEM;
4106 break;
4107 }
4108
4109 for (i = 0; i < write_num; i++)
4110 rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value, 0xFFFF);
4111 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
4112 ret = -EPERM;
4113
4114 final = rtw_read16(padapter, reg);
4115 if (start_value + write_num - 1 == final)
4116 DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
4117 else
4118 DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
4119 }
4120 break;
4121 case 0x08:
4122 {
4123 u16 reg = arg;
4124 u32 start_value = 0x110000c7;
4125 u32 write_num = extra_arg;
4126
4127 int i;
4128 u32 final;
4129 struct xmit_frame *xmit_frame;
4130
4131 xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
4132 if (!xmit_frame) {
4133 ret = -ENOMEM;
4134 break;
4135 }
4136
4137 for (i = 0; i < write_num; i++)
4138 rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value, 0xFFFFFFFF);
4139 if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
4140 ret = -EPERM;
4141
4142 final = rtw_read32(padapter, reg);
4143 if (start_value + write_num - 1 == final)
4144 DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n",
4145 reg, write_num, start_value, final);
4146 else
4147 DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n",
4148 reg, write_num, start_value, final);
4149 }
4150 break;
4151 }
4152 break;
4153 case 0x79:
4154 {
4155
4156
4157
4158
4159 u8 value = extra_arg & 0x0f;
4160 u8 sign = minor_cmd;
4161 u16 write_value = 0;
4162
4163 DBG_88E("%s set RESP_TXAGC to %s %u\n", __func__, sign ? "minus" : "plus", value);
4164
4165 if (sign)
4166 value = value | 0x10;
4167
4168 write_value = value | (value << 5);
4169 rtw_write16(padapter, 0x6d9, write_value);
4170 }
4171 break;
4172 case 0x7a:
4173 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
4174 , WLAN_REASON_EXPIRATION_CHK);
4175 break;
4176 case 0x7F:
4177 switch (minor_cmd) {
4178 case 0x0:
4179 DBG_88E("fwstate = 0x%x\n", get_fwstate(pmlmepriv));
4180 break;
4181 case 0x01:
4182 DBG_88E("auth_alg = 0x%x, enc_alg = 0x%x, auth_type = 0x%x, enc_type = 0x%x\n",
4183 psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
4184 psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
4185 break;
4186 case 0x02:
4187 DBG_88E("pmlmeinfo->state = 0x%x\n", pmlmeinfo->state);
4188 break;
4189 case 0x03:
4190 DBG_88E("qos_option =%d\n", pmlmepriv->qospriv.qos_option);
4191 DBG_88E("ht_option =%d\n", pmlmepriv->htpriv.ht_option);
4192 break;
4193 case 0x04:
4194 DBG_88E("cur_ch =%d\n", pmlmeext->cur_channel);
4195 DBG_88E("cur_bw =%d\n", pmlmeext->cur_bwmode);
4196 DBG_88E("cur_ch_off =%d\n", pmlmeext->cur_ch_offset);
4197 break;
4198 case 0x05:
4199 psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
4200 if (psta) {
4201 int i;
4202 struct recv_reorder_ctrl *preorder_ctrl;
4203
4204 DBG_88E("SSID =%s\n", cur_network->network.Ssid.Ssid);
4205 DBG_88E("sta's macaddr: %pM\n", psta->hwaddr);
4206 DBG_88E("cur_channel =%d, cur_bwmode =%d, cur_ch_offset =%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
4207 DBG_88E("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self);
4208 DBG_88E("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
4209 DBG_88E("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
4210 DBG_88E("bwmode =%d, ch_offset =%d, sgi =%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
4211 DBG_88E("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
4212 DBG_88E("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
4213 for (i = 0; i < 16; i++) {
4214 preorder_ctrl = &psta->recvreorder_ctrl[i];
4215 if (preorder_ctrl->enable)
4216 DBG_88E("tid =%d, indicate_seq =%d\n", i, preorder_ctrl->indicate_seq);
4217 }
4218 } else {
4219 DBG_88E("can't get sta's macaddr, cur_network's macaddr:%pM\n", (cur_network->network.MacAddress));
4220 }
4221 break;
4222 case 0x06:
4223 {
4224 u32 ODMFlag;
4225 rtw_hal_get_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
4226 DBG_88E("(B)DMFlag = 0x%x, arg = 0x%x\n", ODMFlag, arg);
4227 ODMFlag = (u32)(0x0f & arg);
4228 DBG_88E("(A)DMFlag = 0x%x\n", ODMFlag);
4229 rtw_hal_set_hwreg(padapter, HW_VAR_DM_FLAG, (u8 *)(&ODMFlag));
4230 }
4231 break;
4232 case 0x07:
4233 DBG_88E("bSurpriseRemoved =%d, bDriverStopped =%d\n",
4234 padapter->bSurpriseRemoved, padapter->bDriverStopped);
4235 break;
4236 case 0x08:
4237 {
4238 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4239 struct recv_priv *precvpriv = &padapter->recvpriv;
4240
4241 DBG_88E("free_xmitbuf_cnt =%d, free_xmitframe_cnt =%d, free_xmit_extbuf_cnt =%d\n",
4242 pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmit_extbuf_cnt);
4243 DBG_88E("rx_urb_pending_cn =%d\n", precvpriv->rx_pending_cnt);
4244 }
4245 break;
4246 case 0x09:
4247 {
4248 int i, j;
4249 struct list_head *plist, *phead;
4250 struct recv_reorder_ctrl *preorder_ctrl;
4251
4252#ifdef CONFIG_88EU_AP_MODE
4253 DBG_88E("sta_dz_bitmap = 0x%x, tim_bitmap = 0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
4254#endif
4255 spin_lock_bh(&pstapriv->sta_hash_lock);
4256
4257 for (i = 0; i < NUM_STA; i++) {
4258 phead = &pstapriv->sta_hash[i];
4259 plist = phead->next;
4260
4261 while (phead != plist) {
4262 psta = container_of(plist, struct sta_info, hash_list);
4263
4264 plist = plist->next;
4265
4266 if (extra_arg == psta->aid) {
4267 DBG_88E("sta's macaddr:%pM\n", (psta->hwaddr));
4268 DBG_88E("rtsen =%d, cts2slef =%d\n", psta->rtsen, psta->cts2self);
4269 DBG_88E("state = 0x%x, aid =%d, macid =%d, raid =%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
4270 DBG_88E("qos_en =%d, ht_en =%d, init_rate =%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
4271 DBG_88E("bwmode =%d, ch_offset =%d, sgi =%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
4272 DBG_88E("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
4273 DBG_88E("agg_enable_bitmap =%x, candidate_tid_bitmap =%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
4274
4275#ifdef CONFIG_88EU_AP_MODE
4276 DBG_88E("capability = 0x%x\n", psta->capability);
4277 DBG_88E("flags = 0x%x\n", psta->flags);
4278 DBG_88E("wpa_psk = 0x%x\n", psta->wpa_psk);
4279 DBG_88E("wpa2_group_cipher = 0x%x\n", psta->wpa2_group_cipher);
4280 DBG_88E("wpa2_pairwise_cipher = 0x%x\n", psta->wpa2_pairwise_cipher);
4281 DBG_88E("qos_info = 0x%x\n", psta->qos_info);
4282#endif
4283 DBG_88E("dot118021XPrivacy = 0x%x\n", psta->dot118021XPrivacy);
4284
4285 for (j = 0; j < 16; j++) {
4286 preorder_ctrl = &psta->recvreorder_ctrl[j];
4287 if (preorder_ctrl->enable)
4288 DBG_88E("tid =%d, indicate_seq =%d\n", j, preorder_ctrl->indicate_seq);
4289 }
4290 }
4291 }
4292 }
4293 spin_unlock_bh(&pstapriv->sta_hash_lock);
4294 }
4295 break;
4296 case 0x0c:
4297 if (arg == 0) {
4298 DBG_88E("dump rx packet (%d)\n", extra_arg);
4299 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
4300 } else if (arg == 1) {
4301 DBG_88E("dump tx packet (%d)\n", extra_arg);
4302 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
4303 }
4304 break;
4305 case 0x0f:
4306 if (extra_arg == 0) {
4307 DBG_88E("###### silent reset test.......#####\n");
4308 rtw_hal_sreset_reset(padapter);
4309 }
4310 break;
4311 case 0x15:
4312 {
4313 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
4314 DBG_88E("==>silent resete cnts:%d\n", pwrpriv->ips_enter_cnts);
4315 }
4316 break;
4317 case 0x10:
4318 DBG_88E("rtw driver version =%s\n", DRIVERVERSION);
4319 break;
4320 case 0x11:
4321 DBG_88E("turn %s Rx RSSI display function\n", (extra_arg == 1) ? "on" : "off");
4322 padapter->bRxRSSIDisplay = extra_arg;
4323 break;
4324 case 0x12:
4325 {
4326 struct registry_priv *pregpriv = &padapter->registrypriv;
4327
4328
4329 if (pregpriv &&
4330 (extra_arg == 0 ||
4331 extra_arg == 1 ||
4332 extra_arg == 2 ||
4333 extra_arg == 3)) {
4334 pregpriv->rx_stbc = extra_arg;
4335 DBG_88E("set rx_stbc =%d\n", pregpriv->rx_stbc);
4336 } else {
4337 DBG_88E("get rx_stbc =%d\n", pregpriv->rx_stbc);
4338 }
4339 }
4340 break;
4341 case 0x13:
4342 {
4343 struct registry_priv *pregpriv = &padapter->registrypriv;
4344
4345 if (pregpriv && extra_arg >= 0 && extra_arg < 3) {
4346 pregpriv->ampdu_enable = extra_arg;
4347 DBG_88E("set ampdu_enable =%d\n", pregpriv->ampdu_enable);
4348 } else {
4349 DBG_88E("get ampdu_enable =%d\n", pregpriv->ampdu_enable);
4350 }
4351 }
4352 break;
4353 case 0x14:
4354 {
4355 struct registry_priv *pregpriv = &padapter->registrypriv;
4356 DBG_88E("get wifi_spec =%d\n", pregpriv->wifi_spec);
4357 }
4358 break;
4359 case 0x23:
4360 DBG_88E("turn %s the bNotifyChannelChange Variable\n", (extra_arg == 1) ? "on" : "off");
4361 padapter->bNotifyChannelChange = extra_arg;
4362 break;
4363 case 0x24:
4364#ifdef CONFIG_88EU_P2P
4365 DBG_88E("turn %s the bShowGetP2PState Variable\n", (extra_arg == 1) ? "on" : "off");
4366 padapter->bShowGetP2PState = extra_arg;
4367#endif
4368 break;
4369 case 0xaa:
4370 if (extra_arg > 0x13)
4371 extra_arg = 0xFF;
4372 DBG_88E("chang data rate to :0x%02x\n", extra_arg);
4373 padapter->fix_rate = extra_arg;
4374 break;
4375 case 0xdd:
4376 if (extra_arg == 0)
4377 mac_reg_dump(padapter);
4378 else if (extra_arg == 1)
4379 bb_reg_dump(padapter);
4380 else if (extra_arg == 2)
4381 rf_reg_dump(padapter);
4382 break;
4383 case 0xee:
4384 {
4385 u32 odm_flag;
4386
4387 if (0xf == extra_arg) {
4388 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &odm_flag);
4389 DBG_88E(" === DMFlag(0x%08x) ===\n", odm_flag);
4390 DBG_88E("extra_arg = 0 - disable all dynamic func\n");
4391 DBG_88E("extra_arg = 1 - disable DIG- BIT(0)\n");
4392 DBG_88E("extra_arg = 2 - disable High power - BIT(1)\n");
4393 DBG_88E("extra_arg = 3 - disable tx power tracking - BIT(2)\n");
4394 DBG_88E("extra_arg = 4 - disable BT coexistence - BIT(3)\n");
4395 DBG_88E("extra_arg = 5 - disable antenna diversity - BIT(4)\n");
4396 DBG_88E("extra_arg = 6 - enable all dynamic func\n");
4397 } else {
4398
4399
4400
4401
4402
4403 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &(extra_arg));
4404 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DM_FUNC, &odm_flag);
4405 DBG_88E(" === DMFlag(0x%08x) ===\n", odm_flag);
4406 }
4407 }
4408 break;
4409
4410 case 0xfd:
4411 rtw_write8(padapter, 0xc50, arg);
4412 DBG_88E("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
4413 rtw_write8(padapter, 0xc58, arg);
4414 DBG_88E("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
4415 break;
4416 case 0xfe:
4417 DBG_88E("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
4418 DBG_88E("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
4419 break;
4420 case 0xff:
4421 DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
4422 DBG_88E("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608));
4423 DBG_88E("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280));
4424 DBG_88E("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284));
4425 DBG_88E("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288));
4426
4427 DBG_88E("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664));
4428
4429 DBG_88E("\n");
4430
4431 DBG_88E("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430));
4432 DBG_88E("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438));
4433
4434 DBG_88E("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440));
4435
4436 DBG_88E("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458));
4437
4438 DBG_88E("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484));
4439 DBG_88E("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488));
4440
4441 DBG_88E("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444));
4442 DBG_88E("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448));
4443 DBG_88E("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c));
4444 DBG_88E("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450));
4445 break;
4446 }
4447 break;
4448 default:
4449 DBG_88E("error dbg cmd!\n");
4450 break;
4451 }
4452 return ret;
4453}
4454
4455static int rtw_wx_set_priv(struct net_device *dev,
4456 struct iw_request_info *info,
4457 union iwreq_data *awrq,
4458 char *extra)
4459{
4460 int ret = 0;
4461 int len = 0;
4462 char *ext;
4463 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4464 struct iw_point *dwrq = (struct iw_point *)awrq;
4465
4466 if (dwrq->length == 0)
4467 return -EFAULT;
4468
4469 len = dwrq->length;
4470 ext = vmalloc(len);
4471 if (!ext)
4472 return -ENOMEM;
4473
4474 if (copy_from_user(ext, dwrq->pointer, len)) {
4475 vfree(ext);
4476 return -EFAULT;
4477 }
4478
4479
4480 if (dwrq->flags == 0x8766 && len > 8) {
4481 u32 cp_sz;
4482 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4483 u8 *probereq_wpsie = ext;
4484 int probereq_wpsie_len = len;
4485 u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
4486
4487 if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
4488 (!memcmp(&probereq_wpsie[2], wps_oui, 4))) {
4489 cp_sz = probereq_wpsie_len > MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN : probereq_wpsie_len;
4490
4491 pmlmepriv->wps_probe_req_ie_len = 0;
4492 kfree(pmlmepriv->wps_probe_req_ie);
4493 pmlmepriv->wps_probe_req_ie = NULL;
4494
4495 pmlmepriv->wps_probe_req_ie = kmalloc(cp_sz, GFP_KERNEL);
4496 if (!pmlmepriv->wps_probe_req_ie) {
4497 ret = -EINVAL;
4498 goto FREE_EXT;
4499 }
4500 memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
4501 pmlmepriv->wps_probe_req_ie_len = cp_sz;
4502 }
4503 goto FREE_EXT;
4504 }
4505
4506 if (len >= WEXT_CSCAN_HEADER_SIZE &&
4507 !memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE)) {
4508 ret = rtw_wx_set_scan(dev, info, awrq, ext);
4509 goto FREE_EXT;
4510 }
4511
4512FREE_EXT:
4513
4514 vfree(ext);
4515
4516 return ret;
4517}
4518
4519static int rtw_pm_set(struct net_device *dev,
4520 struct iw_request_info *info,
4521 union iwreq_data *wrqu, char *extra)
4522{
4523 int ret = 0;
4524 unsigned mode = 0;
4525 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
4526
4527 DBG_88E("[%s] extra = %s\n", __func__, extra);
4528
4529 if (!memcmp(extra, "lps =", 4)) {
4530 sscanf(extra + 4, "%u", &mode);
4531 ret = rtw_pm_set_lps(padapter, mode);
4532 } else if (!memcmp(extra, "ips =", 4)) {
4533 sscanf(extra + 4, "%u", &mode);
4534 ret = rtw_pm_set_ips(padapter, mode);
4535 } else {
4536 ret = -EINVAL;
4537 }
4538
4539 return ret;
4540}
4541
4542static int rtw_mp_efuse_get(struct net_device *dev,
4543 struct iw_request_info *info,
4544 union iwreq_data *wdata, char *extra)
4545{
4546 struct adapter *padapter = rtw_netdev_priv(dev);
4547 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
4548 struct hal_data_8188e *haldata = GET_HAL_DATA(padapter);
4549 struct efuse_hal *pEfuseHal;
4550 struct iw_point *wrqu;
4551
4552 u8 *PROMContent = pEEPROM->efuse_eeprom_data;
4553 u8 ips_mode = 0, lps_mode = 0;
4554 struct pwrctrl_priv *pwrctrlpriv;
4555 u8 *data = NULL;
4556 u8 *rawdata = NULL;
4557 char *pch, *ptmp, *token, *tmp[3] = {NULL, NULL, NULL};
4558 u16 i = 0, j = 0, mapLen = 0, addr = 0, cnts = 0;
4559 u16 max_available_size = 0, raw_cursize = 0, raw_maxsize = 0;
4560 int err;
4561 u8 org_fw_iol = padapter->registrypriv.fw_iol;
4562
4563 wrqu = (struct iw_point *)wdata;
4564 pwrctrlpriv = &padapter->pwrctrlpriv;
4565 pEfuseHal = &haldata->EfuseHal;
4566
4567 err = 0;
4568 data = kzalloc(EFUSE_BT_MAX_MAP_LEN, GFP_KERNEL);
4569 if (!data) {
4570 err = -ENOMEM;
4571 goto exit;
4572 }
4573 rawdata = kzalloc(EFUSE_BT_MAX_MAP_LEN, GFP_KERNEL);
4574 if (!rawdata) {
4575 err = -ENOMEM;
4576 goto exit;
4577 }
4578
4579 if (copy_from_user(extra, wrqu->pointer, wrqu->length)) {
4580 err = -EFAULT;
4581 goto exit;
4582 }
4583 lps_mode = pwrctrlpriv->power_mgnt;
4584 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
4585
4586 ips_mode = pwrctrlpriv->ips_mode;
4587 rtw_pm_set_ips(padapter, IPS_NONE);
4588
4589 pch = extra;
4590 DBG_88E("%s: in =%s\n", __func__, extra);
4591
4592 i = 0;
4593
4594 while ((token = strsep(&pch, ",")) != NULL) {
4595 if (i > 2)
4596 break;
4597 tmp[i] = token;
4598 i++;
4599 }
4600 padapter->registrypriv.fw_iol = 0;
4601
4602 if (strcmp(tmp[0], "status") == 0) {
4603 sprintf(extra, "Load File efuse =%s, Load File MAC =%s", (pEEPROM->bloadfile_fail_flag ? "FAIL" : "OK"), (pEEPROM->bloadmac_fail_flag ? "FAIL" : "OK"));
4604
4605 goto exit;
4606 } else if (strcmp(tmp[0], "filemap") == 0) {
4607 mapLen = EFUSE_MAP_SIZE;
4608
4609 sprintf(extra, "\n");
4610 for (i = 0; i < EFUSE_MAP_SIZE; i += 16) {
4611 sprintf(extra + strlen(extra), "0x%02x\t", i);
4612 for (j = 0; j < 8; j++)
4613 sprintf(extra + strlen(extra), "%02X ", PROMContent[i + j]);
4614 sprintf(extra + strlen(extra), "\t");
4615 for (; j < 16; j++)
4616 sprintf(extra + strlen(extra), "%02X ", PROMContent[i + j]);
4617 sprintf(extra + strlen(extra), "\n");
4618 }
4619 } else if (strcmp(tmp[0], "realmap") == 0) {
4620 mapLen = EFUSE_MAP_SIZE;
4621 if (rtw_efuse_map_read(padapter, 0, mapLen, pEfuseHal->fakeEfuseInitMap) == _FAIL) {
4622 DBG_88E("%s: read realmap Fail!!\n", __func__);
4623 err = -EFAULT;
4624 goto exit;
4625 }
4626
4627 sprintf(extra, "\n");
4628 for (i = 0; i < EFUSE_MAP_SIZE; i += 16) {
4629 sprintf(extra + strlen(extra), "0x%02x\t", i);
4630 for (j = 0; j < 8; j++)
4631 sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeEfuseInitMap[i + j]);
4632 sprintf(extra + strlen(extra), "\t");
4633 for (; j < 16; j++)
4634 sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeEfuseInitMap[i + j]);
4635 sprintf(extra + strlen(extra), "\n");
4636 }
4637 } else if (strcmp(tmp[0], "rmap") == 0) {
4638 if (!tmp[1] || !tmp[2]) {
4639 DBG_88E("%s: rmap Fail!! Parameters error!\n", __func__);
4640 err = -EINVAL;
4641 goto exit;
4642 }
4643
4644
4645 addr = simple_strtoul(tmp[1], &ptmp, 16);
4646 DBG_88E("%s: addr =%x\n", __func__, addr);
4647
4648 cnts = simple_strtoul(tmp[2], &ptmp, 10);
4649 if (cnts == 0) {
4650 DBG_88E("%s: rmap Fail!! cnts error!\n", __func__);
4651 err = -EINVAL;
4652 goto exit;
4653 }
4654 DBG_88E("%s: cnts =%d\n", __func__, cnts);
4655
4656 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
4657 if ((addr + cnts) > max_available_size) {
4658 DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
4659 err = -EINVAL;
4660 goto exit;
4661 }
4662
4663 if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) {
4664 DBG_88E("%s: rtw_efuse_map_read error!\n", __func__);
4665 err = -EFAULT;
4666 goto exit;
4667 }
4668
4669 *extra = 0;
4670 for (i = 0; i < cnts; i++)
4671 sprintf(extra + strlen(extra), "0x%02X ", data[i]);
4672 } else if (strcmp(tmp[0], "realraw") == 0) {
4673 addr = 0;
4674 mapLen = EFUSE_MAX_SIZE;
4675 if (rtw_efuse_access(padapter, false, addr, mapLen, rawdata) == _FAIL) {
4676 DBG_88E("%s: rtw_efuse_access Fail!!\n", __func__);
4677 err = -EFAULT;
4678 goto exit;
4679 }
4680
4681 sprintf(extra, "\n");
4682 for (i = 0; i < mapLen; i++) {
4683 sprintf(extra + strlen(extra), "%02X", rawdata[i]);
4684
4685 if ((i & 0xF) == 0xF)
4686 sprintf(extra + strlen(extra), "\n");
4687 else if ((i & 0x7) == 0x7)
4688 sprintf(extra + strlen(extra), "\t");
4689 else
4690 sprintf(extra + strlen(extra), " ");
4691 }
4692 } else if (strcmp(tmp[0], "mac") == 0) {
4693 cnts = 6;
4694
4695 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
4696 if ((addr + cnts) > max_available_size) {
4697 DBG_88E("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __func__, addr, cnts);
4698 err = -EFAULT;
4699 goto exit;
4700 }
4701
4702 if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) {
4703 DBG_88E("%s: rtw_efuse_map_read error!\n", __func__);
4704 err = -EFAULT;
4705 goto exit;
4706 }
4707
4708 *extra = 0;
4709 for (i = 0; i < cnts; i++) {
4710 sprintf(extra + strlen(extra), "%02X", data[i]);
4711 if (i != (cnts - 1))
4712 sprintf(extra + strlen(extra), ":");
4713 }
4714 } else if (strcmp(tmp[0], "vidpid") == 0) {
4715 cnts = 4;
4716
4717 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
4718 if ((addr + cnts) > max_available_size) {
4719 DBG_88E("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __func__, addr, cnts);
4720 err = -EFAULT;
4721 goto exit;
4722 }
4723 if (rtw_efuse_map_read(padapter, addr, cnts, data) == _FAIL) {
4724 DBG_88E("%s: rtw_efuse_access error!!\n", __func__);
4725 err = -EFAULT;
4726 goto exit;
4727 }
4728
4729 *extra = 0;
4730 for (i = 0; i < cnts; i++) {
4731 sprintf(extra + strlen(extra), "0x%02X", data[i]);
4732 if (i != (cnts - 1))
4733 sprintf(extra + strlen(extra), ",");
4734 }
4735 } else if (strcmp(tmp[0], "ableraw") == 0) {
4736 efuse_GetCurrentSize(padapter, &raw_cursize);
4737 raw_maxsize = efuse_GetMaxSize(padapter);
4738 sprintf(extra, "[available raw size] = %d bytes", raw_maxsize - raw_cursize);
4739 } else if (strcmp(tmp[0], "btfmap") == 0) {
4740 mapLen = EFUSE_BT_MAX_MAP_LEN;
4741 if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) {
4742 DBG_88E("%s: rtw_BT_efuse_map_read Fail!!\n", __func__);
4743 err = -EFAULT;
4744 goto exit;
4745 }
4746
4747 sprintf(extra, "\n");
4748 for (i = 0; i < 512; i += 16) {
4749
4750 sprintf(extra + strlen(extra), "0x%03x\t", i);
4751 for (j = 0; j < 8; j++)
4752 sprintf(extra + strlen(extra), "%02X ", pEfuseHal->BTEfuseInitMap[i + j]);
4753 sprintf(extra + strlen(extra), "\t");
4754 for (; j < 16; j++)
4755 sprintf(extra + strlen(extra), "%02X ", pEfuseHal->BTEfuseInitMap[i + j]);
4756 sprintf(extra + strlen(extra), "\n");
4757 }
4758 } else if (strcmp(tmp[0], "btbmap") == 0) {
4759 mapLen = EFUSE_BT_MAX_MAP_LEN;
4760 if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) {
4761 DBG_88E("%s: rtw_BT_efuse_map_read Fail!!\n", __func__);
4762 err = -EFAULT;
4763 goto exit;
4764 }
4765
4766 sprintf(extra, "\n");
4767 for (i = 512; i < 1024; i += 16) {
4768 sprintf(extra + strlen(extra), "0x%03x\t", i);
4769 for (j = 0; j < 8; j++)
4770 sprintf(extra + strlen(extra), "%02X ", pEfuseHal->BTEfuseInitMap[i + j]);
4771 sprintf(extra + strlen(extra), "\t");
4772 for (; j < 16; j++)
4773 sprintf(extra + strlen(extra), "%02X ", pEfuseHal->BTEfuseInitMap[i + j]);
4774 sprintf(extra + strlen(extra), "\n");
4775 }
4776 } else if (strcmp(tmp[0], "btrmap") == 0) {
4777 if (!tmp[1] || !tmp[2]) {
4778 err = -EINVAL;
4779 goto exit;
4780 }
4781
4782
4783 addr = simple_strtoul(tmp[1], &ptmp, 16);
4784 DBG_88E("%s: addr = 0x%X\n", __func__, addr);
4785
4786 cnts = simple_strtoul(tmp[2], &ptmp, 10);
4787 if (cnts == 0) {
4788 DBG_88E("%s: btrmap Fail!! cnts error!\n", __func__);
4789 err = -EINVAL;
4790 goto exit;
4791 }
4792 DBG_88E("%s: cnts =%d\n", __func__, cnts);
4793
4794 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
4795 if ((addr + cnts) > max_available_size) {
4796 DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
4797 err = -EFAULT;
4798 goto exit;
4799 }
4800
4801 if (rtw_BT_efuse_map_read(padapter, addr, cnts, data) == _FAIL) {
4802 DBG_88E("%s: rtw_BT_efuse_map_read error!!\n", __func__);
4803 err = -EFAULT;
4804 goto exit;
4805 }
4806
4807 *extra = 0;
4808 for (i = 0; i < cnts; i++)
4809 sprintf(extra + strlen(extra), " 0x%02X ", data[i]);
4810 } else if (strcmp(tmp[0], "btffake") == 0) {
4811 sprintf(extra, "\n");
4812 for (i = 0; i < 512; i += 16) {
4813 sprintf(extra + strlen(extra), "0x%03x\t", i);
4814 for (j = 0; j < 8; j++)
4815 sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
4816 sprintf(extra + strlen(extra), "\t");
4817 for (; j < 16; j++)
4818 sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
4819 sprintf(extra + strlen(extra), "\n");
4820 }
4821 } else if (strcmp(tmp[0], "btbfake") == 0) {
4822 sprintf(extra, "\n");
4823 for (i = 512; i < 1024; i += 16) {
4824 sprintf(extra + strlen(extra), "0x%03x\t", i);
4825 for (j = 0; j < 8; j++)
4826 sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
4827 sprintf(extra + strlen(extra), "\t");
4828 for (; j < 16; j++)
4829 sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
4830 sprintf(extra + strlen(extra), "\n");
4831 }
4832 } else if (strcmp(tmp[0], "wlrfkmap") == 0) {
4833 sprintf(extra, "\n");
4834 for (i = 0; i < EFUSE_MAP_SIZE; i += 16) {
4835 sprintf(extra + strlen(extra), "0x%02x\t", i);
4836 for (j = 0; j < 8; j++)
4837 sprintf(extra + strlen(extra), "%02X ", pEfuseHal->fakeEfuseModifiedMap[i + j]);
4838 sprintf(extra + strlen(extra), "\t");
4839 for (; j < 16; j++)
4840 sprintf(extra + strlen(extra), " %02X", pEfuseHal->fakeEfuseModifiedMap[i + j]);
4841 sprintf(extra + strlen(extra), "\n");
4842 }
4843 } else {
4844 sprintf(extra, "Command not found!");
4845 }
4846
4847exit:
4848 kfree(data);
4849 kfree(rawdata);
4850 if (!err)
4851 wrqu->length = strlen(extra);
4852
4853 rtw_pm_set_ips(padapter, ips_mode);
4854 rtw_pm_set_lps(padapter, lps_mode);
4855 padapter->registrypriv.fw_iol = org_fw_iol;
4856 return err;
4857}
4858
4859static int rtw_mp_efuse_set(struct net_device *dev,
4860 struct iw_request_info *info,
4861 union iwreq_data *wdata, char *extra)
4862{
4863 struct adapter *padapter;
4864 struct pwrctrl_priv *pwrctrlpriv;
4865 struct hal_data_8188e *haldata;
4866 struct efuse_hal *pEfuseHal;
4867
4868 u8 ips_mode = 0, lps_mode = 0;
4869 u32 i, jj, kk;
4870 u8 *setdata = NULL;
4871 u8 *ShadowMapBT = NULL;
4872 u8 *ShadowMapWiFi = NULL;
4873 u8 *setrawdata = NULL;
4874 char *pch, *ptmp, *token, *tmp[3] = {NULL, NULL, NULL};
4875 u16 addr = 0, cnts = 0, max_available_size = 0;
4876 int err;
4877
4878 padapter = rtw_netdev_priv(dev);
4879 pwrctrlpriv = &padapter->pwrctrlpriv;
4880 haldata = GET_HAL_DATA(padapter);
4881 pEfuseHal = &haldata->EfuseHal;
4882 err = 0;
4883 setdata = kzalloc(1024, GFP_KERNEL);
4884 if (!setdata) {
4885 err = -ENOMEM;
4886 goto exit;
4887 }
4888 ShadowMapBT = kmalloc(EFUSE_BT_MAX_MAP_LEN, GFP_KERNEL);
4889 if (!ShadowMapBT) {
4890 err = -ENOMEM;
4891 goto exit;
4892 }
4893 ShadowMapWiFi = kmalloc(EFUSE_MAP_SIZE, GFP_KERNEL);
4894 if (!ShadowMapWiFi) {
4895 err = -ENOMEM;
4896 goto exit;
4897 }
4898 setrawdata = kmalloc(EFUSE_MAX_SIZE, GFP_KERNEL);
4899 if (!setrawdata) {
4900 err = -ENOMEM;
4901 goto exit;
4902 }
4903
4904 lps_mode = pwrctrlpriv->power_mgnt;
4905 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
4906
4907 ips_mode = pwrctrlpriv->ips_mode;
4908 rtw_pm_set_ips(padapter, IPS_NONE);
4909
4910 pch = extra;
4911 DBG_88E("%s: in =%s\n", __func__, extra);
4912
4913 i = 0;
4914 while ((token = strsep(&pch, ",")) != NULL) {
4915 if (i > 2)
4916 break;
4917 tmp[i] = token;
4918 i++;
4919 }
4920
4921
4922
4923 if (strcmp(tmp[0], "wmap") == 0) {
4924 if (!tmp[1] || !tmp[2]) {
4925 err = -EINVAL;
4926 goto exit;
4927 }
4928
4929 addr = simple_strtoul(tmp[1], &ptmp, 16);
4930 addr &= 0xFFF;
4931
4932 cnts = strlen(tmp[2]);
4933 if (cnts % 2) {
4934 err = -EINVAL;
4935 goto exit;
4936 }
4937 cnts /= 2;
4938 if (cnts == 0) {
4939 err = -EINVAL;
4940 goto exit;
4941 }
4942
4943 DBG_88E("%s: addr = 0x%X\n", __func__, addr);
4944 DBG_88E("%s: cnts =%d\n", __func__, cnts);
4945 DBG_88E("%s: map data =%s\n", __func__, tmp[2]);
4946
4947 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
4948 setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
4949
4950 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_size, false);
4951 if ((addr + cnts) > max_available_size) {
4952 DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
4953 err = -EFAULT;
4954 goto exit;
4955 }
4956
4957 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
4958 DBG_88E("%s: rtw_efuse_map_write error!!\n", __func__);
4959 err = -EFAULT;
4960 goto exit;
4961 }
4962 } else if (strcmp(tmp[0], "wraw") == 0) {
4963 if (!tmp[1] || !tmp[2]) {
4964 err = -EINVAL;
4965 goto exit;
4966 }
4967
4968 addr = simple_strtoul(tmp[1], &ptmp, 16);
4969 addr &= 0xFFF;
4970
4971 cnts = strlen(tmp[2]);
4972 if (cnts % 2) {
4973 err = -EINVAL;
4974 goto exit;
4975 }
4976 cnts /= 2;
4977 if (cnts == 0) {
4978 err = -EINVAL;
4979 goto exit;
4980 }
4981
4982 DBG_88E("%s: addr = 0x%X\n", __func__, addr);
4983 DBG_88E("%s: cnts =%d\n", __func__, cnts);
4984 DBG_88E("%s: raw data =%s\n", __func__, tmp[2]);
4985
4986 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
4987 setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
4988
4989 if (rtw_efuse_access(padapter, true, addr, cnts, setrawdata) == _FAIL) {
4990 DBG_88E("%s: rtw_efuse_access error!!\n", __func__);
4991 err = -EFAULT;
4992 goto exit;
4993 }
4994 } else if (strcmp(tmp[0], "mac") == 0) {
4995 if (!tmp[1]) {
4996 err = -EINVAL;
4997 goto exit;
4998 }
4999
5000
5001 addr = EEPROM_MAC_ADDR_88EU;
5002 cnts = strlen(tmp[1]);
5003 if (cnts % 2) {
5004 err = -EINVAL;
5005 goto exit;
5006 }
5007 cnts /= 2;
5008 if (cnts == 0) {
5009 err = -EINVAL;
5010 goto exit;
5011 }
5012 if (cnts > 6) {
5013 DBG_88E("%s: error data for mac addr =\"%s\"\n", __func__, tmp[1]);
5014 err = -EFAULT;
5015 goto exit;
5016 }
5017
5018 DBG_88E("%s: addr = 0x%X\n", __func__, addr);
5019 DBG_88E("%s: cnts =%d\n", __func__, cnts);
5020 DBG_88E("%s: MAC address =%s\n", __func__, tmp[1]);
5021
5022 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
5023 setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
5024
5025 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_size, false);
5026 if ((addr + cnts) > max_available_size) {
5027 DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
5028 err = -EFAULT;
5029 goto exit;
5030 }
5031
5032 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
5033 DBG_88E("%s: rtw_efuse_map_write error!!\n", __func__);
5034 err = -EFAULT;
5035 goto exit;
5036 }
5037 } else if (strcmp(tmp[0], "vidpid") == 0) {
5038 if (!tmp[1]) {
5039 err = -EINVAL;
5040 goto exit;
5041 }
5042
5043
5044 addr = EEPROM_VID_88EE;
5045 cnts = strlen(tmp[1]);
5046 if (cnts % 2) {
5047 err = -EINVAL;
5048 goto exit;
5049 }
5050 cnts /= 2;
5051 if (cnts == 0) {
5052 err = -EINVAL;
5053 goto exit;
5054 }
5055
5056 DBG_88E("%s: addr = 0x%X\n", __func__, addr);
5057 DBG_88E("%s: cnts =%d\n", __func__, cnts);
5058 DBG_88E("%s: VID/PID =%s\n", __func__, tmp[1]);
5059
5060 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
5061 setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
5062
5063 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
5064 if ((addr + cnts) > max_available_size) {
5065 DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
5066 err = -EFAULT;
5067 goto exit;
5068 }
5069
5070 if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
5071 DBG_88E("%s: rtw_efuse_map_write error!!\n", __func__);
5072 err = -EFAULT;
5073 goto exit;
5074 }
5075 } else if (strcmp(tmp[0], "btwmap") == 0) {
5076 if (!tmp[1] || !tmp[2]) {
5077 err = -EINVAL;
5078 goto exit;
5079 }
5080
5081 addr = simple_strtoul(tmp[1], &ptmp, 16);
5082 addr &= 0xFFF;
5083
5084 cnts = strlen(tmp[2]);
5085 if (cnts % 2) {
5086 err = -EINVAL;
5087 goto exit;
5088 }
5089 cnts /= 2;
5090 if (cnts == 0) {
5091 err = -EINVAL;
5092 goto exit;
5093 }
5094
5095 DBG_88E("%s: addr = 0x%X\n", __func__, addr);
5096 DBG_88E("%s: cnts =%d\n", __func__, cnts);
5097 DBG_88E("%s: BT data =%s\n", __func__, tmp[2]);
5098
5099 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
5100 setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
5101
5102 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
5103 if ((addr + cnts) > max_available_size) {
5104 DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
5105 err = -EFAULT;
5106 goto exit;
5107 }
5108
5109 if (rtw_BT_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
5110 DBG_88E("%s: rtw_BT_efuse_map_write error!!\n", __func__);
5111 err = -EFAULT;
5112 goto exit;
5113 }
5114 } else if (strcmp(tmp[0], "btwfake") == 0) {
5115 if (!tmp[1] || !tmp[2]) {
5116 err = -EINVAL;
5117 goto exit;
5118 }
5119
5120 addr = simple_strtoul(tmp[1], &ptmp, 16);
5121 addr &= 0xFFF;
5122
5123 cnts = strlen(tmp[2]);
5124 if (cnts % 2) {
5125 err = -EINVAL;
5126 goto exit;
5127 }
5128 cnts /= 2;
5129 if (cnts == 0) {
5130 err = -EINVAL;
5131 goto exit;
5132 }
5133
5134 DBG_88E("%s: addr = 0x%X\n", __func__, addr);
5135 DBG_88E("%s: cnts =%d\n", __func__, cnts);
5136 DBG_88E("%s: BT tmp data =%s\n", __func__, tmp[2]);
5137
5138 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
5139 pEfuseHal->fakeBTEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
5140 } else if (strcmp(tmp[0], "btdumpfake") == 0) {
5141 if (rtw_BT_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _SUCCESS) {
5142 DBG_88E("%s: BT read all map success\n", __func__);
5143 } else {
5144 DBG_88E("%s: BT read all map Fail!\n", __func__);
5145 err = -EFAULT;
5146 }
5147 } else if (strcmp(tmp[0], "wldumpfake") == 0) {
5148 if (rtw_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeEfuseModifiedMap) == _SUCCESS) {
5149 DBG_88E("%s: BT read all map success\n", __func__);
5150 } else {
5151 DBG_88E("%s: BT read all map Fail\n", __func__);
5152 err = -EFAULT;
5153 }
5154 } else if (strcmp(tmp[0], "btfk2map") == 0) {
5155 memcpy(pEfuseHal->BTEfuseModifiedMap, pEfuseHal->fakeBTEfuseModifiedMap, EFUSE_BT_MAX_MAP_LEN);
5156
5157 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
5158 if (max_available_size < 1) {
5159 err = -EFAULT;
5160 goto exit;
5161 }
5162
5163 if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL) {
5164 DBG_88E("%s: rtw_BT_efuse_map_write error!\n", __func__);
5165 err = -EFAULT;
5166 goto exit;
5167 }
5168 } else if (strcmp(tmp[0], "wlfk2map") == 0) {
5169 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
5170 if (max_available_size < 1) {
5171 err = -EFAULT;
5172 goto exit;
5173 }
5174
5175 if (rtw_efuse_map_write(padapter, 0x00, EFUSE_MAX_MAP_LEN, pEfuseHal->fakeEfuseModifiedMap) == _FAIL) {
5176 DBG_88E("%s: rtw_efuse_map_write error!\n", __func__);
5177 err = -EFAULT;
5178 goto exit;
5179 }
5180 } else if (strcmp(tmp[0], "wlwfake") == 0) {
5181 if (!tmp[1] || !tmp[2]) {
5182 err = -EINVAL;
5183 goto exit;
5184 }
5185
5186 addr = simple_strtoul(tmp[1], &ptmp, 16);
5187 addr &= 0xFFF;
5188
5189 cnts = strlen(tmp[2]);
5190 if (cnts % 2) {
5191 err = -EINVAL;
5192 goto exit;
5193 }
5194 cnts /= 2;
5195 if (cnts == 0) {
5196 err = -EINVAL;
5197 goto exit;
5198 }
5199
5200 DBG_88E("%s: addr = 0x%X\n", __func__, addr);
5201 DBG_88E("%s: cnts =%d\n", __func__, cnts);
5202 DBG_88E("%s: map tmp data =%s\n", __func__, tmp[2]);
5203
5204 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
5205 pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
5206 }
5207
5208exit:
5209 kfree(setdata);
5210 kfree(ShadowMapBT);
5211 kfree(ShadowMapWiFi);
5212 kfree(setrawdata);
5213
5214 rtw_pm_set_ips(padapter, ips_mode);
5215 rtw_pm_set_lps(padapter, lps_mode);
5216
5217 return err;
5218}
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229static int rtw_mp_write_reg(struct net_device *dev,
5230 struct iw_request_info *info,
5231 struct iw_point *wrqu, char *extra)
5232{
5233 char *pch, *pnext, *ptmp;
5234 char *width_str;
5235 char width;
5236 u32 addr, data;
5237 int ret;
5238 struct adapter *padapter = rtw_netdev_priv(dev);
5239
5240 pch = extra;
5241 pnext = strpbrk(pch, ",.-");
5242 if (!pnext)
5243 return -EINVAL;
5244 *pnext = 0;
5245 width_str = pch;
5246
5247 pch = pnext + 1;
5248 pnext = strpbrk(pch, ",.-");
5249 if (!pnext)
5250 return -EINVAL;
5251 *pnext = 0;
5252 addr = simple_strtoul(pch, &ptmp, 16);
5253 if (addr > 0x3FFF)
5254 return -EINVAL;
5255
5256 pch = pnext + 1;
5257 if ((pch - extra) >= wrqu->length)
5258 return -EINVAL;
5259 data = simple_strtoul(pch, &ptmp, 16);
5260
5261 ret = 0;
5262 width = width_str[0];
5263 switch (width) {
5264 case 'b':
5265
5266 if (data > 0xFF) {
5267 ret = -EINVAL;
5268 break;
5269 }
5270 rtw_write8(padapter, addr, data);
5271 break;
5272 case 'w':
5273
5274 if (data > 0xFFFF) {
5275 ret = -EINVAL;
5276 break;
5277 }
5278 rtw_write16(padapter, addr, data);
5279 break;
5280 case 'd':
5281
5282 rtw_write32(padapter, addr, data);
5283 break;
5284 default:
5285 ret = -EINVAL;
5286 break;
5287 }
5288
5289 return ret;
5290}
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303static int rtw_mp_read_reg(struct net_device *dev,
5304 struct iw_request_info *info,
5305 struct iw_point *wrqu, char *extra)
5306{
5307 struct adapter *padapter = rtw_netdev_priv(dev);
5308 char *input = kmalloc(wrqu->length, GFP_KERNEL);
5309 char *pch, *pnext, *ptmp;
5310 char *width_str;
5311 char width;
5312 char data[20], tmp[20];
5313 u32 addr;
5314 u32 ret, i = 0, j = 0, strtout = 0;
5315
5316 if (!input)
5317 return -ENOMEM;
5318 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
5319 kfree(input);
5320 return -EFAULT;
5321 }
5322 memset(data, 0, 20);
5323 memset(tmp, 0, 20);
5324 memset(extra, 0, wrqu->length);
5325
5326 pch = input;
5327 pnext = strpbrk(pch, ",.-");
5328 if (!pnext) {
5329 kfree(input);
5330 return -EINVAL;
5331 }
5332 *pnext = 0;
5333 width_str = pch;
5334
5335 pch = pnext + 1;
5336 if ((pch - input) >= wrqu->length) {
5337 kfree(input);
5338 return -EINVAL;
5339 }
5340 kfree(input);
5341 addr = simple_strtoul(pch, &ptmp, 16);
5342 if (addr > 0x3FFF)
5343 return -EINVAL;
5344
5345 ret = 0;
5346 width = width_str[0];
5347 switch (width) {
5348 case 'b':
5349
5350 sprintf(extra, "%d\n", rtw_read8(padapter, addr));
5351 wrqu->length = strlen(extra);
5352 break;
5353 case 'w':
5354
5355 sprintf(data, "%04x\n", rtw_read16(padapter, addr));
5356 for (i = 0; i <= strlen(data); i++) {
5357 if (i % 2 == 0) {
5358 tmp[j] = ' ';
5359 j++;
5360 }
5361 if (data[i] != '\0')
5362 tmp[j] = data[i];
5363 j++;
5364 }
5365 pch = tmp;
5366 DBG_88E("pch =%s", pch);
5367
5368 while (*pch != '\0') {
5369 pnext = strpbrk(pch, " ");
5370 if (!pnext)
5371 break;
5372
5373 pnext++;
5374 if (*pnext != '\0') {
5375 strtout = simple_strtoul(pnext, &ptmp, 16);
5376 sprintf(extra + strlen(extra), " %d", strtout);
5377 } else {
5378 break;
5379 }
5380 pch = pnext;
5381 }
5382 wrqu->length = 6;
5383 break;
5384 case 'd':
5385
5386 sprintf(data, "%08x", rtw_read32(padapter, addr));
5387
5388 for (i = 0; i <= strlen(data); i++) {
5389 if (i % 2 == 0) {
5390 tmp[j] = ' ';
5391 j++;
5392 }
5393 if (data[i] != '\0')
5394 tmp[j] = data[i];
5395
5396 j++;
5397 }
5398 pch = tmp;
5399 DBG_88E("pch =%s", pch);
5400
5401 while (*pch != '\0') {
5402 pnext = strpbrk(pch, " ");
5403 if (!pnext)
5404 break;
5405 pnext++;
5406 if (*pnext != '\0') {
5407 strtout = simple_strtoul(pnext, &ptmp, 16);
5408 sprintf(extra + strlen(extra), " %d", strtout);
5409 } else {
5410 break;
5411 }
5412 pch = pnext;
5413 }
5414 wrqu->length = strlen(extra);
5415 break;
5416 default:
5417 wrqu->length = 0;
5418 ret = -EINVAL;
5419 break;
5420 }
5421
5422 return ret;
5423}
5424
5425
5426
5427
5428
5429
5430
5431 static int rtw_mp_write_rf(struct net_device *dev,
5432 struct iw_request_info *info,
5433 struct iw_point *wrqu, char *extra)
5434{
5435 u32 path, addr, data;
5436 int ret;
5437 struct adapter *padapter = rtw_netdev_priv(dev);
5438
5439 ret = sscanf(extra, "%d,%x,%x", &path, &addr, &data);
5440 if (ret < 3)
5441 return -EINVAL;
5442
5443 if (path >= RF_PATH_MAX)
5444 return -EINVAL;
5445 if (addr > 0xFF)
5446 return -EINVAL;
5447 if (data > 0xFFFFF)
5448 return -EINVAL;
5449
5450 memset(extra, 0, wrqu->length);
5451
5452 write_rfreg(padapter, path, addr, data);
5453
5454 sprintf(extra, "write_rf completed\n");
5455 wrqu->length = strlen(extra);
5456
5457 return 0;
5458}
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468static int rtw_mp_read_rf(struct net_device *dev,
5469 struct iw_request_info *info,
5470 struct iw_point *wrqu, char *extra)
5471{
5472 char *input = kmalloc(wrqu->length, GFP_KERNEL);
5473 char *pch, *pnext, *ptmp;
5474 char data[20], tmp[20];
5475 u32 path, addr;
5476 u32 ret, i = 0, j = 0, strtou = 0;
5477 struct adapter *padapter = rtw_netdev_priv(dev);
5478
5479 if (!input)
5480 return -ENOMEM;
5481 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
5482 kfree(input);
5483 return -EFAULT;
5484 }
5485 ret = sscanf(input, "%d,%x", &path, &addr);
5486 kfree(input);
5487 if (ret < 2)
5488 return -EINVAL;
5489
5490 if (path >= RF_PATH_MAX)
5491 return -EINVAL;
5492 if (addr > 0xFF)
5493 return -EINVAL;
5494
5495 memset(extra, 0, wrqu->length);
5496
5497 sprintf(data, "%08x", read_rfreg(padapter, path, addr));
5498
5499 for (i = 0; i <= strlen(data); i++) {
5500 if (i % 2 == 0) {
5501 tmp[j] = ' ';
5502 j++;
5503 }
5504 tmp[j] = data[i];
5505 j++;
5506 }
5507 pch = tmp;
5508 DBG_88E("pch =%s", pch);
5509
5510 while (*pch != '\0') {
5511 pnext = strpbrk(pch, " ");
5512 pnext++;
5513 if (*pnext != '\0') {
5514 strtou = simple_strtoul(pnext, &ptmp, 16);
5515 sprintf(extra + strlen(extra), " %d", strtou);
5516 } else {
5517 break;
5518 }
5519 pch = pnext;
5520 }
5521 wrqu->length = strlen(extra);
5522 return 0;
5523}
5524
5525static int rtw_mp_start(struct net_device *dev,
5526 struct iw_request_info *info,
5527 struct iw_point *wrqu, char *extra)
5528{
5529 struct adapter *padapter = rtw_netdev_priv(dev);
5530
5531 if (padapter->registrypriv.mp_mode == 0) {
5532 padapter->registrypriv.mp_mode = 1;
5533
5534 rtw_pm_set_ips(padapter, IPS_NONE);
5535 LeaveAllPowerSaveMode(padapter);
5536
5537 MPT_InitializeAdapter(padapter, 1);
5538 }
5539 if (padapter->registrypriv.mp_mode == 0)
5540 return -EPERM;
5541 if (padapter->mppriv.mode == MP_OFF) {
5542 if (mp_start_test(padapter) == _FAIL)
5543 return -EPERM;
5544 padapter->mppriv.mode = MP_ON;
5545 }
5546 return 0;
5547}
5548
5549static int rtw_mp_stop(struct net_device *dev,
5550 struct iw_request_info *info,
5551 struct iw_point *wrqu, char *extra)
5552{
5553 struct adapter *padapter = rtw_netdev_priv(dev);
5554
5555 if (padapter->registrypriv.mp_mode == 1) {
5556 MPT_DeInitAdapter(padapter);
5557 padapter->registrypriv.mp_mode = 0;
5558 }
5559
5560 if (padapter->mppriv.mode != MP_OFF) {
5561 mp_stop_test(padapter);
5562 padapter->mppriv.mode = MP_OFF;
5563 }
5564
5565 return 0;
5566}
5567
5568extern int wifirate2_ratetbl_inx(unsigned char rate);
5569
5570static int rtw_mp_rate(struct net_device *dev,
5571 struct iw_request_info *info,
5572 struct iw_point *wrqu, char *extra)
5573{
5574 u32 rate = MPT_RATE_1M;
5575 char *input = kmalloc(wrqu->length, GFP_KERNEL);
5576 struct adapter *padapter = rtw_netdev_priv(dev);
5577
5578 if (!input)
5579 return -ENOMEM;
5580 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
5581 kfree(input);
5582 return -EFAULT;
5583 }
5584 rate = rtw_atoi(input);
5585 sprintf(extra, "Set data rate to %d", rate);
5586 kfree(input);
5587 if (rate <= 0x7f)
5588 rate = wifirate2_ratetbl_inx((u8)rate);
5589 else
5590 rate = (rate - 0x80 + MPT_RATE_MCS0);
5591
5592 if (rate >= MPT_RATE_LAST)
5593 return -EINVAL;
5594
5595 padapter->mppriv.rateidx = rate;
5596 Hal_SetDataRate(padapter);
5597
5598 wrqu->length = strlen(extra) + 1;
5599 return 0;
5600}
5601
5602static int rtw_mp_channel(struct net_device *dev,
5603 struct iw_request_info *info,
5604 struct iw_point *wrqu, char *extra)
5605{
5606 struct adapter *padapter = rtw_netdev_priv(dev);
5607 char *input = kmalloc(wrqu->length, GFP_KERNEL);
5608 u32 channel = 1;
5609
5610 if (!input)
5611 return -ENOMEM;
5612 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
5613 kfree(input);
5614 return -EFAULT;
5615 }
5616 channel = rtw_atoi(input);
5617 sprintf(extra, "Change channel %d to channel %d", padapter->mppriv.channel, channel);
5618
5619 padapter->mppriv.channel = channel;
5620 Hal_SetChannel(padapter);
5621
5622 wrqu->length = strlen(extra) + 1;
5623 kfree(input);
5624 return 0;
5625}
5626
5627static int rtw_mp_bandwidth(struct net_device *dev,
5628 struct iw_request_info *info,
5629 struct iw_point *wrqu, char *extra)
5630{
5631 u32 bandwidth = 0, sg = 0;
5632 struct adapter *padapter = rtw_netdev_priv(dev);
5633
5634 sscanf(extra, "40M =%d, shortGI =%d", &bandwidth, &sg);
5635
5636 if (bandwidth != HT_CHANNEL_WIDTH_40)
5637 bandwidth = HT_CHANNEL_WIDTH_20;
5638
5639 padapter->mppriv.bandwidth = (u8)bandwidth;
5640 padapter->mppriv.preamble = sg;
5641
5642 SetBandwidth(padapter);
5643
5644 return 0;
5645}
5646
5647static int rtw_mp_txpower(struct net_device *dev,
5648 struct iw_request_info *info,
5649 struct iw_point *wrqu, char *extra)
5650{
5651 u32 idx_a = 0, idx_b = 0;
5652 char *input = kmalloc(wrqu->length, GFP_KERNEL);
5653 struct adapter *padapter = rtw_netdev_priv(dev);
5654
5655 if (!input)
5656 return -ENOMEM;
5657 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
5658 kfree(input);
5659 return -EFAULT;
5660 }
5661 sscanf(input, "patha =%d, pathb =%d", &idx_a, &idx_b);
5662
5663 sprintf(extra, "Set power level path_A:%d path_B:%d", idx_a, idx_b);
5664 padapter->mppriv.txpoweridx = (u8)idx_a;
5665 padapter->mppriv.txpoweridx_b = (u8)idx_b;
5666 padapter->mppriv.bSetTxPower = 1;
5667 Hal_SetAntennaPathPower(padapter);
5668
5669 wrqu->length = strlen(extra) + 1;
5670 kfree(input);
5671 return 0;
5672}
5673
5674static int rtw_mp_ant_tx(struct net_device *dev,
5675 struct iw_request_info *info,
5676 struct iw_point *wrqu, char *extra)
5677{
5678 u8 i;
5679 char *input = kmalloc(wrqu->length, GFP_KERNEL);
5680 u16 antenna = 0;
5681 struct adapter *padapter = rtw_netdev_priv(dev);
5682
5683 if (!input)
5684 return -ENOMEM;
5685 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
5686 kfree(input);
5687 return -EFAULT;
5688 }
5689
5690 sprintf(extra, "switch Tx antenna to %s", input);
5691
5692 for (i = 0; i < strlen(input); i++) {
5693 switch (input[i]) {
5694 case 'a':
5695 antenna |= ANTENNA_A;
5696 break;
5697 case 'b':
5698 antenna |= ANTENNA_B;
5699 break;
5700 }
5701 }
5702 padapter->mppriv.antenna_tx = antenna;
5703
5704 Hal_SetAntenna(padapter);
5705
5706 wrqu->length = strlen(extra) + 1;
5707 kfree(input);
5708 return 0;
5709}
5710
5711static int rtw_mp_ant_rx(struct net_device *dev,
5712 struct iw_request_info *info,
5713 struct iw_point *wrqu, char *extra)
5714{
5715 u8 i;
5716 u16 antenna = 0;
5717 char *input = kmalloc(wrqu->length, GFP_KERNEL);
5718 struct adapter *padapter = rtw_netdev_priv(dev);
5719
5720 if (!input)
5721 return -ENOMEM;
5722 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
5723 kfree(input);
5724 return -EFAULT;
5725 }
5726 memset(extra, 0, wrqu->length);
5727
5728 sprintf(extra, "switch Rx antenna to %s", input);
5729
5730 for (i = 0; i < strlen(input); i++) {
5731 switch (input[i]) {
5732 case 'a':
5733 antenna |= ANTENNA_A;
5734 break;
5735 case 'b':
5736 antenna |= ANTENNA_B;
5737 break;
5738 }
5739 }
5740
5741 padapter->mppriv.antenna_rx = antenna;
5742 Hal_SetAntenna(padapter);
5743 wrqu->length = strlen(extra);
5744 kfree(input);
5745 return 0;
5746}
5747
5748static int rtw_mp_ctx(struct net_device *dev,
5749 struct iw_request_info *info,
5750 struct iw_point *wrqu, char *extra)
5751{
5752 u32 pkTx = 1, countPkTx = 1, cotuTx = 1, CarrSprTx = 1, scTx = 1, sgleTx = 1, stop = 1;
5753 u32 bStartTest = 1;
5754 u32 count = 0;
5755 struct mp_priv *pmp_priv;
5756 struct pkt_attrib *pattrib;
5757
5758 struct adapter *padapter = rtw_netdev_priv(dev);
5759
5760 pmp_priv = &padapter->mppriv;
5761
5762 if (copy_from_user(extra, wrqu->pointer, wrqu->length))
5763 return -EFAULT;
5764
5765 DBG_88E("%s: in =%s\n", __func__, extra);
5766
5767 countPkTx = strncmp(extra, "count =", 5);
5768 cotuTx = strncmp(extra, "background", 20);
5769 CarrSprTx = strncmp(extra, "background, cs", 20);
5770 scTx = strncmp(extra, "background, sc", 20);
5771 sgleTx = strncmp(extra, "background, stone", 20);
5772 pkTx = strncmp(extra, "background, pkt", 20);
5773 stop = strncmp(extra, "stop", 4);
5774 sscanf(extra, "count =%d, pkt", &count);
5775
5776 memset(extra, '\0', sizeof(*extra));
5777
5778 if (stop == 0) {
5779 bStartTest = 0;
5780 pmp_priv->tx.stop = 1;
5781 sprintf(extra, "Stop continuous Tx");
5782 } else {
5783 bStartTest = 1;
5784 if (pmp_priv->mode != MP_ON) {
5785 if (pmp_priv->tx.stop != 1) {
5786 DBG_88E("%s: MP_MODE != ON %d\n", __func__, pmp_priv->mode);
5787 return -EFAULT;
5788 }
5789 }
5790 }
5791
5792 if (pkTx == 0 || countPkTx == 0)
5793 pmp_priv->mode = MP_PACKET_TX;
5794 if (sgleTx == 0)
5795 pmp_priv->mode = MP_SINGLE_TONE_TX;
5796 if (cotuTx == 0)
5797 pmp_priv->mode = MP_CONTINUOUS_TX;
5798 if (CarrSprTx == 0)
5799 pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX;
5800 if (scTx == 0)
5801 pmp_priv->mode = MP_SINGLE_CARRIER_TX;
5802
5803 switch (pmp_priv->mode) {
5804 case MP_PACKET_TX:
5805 if (bStartTest == 0) {
5806 pmp_priv->tx.stop = 1;
5807 pmp_priv->mode = MP_ON;
5808 sprintf(extra, "Stop continuous Tx");
5809 } else if (pmp_priv->tx.stop == 1) {
5810 sprintf(extra, "Start continuous DA = ffffffffffff len = 1500 count =%u,\n", count);
5811 pmp_priv->tx.stop = 0;
5812 pmp_priv->tx.count = count;
5813 pmp_priv->tx.payload = 2;
5814 pattrib = &pmp_priv->tx.attrib;
5815 pattrib->pktlen = 1500;
5816 memset(pattrib->dst, 0xFF, ETH_ALEN);
5817 SetPacketTx(padapter);
5818 } else {
5819 return -EFAULT;
5820 }
5821 wrqu->length = strlen(extra);
5822 return 0;
5823 case MP_SINGLE_TONE_TX:
5824 if (bStartTest != 0)
5825 sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes.");
5826 Hal_SetSingleToneTx(padapter, (u8)bStartTest);
5827 break;
5828 case MP_CONTINUOUS_TX:
5829 if (bStartTest != 0)
5830 sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes.");
5831 Hal_SetContinuousTx(padapter, (u8)bStartTest);
5832 break;
5833 case MP_CARRIER_SUPPRISSION_TX:
5834 if (bStartTest != 0) {
5835 if (pmp_priv->rateidx <= MPT_RATE_11M) {
5836 sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes.");
5837 Hal_SetCarrierSuppressionTx(padapter, (u8)bStartTest);
5838 } else {
5839 sprintf(extra, "Specify carrier suppression but not CCK rate");
5840 }
5841 }
5842 break;
5843 case MP_SINGLE_CARRIER_TX:
5844 if (bStartTest != 0)
5845 sprintf(extra, "Start continuous DA = ffffffffffff len = 1500\n infinite = yes.");
5846 Hal_SetSingleCarrierTx(padapter, (u8)bStartTest);
5847 break;
5848 default:
5849 sprintf(extra, "Error! Continuous-Tx is not on-going.");
5850 return -EFAULT;
5851 }
5852
5853 if (bStartTest == 1 && pmp_priv->mode != MP_ON) {
5854 struct mp_priv *pmp_priv = &padapter->mppriv;
5855 if (pmp_priv->tx.stop == 0) {
5856 pmp_priv->tx.stop = 1;
5857 msleep(5);
5858 }
5859 pmp_priv->tx.stop = 0;
5860 pmp_priv->tx.count = 1;
5861 SetPacketTx(padapter);
5862 } else {
5863 pmp_priv->mode = MP_ON;
5864 }
5865
5866 wrqu->length = strlen(extra);
5867 return 0;
5868}
5869
5870static int rtw_mp_arx(struct net_device *dev,
5871 struct iw_request_info *info,
5872 struct iw_point *wrqu, char *extra)
5873{
5874 u8 bStartRx = 0, bStopRx = 0, bQueryPhy;
5875 u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0;
5876 char *input = kmalloc(wrqu->length, GFP_KERNEL);
5877 struct adapter *padapter = rtw_netdev_priv(dev);
5878
5879 if (!input)
5880 return -ENOMEM;
5881
5882 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
5883 kfree(input);
5884 return -EFAULT;
5885 }
5886 DBG_88E("%s: %s\n", __func__, input);
5887
5888 bStartRx = (strncmp(input, "start", 5) == 0) ? 1 : 0;
5889 bStopRx = (strncmp(input, "stop", 5) == 0) ? 1 : 0;
5890 bQueryPhy = (strncmp(input, "phy", 3) == 0) ? 1 : 0;
5891
5892 if (bStartRx) {
5893 sprintf(extra, "start");
5894 SetPacketRx(padapter, bStartRx);
5895 } else if (bStopRx) {
5896 SetPacketRx(padapter, 0);
5897 sprintf(extra, "Received packet OK:%d CRC error:%d", padapter->mppriv.rx_pktcount, padapter->mppriv.rx_crcerrpktcount);
5898 } else if (bQueryPhy) {
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910 cckok = read_bbreg(padapter, 0xf88, 0xffffffff);
5911 cckcrc = read_bbreg(padapter, 0xf84, 0xffffffff);
5912 ofdmok = read_bbreg(padapter, 0xf94, 0x0000FFFF);
5913 ofdmcrc = read_bbreg(padapter, 0xf94, 0xFFFF0000);
5914 htok = read_bbreg(padapter, 0xf90, 0x0000FFFF);
5915 htcrc = read_bbreg(padapter, 0xf90, 0xFFFF0000);
5916
5917 OFDM_FA = read_bbreg(padapter, 0xcf0, 0x0000FFFF);
5918 OFDM_FA = read_bbreg(padapter, 0xcf2, 0xFFFF0000);
5919 OFDM_FA = read_bbreg(padapter, 0xda0, 0xFFFF0000);
5920 OFDM_FA = read_bbreg(padapter, 0xda4, 0x0000FFFF);
5921 OFDM_FA = read_bbreg(padapter, 0xda4, 0xFFFF0000);
5922 OFDM_FA = read_bbreg(padapter, 0xda8, 0x0000FFFF);
5923 CCK_FA = (rtw_read8(padapter, 0xa5b) << 8) | (rtw_read8(padapter, 0xa5c));
5924
5925 sprintf(extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d", cckok + ofdmok + htok, cckcrc + ofdmcrc + htcrc, OFDM_FA + CCK_FA);
5926 }
5927 wrqu->length = strlen(extra) + 1;
5928 kfree(input);
5929 return 0;
5930}
5931
5932static int rtw_mp_trx_query(struct net_device *dev,
5933 struct iw_request_info *info,
5934 struct iw_point *wrqu, char *extra)
5935{
5936 u32 txok, txfail, rxok, rxfail;
5937 struct adapter *padapter = rtw_netdev_priv(dev);
5938
5939 txok = padapter->mppriv.tx.sended;
5940 txfail = 0;
5941 rxok = padapter->mppriv.rx_pktcount;
5942 rxfail = padapter->mppriv.rx_crcerrpktcount;
5943
5944 memset(extra, '\0', 128);
5945
5946 sprintf(extra, "Tx OK:%d, Tx Fail:%d, Rx OK:%d, CRC error:%d ", txok, txfail, rxok, rxfail);
5947
5948 wrqu->length = strlen(extra) + 1;
5949
5950 return 0;
5951}
5952
5953static int rtw_mp_pwrtrk(struct net_device *dev,
5954 struct iw_request_info *info,
5955 struct iw_point *wrqu, char *extra)
5956{
5957 u8 enable;
5958 u32 thermal;
5959 s32 ret;
5960 struct adapter *padapter = rtw_netdev_priv(dev);
5961 char *input = kmalloc(wrqu->length, GFP_KERNEL);
5962
5963 if (!input)
5964 return -ENOMEM;
5965 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
5966 kfree(input);
5967 return -EFAULT;
5968 }
5969 memset(extra, 0, wrqu->length);
5970
5971 enable = 1;
5972 if (wrqu->length > 1) {
5973 if (strncmp(input, "stop", 4) == 0) {
5974 enable = 0;
5975 sprintf(extra, "mp tx power tracking stop");
5976 } else if (sscanf(input, "ther =%d", &thermal)) {
5977 ret = Hal_SetThermalMeter(padapter, (u8)thermal);
5978 if (ret == _FAIL)
5979 return -EPERM;
5980 sprintf(extra, "mp tx power tracking start, target value =%d ok ", thermal);
5981 } else {
5982 kfree(input);
5983 return -EINVAL;
5984 }
5985 }
5986
5987 kfree(input);
5988 ret = Hal_SetPowerTracking(padapter, enable);
5989 if (ret == _FAIL)
5990 return -EPERM;
5991
5992 wrqu->length = strlen(extra);
5993 return 0;
5994}
5995
5996static int rtw_mp_psd(struct net_device *dev,
5997 struct iw_request_info *info,
5998 struct iw_point *wrqu, char *extra)
5999{
6000 struct adapter *padapter = rtw_netdev_priv(dev);
6001 char *input = kmalloc(wrqu->length, GFP_KERNEL);
6002
6003 if (!input)
6004 return -ENOMEM;
6005 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
6006 kfree(input);
6007 return -EFAULT;
6008 }
6009
6010 strcpy(extra, input);
6011
6012 wrqu->length = mp_query_psd(padapter, extra);
6013 kfree(input);
6014 return 0;
6015}
6016
6017static int rtw_mp_thermal(struct net_device *dev,
6018 struct iw_request_info *info,
6019 struct iw_point *wrqu, char *extra)
6020{
6021 u8 val;
6022 u16 bwrite = 1;
6023 u16 addr = EEPROM_THERMAL_METER_88E;
6024
6025 u16 cnt = 1;
6026 u16 max_available_size = 0;
6027 struct adapter *padapter = rtw_netdev_priv(dev);
6028
6029 if (copy_from_user(extra, wrqu->pointer, wrqu->length))
6030 return -EFAULT;
6031
6032 bwrite = strncmp(extra, "write", 6);
6033
6034 Hal_GetThermalMeter(padapter, &val);
6035
6036 if (bwrite == 0) {
6037 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false);
6038 if (2 > max_available_size) {
6039 DBG_88E("no available efuse!\n");
6040 return -EFAULT;
6041 }
6042 if (rtw_efuse_map_write(padapter, addr, cnt, &val) == _FAIL) {
6043 DBG_88E("rtw_efuse_map_write error\n");
6044 return -EFAULT;
6045 } else {
6046 sprintf(extra, " efuse write ok :%d", val);
6047 }
6048 } else {
6049 sprintf(extra, "%d", val);
6050 }
6051 wrqu->length = strlen(extra);
6052
6053 return 0;
6054}
6055
6056static int rtw_mp_reset_stats(struct net_device *dev,
6057 struct iw_request_info *info,
6058 struct iw_point *wrqu, char *extra)
6059{
6060 struct mp_priv *pmp_priv;
6061 struct adapter *padapter = rtw_netdev_priv(dev);
6062
6063 pmp_priv = &padapter->mppriv;
6064
6065 pmp_priv->tx.sended = 0;
6066 pmp_priv->tx_pktcount = 0;
6067 pmp_priv->rx_pktcount = 0;
6068 pmp_priv->rx_crcerrpktcount = 0;
6069
6070
6071 write_bbreg(padapter, 0xf14, BIT(16), 0x1);
6072 msleep(10);
6073 write_bbreg(padapter, 0xf14, BIT(16), 0x0);
6074
6075 return 0;
6076}
6077
6078static int rtw_mp_dump(struct net_device *dev,
6079 struct iw_request_info *info,
6080 struct iw_point *wrqu, char *extra)
6081{
6082 u32 value;
6083 u8 rf_type, path_nums = 0;
6084 u32 i, j = 1, path;
6085 struct adapter *padapter = rtw_netdev_priv(dev);
6086
6087 if (strncmp(extra, "all", 4) == 0) {
6088 DBG_88E("\n ======= MAC REG =======\n");
6089 for (i = 0x0; i < 0x300; i += 4) {
6090 if (j % 4 == 1)
6091 DBG_88E("0x%02x", i);
6092 DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
6093 if ((j++) % 4 == 0)
6094 DBG_88E("\n");
6095 }
6096 for (i = 0x400; i < 0x1000; i += 4) {
6097 if (j % 4 == 1)
6098 DBG_88E("0x%02x", i);
6099 DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
6100 if ((j++) % 4 == 0)
6101 DBG_88E("\n");
6102 }
6103
6104 j = 1;
6105 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
6106
6107 DBG_88E("\n ======= RF REG =======\n");
6108 if ((RF_1T2R == rf_type) || (RF_1T1R == rf_type))
6109 path_nums = 1;
6110 else
6111 path_nums = 2;
6112
6113 for (path = 0; path < path_nums; path++) {
6114 for (i = 0; i < 0x34; i++) {
6115 value = rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
6116 if (j % 4 == 1)
6117 DBG_88E("0x%02x ", i);
6118 DBG_88E(" 0x%08x ", value);
6119 if ((j++) % 4 == 0)
6120 DBG_88E("\n");
6121 }
6122 }
6123 }
6124 return 0;
6125}
6126
6127static int rtw_mp_phypara(struct net_device *dev,
6128 struct iw_request_info *info,
6129 struct iw_point *wrqu, char *extra)
6130{
6131 char *input = kmalloc(wrqu->length, GFP_KERNEL);
6132 u32 valxcap;
6133
6134 if (!input)
6135 return -ENOMEM;
6136 if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
6137 kfree(input);
6138 return -EFAULT;
6139 }
6140
6141 DBG_88E("%s:iwpriv in =%s\n", __func__, input);
6142
6143 sscanf(input, "xcap =%d", &valxcap);
6144
6145 kfree(input);
6146 return 0;
6147}
6148
6149static int rtw_mp_SetRFPath(struct net_device *dev,
6150 struct iw_request_info *info,
6151 union iwreq_data *wrqu, char *extra)
6152{
6153 struct adapter *padapter = rtw_netdev_priv(dev);
6154 char *input = kmalloc(wrqu->data.length, GFP_KERNEL);
6155 u8 bMain = 1, bTurnoff = 1;
6156
6157 if (!input)
6158 return -ENOMEM;
6159 if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
6160 return -EFAULT;
6161 DBG_88E("%s:iwpriv in =%s\n", __func__, input);
6162
6163 bMain = strncmp(input, "1", 2);
6164 bTurnoff = strncmp(input, "0", 3);
6165
6166 if (bMain == 0) {
6167 MP_PHY_SetRFPathSwitch(padapter, true);
6168 DBG_88E("%s:PHY_SetRFPathSwitch = true\n", __func__);
6169 } else if (bTurnoff == 0) {
6170 MP_PHY_SetRFPathSwitch(padapter, false);
6171 DBG_88E("%s:PHY_SetRFPathSwitch = false\n", __func__);
6172 }
6173 kfree(input);
6174 return 0;
6175}
6176
6177static int rtw_mp_QueryDrv(struct net_device *dev,
6178 struct iw_request_info *info,
6179 union iwreq_data *wrqu, char *extra)
6180{
6181 struct adapter *padapter = rtw_netdev_priv(dev);
6182 char *input = kmalloc(wrqu->data.length, GFP_KERNEL);
6183 u8 qAutoLoad = 1;
6184 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
6185
6186 if (!input)
6187 return -ENOMEM;
6188
6189 if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
6190 return -EFAULT;
6191 DBG_88E("%s:iwpriv in =%s\n", __func__, input);
6192
6193 qAutoLoad = strncmp(input, "autoload", 8);
6194
6195 if (qAutoLoad == 0) {
6196 DBG_88E("%s:qAutoLoad\n", __func__);
6197
6198 if (pEEPROM->bautoload_fail_flag)
6199 sprintf(extra, "fail");
6200 else
6201 sprintf(extra, "ok");
6202 }
6203 wrqu->data.length = strlen(extra) + 1;
6204 kfree(input);
6205 return 0;
6206}
6207
6208static int rtw_mp_set(struct net_device *dev,
6209 struct iw_request_info *info,
6210 union iwreq_data *wdata, char *extra)
6211{
6212 struct iw_point *wrqu = (struct iw_point *)wdata;
6213 u32 subcmd = wrqu->flags;
6214 struct adapter *padapter = rtw_netdev_priv(dev);
6215
6216 if (!padapter)
6217 return -ENETDOWN;
6218
6219 if (!extra) {
6220 wrqu->length = 0;
6221 return -EIO;
6222 }
6223
6224 switch (subcmd) {
6225 case MP_START:
6226 DBG_88E("set case mp_start\n");
6227 rtw_mp_start(dev, info, wrqu, extra);
6228 break;
6229 case MP_STOP:
6230 DBG_88E("set case mp_stop\n");
6231 rtw_mp_stop(dev, info, wrqu, extra);
6232 break;
6233 case MP_BANDWIDTH:
6234 DBG_88E("set case mp_bandwidth\n");
6235 rtw_mp_bandwidth(dev, info, wrqu, extra);
6236 break;
6237 case MP_RESET_STATS:
6238 DBG_88E("set case MP_RESET_STATS\n");
6239 rtw_mp_reset_stats(dev, info, wrqu, extra);
6240 break;
6241 case MP_SetRFPathSwh:
6242 DBG_88E("set MP_SetRFPathSwitch\n");
6243 rtw_mp_SetRFPath(dev, info, wdata, extra);
6244 break;
6245 case CTA_TEST:
6246 DBG_88E("set CTA_TEST\n");
6247 rtw_cta_test_start(dev, info, wdata, extra);
6248 break;
6249 }
6250
6251 return 0;
6252}
6253
6254static int rtw_mp_get(struct net_device *dev,
6255 struct iw_request_info *info,
6256 union iwreq_data *wdata, char *extra)
6257{
6258 struct iw_point *wrqu = (struct iw_point *)wdata;
6259 u32 subcmd = wrqu->flags;
6260 struct adapter *padapter = rtw_netdev_priv(dev);
6261
6262 if (!padapter)
6263 return -ENETDOWN;
6264 if (!extra) {
6265 wrqu->length = 0;
6266 return -EIO;
6267 }
6268
6269 switch (subcmd) {
6270 case WRITE_REG:
6271 rtw_mp_write_reg(dev, info, wrqu, extra);
6272 break;
6273 case WRITE_RF:
6274 rtw_mp_write_rf(dev, info, wrqu, extra);
6275 break;
6276 case MP_PHYPARA:
6277 DBG_88E("mp_get MP_PHYPARA\n");
6278 rtw_mp_phypara(dev, info, wrqu, extra);
6279 break;
6280 case MP_CHANNEL:
6281 DBG_88E("set case mp_channel\n");
6282 rtw_mp_channel(dev, info, wrqu, extra);
6283 break;
6284 case READ_REG:
6285 DBG_88E("mp_get READ_REG\n");
6286 rtw_mp_read_reg(dev, info, wrqu, extra);
6287 break;
6288 case READ_RF:
6289 DBG_88E("mp_get READ_RF\n");
6290 rtw_mp_read_rf(dev, info, wrqu, extra);
6291 break;
6292 case MP_RATE:
6293 DBG_88E("set case mp_rate\n");
6294 rtw_mp_rate(dev, info, wrqu, extra);
6295 break;
6296 case MP_TXPOWER:
6297 DBG_88E("set case MP_TXPOWER\n");
6298 rtw_mp_txpower(dev, info, wrqu, extra);
6299 break;
6300 case MP_ANT_TX:
6301 DBG_88E("set case MP_ANT_TX\n");
6302 rtw_mp_ant_tx(dev, info, wrqu, extra);
6303 break;
6304 case MP_ANT_RX:
6305 DBG_88E("set case MP_ANT_RX\n");
6306 rtw_mp_ant_rx(dev, info, wrqu, extra);
6307 break;
6308 case MP_QUERY:
6309 rtw_mp_trx_query(dev, info, wrqu, extra);
6310 break;
6311 case MP_CTX:
6312 DBG_88E("set case MP_CTX\n");
6313 rtw_mp_ctx(dev, info, wrqu, extra);
6314 break;
6315 case MP_ARX:
6316 DBG_88E("set case MP_ARX\n");
6317 rtw_mp_arx(dev, info, wrqu, extra);
6318 break;
6319 case EFUSE_GET:
6320 DBG_88E("efuse get EFUSE_GET\n");
6321 rtw_mp_efuse_get(dev, info, wdata, extra);
6322 break;
6323 case MP_DUMP:
6324 DBG_88E("set case MP_DUMP\n");
6325 rtw_mp_dump(dev, info, wrqu, extra);
6326 break;
6327 case MP_PSD:
6328 DBG_88E("set case MP_PSD\n");
6329 rtw_mp_psd(dev, info, wrqu, extra);
6330 break;
6331 case MP_THER:
6332 DBG_88E("set case MP_THER\n");
6333 rtw_mp_thermal(dev, info, wrqu, extra);
6334 break;
6335 case MP_QueryDrvStats:
6336 DBG_88E("mp_get MP_QueryDrvStats\n");
6337 rtw_mp_QueryDrv(dev, info, wdata, extra);
6338 break;
6339 case MP_PWRTRK:
6340 DBG_88E("set case MP_PWRTRK\n");
6341 rtw_mp_pwrtrk(dev, info, wrqu, extra);
6342 break;
6343 case EFUSE_SET:
6344 DBG_88E("set case efuse set\n");
6345 rtw_mp_efuse_set(dev, info, wdata, extra);
6346 break;
6347 }
6348
6349 msleep(10);
6350 return 0;
6351}
6352
6353static int rtw_tdls(struct net_device *dev,
6354 struct iw_request_info *info,
6355 union iwreq_data *wrqu, char *extra)
6356{
6357 return 0;
6358}
6359
6360static int rtw_tdls_get(struct net_device *dev,
6361 struct iw_request_info *info,
6362 union iwreq_data *wrqu, char *extra)
6363{
6364 return 0;
6365}
6366
6367static int rtw_test(
6368 struct net_device *dev,
6369 struct iw_request_info *info,
6370 union iwreq_data *wrqu, char *extra)
6371{
6372 u32 len;
6373 u8 *pbuf, *pch;
6374 char *ptmp;
6375 u8 *delim = ",";
6376
6377 DBG_88E("+%s\n", __func__);
6378 len = wrqu->data.length;
6379
6380 pbuf = kzalloc(len, GFP_KERNEL);
6381 if (!pbuf) {
6382 DBG_88E("%s: no memory!\n", __func__);
6383 return -ENOMEM;
6384 }
6385
6386 if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
6387 kfree(pbuf);
6388 DBG_88E("%s: copy from user fail!\n", __func__);
6389 return -EFAULT;
6390 }
6391 DBG_88E("%s: string =\"%s\"\n", __func__, pbuf);
6392
6393 ptmp = (char *)pbuf;
6394 pch = strsep(&ptmp, delim);
6395 if (!pch || strlen(pch) == 0) {
6396 kfree(pbuf);
6397 DBG_88E("%s: parameter error(level 1)!\n", __func__);
6398 return -EFAULT;
6399 }
6400 kfree(pbuf);
6401 return 0;
6402}
6403
6404static iw_handler rtw_handlers[] = {
6405 IW_HANDLER(SIOCGIWNAME, rtw_wx_get_name),
6406 IW_HANDLER(SIOCSIWNWID, dummy),
6407 IW_HANDLER(SIOCGIWNWID, dummy),
6408 IW_HANDLER(SIOCGIWFREQ, rtw_wx_get_freq),
6409 IW_HANDLER(SIOCSIWMODE, rtw_wx_set_mode),
6410 IW_HANDLER(SIOCGIWMODE, rtw_wx_get_mode),
6411 IW_HANDLER(SIOCSIWSENS, dummy),
6412 IW_HANDLER(SIOCGIWSENS, rtw_wx_get_sens),
6413 IW_HANDLER(SIOCGIWRANGE, rtw_wx_get_range),
6414 IW_HANDLER(SIOCSIWPRIV, rtw_wx_set_priv),
6415 IW_HANDLER(SIOCSIWSPY, dummy),
6416 IW_HANDLER(SIOCGIWSPY, dummy),
6417 IW_HANDLER(SIOCSIWAP, rtw_wx_set_wap),
6418 IW_HANDLER(SIOCGIWAP, rtw_wx_get_wap),
6419 IW_HANDLER(SIOCSIWMLME, rtw_wx_set_mlme),
6420 IW_HANDLER(SIOCGIWAPLIST, dummy),
6421 IW_HANDLER(SIOCSIWSCAN, rtw_wx_set_scan),
6422 IW_HANDLER(SIOCGIWSCAN, rtw_wx_get_scan),
6423 IW_HANDLER(SIOCSIWESSID, rtw_wx_set_essid),
6424 IW_HANDLER(SIOCGIWESSID, rtw_wx_get_essid),
6425 IW_HANDLER(SIOCSIWNICKN, dummy),
6426 IW_HANDLER(SIOCGIWNICKN, rtw_wx_get_nick),
6427 IW_HANDLER(SIOCSIWRATE, rtw_wx_set_rate),
6428 IW_HANDLER(SIOCGIWRATE, rtw_wx_get_rate),
6429 IW_HANDLER(SIOCSIWRTS, rtw_wx_set_rts),
6430 IW_HANDLER(SIOCGIWRTS, rtw_wx_get_rts),
6431 IW_HANDLER(SIOCSIWFRAG, rtw_wx_set_frag),
6432 IW_HANDLER(SIOCGIWFRAG, rtw_wx_get_frag),
6433 IW_HANDLER(SIOCSIWTXPOW, dummy),
6434 IW_HANDLER(SIOCGIWTXPOW, dummy),
6435 IW_HANDLER(SIOCSIWRETRY, dummy),
6436 IW_HANDLER(SIOCGIWRETRY, rtw_wx_get_retry),
6437 IW_HANDLER(SIOCSIWENCODE, rtw_wx_set_enc),
6438 IW_HANDLER(SIOCGIWENCODE, rtw_wx_get_enc),
6439 IW_HANDLER(SIOCSIWPOWER, dummy),
6440 IW_HANDLER(SIOCGIWPOWER, rtw_wx_get_power),
6441 IW_HANDLER(SIOCSIWGENIE, rtw_wx_set_gen_ie),
6442 IW_HANDLER(SIOCSIWAUTH, rtw_wx_set_auth),
6443 IW_HANDLER(SIOCSIWENCODEEXT, rtw_wx_set_enc_ext),
6444 IW_HANDLER(SIOCSIWPMKSA, rtw_wx_set_pmkid),
6445};
6446
6447static const struct iw_priv_args rtw_private_args[] = {
6448 {
6449 SIOCIWFIRSTPRIV + 0x0,
6450 IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
6451 },
6452 {
6453 SIOCIWFIRSTPRIV + 0x1,
6454 IW_PRIV_TYPE_CHAR | 0x7FF,
6455 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
6456 },
6457 {
6458 SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
6459 },
6460 {
6461 SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
6462 },
6463 {
6464 SIOCIWFIRSTPRIV + 0x4,
6465 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
6466 },
6467 {
6468 SIOCIWFIRSTPRIV + 0x5,
6469 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
6470 },
6471 {
6472 SIOCIWFIRSTPRIV + 0x6,
6473 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
6474 },
6475 {
6476 SIOCIWFIRSTPRIV + 0x7,
6477 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
6478 },
6479 {
6480 SIOCIWFIRSTPRIV + 0x8,
6481 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
6482 },
6483 {
6484 SIOCIWFIRSTPRIV + 0x9,
6485 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
6486 },
6487
6488 {
6489 SIOCIWFIRSTPRIV + 0xA,
6490 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
6491 },
6492
6493 {
6494 SIOCIWFIRSTPRIV + 0xB,
6495 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
6496 },
6497 {
6498 SIOCIWFIRSTPRIV + 0xC,
6499 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
6500 },
6501 {
6502 SIOCIWFIRSTPRIV + 0xD,
6503 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
6504 },
6505 {
6506 SIOCIWFIRSTPRIV + 0x10,
6507 IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, 0, "p2p_set"
6508 },
6509 {
6510 SIOCIWFIRSTPRIV + 0x11,
6511 IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN, "p2p_get"
6512 },
6513 {
6514 SIOCIWFIRSTPRIV + 0x12,
6515 IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IFNAMSIZ, "p2p_get2"
6516 },
6517 {SIOCIWFIRSTPRIV + 0x13, IW_PRIV_TYPE_CHAR | 128, 0, "NULL"},
6518 {
6519 SIOCIWFIRSTPRIV + 0x14,
6520 IW_PRIV_TYPE_CHAR | 64, 0, "tdls"
6521 },
6522 {
6523 SIOCIWFIRSTPRIV + 0x15,
6524 IW_PRIV_TYPE_CHAR | P2P_PRIVATE_IOCTL_SET_LEN, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | P2P_PRIVATE_IOCTL_SET_LEN, "tdls_get"
6525 },
6526 {
6527 SIOCIWFIRSTPRIV + 0x16,
6528 IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
6529 },
6530
6531 {SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ, 0, "rereg_nd_name"},
6532
6533 {SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "efuse_set"},
6534 {SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
6535 {SIOCIWFIRSTPRIV + 0x1D, IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
6536 },
6537
6538 {SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0, ""},
6539 {SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, ""},
6540
6541
6542 {MP_START, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_start"},
6543 {MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara"},
6544 {MP_STOP, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_stop"},
6545 {MP_CHANNEL, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel"},
6546 {MP_BANDWIDTH, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_bandwidth"},
6547 {MP_RATE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate"},
6548 {MP_RESET_STATS, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_reset_stats"},
6549 {MP_QUERY, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_query"},
6550 {READ_REG, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg"},
6551 {MP_RATE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate"},
6552 {READ_RF, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf"},
6553 {MP_PSD, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"},
6554 {MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump"},
6555 {MP_TXPOWER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},
6556 {MP_ANT_TX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},
6557 {MP_ANT_RX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},
6558 {WRITE_REG, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg"},
6559 {WRITE_RF, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf"},
6560 {MP_CTX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},
6561 {MP_ARX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},
6562 {MP_THER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},
6563 {EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_set"},
6564 {EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
6565 {MP_PWRTRK, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_pwrtrk"},
6566 {MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery"},
6567 {MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"},
6568 {MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_setrfpath"},
6569 {CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"},
6570};
6571
6572static iw_handler rtw_private_handler[] = {
6573rtw_wx_write32,
6574rtw_wx_read32,
6575rtw_drvext_hdl,
6576rtw_mp_ioctl_hdl,
6577
6578
6579 rtw_get_ap_info,
6580
6581 rtw_set_pid,
6582 rtw_wps_start,
6583
6584 rtw_wx_get_sensitivity,
6585 rtw_wx_set_mtk_wps_probe_ie,
6586 rtw_wx_set_mtk_wps_ie,
6587
6588
6589 rtw_wx_set_channel_plan,
6590
6591 rtw_dbg_port,
6592 rtw_wx_write_rf,
6593 rtw_wx_read_rf,
6594
6595 rtw_mp_set,
6596 rtw_mp_get,
6597 rtw_p2p_set,
6598 rtw_p2p_get,
6599 rtw_p2p_get2,
6600
6601 NULL,
6602 rtw_tdls,
6603 rtw_tdls_get,
6604
6605 rtw_pm_set,
6606 rtw_wx_priv_null,
6607 rtw_rereg_nd_name,
6608 rtw_wx_priv_null,
6609
6610 rtw_mp_efuse_set,
6611 rtw_mp_efuse_get,
6612 NULL,
6613 rtw_test,
6614};
6615
6616static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
6617{
6618 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
6619 struct iw_statistics *piwstats = &padapter->iwstats;
6620 int tmp_noise = 0;
6621 int tmp;
6622
6623 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
6624 piwstats->qual.qual = 0;
6625 piwstats->qual.level = 0;
6626 piwstats->qual.noise = 0;
6627 } else {
6628 tmp_noise = padapter->recvpriv.noise;
6629
6630 piwstats->qual.level = padapter->signal_strength;
6631 tmp = 219 + 3 * padapter->signal_strength;
6632 tmp = min(100, tmp);
6633 tmp = max(0, tmp);
6634 piwstats->qual.qual = tmp;
6635 piwstats->qual.noise = tmp_noise;
6636 }
6637 piwstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
6638 return &padapter->iwstats;
6639}
6640
6641struct iw_handler_def rtw_handlers_def = {
6642 .standard = rtw_handlers,
6643 .num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
6644 .private = rtw_private_handler,
6645 .private_args = (struct iw_priv_args *)rtw_private_args,
6646 .num_private = sizeof(rtw_private_handler) / sizeof(iw_handler),
6647 .num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args),
6648 .get_wireless_stats = rtw_get_wireless_stats,
6649};
6650