xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8188fu/os_dep/linux/ioctl_mp.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2017 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #if defined(CONFIG_MP_INCLUDED)
16 
17 #include <drv_types.h>
18 #include <rtw_mp.h>
19 #include "../../hal/phydm/phydm_precomp.h"
20 #include <linux/ctype.h>
21 
22 
23 #if defined(CONFIG_RTL8723B)
24 	#include <rtw_bt_mp.h>
25 #endif
26 
27 #define RTW_IWD_MAX_LEN	128
rtw_do_mp_iwdata_len_chk(const char * caller,u32 len)28 inline u8 rtw_do_mp_iwdata_len_chk(const char *caller, u32 len)
29 {
30 	u8 is_illegal = _FALSE;
31 	if (len >= RTW_IWD_MAX_LEN) {
32 		RTW_ERR("%s : iw data len(%u) > RTW_IWD_MAX_LEN(%u)",
33 			caller, len, RTW_IWD_MAX_LEN);
34 		is_illegal = _TRUE;
35 	}
36 	return is_illegal;
37 }
38 
39 /*
40  * Input Format: %s,%d,%d
41  *	%s is width, could be
42  *		"b" for 1 byte
43  *		"w" for WORD (2 bytes)
44  *		"dw" for DWORD (4 bytes)
45  *	1st %d is address(offset)
46  *	2st %d is data to write
47  */
rtw_mp_write_reg(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)48 int rtw_mp_write_reg(struct net_device *dev,
49 		     struct iw_request_info *info,
50 		     struct iw_point *wrqu, char *extra)
51 {
52 	char *pch, *pnext;
53 	char *width_str;
54 	char width;
55 	u32 addr, data;
56 	int ret;
57 	PADAPTER padapter = rtw_netdev_priv(dev);
58 	char input[RTW_IWD_MAX_LEN];
59 
60 	if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1)))
61 		return -EFAULT;
62 
63 	_rtw_memset(input, 0, sizeof(input));
64 
65 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
66 		return -EFAULT;
67 
68 	input[wrqu->length] = '\0';
69 
70 	_rtw_memset(extra, 0, wrqu->length);
71 
72 	pch = input;
73 
74 	pnext = strpbrk(pch, " ,.-");
75 	if (pnext == NULL)
76 		return -EINVAL;
77 	*pnext = 0;
78 	width_str = pch;
79 
80 	pch = pnext + 1;
81 	pnext = strpbrk(pch, " ,.-");
82 	if (pnext == NULL)
83 		return -EINVAL;
84 	*pnext = 0;
85 	/*addr = simple_strtoul(pch, &ptmp, 16);
86 	_rtw_memset(buf, '\0', sizeof(buf));
87 	_rtw_memcpy(buf, pch, pnext-pch);
88 	ret = kstrtoul(buf, 16, &addr);*/
89 	ret = sscanf(pch, "%x", &addr);
90 
91 	pch = pnext + 1;
92 	pnext = strpbrk(pch, " ,.-");
93 	if ((pch - input) >= wrqu->length)
94 		return -EINVAL;
95 	/*data = simple_strtoul(pch, &ptmp, 16);*/
96 	ret = sscanf(pch, "%x", &data);
97 	RTW_INFO("data=%x,addr=%x\n", (u32)data, (u32)addr);
98 	ret = 0;
99 	width = width_str[0];
100 	switch (width) {
101 	case 'b':
102 		/* 1 byte*/
103 		if (data > 0xFF) {
104 			ret = -EINVAL;
105 			break;
106 		}
107 		rtw_write8(padapter, addr, data);
108 		break;
109 	case 'w':
110 		/* 2 bytes*/
111 		if (data > 0xFFFF) {
112 			ret = -EINVAL;
113 			break;
114 		}
115 		rtw_write16(padapter, addr, data);
116 		break;
117 	case 'd':
118 		/* 4 bytes*/
119 		rtw_write32(padapter, addr, data);
120 		break;
121 	default:
122 		ret = -EINVAL;
123 		break;
124 	}
125 
126 	return ret;
127 }
128 
129 
130 /*
131  * Input Format: %s,%d
132  *	%s is width, could be
133  *		"b" for 1 byte
134  *		"w" for WORD (2 bytes)
135  *		"dw" for DWORD (4 bytes)
136  *	%d is address(offset)
137  *
138  * Return:
139  *	%d for data readed
140  */
rtw_mp_read_reg(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)141 int rtw_mp_read_reg(struct net_device *dev,
142 		    struct iw_request_info *info,
143 		    struct iw_point *wrqu, char *extra)
144 {
145 	char input[RTW_IWD_MAX_LEN];
146 	char *pch, *pnext;
147 	char *width_str;
148 	char width;
149 	char data[20], tmp[20];
150 	u32 addr = 0, strtout = 0;
151 	u32 i = 0, j = 0, ret = 0, data32 = 0;
152 	PADAPTER padapter = rtw_netdev_priv(dev);
153 	char *pextra = extra;
154 
155 	if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1)))
156 		return -EFAULT;
157 
158 	if (wrqu->length > 128)
159 		return -EFAULT;
160 
161 	_rtw_memset(input, 0, sizeof(input));
162 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
163 		return -EFAULT;
164 
165 	input[wrqu->length] = '\0';
166 	_rtw_memset(extra, 0, wrqu->length);
167 	_rtw_memset(data, '\0', sizeof(data));
168 	_rtw_memset(tmp, '\0', sizeof(tmp));
169 	pch = input;
170 	pnext = strpbrk(pch, " ,.-");
171 	if (pnext == NULL)
172 		return -EINVAL;
173 	*pnext = 0;
174 	width_str = pch;
175 
176 	pch = pnext + 1;
177 
178 	ret = sscanf(pch, "%x", &addr);
179 	if (addr > MP_READ_REG_MAX_OFFSET)
180 		return -EINVAL;
181 
182 	ret = 0;
183 	width = width_str[0];
184 
185 	switch (width) {
186 	case 'b':
187 		data32 = rtw_read8(padapter, addr);
188 		RTW_INFO("%x\n", data32);
189 		sprintf(extra, "%d", data32);
190 		wrqu->length = strlen(extra);
191 		break;
192 	case 'w':
193 		/* 2 bytes*/
194 		sprintf(data, "%04x\n", rtw_read16(padapter, addr));
195 
196 		for (i = 0 ; i <= strlen(data) ; i++) {
197 			if (i % 2 == 0) {
198 				tmp[j] = ' ';
199 				j++;
200 			}
201 			if (data[i] != '\0')
202 				tmp[j] = data[i];
203 
204 			j++;
205 		}
206 		pch = tmp;
207 		RTW_INFO("pch=%s", pch);
208 
209 		while (*pch != '\0') {
210 			pnext = strpbrk(pch, " ");
211 			if (!pnext || ((pnext - tmp) > 4))
212 				break;
213 
214 			pnext++;
215 			if (*pnext != '\0') {
216 				/*strtout = simple_strtoul(pnext , &ptmp, 16);*/
217 				ret = sscanf(pnext, "%x", &strtout);
218 				pextra += sprintf(pextra, " %d", strtout);
219 			} else
220 				break;
221 			pch = pnext;
222 		}
223 		wrqu->length = strlen(extra);
224 		break;
225 	case 'd':
226 		/* 4 bytes */
227 		sprintf(data, "%08x", rtw_read32(padapter, addr));
228 		/*add read data format blank*/
229 		for (i = 0 ; i <= strlen(data) ; i++) {
230 			if (i % 2 == 0) {
231 				tmp[j] = ' ';
232 				j++;
233 			}
234 			if (data[i] != '\0')
235 				tmp[j] = data[i];
236 
237 			j++;
238 		}
239 		pch = tmp;
240 		RTW_INFO("pch=%s", pch);
241 
242 		while (*pch != '\0') {
243 			pnext = strpbrk(pch, " ");
244 			if (!pnext)
245 				break;
246 
247 			pnext++;
248 			if (*pnext != '\0') {
249 				ret = sscanf(pnext, "%x", &strtout);
250 				pextra += sprintf(pextra, " %d", strtout);
251 			} else
252 				break;
253 			pch = pnext;
254 		}
255 		wrqu->length = strlen(extra);
256 		break;
257 
258 	default:
259 		wrqu->length = 0;
260 		ret = -EINVAL;
261 		break;
262 	}
263 
264 	return ret;
265 }
266 
267 
268 /*
269  * Input Format: %d,%x,%x
270  *	%d is RF path, should be smaller than MAX_RF_PATH_NUMS
271  *	1st %x is address(offset)
272  *	2st %x is data to write
273  */
rtw_mp_write_rf(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)274 int rtw_mp_write_rf(struct net_device *dev,
275 		    struct iw_request_info *info,
276 		    struct iw_point *wrqu, char *extra)
277 {
278 	u32 path, addr, data;
279 	int ret;
280 	PADAPTER padapter = rtw_netdev_priv(dev);
281 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
282 	char input[RTW_IWD_MAX_LEN];
283 
284 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
285 		return -EFAULT;
286 
287 	_rtw_memset(input, 0, wrqu->length);
288 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
289 		return -EFAULT;
290 
291 
292 	ret = sscanf(input, "%d,%x,%x", &path, &addr, &data);
293 	if (ret < 3)
294 		return -EINVAL;
295 
296 	if (path >= hal_spec->rf_reg_path_num)
297 		return -EINVAL;
298 	if (addr > 0xFF)
299 		return -EINVAL;
300 	if (data > 0xFFFFF)
301 		return -EINVAL;
302 
303 	_rtw_memset(extra, 0, wrqu->length);
304 
305 	write_rfreg(padapter, path, addr, data);
306 
307 	sprintf(extra, "write_rf completed\n");
308 	wrqu->length = strlen(extra);
309 
310 	return 0;
311 }
312 
313 
314 /*
315  * Input Format: %d,%x
316  *	%d is RF path, should be smaller than MAX_RF_PATH_NUMS
317  *	%x is address(offset)
318  *
319  * Return:
320  *	%d for data readed
321  */
rtw_mp_read_rf(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)322 int rtw_mp_read_rf(struct net_device *dev,
323 		   struct iw_request_info *info,
324 		   struct iw_point *wrqu, char *extra)
325 {
326 	char input[RTW_IWD_MAX_LEN];
327 	char *pch, *pnext;
328 	char data[20], tmp[20];
329 	u32 path, addr, strtou;
330 	u32 ret, i = 0 , j = 0;
331 	PADAPTER padapter = rtw_netdev_priv(dev);
332 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
333 	char *pextra = extra;
334 
335 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
336 		return -EFAULT;
337 
338 	if (wrqu->length > 128)
339 		return -EFAULT;
340 	_rtw_memset(input, 0, wrqu->length);
341 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
342 		return -EFAULT;
343 
344 	ret = sscanf(input, "%d,%x", &path, &addr);
345 	if (ret < 2)
346 		return -EINVAL;
347 
348 	if (path >= hal_spec->rf_reg_path_num)
349 		return -EINVAL;
350 
351 	if (addr > MP_READ_REG_MAX_OFFSET)
352 		return -EINVAL;
353 
354 	_rtw_memset(extra, 0, wrqu->length);
355 
356 	sprintf(data, "%08x", read_rfreg(padapter, path, addr));
357 	/*add read data format blank*/
358 	for (i = 0 ; i <= strlen(data) ; i++) {
359 		if (i % 2 == 0) {
360 			tmp[j] = ' ';
361 			j++;
362 		}
363 		tmp[j] = data[i];
364 		j++;
365 	}
366 	pch = tmp;
367 	RTW_INFO("pch=%s", pch);
368 
369 	while (*pch != '\0') {
370 		pnext = strpbrk(pch, " ");
371 		if (!pnext)
372 			break;
373 		pnext++;
374 		if (*pnext != '\0') {
375 			/*strtou =simple_strtoul(pnext , &ptmp, 16);*/
376 			ret = sscanf(pnext, "%x", &strtou);
377 			pextra += sprintf(pextra, " %d", strtou);
378 		} else
379 			break;
380 		pch = pnext;
381 	}
382 	wrqu->length = strlen(extra);
383 
384 	return 0;
385 }
386 
387 
rtw_mp_start(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)388 int rtw_mp_start(struct net_device *dev,
389 		 struct iw_request_info *info,
390 		 struct iw_point *wrqu, char *extra)
391 {
392 	int ret = 0;
393 	PADAPTER padapter = rtw_netdev_priv(dev);
394 	struct mp_priv *pmppriv = &padapter->mppriv;
395 
396 	rtw_pm_set_ips(padapter, IPS_NONE);
397 	LeaveAllPowerSaveMode(padapter);
398 
399 	pmppriv->bprocess_mp_mode = _TRUE;
400 
401 	if (rtw_mi_check_fwstate(padapter, WIFI_UNDER_SURVEY)) {
402 		rtw_mi_buddy_set_scan_deny(padapter, 5000);
403 		rtw_mi_scan_abort(padapter, _TRUE);
404 	}
405 
406 	rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
407 
408 	if (rtw_mp_cmd(padapter, MP_START, RTW_CMDF_WAIT_ACK) != _SUCCESS)
409 		ret = -EPERM;
410 
411 	_rtw_memset(extra, 0, wrqu->length);
412 	sprintf(extra, "mp_start %s\n", ret == 0 ? "ok" : "fail");
413 	wrqu->length = strlen(extra);
414 
415 	return ret;
416 }
417 
418 
419 
rtw_mp_stop(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)420 int rtw_mp_stop(struct net_device *dev,
421 		struct iw_request_info *info,
422 		struct iw_point *wrqu, char *extra)
423 {
424 	int ret = 0;
425 	PADAPTER padapter = rtw_netdev_priv(dev);
426 	struct mp_priv *pmppriv = &padapter->mppriv;
427 
428 	if (pmppriv->mode != MP_ON)
429 		return -EPERM;
430 
431 	if (rtw_mp_cmd(padapter, MP_STOP, RTW_CMDF_WAIT_ACK) != _SUCCESS)
432 		ret = -EPERM;
433 
434 	pmppriv->bprocess_mp_mode = _FALSE;
435 	_rtw_memset(extra, 0, wrqu->length);
436 	sprintf(extra, "mp_stop %s\n", ret == 0 ? "ok" : "fail");
437 	wrqu->length = strlen(extra);
438 
439 	return ret;
440 }
441 
442 
rtw_mp_rate(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)443 int rtw_mp_rate(struct net_device *dev,
444 		struct iw_request_info *info,
445 		struct iw_point *wrqu, char *extra)
446 {
447 	u32 rate = MPT_RATE_1M;
448 	u8 err = 0;
449 	u8 input[RTW_IWD_MAX_LEN];
450 	PADAPTER padapter = rtw_netdev_priv(dev);
451 	PMPT_CONTEXT		pMptCtx = &(padapter->mppriv.mpt_ctx);
452 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
453 	struct	mp_priv	*pmppriv = &padapter->mppriv;
454 
455 	if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1)))
456 		return -EFAULT;
457 
458 	_rtw_memset(input, 0, sizeof(input));
459 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
460 		return -EFAULT;
461 
462 	input[wrqu->length] = '\0';
463 	rate = rtw_mpRateParseFunc(padapter, input);
464 	pmppriv->rateidx = rate;
465 
466 	if (rate == 0 && strcmp(input, "1M") != 0) {
467 		rate = rtw_atoi(input);
468 		if (rate <= MGN_VHT4SS_MCS9)
469 			pmppriv->rateidx = MRateToHwRate(rate);
470 		/*if (rate <= 0x7f)
471 			rate = wifirate2_ratetbl_inx((u8)rate);
472 		else if (rate < 0xC8)
473 			rate = (rate - 0x79 + MPT_RATE_MCS0);
474 		HT  rate 0x80(MCS0)  ~ 0x8F(MCS15) ~ 0x9F(MCS31) 128~159
475 		VHT1SS~2SS rate 0xA0 (VHT1SS_MCS0 44) ~ 0xB3 (VHT2SS_MCS9 #63) 160~179
476 		VHT rate 0xB4 (VHT3SS_MCS0 64) ~ 0xC7 (VHT2SS_MCS9 #83) 180~199
477 		else
478 		VHT rate 0x90(VHT1SS_MCS0) ~ 0x99(VHT1SS_MCS9) 144~153
479 		rate =(rate - MPT_RATE_VHT1SS_MCS0);
480 		*/
481 	}
482 
483 	_rtw_memset(extra, 0, wrqu->length);
484 
485 	if (pmppriv->rateidx > DESC_RATEVHTSS4MCS9) {
486 		sprintf(extra, "Set %s Error" , input);
487 		return -EINVAL;
488 	}
489 
490 	if (hal_spec->tx_nss_num < 2 && MPT_IS_2SS_RATE(HwRateToMPTRate(pmppriv->rateidx)))
491 		err = 1;
492 	if (hal_spec->tx_nss_num < 3 && MPT_IS_3SS_RATE(HwRateToMPTRate(pmppriv->rateidx)))
493 		err = 1;
494 	if (hal_spec->tx_nss_num < 4 && MPT_IS_4SS_RATE(HwRateToMPTRate(pmppriv->rateidx)))
495 		err = 1;
496 	if (!is_supported_vht(padapter->registrypriv.wireless_mode) && MPT_IS_VHT_RATE(HwRateToMPTRate(pmppriv->rateidx)))
497 		err = 1;
498 	if (!is_supported_ht(padapter->registrypriv.wireless_mode) && MPT_IS_HT_RATE(HwRateToMPTRate(pmppriv->rateidx)))
499 		err = 1;
500 
501 	if (err == 1) {
502 		sprintf(extra, "Set data rate to %s Error" , input);
503 		pmppriv->rateidx = 0;
504 	} else {
505 		sprintf(extra, "Set data rate to %s index %d" , input, pmppriv->rateidx);
506 		RTW_INFO("%s: %s rate index=%d\n", __func__, input, pmppriv->rateidx);
507 		pMptCtx->mpt_rate_index = HwRateToMPTRate(pmppriv->rateidx);
508 		SetDataRate(padapter);
509 	}
510 	wrqu->length = strlen(extra);
511 	return err;
512 }
513 
rtw_mp_channel(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)514 int rtw_mp_channel(struct net_device *dev,
515 		   struct iw_request_info *info,
516 		   struct iw_point *wrqu, char *extra)
517 {
518 
519 	PADAPTER padapter = rtw_netdev_priv(dev);
520 	HAL_DATA_TYPE	*pHalData	= GET_HAL_DATA(padapter);
521 	u8 input[RTW_IWD_MAX_LEN];
522 	u8	channel = 1;
523 	struct	mp_priv	*pmppriv = &padapter->mppriv;
524 
525 	if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1)))
526 		return -EFAULT;
527 
528 	_rtw_memset(input, 0, sizeof(input));
529 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
530 		return -EFAULT;
531 
532 	input[wrqu->length] = '\0';
533 	channel = rtw_atoi(input);
534 	/*RTW_INFO("%s: channel=%d\n", __func__, channel);*/
535 	_rtw_memset(extra, 0, wrqu->length);
536 	sprintf(extra, "Change channel %d to channel %d", padapter->mppriv.channel , channel);
537 	padapter->mppriv.channel = channel;
538 	rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
539 	rtw_adjust_chbw(padapter, channel, &pmppriv->bandwidth, &pmppriv->prime_channel_offset);
540 	SetChannel(padapter);
541 	pHalData->current_channel = channel;
542 
543 	wrqu->length = strlen(extra);
544 	return 0;
545 }
546 
547 
rtw_mp_ch_offset(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)548 int rtw_mp_ch_offset(struct net_device *dev,
549 		   struct iw_request_info *info,
550 		   struct iw_point *wrqu, char *extra)
551 {
552 
553 	PADAPTER padapter = rtw_netdev_priv(dev);
554 	u8 input[RTW_IWD_MAX_LEN];
555 	u32	ch_offset = 0;
556 	char *pch;
557 
558 	if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1)))
559 		return -EFAULT;
560 
561 	_rtw_memset(input, 0, sizeof(input));
562 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
563 		return -EFAULT;
564 
565 	input[wrqu->length] = '\0';
566 	ch_offset = rtw_atoi(input);
567 	/*RTW_INFO("%s: channel=%d\n", __func__, channel);*/
568 	_rtw_memset(extra, 0, wrqu->length);
569 	pch = extra;
570 	pch += sprintf(pch, "Change prime channel offset %d to %d", padapter->mppriv.prime_channel_offset , ch_offset);
571 	padapter->mppriv.prime_channel_offset = ch_offset;
572 	SetChannel(padapter);
573 
574 	wrqu->length = strlen(extra);
575 	return 0;
576 }
577 
578 
rtw_mp_bandwidth(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)579 int rtw_mp_bandwidth(struct net_device *dev,
580 		     struct iw_request_info *info,
581 		     struct iw_point *wrqu, char *extra)
582 {
583 	u8 bandwidth = 0, sg = 0;
584 	PADAPTER padapter = rtw_netdev_priv(dev);
585 	HAL_DATA_TYPE	*pHalData	= GET_HAL_DATA(padapter);
586 	struct	mp_priv	*pmppriv = &padapter->mppriv;
587 	u8 input[RTW_IWD_MAX_LEN];
588 
589 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
590 		return -EFAULT;
591 
592 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
593 		return -EFAULT;
594 
595 	if (sscanf(input, "40M=%hhd,shortGI=%hhd", &bandwidth, &sg) > 0)
596 		RTW_INFO("%s: bw=%hhd sg=%hhd\n", __func__, bandwidth , sg);
597 
598 	rtw_adjust_chbw(padapter, pmppriv->channel, &bandwidth, &pmppriv->prime_channel_offset);
599 
600 	padapter->mppriv.bandwidth = (u8)bandwidth;
601 	padapter->mppriv.preamble = sg;
602 	_rtw_memset(extra, 0, wrqu->length);
603 	sprintf(extra, "Change BW %d to BW %d\n", pHalData->current_channel_bw , bandwidth);
604 	rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
605 	SetBandwidth(padapter);
606 	pHalData->current_channel_bw = bandwidth;
607 
608 	wrqu->length = strlen(extra);
609 
610 	return 0;
611 }
612 
613 
rtw_mp_txpower_index(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)614 int rtw_mp_txpower_index(struct net_device *dev,
615 			 struct iw_request_info *info,
616 			 struct iw_point *wrqu, char *extra)
617 {
618 	PADAPTER padapter = rtw_netdev_priv(dev);
619  	HAL_DATA_TYPE	*phal_data	= GET_HAL_DATA(padapter);
620 	char input[RTW_IWD_MAX_LEN];
621 	u32 rfpath = 0 ;
622 	u32 txpower_inx = 0, tarpowerdbm = 0;
623 	char *pextra = extra;
624 
625 	if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1)))
626 		return -EFAULT;
627 
628 	if (wrqu->length > 128)
629 		return -EFAULT;
630 
631 	_rtw_memset(input, 0, sizeof(input));
632 
633 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
634 		return -EFAULT;
635 
636 	input[wrqu->length] = '\0';
637 	_rtw_memset(extra, 0, strlen(extra));
638 
639 	if (wrqu->length == 2) {
640 		if (input[0] != '\0' ) {
641 			rfpath = rtw_atoi(input);
642 			txpower_inx = mpt_ProQueryCalTxPower(padapter, rfpath);
643 		}
644 		pextra += sprintf(pextra, " %d\n", txpower_inx);
645 		tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, rfpath);
646 		if (tarpowerdbm > 0)
647 			pextra += sprintf(pextra, "\t\t dBm:%d", tarpowerdbm);
648 	} else {
649 		if (phal_data->ant_path == 1)
650 			rfpath = 1;
651 		else
652 			rfpath = 0;
653 
654 		txpower_inx = mpt_ProQueryCalTxPower(padapter, rfpath);
655 		pextra += sprintf(pextra, "patha=%d", txpower_inx);
656 		if (phal_data->rf_type > RF_1T2R) {
657 			txpower_inx = mpt_ProQueryCalTxPower(padapter, 1);
658 			pextra += sprintf(pextra, ",pathb=%d", txpower_inx);
659 		}
660 		if (phal_data->rf_type > RF_2T4R) {
661 			txpower_inx = mpt_ProQueryCalTxPower(padapter, 2);
662 			pextra += sprintf(pextra, ",pathc=%d", txpower_inx);
663 		}
664 		if (phal_data->rf_type > RF_3T4R) {
665 			txpower_inx = mpt_ProQueryCalTxPower(padapter, 3);
666 			pextra += sprintf(pextra, ",pathd=%d", txpower_inx);
667 		}
668 
669 		tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, rfpath);
670 		pextra += sprintf(pextra, "\n\t\t\tpatha dBm=%d", tarpowerdbm);
671 		if (phal_data->rf_type > RF_1T2R) {
672 			tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, 1);
673 			pextra += sprintf(pextra, ",pathb dBm=%d", tarpowerdbm);
674 		}
675 		if (phal_data->rf_type > RF_2T4R) {
676 			tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, 2);
677 			pextra += sprintf(pextra, ",pathc dBm=%d", tarpowerdbm);
678 		}
679 		if (phal_data->rf_type > RF_3T4R) {
680 			tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, 3);
681 			pextra += sprintf(pextra, ",pathd dBm=%d", tarpowerdbm);
682 		}
683 	}
684 	wrqu->length = strlen(extra);
685 
686 	return 0;
687 }
688 
689 
rtw_mp_txpower(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)690 int rtw_mp_txpower(struct net_device *dev,
691 		   struct iw_request_info *info,
692 		   struct iw_point *wrqu, char *extra)
693 {
694 	u32 idx_a = 0, idx_b = 0, idx_c = 0, idx_d = 0;
695 	int MsetPower = 1;
696 	u8 input[RTW_IWD_MAX_LEN];
697 	u8 res = 0;
698 
699 	PADAPTER padapter = rtw_netdev_priv(dev);
700 	PMPT_CONTEXT		pMptCtx = &(padapter->mppriv.mpt_ctx);
701 
702 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
703 		return -EFAULT;
704 
705 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
706 		return -EFAULT;
707 
708 	MsetPower = strncmp(input, "off", 3);
709 	if (MsetPower == 0) {
710 		padapter->mppriv.bSetTxPower = 0;
711 		sprintf(extra, "MP Set power off");
712 	} else {
713 			res = sscanf(input, "patha=%d,pathb=%d,pathc=%d,pathd=%d", &idx_a, &idx_b, &idx_c, &idx_d);
714 			if (res < 1) {
715 				if(isdigit(input[0])){
716 					idx_a = rtw_atoi(input);
717 					RTW_INFO("direct set RF Path A Power =%d\n", idx_a);
718 				} else
719 					RTW_INFO("Invalid format on %s !, Get patha=%d,pathb=%d,pathc=%d,pathd=%d\n", input , idx_a , idx_b , idx_c , idx_d);
720 			}
721 		if (res > 0 || idx_a !=0)
722 			sprintf(extra, "Set power level path_A:%d path_B:%d path_C:%d path_D:%d", idx_a , idx_b , idx_c , idx_d);
723 		else
724 			sprintf(extra, "Invalid format on string :%s ", input);
725 
726 		padapter->mppriv.txpoweridx = (u8)idx_a;
727 
728 		pMptCtx->TxPwrLevel[RF_PATH_A] = (u8)idx_a;
729 		pMptCtx->TxPwrLevel[RF_PATH_B] = (u8)idx_b;
730 		pMptCtx->TxPwrLevel[RF_PATH_C] = (u8)idx_c;
731 		pMptCtx->TxPwrLevel[RF_PATH_D]  = (u8)idx_d;
732 		padapter->mppriv.bSetTxPower = 1;
733 
734 		SetTxPower(padapter);
735 	}
736 
737 	wrqu->length = strlen(extra);
738 	return 0;
739 }
740 
741 
rtw_mp_ant_tx(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)742 int rtw_mp_ant_tx(struct net_device *dev,
743 		  struct iw_request_info *info,
744 		  struct iw_point *wrqu, char *extra)
745 {
746 	u8 i;
747 	u8 input[RTW_IWD_MAX_LEN];
748 	u16 antenna = 0;
749 	PADAPTER padapter = rtw_netdev_priv(dev);
750 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
751 
752 	if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1)))
753 		return -EFAULT;
754 
755 	_rtw_memset(input, 0, sizeof(input));
756 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
757 		return -EFAULT;
758 
759 	input[wrqu->length] = '\0';
760 	sprintf(extra, "switch Tx antenna to %s", input);
761 
762 	for (i = 0; i < strlen(input); i++) {
763 		switch (input[i]) {
764 		case 'a':
765 			antenna |= ANTENNA_A;
766 			break;
767 		case 'b':
768 			antenna |= ANTENNA_B;
769 			break;
770 		case 'c':
771 			antenna |= ANTENNA_C;
772 			break;
773 		case 'd':
774 			antenna |= ANTENNA_D;
775 			break;
776 		}
777 	}
778 	/*antenna |= BIT(extra[i]-'a');*/
779 	RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);
780 	padapter->mppriv.antenna_tx = antenna;
781 
782 	/*RTW_INFO("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_tx);*/
783 	pHalData->antenna_tx_path = antenna;
784 	if (IS_HARDWARE_TYPE_8822C(padapter) && padapter->mppriv.antenna_tx == ANTENNA_B) {
785 		if (padapter->mppriv.antenna_rx == ANTENNA_A || padapter->mppriv.antenna_rx == ANTENNA_B) {
786 			padapter->mppriv.antenna_rx = ANTENNA_AB;
787 			pHalData->AntennaRxPath = ANTENNA_AB;
788 			RTW_INFO("%s:8822C Tx-B Rx Ant to AB\n", __func__);
789 		}
790 	}
791 	SetAntenna(padapter);
792 
793 	wrqu->length = strlen(extra);
794 	return 0;
795 }
796 
797 
rtw_mp_ant_rx(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)798 int rtw_mp_ant_rx(struct net_device *dev,
799 		  struct iw_request_info *info,
800 		  struct iw_point *wrqu, char *extra)
801 {
802 	u8 i;
803 	u16 antenna = 0;
804 	u8 input[RTW_IWD_MAX_LEN];
805 	PADAPTER padapter = rtw_netdev_priv(dev);
806 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
807 
808 	if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1)))
809 		return -EFAULT;
810 
811 	_rtw_memset(input, 0, sizeof(input));
812 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
813 		return -EFAULT;
814 
815 	input[wrqu->length] = '\0';
816 	/*RTW_INFO("%s: input=%s\n", __func__, input);*/
817 	_rtw_memset(extra, 0, wrqu->length);
818 
819 	sprintf(extra, "switch Rx antenna to %s", input);
820 
821 	for (i = 0; i < strlen(input); i++) {
822 		switch (input[i]) {
823 		case 'a':
824 			antenna |= ANTENNA_A;
825 			break;
826 		case 'b':
827 			antenna |= ANTENNA_B;
828 			break;
829 		case 'c':
830 			antenna |= ANTENNA_C;
831 			break;
832 		case 'd':
833 			antenna |= ANTENNA_D;
834 			break;
835 		}
836 	}
837 
838 	RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);
839 
840 	padapter->mppriv.antenna_rx = antenna;
841 	pHalData->AntennaRxPath = antenna;
842 	/*RTW_INFO("%s:mppriv.antenna_rx=%d\n", __func__, padapter->mppriv.antenna_rx);*/
843 	SetAntenna(padapter);
844 	wrqu->length = strlen(extra);
845 
846 	return 0;
847 }
848 
849 
rtw_set_ctx_destAddr(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)850 int rtw_set_ctx_destAddr(struct net_device *dev,
851 			 struct iw_request_info *info,
852 			 struct iw_point *wrqu, char *extra)
853 {
854 	int jj, kk = 0;
855 
856 	struct pkt_attrib *pattrib;
857 	struct mp_priv *pmp_priv;
858 	PADAPTER padapter = rtw_netdev_priv(dev);
859 
860 	pmp_priv = &padapter->mppriv;
861 	pattrib = &pmp_priv->tx.attrib;
862 
863 	if (strlen(extra) < 5)
864 		return _FAIL;
865 
866 	RTW_INFO("%s: in=%s\n", __func__, extra);
867 	for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
868 		pattrib->dst[jj] = key_2char2num(extra[kk], extra[kk + 1]);
869 
870 	RTW_INFO("pattrib->dst:%x %x %x %x %x %x\n", pattrib->dst[0], pattrib->dst[1], pattrib->dst[2], pattrib->dst[3], pattrib->dst[4], pattrib->dst[5]);
871 	return 0;
872 }
873 
874 
875 
rtw_mp_ctx(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)876 int rtw_mp_ctx(struct net_device *dev,
877 	       struct iw_request_info *info,
878 	       struct iw_point *wrqu, char *extra)
879 {
880 	u32 pkTx = 1;
881 	int countPkTx = 1, cotuTx = 1, CarrSprTx = 1, scTx = 1, sgleTx = 1, stop = 1, payload = 1;
882 	u32 bStartTest = 1;
883 	u32 count = 0, pktinterval = 0, pktlen = 0;
884 	u8 status;
885 	struct mp_priv *pmp_priv;
886 	struct pkt_attrib *pattrib;
887 	PADAPTER padapter = rtw_netdev_priv(dev);
888 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
889 
890 	pmp_priv = &padapter->mppriv;
891 	pattrib = &pmp_priv->tx.attrib;
892 
893 	if (padapter->registrypriv.mp_mode != 1 ) {
894 		sprintf(extra, "Error: can't tx ,not in MP mode. \n");
895 		wrqu->length = strlen(extra);
896 		return 0;
897 	}
898 
899 	if (copy_from_user(extra, wrqu->pointer, wrqu->length))
900 		return -EFAULT;
901 
902 	*(extra + wrqu->length) = '\0';
903 	RTW_INFO("%s: in=%s\n", __func__, extra);
904 #ifdef CONFIG_CONCURRENT_MODE
905 	if (!is_primary_adapter(padapter)) {
906 		sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n");
907 		wrqu->length = strlen(extra);
908 		return 0;
909 	}
910 #endif
911 	countPkTx = strncmp(extra, "count=", 5); /* strncmp TRUE is 0*/
912 	cotuTx = strncmp(extra, "background", 20);
913 	CarrSprTx = strncmp(extra, "background,cs", 20);
914 	scTx = strncmp(extra, "background,sc", 20);
915 	sgleTx = strncmp(extra, "background,stone", 20);
916 	pkTx = strncmp(extra, "background,pkt", 20);
917 	stop = strncmp(extra, "stop", 4);
918 	payload = strncmp(extra, "payload=", 8);
919 
920 	if (sscanf(extra, "count=%d,pkt", &count) > 0)
921 		RTW_INFO("count= %d\n", count);
922 	if (sscanf(extra, "pktinterval=%d", &pktinterval) > 0)
923 		RTW_INFO("pktinterval= %d\n", pktinterval);
924 	if (sscanf(extra, "pktlen=%d", &pktlen) > 0)
925 		RTW_INFO("pktlen= %d\n", pktlen);
926 
927 	if (payload == 0) {
928 			payload = MP_TX_Payload_default_random;
929 			if (strncmp(extra, "payload=prbs9", 14) == 0) {
930 				payload = MP_TX_Payload_prbs9;
931 				sprintf(extra, "config payload PRBS9\n");
932 			} else {
933 				if (sscanf(extra, "payload=%x", &payload) > 0){
934 					RTW_INFO("payload= %x\n", payload);
935 					sprintf(extra, "config payload setting = %x\n"
936 									"1. input payload=[]:\n		"
937 									"[0]: 00, [1]: A5, [2]: 5A, [3]: FF, [4]: PRBS-9, [5]: Random\n"
938 									"2. specified a hex payload: payload=0xee\n", payload);
939 				 }
940 			}
941 			pmp_priv->tx.payload = payload;
942 			wrqu->length = strlen(extra);
943 			return 0;
944 	}
945 
946 	if (_rtw_memcmp(extra, "destmac=", 8)) {
947 		wrqu->length -= 8;
948 		rtw_set_ctx_destAddr(dev, info, wrqu, &extra[8]);
949 		sprintf(extra, "Set dest mac OK !\n");
950 		return 0;
951 	}
952 	/*RTW_INFO("%s: count=%d countPkTx=%d cotuTx=%d CarrSprTx=%d scTx=%d sgleTx=%d pkTx=%d stop=%d\n", __func__, count, countPkTx, cotuTx, CarrSprTx, pkTx, sgleTx, scTx, stop);*/
953 	_rtw_memset(extra, '\0', strlen(extra));
954 
955 	if (pktinterval != 0) {
956 		sprintf(extra, "Pkt Interval = %d", pktinterval);
957 		padapter->mppriv.pktInterval = pktinterval;
958 		wrqu->length = strlen(extra);
959 		return 0;
960 
961 	} else if (pktlen != 0) {
962 		sprintf(extra, "Pkt len = %d", pktlen);
963 		pattrib->pktlen = pktlen;
964 		wrqu->length = strlen(extra);
965 		return 0;
966 
967 	} else if (stop == 0) {
968 		struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
969 		_queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
970 		_queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
971 
972 		u32 i = 0;
973 		bStartTest = 0; /* To set Stop*/
974 		pmp_priv->tx.stop = 1;
975 		sprintf(extra, "Stop continuous Tx");
976 		odm_write_dig(&pHalData->odmpriv, 0x20);
977 		do {
978 			if (pxmitpriv->free_xmitframe_cnt == NR_XMITFRAME && pxmitpriv->free_xmitbuf_cnt == NR_XMITBUFF)
979 				break;
980 			else {
981 				i++;
982 				RTW_INFO("%s:wait queue_empty %d!!\n", __func__, i);
983 				rtw_msleep_os(10);
984 			}
985 		} while (i < 1000);
986 	} else {
987 		bStartTest = 1;
988 		odm_write_dig(&pHalData->odmpriv, 0x3f);
989 		if (IS_HARDWARE_TYPE_8822C(padapter) && pmp_priv->antenna_tx == ANTENNA_B) {
990 			if (pmp_priv->antenna_rx == ANTENNA_A || pmp_priv->antenna_rx == ANTENNA_B) {
991 				pmp_priv->antenna_rx = ANTENNA_AB;
992 				pHalData->AntennaRxPath = ANTENNA_AB;
993 				RTW_INFO("%s:8822C Tx-B Rx Ant to AB\n", __func__);
994 				SetAntenna(padapter);
995 			}
996 		}
997 		if (pmp_priv->mode != MP_ON) {
998 			if (pmp_priv->tx.stop != 1) {
999 				RTW_INFO("%s:Error MP_MODE %d != ON\n", __func__, pmp_priv->mode);
1000 				return	-EFAULT;
1001 			}
1002 		}
1003 	}
1004 
1005 	pmp_priv->tx.count = count;
1006 
1007 	if (pkTx == 0 || countPkTx == 0)
1008 		pmp_priv->mode = MP_PACKET_TX;
1009 	if (sgleTx == 0)
1010 		pmp_priv->mode = MP_SINGLE_TONE_TX;
1011 	if (cotuTx == 0)
1012 		pmp_priv->mode = MP_CONTINUOUS_TX;
1013 	if (CarrSprTx == 0)
1014 		pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX;
1015 	if (scTx == 0)
1016 		pmp_priv->mode = MP_SINGLE_CARRIER_TX;
1017 
1018 	status = rtw_mp_pretx_proc(padapter, bStartTest, extra);
1019 
1020 	if (stop == 0)
1021 		pmp_priv->mode = MP_ON;
1022 
1023 	wrqu->length = strlen(extra);
1024 	return status;
1025 }
1026 
1027 
1028 
rtw_mp_disable_bt_coexist(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1029 int rtw_mp_disable_bt_coexist(struct net_device *dev,
1030 			      struct iw_request_info *info,
1031 			      union iwreq_data *wrqu, char *extra)
1032 {
1033 #ifdef CONFIG_BT_COEXIST
1034 	PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
1035 
1036 #endif
1037 	u8 input[RTW_IWD_MAX_LEN];
1038 	u32 bt_coexist;
1039 
1040 	if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->data.length + 1)))
1041 		return -EFAULT;
1042 
1043 	_rtw_memset(input, 0, sizeof(input));
1044 
1045 	if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
1046 		return -EFAULT;
1047 
1048 	input[wrqu->data.length] = '\0';
1049 
1050 	bt_coexist = rtw_atoi(input);
1051 
1052 	if (bt_coexist == 0) {
1053 		RTW_INFO("Set OID_RT_SET_DISABLE_BT_COEXIST: disable BT_COEXIST\n");
1054 #ifdef CONFIG_BT_COEXIST
1055 		rtw_btcoex_HaltNotify(padapter);
1056 		rtw_btcoex_SetManualControl(padapter, _TRUE);
1057 		/* Force to switch Antenna to WiFi*/
1058 		rtw_write16(padapter, 0x870, 0x300);
1059 		rtw_write16(padapter, 0x860, 0x110);
1060 #endif
1061 		/* CONFIG_BT_COEXIST */
1062 	} else {
1063 #ifdef CONFIG_BT_COEXIST
1064 		rtw_btcoex_SetManualControl(padapter, _FALSE);
1065 #endif
1066 	}
1067 
1068 	return 0;
1069 }
1070 
1071 
rtw_mp_arx(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1072 int rtw_mp_arx(struct net_device *dev,
1073 	       struct iw_request_info *info,
1074 	       struct iw_point *wrqu, char *extra)
1075 {
1076 	int bStartRx = 0, bStopRx = 0, bQueryPhy = 0, bQueryMac = 0, bSetBssid = 0, bSetRxframe = 0;
1077 	int bmac_filter = 0, bmon = 0, bSmpCfg = 0;
1078 	u8 input[RTW_IWD_MAX_LEN];
1079 	char *pch, *token, *tmp[2] = {0x00, 0x00};
1080 	u32 i = 0, jj = 0, kk = 0, cnts = 0, ret;
1081 	PADAPTER padapter = rtw_netdev_priv(dev);
1082 	struct mp_priv *pmppriv = &padapter->mppriv;
1083 	struct dbg_rx_counter rx_counter;
1084 
1085 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1086 		return -EFAULT;
1087 
1088 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1089 		return -EFAULT;
1090 
1091 	RTW_INFO("%s: %s\n", __func__, input);
1092 #ifdef CONFIG_CONCURRENT_MODE
1093 	if (!is_primary_adapter(padapter)) {
1094 		sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n");
1095 		wrqu->length = strlen(extra);
1096 		return 0;
1097 	}
1098 #endif
1099 	bStartRx = (strncmp(input, "start", 5) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
1100 	bStopRx = (strncmp(input, "stop", 5) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
1101 	bQueryPhy = (strncmp(input, "phy", 3) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
1102 	bQueryMac = (strncmp(input, "mac", 3) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
1103 	bSetBssid = (strncmp(input, "setbssid=", 8) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
1104 	bSetRxframe = (strncmp(input, "frametype", 9) == 0) ? 1 : 0;
1105 	/*bfilter_init = (strncmp(input, "filter_init",11)==0)?1:0;*/
1106 	bmac_filter = (strncmp(input, "accept_mac", 10) == 0) ? 1 : 0;
1107 	bmon = (strncmp(input, "mon=", 4) == 0) ? 1 : 0;
1108 	bSmpCfg = (strncmp(input , "smpcfg=" , 7) == 0) ? 1 : 0;
1109 	pmppriv->bloopback = (strncmp(input, "loopbk", 6) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
1110 
1111 	if (bSetBssid == 1) {
1112 		pch = input;
1113 		while ((token = strsep(&pch, "=")) != NULL) {
1114 			if (i > 1)
1115 				break;
1116 			tmp[i] = token;
1117 			i++;
1118 		}
1119 		if ((tmp[0] != NULL) && (tmp[1] != NULL)) {
1120 			cnts = strlen(tmp[1]) / 2;
1121 			if (cnts < 1)
1122 				return -EFAULT;
1123 			RTW_INFO("%s: cnts=%d\n", __func__, cnts);
1124 			RTW_INFO("%s: data=%s\n", __func__, tmp[1]);
1125 			for (jj = 0, kk = 0; jj < cnts ; jj++, kk += 2) {
1126 				pmppriv->network_macaddr[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
1127 				RTW_INFO("network_macaddr[%d]=%x\n", jj, pmppriv->network_macaddr[jj]);
1128 			}
1129 		} else
1130 			return -EFAULT;
1131 
1132 		pmppriv->bSetRxBssid = _TRUE;
1133 	}
1134 	if (bSetRxframe) {
1135 		if (strncmp(input, "frametype beacon", 16) == 0)
1136 			pmppriv->brx_filter_beacon = _TRUE;
1137 		else
1138 			pmppriv->brx_filter_beacon = _FALSE;
1139 	}
1140 
1141 	if (bmac_filter) {
1142 		pmppriv->bmac_filter = bmac_filter;
1143 		pch = input;
1144 		while ((token = strsep(&pch, "=")) != NULL) {
1145 			if (i > 1)
1146 				break;
1147 			tmp[i] = token;
1148 			i++;
1149 		}
1150 		if ((tmp[0] != NULL) && (tmp[1] != NULL)) {
1151 			cnts = strlen(tmp[1]) / 2;
1152 			if (cnts < 1)
1153 				return -EFAULT;
1154 			RTW_INFO("%s: cnts=%d\n", __func__, cnts);
1155 			RTW_INFO("%s: data=%s\n", __func__, tmp[1]);
1156 			for (jj = 0, kk = 0; jj < cnts ; jj++, kk += 2) {
1157 				pmppriv->mac_filter[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
1158 				RTW_INFO("%s mac_filter[%d]=%x\n", __func__, jj, pmppriv->mac_filter[jj]);
1159 			}
1160 		} else
1161 			return -EFAULT;
1162 
1163 	}
1164 
1165 	if (bStartRx) {
1166 		sprintf(extra, "start");
1167 		SetPacketRx(padapter, bStartRx, _FALSE);
1168 	} else if (bStopRx) {
1169 		SetPacketRx(padapter, bStartRx, _FALSE);
1170 		pmppriv->bmac_filter = _FALSE;
1171 		pmppriv->bSetRxBssid = _FALSE;
1172 		sprintf(extra, "Received packet OK:%d CRC error:%d ,Filter out:%d", padapter->mppriv.rx_pktcount, padapter->mppriv.rx_crcerrpktcount, padapter->mppriv.rx_pktcount_filter_out);
1173 	} else if (bQueryPhy) {
1174 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
1175 		rtw_dump_phy_rx_counters(padapter, &rx_counter);
1176 
1177 		RTW_INFO("%s: OFDM_FA =%d\n", __func__, rx_counter.rx_ofdm_fa);
1178 		RTW_INFO("%s: CCK_FA =%d\n", __func__, rx_counter.rx_cck_fa);
1179 		sprintf(extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d", rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_cck_fa + rx_counter.rx_ofdm_fa);
1180 
1181 
1182 	} else if (bQueryMac) {
1183 		_rtw_memset(&rx_counter, 0, sizeof(struct dbg_rx_counter));
1184 		rtw_dump_mac_rx_counters(padapter, &rx_counter);
1185 		sprintf(extra, "Mac Received packet OK: %d , CRC error: %d , Drop Packets: %d\n",
1186 			rx_counter.rx_pkt_ok, rx_counter.rx_pkt_crc_error, rx_counter.rx_pkt_drop);
1187 
1188 	}
1189 
1190 	if (bmon == 1) {
1191 		ret = sscanf(input, "mon=%d", &bmon);
1192 
1193 		if (bmon == 1) {
1194 			pmppriv->rx_bindicatePkt = _TRUE;
1195 			sprintf(extra, "Indicating Receive Packet to network start\n");
1196 		} else {
1197 			pmppriv->rx_bindicatePkt = _FALSE;
1198 			sprintf(extra, "Indicating Receive Packet to network Stop\n");
1199 		}
1200 	}
1201 	if (bSmpCfg == 1) {
1202 		ret = sscanf(input, "smpcfg=%d", &bSmpCfg);
1203 
1204 		if (bSmpCfg == 1) {
1205 			pmppriv->bRTWSmbCfg = _TRUE;
1206 			sprintf(extra , "Indicate By Simple Config Format\n");
1207 			SetPacketRx(padapter, _TRUE, _TRUE);
1208 		} else {
1209 			pmppriv->bRTWSmbCfg = _FALSE;
1210 			sprintf(extra , "Indicate By Normal Format\n");
1211 			SetPacketRx(padapter, _TRUE, _FALSE);
1212 		}
1213 	}
1214 
1215 	if (pmppriv->bloopback == _TRUE) {
1216 		sprintf(extra , "Enter MAC LoopBack mode\n");
1217 #if defined(CONFIG_RTL8814B)
1218 		/* 1. No adhoc, 2. Enable short cut */
1219 		rtw_write32(padapter, 0x100, 0x0B000EFF);
1220 #else
1221 		rtw_write32(padapter, 0x100, 0x0B0106FF);
1222 #endif
1223 		RTW_INFO("0x100 :0x%x", rtw_read32(padapter, 0x100));
1224 		rtw_write16(padapter, 0x608, 0x30c);
1225 		RTW_INFO("0x608 :0x%x", rtw_read32(padapter, 0x608));
1226 	}
1227 
1228 	wrqu->length = strlen(extra) + 1;
1229 
1230 	return 0;
1231 }
1232 
1233 
rtw_mp_trx_query(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1234 int rtw_mp_trx_query(struct net_device *dev,
1235 		     struct iw_request_info *info,
1236 		     struct iw_point *wrqu, char *extra)
1237 {
1238 	u32 txok, txfail, rxok, rxfail, rxfilterout;
1239 	PADAPTER padapter = rtw_netdev_priv(dev);
1240 	PMPT_CONTEXT	pMptCtx		=	&(padapter->mppriv.mpt_ctx);
1241 	RT_PMAC_TX_INFO	PMacTxInfo	=	pMptCtx->PMacTxInfo;
1242 
1243 	if (PMacTxInfo.bEnPMacTx == TRUE)
1244 		txok = hal_mpt_query_phytxok(padapter);
1245 	else
1246 		txok = padapter->mppriv.tx.sended;
1247 
1248 	txfail = 0;
1249 	rxok = padapter->mppriv.rx_pktcount;
1250 	rxfail = padapter->mppriv.rx_crcerrpktcount;
1251 	rxfilterout = padapter->mppriv.rx_pktcount_filter_out;
1252 
1253 	_rtw_memset(extra, '\0', 128);
1254 
1255 	sprintf(extra, "Tx OK:%d, Tx Fail:%d, Rx OK:%d, CRC error:%d ,Rx Filter out:%d\n", txok, txfail, rxok, rxfail, rxfilterout);
1256 
1257 	wrqu->length = strlen(extra) + 1;
1258 
1259 	return 0;
1260 }
1261 
1262 
rtw_mp_pwrtrk(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1263 int rtw_mp_pwrtrk(struct net_device *dev,
1264 		  struct iw_request_info *info,
1265 		  struct iw_point *wrqu, char *extra)
1266 {
1267 	u8 enable;
1268 	u32 thermal;
1269 	s32 ret;
1270 	PADAPTER padapter = rtw_netdev_priv(dev);
1271 	u8 input[RTW_IWD_MAX_LEN];
1272 
1273 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1274 		return -EFAULT;
1275 
1276 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1277 		return -EFAULT;
1278 
1279 	_rtw_memset(extra, 0, wrqu->length);
1280 
1281 	enable = 1;
1282 	if (wrqu->length > 1) {
1283 		/* not empty string*/
1284 		if (strncmp(input, "stop", 4) == 0) {
1285 			enable = 0;
1286 			sprintf(extra, "mp tx power tracking stop");
1287 		} else if (sscanf(input, "ther=%d", &thermal) == 1) {
1288 			ret = SetThermalMeter(padapter, (u8)thermal);
1289 			if (ret == _FAIL)
1290 				return -EPERM;
1291 			sprintf(extra, "mp tx power tracking start,target value=%d ok", thermal);
1292 		} else
1293 			return -EINVAL;
1294 	}
1295 
1296 	ret = SetPowerTracking(padapter, enable);
1297 	if (ret == _FAIL)
1298 		return -EPERM;
1299 
1300 	wrqu->length = strlen(extra);
1301 
1302 	return 0;
1303 }
1304 
1305 
1306 
rtw_mp_psd(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1307 int rtw_mp_psd(struct net_device *dev,
1308 	       struct iw_request_info *info,
1309 	       struct iw_point *wrqu, char *extra)
1310 {
1311 	PADAPTER padapter = rtw_netdev_priv(dev);
1312 	u8 input[RTW_IWD_MAX_LEN];
1313 
1314 	if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1)))
1315 		return -EFAULT;
1316 
1317 	_rtw_memset(input, 0, sizeof(input));
1318 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1319 		return -EFAULT;
1320 
1321 	input[wrqu->length] = '\0';
1322 	strcpy(extra, input);
1323 
1324 	wrqu->length = mp_query_psd(padapter, extra);
1325 
1326 	return 0;
1327 }
1328 
1329 
rtw_mp_thermal(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1330 int rtw_mp_thermal(struct net_device *dev,
1331 		   struct iw_request_info *info,
1332 		   struct iw_point *wrqu, char *extra)
1333 {
1334 	u8 val[4] = {0};
1335 	u8 ret = 0;
1336 	u16 ther_path_addr[4] = {0};
1337 	u16 cnt = 1;
1338 	PADAPTER padapter = rtw_netdev_priv(dev);
1339 	struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter);
1340 	int rfpath = RF_PATH_A;
1341 
1342 #ifdef CONFIG_RTL8188E
1343 	ther_path_addr[0] = EEPROM_THERMAL_METER_88E;
1344 #endif
1345 #if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A) || defined(CONFIG_RTL8814A)
1346 	ther_path_addr[0] = EEPROM_THERMAL_METER_8812;
1347 #endif
1348 #ifdef CONFIG_RTL8192E
1349 	ther_path_addr[0] = EEPROM_THERMAL_METER_8192E;
1350 #endif
1351 #ifdef CONFIG_RTL8192F
1352 	ther_path_addr[0] = EEPROM_THERMAL_METER_8192F;
1353 #endif
1354 #ifdef CONFIG_RTL8723B
1355 	ther_path_addr[0] = EEPROM_THERMAL_METER_8723B;
1356 #endif
1357 #ifdef CONFIG_RTL8703B
1358 	ther_path_addr[0] = EEPROM_THERMAL_METER_8703B;
1359 #endif
1360 #ifdef CONFIG_RTL8723D
1361 	ther_path_addr[0] = EEPROM_THERMAL_METER_8723D;
1362 #endif
1363 #ifdef CONFIG_RTL8188F
1364 	ther_path_addr[0] = EEPROM_THERMAL_METER_8188F;
1365 #endif
1366 #ifdef CONFIG_RTL8188GTV
1367 	ther_path_addr[0] = EEPROM_THERMAL_METER_8188GTV;
1368 #endif
1369 #ifdef CONFIG_RTL8822B
1370 	ther_path_addr[0] = EEPROM_THERMAL_METER_8822B;
1371 #endif
1372 #ifdef CONFIG_RTL8821C
1373 	ther_path_addr[0] = EEPROM_THERMAL_METER_8821C;
1374 #endif
1375 #ifdef CONFIG_RTL8710B
1376 	ther_path_addr[0] = EEPROM_THERMAL_METER_8710B;
1377 #endif
1378 #ifdef CONFIG_RTL8822C
1379 	ther_path_addr[0]  = EEPROM_THERMAL_METER_A_8822C;
1380 	ther_path_addr[1]  = EEPROM_THERMAL_METER_B_8822C;
1381 #endif
1382 #ifdef CONFIG_RTL8814B
1383 	ther_path_addr[0] = EEPROM_THERMAL_METER_A_8814B;
1384 	ther_path_addr[1] = EEPROM_THERMAL_METER_B_8814B;
1385 	ther_path_addr[2] = EEPROM_THERMAL_METER_C_8814B;
1386 	ther_path_addr[3] = EEPROM_THERMAL_METER_D_8814B;
1387 #endif
1388 
1389 	if (copy_from_user(extra, wrqu->pointer, wrqu->length))
1390 		return -EFAULT;
1391 
1392 	if ((strncmp(extra, "write", 6) == 0)) {
1393 		int i;
1394 		u16 raw_cursize = 0, raw_maxsize = 0;
1395 #ifdef RTW_HALMAC
1396 		raw_maxsize = efuse_GetavailableSize(padapter);
1397 #else
1398 		efuse_GetCurrentSize(padapter, &raw_cursize);
1399 		raw_maxsize = efuse_GetMaxSize(padapter);
1400 #endif
1401 		RTW_INFO("[eFuse available raw size]= %d bytes\n", raw_maxsize - raw_cursize);
1402 		if (2 > raw_maxsize - raw_cursize) {
1403 			RTW_INFO("no available efuse!\n");
1404 			return -EFAULT;
1405 		}
1406 
1407 		for (i = 0; i < hal_spec->rf_reg_path_num; i++) {
1408 				GetThermalMeter(padapter, i , &val[i]);
1409 				if (ther_path_addr[i] != 0 && val[i] != 0) {
1410 					if (rtw_efuse_map_write(padapter, ther_path_addr[i], cnt, &val[i]) == _FAIL) {
1411 						RTW_INFO("Error efuse write thermal addr 0x%x ,val = 0x%x\n", ther_path_addr[i], val[i]);
1412 						return -EFAULT;
1413 					}
1414 				} else {
1415 						RTW_INFO("Error efuse write thermal Null addr,val \n");
1416 						return -EFAULT;
1417 				}
1418 		}
1419 		_rtw_memset(extra, 0, wrqu->length);
1420 		sprintf(extra, " efuse write ok :%d", val[0]);
1421 	} else {
1422 		ret = sscanf(extra, "%d", &rfpath);
1423 		if (ret < 1) {
1424 			rfpath = RF_PATH_A;
1425 			RTW_INFO("default thermal of path(%d)\n", rfpath);
1426 		}
1427 		if (rfpath >= hal_spec->rf_reg_path_num)
1428 			return -EINVAL;
1429 
1430 		RTW_INFO("read thermal of path(%d)\n", rfpath);
1431 		GetThermalMeter(padapter, rfpath, &val[0]);
1432 
1433 		_rtw_memset(extra, 0, wrqu->length);
1434 		sprintf(extra, "%d", val[0]);
1435 	}
1436 	wrqu->length = strlen(extra);
1437 
1438 	return 0;
1439 }
1440 
1441 
1442 
rtw_mp_reset_stats(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1443 int rtw_mp_reset_stats(struct net_device *dev,
1444 		       struct iw_request_info *info,
1445 		       struct iw_point *wrqu, char *extra)
1446 {
1447 	struct mp_priv *pmp_priv;
1448 	PADAPTER padapter = rtw_netdev_priv(dev);
1449 
1450 	pmp_priv = &padapter->mppriv;
1451 
1452 	pmp_priv->tx.sended = 0;
1453 	pmp_priv->tx_pktcount = 0;
1454 	pmp_priv->rx_pktcount = 0;
1455 	pmp_priv->rx_pktcount_filter_out = 0;
1456 	pmp_priv->rx_crcerrpktcount = 0;
1457 
1458 	rtw_reset_phy_rx_counters(padapter);
1459 	rtw_reset_mac_rx_counters(padapter);
1460 
1461 	_rtw_memset(extra, 0, wrqu->length);
1462 	sprintf(extra, "mp_reset_stats ok\n");
1463 	wrqu->length = strlen(extra);
1464 
1465 	return 0;
1466 }
1467 
1468 
rtw_mp_dump(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1469 int rtw_mp_dump(struct net_device *dev,
1470 		struct iw_request_info *info,
1471 		struct iw_point *wrqu, char *extra)
1472 {
1473 	struct mp_priv *pmp_priv;
1474 	u8 input[RTW_IWD_MAX_LEN];
1475 	PADAPTER padapter = rtw_netdev_priv(dev);
1476 
1477 	pmp_priv = &padapter->mppriv;
1478 
1479 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1480 		return -EFAULT;
1481 
1482 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1483 		return -EFAULT;
1484 
1485 	if (strncmp(input, "all", 4) == 0) {
1486 		mac_reg_dump(RTW_DBGDUMP, padapter);
1487 		bb_reg_dump(RTW_DBGDUMP, padapter);
1488 		rf_reg_dump(RTW_DBGDUMP, padapter);
1489 	}
1490 	return 0;
1491 }
1492 
1493 
rtw_mp_phypara(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1494 int rtw_mp_phypara(struct net_device *dev,
1495 		   struct iw_request_info *info,
1496 		   struct iw_point *wrqu, char *extra)
1497 {
1498 
1499 	PADAPTER padapter = rtw_netdev_priv(dev);
1500 	HAL_DATA_TYPE	*pHalData	= GET_HAL_DATA(padapter);
1501 	char input[RTW_IWD_MAX_LEN];
1502 	u32		invalxcap = 0, ret = 0, bwrite_xcap = 0, hwxtaladdr = 0;
1503 	u16		pgval;
1504 
1505 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1506 		return -EFAULT;
1507 
1508 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1509 		return -EFAULT;
1510 
1511 	RTW_INFO("%s:priv in=%s\n", __func__, input);
1512 	bwrite_xcap = (strncmp(input, "write_xcap=", 11) == 0) ? 1 : 0;
1513 
1514 	if (bwrite_xcap == 1) {
1515 		ret = sscanf(input, "write_xcap=%d", &invalxcap);
1516 		invalxcap = invalxcap & 0x7f; /* xtal bit 0 ~6 */
1517 		RTW_INFO("get crystal_cap %d\n", invalxcap);
1518 
1519 		if (IS_HARDWARE_TYPE_8822C(padapter) && ret == 1) {
1520 			hwxtaladdr = 0x110;
1521 			pgval = invalxcap | 0x80; /* reserved default bit7 on */
1522 			pgval = pgval | pgval << 8; /* xtal xi/xo efuse 0x110 0x111 */
1523 
1524 			RTW_INFO("Get crystal_cap 0x%x\n", pgval);
1525 			if (rtw_efuse_map_write(padapter, hwxtaladdr, 2, (u8*)&pgval) == _FAIL) {
1526 					RTW_INFO("%s: rtw_efuse_map_write xcap error!!\n", __func__);
1527 					sprintf(extra, "write xcap pgdata fail");
1528 					ret = -EFAULT;
1529 			} else
1530 					sprintf(extra, "write xcap pgdata ok");
1531 
1532 		}
1533 	} else {
1534 		ret = sscanf(input, "xcap=%d", &invalxcap);
1535 
1536 		if (ret == 1) {
1537 			pHalData->crystal_cap = (u8)invalxcap;
1538 			RTW_INFO("%s:crystal_cap=%d\n", __func__, pHalData->crystal_cap);
1539 
1540 			if (rtw_phydm_set_crystal_cap(padapter, pHalData->crystal_cap) == _FALSE) {
1541 				RTW_ERR("set crystal_cap failed\n");
1542 				rtw_warn_on(1);
1543 			}
1544 			sprintf(extra, "Set xcap=%d", invalxcap);
1545 		}
1546 	}
1547 
1548 	wrqu->length = strlen(extra) + 1;
1549 	return ret;
1550 }
1551 
1552 
rtw_mp_SetRFPath(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1553 int rtw_mp_SetRFPath(struct net_device *dev,
1554 		     struct iw_request_info *info,
1555 		     struct iw_point *wrqu, char *extra)
1556 {
1557 	PADAPTER padapter = rtw_netdev_priv(dev);
1558 	char input[RTW_IWD_MAX_LEN];
1559 	int		bMain = 1, bTurnoff = 1;
1560 #ifdef CONFIG_ANTENNA_DIVERSITY
1561 	u8 ret = _TRUE;
1562 #endif
1563 
1564 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1565 		return -EFAULT;
1566 
1567 	RTW_INFO("%s:iwpriv in=%s\n", __func__, input);
1568 
1569 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1570 		return -EFAULT;
1571 
1572 	bMain = strncmp(input, "1", 2); /* strncmp TRUE is 0*/
1573 	bTurnoff = strncmp(input, "0", 3); /* strncmp TRUE is 0*/
1574 
1575 	_rtw_memset(extra, 0, wrqu->length);
1576 #ifdef CONFIG_ANTENNA_DIVERSITY
1577 	if (bMain == 0)
1578 		ret = rtw_mp_set_antdiv(padapter, _TRUE);
1579 	else
1580 		ret = rtw_mp_set_antdiv(padapter, _FALSE);
1581 	if (ret == _FALSE)
1582 		RTW_INFO("%s:ANTENNA_DIVERSITY FAIL\n", __func__);
1583 #endif
1584 
1585 	if (bMain == 0) {
1586 		MP_PHY_SetRFPathSwitch(padapter, _TRUE);
1587 		RTW_INFO("%s:PHY_SetRFPathSwitch=TRUE\n", __func__);
1588 		sprintf(extra, "mp_setrfpath Main\n");
1589 
1590 	} else if (bTurnoff == 0) {
1591 		MP_PHY_SetRFPathSwitch(padapter, _FALSE);
1592 		RTW_INFO("%s:PHY_SetRFPathSwitch=FALSE\n", __func__);
1593 		sprintf(extra, "mp_setrfpath Aux\n");
1594 	} else {
1595 		bMain = MP_PHY_QueryRFPathSwitch(padapter);
1596 		RTW_INFO("%s:Query RF Path = %s\n", __func__, (bMain ? "Main":"Aux"));
1597 		sprintf(extra, "RF Path %s\n" , (bMain ? "1":"0"));
1598 	}
1599 
1600 	wrqu->length = strlen(extra);
1601 
1602 	return 0;
1603 }
1604 
1605 
rtw_mp_switch_rf_path(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1606 int rtw_mp_switch_rf_path(struct net_device *dev,
1607 			struct iw_request_info *info,
1608 			struct iw_point *wrqu, char *extra)
1609 {
1610 	PADAPTER padapter = rtw_netdev_priv(dev);
1611 	struct mp_priv *pmp_priv;
1612 	char input[RTW_IWD_MAX_LEN];
1613 	char *pch;
1614 	int		bwlg = 1, bwla = 1, btg = 1, bbt=1;
1615 	u8 ret = 0;
1616 
1617 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1618 		return -EFAULT;
1619 
1620 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1621 		return -EFAULT;
1622 
1623 	pmp_priv = &padapter->mppriv;
1624 
1625 	RTW_INFO("%s: in=%s\n", __func__, input);
1626 
1627 	_rtw_memset(extra, '\0', wrqu->length);
1628 	pch = extra;
1629 #ifdef CONFIG_RTL8821C /* only support for 8821c wlg/wla/btg/bt RF switch path */
1630 	if ((strncmp(input, "WLG", 3) == 0) || (strncmp(input, "1", 1) == 0)) {
1631 		pmp_priv->rf_path_cfg = SWITCH_TO_WLG;
1632 		pch += sprintf(pch, "switch rf path WLG\n");
1633 
1634 	} else if ((strncmp(input, "WLA", 3) == 0) || (strncmp(input, "2", 1) == 0)) {
1635 		pmp_priv->rf_path_cfg = SWITCH_TO_WLA;
1636 		pch += sprintf(pch, "switch rf path WLA\n");
1637 
1638 	} else if ((strncmp(input, "BTG", 3) == 0) || (strncmp(input, "0", 1) == 0)) {
1639 		pmp_priv->rf_path_cfg = SWITCH_TO_BTG;
1640 		pch += sprintf(pch, "switch rf path BTG\n");
1641 
1642 	} else if ((strncmp(input, "BT", 3) == 0) || (strncmp(input, "3", 1) == 0)) {
1643 		pmp_priv->rf_path_cfg = SWITCH_TO_BT;
1644 		pch += sprintf(pch, "switch rf path BT\n");
1645 	} else {
1646 		pmp_priv->rf_path_cfg = SWITCH_TO_WLG;
1647 		pch += sprintf(pch, "Error input, default set WLG\n");
1648 		return -EFAULT;
1649 	}
1650 
1651 	mp_phy_switch_rf_path_set(padapter, &pmp_priv->rf_path_cfg);
1652 #endif
1653 	wrqu->length = strlen(extra);
1654 
1655 	return ret;
1656 
1657 }
rtw_mp_QueryDrv(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1658 int rtw_mp_QueryDrv(struct net_device *dev,
1659 		    struct iw_request_info *info,
1660 		    union iwreq_data *wrqu, char *extra)
1661 {
1662 	PADAPTER padapter = rtw_netdev_priv(dev);
1663 	char input[RTW_IWD_MAX_LEN];
1664 	int	qAutoLoad = 1;
1665 
1666 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1667 
1668 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->data.length))
1669 		return -EFAULT;
1670 
1671 	if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
1672 		return -EFAULT;
1673 	RTW_INFO("%s:iwpriv in=%s\n", __func__, input);
1674 
1675 	qAutoLoad = strncmp(input, "autoload", 8); /* strncmp TRUE is 0*/
1676 
1677 	if (qAutoLoad == 0) {
1678 		RTW_INFO("%s:qAutoLoad\n", __func__);
1679 
1680 		if (pHalData->bautoload_fail_flag)
1681 			sprintf(extra, "fail");
1682 		else
1683 			sprintf(extra, "ok");
1684 	}
1685 	wrqu->data.length = strlen(extra) + 1;
1686 	return 0;
1687 }
1688 
1689 
rtw_mp_PwrCtlDM(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1690 int rtw_mp_PwrCtlDM(struct net_device *dev,
1691 		    struct iw_request_info *info,
1692 		    struct iw_point *wrqu, char *extra)
1693 {
1694 	PADAPTER padapter = rtw_netdev_priv(dev);
1695 	u8 input[RTW_IWD_MAX_LEN];
1696 	u8		pwrtrk_state = 0;
1697 	u8		pwtk_type[5][25] = {"Thermal tracking off","Thermal tracking on",
1698 					"TSSI tracking off","TSSI tracking on","TSSI calibration"};
1699 
1700 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1701 		return -EFAULT;
1702 
1703 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1704 		return -EFAULT;
1705 
1706 	input[wrqu->length - 1] = '\0';
1707 	RTW_INFO("%s: in=%s\n", __func__, input);
1708 
1709 	if (wrqu->length == 2) {
1710 		if(input[0] >= '0' && input[0] <= '4') {
1711 			pwrtrk_state = rtw_atoi(input);
1712 			MPT_PwrCtlDM(padapter, pwrtrk_state);
1713 			sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1714 		} else {
1715 			sprintf(extra, "Error unknown number ! Please check your input number\n"
1716 				" 0 : Thermal tracking off\n 1 : Thermal tracking on\n 2 : TSSI tracking off\n"
1717 				" 3 : TSSI tracking on\n 4 : TSSI calibration\n");
1718 		}
1719 		wrqu->length = strlen(extra);
1720 
1721 		return 0;
1722 	}
1723 	if (strncmp(input, "start", 5) == 0 || strncmp(input, "thertrk on", 10) == 0) {/* strncmp TRUE is 0*/
1724 		pwrtrk_state = 1;
1725 		sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1726 	} else if (strncmp(input, "thertrk off", 11) == 0 || strncmp(input, "stop", 5) == 0) {
1727 		pwrtrk_state = 0;
1728 		sprintf(extra, "PwrCtlDM stop %s\n" , pwtk_type[pwrtrk_state]);
1729 	} else if (strncmp(input, "tssitrk off", 11) == 0){
1730 		pwrtrk_state = 2;
1731 		sprintf(extra, "PwrCtlDM stop %s\n" , pwtk_type[pwrtrk_state]);
1732 	} else if (strncmp(input, "tssitrk on", 10) == 0){
1733 		pwrtrk_state = 3;
1734 		sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1735 	} else if (strncmp(input, "tssik", 5) == 0){
1736 		pwrtrk_state = 4;
1737 		sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1738 	} else {
1739 		sprintf(extra, "Error input !!!\n"
1740 			" thertrk off : Thermal tracking off\n thertrk on : Thermal tracking on\n"
1741 			" tssitrk off : TSSI tracking off\n tssitrk on : TSSI tracking on\n tssik : TSSI calibration\n\n"
1742 			" 0 : Thermal tracking off\n 1 : Thermal tracking on\n 2 : TSSI tracking off\n"
1743 			" 3 : TSSI tracking on\n 4 : TSSI calibration\n");
1744 		wrqu->length = strlen(extra);
1745 		return 0;
1746 	}
1747 
1748 	MPT_PwrCtlDM(padapter, pwrtrk_state);
1749 	wrqu->length = strlen(extra);
1750 
1751 	return 0;
1752 }
1753 
rtw_mp_iqk(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1754 int rtw_mp_iqk(struct net_device *dev,
1755 		 struct iw_request_info *info,
1756 		 struct iw_point *wrqu, char *extra)
1757 {
1758 	PADAPTER padapter = rtw_netdev_priv(dev);
1759 
1760 	rtw_mp_trigger_iqk(padapter);
1761 
1762 	return 0;
1763 }
1764 
rtw_mp_lck(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1765 int rtw_mp_lck(struct net_device *dev,
1766 		 struct iw_request_info *info,
1767 		 struct iw_point *wrqu, char *extra)
1768 {
1769 	PADAPTER padapter = rtw_netdev_priv(dev);
1770 
1771 	rtw_mp_trigger_lck(padapter);
1772 
1773 	return 0;
1774 }
1775 
rtw_mp_dpk(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1776 int rtw_mp_dpk(struct net_device *dev,
1777 			struct iw_request_info *info,
1778 			union iwreq_data *wrqu, char *extra)
1779 {
1780 	PADAPTER padapter = rtw_netdev_priv(dev);
1781 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
1782 	struct dm_struct		*pDM_Odm = &pHalData->odmpriv;
1783 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
1784 	char *pch;
1785 
1786 	u8 ips_mode = IPS_NUM; /* init invalid value */
1787 	u8 lps_mode = PS_MODE_NUM; /* init invalid value */
1788 
1789 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
1790 		return -EFAULT;
1791 
1792 	*(extra + wrqu->data.length) = '\0';
1793 	pch = extra;
1794 
1795 	if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
1796 			pDM_Odm->dpk_info.is_dpk_enable = 0;
1797 			halrf_dpk_enable_disable(pDM_Odm);
1798 			pch += sprintf(pch, "set dpk off\n");
1799 
1800 	} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
1801 			pDM_Odm->dpk_info.is_dpk_enable = 1;
1802 			halrf_dpk_enable_disable(pDM_Odm);
1803 			pch += sprintf(pch, "set dpk on\n");
1804 	} else	{
1805 #ifdef CONFIG_LPS
1806 			lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */
1807 			rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
1808 #endif
1809 #ifdef CONFIG_IPS
1810 			ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
1811 			rtw_pm_set_ips(padapter, IPS_NONE);
1812 #endif
1813 			rtw_mp_trigger_dpk(padapter);
1814 	if (padapter->registrypriv.mp_mode == 0) {
1815 #ifdef CONFIG_IPS
1816 			rtw_pm_set_ips(padapter, ips_mode);
1817 #endif /* CONFIG_IPS */
1818 
1819 #ifdef CONFIG_LPS
1820 			rtw_pm_set_lps(padapter, lps_mode);
1821 #endif /* CONFIG_LPS */
1822 	}
1823 			pch += sprintf(pch, "set dpk trigger\n");
1824 	}
1825 
1826 	wrqu->data.length = strlen(extra);
1827 
1828 	return 0;
1829 }
1830 
rtw_mp_get_tsside(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1831 int rtw_mp_get_tsside(struct net_device *dev,
1832 			 struct iw_request_info *info,
1833 			 struct iw_point *wrqu, char *extra)
1834 {
1835 	PADAPTER padapter = rtw_netdev_priv(dev);
1836  	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
1837 	struct dm_struct		*pDM_Odm = &pHalData->odmpriv;
1838 	char input[RTW_IWD_MAX_LEN];
1839 	u8 rfpath;
1840 	u32 tssi_de;
1841 
1842 	if (wrqu->length > 128)
1843 		return -EFAULT;
1844 
1845 	if (rtw_do_mp_iwdata_len_chk(__func__, (wrqu->length + 1)))
1846 		return -EFAULT;
1847 
1848 	_rtw_memset(input, 0, sizeof(input));
1849 
1850 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1851 		return -EFAULT;
1852 
1853 	input[wrqu->length] = '\0';
1854 
1855 	if (wrqu->length == 2) {
1856 		rfpath = rtw_atoi(input);
1857 		if (rfpath >= 0 && rfpath <= 3) {
1858 			tssi_de = halrf_tssi_get_de(pDM_Odm, rfpath);
1859 			if (rfpath == 0)
1860 				sprintf(extra, "patha=%d", tssi_de);
1861 			else if (rfpath == 1)
1862 				sprintf(extra, "pathb=%d", tssi_de);
1863 			else if (rfpath == 2)
1864 				sprintf(extra, "pathc=%d", tssi_de);
1865 			else if (rfpath == 3)
1866 				sprintf(extra, "pathd=%d", tssi_de);
1867 		} else
1868 			sprintf(extra, "Invalid command format, please indicate RF path 0/1/2/3");
1869 	} else
1870 		sprintf(extra, "Invalid command format, please indicate RF path 0/1/2/3");
1871 
1872 	wrqu->length = strlen(extra);
1873 
1874 	return 0;
1875 }
1876 
rtw_mp_set_tsside(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1877 int rtw_mp_set_tsside(struct net_device *dev,
1878 		   struct iw_request_info *info,
1879 		   struct iw_point *wrqu, char *extra)
1880 {
1881 	u32 tsside_a = 0, tsside_b = 0, tsside_c = 0, tsside_d = 0;
1882 	char input[RTW_IWD_MAX_LEN];
1883 
1884 	PADAPTER padapter = rtw_netdev_priv(dev);
1885 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
1886 	struct dm_struct		*pDM_Odm = &pHalData->odmpriv;
1887 
1888 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1889 		return -EFAULT;
1890 
1891 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1892 		return -EFAULT;
1893 
1894 	if (sscanf(input, "patha=%d", &tsside_a) == 1) {
1895 		sprintf(extra, "Set TSSI DE path_A: %d", tsside_a);
1896 		halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_a, RF_PATH_A);
1897 		mpt_trigger_tssi_tracking(padapter, RF_PATH_A);
1898 
1899 	} else if (sscanf(input, "pathb=%d", &tsside_b) == 1) {
1900 		sprintf(extra, "Set TSSI DE path_B: %d", tsside_b);
1901 		halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_b, RF_PATH_B);
1902 		mpt_trigger_tssi_tracking(padapter, RF_PATH_B);
1903 
1904 	} else if (sscanf(input, "pathc=%d", &tsside_c) == 1) {
1905 		sprintf(extra, "Set TSSI DE path_C: %d", tsside_c);
1906 		halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_c, RF_PATH_C);
1907 		mpt_trigger_tssi_tracking(padapter, RF_PATH_C);
1908 
1909 	} else if (sscanf(input, "pathd=%d", &tsside_d) == 1) {
1910 		sprintf(extra, "Set TSSI DE path_D: %d", tsside_d);
1911 		halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_d, RF_PATH_D);
1912 		mpt_trigger_tssi_tracking(padapter, RF_PATH_D);
1913 
1914 	} else
1915 		sprintf(extra, "Invalid command format, please input TSSI DE value within patha/b/c/d=xyz");
1916 
1917 	wrqu->length = strlen(extra);
1918 
1919 	return 0;
1920 }
1921 
rtw_mp_getver(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1922 int rtw_mp_getver(struct net_device *dev,
1923 		  struct iw_request_info *info,
1924 		  union iwreq_data *wrqu, char *extra)
1925 {
1926 	PADAPTER padapter = rtw_netdev_priv(dev);
1927 	struct mp_priv *pmp_priv;
1928 
1929 	pmp_priv = &padapter->mppriv;
1930 
1931 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
1932 		return -EFAULT;
1933 
1934 	sprintf(extra, "rtwpriv=%d\n", RTWPRIV_VER_INFO);
1935 	wrqu->data.length = strlen(extra);
1936 	return 0;
1937 }
1938 
1939 
rtw_mp_mon(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1940 int rtw_mp_mon(struct net_device *dev,
1941 	       struct iw_request_info *info,
1942 	       union iwreq_data *wrqu, char *extra)
1943 {
1944 	PADAPTER padapter = rtw_netdev_priv(dev);
1945 	struct mp_priv *pmp_priv = &padapter->mppriv;
1946 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1947 	struct hal_ops *pHalFunc = &padapter->hal_func;
1948 	NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
1949 	int bstart = 1, bstop = 1;
1950 
1951 	networkType = Ndis802_11Infrastructure;
1952 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
1953 		return -EFAULT;
1954 
1955 	*(extra + wrqu->data.length) = '\0';
1956 	rtw_pm_set_ips(padapter, IPS_NONE);
1957 	LeaveAllPowerSaveMode(padapter);
1958 
1959 #ifdef CONFIG_MP_INCLUDED
1960 	if (init_mp_priv(padapter) == _FAIL)
1961 		RTW_INFO("%s: initialize MP private data Fail!\n", __func__);
1962 	padapter->mppriv.channel = 6;
1963 
1964 	bstart = strncmp(extra, "start", 5); /* strncmp TRUE is 0*/
1965 	bstop = strncmp(extra, "stop", 4); /* strncmp TRUE is 0*/
1966 	if (bstart == 0) {
1967 		mp_join(padapter, WIFI_FW_ADHOC_STATE);
1968 		SetPacketRx(padapter, _TRUE, _FALSE);
1969 		SetChannel(padapter);
1970 		pmp_priv->rx_bindicatePkt = _TRUE;
1971 		pmp_priv->bRTWSmbCfg = _TRUE;
1972 		sprintf(extra, "monitor mode start\n");
1973 	} else if (bstop == 0) {
1974 		SetPacketRx(padapter, _FALSE, _FALSE);
1975 		pmp_priv->rx_bindicatePkt = _FALSE;
1976 		pmp_priv->bRTWSmbCfg = _FALSE;
1977 		padapter->registrypriv.mp_mode = 1;
1978 		pHalFunc->hal_deinit(padapter);
1979 		padapter->registrypriv.mp_mode = 0;
1980 		pHalFunc->hal_init(padapter);
1981 		/*rtw_disassoc_cmd(padapter, 0, 0);*/
1982 		if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
1983 			rtw_disassoc_cmd(padapter, 500, 0);
1984 			rtw_indicate_disconnect(padapter, 0, _FALSE);
1985 			/*rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);*/
1986 		}
1987 		rtw_pm_set_ips(padapter, IPS_NORMAL);
1988 		sprintf(extra, "monitor mode Stop\n");
1989 	}
1990 #endif
1991 	wrqu->data.length = strlen(extra);
1992 	return 0;
1993 }
1994 
rtw_mp_pretx_proc(PADAPTER padapter,u8 bStartTest,char * extra)1995 int rtw_mp_pretx_proc(PADAPTER padapter, u8 bStartTest, char *extra)
1996 {
1997 	struct mp_priv *pmp_priv = &padapter->mppriv;
1998 	char *pextra = extra;
1999 
2000 	switch (pmp_priv->mode) {
2001 
2002 	case MP_PACKET_TX:
2003 		if (bStartTest == 0) {
2004 			pmp_priv->tx.stop = 1;
2005 			pmp_priv->mode = MP_ON;
2006 			#ifdef CONFIG_RTL8822B
2007 			rtw_write8(padapter, 0x838, 0x61);
2008 			#endif
2009 			sprintf(extra, "Stop continuous Tx");
2010 		} else if (pmp_priv->tx.stop == 1) {
2011 			pextra = extra + strlen(extra);
2012 			pextra += sprintf(pextra, "\nStart continuous DA=ffffffffffff len=1500 count=%u\n", pmp_priv->tx.count);
2013 			pmp_priv->tx.stop = 0;
2014 			#ifdef CONFIG_RTL8822B
2015 			rtw_write8(padapter, 0x838, 0x6d);
2016 			#endif
2017 			SetPacketTx(padapter);
2018 		} else
2019 			return -EFAULT;
2020 		return 0;
2021 	case MP_SINGLE_TONE_TX:
2022 		if (bStartTest != 0)
2023 			strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2024 		SetSingleToneTx(padapter, (u8)bStartTest);
2025 		break;
2026 	case MP_CONTINUOUS_TX:
2027 		if (bStartTest != 0)
2028 			strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2029 		SetContinuousTx(padapter, (u8)bStartTest);
2030 		break;
2031 	case MP_CARRIER_SUPPRISSION_TX:
2032 		if (bStartTest != 0) {
2033 			if (HwRateToMPTRate(pmp_priv->rateidx) <= MPT_RATE_11M)
2034 				strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2035 			else
2036 				strcat(extra, "\nSpecify carrier suppression but not CCK rate");
2037 		}
2038 		SetCarrierSuppressionTx(padapter, (u8)bStartTest);
2039 		break;
2040 	case MP_SINGLE_CARRIER_TX:
2041 		if (bStartTest != 0)
2042 			strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2043 		SetSingleCarrierTx(padapter, (u8)bStartTest);
2044 		break;
2045 
2046 	default:
2047 		sprintf(extra, "Error! Continuous-Tx is not on-going.");
2048 		return -EFAULT;
2049 	}
2050 
2051 	if (bStartTest == 1 && pmp_priv->mode != MP_ON) {
2052 		struct mp_priv *pmp_priv = &padapter->mppriv;
2053 
2054 		if (pmp_priv->tx.stop == 0) {
2055 			pmp_priv->tx.stop = 1;
2056 			rtw_msleep_os(5);
2057 		}
2058 #ifdef CONFIG_80211N_HT
2059 		if(padapter->registrypriv.ht_enable &&
2060 			is_supported_ht(padapter->registrypriv.wireless_mode))
2061 			pmp_priv->tx.attrib.ht_en = 1;
2062 #endif
2063 		pmp_priv->tx.stop = 0;
2064 		pmp_priv->tx.count = 1;
2065 		SetPacketTx(padapter);
2066 	} else
2067 		pmp_priv->mode = MP_ON;
2068 
2069 #if defined(CONFIG_RTL8812A)
2070 	if (IS_HARDWARE_TYPE_8812AU(padapter)) {
2071 		/* <20130425, Kordan> Turn off OFDM Rx to prevent from CCA causing Tx hang.*/
2072 		if (pmp_priv->mode == MP_PACKET_TX)
2073 			phy_set_bb_reg(padapter, rCCAonSec_Jaguar, BIT3, 1);
2074 		else
2075 			phy_set_bb_reg(padapter, rCCAonSec_Jaguar, BIT3, 0);
2076 	}
2077 #endif
2078 
2079 	return 0;
2080 }
2081 
2082 
rtw_mp_tx(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2083 int rtw_mp_tx(struct net_device *dev,
2084 	      struct iw_request_info *info,
2085 	      union iwreq_data *wrqu, char *extra)
2086 {
2087 	PADAPTER padapter = rtw_netdev_priv(dev);
2088 	HAL_DATA_TYPE	*pHalData	= GET_HAL_DATA(padapter);
2089 	struct mp_priv *pmp_priv = &padapter->mppriv;
2090 	PMPT_CONTEXT		pMptCtx = &(padapter->mppriv.mpt_ctx);
2091 	char *pextra = extra;
2092 	u32 bandwidth = 0, sg = 0, channel = 6, txpower = 40, rate = 108, ant = 0, txmode = 1, count = 0;
2093 	u8 bStartTest = 1, status = 0;
2094 #ifdef CONFIG_MP_VHT_HW_TX_MODE
2095 	u8 Idx = 0, tmpU1B;
2096 #endif
2097 	u16 antenna = 0;
2098 
2099 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2100 		return -EFAULT;
2101 	RTW_INFO("extra = %s\n", extra);
2102 #ifdef CONFIG_CONCURRENT_MODE
2103 	if (!is_primary_adapter(padapter)) {
2104 		sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n");
2105 		wrqu->data.length = strlen(extra);
2106 		return 0;
2107 	}
2108 #endif
2109 
2110 	if (strncmp(extra, "stop", 3) == 0) {
2111 		bStartTest = 0; /* To set Stop*/
2112 		pmp_priv->tx.stop = 1;
2113 		sprintf(extra, "Stop continuous Tx");
2114 		status = rtw_mp_pretx_proc(padapter, bStartTest, extra);
2115 		wrqu->data.length = strlen(extra);
2116 		return status;
2117 	} else if (strncmp(extra, "count", 5) == 0) {
2118 		if (sscanf(extra, "count=%d", &count) < 1)
2119 			RTW_INFO("Got Count=%d]\n", count);
2120 		pmp_priv->tx.count = count;
2121 		return 0;
2122 	} else if (strncmp(extra, "setting", 7) == 0) {
2123 		_rtw_memset(extra, 0, wrqu->data.length);
2124 		pextra += sprintf(pextra, "Current Setting :\n Channel:%d", pmp_priv->channel);
2125 		pextra += sprintf(pextra, "\n Bandwidth:%d", pmp_priv->bandwidth);
2126 		pextra += sprintf(pextra, "\n Rate index:%d", pmp_priv->rateidx);
2127 		pextra += sprintf(pextra, "\n TxPower index:%d", pmp_priv->txpoweridx);
2128 		pextra += sprintf(pextra, "\n Antenna TxPath:%d", pmp_priv->antenna_tx);
2129 		pextra += sprintf(pextra, "\n Antenna RxPath:%d", pmp_priv->antenna_rx);
2130 		pextra += sprintf(pextra, "\n MP Mode:%d", pmp_priv->mode);
2131 		wrqu->data.length = strlen(extra);
2132 		return 0;
2133 #ifdef CONFIG_MP_VHT_HW_TX_MODE
2134 	} else if (strncmp(extra, "pmact", 5) == 0) {
2135 		if (strncmp(extra, "pmact=", 6) == 0) {
2136 			_rtw_memset(&pMptCtx->PMacTxInfo, 0, sizeof(pMptCtx->PMacTxInfo));
2137 			if (strncmp(extra, "pmact=start", 11) == 0) {
2138 				pMptCtx->PMacTxInfo.bEnPMacTx = _TRUE;
2139 				sprintf(extra, "Set PMac Tx Mode start\n");
2140 			} else {
2141 				pMptCtx->PMacTxInfo.bEnPMacTx = _FALSE;
2142 				sprintf(extra, "Set PMac Tx Mode Stop\n");
2143 			}
2144 			if (pMptCtx->bldpc == TRUE)
2145 				pMptCtx->PMacTxInfo.bLDPC = _TRUE;
2146 
2147 			if (pMptCtx->bstbc == TRUE)
2148 				pMptCtx->PMacTxInfo.bSTBC = _TRUE;
2149 
2150 			pMptCtx->PMacTxInfo.bSPreamble = pmp_priv->preamble;
2151 			pMptCtx->PMacTxInfo.bSGI = pmp_priv->preamble;
2152 			pMptCtx->PMacTxInfo.BandWidth = pmp_priv->bandwidth;
2153 			pMptCtx->PMacTxInfo.TX_RATE = HwRateToMPTRate(pmp_priv->rateidx);
2154 
2155 			pMptCtx->PMacTxInfo.Mode = pMptCtx->HWTxmode;
2156 
2157 			pMptCtx->PMacTxInfo.NDP_sound = FALSE;/*(Adapter.PacketType == NDP_PKT)?TRUE:FALSE;*/
2158 
2159 			if (padapter->mppriv.pktInterval == 0)
2160 				pMptCtx->PMacTxInfo.PacketPeriod = 100;
2161 			else
2162 				pMptCtx->PMacTxInfo.PacketPeriod = padapter->mppriv.pktInterval;
2163 
2164 			if (padapter->mppriv.pktLength < 1000)
2165 				pMptCtx->PMacTxInfo.PacketLength = 1000;
2166 			else
2167 				pMptCtx->PMacTxInfo.PacketLength = padapter->mppriv.pktLength;
2168 
2169 			pMptCtx->PMacTxInfo.PacketPattern  = rtw_random32() % 0xFF;
2170 
2171 			if (padapter->mppriv.tx_pktcount != 0)
2172 				pMptCtx->PMacTxInfo.PacketCount = padapter->mppriv.tx_pktcount;
2173 
2174 			pMptCtx->PMacTxInfo.Ntx = 0;
2175 			for (Idx = 16; Idx < 20; Idx++) {
2176 				tmpU1B = (padapter->mppriv.antenna_tx >> Idx) & 1;
2177 				if (tmpU1B)
2178 					pMptCtx->PMacTxInfo.Ntx++;
2179 			}
2180 
2181 			_rtw_memset(pMptCtx->PMacTxInfo.MacAddress, 0xFF, ETH_ALEN);
2182 
2183 			PMAC_Get_Pkt_Param(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2184 
2185 			if (MPT_IS_CCK_RATE(pMptCtx->PMacTxInfo.TX_RATE))
2186 
2187 				CCK_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2188 			else {
2189 				PMAC_Nsym_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2190 				/* 24 BIT*/
2191 				L_SIG_generator(pMptCtx->PMacPktInfo.N_sym, &pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2192 			}
2193 			/*	48BIT*/
2194 			if (MPT_IS_HT_RATE(pMptCtx->PMacTxInfo.TX_RATE))
2195 				HT_SIG_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2196 			else if (MPT_IS_VHT_RATE(pMptCtx->PMacTxInfo.TX_RATE)) {
2197 				/*	48BIT*/
2198 				VHT_SIG_A_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2199 
2200 				/*	26/27/29 BIT  & CRC 8 BIT*/
2201 				VHT_SIG_B_generator(&pMptCtx->PMacTxInfo);
2202 
2203 				/* 32 BIT*/
2204 				VHT_Delimiter_generator(&pMptCtx->PMacTxInfo);
2205 			}
2206 
2207 			mpt_ProSetPMacTx(padapter);
2208 
2209 		} else if (strncmp(extra, "pmact,mode=", 11) == 0) {
2210 			int txmode = 0;
2211 
2212 			if (sscanf(extra, "pmact,mode=%d", &txmode) > 0) {
2213 				if (txmode == 1) {
2214 					pMptCtx->HWTxmode = CONTINUOUS_TX;
2215 					sprintf(extra, "\t Config HW Tx mode = CONTINUOUS_TX\n");
2216 				} else if (txmode == 2) {
2217 					pMptCtx->HWTxmode = OFDM_Single_Tone_TX;
2218 					sprintf(extra, "\t Config HW Tx mode = OFDM_Single_Tone_TX\n");
2219 				} else {
2220 					pMptCtx->HWTxmode = PACKETS_TX;
2221 					sprintf(extra, "\t Config HW Tx mode = PACKETS_TX\n");
2222 				}
2223 			} else {
2224 				pMptCtx->HWTxmode = PACKETS_TX;
2225 				sprintf(extra, "\t Config HW Tx mode=\n 0 = PACKETS_TX\n 1 = CONTINUOUS_TX\n 2 = OFDM_Single_Tone_TX");
2226 			}
2227 		} else if (strncmp(extra, "pmact,", 6) == 0) {
2228 			int PacketPeriod = 0, PacketLength = 0, PacketCout = 0;
2229 			int bldpc = 0, bstbc = 0;
2230 
2231 			if (sscanf(extra, "pmact,period=%d", &PacketPeriod) > 0) {
2232 				padapter->mppriv.pktInterval = PacketPeriod;
2233 				RTW_INFO("PacketPeriod=%d\n", padapter->mppriv.pktInterval);
2234 				sprintf(extra, "PacketPeriod [1~255]= %d\n", padapter->mppriv.pktInterval);
2235 
2236 			} else if (sscanf(extra, "pmact,length=%d", &PacketLength) > 0) {
2237 				padapter->mppriv.pktLength = PacketLength;
2238 				RTW_INFO("PacketPeriod=%d\n", padapter->mppriv.pktLength);
2239 				sprintf(extra, "PacketLength[~65535]=%d\n", padapter->mppriv.pktLength);
2240 
2241 			} else if (sscanf(extra, "pmact,count=%d", &PacketCout) > 0) {
2242 				padapter->mppriv.tx_pktcount = PacketCout;
2243 				RTW_INFO("Packet Cout =%d\n", padapter->mppriv.tx_pktcount);
2244 				sprintf(extra, "Packet Cout =%d\n", padapter->mppriv.tx_pktcount);
2245 
2246 			} else if (sscanf(extra, "pmact,ldpc=%d", &bldpc) > 0) {
2247 				pMptCtx->bldpc = bldpc;
2248 				RTW_INFO("Set LDPC =%d\n", pMptCtx->bldpc);
2249 				sprintf(extra, "Set LDPC =%d\n", pMptCtx->bldpc);
2250 
2251 			} else if (sscanf(extra, "pmact,stbc=%d", &bstbc) > 0) {
2252 				pMptCtx->bstbc = bstbc;
2253 				RTW_INFO("Set STBC =%d\n", pMptCtx->bstbc);
2254 				sprintf(extra, "Set STBC =%d\n", pMptCtx->bstbc);
2255 			} else
2256 				sprintf(extra, "\n period={1~255}\n length={1000~65535}\n count={0~}\n ldpc={0/1}\n stbc={0/1}");
2257 
2258 		}
2259 
2260 		wrqu->data.length = strlen(extra);
2261 		return 0;
2262 #endif
2263 	} else {
2264 
2265 		if (sscanf(extra, "ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d", &channel, &bandwidth, &rate, &txpower, &ant, &txmode) < 6) {
2266 			RTW_INFO("Invalid format [ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d]\n", channel, bandwidth, rate, txpower, ant, txmode);
2267 			_rtw_memset(extra, 0, wrqu->data.length);
2268 			pextra += sprintf(pextra, "\n Please input correct format as bleow:\n");
2269 			pextra += sprintf(pextra, "\t ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d\n", channel, bandwidth, rate, txpower, ant, txmode);
2270 			pextra += sprintf(pextra, "\n [ ch : BGN = <1~14> , A or AC = <36~165> ]");
2271 			pextra += sprintf(pextra, "\n [ bw : Bandwidth: 0 = 20M, 1 = 40M, 2 = 80M ]");
2272 			pextra += sprintf(pextra, "\n [ rate :	CCK: 1 2 5.5 11M X 2 = < 2 4 11 22 >]");
2273 			pextra += sprintf(pextra, "\n [		OFDM: 6 9 12 18 24 36 48 54M X 2 = < 12 18 24 36 48 72 96 108>");
2274 			pextra += sprintf(pextra, "\n [		HT 1S2SS MCS0 ~ MCS15 : < [MCS0]=128 ~ [MCS7]=135 ~ [MCS15]=143 >");
2275 			pextra += sprintf(pextra, "\n [		HT 3SS MCS16 ~ MCS32 : < [MCS16]=144 ~ [MCS23]=151 ~ [MCS32]=159 >");
2276 			pextra += sprintf(pextra, "\n [		VHT 1SS MCS0 ~ MCS9 : < [MCS0]=160 ~ [MCS9]=169 >");
2277 			pextra += sprintf(pextra, "\n [ txpower : 1~63 power index");
2278 			pextra += sprintf(pextra, "\n [ ant : <A = 1, B = 2, C = 4, D = 8> ,2T ex: AB=3 BC=6 CD=12");
2279 			pextra += sprintf(pextra, "\n [ txmode : < 0 = CONTINUOUS_TX, 1 = PACKET_TX, 2 = SINGLE_TONE_TX, 3 = CARRIER_SUPPRISSION_TX, 4 = SINGLE_CARRIER_TX>\n");
2280 			wrqu->data.length = strlen(extra);
2281 			return status;
2282 
2283 		} else {
2284 			char *pextra = extra;
2285 			RTW_INFO("Got format [ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d]\n", channel, bandwidth, rate, txpower, ant, txmode);
2286 			_rtw_memset(extra, 0, wrqu->data.length);
2287 			sprintf(extra, "Change Current channel %d to channel %d", padapter->mppriv.channel , channel);
2288 			padapter->mppriv.channel = channel;
2289 			SetChannel(padapter);
2290 			pHalData->current_channel = channel;
2291 
2292 			if (bandwidth == 1)
2293 				bandwidth = CHANNEL_WIDTH_40;
2294 			else if (bandwidth == 2)
2295 				bandwidth = CHANNEL_WIDTH_80;
2296 			pextra = extra + strlen(pextra);
2297 			pextra += sprintf(pextra, "\nChange Current Bandwidth %d to Bandwidth %d", padapter->mppriv.bandwidth, bandwidth);
2298 			padapter->mppriv.bandwidth = (u8)bandwidth;
2299 			padapter->mppriv.preamble = sg;
2300 			SetBandwidth(padapter);
2301 			pHalData->current_channel_bw = bandwidth;
2302 
2303 			pextra += sprintf(pextra, "\nSet power level :%d", txpower);
2304 			padapter->mppriv.txpoweridx = (u8)txpower;
2305 			pMptCtx->TxPwrLevel[RF_PATH_A] = (u8)txpower;
2306 			pMptCtx->TxPwrLevel[RF_PATH_B] = (u8)txpower;
2307 			pMptCtx->TxPwrLevel[RF_PATH_C] = (u8)txpower;
2308 			pMptCtx->TxPwrLevel[RF_PATH_D]  = (u8)txpower;
2309 			SetTxPower(padapter);
2310 
2311 			RTW_INFO("%s: bw=%d sg=%d\n", __func__, bandwidth, sg);
2312 
2313 			if (rate <= 0x7f)
2314 				rate = wifirate2_ratetbl_inx((u8)rate);
2315 			else if (rate < 0xC8)
2316 				rate = (rate - 0x80 + MPT_RATE_MCS0);
2317 			/*HT  rate 0x80(MCS0)  ~ 0x8F(MCS15) ~ 0x9F(MCS31) 128~159
2318 			VHT1SS~2SS rate 0xA0 (VHT1SS_MCS0 44) ~ 0xB3 (VHT2SS_MCS9 #63) 160~179
2319 			VHT rate 0xB4 (VHT3SS_MCS0 64) ~ 0xC7 (VHT2SS_MCS9 #83) 180~199
2320 			else
2321 			VHT rate 0x90(VHT1SS_MCS0) ~ 0x99(VHT1SS_MCS9) 144~153
2322 			rate =(rate - MPT_RATE_VHT1SS_MCS0);
2323 			*/
2324 			RTW_INFO("%s: rate index=%d\n", __func__, rate);
2325 			if (rate >= MPT_RATE_LAST)
2326 				return -EINVAL;
2327 			pextra += sprintf(pextra, "\nSet data rate to %d index %d", padapter->mppriv.rateidx, rate);
2328 
2329 			padapter->mppriv.rateidx = rate;
2330 			pMptCtx->mpt_rate_index = rate;
2331 			SetDataRate(padapter);
2332 
2333 			pextra += sprintf(pextra, "\nSet Antenna Path :%d", ant);
2334 			switch (ant) {
2335 			case 1:
2336 				antenna = ANTENNA_A;
2337 				break;
2338 			case 2:
2339 				antenna = ANTENNA_B;
2340 				break;
2341 			case 4:
2342 				antenna = ANTENNA_C;
2343 				break;
2344 			case 8:
2345 				antenna = ANTENNA_D;
2346 				break;
2347 			case 3:
2348 				antenna = ANTENNA_AB;
2349 				break;
2350 			case 5:
2351 				antenna = ANTENNA_AC;
2352 				break;
2353 			case 9:
2354 				antenna = ANTENNA_AD;
2355 				break;
2356 			case 6:
2357 				antenna = ANTENNA_BC;
2358 				break;
2359 			case 10:
2360 				antenna = ANTENNA_BD;
2361 				break;
2362 			case 12:
2363 				antenna = ANTENNA_CD;
2364 				break;
2365 			case 7:
2366 				antenna = ANTENNA_ABC;
2367 				break;
2368 			case 14:
2369 				antenna = ANTENNA_BCD;
2370 				break;
2371 			case 11:
2372 				antenna = ANTENNA_ABD;
2373 				break;
2374 			case 15:
2375 				antenna = ANTENNA_ABCD;
2376 				break;
2377 			}
2378 			RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);
2379 			padapter->mppriv.antenna_tx = antenna;
2380 			padapter->mppriv.antenna_rx = antenna;
2381 			pHalData->antenna_tx_path = antenna;
2382 			SetAntenna(padapter);
2383 
2384 			if (txmode == 0)
2385 				pmp_priv->mode = MP_CONTINUOUS_TX;
2386 			else if (txmode == 1) {
2387 				pmp_priv->mode = MP_PACKET_TX;
2388 				pmp_priv->tx.count = count;
2389 			} else if (txmode == 2)
2390 				pmp_priv->mode = MP_SINGLE_TONE_TX;
2391 			else if (txmode == 3)
2392 				pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX;
2393 			else if (txmode == 4)
2394 				pmp_priv->mode = MP_SINGLE_CARRIER_TX;
2395 
2396 			status = rtw_mp_pretx_proc(padapter, bStartTest, extra);
2397 		}
2398 
2399 	}
2400 
2401 	wrqu->data.length = strlen(extra);
2402 	return status;
2403 }
2404 
2405 
rtw_mp_rx(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2406 int rtw_mp_rx(struct net_device *dev,
2407 	      struct iw_request_info *info,
2408 	      union iwreq_data *wrqu, char *extra)
2409 {
2410 	PADAPTER padapter = rtw_netdev_priv(dev);
2411 	HAL_DATA_TYPE	*pHalData	= GET_HAL_DATA(padapter);
2412 	struct mp_priv *pmp_priv = &padapter->mppriv;
2413 	char *pextra = extra;
2414 	u32 bandwidth = 0, sg = 0, channel = 6, ant = 0;
2415 	u16 antenna = 0;
2416 	u8 bStartRx = 0;
2417 
2418 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2419 		return -EFAULT;
2420 
2421 #ifdef CONFIG_CONCURRENT_MODE
2422 	if (!is_primary_adapter(padapter)) {
2423 		sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n");
2424 		wrqu->data.length = strlen(extra);
2425 		return 0;
2426 	}
2427 #endif
2428 
2429 	if (strncmp(extra, "stop", 4) == 0) {
2430 		_rtw_memset(extra, 0, wrqu->data.length);
2431 		SetPacketRx(padapter, bStartRx, _FALSE);
2432 		pmp_priv->bmac_filter = _FALSE;
2433 		sprintf(extra, "Received packet OK:%d CRC error:%d ,Filter out:%d", padapter->mppriv.rx_pktcount, padapter->mppriv.rx_crcerrpktcount, padapter->mppriv.rx_pktcount_filter_out);
2434 		wrqu->data.length = strlen(extra);
2435 		return 0;
2436 
2437 	} else if (sscanf(extra, "ch=%d,bw=%d,ant=%d", &channel, &bandwidth, &ant) < 3) {
2438 		RTW_INFO("Invalid format [ch=%d,bw=%d,ant=%d]\n", channel, bandwidth, ant);
2439 		_rtw_memset(extra, 0, wrqu->data.length);
2440 		pextra += sprintf(pextra, "\n Please input correct format as bleow:\n");
2441 		pextra += sprintf(pextra, "\t ch=%d,bw=%d,ant=%d\n", channel, bandwidth, ant);
2442 		pextra += sprintf(pextra, "\n [ ch : BGN = <1~14> , A or AC = <36~165> ]");
2443 		pextra += sprintf(pextra, "\n [ bw : Bandwidth: 0 = 20M, 1 = 40M, 2 = 80M ]");
2444 		pextra += sprintf(pextra, "\n [ ant : <A = 1, B = 2, C = 4, D = 8> ,2T ex: AB=3 BC=6 CD=12");
2445 		wrqu->data.length = strlen(extra);
2446 		return 0;
2447 
2448 	} else {
2449 		char *pextra = extra;
2450 		bStartRx = 1;
2451 		RTW_INFO("Got format [ch=%d,bw=%d,ant=%d]\n", channel, bandwidth, ant);
2452 		_rtw_memset(extra, 0, wrqu->data.length);
2453 		sprintf(extra, "Change Current channel %d to channel %d", padapter->mppriv.channel , channel);
2454 		padapter->mppriv.channel = channel;
2455 		SetChannel(padapter);
2456 		pHalData->current_channel = channel;
2457 
2458 		if (bandwidth == 1)
2459 			bandwidth = CHANNEL_WIDTH_40;
2460 		else if (bandwidth == 2)
2461 			bandwidth = CHANNEL_WIDTH_80;
2462 		pextra = extra + strlen(extra);
2463 		pextra += sprintf(pextra, "\nChange Current Bandwidth %d to Bandwidth %d", padapter->mppriv.bandwidth, bandwidth);
2464 		padapter->mppriv.bandwidth = (u8)bandwidth;
2465 		padapter->mppriv.preamble = sg;
2466 		SetBandwidth(padapter);
2467 		pHalData->current_channel_bw = bandwidth;
2468 
2469 		pextra += sprintf(pextra, "\nSet Antenna Path :%d", ant);
2470 		switch (ant) {
2471 		case 1:
2472 			antenna = ANTENNA_A;
2473 			break;
2474 		case 2:
2475 			antenna = ANTENNA_B;
2476 			break;
2477 		case 4:
2478 			antenna = ANTENNA_C;
2479 			break;
2480 		case 8:
2481 			antenna = ANTENNA_D;
2482 			break;
2483 		case 3:
2484 			antenna = ANTENNA_AB;
2485 			break;
2486 		case 5:
2487 			antenna = ANTENNA_AC;
2488 			break;
2489 		case 9:
2490 			antenna = ANTENNA_AD;
2491 			break;
2492 		case 6:
2493 			antenna = ANTENNA_BC;
2494 			break;
2495 		case 10:
2496 			antenna = ANTENNA_BD;
2497 			break;
2498 		case 12:
2499 			antenna = ANTENNA_CD;
2500 			break;
2501 		case 7:
2502 			antenna = ANTENNA_ABC;
2503 			break;
2504 		case 14:
2505 			antenna = ANTENNA_BCD;
2506 			break;
2507 		case 11:
2508 			antenna = ANTENNA_ABD;
2509 			break;
2510 		case 15:
2511 			antenna = ANTENNA_ABCD;
2512 			break;
2513 		}
2514 		RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);
2515 		padapter->mppriv.antenna_tx = antenna;
2516 		padapter->mppriv.antenna_rx = antenna;
2517 		pHalData->antenna_tx_path = antenna;
2518 		SetAntenna(padapter);
2519 
2520 		strcat(extra, "\nstart Rx");
2521 		SetPacketRx(padapter, bStartRx, _FALSE);
2522 	}
2523 	wrqu->data.length = strlen(extra);
2524 	return 0;
2525 }
2526 
2527 
rtw_mp_hwtx(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2528 int rtw_mp_hwtx(struct net_device *dev,
2529 		struct iw_request_info *info,
2530 		union iwreq_data *wrqu, char *extra)
2531 {
2532 	PADAPTER padapter = rtw_netdev_priv(dev);
2533 	struct mp_priv *pmp_priv = &padapter->mppriv;
2534 	PMPT_CONTEXT		pMptCtx = &(padapter->mppriv.mpt_ctx);
2535 	char *pch;
2536 
2537 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
2538 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2539 		return -EFAULT;
2540 	*(extra + wrqu->data.length) = '\0';
2541 
2542 	_rtw_memset(&pMptCtx->PMacTxInfo, 0, sizeof(RT_PMAC_TX_INFO));
2543 	_rtw_memcpy((void *)&pMptCtx->PMacTxInfo, (void *)extra, sizeof(RT_PMAC_TX_INFO));
2544 	_rtw_memset(extra, 0, wrqu->data.length);
2545 	pch = extra;
2546 
2547 	if (pMptCtx->PMacTxInfo.bEnPMacTx == 1 && pmp_priv->mode != MP_ON) {
2548 		pch += sprintf(pch, "MP Tx Running, Please Set PMac Tx Mode Stop\n");
2549 		RTW_INFO("Error !!! MP Tx Running, Please Set PMac Tx Mode Stop\n");
2550 	} else {
2551 		RTW_INFO("To set MAC Tx mode\n");
2552 		if (mpt_ProSetPMacTx(padapter))
2553 			pch += sprintf(pch, "Set PMac Tx Mode OK\n");
2554 		else
2555 			pch += sprintf(pch, "Set PMac Tx Mode Error\n");
2556 	}
2557 	wrqu->data.length = strlen(extra);
2558 #endif
2559 	return 0;
2560 
2561 }
2562 
rtw_mp_pwrlmt(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2563 int rtw_mp_pwrlmt(struct net_device *dev,
2564 			struct iw_request_info *info,
2565 			union iwreq_data *wrqu, char *extra)
2566 {
2567 	PADAPTER padapter = rtw_netdev_priv(dev);
2568 	struct registry_priv  *registry_par = &padapter->registrypriv;
2569 	char *pch;
2570 
2571 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2572 		return -EFAULT;
2573 
2574 	*(extra + wrqu->data.length) = '\0';
2575 	pch = extra;
2576 
2577 #if CONFIG_TXPWR_LIMIT
2578 	if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
2579 		padapter->registrypriv.RegEnableTxPowerLimit = 0;
2580 		pch += sprintf(pch, "Turn off Power Limit\n");
2581 
2582 	} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
2583 		padapter->registrypriv.RegEnableTxPowerLimit = 1;
2584 		pch += sprintf(pch, "Turn on Power Limit\n");
2585 
2586 	} else
2587 #endif
2588 		pch += sprintf(pch, "Get Power Limit Status:%s\n", (registry_par->RegEnableTxPowerLimit == 1) ? "ON" : "OFF");
2589 
2590 
2591 	wrqu->data.length = strlen(extra);
2592 	return 0;
2593 }
2594 
rtw_mp_pwrbyrate(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2595 int rtw_mp_pwrbyrate(struct net_device *dev,
2596 			struct iw_request_info *info,
2597 			union iwreq_data *wrqu, char *extra)
2598 {
2599 	PADAPTER padapter = rtw_netdev_priv(dev);
2600 
2601 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2602 		return -EFAULT;
2603 
2604 	*(extra + wrqu->data.length) = '\0';
2605 	if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
2606 		padapter->registrypriv.RegEnableTxPowerByRate = 0;
2607 		sprintf(extra, "Turn off Tx Power by Rate\n");
2608 
2609 	} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
2610 		padapter->registrypriv.RegEnableTxPowerByRate = 1;
2611 		sprintf(extra, "Turn On Tx Power by Rate\n");
2612 
2613 	} else {
2614 		sprintf(extra, "Get Power by Rate Status:%s\n", (padapter->registrypriv.RegEnableTxPowerByRate == 1) ? "ON" : "OFF");
2615 	}
2616 
2617 	wrqu->data.length = strlen(extra);
2618 	return 0;
2619 }
2620 
2621 
rtw_mp_dpk_track(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2622 int rtw_mp_dpk_track(struct net_device *dev,
2623 			struct iw_request_info *info,
2624 			union iwreq_data *wrqu, char *extra)
2625 {
2626 	PADAPTER padapter = rtw_netdev_priv(dev);
2627 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
2628 	struct dm_struct		*pDM_Odm = &pHalData->odmpriv;
2629 	char *pch;
2630 
2631 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2632 		return -EFAULT;
2633 
2634 	*(extra + wrqu->data.length) = '\0';
2635 	pch = extra;
2636 
2637 	if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
2638 		halrf_set_dpk_track(pDM_Odm, FALSE);
2639 		pch += sprintf(pch, "set dpk track off\n");
2640 
2641 	} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
2642 		halrf_set_dpk_track(pDM_Odm, TRUE);
2643 		pch += sprintf(pch, "set dpk track on\n");
2644 	}
2645 
2646 	wrqu->data.length = strlen(extra);
2647 	return 0;
2648 }
2649 
2650 
rtw_bt_efuse_mask_file(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2651 int rtw_bt_efuse_mask_file(struct net_device *dev,
2652 			struct iw_request_info *info,
2653 			union iwreq_data *wrqu, char *extra)
2654 {
2655 	char *rtw_efuse_mask_file_path;
2656 	u8	*pch;
2657 	char	*ptmp, tmp;
2658 	u8 Status;
2659 	PADAPTER padapter = rtw_netdev_priv(dev);
2660 
2661 	_rtw_memset(btmaskfileBuffer, 0x00, sizeof(btmaskfileBuffer));
2662 
2663 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2664 		return -EFAULT;
2665 
2666 	*(extra + wrqu->data.length) = '\0';
2667 	ptmp = extra;
2668 
2669 	if (strncmp(extra, "data,", 5) == 0) {
2670 		u8	count = 0;
2671 		u8	i = 0;
2672 
2673 		pch = strsep(&ptmp, ",");
2674 
2675 		if ((pch == NULL) || (strlen(pch) == 0)) {
2676 			RTW_INFO("%s: parameter error(no cmd)!\n", __func__);
2677 			return -EFAULT;
2678 		}
2679 
2680 		do {
2681 			pch = strsep(&ptmp, ":");
2682 			if ((pch == NULL) || (strlen(pch) == 0))
2683 				break;
2684 			if (strlen(pch) != 2
2685 				|| IsHexDigit(*pch) == _FALSE
2686 				|| IsHexDigit(*(pch + 1)) == _FALSE
2687 				|| sscanf(pch, "%hhx", &tmp) != 1
2688 			) {
2689 				RTW_INFO("%s: invalid 8-bit hex! input format: data,01:23:45:67:89:ab:cd:ef...\n", __func__);
2690 				return -EFAULT;
2691 			}
2692 			btmaskfileBuffer[count++] = tmp;
2693 
2694 		 } while (count < 64);
2695 
2696 		_rtw_memset(extra, '\0' , strlen(extra));
2697 
2698 		for (i = 0; i < count; i++)
2699 			ptmp += sprintf(ptmp, "%02x:", btmaskfileBuffer[i]);
2700 
2701 		padapter->registrypriv.bBTFileMaskEfuse = _TRUE;
2702 
2703 		ptmp += sprintf(ptmp, "\nLoad BT Efuse Mask data %d hex ok\n", count);
2704 		wrqu->data.length = strlen(extra);
2705 		return 0;
2706 	}
2707 	rtw_efuse_mask_file_path = extra;
2708 
2709 	if (rtw_is_file_readable(rtw_efuse_mask_file_path) == _TRUE) {
2710 		RTW_INFO("%s do rtw_is_file_readable = %s! ,sizeof BT maskfileBuffer %zu\n", __func__, rtw_efuse_mask_file_path, sizeof(btmaskfileBuffer));
2711 		Status = rtw_efuse_file_read(padapter, rtw_efuse_mask_file_path, btmaskfileBuffer, sizeof(btmaskfileBuffer));
2712 		_rtw_memset(extra, '\0' , strlen(extra));
2713 		if (Status == _TRUE) {
2714 			padapter->registrypriv.bBTFileMaskEfuse = _TRUE;
2715 			ptmp += sprintf(ptmp, "BT efuse mask file read OK\n");
2716 		} else {
2717 			padapter->registrypriv.bBTFileMaskEfuse = _FALSE;
2718 			ptmp += sprintf(ptmp, "read BT efuse mask file FAIL\n");
2719 			RTW_INFO("%s rtw_efuse_file_read BT mask fail!\n", __func__);
2720 		}
2721 	} else {
2722 		padapter->registrypriv.bBTFileMaskEfuse = _FALSE;
2723 		ptmp += sprintf(ptmp, "BT efuse mask file readable FAIL\n");
2724 		RTW_INFO("%s rtw_is_file_readable BT Mask file fail!\n", __func__);
2725 	}
2726 	wrqu->data.length = strlen(extra);
2727 	return 0;
2728 }
2729 
2730 
rtw_efuse_mask_file(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2731 int rtw_efuse_mask_file(struct net_device *dev,
2732 			struct iw_request_info *info,
2733 			union iwreq_data *wrqu, char *extra)
2734 {
2735 	char *rtw_efuse_mask_file_path;
2736 	u8 Status;
2737 	PADAPTER padapter = rtw_netdev_priv(dev);
2738 
2739 	_rtw_memset(maskfileBuffer, 0x00, sizeof(maskfileBuffer));
2740 
2741 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2742 		return -EFAULT;
2743 
2744 	*(extra + wrqu->data.length) = '\0';
2745 	if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
2746 		padapter->registrypriv.boffefusemask = 1;
2747 		sprintf(extra, "Turn off Efuse Mask\n");
2748 		wrqu->data.length = strlen(extra);
2749 		return 0;
2750 	}
2751 	if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
2752 		padapter->registrypriv.boffefusemask = 0;
2753 		sprintf(extra, "Turn on Efuse Mask\n");
2754 		wrqu->data.length = strlen(extra);
2755 		return 0;
2756 	}
2757 	if (strncmp(extra, "data,", 5) == 0) {
2758 		u8	*pch;
2759 		char	*ptmp, tmp;
2760 		u8	count = 0;
2761 		u8	i = 0;
2762 
2763 		ptmp = extra;
2764 		pch = strsep(&ptmp, ",");
2765 
2766 		if ((pch == NULL) || (strlen(pch) == 0)) {
2767 			RTW_INFO("%s: parameter error(no cmd)!\n", __func__);
2768 			return -EFAULT;
2769 		}
2770 
2771 		do {
2772 			pch = strsep(&ptmp, ":");
2773 			if ((pch == NULL) || (strlen(pch) == 0))
2774 				break;
2775 			if (strlen(pch) != 2
2776 				|| IsHexDigit(*pch) == _FALSE
2777 				|| IsHexDigit(*(pch + 1)) == _FALSE
2778 				|| sscanf(pch, "%hhx", &tmp) != 1
2779 			) {
2780 				RTW_INFO("%s: invalid 8-bit hex! input format: data,01:23:45:67:89:ab:cd:ef...\n", __func__);
2781 				return -EFAULT;
2782 			}
2783 			maskfileBuffer[count++] = tmp;
2784 
2785 		} while (count < 64);
2786 
2787 		_rtw_memset(extra, '\0' , strlen(extra));
2788 
2789 		for (i = 0; i < count; i++)
2790 			ptmp += sprintf(ptmp, "%02x:", maskfileBuffer[i]);
2791 
2792 		padapter->registrypriv.bFileMaskEfuse = _TRUE;
2793 
2794 		sprintf(ptmp, "\nLoad Efuse Mask data %d hex ok\n", count);
2795 		wrqu->data.length = strlen(extra);
2796 		return 0;
2797 	}
2798 	rtw_efuse_mask_file_path = extra;
2799 
2800 	if (rtw_is_file_readable(rtw_efuse_mask_file_path) == _TRUE) {
2801 		RTW_INFO("%s do rtw_efuse_mask_file_read = %s! ,sizeof maskfileBuffer %zu\n", __func__, rtw_efuse_mask_file_path, sizeof(maskfileBuffer));
2802 		Status = rtw_efuse_file_read(padapter, rtw_efuse_mask_file_path, maskfileBuffer, sizeof(maskfileBuffer));
2803 		if (Status == _TRUE) {
2804 			padapter->registrypriv.bFileMaskEfuse = _TRUE;
2805 			sprintf(extra, "efuse mask file read OK\n");
2806 		} else {
2807 			padapter->registrypriv.bFileMaskEfuse = _FALSE;
2808 			sprintf(extra, "read efuse mask file FAIL\n");
2809 			RTW_INFO("%s rtw_efuse_file_read mask fail!\n", __func__);
2810 		}
2811 	} else {
2812 		padapter->registrypriv.bFileMaskEfuse = _FALSE;
2813 		sprintf(extra, "efuse mask file readable FAIL\n");
2814 		RTW_INFO("%s rtw_is_file_readable fail!\n", __func__);
2815 	}
2816 	wrqu->data.length = strlen(extra);
2817 	return 0;
2818 }
2819 
2820 
rtw_efuse_file_map(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2821 int rtw_efuse_file_map(struct net_device *dev,
2822 		       struct iw_request_info *info,
2823 		       union iwreq_data *wrqu, char *extra)
2824 {
2825 	char *rtw_efuse_file_map_path;
2826 	u8 Status;
2827 	PEFUSE_HAL pEfuseHal;
2828 	PADAPTER padapter = rtw_netdev_priv(dev);
2829 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
2830 	struct mp_priv *pmp_priv = &padapter->mppriv;
2831 
2832 	pEfuseHal = &pHalData->EfuseHal;
2833 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2834 		return -EFAULT;
2835 
2836 	rtw_efuse_file_map_path = extra;
2837 
2838 	_rtw_memset(pEfuseHal->fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);
2839 
2840 	if (rtw_is_file_readable(rtw_efuse_file_map_path) == _TRUE) {
2841 		RTW_INFO("%s do rtw_efuse_mask_file_read = %s!\n", __func__, rtw_efuse_file_map_path);
2842 		Status = rtw_efuse_file_read(padapter, rtw_efuse_file_map_path, pEfuseHal->fakeEfuseModifiedMap, sizeof(pEfuseHal->fakeEfuseModifiedMap));
2843 		if (Status == _TRUE) {
2844 			pmp_priv->bloadefusemap = _TRUE;
2845 			sprintf(extra, "efuse file file_read OK\n");
2846 		} else {
2847 			pmp_priv->bloadefusemap = _FALSE;
2848 			sprintf(extra, "efuse file file_read FAIL\n");
2849 		}
2850 	} else {
2851 		sprintf(extra, "efuse file readable FAIL\n");
2852 		RTW_INFO("%s rtw_is_file_readable fail!\n", __func__);
2853 	}
2854 	wrqu->data.length = strlen(extra);
2855 	return 0;
2856 }
2857 
2858 
rtw_efuse_file_map_store(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2859 int rtw_efuse_file_map_store(struct net_device *dev,
2860 				struct iw_request_info *info,
2861 				union iwreq_data *wrqu, char *extra)
2862 {
2863 	char *rtw_efuse_file_map_path;
2864 	u8 Status;
2865 	u16 mapLen;
2866 	PEFUSE_HAL pEfuseHal;
2867 	PADAPTER padapter = rtw_netdev_priv(dev);
2868 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
2869 	struct mp_priv *pmp_priv = &padapter->mppriv;
2870 
2871 	pEfuseHal = &pHalData->EfuseHal;
2872 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2873 		return -EFAULT;
2874 
2875 	rtw_efuse_file_map_path = extra;
2876 	RTW_INFO("%s rtw_is_file_readable! %s\n", __func__, rtw_efuse_file_map_path);
2877 
2878 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapLen, _FALSE);
2879 
2880 	if (mapLen != 0) {
2881 		RTW_INFO("%s, efuse store path = %s! mapLen = %d\n", __func__, rtw_efuse_file_map_path, mapLen);
2882 		Status = rtw_efuse_file_store(padapter, rtw_efuse_file_map_path, pEfuseHal->fakeEfuseModifiedMap, mapLen);
2883 		if (Status) {
2884 			sprintf(extra, "efuse file restore OK\n");
2885 		} else {
2886 			sprintf(extra, "efuse file restore FAIL\n");
2887 		}
2888 	} else {
2889 		sprintf(extra, "efuse file readable FAIL\n");
2890 		RTW_INFO("%s rtw_is_file_readable fail! map Len %d\n", __func__, mapLen);
2891 	}
2892 
2893 	wrqu->data.length = strlen(extra);
2894 	return 0;
2895 }
2896 
rtw_bt_efuse_file_map(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2897 int rtw_bt_efuse_file_map(struct net_device *dev,
2898 				struct iw_request_info *info,
2899 				union iwreq_data *wrqu, char *extra)
2900 {
2901 	char *rtw_efuse_file_map_path;
2902 	u8 Status;
2903 	PEFUSE_HAL pEfuseHal;
2904 	PADAPTER padapter = rtw_netdev_priv(dev);
2905 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
2906 	struct mp_priv *pmp_priv = &padapter->mppriv;
2907 
2908 	pEfuseHal = &pHalData->EfuseHal;
2909 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2910 		return -EFAULT;
2911 
2912 	rtw_efuse_file_map_path = extra;
2913 
2914 	_rtw_memset(pEfuseHal->fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2915 
2916 	if (rtw_is_file_readable(rtw_efuse_file_map_path) == _TRUE) {
2917 		RTW_INFO("%s do rtw_efuse_mask_file_read = %s!\n", __func__, rtw_efuse_file_map_path);
2918 		Status = rtw_efuse_file_read(padapter, rtw_efuse_file_map_path, pEfuseHal->fakeBTEfuseModifiedMap, sizeof(pEfuseHal->fakeBTEfuseModifiedMap));
2919 		if (Status == _TRUE) {
2920 			pmp_priv->bloadBTefusemap = _TRUE;
2921 			sprintf(extra, "BT efuse file file_read OK\n");
2922 		} else {
2923 			pmp_priv->bloadBTefusemap = _FALSE;
2924 			sprintf(extra, "BT efuse file file_read FAIL\n");
2925 		}
2926 	} else {
2927 		sprintf(extra, "BT efuse file readable FAIL\n");
2928 		RTW_INFO("%s rtw_is_file_readable fail!\n", __func__);
2929 	}
2930 	wrqu->data.length = strlen(extra);
2931 	return 0;
2932 }
2933 
2934 
dump_buf(u8 * buf,u32 len)2935 static inline void dump_buf(u8 *buf, u32 len)
2936 {
2937 	u32 i;
2938 
2939 	RTW_INFO("-----------------Len %d----------------\n", len);
2940 	for (i = 0; i < len; i++)
2941 		RTW_INFO("%2.2x-", *(buf + i));
2942 	RTW_INFO("\n");
2943 }
2944 
rtw_mp_link(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)2945 int rtw_mp_link(struct net_device *dev,
2946 			struct iw_request_info *info,
2947 			struct iw_point *wrqu, char *extra)
2948 {
2949 	PADAPTER padapter = rtw_netdev_priv(dev);
2950 	struct mp_priv *pmp_priv;
2951 	char input[RTW_IWD_MAX_LEN];
2952 	int		bgetrxdata = 0, btxdata = 0, bsetbt = 0;
2953 	u8 err = 0;
2954 	u32 i = 0, datalen = 0,jj, kk, waittime = 0;
2955 	u16 val = 0x00, ret = 0;
2956 	char *pextra = NULL;
2957 	u8 *setdata = NULL;
2958 	char *pch, *ptmp, *token, *tmp[4] = {0x00, 0x00, 0x00};
2959 
2960 	pmp_priv = &padapter->mppriv;
2961 
2962 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
2963 		return -EFAULT;
2964 
2965 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
2966 		return -EFAULT;
2967 
2968 	_rtw_memset(extra, 0, wrqu->length);
2969 
2970 	RTW_INFO("%s: in=%s\n", __func__, input);
2971 
2972 	bgetrxdata =  (strncmp(input, "rxdata", 6) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
2973 	btxdata =  (strncmp(input, "txdata", 6) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
2974 	bsetbt =  (strncmp(input, "setbt", 5) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
2975 
2976 	if (bgetrxdata) {
2977 		RTW_INFO("%s: in= 1 \n", __func__);
2978 		if (pmp_priv->mplink_brx == _TRUE) {
2979 			pch = extra;
2980 				while (waittime < 100 && pmp_priv->mplink_brx == _FALSE) {
2981 						if (pmp_priv->mplink_brx == _FALSE)
2982 							rtw_msleep_os(10);
2983 						else
2984 							break;
2985 						waittime++;
2986 				}
2987 				if (pmp_priv->mplink_brx == _TRUE) {
2988 					pch += sprintf(pch, "\n");
2989 
2990 					for (i = 0; i < pmp_priv->mplink_rx_len; i ++) {
2991 						pch += sprintf(pch, "%02x:", pmp_priv->mplink_buf[i]);
2992 					}
2993 					_rtw_memset(pmp_priv->mplink_buf, '\0' , sizeof(pmp_priv->mplink_buf));
2994 					pmp_priv->mplink_brx = _FALSE;
2995 				}
2996 		}
2997 	} else if (btxdata) {
2998 		struct pkt_attrib *pattrib;
2999 
3000 		pch = input;
3001 		setdata = rtw_zmalloc(1024);
3002 		if (setdata == NULL) {
3003 			err = -ENOMEM;
3004 			goto exit;
3005 		}
3006 
3007 		i = 0;
3008 		while ((token = strsep(&pch, ",")) != NULL) {
3009 			if (i > 2)
3010 				break;
3011 			tmp[i] = token;
3012 			i++;
3013 		}
3014 
3015 		/* tmp[0],[1],[2] */
3016 		/* txdata,00e04c871200........... */
3017 		if (strcmp(tmp[0], "txdata") == 0) {
3018 			if ((tmp[1] == NULL)) {
3019 				err = -EINVAL;
3020 				goto exit;
3021 			}
3022 		}
3023 
3024 		datalen = strlen(tmp[1]);
3025 		if (datalen % 2) {
3026 			err = -EINVAL;
3027 			goto exit;
3028 		}
3029 		datalen /= 2;
3030 		if (datalen == 0) {
3031 			err = -EINVAL;
3032 			goto exit;
3033 		}
3034 
3035 		RTW_INFO("%s: data len=%d\n", __FUNCTION__, datalen);
3036 		RTW_INFO("%s: tx data=%s\n", __FUNCTION__, tmp[1]);
3037 
3038 		for (jj = 0, kk = 0; jj < datalen; jj++, kk += 2)
3039 			setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
3040 
3041 		dump_buf(setdata, datalen);
3042 		_rtw_memset(pmp_priv->mplink_buf, '\0' , sizeof(pmp_priv->mplink_buf));
3043 		_rtw_memcpy(pmp_priv->mplink_buf, setdata, datalen);
3044 
3045 		pattrib = &pmp_priv->tx.attrib;
3046 		pattrib->pktlen = datalen;
3047 		pmp_priv->tx.count = 1;
3048 		pmp_priv->tx.stop = 0;
3049 		pmp_priv->mplink_btx = _TRUE;
3050 		SetPacketTx(padapter);
3051 		pmp_priv->mode = MP_PACKET_TX;
3052 
3053 	} else if (bsetbt) {
3054 
3055 #ifdef CONFIG_BT_COEXIST
3056 		pch = input;
3057 		i = 0;
3058 
3059 		while ((token = strsep(&pch, ",")) != NULL) {
3060 			if (i > 3)
3061 				break;
3062 			tmp[i] = token;
3063 			i++;
3064 		}
3065 
3066 		if (tmp[1] == NULL) {
3067 			err = -EINVAL;
3068 			goto exit;
3069 		}
3070 
3071 		if (strcmp(tmp[1], "scbd") == 0) {
3072 			u16 org_val = 0x8002, pre_val, read_score_board_val;
3073 			u8 state;
3074 
3075 			pre_val = (rtw_read16(padapter,(0xaa))) & 0x7fff;
3076 
3077 			if (tmp[2] != NULL) {
3078 				state = simple_strtoul(tmp[2], &ptmp, 10);
3079 
3080 				if (state)
3081 						org_val = org_val | BIT6;
3082 				else
3083 						org_val = org_val & (~BIT6);
3084 
3085 				if (org_val != pre_val) {
3086 					pre_val = org_val;
3087 					rtw_write16(padapter, 0xaa, org_val);
3088 					RTW_INFO("%s,setbt scbd write org_val = 0x%x , pre_val = 0x%x\n", __func__, org_val, pre_val);
3089 				} else {
3090 					RTW_INFO("%s,setbt scbd org_val = 0x%x ,pre_val = 0x%x\n", __func__, org_val, pre_val);
3091 				}
3092 			} else {
3093 					read_score_board_val = (rtw_read16(padapter,(0xaa))) & 0x7fff;
3094 					RTW_INFO("%s,read_score_board_val = 0x%x\n", __func__, read_score_board_val);
3095 			}
3096 			goto exit;
3097 
3098 		} else if (strcmp(tmp[1], "testmode") == 0) {
3099 
3100 			if (tmp[2] == NULL) {
3101 				err = -EINVAL;
3102 				goto exit;
3103 			}
3104 
3105 			val = simple_strtoul(tmp[2], &ptmp, 16);
3106 			RTW_INFO("get tmp, type  %s, val =0x%x!\n", tmp[1], val);
3107 
3108 			if (tmp[2] != NULL) {
3109 				_rtw_memset(extra, 0, wrqu->length);
3110 				pch = extra;
3111 				ret = rtw_btcoex_btset_testmode(padapter, val);
3112 				if (!CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(ret, BT_STATUS_BT_OP_SUCCESS)) {
3113 					RTW_INFO("%s: BT_OP fail = 0x%x!\n", __FUNCTION__, val);
3114 					pch += sprintf(pch, "BT_OP fail  0x%x!\n", val);
3115 				} else
3116 					pch += sprintf(pch, "Set BT_OP 0x%x done!\n", val);
3117 			}
3118 
3119 		}
3120 #endif /* CONFIG_BT_COEXIST */
3121 	}
3122 
3123 exit:
3124 	if (setdata)
3125 		rtw_mfree(setdata, 1024);
3126 
3127 	wrqu->length = strlen(extra);
3128 	return err;
3129 
3130 }
3131 
3132 #if defined(CONFIG_RTL8723B)
rtw_mp_SetBT(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3133 int rtw_mp_SetBT(struct net_device *dev,
3134 		 struct iw_request_info *info,
3135 		 union iwreq_data *wrqu, char *extra)
3136 {
3137 	PADAPTER padapter = rtw_netdev_priv(dev);
3138 	struct hal_ops *pHalFunc = &padapter->hal_func;
3139 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
3140 
3141 	BT_REQ_CMD	BtReq;
3142 	PMPT_CONTEXT	pMptCtx = &(padapter->mppriv.mpt_ctx);
3143 	PBT_RSP_CMD	pBtRsp = (PBT_RSP_CMD)&pMptCtx->mptOutBuf[0];
3144 	char	input[128];
3145 	char *pch, *ptmp, *token, *tmp[2] = {0x00, 0x00};
3146 	u8 setdata[100];
3147 	u8 resetbt = 0x00;
3148 	u8 tempval, BTStatus;
3149 	u8 H2cSetbtmac[6];
3150 	u8 u1H2CBtMpOperParm[4] = {0x01};
3151 	int testmode = 1, ready = 1, trxparam = 1, setgen = 1, getgen = 1, testctrl = 1, testbt = 1, readtherm = 1, setbtmac = 1;
3152 	u32 i = 0, ii = 0, jj = 0, kk = 0, cnts = 0, status = 0;
3153 	PRT_MP_FIRMWARE pBTFirmware = NULL;
3154 
3155 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
3156 		return -EFAULT;
3157 
3158 	*(extra + wrqu->data.length) = '\0';
3159 	pch = extra;
3160 
3161 	if (strlen(extra) < 1)
3162 		return -EFAULT;
3163 
3164 	RTW_INFO("%s:iwpriv in=%s\n", __func__, extra);
3165 	ready = strncmp(extra, "ready", 5);
3166 	testmode = strncmp(extra, "testmode", 8); /* strncmp TRUE is 0*/
3167 	trxparam = strncmp(extra, "trxparam", 8);
3168 	setgen = strncmp(extra, "setgen", 6);
3169 	getgen = strncmp(extra, "getgen", 6);
3170 	testctrl = strncmp(extra, "testctrl", 8);
3171 	testbt = strncmp(extra, "testbt", 6);
3172 	readtherm = strncmp(extra, "readtherm", 9);
3173 	setbtmac = strncmp(extra, "setbtmac", 8);
3174 
3175 	if (strncmp(extra, "dlbt", 4) == 0) {
3176 		pHalData->LastHMEBoxNum = 0;
3177 		pHalData->bBTFWReady = _FALSE;
3178 		rtw_write8(padapter, 0xa3, 0x05);
3179 		BTStatus = rtw_read8(padapter, 0xa0);
3180 		RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __func__, BTStatus);
3181 		if (BTStatus != 0x04) {
3182 			pch += sprintf(pch, "BT Status not Active DLFW FAIL\n");
3183 			goto exit;
3184 		}
3185 
3186 		tempval = rtw_read8(padapter, 0x6B);
3187 		tempval |= BIT7;
3188 		rtw_write8(padapter, 0x6B, tempval);
3189 
3190 		/* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay*/
3191 		/* So don't write 0x6A[14]=1 and 0x6A[15]=0 together!*/
3192 		rtw_usleep_os(100);
3193 		/* disable BT power cut*/
3194 		/* 0x6A[14] = 0*/
3195 		tempval = rtw_read8(padapter, 0x6B);
3196 		tempval &= ~BIT6;
3197 		rtw_write8(padapter, 0x6B, tempval);
3198 		rtw_usleep_os(100);
3199 		MPT_PwrCtlDM(padapter, 0);
3200 		rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004));
3201 		rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF));
3202 		rtw_msleep_os(600);
3203 		rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010));
3204 		rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB));
3205 		rtw_msleep_os(1200);
3206 		pBTFirmware = (PRT_MP_FIRMWARE)rtw_zmalloc(sizeof(RT_MP_FIRMWARE));
3207 		if (pBTFirmware == NULL)
3208 			goto exit;
3209 		pHalData->bBTFWReady = _FALSE;
3210 		FirmwareDownloadBT(padapter, pBTFirmware);
3211 		if (pBTFirmware)
3212 			rtw_mfree((u8 *)pBTFirmware, sizeof(RT_MP_FIRMWARE));
3213 
3214 		RTW_INFO("Wait for FirmwareDownloadBT fw boot!\n");
3215 		rtw_msleep_os(2000);
3216 		_rtw_memset(extra, '\0', wrqu->data.length);
3217 		BtReq.opCodeVer = 1;
3218 		BtReq.OpCode = 0;
3219 		BtReq.paraLength = 0;
3220 		mptbt_BtControlProcess(padapter, &BtReq);
3221 		rtw_msleep_os(100);
3222 
3223 		RTW_INFO("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4], pMptCtx->mptOutBuf[5]);
3224 		if ((pMptCtx->mptOutBuf[4] == 0x00) && (pMptCtx->mptOutBuf[5] == 0x00)) {
3225 
3226 			if (padapter->mppriv.bTxBufCkFail == _TRUE)
3227 				pch += sprintf(pch, "check TxBuf Fail.\n");
3228 			else
3229 				pch += sprintf(pch, "download FW Fail.\n");
3230 		} else {
3231 			pch += sprintf(pch, "download FW OK.\n");
3232 			goto exit;
3233 		}
3234 		goto exit;
3235 	}
3236 	if (strncmp(extra, "dlfw", 4) == 0) {
3237 		pHalData->LastHMEBoxNum = 0;
3238 		pHalData->bBTFWReady = _FALSE;
3239 		rtw_write8(padapter, 0xa3, 0x05);
3240 		BTStatus = rtw_read8(padapter, 0xa0);
3241 		RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __func__, BTStatus);
3242 		if (BTStatus != 0x04) {
3243 			pch += sprintf(pch, "BT Status not Active DLFW FAIL\n");
3244 			goto exit;
3245 		}
3246 
3247 		tempval = rtw_read8(padapter, 0x6B);
3248 		tempval |= BIT7;
3249 		rtw_write8(padapter, 0x6B, tempval);
3250 
3251 		/* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay*/
3252 		/* So don't write 0x6A[14]=1 and 0x6A[15]=0 together!*/
3253 		rtw_usleep_os(100);
3254 		/* disable BT power cut*/
3255 		/* 0x6A[14] = 0*/
3256 		tempval = rtw_read8(padapter, 0x6B);
3257 		tempval &= ~BIT6;
3258 		rtw_write8(padapter, 0x6B, tempval);
3259 		rtw_usleep_os(100);
3260 
3261 		MPT_PwrCtlDM(padapter, 0);
3262 		rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004));
3263 		rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF));
3264 		rtw_msleep_os(600);
3265 		rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010));
3266 		rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB));
3267 		rtw_msleep_os(1200);
3268 
3269 #if defined(CONFIG_PLATFORM_SPRD) && (MP_DRIVER == 1)
3270 		/* Pull up BT reset pin.*/
3271 		RTW_INFO("%s: pull up BT reset pin when bt start mp test\n", __func__);
3272 		rtw_wifi_gpio_wlan_ctrl(WLAN_BT_PWDN_ON);
3273 #endif
3274 		RTW_INFO(" FirmwareDownload!\n");
3275 
3276 #if defined(CONFIG_RTL8723B)
3277 		status = rtl8723b_FirmwareDownload(padapter, _FALSE);
3278 #endif
3279 		RTW_INFO("Wait for FirmwareDownloadBT fw boot!\n");
3280 		rtw_msleep_os(1000);
3281 #ifdef CONFIG_BT_COEXIST
3282 		rtw_btcoex_HaltNotify(padapter);
3283 		RTW_INFO("SetBT btcoex HaltNotify !\n");
3284 		/*hal_btcoex1ant_SetAntPath(padapter);*/
3285 		rtw_btcoex_SetManualControl(padapter, _TRUE);
3286 #endif
3287 		_rtw_memset(extra, '\0', wrqu->data.length);
3288 		BtReq.opCodeVer = 1;
3289 		BtReq.OpCode = 0;
3290 		BtReq.paraLength = 0;
3291 		mptbt_BtControlProcess(padapter, &BtReq);
3292 		rtw_msleep_os(200);
3293 
3294 		RTW_INFO("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4], pMptCtx->mptOutBuf[5]);
3295 		if ((pMptCtx->mptOutBuf[4] == 0x00) && (pMptCtx->mptOutBuf[5] == 0x00)) {
3296 			if (padapter->mppriv.bTxBufCkFail == _TRUE)
3297 				pch += sprintf(pch, "check TxBuf Fail.\n");
3298 			else
3299 				pch += sprintf(pch, "download FW Fail.\n");
3300 		} else {
3301 #ifdef CONFIG_BT_COEXIST
3302 			rtw_btcoex_SwitchBtTRxMask(padapter);
3303 #endif
3304 			rtw_msleep_os(200);
3305 			pch += sprintf(pch, "download FW OK.\n");
3306 			goto exit;
3307 		}
3308 		goto exit;
3309 	}
3310 
3311 	if (strncmp(extra, "down", 4) == 0) {
3312 		RTW_INFO("SetBT down for to hal_init !\n");
3313 #ifdef CONFIG_BT_COEXIST
3314 		rtw_btcoex_SetManualControl(padapter, _FALSE);
3315 		rtw_btcoex_Initialize(padapter);
3316 #endif
3317 		pHalFunc->read_adapter_info(padapter);
3318 		pHalFunc->hal_deinit(padapter);
3319 		pHalFunc->hal_init(padapter);
3320 		rtw_pm_set_ips(padapter, IPS_NONE);
3321 		LeaveAllPowerSaveMode(padapter);
3322 		MPT_PwrCtlDM(padapter, 0);
3323 		rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004));
3324 		rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF));
3325 		rtw_msleep_os(600);
3326 		/*rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFE));*/
3327 		rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010));
3328 		rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB));
3329 		rtw_msleep_os(1200);
3330 		goto exit;
3331 	}
3332 	if (strncmp(extra, "disable", 7) == 0) {
3333 		RTW_INFO("SetBT disable !\n");
3334 		rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a) & 0xFFFFFFFB));
3335 		rtw_msleep_os(500);
3336 		goto exit;
3337 	}
3338 	if (strncmp(extra, "enable", 6) == 0) {
3339 		RTW_INFO("SetBT enable !\n");
3340 		rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a) | 0x00000004));
3341 		rtw_msleep_os(500);
3342 		goto exit;
3343 	}
3344 	if (strncmp(extra, "h2c", 3) == 0) {
3345 		RTW_INFO("SetBT h2c !\n");
3346 		pHalData->bBTFWReady = _TRUE;
3347 		rtw_hal_fill_h2c_cmd(padapter, 0x63, 1, u1H2CBtMpOperParm);
3348 		goto exit;
3349 	}
3350 	if (strncmp(extra, "2ant", 4) == 0) {
3351 		RTW_INFO("Set BT 2ant use!\n");
3352 		phy_set_mac_reg(padapter, 0x67, BIT5, 0x1);
3353 		rtw_write32(padapter, 0x948, 0000);
3354 
3355 		goto exit;
3356 	}
3357 
3358 	if (ready != 0 && testmode != 0 && trxparam != 0 && setgen != 0 && getgen != 0 && testctrl != 0 && testbt != 0 && readtherm != 0 && setbtmac != 0)
3359 		return -EFAULT;
3360 
3361 	if (testbt == 0) {
3362 		BtReq.opCodeVer = 1;
3363 		BtReq.OpCode = 6;
3364 		BtReq.paraLength = cnts / 2;
3365 		goto todo;
3366 	}
3367 	if (ready == 0) {
3368 		BtReq.opCodeVer = 1;
3369 		BtReq.OpCode = 0;
3370 		BtReq.paraLength = 0;
3371 		goto todo;
3372 	}
3373 
3374 	i = 0;
3375 	while ((token = strsep(&pch, ",")) != NULL) {
3376 		if (i > 1)
3377 			break;
3378 		tmp[i] = token;
3379 		i++;
3380 	}
3381 
3382 	if ((tmp[0] != NULL) && (tmp[1] != NULL)) {
3383 		cnts = strlen(tmp[1]);
3384 		if (cnts < 1)
3385 			return -EFAULT;
3386 
3387 		RTW_INFO("%s: cnts=%d\n", __func__, cnts);
3388 		RTW_INFO("%s: data=%s\n", __func__, tmp[1]);
3389 
3390 		for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) {
3391 			BtReq.pParamStart[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
3392 			/*			RTW_INFO("BtReq.pParamStart[%d]=0x%02x\n", jj, BtReq.pParamStart[jj]);*/
3393 		}
3394 	} else
3395 		return -EFAULT;
3396 
3397 	if (testmode == 0) {
3398 		BtReq.opCodeVer = 1;
3399 		BtReq.OpCode = 1;
3400 		BtReq.paraLength = 1;
3401 	}
3402 	if (trxparam == 0) {
3403 		BtReq.opCodeVer = 1;
3404 		BtReq.OpCode = 2;
3405 		BtReq.paraLength = cnts / 2;
3406 	}
3407 	if (setgen == 0) {
3408 		RTW_INFO("%s: BT_SET_GENERAL\n", __func__);
3409 		BtReq.opCodeVer = 1;
3410 		BtReq.OpCode = 3;/*BT_SET_GENERAL	3*/
3411 		BtReq.paraLength = cnts / 2;
3412 	}
3413 	if (getgen == 0) {
3414 		RTW_INFO("%s: BT_GET_GENERAL\n", __func__);
3415 		BtReq.opCodeVer = 1;
3416 		BtReq.OpCode = 4;/*BT_GET_GENERAL	4*/
3417 		BtReq.paraLength = cnts / 2;
3418 	}
3419 	if (readtherm == 0) {
3420 		RTW_INFO("%s: BT_GET_GENERAL\n", __func__);
3421 		BtReq.opCodeVer = 1;
3422 		BtReq.OpCode = 4;/*BT_GET_GENERAL	4*/
3423 		BtReq.paraLength = cnts / 2;
3424 	}
3425 
3426 	if (testctrl == 0) {
3427 		RTW_INFO("%s: BT_TEST_CTRL\n", __func__);
3428 		BtReq.opCodeVer = 1;
3429 		BtReq.OpCode = 5;/*BT_TEST_CTRL	5*/
3430 		BtReq.paraLength = cnts / 2;
3431 	}
3432 
3433 	RTW_INFO("%s: Req opCodeVer=%d OpCode=%d paraLength=%d\n",
3434 		 __func__, BtReq.opCodeVer, BtReq.OpCode, BtReq.paraLength);
3435 
3436 	if (BtReq.paraLength < 1)
3437 		goto todo;
3438 	for (i = 0; i < BtReq.paraLength; i++) {
3439 		RTW_INFO("%s: BtReq.pParamStart[%d] = 0x%02x\n",
3440 			 __func__, i, BtReq.pParamStart[i]);
3441 	}
3442 
3443 todo:
3444 	_rtw_memset(extra, '\0', wrqu->data.length);
3445 
3446 	if (pHalData->bBTFWReady == _FALSE) {
3447 		pch += sprintf(pch, "BTFWReady = FALSE.\n");
3448 		goto exit;
3449 	}
3450 
3451 	mptbt_BtControlProcess(padapter, &BtReq);
3452 
3453 	if (readtherm == 0) {
3454 		pch += sprintf(pch, "BT thermal=");
3455 		for (i = 4; i < pMptCtx->mptOutLen; i++) {
3456 			if ((pMptCtx->mptOutBuf[i] == 0x00) && (pMptCtx->mptOutBuf[i + 1] == 0x00))
3457 				goto exit;
3458 
3459 			pch += sprintf(pch, " %d ", (pMptCtx->mptOutBuf[i] & 0x1f));
3460 		}
3461 	} else {
3462 		for (i = 4; i < pMptCtx->mptOutLen; i++)
3463 			pch += sprintf(pch, " 0x%x ", pMptCtx->mptOutBuf[i]);
3464 	}
3465 
3466 exit:
3467 	wrqu->data.length = strlen(extra) + 1;
3468 	RTW_INFO("-%s: output len=%d data=%s\n", __func__, wrqu->data.length, extra);
3469 
3470 	return status;
3471 }
3472 
3473 #endif /*#ifdef CONFIG_RTL8723B*/
3474 
3475 #endif
3476