1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2012 Realtek Corporation. */
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 /*  combo scan */
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 
41 static struct mp_ioctl_handler mp_ioctl_hdl[] = {
42 /*0*/	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 /*5*/	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 /*10*/	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 /*15*/	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 /*20*/	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 /*25*/	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 /*30*/	GEN_HANDLER(sizeof(u8), rtl8188eu_oid_rt_set_power_down_hdl, OID_RT_SET_POWER_DOWN)
80 /*31*/	GEN_HANDLER(0, rtl8188eu_oid_rt_pro_trigger_gpio_hdl, 0)
81 };
82 
83 static u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
84 	6000000, 9000000, 12000000, 18000000, 24000000, 36000000,
85 	48000000, 54000000};
86 
indicate_wx_scan_complete_event(struct adapter * padapter)87 void 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 
rtw_indicate_wx_assoc_event(struct adapter * padapter)95 void 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 
rtw_indicate_wx_disassoc_event(struct adapter * padapter)110 void 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 
translate_scan(struct adapter * padapter,struct iw_request_info * info,struct wlan_network * pnetwork,char * start,char * stop)123 static 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 		/*	User is doing the P2P device discovery */
147 		/*	The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE. */
148 		/*	If not, the driver should ignore this AP and go to the next AP. */
149 
150 		/*	Verifying the SSID */
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) {/*  Probe Request */
155 				/*	Verifying the P2P IE */
156 				if (rtw_get_p2p_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &p2pielen))
157 					blnGotP2PIE = true;
158 			} else {/*  Beacon or Probe Respones */
159 				/*	Verifying the P2P IE */
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 /* CONFIG_88EU_P2P */
169 
170 	/*  AP MAC address  */
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 	/* Add the ESSID */
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 	/* parsing HT_CAP_IE */
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 	/* Add the protocol name */
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 	  /* Add mode */
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 	 /* Add frequency/channel */
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 	/* Add encryption capability */
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 	/*Add basic and extended rates */
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)/* MCS15 */
271 			max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130);
272 		else if (mcs_rate & 0x0080)/* MCS7 */
273 			;
274 		else/* default MCS7 */
275 			max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
276 
277 		max_rate = max_rate * 2;/* Mbps/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 	/* parsing WPA/WPA2 IE */
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 	{/* parsing WPS IE */
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; /* goto next */
363 		}
364 	}
365 
366 	/* Add quality statistics */
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;   /*  signal quality */
381 	iwe.u.qual.noise = 0; /*  noise level */
382 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
383 exit:
384 	kfree(custom);
385 	return start;
386 }
387 
wpa_set_auth_algs(struct net_device * dev,u32 value)388 static 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 
wpa_set_encryption(struct net_device * dev,struct ieee_param * param,u32 param_len)419 static 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 /* CONFIG_88EU_P2P */
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) { /*  802_1x */
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)) { /* sta mode */
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) { /* pairwise key */
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) { /* set mic key */
524 						memcpy(psta->dot11tkiptxmickey.skey, &param->u.crypt.key[16], 8);
525 						memcpy(psta->dot11tkiprxmickey.skey, &param->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 { /* group key */
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, &param->u.crypt.key[16], 8);
535 					memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &param->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 /* CONFIG_88EU_P2P */
546 				}
547 			}
548 			pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
549 			if (!pbcmc_sta) {
550 				;
551 			} else {
552 				/* Jeff: don't disable ieee8021x_blocked while clearing key */
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 
563 exit:
564 
565 	kfree(pwep);
566 
567 	return ret;
568 }
569 
rtw_set_wpa_ie(struct adapter * padapter,char * pie,unsigned short ielen)570 static 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 /* CONFIG_88EU_P2P */
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 		/* dump */
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 		{/* set wps_ie */
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 /* CONFIG_88EU_P2P */
686 					cnt += buf[cnt + 1] + 2;
687 					break;
688 				} else {
689 					cnt += buf[cnt + 1] + 2; /* goto next */
690 				}
691 			}
692 		}
693 	}
694 
695 exit:
696 	kfree(buf);
697 	return ret;
698 }
699 
700 typedef unsigned char   NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];
701 
rtw_wx_get_name(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)702 static 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 		/* parsing HT_CAP_IE */
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 
rtw_wx_get_freq(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)747 static 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 		/* wrqu->freq.m = ieee80211_wlan_frequencies[pcur_bss->Configuration.DSConfig-1] * 100000; */
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 
rtw_wx_set_mode(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)769 static 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);
814 exit:
815 
816 	return ret;
817 }
818 
rtw_wx_get_mode(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)819 static 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 
rtw_wx_set_pmkid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)840 static 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 		/* overwrite PMKID */
862 		for (j = 0; j < NUM_PMKID_CACHE; j++) {
863 			if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN)) {
864 				/*  BSSID is matched, the same AP => rewrite with new PMKID. */
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 			/*  Find a new entry */
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 				/*  BSSID is matched, the same AP => Remove this PMKID information and reset it. */
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 
rtw_wx_get_sens(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)907 static 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;	/* no auto select */
913 	wrqu->sens.disabled = 1;
914 	return 0;
915 }
916 
rtw_wx_get_range(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)917 static 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 	/* Let's try to keep this struct in the same order as in
932 	 * linux/include/wireless.h
933 	 */
934 
935 	/* TODO: See what values we can set, and remove the ones we can't
936 	 * set, or fill them with some default data.
937 	 */
938 
939 	/* ~5 Mb/s real (802.11b) */
940 	range->throughput = 5 * 1000 * 1000;
941 
942 	/* signal level threshold range */
943 
944 	/* percent values between 0 and 100. */
945 	range->max_qual.qual = 100;
946 	range->max_qual.level = 100;
947 	range->max_qual.noise = 100;
948 	range->max_qual.updated = 7; /* Updated all three */
949 
950 	range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
951 	/* TODO: Find real 'good' to 'bad' threshol value for RSSI */
952 	range->avg_qual.level = 178; /* -78 dBm */
953 	range->avg_qual.noise = 0;
954 	range->avg_qual.updated = 7; /* Updated all three */
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 		/*  Include only legal frequencies for some countries */
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 /*  The following code will proivde the security capability to network manager. */
986 /*  If the driver doesn't provide this capability to network manager, */
987 /*  the WPA/WPA2 routers can't be chosen in the network manager. */
988 
989 /*
990 #define IW_SCAN_CAPA_NONE		0x00
991 #define IW_SCAN_CAPA_ESSID		0x01
992 #define IW_SCAN_CAPA_BSSID		0x02
993 #define IW_SCAN_CAPA_CHANNEL		0x04
994 #define IW_SCAN_CAPA_MODE		0x08
995 #define IW_SCAN_CAPA_RATE		0x10
996 #define IW_SCAN_CAPA_TYPE		0x20
997 #define IW_SCAN_CAPA_TIME		0x40
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 /* set bssid flow */
1012 /* s1. rtw_set_802_11_infrastructure_mode() */
1013 /* s2. rtw_set_802_11_authentication_mode() */
1014 /* s3. set_802_11_encryption_mode() */
1015 /* s4. rtw_set_802_11_bssid() */
rtw_wx_set_wap(struct net_device * dev,struct iw_request_info * info,union iwreq_data * awrq,char * extra)1016 static 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 	/* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
1077 	if (!rtw_set_802_11_bssid(padapter, temp->sa_data)) {
1078 		ret = -1;
1079 		goto exit;
1080 	}
1081 
1082 exit:
1083 
1084 
1085 
1086 	return ret;
1087 }
1088 
rtw_wx_get_wap(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1089 static 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 
rtw_wx_set_mlme(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1113 static 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 
rtw_wx_set_scan(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1146 static 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 /* CONFIG_88EU_P2P */
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 	/*  When Busy Traffic, driver do not site survey. So driver return success. */
1186 	/*  wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
1187 	/*  modify by thomas 2011-02-22. */
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 /*	For the DMP WiFi Display project, the driver won't to scan because */
1199 /*	the pmlmepriv->scan_interval is always equal to 3. */
1200 /*	So, the wpa_supplicant won't find out the WPS SoftAP. */
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 /* CONFIG_88EU_P2P */
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; /*  stop parsing */
1273 				}
1274 			}
1275 
1276 			/* it has still some scan parameter to parse, we only do this now... */
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 
1286 exit:
1287 
1288 	return ret;
1289 }
1290 
rtw_wx_get_scan(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1291 static 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 /* CONFIG_88EU_P2P */
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 		/*	P2P is enabled */
1317 		wait_for_surveydone = 200;
1318 	} else {
1319 		/*	P2P is disabled */
1320 		wait_for_surveydone = 100;
1321 	}
1322 #else
1323 	{
1324 		wait_for_surveydone = 100;
1325 	}
1326 #endif /* CONFIG_88EU_P2P */
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 		/* report network only if the current channel set contains the channel to which this network belongs */
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 
1362 exit:
1363 
1364 	return ret;
1365 }
1366 
1367 /* set ssid flow */
1368 /* s1. rtw_set_802_11_infrastructure_mode() */
1369 /* s2. set_802_11_authenticaion_mode() */
1370 /* s3. set_802_11_encryption_mode() */
1371 /* s4. rtw_set_802_11_ssid() */
rtw_wx_set_essid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1372 static 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 
1456 exit:
1457 
1458 	DBG_88E("<=%s, ret %d\n", __func__, ret);
1459 
1460 
1461 
1462 	return ret;
1463 }
1464 
rtw_wx_get_essid(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1465 static 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 
rtw_wx_set_rate(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * extra)1488 static 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 
1548 set_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 
rtw_wx_get_rate(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1566 static 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;	/* no auto select */
1578 	wrqu->bitrate.value = max_rate * 100000;
1579 
1580 	return 0;
1581 }
1582 
rtw_wx_set_rts(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1583 static 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 
rtw_wx_get_rts(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1608 static 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;	/* no auto select */
1620 	/* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */
1621 
1622 
1623 
1624 	return 0;
1625 }
1626 
rtw_wx_set_frag(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1627 static 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 
rtw_wx_get_frag(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1652 static 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;	/* no auto select */
1664 
1665 
1666 
1667 	return 0;
1668 }
1669 
rtw_wx_get_retry(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1670 static 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;	/* no auto select */
1676 	wrqu->retry.disabled = 1;
1677 
1678 	return 0;
1679 }
1680 
rtw_wx_set_enc(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * keybuf)1681 static 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; /* open system */
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 	/* set authentication mode */
1725 	if (erq->flags & IW_ENCODE_OPEN) {
1726 		DBG_88E("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
1727 		padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
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;/* Ndis802_11EncryptionDisabled; */
1745 		padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
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 			/*  set key_id only, no given KeyMaterial(erq->length == 0). */
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 
1792 exit:
1793 
1794 
1795 
1796 	return ret;
1797 }
1798 
rtw_wx_get_enc(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * keybuf)1799 static 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 
rtw_wx_get_power(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1867 static 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;	/* no auto select */
1873 	wrqu->power.disabled = 1;
1874 
1875 	return 0;
1876 }
1877 
rtw_wx_set_gen_ie(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1878 static 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 
rtw_wx_set_auth(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1889 static 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 		 *  ??? does not use these parameters
1909 		 */
1910 		break;
1911 	case IW_AUTH_TKIP_COUNTERMEASURES:
1912 		if (param->value) {
1913 			/*  wpa_supplicant is enabling the tkip countermeasure. */
1914 			padapter->securitypriv.btkip_countermeasure = true;
1915 		} else {
1916 			/*  wpa_supplicant is disabling the tkip countermeasure. */
1917 			padapter->securitypriv.btkip_countermeasure = false;
1918 		}
1919 		break;
1920 	case IW_AUTH_DROP_UNENCRYPTED:
1921 		/* HACK:
1922 		 *
1923 		 * wpa_supplicant calls set_wpa_enabled when the driver
1924 		 * is loaded and unloaded, regardless of if WPA is being
1925 		 * used.  No other calls are made which can be used to
1926 		 * determine if encryption will be used or not prior to
1927 		 * association being expected.  If encryption is not being
1928 		 * used, drop_unencrypted is set to false, else true -- we
1929 		 * can use this to determine if the CAP_PRIVACY_ON bit should
1930 		 * be set.
1931 		 */
1932 
1933 		if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled)
1934 			break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */
1935 					/*  then it needn't reset it; */
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; /* open system */
1942 			padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
1943 		}
1944 
1945 		break;
1946 	case IW_AUTH_80211_AUTH_ALG:
1947 		/*
1948 		 *  It's the starting point of a link layer connection using wpa_supplicant
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 
rtw_wx_set_enc_ext(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1972 static 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 		/* todo: remove key */
1994 		/* remove = 1; */
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 	/* cliW: WEP does not have group key
2016 	 * just not checking GROUP key setting
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 
rtw_wx_get_nick(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2038 static 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 	/* dump debug info here */
2049 	return 0;
2050 }
2051 
rtw_wx_read32(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2052 static 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 
rtw_wx_write32(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2103 static 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 
rtw_wx_read_rf(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2139 static 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 	 * IMPORTANT!!
2151 	 * Only when wireless private ioctl is at odd order,
2152 	 * "extra" would be copied to user space.
2153 	 */
2154 	sprintf(extra, "0x%05x", data32);
2155 
2156 	return 0;
2157 }
2158 
rtw_wx_write_rf(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2159 static 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 
rtw_wx_priv_null(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)2174 static 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 
dummy(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)2180 static int dummy(struct net_device *dev, struct iw_request_info *a,
2181 		 union iwreq_data *wrqu, char *b)
2182 {
2183 	return -1;
2184 }
2185 
rtw_wx_set_channel_plan(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2186 static 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 
rtw_wx_set_mtk_wps_probe_ie(struct net_device * dev,struct iw_request_info * a,union iwreq_data * wrqu,char * b)2202 static 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 
rtw_wx_get_sensitivity(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * buf)2209 static 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 
rtw_wx_set_mtk_wps_ie(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2216 static 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  *	For all data larger than 16 octets, we need to use a
2225  *	pointer to memory allocated in user space.
2226  */
rtw_drvext_hdl(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2227 static  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 
rtw_dbg_mode_hdl(struct adapter * padapter,u32 id,u8 * pdata,u32 len)2233 static 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 
rtw_mp_ioctl_hdl(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2316 static 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) {/* query info */
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 
rtw_get_ap_info(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2410 static 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 			/* BSSID match, then check if supporting wpa/wpa2 */
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 
2493 exit:
2494 
2495 	return ret;
2496 }
2497 
rtw_set_pid(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2498 static 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 	}
2520 exit:
2521 	return ret;
2522 }
2523 
rtw_wps_start(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2524 static 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) /*  WPS Start */
2552 		rtw_led_control(padapter, LED_CTL_START_WPS);
2553 	else if (u32wps_start == 2) /*  WPS Stop because of wps success */
2554 		rtw_led_control(padapter, LED_CTL_STOP_WPS);
2555 	else if (u32wps_start == 3) /*  WPS Stop because of wps fail */
2556 		rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);
2557 
2558 exit:
2559 	return ret;
2560 }
2561 
2562 #ifdef CONFIG_88EU_P2P
rtw_wext_p2p_enable(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2563 static 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 	/* set channel/bandwidth */
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 			/*	Stay at the listen state and wait for discovery. */
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 
2609 exit:
2610 	return ret;
2611 }
2612 
rtw_p2p_set_go_nego_ssid(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2613 static 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 
rtw_p2p_set_intent(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2628 static 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 
rtw_p2p_set_listen_ch(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2653 static 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;	/*	Listen channel number */
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 
rtw_p2p_set_op_ch(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2683 static 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 /*	Commented by Albert 20110524 */
2688 /*	This function is used to set the operating channel if the driver will become the group owner */
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;	/*	Operating channel number */
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 
rtw_p2p_profilefound(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2714 static 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 	/*	Comment by Albert 2010/10/13 */
2723 	/*	Input data format: */
2724 	/*	Ex:  0 */
2725 	/*	Ex:  1XX:XX:XX:XX:XX:XXYYSSID */
2726 	/*	0 => Reflush the profile record list. */
2727 	/*	1 => Add the profile list */
2728 	/*	XX:XX:XX:XX:XX:XX => peer's MAC Address (ex: 00:E0:4C:00:00:01) */
2729 	/*	YY => SSID Length */
2730 	/*	SSID => SSID for persistence group */
2731 
2732 	DBG_88E("[%s] In value = %s, len = %d\n", __func__, extra, wrqu->data.length - 1);
2733 
2734 	/*	The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function. */
2735 	if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
2736 		if (extra[0] == '0') {
2737 			/*	Remove all the profile information of wifidirect_info structure. */
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 				/*	Add this profile information into pwdinfo->profileinfo */
2747 				/*	Ex:  1XX:XX:XX:XX:XX:XXYYSSID */
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 
rtw_p2p_setDN(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2761 static 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 
rtw_p2p_get_status(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2777 static 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 	/*	Commented by Albert 2010/10/12 */
2791 	/*	Because of the output size limitation, I had removed the "Role" information. */
2792 	/*	About the "Role" information, we will use the new private IOCTL to get the "Role" information. */
2793 	sprintf(extra, "\n\nStatus =%.2d\n", rtw_p2p_state(pwdinfo));
2794 	wrqu->data.length = strlen(extra);
2795 
2796 	return ret;
2797 }
2798 
2799 /*	Commented by Albert 20110520 */
2800 /*	This function will return the config method description */
2801 /*	This config method description will show us which config method the remote P2P device is intended to use */
2802 /*	by sending the provisioning discovery request frame. */
2803 
rtw_p2p_get_req_cm(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2804 static 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 
rtw_p2p_get_role(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2817 static 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 
rtw_p2p_get_peer_ifaddr(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2834 static 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 
rtw_p2p_get_peer_devaddr(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2851 static 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 
rtw_p2p_get_peer_devaddr_by_invitation(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2869 static 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 
rtw_p2p_get_groupid(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2887 static 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 
rtw_p2p_get_op_ch(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2905 static 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 
rtw_p2p_get_wps_configmethod(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2921 static 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 	/* 6 is the string "wpsCM =", 17 is the MAC addr, we have to clear it at wrqu->data.pointer */
2938 	u8 attr_content_str[6 + 17] = {0x00};
2939 
2940 	/*	Commented by Albert 20110727 */
2941 	/*	The input data is the MAC address which the application wants to know its WPS config method. */
2942 	/*	After knowing its WPS config method, the application can decide the config method for provisioning discovery. */
2943 	/*	Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05 */
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 			/*  The mac address is matched. */
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 
rtw_p2p_get_go_device_address(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2989 static 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 	/*  +10 is for the str "go_devadd =", we have to clear it at wrqu->data.pointer */
3009 
3010 	/*	Commented by Albert 20121209 */
3011 	/*	The input data is the GO's interface address which the application wants to know its device address. */
3012 	/*	Format: iwpriv wlanx p2p_get2 go_devadd = 00:E0:4C:00:00:05 */
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 			/*	Commented by Albert 2011/05/18 */
3030 			/*	Match the device address located in the P2P IE */
3031 			/*	This is for the case that the P2P device address is not the same as the P2P interface address. */
3032 
3033 			p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
3034 			if (p2pie) {
3035 				while (p2pie) {
3036 					/*	The P2P Device ID attribute is included in the Beacon frame. */
3037 					/*	The P2P Device Info attribute is included in the probe response frame. */
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 						/*	Handle the P2P Device ID attribute of Beacon first */
3042 						blnMatch = 1;
3043 						break;
3044 					} else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
3045 						/*	Handle the P2P Device Info attribute of probe response */
3046 						blnMatch = 1;
3047 						break;
3048 					}
3049 
3050 					/* Get the next P2P IE */
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 
rtw_p2p_get_device_type(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3072 static 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};	/*  +9 is for the str "dev_type =", we have to clear it at wrqu->data.pointer */
3089 
3090 	/*	Commented by Albert 20121209 */
3091 	/*	The input data is the MAC address which the application wants to know its device type. */
3092 	/*	Such user interface could know the device type. */
3093 	/*	Format: iwpriv wlanx p2p_get2 dev_type = 00:E0:4C:00:00:05 */
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 		/*	The mac address is matched. */
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 
rtw_p2p_get_device_name(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3148 static 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};	/*  +5 is for the str "devN =", we have to clear it at wrqu->data.pointer */
3165 
3166 	/*	Commented by Albert 20121225 */
3167 	/*	The input data is the MAC address which the application wants to know its device name. */
3168 	/*	Such user interface could show peer device's device name instead of ssid. */
3169 	/*	Format: iwpriv wlanx p2p_get2 devN = 00:E0:4C:00:00:05 */
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 			/*	The mac address is matched. */
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 
rtw_p2p_get_invitation_procedure(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3214 static 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 	/*  +8 is for the str "InvProc =", we have to clear it at wrqu->data.pointer */
3234 
3235 	/*	Commented by Ouden 20121226 */
3236 	/*	The application wants to know P2P initiation procedure is supported or not. */
3237 	/*	Format: iwpriv wlanx p2p_get2 InvProc = 00:E0:4C:00:00:05 */
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 			/*	Commented by Albert 20121226 */
3255 			/*	Match the device address located in the P2P IE */
3256 			/*	This is for the case that the P2P device address is not the same as the P2P interface address. */
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 						/*	Handle the P2P capability attribute */
3263 						blnMatch = 1;
3264 						break;
3265 					}
3266 
3267 					/* Get the next P2P IE */
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 
rtw_p2p_connect(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3290 static 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 	/*	Commented by Albert 20110304 */
3306 	/*	The input data contains two informations. */
3307 	/*	1. First information is the MAC address which wants to formate with */
3308 	/*	2. Second information is the WPS PINCode or "pbc" string for push button method */
3309 	/*	Format: 00:E0:4C:00:00:05 */
3310 	/*	Format: 00:E0:4C:00:00:05 */
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 			/*	Restore to the listen state if the current p2p state is not nego OK */
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 
rtw_p2p_invite_req(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3369 static 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 	/*	The input data contains two informations. */
3388 	/*	1. First information is the P2P device address which you want to send to. */
3389 	/*	2. Second information is the group id which combines with GO's mac address, space and GO's ssid. */
3390 	/*	Command line sample: iwpriv wlan0 p2p_set invite ="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */
3391 	/*	Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy */
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 		/*	Reset the content of struct tx_invite_req_info */
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 		/*	Commented by Albert 2011/05/18 */
3426 		/*	Match the device address located in the P2P IE */
3427 		/*	This is for the case that the P2P device address is not the same as the P2P interface address. */
3428 
3429 		p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
3430 		if (p2pie) {
3431 			/*	The P2P Device ID attribute is included in the Beacon frame. */
3432 			/*	The P2P Device Info attribute is included in the probe response frame. */
3433 
3434 			if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
3435 				/*	Handle the P2P Device ID attribute of Beacon first */
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 				/*	Handle the P2P Device Info attribute of probe response */
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 		/*	Store the GO's bssid */
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 		/*	Store the GO's ssid */
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 
rtw_p2p_set_persistent(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3478 static 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 	/*	The input data is 0 or 1 */
3487 	/*	0: disable persistent group functionality */
3488 	/*	1: enable persistent group founctionality */
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')	/*	Disable the persistent group function. */
3497 			pwdinfo->persistent_supported = false;
3498 		else if (extra[0] == '1')	/*	Enable the persistent group function. */
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 
rtw_p2p_prov_disc(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3507 static 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 	/*	The input data contains two informations. */
3526 	/*	1. First information is the MAC address which wants to issue the provisioning discovery request frame. */
3527 	/*	2. Second information is the WPS configuration method which wants to discovery */
3528 	/*	Format: 00:E0:4C:00:00:05_display */
3529 	/*	Format: 00:E0:4C:00:00:05_keypad */
3530 	/*	Format: 00:E0:4C:00:00:05_pbc */
3531 	/*	Format: 00:E0:4C:00:00:05_label */
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 		/*	Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request. */
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 		/*	Commented by Albert 2011/05/18 */
3576 		/*	Match the device address located in the P2P IE */
3577 		/*	This is for the case that the P2P device address is not the same as the P2P interface address. */
3578 
3579 		p2pie = rtw_get_p2p_ie(&pnetwork->network.IEs[12], pnetwork->network.IELength - 12, NULL, &p2pielen);
3580 		if (p2pie) {
3581 			while (p2pie) {
3582 				/*	The P2P Device ID attribute is included in the Beacon frame. */
3583 				/*	The P2P Device Info attribute is included in the probe response frame. */
3584 
3585 				if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
3586 					/*	Handle the P2P Device ID attribute of Beacon first */
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 					/*	Handle the P2P Device Info attribute of probe response */
3593 					if (!memcmp(attr_content, peerMAC, ETH_ALEN)) {
3594 						uintPeerChannel = pnetwork->network.Configuration.DSConfig;
3595 						break;
3596 					}
3597 				}
3598 
3599 				/* Get the next P2P IE */
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 /*	This function is used to inform the driver the user had specified the pin code value or pbc */
3637 /*	to application. */
3638 
rtw_p2p_got_wpsinfo(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3639 static 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 	/*	Added by Albert 20110328 */
3649 	/*	if the input data is P2P_NO_WPSINFO -> reset the wpsinfo */
3650 	/*	if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device. */
3651 	/*	if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself. */
3652 	/*	if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC */
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 /* CONFIG_88EU_P2P */
3668 
rtw_p2p_set(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3669 static 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 		/*	Commented by Albert 2011/03/23 */
3693 		/*	The wrqu->data.length will include the null character */
3694 		/*	So, we will decrease 7 + 1 */
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 		/*	Commented by Albert 2011/05/24 */
3705 		/*	The wrqu->data.length will include the null character */
3706 		/*	So, we will decrease (10 + 1) */
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 		/*	Commented by Albert 2011/05/24 */
3711 		/*	The wrqu->data.length will include the null character */
3712 		/*	So, we will decrease (6 + 1) */
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 /* CONFIG_88EU_P2P */
3723 
3724 	return ret;
3725 }
3726 
rtw_p2p_get(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3727 static 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 		/*	Get the P2P device address when receiving the provision discovery request frame. */
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 		/*	Get the P2P device address when receiving the P2P Invitation request frame. */
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 /* CONFIG_88EU_P2P */
3758 	return ret;
3759 }
3760 
rtw_p2p_get2(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3761 static 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 /* CONFIG_88EU_P2P */
3787 
3788 	return ret;
3789 }
3790 
rtw_cta_test_start(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3791 static 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);/*  RCR_ADF */
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;/*  RCR_ADF */
3811 		rtw_write32(padapter, REG_RCR, v);
3812 		DBG_88E("disable RCR_ADF\n");
3813 	}
3814 	return ret;
3815 }
3816 
rtw_rereg_nd_name(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3817 static 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 		/*  free network queue for Android's timming issue */
3860 		rtw_free_network_queue(padapter, true);
3861 
3862 		/*  close led */
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 		/*  the interface is being "disabled", we can do deeper IPS */
3869 		rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv);
3870 		rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL);
3871 	}
3872 exit:
3873 	return ret;
3874 }
3875 
mac_reg_dump(struct adapter * padapter)3876 static 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 
bb_reg_dump(struct adapter * padapter)3896 static 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 
rf_reg_dump(struct adapter * padapter)3910 static 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 
rtw_dbg_port(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3936 static 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:/* read_reg */
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:/* write_reg */
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:/* read_bb */
3994 		DBG_88E("read_bbreg(0x%x) = 0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
3995 		break;
3996 	case 0x73:/* write_bb */
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:/* read_rf */
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:/* write_rf */
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: /* normal mode, */
4011 			padapter->recvpriv.is_signal_dbg = 0;
4012 			break;
4013 		case 0x01: /* dbg mode */
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: /* IOL test */
4022 		switch (minor_cmd) {
4023 		case 0x04: /* LLT table initialization test */
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: /* blink LED test */
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: /* continuous write byte test */
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: /* continuous write word test */
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: /* continuous write dword test */
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 			* dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15
4157 			* dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15
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:/* dump rx/tx packet */
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:/*  driver version display */
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: /* set rx_stbc */
4325 		{
4326 			struct registry_priv	*pregpriv = &padapter->registrypriv;
4327 			/*  0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g */
4328 			/* default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */
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: /* set ampdu_enable */
4342 		{
4343 			struct registry_priv	*pregpriv = &padapter->registrypriv;
4344 			/*  0: disable, 0x1:enable (but wifi_spec should be 0), 0x2: force enable (don't care wifi_spec) */
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: /* get wifi_spec */
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 /*  CONFIG_88EU_P2P */
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:/* registers dump, 0 for mac reg, 1 for bb reg, 2 for rf reg */
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:/* turn on/off dynamic funcs */
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 					/*	extra_arg = 0  - disable all dynamic func
4399 						extra_arg = 1  - disable DIG
4400 						extra_arg = 2  - disable tx power tracking
4401 						extra_arg = 3  - turn on all dynamic func
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 
rtw_wx_set_priv(struct net_device * dev,struct iw_request_info * info,union iwreq_data * awrq,char * extra)4455 static 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 	/* added for wps2.0 @20110524 */
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 
4512 FREE_EXT:
4513 
4514 	vfree(ext);
4515 
4516 	return ret;
4517 }
4518 
rtw_pm_set(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)4519 static 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 
rtw_mp_efuse_get(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wdata,char * extra)4542 static 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;/*  0:Disable, 1:enable, 2:by usb speed */
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;/* keep org value */
4584 	rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
4585 
4586 	ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
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 	/* mac 16 "00e04c871200" rmap, 00, 2 */
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;/*  0:Disable, 1:enable, 2:by usb speed */
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 		/*  rmap addr cnts */
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 			/*  set 512 because the iwpriv's extra size have limit 0x7FF */
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 		/*  rmap addr cnts */
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 
4847 exit:
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;/*  0:Disable, 1:enable, 2:by usb speed */
4856 	return err;
4857 }
4858 
rtw_mp_efuse_set(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wdata,char * extra)4859 static 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;/* keep org value */
4905 	rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
4906 
4907 	ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
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 	/*  tmp[0],[1],[2] */
4922 	/*  wmap, addr, 00e04c871200 */
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 		/* Change to check TYPE_EFUSE_MAP_LEN, because 8188E raw 256, logic map over 256. */
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 		/* mac, 00e04c871200 */
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 		/* Change to check TYPE_EFUSE_MAP_LEN, because 8188E raw 256, logic map over 256. */
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 		/*  pidvid, da0b7881 */
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 
5208 exit:
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  * Input Format: %s,%d,%d
5222  *	%s is width, could be
5223  *		"b" for 1 byte
5224  *		"w" for WORD (2 bytes)
5225  *		"dw" for DWORD (4 bytes)
5226  *	1st %d is address(offset)
5227  *	2st %d is data to write
5228  */
rtw_mp_write_reg(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5229 static 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 		/*  1 byte */
5266 		if (data > 0xFF) {
5267 			ret = -EINVAL;
5268 			break;
5269 		}
5270 		rtw_write8(padapter, addr, data);
5271 		break;
5272 	case 'w':
5273 		/*  2 bytes */
5274 		if (data > 0xFFFF) {
5275 			ret = -EINVAL;
5276 			break;
5277 		}
5278 		rtw_write16(padapter, addr, data);
5279 		break;
5280 	case 'd':
5281 		/*  4 bytes */
5282 		rtw_write32(padapter, addr, data);
5283 		break;
5284 	default:
5285 		ret = -EINVAL;
5286 		break;
5287 	}
5288 
5289 	return ret;
5290 }
5291 
5292 /*
5293  * Input Format: %s,%d
5294  *	%s is width, could be
5295  *		"b" for 1 byte
5296  *		"w" for WORD (2 bytes)
5297  *		"dw" for DWORD (4 bytes)
5298  *	%d is address(offset)
5299  *
5300  * Return:
5301  *	%d for data readed
5302  */
rtw_mp_read_reg(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5303 static 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 		/*  1 byte */
5350 		sprintf(extra, "%d\n",  rtw_read8(padapter, addr));
5351 		wrqu->length = strlen(extra);
5352 		break;
5353 	case 'w':
5354 		/*  2 bytes */
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 		/*  4 bytes */
5386 		sprintf(data, "%08x", rtw_read32(padapter, addr));
5387 		/* add read data format blank */
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  * Input Format: %d,%x,%x
5427  *	%d is RF path, should be smaller than RF_PATH_MAX
5428  *	1st %x is address(offset)
5429  *	2st %x is data to write
5430  */
rtw_mp_write_rf(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)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  * Input Format: %d,%x
5462  *	%d is RF path, should be smaller than RF_PATH_MAX
5463  *	%x is address(offset)
5464  *
5465  * Return:
5466  *	%d for data readed
5467  */
rtw_mp_read_rf(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5468 static 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 	/* add read data format blank */
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 
rtw_mp_start(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5525 static 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 
rtw_mp_stop(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5549 static 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 
5568 extern int wifirate2_ratetbl_inx(unsigned char rate);
5569 
rtw_mp_rate(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5570 static 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 
rtw_mp_channel(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5602 static 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 
rtw_mp_bandwidth(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5627 static 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 
rtw_mp_txpower(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5647 static 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 
rtw_mp_ant_tx(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5674 static 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 
rtw_mp_ant_rx(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5711 static 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 
rtw_mp_ctx(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5748 static 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); /*  strncmp true is 0 */
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; /*  To set Stop */
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 
rtw_mp_arx(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5870 static 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; /*  strncmp true is 0 */
5889 	bStopRx = (strncmp(input, "stop", 5) == 0) ? 1 : 0; /*  strncmp true is 0 */
5890 	bQueryPhy = (strncmp(input, "phy", 3) == 0) ? 1 : 0; /*  strncmp true is 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 		OFDM FA
5901 		RegCF0[15:0]
5902 		RegCF2[31:16]
5903 		RegDA0[31:16]
5904 		RegDA4[15:0]
5905 		RegDA4[31:16]
5906 		RegDA8[15:0]
5907 		CCK FA
5908 		(RegA5B<<8) | RegA5C
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 
rtw_mp_trx_query(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5932 static 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 
rtw_mp_pwrtrk(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5953 static 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) {/*  not empty string */
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 
rtw_mp_psd(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)5996 static 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 
rtw_mp_thermal(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)6017 static 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); /*  strncmp true is 0 */
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 
rtw_mp_reset_stats(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)6056 static 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 	/* reset phy counter */
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 
rtw_mp_dump(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)6078 static 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 
rtw_mp_phypara(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)6127 static 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 
rtw_mp_SetRFPath(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)6149 static 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); /*  strncmp true is 0 */
6164 	bTurnoff = strncmp(input, "0", 3); /*  strncmp true is 0 */
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 
rtw_mp_QueryDrv(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)6177 static 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); /*  strncmp true is 0 */
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 
rtw_mp_set(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wdata,char * extra)6208 static 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 
rtw_mp_get(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wdata,char * extra)6254 static 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); /* delay 5ms for sending pkt before exit adb shell operation */
6350 	return 0;
6351 }
6352 
rtw_tdls(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)6353 static 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 
rtw_tdls_get(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)6360 static 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 
rtw_test(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)6367 static 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 
6404 static 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 
6447 static 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, ""},  /* set */
6539 	{SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, ""},/* get */
6540 /* --- sub-ioctls definitions --- */
6541 
6542 	{MP_START, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_start"}, /* set */
6543 	{MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara"},/* get */
6544 	{MP_STOP, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_stop"}, /* set */
6545 	{MP_CHANNEL, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel"},/* get */
6546 	{MP_BANDWIDTH, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_bandwidth"}, /* set */
6547 	{MP_RATE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate"},/* get */
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"}, /* get */
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"}, /*  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 
6572 static iw_handler rtw_private_handler[] = {
6573 rtw_wx_write32,				/* 0x00 */
6574 rtw_wx_read32,				/* 0x01 */
6575 rtw_drvext_hdl,				/* 0x02 */
6576 rtw_mp_ioctl_hdl,			/* 0x03 */
6577 
6578 /*  for MM DTV platform */
6579 	rtw_get_ap_info,		/* 0x04 */
6580 
6581 	rtw_set_pid,			/* 0x05 */
6582 	rtw_wps_start,			/* 0x06 */
6583 
6584 	rtw_wx_get_sensitivity,		/* 0x07 */
6585 	rtw_wx_set_mtk_wps_probe_ie,	/* 0x08 */
6586 	rtw_wx_set_mtk_wps_ie,		/* 0x09 */
6587 
6588 /*  Set Channel depend on the country code */
6589 	rtw_wx_set_channel_plan,	/* 0x0A */
6590 
6591 	rtw_dbg_port,			/* 0x0B */
6592 	rtw_wx_write_rf,		/* 0x0C */
6593 	rtw_wx_read_rf,			/* 0x0D */
6594 
6595 	rtw_mp_set,			/* 0x0E */
6596 	rtw_mp_get,			/* 0x0F */
6597 	rtw_p2p_set,			/* 0x10 */
6598 	rtw_p2p_get,			/* 0x11 */
6599 	rtw_p2p_get2,			/* 0x12 */
6600 
6601 	NULL,				/* 0x13 */
6602 	rtw_tdls,			/* 0x14 */
6603 	rtw_tdls_get,			/* 0x15 */
6604 
6605 	rtw_pm_set,			/* 0x16 */
6606 	rtw_wx_priv_null,		/* 0x17 */
6607 	rtw_rereg_nd_name,		/* 0x18 */
6608 	rtw_wx_priv_null,		/* 0x19 */
6609 
6610 	rtw_mp_efuse_set,		/* 0x1A */
6611 	rtw_mp_efuse_get,		/* 0x1B */
6612 	NULL,				/*  0x1C is reserved for hostapd */
6613 	rtw_test,			/*  0x1D */
6614 };
6615 
rtw_get_wireless_stats(struct net_device * dev)6616 static 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 
6641 struct 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