xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8723ds/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 #ifdef CONFIG_RTL8723F
1389 	ther_path_addr[0] = EEPROM_THERMAL_METER_8723F;
1390 #endif
1391 
1392 	if (copy_from_user(extra, wrqu->pointer, wrqu->length))
1393 		return -EFAULT;
1394 
1395 	if ((strncmp(extra, "write", 6) == 0)) {
1396 		int i;
1397 		u16 raw_cursize = 0, raw_maxsize = 0;
1398 #ifdef RTW_HALMAC
1399 		raw_maxsize = efuse_GetavailableSize(padapter);
1400 #else
1401 		efuse_GetCurrentSize(padapter, &raw_cursize);
1402 		raw_maxsize = efuse_GetMaxSize(padapter);
1403 #endif
1404 		RTW_INFO("[eFuse available raw size]= %d bytes\n", raw_maxsize - raw_cursize);
1405 		if (2 > raw_maxsize - raw_cursize) {
1406 			RTW_INFO("no available efuse!\n");
1407 			return -EFAULT;
1408 		}
1409 
1410 		for (i = 0; i < hal_spec->rf_reg_path_num; i++) {
1411 				GetThermalMeter(padapter, i , &val[i]);
1412 				if (ther_path_addr[i] != 0 && val[i] != 0) {
1413 					if (rtw_efuse_map_write(padapter, ther_path_addr[i], cnt, &val[i]) == _FAIL) {
1414 						RTW_INFO("Error efuse write thermal addr 0x%x ,val = 0x%x\n", ther_path_addr[i], val[i]);
1415 						return -EFAULT;
1416 					}
1417 				} else {
1418 						RTW_INFO("Error efuse write thermal Null addr,val \n");
1419 						return -EFAULT;
1420 				}
1421 		}
1422 		_rtw_memset(extra, 0, wrqu->length);
1423 		sprintf(extra, " efuse write ok :%d", val[0]);
1424 	} else {
1425 		ret = sscanf(extra, "%d", &rfpath);
1426 		if (ret < 1) {
1427 			rfpath = RF_PATH_A;
1428 			RTW_INFO("default thermal of path(%d)\n", rfpath);
1429 		}
1430 		if (rfpath >= hal_spec->rf_reg_path_num)
1431 			return -EINVAL;
1432 
1433 		RTW_INFO("read thermal of path(%d)\n", rfpath);
1434 		GetThermalMeter(padapter, rfpath, &val[0]);
1435 
1436 		_rtw_memset(extra, 0, wrqu->length);
1437 		sprintf(extra, "%d", val[0]);
1438 	}
1439 	wrqu->length = strlen(extra);
1440 
1441 	return 0;
1442 }
1443 
1444 
1445 
rtw_mp_reset_stats(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1446 int rtw_mp_reset_stats(struct net_device *dev,
1447 		       struct iw_request_info *info,
1448 		       struct iw_point *wrqu, char *extra)
1449 {
1450 	struct mp_priv *pmp_priv;
1451 	PADAPTER padapter = rtw_netdev_priv(dev);
1452 
1453 	pmp_priv = &padapter->mppriv;
1454 
1455 	pmp_priv->tx.sended = 0;
1456 	pmp_priv->tx_pktcount = 0;
1457 	pmp_priv->rx_pktcount = 0;
1458 	pmp_priv->rx_pktcount_filter_out = 0;
1459 	pmp_priv->rx_crcerrpktcount = 0;
1460 
1461 	rtw_reset_phy_rx_counters(padapter);
1462 	rtw_reset_mac_rx_counters(padapter);
1463 
1464 	_rtw_memset(extra, 0, wrqu->length);
1465 	sprintf(extra, "mp_reset_stats ok\n");
1466 	wrqu->length = strlen(extra);
1467 
1468 	return 0;
1469 }
1470 
1471 
rtw_mp_dump(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1472 int rtw_mp_dump(struct net_device *dev,
1473 		struct iw_request_info *info,
1474 		struct iw_point *wrqu, char *extra)
1475 {
1476 	struct mp_priv *pmp_priv;
1477 	u8 input[RTW_IWD_MAX_LEN];
1478 	PADAPTER padapter = rtw_netdev_priv(dev);
1479 
1480 	pmp_priv = &padapter->mppriv;
1481 
1482 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1483 		return -EFAULT;
1484 
1485 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1486 		return -EFAULT;
1487 
1488 	if (strncmp(input, "all", 4) == 0) {
1489 		mac_reg_dump(RTW_DBGDUMP, padapter);
1490 		bb_reg_dump(RTW_DBGDUMP, padapter);
1491 		rf_reg_dump(RTW_DBGDUMP, padapter);
1492 	}
1493 	return 0;
1494 }
1495 
1496 
rtw_mp_phypara(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1497 int rtw_mp_phypara(struct net_device *dev,
1498 		   struct iw_request_info *info,
1499 		   struct iw_point *wrqu, char *extra)
1500 {
1501 
1502 	PADAPTER padapter = rtw_netdev_priv(dev);
1503 	HAL_DATA_TYPE	*pHalData	= GET_HAL_DATA(padapter);
1504 	char input[RTW_IWD_MAX_LEN];
1505 	u32		invalxcap = 0, ret = 0, bwrite_xcap = 0, hwxtaladdr = 0;
1506 	u16		pgval;
1507 
1508 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1509 		return -EFAULT;
1510 
1511 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1512 		return -EFAULT;
1513 
1514 	RTW_INFO("%s:priv in=%s\n", __func__, input);
1515 	bwrite_xcap = (strncmp(input, "write_xcap=", 11) == 0) ? 1 : 0;
1516 
1517 	if (bwrite_xcap == 1) {
1518 		ret = sscanf(input, "write_xcap=%d", &invalxcap);
1519 		invalxcap = invalxcap & 0x7f; /* xtal bit 0 ~6 */
1520 		RTW_INFO("get crystal_cap %d\n", invalxcap);
1521 
1522 		if (IS_HARDWARE_TYPE_8822C(padapter) && ret == 1) {
1523 			hwxtaladdr = 0x110;
1524 			pgval = invalxcap | 0x80; /* reserved default bit7 on */
1525 			pgval = pgval | pgval << 8; /* xtal xi/xo efuse 0x110 0x111 */
1526 
1527 			RTW_INFO("Get crystal_cap 0x%x\n", pgval);
1528 			if (rtw_efuse_map_write(padapter, hwxtaladdr, 2, (u8*)&pgval) == _FAIL) {
1529 					RTW_INFO("%s: rtw_efuse_map_write xcap error!!\n", __func__);
1530 					sprintf(extra, "write xcap pgdata fail");
1531 					ret = -EFAULT;
1532 			} else
1533 					sprintf(extra, "write xcap pgdata ok");
1534 
1535 		}
1536 	} else {
1537 		ret = sscanf(input, "xcap=%d", &invalxcap);
1538 
1539 		if (ret == 1) {
1540 			pHalData->crystal_cap = (u8)invalxcap;
1541 			RTW_INFO("%s:crystal_cap=%d\n", __func__, pHalData->crystal_cap);
1542 
1543 			if (rtw_phydm_set_crystal_cap(padapter, pHalData->crystal_cap) == _FALSE) {
1544 				RTW_ERR("set crystal_cap failed\n");
1545 				rtw_warn_on(1);
1546 			}
1547 			sprintf(extra, "Set xcap=%d", invalxcap);
1548 		}
1549 	}
1550 
1551 	wrqu->length = strlen(extra) + 1;
1552 	return ret;
1553 }
1554 
1555 
rtw_mp_SetRFPath(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1556 int rtw_mp_SetRFPath(struct net_device *dev,
1557 		     struct iw_request_info *info,
1558 		     struct iw_point *wrqu, char *extra)
1559 {
1560 	PADAPTER padapter = rtw_netdev_priv(dev);
1561 	char input[RTW_IWD_MAX_LEN];
1562 	int		bMain = 1, bTurnoff = 1;
1563 #ifdef CONFIG_ANTENNA_DIVERSITY
1564 	u8 ret = _TRUE;
1565 #endif
1566 
1567 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1568 		return -EFAULT;
1569 
1570 	RTW_INFO("%s:iwpriv in=%s\n", __func__, input);
1571 
1572 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1573 		return -EFAULT;
1574 
1575 	bMain = strncmp(input, "1", 2); /* strncmp TRUE is 0*/
1576 	bTurnoff = strncmp(input, "0", 3); /* strncmp TRUE is 0*/
1577 
1578 	_rtw_memset(extra, 0, wrqu->length);
1579 #ifdef CONFIG_ANTENNA_DIVERSITY
1580 	if (bMain == 0)
1581 		ret = rtw_mp_set_antdiv(padapter, _TRUE);
1582 	else
1583 		ret = rtw_mp_set_antdiv(padapter, _FALSE);
1584 	if (ret == _FALSE)
1585 		RTW_INFO("%s:ANTENNA_DIVERSITY FAIL\n", __func__);
1586 #endif
1587 
1588 	if (bMain == 0) {
1589 		MP_PHY_SetRFPathSwitch(padapter, _TRUE);
1590 		RTW_INFO("%s:PHY_SetRFPathSwitch=TRUE\n", __func__);
1591 		sprintf(extra, "mp_setrfpath Main\n");
1592 
1593 	} else if (bTurnoff == 0) {
1594 		MP_PHY_SetRFPathSwitch(padapter, _FALSE);
1595 		RTW_INFO("%s:PHY_SetRFPathSwitch=FALSE\n", __func__);
1596 		sprintf(extra, "mp_setrfpath Aux\n");
1597 	} else {
1598 		bMain = MP_PHY_QueryRFPathSwitch(padapter);
1599 		RTW_INFO("%s:Query RF Path = %s\n", __func__, (bMain ? "Main":"Aux"));
1600 		sprintf(extra, "RF Path %s\n" , (bMain ? "1":"0"));
1601 	}
1602 
1603 	wrqu->length = strlen(extra);
1604 
1605 	return 0;
1606 }
1607 
1608 
rtw_mp_switch_rf_path(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1609 int rtw_mp_switch_rf_path(struct net_device *dev,
1610 			struct iw_request_info *info,
1611 			struct iw_point *wrqu, char *extra)
1612 {
1613 	PADAPTER padapter = rtw_netdev_priv(dev);
1614 	struct mp_priv *pmp_priv;
1615 	char input[RTW_IWD_MAX_LEN];
1616 	char *pch;
1617 	int		bwlg = 1, bwla = 1, btg = 1, bbt=1;
1618 	u8 ret = 0;
1619 
1620 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1621 		return -EFAULT;
1622 
1623 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1624 		return -EFAULT;
1625 
1626 	pmp_priv = &padapter->mppriv;
1627 
1628 	RTW_INFO("%s: in=%s\n", __func__, input);
1629 
1630 	_rtw_memset(extra, '\0', wrqu->length);
1631 	pch = extra;
1632 #ifdef CONFIG_RTL8821C /* only support for 8821c wlg/wla/btg/bt RF switch path */
1633 	if ((strncmp(input, "WLG", 3) == 0) || (strncmp(input, "1", 1) == 0)) {
1634 		pmp_priv->rf_path_cfg = SWITCH_TO_WLG;
1635 		pch += sprintf(pch, "switch rf path WLG\n");
1636 
1637 	} else if ((strncmp(input, "WLA", 3) == 0) || (strncmp(input, "2", 1) == 0)) {
1638 		pmp_priv->rf_path_cfg = SWITCH_TO_WLA;
1639 		pch += sprintf(pch, "switch rf path WLA\n");
1640 
1641 	} else if ((strncmp(input, "BTG", 3) == 0) || (strncmp(input, "0", 1) == 0)) {
1642 		pmp_priv->rf_path_cfg = SWITCH_TO_BTG;
1643 		pch += sprintf(pch, "switch rf path BTG\n");
1644 
1645 	} else if ((strncmp(input, "BT", 3) == 0) || (strncmp(input, "3", 1) == 0)) {
1646 		pmp_priv->rf_path_cfg = SWITCH_TO_BT;
1647 		pch += sprintf(pch, "switch rf path BT\n");
1648 	} else {
1649 		pmp_priv->rf_path_cfg = SWITCH_TO_WLG;
1650 		pch += sprintf(pch, "Error input, default set WLG\n");
1651 		return -EFAULT;
1652 	}
1653 
1654 	mp_phy_switch_rf_path_set(padapter, &pmp_priv->rf_path_cfg);
1655 #endif
1656 	wrqu->length = strlen(extra);
1657 
1658 	return ret;
1659 
1660 }
rtw_mp_QueryDrv(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1661 int rtw_mp_QueryDrv(struct net_device *dev,
1662 		    struct iw_request_info *info,
1663 		    union iwreq_data *wrqu, char *extra)
1664 {
1665 	PADAPTER padapter = rtw_netdev_priv(dev);
1666 	char input[RTW_IWD_MAX_LEN];
1667 	int	qAutoLoad = 1;
1668 
1669 	PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1670 
1671 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->data.length))
1672 		return -EFAULT;
1673 
1674 	if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
1675 		return -EFAULT;
1676 	RTW_INFO("%s:iwpriv in=%s\n", __func__, input);
1677 
1678 	qAutoLoad = strncmp(input, "autoload", 8); /* strncmp TRUE is 0*/
1679 
1680 	if (qAutoLoad == 0) {
1681 		RTW_INFO("%s:qAutoLoad\n", __func__);
1682 
1683 		if (pHalData->bautoload_fail_flag)
1684 			sprintf(extra, "fail");
1685 		else
1686 			sprintf(extra, "ok");
1687 	}
1688 	wrqu->data.length = strlen(extra) + 1;
1689 	return 0;
1690 }
1691 
1692 
rtw_mp_PwrCtlDM(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1693 int rtw_mp_PwrCtlDM(struct net_device *dev,
1694 		    struct iw_request_info *info,
1695 		    struct iw_point *wrqu, char *extra)
1696 {
1697 	PADAPTER padapter = rtw_netdev_priv(dev);
1698 	u8 input[RTW_IWD_MAX_LEN];
1699 	u8		pwrtrk_state = 0;
1700 	u8		pwtk_type[5][25] = {"Thermal tracking off","Thermal tracking on",
1701 					"TSSI tracking off","TSSI tracking on","TSSI calibration"};
1702 
1703 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1704 		return -EFAULT;
1705 
1706 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1707 		return -EFAULT;
1708 
1709 	input[wrqu->length - 1] = '\0';
1710 	RTW_INFO("%s: in=%s\n", __func__, input);
1711 
1712 	if (wrqu->length == 2) {
1713 		if(input[0] >= '0' && input[0] <= '4') {
1714 			pwrtrk_state = rtw_atoi(input);
1715 			MPT_PwrCtlDM(padapter, pwrtrk_state);
1716 			sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1717 		} else {
1718 			sprintf(extra, "Error unknown number ! Please check your input number\n"
1719 				" 0 : Thermal tracking off\n 1 : Thermal tracking on\n 2 : TSSI tracking off\n"
1720 				" 3 : TSSI tracking on\n 4 : TSSI calibration\n");
1721 		}
1722 		wrqu->length = strlen(extra);
1723 
1724 		return 0;
1725 	}
1726 	if (strncmp(input, "start", 5) == 0 || strncmp(input, "thertrk on", 10) == 0) {/* strncmp TRUE is 0*/
1727 		pwrtrk_state = 1;
1728 		sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1729 	} else if (strncmp(input, "thertrk off", 11) == 0 || strncmp(input, "stop", 5) == 0) {
1730 		pwrtrk_state = 0;
1731 		sprintf(extra, "PwrCtlDM stop %s\n" , pwtk_type[pwrtrk_state]);
1732 	} else if (strncmp(input, "tssitrk off", 11) == 0){
1733 		pwrtrk_state = 2;
1734 		sprintf(extra, "PwrCtlDM stop %s\n" , pwtk_type[pwrtrk_state]);
1735 	} else if (strncmp(input, "tssitrk on", 10) == 0){
1736 		pwrtrk_state = 3;
1737 		sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1738 	} else if (strncmp(input, "tssik", 5) == 0){
1739 		pwrtrk_state = 4;
1740 		sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1741 	} else {
1742 		sprintf(extra, "Error input !!!\n"
1743 			" thertrk off : Thermal tracking off\n thertrk on : Thermal tracking on\n"
1744 			" tssitrk off : TSSI tracking off\n tssitrk on : TSSI tracking on\n tssik : TSSI calibration\n\n"
1745 			" 0 : Thermal tracking off\n 1 : Thermal tracking on\n 2 : TSSI tracking off\n"
1746 			" 3 : TSSI tracking on\n 4 : TSSI calibration\n");
1747 		wrqu->length = strlen(extra);
1748 		return 0;
1749 	}
1750 
1751 	MPT_PwrCtlDM(padapter, pwrtrk_state);
1752 	wrqu->length = strlen(extra);
1753 
1754 	return 0;
1755 }
1756 
rtw_mp_iqk(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1757 int rtw_mp_iqk(struct net_device *dev,
1758 		 struct iw_request_info *info,
1759 		 struct iw_point *wrqu, char *extra)
1760 {
1761 	PADAPTER padapter = rtw_netdev_priv(dev);
1762 
1763 	rtw_mp_trigger_iqk(padapter);
1764 
1765 	return 0;
1766 }
1767 
rtw_mp_lck(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1768 int rtw_mp_lck(struct net_device *dev,
1769 		 struct iw_request_info *info,
1770 		 struct iw_point *wrqu, char *extra)
1771 {
1772 	PADAPTER padapter = rtw_netdev_priv(dev);
1773 
1774 	rtw_mp_trigger_lck(padapter);
1775 
1776 	return 0;
1777 }
1778 
rtw_mp_dpk(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1779 int rtw_mp_dpk(struct net_device *dev,
1780 			struct iw_request_info *info,
1781 			union iwreq_data *wrqu, char *extra)
1782 {
1783 	PADAPTER padapter = rtw_netdev_priv(dev);
1784 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
1785 	struct dm_struct		*pDM_Odm = &pHalData->odmpriv;
1786 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
1787 	char *pch;
1788 
1789 	u8 ips_mode = IPS_NUM; /* init invalid value */
1790 	u8 lps_mode = PS_MODE_NUM; /* init invalid value */
1791 
1792 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
1793 		return -EFAULT;
1794 
1795 	*(extra + wrqu->data.length) = '\0';
1796 	pch = extra;
1797 
1798 	if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
1799 			pDM_Odm->dpk_info.is_dpk_enable = 0;
1800 			halrf_dpk_enable_disable(pDM_Odm);
1801 			pch += sprintf(pch, "set dpk off\n");
1802 
1803 	} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
1804 			pDM_Odm->dpk_info.is_dpk_enable = 1;
1805 			halrf_dpk_enable_disable(pDM_Odm);
1806 			pch += sprintf(pch, "set dpk on\n");
1807 	} else	{
1808 #ifdef CONFIG_LPS
1809 			lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */
1810 			rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
1811 #endif
1812 #ifdef CONFIG_IPS
1813 			ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
1814 			rtw_pm_set_ips(padapter, IPS_NONE);
1815 #endif
1816 			rtw_mp_trigger_dpk(padapter);
1817 	if (padapter->registrypriv.mp_mode == 0) {
1818 #ifdef CONFIG_IPS
1819 			rtw_pm_set_ips(padapter, ips_mode);
1820 #endif /* CONFIG_IPS */
1821 
1822 #ifdef CONFIG_LPS
1823 			rtw_pm_set_lps(padapter, lps_mode);
1824 #endif /* CONFIG_LPS */
1825 	}
1826 			pch += sprintf(pch, "set dpk trigger\n");
1827 	}
1828 
1829 	wrqu->data.length = strlen(extra);
1830 
1831 	return 0;
1832 }
1833 
rtw_mp_get_tsside(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1834 int rtw_mp_get_tsside(struct net_device *dev,
1835 			 struct iw_request_info *info,
1836 			 struct iw_point *wrqu, char *extra)
1837 {
1838 	PADAPTER padapter = rtw_netdev_priv(dev);
1839  	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
1840 	struct dm_struct		*pDM_Odm = &pHalData->odmpriv;
1841 	char input[RTW_IWD_MAX_LEN];
1842 	u8 rfpath;
1843 	u32 tssi_de;
1844 
1845 	u8 legal_param_num = 1;
1846 	int param_num;
1847 	char pout_str_buf[7];
1848 	u8 signed_flag = 0;
1849 	int integer_num;
1850 	u32 decimal_num;
1851 	s32 pout;
1852 	char *pextra;
1853 	int i;
1854 
1855 	#ifdef CONFIG_RTL8723F
1856 	/*
1857 	* rtwpriv wlan0 mp_get_tsside rf_path pout
1858 	* rf_path : 0 ~ 1
1859 	* pout : -15.000 ~ 25.000
1860 	* ex : rtwpriv wlan0 mp_get_tsside 0 -12.123
1861 	*/
1862 	legal_param_num = 2;
1863 	#endif
1864 	if (wrqu->length > 128)
1865 		return -EFAULT;
1866 
1867 	_rtw_memset(input, 0, sizeof(input));
1868 
1869 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1870 		return -EFAULT;
1871 
1872 	param_num = sscanf(input, "%hhu %7s", &rfpath, pout_str_buf);
1873 
1874 	/* Check parameter format*/
1875 	if(param_num != legal_param_num)
1876 		goto invalid_param_format;
1877 
1878 	if(rfpath <0 || 3 < rfpath)
1879 		goto invalid_param_format;
1880 
1881 #ifdef CONFIG_RTL8723F
1882 	/* Convert pout from floating-point to integer
1883 	 * For Floating-Point Precision, pout*1000
1884 	 */
1885 	if(pout_str_buf[0] == '-')
1886 		signed_flag = 1;
1887 	i = sscanf(pout_str_buf, "%d.%3u", &integer_num, &decimal_num);
1888 	pout = integer_num * 1000;
1889 	if(i == 2) {
1890 		/* Convert decimal number
1891 		 * ex : 0.1 => 100, -0.1 => 100
1892 		 */
1893 		decimal_num = (decimal_num < 10) ? decimal_num * 100 : decimal_num;
1894 		decimal_num = (decimal_num < 100) ? decimal_num * 10 : decimal_num;
1895 		pout += ((pout < 0 || signed_flag == 1) ? -decimal_num : decimal_num);
1896 	}
1897 	if(pout < -15000 || 25000 < pout)
1898 		goto invalid_param_format;
1899 #endif
1900 
1901 #ifdef CONFIG_RTL8723F
1902 	/* For Floating-Point Precision, pout */
1903 	tssi_de = halrf_get_online_tssi_de(pDM_Odm, rfpath, pout);
1904 #else
1905 	tssi_de = halrf_tssi_get_de(pDM_Odm, rfpath);
1906 #endif
1907 
1908 	if (rfpath == 0)
1909 		sprintf(extra, "patha=%d hex=%02x", tssi_de, (u8)tssi_de);
1910 	else if (rfpath == 1)
1911 		sprintf(extra, "pathb=%d hex=%02x", tssi_de, (u8)tssi_de);
1912 	else if (rfpath == 2)
1913 		sprintf(extra, "pathc=%d hex=%02x", tssi_de, (u8)tssi_de);
1914 	else if (rfpath == 3)
1915 		sprintf(extra, "pathd=%d hex=%02x", tssi_de, (u8)tssi_de);
1916 
1917 	wrqu->length = strlen(extra);
1918 	return 0;
1919 
1920 invalid_param_format:
1921 	sprintf(extra, "Invalid command format, please indicate RF path 0/1/2/3");
1922 #ifdef CONFIG_RTL8723F
1923 	pextra = extra + strlen(extra);
1924 	sprintf(pextra, " and pout value : -15.000 ~ 25.000\n");
1925 #endif
1926 	wrqu->length = strlen(extra);
1927 
1928 	return 0;
1929 }
1930 
rtw_mp_set_tsside(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1931 int rtw_mp_set_tsside(struct net_device *dev,
1932 		   struct iw_request_info *info,
1933 		   struct iw_point *wrqu, char *extra)
1934 {
1935 	u32 tsside_a = 0, tsside_b = 0, tsside_c = 0, tsside_d = 0;
1936 	char input[RTW_IWD_MAX_LEN];
1937 
1938 	PADAPTER padapter = rtw_netdev_priv(dev);
1939 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
1940 	struct dm_struct		*pDM_Odm = &pHalData->odmpriv;
1941 
1942 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1943 		return -EFAULT;
1944 
1945 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1946 		return -EFAULT;
1947 
1948 	if (sscanf(input, "patha=%d", &tsside_a) == 1) {
1949 		sprintf(extra, "Set TSSI DE path_A: %d", tsside_a);
1950 		halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_a, RF_PATH_A);
1951 		mpt_trigger_tssi_tracking(padapter, RF_PATH_A);
1952 
1953 	} else if (sscanf(input, "pathb=%d", &tsside_b) == 1) {
1954 		sprintf(extra, "Set TSSI DE path_B: %d", tsside_b);
1955 		halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_b, RF_PATH_B);
1956 		mpt_trigger_tssi_tracking(padapter, RF_PATH_B);
1957 
1958 	} else if (sscanf(input, "pathc=%d", &tsside_c) == 1) {
1959 		sprintf(extra, "Set TSSI DE path_C: %d", tsside_c);
1960 		halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_c, RF_PATH_C);
1961 		mpt_trigger_tssi_tracking(padapter, RF_PATH_C);
1962 
1963 	} else if (sscanf(input, "pathd=%d", &tsside_d) == 1) {
1964 		sprintf(extra, "Set TSSI DE path_D: %d", tsside_d);
1965 		halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_d, RF_PATH_D);
1966 		mpt_trigger_tssi_tracking(padapter, RF_PATH_D);
1967 
1968 	} else
1969 		sprintf(extra, "Invalid command format, please input TSSI DE value within patha/b/c/d=xyz");
1970 
1971 	wrqu->length = strlen(extra);
1972 
1973 	return 0;
1974 }
1975 
rtw_mp_getver(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1976 int rtw_mp_getver(struct net_device *dev,
1977 		  struct iw_request_info *info,
1978 		  union iwreq_data *wrqu, char *extra)
1979 {
1980 	PADAPTER padapter = rtw_netdev_priv(dev);
1981 	struct mp_priv *pmp_priv;
1982 
1983 	pmp_priv = &padapter->mppriv;
1984 
1985 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
1986 		return -EFAULT;
1987 
1988 	sprintf(extra, "rtwpriv=%d\n", RTWPRIV_VER_INFO);
1989 	wrqu->data.length = strlen(extra);
1990 	return 0;
1991 }
1992 
1993 
rtw_mp_mon(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1994 int rtw_mp_mon(struct net_device *dev,
1995 	       struct iw_request_info *info,
1996 	       union iwreq_data *wrqu, char *extra)
1997 {
1998 	PADAPTER padapter = rtw_netdev_priv(dev);
1999 	struct mp_priv *pmp_priv = &padapter->mppriv;
2000 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2001 	struct hal_ops *pHalFunc = &padapter->hal_func;
2002 	NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
2003 	int bstart = 1, bstop = 1;
2004 
2005 	networkType = Ndis802_11Infrastructure;
2006 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2007 		return -EFAULT;
2008 
2009 	*(extra + wrqu->data.length) = '\0';
2010 	rtw_pm_set_ips(padapter, IPS_NONE);
2011 	LeaveAllPowerSaveMode(padapter);
2012 
2013 #ifdef CONFIG_MP_INCLUDED
2014 	if (init_mp_priv(padapter) == _FAIL)
2015 		RTW_INFO("%s: initialize MP private data Fail!\n", __func__);
2016 	padapter->mppriv.channel = 6;
2017 
2018 	bstart = strncmp(extra, "start", 5); /* strncmp TRUE is 0*/
2019 	bstop = strncmp(extra, "stop", 4); /* strncmp TRUE is 0*/
2020 	if (bstart == 0) {
2021 		mp_join(padapter, WIFI_FW_ADHOC_STATE);
2022 		SetPacketRx(padapter, _TRUE, _FALSE);
2023 		SetChannel(padapter);
2024 		pmp_priv->rx_bindicatePkt = _TRUE;
2025 		pmp_priv->bRTWSmbCfg = _TRUE;
2026 		sprintf(extra, "monitor mode start\n");
2027 	} else if (bstop == 0) {
2028 		SetPacketRx(padapter, _FALSE, _FALSE);
2029 		pmp_priv->rx_bindicatePkt = _FALSE;
2030 		pmp_priv->bRTWSmbCfg = _FALSE;
2031 		padapter->registrypriv.mp_mode = 1;
2032 		pHalFunc->hal_deinit(padapter);
2033 		padapter->registrypriv.mp_mode = 0;
2034 		pHalFunc->hal_init(padapter);
2035 		/*rtw_disassoc_cmd(padapter, 0, 0);*/
2036 		if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
2037 			rtw_disassoc_cmd(padapter, 500, 0);
2038 			rtw_indicate_disconnect(padapter, 0, _FALSE);
2039 			/*rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);*/
2040 		}
2041 		rtw_pm_set_ips(padapter, IPS_NORMAL);
2042 		sprintf(extra, "monitor mode Stop\n");
2043 	}
2044 #endif
2045 	wrqu->data.length = strlen(extra);
2046 	return 0;
2047 }
2048 
rtw_mp_pretx_proc(PADAPTER padapter,u8 bStartTest,char * extra)2049 int rtw_mp_pretx_proc(PADAPTER padapter, u8 bStartTest, char *extra)
2050 {
2051 	struct mp_priv *pmp_priv = &padapter->mppriv;
2052 	char *pextra = extra;
2053 
2054 	switch (pmp_priv->mode) {
2055 
2056 	case MP_PACKET_TX:
2057 		if (bStartTest == 0) {
2058 			pmp_priv->tx.stop = 1;
2059 			pmp_priv->mode = MP_ON;
2060 			#ifdef CONFIG_RTL8822B
2061 			rtw_write8(padapter, 0x838, 0x61);
2062 			#endif
2063 			sprintf(extra, "Stop continuous Tx");
2064 		} else if (pmp_priv->tx.stop == 1) {
2065 			pextra = extra + strlen(extra);
2066 			pextra += sprintf(pextra, "\nStart continuous DA=ffffffffffff len=1500 count=%u\n", pmp_priv->tx.count);
2067 			pmp_priv->tx.stop = 0;
2068 			#ifdef CONFIG_RTL8822B
2069 			rtw_write8(padapter, 0x838, 0x6d);
2070 			#endif
2071 			SetPacketTx(padapter);
2072 		} else
2073 			return -EFAULT;
2074 		return 0;
2075 	case MP_SINGLE_TONE_TX:
2076 		if (bStartTest != 0)
2077 			strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2078 		SetSingleToneTx(padapter, (u8)bStartTest);
2079 		break;
2080 	case MP_CONTINUOUS_TX:
2081 		if (bStartTest != 0)
2082 			strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2083 		SetContinuousTx(padapter, (u8)bStartTest);
2084 		break;
2085 	case MP_CARRIER_SUPPRISSION_TX:
2086 		if (bStartTest != 0) {
2087 			if (HwRateToMPTRate(pmp_priv->rateidx) <= MPT_RATE_11M)
2088 				strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2089 			else
2090 				strcat(extra, "\nSpecify carrier suppression but not CCK rate");
2091 		}
2092 		SetCarrierSuppressionTx(padapter, (u8)bStartTest);
2093 		break;
2094 	case MP_SINGLE_CARRIER_TX:
2095 		if (bStartTest != 0)
2096 			strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2097 		SetSingleCarrierTx(padapter, (u8)bStartTest);
2098 		break;
2099 
2100 	default:
2101 		sprintf(extra, "Error! Continuous-Tx is not on-going.");
2102 		return -EFAULT;
2103 	}
2104 
2105 	if (bStartTest == 1 && pmp_priv->mode != MP_ON) {
2106 		struct mp_priv *pmp_priv = &padapter->mppriv;
2107 
2108 		if (pmp_priv->tx.stop == 0) {
2109 			pmp_priv->tx.stop = 1;
2110 			rtw_msleep_os(5);
2111 		}
2112 #ifdef CONFIG_80211N_HT
2113 		if(padapter->registrypriv.ht_enable &&
2114 			is_supported_ht(padapter->registrypriv.wireless_mode))
2115 			pmp_priv->tx.attrib.ht_en = 1;
2116 #endif
2117 		pmp_priv->tx.stop = 0;
2118 		pmp_priv->tx.count = 1;
2119 		SetPacketTx(padapter);
2120 	} else
2121 		pmp_priv->mode = MP_ON;
2122 
2123 #if defined(CONFIG_RTL8812A)
2124 	if (IS_HARDWARE_TYPE_8812AU(padapter)) {
2125 		/* <20130425, Kordan> Turn off OFDM Rx to prevent from CCA causing Tx hang.*/
2126 		if (pmp_priv->mode == MP_PACKET_TX)
2127 			phy_set_bb_reg(padapter, rCCAonSec_Jaguar, BIT3, 1);
2128 		else
2129 			phy_set_bb_reg(padapter, rCCAonSec_Jaguar, BIT3, 0);
2130 	}
2131 #endif
2132 
2133 	return 0;
2134 }
2135 
2136 
rtw_mp_tx(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2137 int rtw_mp_tx(struct net_device *dev,
2138 	      struct iw_request_info *info,
2139 	      union iwreq_data *wrqu, char *extra)
2140 {
2141 	PADAPTER padapter = rtw_netdev_priv(dev);
2142 	HAL_DATA_TYPE	*pHalData	= GET_HAL_DATA(padapter);
2143 	struct mp_priv *pmp_priv = &padapter->mppriv;
2144 	PMPT_CONTEXT		pMptCtx = &(padapter->mppriv.mpt_ctx);
2145 	char *pextra = extra;
2146 	u32 bandwidth = 0, sg = 0, channel = 6, txpower = 40, rate = 108, ant = 0, txmode = 1, count = 0;
2147 	u8 bStartTest = 1, status = 0;
2148 #ifdef CONFIG_MP_VHT_HW_TX_MODE
2149 	u8 Idx = 0, tmpU1B;
2150 #endif
2151 	u16 antenna = 0;
2152 
2153 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2154 		return -EFAULT;
2155 	RTW_INFO("extra = %s\n", extra);
2156 #ifdef CONFIG_CONCURRENT_MODE
2157 	if (!is_primary_adapter(padapter)) {
2158 		sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n");
2159 		wrqu->data.length = strlen(extra);
2160 		return 0;
2161 	}
2162 #endif
2163 
2164 	if (strncmp(extra, "stop", 3) == 0) {
2165 		bStartTest = 0; /* To set Stop*/
2166 		pmp_priv->tx.stop = 1;
2167 		sprintf(extra, "Stop continuous Tx");
2168 		status = rtw_mp_pretx_proc(padapter, bStartTest, extra);
2169 		wrqu->data.length = strlen(extra);
2170 		return status;
2171 	} else if (strncmp(extra, "count", 5) == 0) {
2172 		if (sscanf(extra, "count=%d", &count) < 1)
2173 			RTW_INFO("Got Count=%d]\n", count);
2174 		pmp_priv->tx.count = count;
2175 		return 0;
2176 	} else if (strncmp(extra, "setting", 7) == 0) {
2177 		_rtw_memset(extra, 0, wrqu->data.length);
2178 		pextra += sprintf(pextra, "Current Setting :\n Channel:%d", pmp_priv->channel);
2179 		pextra += sprintf(pextra, "\n Bandwidth:%d", pmp_priv->bandwidth);
2180 		pextra += sprintf(pextra, "\n Rate index:%d", pmp_priv->rateidx);
2181 		pextra += sprintf(pextra, "\n TxPower index:%d", pmp_priv->txpoweridx);
2182 		pextra += sprintf(pextra, "\n Antenna TxPath:%d", pmp_priv->antenna_tx);
2183 		pextra += sprintf(pextra, "\n Antenna RxPath:%d", pmp_priv->antenna_rx);
2184 		pextra += sprintf(pextra, "\n MP Mode:%d", pmp_priv->mode);
2185 		wrqu->data.length = strlen(extra);
2186 		return 0;
2187 #ifdef CONFIG_MP_VHT_HW_TX_MODE
2188 	} else if (strncmp(extra, "pmact", 5) == 0) {
2189 		if (strncmp(extra, "pmact=", 6) == 0) {
2190 			_rtw_memset(&pMptCtx->PMacTxInfo, 0, sizeof(pMptCtx->PMacTxInfo));
2191 			if (strncmp(extra, "pmact=start", 11) == 0) {
2192 				pMptCtx->PMacTxInfo.bEnPMacTx = _TRUE;
2193 				sprintf(extra, "Set PMac Tx Mode start\n");
2194 			} else {
2195 				pMptCtx->PMacTxInfo.bEnPMacTx = _FALSE;
2196 				sprintf(extra, "Set PMac Tx Mode Stop\n");
2197 			}
2198 			if (pMptCtx->bldpc == TRUE)
2199 				pMptCtx->PMacTxInfo.bLDPC = _TRUE;
2200 
2201 			if (pMptCtx->bstbc == TRUE)
2202 				pMptCtx->PMacTxInfo.bSTBC = _TRUE;
2203 
2204 			pMptCtx->PMacTxInfo.bSPreamble = pmp_priv->preamble;
2205 			pMptCtx->PMacTxInfo.bSGI = pmp_priv->preamble;
2206 			pMptCtx->PMacTxInfo.BandWidth = pmp_priv->bandwidth;
2207 			pMptCtx->PMacTxInfo.TX_RATE = HwRateToMPTRate(pmp_priv->rateidx);
2208 
2209 			pMptCtx->PMacTxInfo.Mode = pMptCtx->HWTxmode;
2210 
2211 			pMptCtx->PMacTxInfo.NDP_sound = FALSE;/*(Adapter.PacketType == NDP_PKT)?TRUE:FALSE;*/
2212 
2213 			if (padapter->mppriv.pktInterval == 0)
2214 				pMptCtx->PMacTxInfo.PacketPeriod = 100;
2215 			else
2216 				pMptCtx->PMacTxInfo.PacketPeriod = padapter->mppriv.pktInterval;
2217 
2218 			if (padapter->mppriv.pktLength < 1000)
2219 				pMptCtx->PMacTxInfo.PacketLength = 1000;
2220 			else
2221 				pMptCtx->PMacTxInfo.PacketLength = padapter->mppriv.pktLength;
2222 
2223 			pMptCtx->PMacTxInfo.PacketPattern  = rtw_random32() % 0xFF;
2224 
2225 			if (padapter->mppriv.tx_pktcount != 0)
2226 				pMptCtx->PMacTxInfo.PacketCount = padapter->mppriv.tx_pktcount;
2227 
2228 			pMptCtx->PMacTxInfo.Ntx = 0;
2229 			for (Idx = 16; Idx < 20; Idx++) {
2230 				tmpU1B = (padapter->mppriv.antenna_tx >> Idx) & 1;
2231 				if (tmpU1B)
2232 					pMptCtx->PMacTxInfo.Ntx++;
2233 			}
2234 
2235 			_rtw_memset(pMptCtx->PMacTxInfo.MacAddress, 0xFF, ETH_ALEN);
2236 
2237 			PMAC_Get_Pkt_Param(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2238 
2239 			if (MPT_IS_CCK_RATE(pMptCtx->PMacTxInfo.TX_RATE))
2240 
2241 				CCK_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2242 			else {
2243 				PMAC_Nsym_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2244 				/* 24 BIT*/
2245 				L_SIG_generator(pMptCtx->PMacPktInfo.N_sym, &pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2246 			}
2247 			/*	48BIT*/
2248 			if (MPT_IS_HT_RATE(pMptCtx->PMacTxInfo.TX_RATE))
2249 				HT_SIG_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2250 			else if (MPT_IS_VHT_RATE(pMptCtx->PMacTxInfo.TX_RATE)) {
2251 				/*	48BIT*/
2252 				VHT_SIG_A_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2253 
2254 				/*	26/27/29 BIT  & CRC 8 BIT*/
2255 				VHT_SIG_B_generator(&pMptCtx->PMacTxInfo);
2256 
2257 				/* 32 BIT*/
2258 				VHT_Delimiter_generator(&pMptCtx->PMacTxInfo);
2259 			}
2260 
2261 			mpt_ProSetPMacTx(padapter);
2262 
2263 		} else if (strncmp(extra, "pmact,mode=", 11) == 0) {
2264 			int txmode = 0;
2265 
2266 			if (sscanf(extra, "pmact,mode=%d", &txmode) > 0) {
2267 				if (txmode == 1) {
2268 					pMptCtx->HWTxmode = CONTINUOUS_TX;
2269 					sprintf(extra, "\t Config HW Tx mode = CONTINUOUS_TX\n");
2270 				} else if (txmode == 2) {
2271 					pMptCtx->HWTxmode = OFDM_Single_Tone_TX;
2272 					sprintf(extra, "\t Config HW Tx mode = OFDM_Single_Tone_TX\n");
2273 				} else {
2274 					pMptCtx->HWTxmode = PACKETS_TX;
2275 					sprintf(extra, "\t Config HW Tx mode = PACKETS_TX\n");
2276 				}
2277 			} else {
2278 				pMptCtx->HWTxmode = PACKETS_TX;
2279 				sprintf(extra, "\t Config HW Tx mode=\n 0 = PACKETS_TX\n 1 = CONTINUOUS_TX\n 2 = OFDM_Single_Tone_TX");
2280 			}
2281 		} else if (strncmp(extra, "pmact,", 6) == 0) {
2282 			int PacketPeriod = 0, PacketLength = 0, PacketCout = 0;
2283 			int bldpc = 0, bstbc = 0;
2284 
2285 			if (sscanf(extra, "pmact,period=%d", &PacketPeriod) > 0) {
2286 				padapter->mppriv.pktInterval = PacketPeriod;
2287 				RTW_INFO("PacketPeriod=%d\n", padapter->mppriv.pktInterval);
2288 				sprintf(extra, "PacketPeriod [1~255]= %d\n", padapter->mppriv.pktInterval);
2289 
2290 			} else if (sscanf(extra, "pmact,length=%d", &PacketLength) > 0) {
2291 				padapter->mppriv.pktLength = PacketLength;
2292 				RTW_INFO("PacketPeriod=%d\n", padapter->mppriv.pktLength);
2293 				sprintf(extra, "PacketLength[~65535]=%d\n", padapter->mppriv.pktLength);
2294 
2295 			} else if (sscanf(extra, "pmact,count=%d", &PacketCout) > 0) {
2296 				padapter->mppriv.tx_pktcount = PacketCout;
2297 				RTW_INFO("Packet Cout =%d\n", padapter->mppriv.tx_pktcount);
2298 				sprintf(extra, "Packet Cout =%d\n", padapter->mppriv.tx_pktcount);
2299 
2300 			} else if (sscanf(extra, "pmact,ldpc=%d", &bldpc) > 0) {
2301 				pMptCtx->bldpc = bldpc;
2302 				RTW_INFO("Set LDPC =%d\n", pMptCtx->bldpc);
2303 				sprintf(extra, "Set LDPC =%d\n", pMptCtx->bldpc);
2304 
2305 			} else if (sscanf(extra, "pmact,stbc=%d", &bstbc) > 0) {
2306 				pMptCtx->bstbc = bstbc;
2307 				RTW_INFO("Set STBC =%d\n", pMptCtx->bstbc);
2308 				sprintf(extra, "Set STBC =%d\n", pMptCtx->bstbc);
2309 			} else
2310 				sprintf(extra, "\n period={1~255}\n length={1000~65535}\n count={0~}\n ldpc={0/1}\n stbc={0/1}");
2311 
2312 		}
2313 
2314 		wrqu->data.length = strlen(extra);
2315 		return 0;
2316 #endif
2317 	} else {
2318 
2319 		if (sscanf(extra, "ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d", &channel, &bandwidth, &rate, &txpower, &ant, &txmode) < 6) {
2320 			RTW_INFO("Invalid format [ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d]\n", channel, bandwidth, rate, txpower, ant, txmode);
2321 			_rtw_memset(extra, 0, wrqu->data.length);
2322 			pextra += sprintf(pextra, "\n Please input correct format as bleow:\n");
2323 			pextra += sprintf(pextra, "\t ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d\n", channel, bandwidth, rate, txpower, ant, txmode);
2324 			pextra += sprintf(pextra, "\n [ ch : BGN = <1~14> , A or AC = <36~165> ]");
2325 			pextra += sprintf(pextra, "\n [ bw : Bandwidth: 0 = 20M, 1 = 40M, 2 = 80M ]");
2326 			pextra += sprintf(pextra, "\n [ rate :	CCK: 1 2 5.5 11M X 2 = < 2 4 11 22 >]");
2327 			pextra += sprintf(pextra, "\n [		OFDM: 6 9 12 18 24 36 48 54M X 2 = < 12 18 24 36 48 72 96 108>");
2328 			pextra += sprintf(pextra, "\n [		HT 1S2SS MCS0 ~ MCS15 : < [MCS0]=128 ~ [MCS7]=135 ~ [MCS15]=143 >");
2329 			pextra += sprintf(pextra, "\n [		HT 3SS MCS16 ~ MCS32 : < [MCS16]=144 ~ [MCS23]=151 ~ [MCS32]=159 >");
2330 			pextra += sprintf(pextra, "\n [		VHT 1SS MCS0 ~ MCS9 : < [MCS0]=160 ~ [MCS9]=169 >");
2331 			pextra += sprintf(pextra, "\n [ txpower : 1~63 power index");
2332 			pextra += sprintf(pextra, "\n [ ant : <A = 1, B = 2, C = 4, D = 8> ,2T ex: AB=3 BC=6 CD=12");
2333 			pextra += sprintf(pextra, "\n [ txmode : < 0 = CONTINUOUS_TX, 1 = PACKET_TX, 2 = SINGLE_TONE_TX, 3 = CARRIER_SUPPRISSION_TX, 4 = SINGLE_CARRIER_TX>\n");
2334 			wrqu->data.length = strlen(extra);
2335 			return status;
2336 
2337 		} else {
2338 			char *pextra = extra;
2339 			RTW_INFO("Got format [ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d]\n", channel, bandwidth, rate, txpower, ant, txmode);
2340 			_rtw_memset(extra, 0, wrqu->data.length);
2341 			sprintf(extra, "Change Current channel %d to channel %d", padapter->mppriv.channel , channel);
2342 			padapter->mppriv.channel = channel;
2343 			SetChannel(padapter);
2344 			pHalData->current_channel = channel;
2345 
2346 			if (bandwidth == 1)
2347 				bandwidth = CHANNEL_WIDTH_40;
2348 			else if (bandwidth == 2)
2349 				bandwidth = CHANNEL_WIDTH_80;
2350 			pextra = extra + strlen(pextra);
2351 			pextra += sprintf(pextra, "\nChange Current Bandwidth %d to Bandwidth %d", padapter->mppriv.bandwidth, bandwidth);
2352 			padapter->mppriv.bandwidth = (u8)bandwidth;
2353 			padapter->mppriv.preamble = sg;
2354 			SetBandwidth(padapter);
2355 			pHalData->current_channel_bw = bandwidth;
2356 
2357 			pextra += sprintf(pextra, "\nSet power level :%d", txpower);
2358 			padapter->mppriv.txpoweridx = (u8)txpower;
2359 			pMptCtx->TxPwrLevel[RF_PATH_A] = (u8)txpower;
2360 			pMptCtx->TxPwrLevel[RF_PATH_B] = (u8)txpower;
2361 			pMptCtx->TxPwrLevel[RF_PATH_C] = (u8)txpower;
2362 			pMptCtx->TxPwrLevel[RF_PATH_D]  = (u8)txpower;
2363 			SetTxPower(padapter);
2364 
2365 			RTW_INFO("%s: bw=%d sg=%d\n", __func__, bandwidth, sg);
2366 
2367 			if (rate <= 0x7f)
2368 				rate = wifirate2_ratetbl_inx((u8)rate);
2369 			else if (rate < 0xC8)
2370 				rate = (rate - 0x80 + MPT_RATE_MCS0);
2371 			/*HT  rate 0x80(MCS0)  ~ 0x8F(MCS15) ~ 0x9F(MCS31) 128~159
2372 			VHT1SS~2SS rate 0xA0 (VHT1SS_MCS0 44) ~ 0xB3 (VHT2SS_MCS9 #63) 160~179
2373 			VHT rate 0xB4 (VHT3SS_MCS0 64) ~ 0xC7 (VHT2SS_MCS9 #83) 180~199
2374 			else
2375 			VHT rate 0x90(VHT1SS_MCS0) ~ 0x99(VHT1SS_MCS9) 144~153
2376 			rate =(rate - MPT_RATE_VHT1SS_MCS0);
2377 			*/
2378 			RTW_INFO("%s: rate index=%d\n", __func__, rate);
2379 			if (rate >= MPT_RATE_LAST)
2380 				return -EINVAL;
2381 			pextra += sprintf(pextra, "\nSet data rate to %d index %d", padapter->mppriv.rateidx, rate);
2382 
2383 			padapter->mppriv.rateidx = rate;
2384 			pMptCtx->mpt_rate_index = rate;
2385 			SetDataRate(padapter);
2386 
2387 			pextra += sprintf(pextra, "\nSet Antenna Path :%d", ant);
2388 			switch (ant) {
2389 			case 1:
2390 				antenna = ANTENNA_A;
2391 				break;
2392 			case 2:
2393 				antenna = ANTENNA_B;
2394 				break;
2395 			case 4:
2396 				antenna = ANTENNA_C;
2397 				break;
2398 			case 8:
2399 				antenna = ANTENNA_D;
2400 				break;
2401 			case 3:
2402 				antenna = ANTENNA_AB;
2403 				break;
2404 			case 5:
2405 				antenna = ANTENNA_AC;
2406 				break;
2407 			case 9:
2408 				antenna = ANTENNA_AD;
2409 				break;
2410 			case 6:
2411 				antenna = ANTENNA_BC;
2412 				break;
2413 			case 10:
2414 				antenna = ANTENNA_BD;
2415 				break;
2416 			case 12:
2417 				antenna = ANTENNA_CD;
2418 				break;
2419 			case 7:
2420 				antenna = ANTENNA_ABC;
2421 				break;
2422 			case 14:
2423 				antenna = ANTENNA_BCD;
2424 				break;
2425 			case 11:
2426 				antenna = ANTENNA_ABD;
2427 				break;
2428 			case 15:
2429 				antenna = ANTENNA_ABCD;
2430 				break;
2431 			}
2432 			RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);
2433 			padapter->mppriv.antenna_tx = antenna;
2434 			padapter->mppriv.antenna_rx = antenna;
2435 			pHalData->antenna_tx_path = antenna;
2436 			SetAntenna(padapter);
2437 
2438 			if (txmode == 0)
2439 				pmp_priv->mode = MP_CONTINUOUS_TX;
2440 			else if (txmode == 1) {
2441 				pmp_priv->mode = MP_PACKET_TX;
2442 				pmp_priv->tx.count = count;
2443 			} else if (txmode == 2)
2444 				pmp_priv->mode = MP_SINGLE_TONE_TX;
2445 			else if (txmode == 3)
2446 				pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX;
2447 			else if (txmode == 4)
2448 				pmp_priv->mode = MP_SINGLE_CARRIER_TX;
2449 
2450 			status = rtw_mp_pretx_proc(padapter, bStartTest, extra);
2451 		}
2452 
2453 	}
2454 
2455 	wrqu->data.length = strlen(extra);
2456 	return status;
2457 }
2458 
2459 
rtw_mp_rx(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2460 int rtw_mp_rx(struct net_device *dev,
2461 	      struct iw_request_info *info,
2462 	      union iwreq_data *wrqu, char *extra)
2463 {
2464 	PADAPTER padapter = rtw_netdev_priv(dev);
2465 	HAL_DATA_TYPE	*pHalData	= GET_HAL_DATA(padapter);
2466 	struct mp_priv *pmp_priv = &padapter->mppriv;
2467 	char *pextra = extra;
2468 	u32 bandwidth = 0, sg = 0, channel = 6, ant = 0;
2469 	u16 antenna = 0;
2470 	u8 bStartRx = 0;
2471 
2472 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2473 		return -EFAULT;
2474 
2475 #ifdef CONFIG_CONCURRENT_MODE
2476 	if (!is_primary_adapter(padapter)) {
2477 		sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n");
2478 		wrqu->data.length = strlen(extra);
2479 		return 0;
2480 	}
2481 #endif
2482 
2483 	if (strncmp(extra, "stop", 4) == 0) {
2484 		_rtw_memset(extra, 0, wrqu->data.length);
2485 		SetPacketRx(padapter, bStartRx, _FALSE);
2486 		pmp_priv->bmac_filter = _FALSE;
2487 		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);
2488 		wrqu->data.length = strlen(extra);
2489 		return 0;
2490 
2491 	} else if (sscanf(extra, "ch=%d,bw=%d,ant=%d", &channel, &bandwidth, &ant) < 3) {
2492 		RTW_INFO("Invalid format [ch=%d,bw=%d,ant=%d]\n", channel, bandwidth, ant);
2493 		_rtw_memset(extra, 0, wrqu->data.length);
2494 		pextra += sprintf(pextra, "\n Please input correct format as bleow:\n");
2495 		pextra += sprintf(pextra, "\t ch=%d,bw=%d,ant=%d\n", channel, bandwidth, ant);
2496 		pextra += sprintf(pextra, "\n [ ch : BGN = <1~14> , A or AC = <36~165> ]");
2497 		pextra += sprintf(pextra, "\n [ bw : Bandwidth: 0 = 20M, 1 = 40M, 2 = 80M ]");
2498 		pextra += sprintf(pextra, "\n [ ant : <A = 1, B = 2, C = 4, D = 8> ,2T ex: AB=3 BC=6 CD=12");
2499 		wrqu->data.length = strlen(extra);
2500 		return 0;
2501 
2502 	} else {
2503 		char *pextra = extra;
2504 		bStartRx = 1;
2505 		RTW_INFO("Got format [ch=%d,bw=%d,ant=%d]\n", channel, bandwidth, ant);
2506 		_rtw_memset(extra, 0, wrqu->data.length);
2507 		sprintf(extra, "Change Current channel %d to channel %d", padapter->mppriv.channel , channel);
2508 		padapter->mppriv.channel = channel;
2509 		SetChannel(padapter);
2510 		pHalData->current_channel = channel;
2511 
2512 		if (bandwidth == 1)
2513 			bandwidth = CHANNEL_WIDTH_40;
2514 		else if (bandwidth == 2)
2515 			bandwidth = CHANNEL_WIDTH_80;
2516 		pextra = extra + strlen(extra);
2517 		pextra += sprintf(pextra, "\nChange Current Bandwidth %d to Bandwidth %d", padapter->mppriv.bandwidth, bandwidth);
2518 		padapter->mppriv.bandwidth = (u8)bandwidth;
2519 		padapter->mppriv.preamble = sg;
2520 		SetBandwidth(padapter);
2521 		pHalData->current_channel_bw = bandwidth;
2522 
2523 		pextra += sprintf(pextra, "\nSet Antenna Path :%d", ant);
2524 		switch (ant) {
2525 		case 1:
2526 			antenna = ANTENNA_A;
2527 			break;
2528 		case 2:
2529 			antenna = ANTENNA_B;
2530 			break;
2531 		case 4:
2532 			antenna = ANTENNA_C;
2533 			break;
2534 		case 8:
2535 			antenna = ANTENNA_D;
2536 			break;
2537 		case 3:
2538 			antenna = ANTENNA_AB;
2539 			break;
2540 		case 5:
2541 			antenna = ANTENNA_AC;
2542 			break;
2543 		case 9:
2544 			antenna = ANTENNA_AD;
2545 			break;
2546 		case 6:
2547 			antenna = ANTENNA_BC;
2548 			break;
2549 		case 10:
2550 			antenna = ANTENNA_BD;
2551 			break;
2552 		case 12:
2553 			antenna = ANTENNA_CD;
2554 			break;
2555 		case 7:
2556 			antenna = ANTENNA_ABC;
2557 			break;
2558 		case 14:
2559 			antenna = ANTENNA_BCD;
2560 			break;
2561 		case 11:
2562 			antenna = ANTENNA_ABD;
2563 			break;
2564 		case 15:
2565 			antenna = ANTENNA_ABCD;
2566 			break;
2567 		}
2568 		RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);
2569 		padapter->mppriv.antenna_tx = antenna;
2570 		padapter->mppriv.antenna_rx = antenna;
2571 		pHalData->antenna_tx_path = antenna;
2572 		SetAntenna(padapter);
2573 
2574 		strcat(extra, "\nstart Rx");
2575 		SetPacketRx(padapter, bStartRx, _FALSE);
2576 	}
2577 	wrqu->data.length = strlen(extra);
2578 	return 0;
2579 }
2580 
2581 
rtw_mp_hwtx(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2582 int rtw_mp_hwtx(struct net_device *dev,
2583 		struct iw_request_info *info,
2584 		union iwreq_data *wrqu, char *extra)
2585 {
2586 	PADAPTER padapter = rtw_netdev_priv(dev);
2587 	struct mp_priv *pmp_priv = &padapter->mppriv;
2588 	PMPT_CONTEXT		pMptCtx = &(padapter->mppriv.mpt_ctx);
2589 	char *pch;
2590 
2591 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) \
2592 	|| defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8723F)
2593 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2594 		return -EFAULT;
2595 	*(extra + wrqu->data.length) = '\0';
2596 
2597 	_rtw_memset(&pMptCtx->PMacTxInfo, 0, sizeof(RT_PMAC_TX_INFO));
2598 	_rtw_memcpy((void *)&pMptCtx->PMacTxInfo, (void *)extra, sizeof(RT_PMAC_TX_INFO));
2599 	_rtw_memset(extra, 0, wrqu->data.length);
2600 	pch = extra;
2601 
2602 	if (pMptCtx->PMacTxInfo.bEnPMacTx == 1 && pmp_priv->mode != MP_ON) {
2603 		pch += sprintf(pch, "MP Tx Running, Please Set PMac Tx Mode Stop\n");
2604 		RTW_INFO("Error !!! MP Tx Running, Please Set PMac Tx Mode Stop\n");
2605 	} else {
2606 		RTW_INFO("To set MAC Tx mode\n");
2607 		if (mpt_ProSetPMacTx(padapter))
2608 			pch += sprintf(pch, "Set PMac Tx Mode OK\n");
2609 		else
2610 			pch += sprintf(pch, "Set PMac Tx Mode Error\n");
2611 	}
2612 	wrqu->data.length = strlen(extra);
2613 #endif
2614 	return 0;
2615 
2616 }
2617 
rtw_mp_pwrlmt(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2618 int rtw_mp_pwrlmt(struct net_device *dev,
2619 			struct iw_request_info *info,
2620 			union iwreq_data *wrqu, char *extra)
2621 {
2622 	PADAPTER padapter = rtw_netdev_priv(dev);
2623 	struct registry_priv  *registry_par = &padapter->registrypriv;
2624 	char *pch;
2625 
2626 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2627 		return -EFAULT;
2628 
2629 	*(extra + wrqu->data.length) = '\0';
2630 	pch = extra;
2631 
2632 #if CONFIG_TXPWR_LIMIT
2633 	if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
2634 		padapter->registrypriv.RegEnableTxPowerLimit = 0;
2635 		pch += sprintf(pch, "Turn off Power Limit\n");
2636 
2637 	} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
2638 		padapter->registrypriv.RegEnableTxPowerLimit = 1;
2639 		pch += sprintf(pch, "Turn on Power Limit\n");
2640 
2641 	} else
2642 #endif
2643 		pch += sprintf(pch, "Get Power Limit Status:%s\n", (registry_par->RegEnableTxPowerLimit == 1) ? "ON" : "OFF");
2644 
2645 
2646 	wrqu->data.length = strlen(extra);
2647 	return 0;
2648 }
2649 
rtw_mp_pwrbyrate(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2650 int rtw_mp_pwrbyrate(struct net_device *dev,
2651 			struct iw_request_info *info,
2652 			union iwreq_data *wrqu, char *extra)
2653 {
2654 	PADAPTER padapter = rtw_netdev_priv(dev);
2655 
2656 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2657 		return -EFAULT;
2658 
2659 	*(extra + wrqu->data.length) = '\0';
2660 	if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
2661 		padapter->registrypriv.RegEnableTxPowerByRate = 0;
2662 		sprintf(extra, "Turn off Tx Power by Rate\n");
2663 
2664 	} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
2665 		padapter->registrypriv.RegEnableTxPowerByRate = 1;
2666 		sprintf(extra, "Turn On Tx Power by Rate\n");
2667 
2668 	} else {
2669 		sprintf(extra, "Get Power by Rate Status:%s\n", (padapter->registrypriv.RegEnableTxPowerByRate == 1) ? "ON" : "OFF");
2670 	}
2671 
2672 	wrqu->data.length = strlen(extra);
2673 	return 0;
2674 }
2675 
2676 
rtw_mp_dpk_track(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2677 int rtw_mp_dpk_track(struct net_device *dev,
2678 			struct iw_request_info *info,
2679 			union iwreq_data *wrqu, char *extra)
2680 {
2681 	PADAPTER padapter = rtw_netdev_priv(dev);
2682 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
2683 	struct dm_struct		*pDM_Odm = &pHalData->odmpriv;
2684 	char *pch;
2685 
2686 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2687 		return -EFAULT;
2688 
2689 	*(extra + wrqu->data.length) = '\0';
2690 	pch = extra;
2691 
2692 	if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
2693 		halrf_set_dpk_track(pDM_Odm, FALSE);
2694 		pch += sprintf(pch, "set dpk track off\n");
2695 
2696 	} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
2697 		halrf_set_dpk_track(pDM_Odm, TRUE);
2698 		pch += sprintf(pch, "set dpk track on\n");
2699 	}
2700 
2701 	wrqu->data.length = strlen(extra);
2702 	return 0;
2703 }
2704 
2705 
rtw_bt_efuse_mask_file(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2706 int rtw_bt_efuse_mask_file(struct net_device *dev,
2707 			struct iw_request_info *info,
2708 			union iwreq_data *wrqu, char *extra)
2709 {
2710 	char *rtw_efuse_mask_file_path;
2711 	u8	*pch;
2712 	char	*ptmp, tmp;
2713 	u8 Status;
2714 	PADAPTER padapter = rtw_netdev_priv(dev);
2715 
2716 	_rtw_memset(btmaskfileBuffer, 0x00, sizeof(btmaskfileBuffer));
2717 
2718 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2719 		return -EFAULT;
2720 
2721 	*(extra + wrqu->data.length) = '\0';
2722 	ptmp = extra;
2723 
2724 	if (strncmp(extra, "data,", 5) == 0) {
2725 		u8	count = 0;
2726 		u8	i = 0;
2727 
2728 		pch = strsep(&ptmp, ",");
2729 
2730 		if ((pch == NULL) || (strlen(pch) == 0)) {
2731 			RTW_INFO("%s: parameter error(no cmd)!\n", __func__);
2732 			return -EFAULT;
2733 		}
2734 
2735 		do {
2736 			pch = strsep(&ptmp, ":");
2737 			if ((pch == NULL) || (strlen(pch) == 0))
2738 				break;
2739 			if (strlen(pch) != 2
2740 				|| IsHexDigit(*pch) == _FALSE
2741 				|| IsHexDigit(*(pch + 1)) == _FALSE
2742 				|| sscanf(pch, "%hhx", &tmp) != 1
2743 			) {
2744 				RTW_INFO("%s: invalid 8-bit hex! input format: data,01:23:45:67:89:ab:cd:ef...\n", __func__);
2745 				return -EFAULT;
2746 			}
2747 			btmaskfileBuffer[count++] = tmp;
2748 
2749 		 } while (count < 64);
2750 
2751 		_rtw_memset(extra, '\0' , strlen(extra));
2752 
2753 		for (i = 0; i < count; i++)
2754 			ptmp += sprintf(ptmp, "%02x:", btmaskfileBuffer[i]);
2755 
2756 		padapter->registrypriv.bBTFileMaskEfuse = _TRUE;
2757 
2758 		ptmp += sprintf(ptmp, "\nLoad BT Efuse Mask data %d hex ok\n", count);
2759 		wrqu->data.length = strlen(extra);
2760 		return 0;
2761 	}
2762 	rtw_efuse_mask_file_path = extra;
2763 
2764 	if (rtw_is_file_readable(rtw_efuse_mask_file_path) == _TRUE) {
2765 		RTW_INFO("%s do rtw_is_file_readable = %s! ,sizeof BT maskfileBuffer %zu\n", __func__, rtw_efuse_mask_file_path, sizeof(btmaskfileBuffer));
2766 		Status = rtw_efuse_file_read(padapter, rtw_efuse_mask_file_path, btmaskfileBuffer, sizeof(btmaskfileBuffer));
2767 		_rtw_memset(extra, '\0' , strlen(extra));
2768 		if (Status == _TRUE) {
2769 			padapter->registrypriv.bBTFileMaskEfuse = _TRUE;
2770 			ptmp += sprintf(ptmp, "BT efuse mask file read OK\n");
2771 		} else {
2772 			padapter->registrypriv.bBTFileMaskEfuse = _FALSE;
2773 			ptmp += sprintf(ptmp, "read BT efuse mask file FAIL\n");
2774 			RTW_INFO("%s rtw_efuse_file_read BT mask fail!\n", __func__);
2775 		}
2776 	} else {
2777 		padapter->registrypriv.bBTFileMaskEfuse = _FALSE;
2778 		ptmp += sprintf(ptmp, "BT efuse mask file readable FAIL\n");
2779 		RTW_INFO("%s rtw_is_file_readable BT Mask file fail!\n", __func__);
2780 	}
2781 	wrqu->data.length = strlen(extra);
2782 	return 0;
2783 }
2784 
2785 
rtw_efuse_mask_file(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2786 int rtw_efuse_mask_file(struct net_device *dev,
2787 			struct iw_request_info *info,
2788 			union iwreq_data *wrqu, char *extra)
2789 {
2790 	char *rtw_efuse_mask_file_path;
2791 	u8 Status;
2792 	PADAPTER padapter = rtw_netdev_priv(dev);
2793 
2794 	_rtw_memset(maskfileBuffer, 0x00, sizeof(maskfileBuffer));
2795 
2796 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2797 		return -EFAULT;
2798 
2799 	*(extra + wrqu->data.length) = '\0';
2800 	if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
2801 		padapter->registrypriv.boffefusemask = 1;
2802 		sprintf(extra, "Turn off Efuse Mask\n");
2803 		wrqu->data.length = strlen(extra);
2804 		return 0;
2805 	}
2806 	if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
2807 		padapter->registrypriv.boffefusemask = 0;
2808 		sprintf(extra, "Turn on Efuse Mask\n");
2809 		wrqu->data.length = strlen(extra);
2810 		return 0;
2811 	}
2812 	if (strncmp(extra, "data,", 5) == 0) {
2813 		u8	*pch;
2814 		char	*ptmp, tmp;
2815 		u8	count = 0;
2816 		u8	i = 0;
2817 
2818 		ptmp = extra;
2819 		pch = strsep(&ptmp, ",");
2820 
2821 		if ((pch == NULL) || (strlen(pch) == 0)) {
2822 			RTW_INFO("%s: parameter error(no cmd)!\n", __func__);
2823 			return -EFAULT;
2824 		}
2825 
2826 		do {
2827 			pch = strsep(&ptmp, ":");
2828 			if ((pch == NULL) || (strlen(pch) == 0))
2829 				break;
2830 			if (strlen(pch) != 2
2831 				|| IsHexDigit(*pch) == _FALSE
2832 				|| IsHexDigit(*(pch + 1)) == _FALSE
2833 				|| sscanf(pch, "%hhx", &tmp) != 1
2834 			) {
2835 				RTW_INFO("%s: invalid 8-bit hex! input format: data,01:23:45:67:89:ab:cd:ef...\n", __func__);
2836 				return -EFAULT;
2837 			}
2838 			maskfileBuffer[count++] = tmp;
2839 
2840 		} while (count < 64);
2841 
2842 		_rtw_memset(extra, '\0' , strlen(extra));
2843 
2844 		for (i = 0; i < count; i++)
2845 			ptmp += sprintf(ptmp, "%02x:", maskfileBuffer[i]);
2846 
2847 		padapter->registrypriv.bFileMaskEfuse = _TRUE;
2848 
2849 		sprintf(ptmp, "\nLoad Efuse Mask data %d hex ok\n", count);
2850 		wrqu->data.length = strlen(extra);
2851 		return 0;
2852 	}
2853 	rtw_efuse_mask_file_path = extra;
2854 
2855 	if (rtw_is_file_readable(rtw_efuse_mask_file_path) == _TRUE) {
2856 		RTW_INFO("%s do rtw_efuse_mask_file_read = %s! ,sizeof maskfileBuffer %zu\n", __func__, rtw_efuse_mask_file_path, sizeof(maskfileBuffer));
2857 		Status = rtw_efuse_file_read(padapter, rtw_efuse_mask_file_path, maskfileBuffer, sizeof(maskfileBuffer));
2858 		if (Status == _TRUE) {
2859 			padapter->registrypriv.bFileMaskEfuse = _TRUE;
2860 			sprintf(extra, "efuse mask file read OK\n");
2861 		} else {
2862 			padapter->registrypriv.bFileMaskEfuse = _FALSE;
2863 			sprintf(extra, "read efuse mask file FAIL\n");
2864 			RTW_INFO("%s rtw_efuse_file_read mask fail!\n", __func__);
2865 		}
2866 	} else {
2867 		padapter->registrypriv.bFileMaskEfuse = _FALSE;
2868 		sprintf(extra, "efuse mask file readable FAIL\n");
2869 		RTW_INFO("%s rtw_is_file_readable fail!\n", __func__);
2870 	}
2871 	wrqu->data.length = strlen(extra);
2872 	return 0;
2873 }
2874 
2875 
rtw_efuse_file_map(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2876 int rtw_efuse_file_map(struct net_device *dev,
2877 		       struct iw_request_info *info,
2878 		       union iwreq_data *wrqu, char *extra)
2879 {
2880 	char *rtw_efuse_file_map_path;
2881 	u8 Status;
2882 	PEFUSE_HAL pEfuseHal;
2883 	PADAPTER padapter = rtw_netdev_priv(dev);
2884 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
2885 	struct mp_priv *pmp_priv = &padapter->mppriv;
2886 
2887 	pEfuseHal = &pHalData->EfuseHal;
2888 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2889 		return -EFAULT;
2890 
2891 	rtw_efuse_file_map_path = extra;
2892 
2893 	_rtw_memset(pEfuseHal->fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);
2894 
2895 	if (rtw_is_file_readable(rtw_efuse_file_map_path) == _TRUE) {
2896 		RTW_INFO("%s do rtw_efuse_mask_file_read = %s!\n", __func__, rtw_efuse_file_map_path);
2897 		Status = rtw_efuse_file_read(padapter, rtw_efuse_file_map_path, pEfuseHal->fakeEfuseModifiedMap, sizeof(pEfuseHal->fakeEfuseModifiedMap));
2898 		if (Status == _TRUE) {
2899 			pmp_priv->bloadefusemap = _TRUE;
2900 			sprintf(extra, "efuse file file_read OK\n");
2901 		} else {
2902 			pmp_priv->bloadefusemap = _FALSE;
2903 			sprintf(extra, "efuse file file_read FAIL\n");
2904 		}
2905 	} else {
2906 		sprintf(extra, "efuse file readable FAIL\n");
2907 		RTW_INFO("%s rtw_is_file_readable fail!\n", __func__);
2908 	}
2909 	wrqu->data.length = strlen(extra);
2910 	return 0;
2911 }
2912 
2913 
rtw_efuse_file_map_store(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2914 int rtw_efuse_file_map_store(struct net_device *dev,
2915 				struct iw_request_info *info,
2916 				union iwreq_data *wrqu, char *extra)
2917 {
2918 	char *rtw_efuse_file_map_path;
2919 	u8 Status;
2920 	u16 mapLen;
2921 	PEFUSE_HAL pEfuseHal;
2922 	PADAPTER padapter = rtw_netdev_priv(dev);
2923 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
2924 	struct mp_priv *pmp_priv = &padapter->mppriv;
2925 
2926 	pEfuseHal = &pHalData->EfuseHal;
2927 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2928 		return -EFAULT;
2929 
2930 	rtw_efuse_file_map_path = extra;
2931 	RTW_INFO("%s rtw_is_file_readable! %s\n", __func__, rtw_efuse_file_map_path);
2932 
2933 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapLen, _FALSE);
2934 
2935 	if (mapLen != 0) {
2936 		RTW_INFO("%s, efuse store path = %s! mapLen = %d\n", __func__, rtw_efuse_file_map_path, mapLen);
2937 		Status = rtw_efuse_file_store(padapter, rtw_efuse_file_map_path, pEfuseHal->fakeEfuseModifiedMap, mapLen);
2938 		if (Status) {
2939 			sprintf(extra, "efuse file restore OK\n");
2940 		} else {
2941 			sprintf(extra, "efuse file restore FAIL\n");
2942 		}
2943 	} else {
2944 		sprintf(extra, "efuse file readable FAIL\n");
2945 		RTW_INFO("%s rtw_is_file_readable fail! map Len %d\n", __func__, mapLen);
2946 	}
2947 
2948 	wrqu->data.length = strlen(extra);
2949 	return 0;
2950 }
2951 
rtw_bt_efuse_file_map(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2952 int rtw_bt_efuse_file_map(struct net_device *dev,
2953 				struct iw_request_info *info,
2954 				union iwreq_data *wrqu, char *extra)
2955 {
2956 	char *rtw_efuse_file_map_path;
2957 	u8 Status;
2958 	PEFUSE_HAL pEfuseHal;
2959 	PADAPTER padapter = rtw_netdev_priv(dev);
2960 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
2961 	struct mp_priv *pmp_priv = &padapter->mppriv;
2962 
2963 	pEfuseHal = &pHalData->EfuseHal;
2964 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2965 		return -EFAULT;
2966 
2967 	rtw_efuse_file_map_path = extra;
2968 
2969 	_rtw_memset(pEfuseHal->fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2970 
2971 	if (rtw_is_file_readable(rtw_efuse_file_map_path) == _TRUE) {
2972 		RTW_INFO("%s do rtw_efuse_mask_file_read = %s!\n", __func__, rtw_efuse_file_map_path);
2973 		Status = rtw_efuse_file_read(padapter, rtw_efuse_file_map_path, pEfuseHal->fakeBTEfuseModifiedMap, sizeof(pEfuseHal->fakeBTEfuseModifiedMap));
2974 		if (Status == _TRUE) {
2975 			pmp_priv->bloadBTefusemap = _TRUE;
2976 			sprintf(extra, "BT efuse file file_read OK\n");
2977 		} else {
2978 			pmp_priv->bloadBTefusemap = _FALSE;
2979 			sprintf(extra, "BT efuse file file_read FAIL\n");
2980 		}
2981 	} else {
2982 		sprintf(extra, "BT efuse file readable FAIL\n");
2983 		RTW_INFO("%s rtw_is_file_readable fail!\n", __func__);
2984 	}
2985 	wrqu->data.length = strlen(extra);
2986 	return 0;
2987 }
2988 
2989 
dump_buf(u8 * buf,u32 len)2990 static inline void dump_buf(u8 *buf, u32 len)
2991 {
2992 	u32 i;
2993 
2994 	RTW_INFO("-----------------Len %d----------------\n", len);
2995 	for (i = 0; i < len; i++)
2996 		RTW_INFO("%2.2x-", *(buf + i));
2997 	RTW_INFO("\n");
2998 }
2999 
rtw_mp_link(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)3000 int rtw_mp_link(struct net_device *dev,
3001 			struct iw_request_info *info,
3002 			struct iw_point *wrqu, char *extra)
3003 {
3004 	PADAPTER padapter = rtw_netdev_priv(dev);
3005 	struct mp_priv *pmp_priv;
3006 	char input[RTW_IWD_MAX_LEN];
3007 	int		bgetrxdata = 0, btxdata = 0, bsetbt = 0;
3008 	u8 err = 0;
3009 	u32 i = 0, datalen = 0,jj, kk, waittime = 0;
3010 	u16 val = 0x00, ret = 0;
3011 	char *pextra = NULL;
3012 	u8 *setdata = NULL;
3013 	char *pch, *ptmp, *token, *tmp[4] = {0x00, 0x00, 0x00};
3014 
3015 	pmp_priv = &padapter->mppriv;
3016 
3017 	if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
3018 		return -EFAULT;
3019 
3020 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
3021 		return -EFAULT;
3022 
3023 	_rtw_memset(extra, 0, wrqu->length);
3024 
3025 	RTW_INFO("%s: in=%s\n", __func__, input);
3026 
3027 	bgetrxdata =  (strncmp(input, "rxdata", 6) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
3028 	btxdata =  (strncmp(input, "txdata", 6) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
3029 	bsetbt =  (strncmp(input, "setbt", 5) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
3030 
3031 	if (bgetrxdata) {
3032 		RTW_INFO("%s: in= 1 \n", __func__);
3033 		if (pmp_priv->mplink_brx == _TRUE) {
3034 			pch = extra;
3035 				while (waittime < 100 && pmp_priv->mplink_brx == _FALSE) {
3036 						if (pmp_priv->mplink_brx == _FALSE)
3037 							rtw_msleep_os(10);
3038 						else
3039 							break;
3040 						waittime++;
3041 				}
3042 				if (pmp_priv->mplink_brx == _TRUE) {
3043 					pch += sprintf(pch, "\n");
3044 
3045 					for (i = 0; i < pmp_priv->mplink_rx_len; i ++) {
3046 						pch += sprintf(pch, "%02x:", pmp_priv->mplink_buf[i]);
3047 					}
3048 					_rtw_memset(pmp_priv->mplink_buf, '\0' , sizeof(pmp_priv->mplink_buf));
3049 					pmp_priv->mplink_brx = _FALSE;
3050 				}
3051 		}
3052 	} else if (btxdata) {
3053 		struct pkt_attrib *pattrib;
3054 
3055 		pch = input;
3056 		setdata = rtw_zmalloc(1024);
3057 		if (setdata == NULL) {
3058 			err = -ENOMEM;
3059 			goto exit;
3060 		}
3061 
3062 		i = 0;
3063 		while ((token = strsep(&pch, ",")) != NULL) {
3064 			if (i > 2)
3065 				break;
3066 			tmp[i] = token;
3067 			i++;
3068 		}
3069 
3070 		/* tmp[0],[1],[2] */
3071 		/* txdata,00e04c871200........... */
3072 		if (strcmp(tmp[0], "txdata") == 0) {
3073 			if ((tmp[1] == NULL)) {
3074 				err = -EINVAL;
3075 				goto exit;
3076 			}
3077 		}
3078 
3079 		datalen = strlen(tmp[1]);
3080 		if (datalen % 2) {
3081 			err = -EINVAL;
3082 			goto exit;
3083 		}
3084 		datalen /= 2;
3085 		if (datalen == 0) {
3086 			err = -EINVAL;
3087 			goto exit;
3088 		}
3089 
3090 		RTW_INFO("%s: data len=%d\n", __FUNCTION__, datalen);
3091 		RTW_INFO("%s: tx data=%s\n", __FUNCTION__, tmp[1]);
3092 
3093 		for (jj = 0, kk = 0; jj < datalen; jj++, kk += 2)
3094 			setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
3095 
3096 		dump_buf(setdata, datalen);
3097 		_rtw_memset(pmp_priv->mplink_buf, '\0' , sizeof(pmp_priv->mplink_buf));
3098 		_rtw_memcpy(pmp_priv->mplink_buf, setdata, datalen);
3099 
3100 		pattrib = &pmp_priv->tx.attrib;
3101 		pattrib->pktlen = datalen;
3102 		pmp_priv->tx.count = 1;
3103 		pmp_priv->tx.stop = 0;
3104 		pmp_priv->mplink_btx = _TRUE;
3105 		SetPacketTx(padapter);
3106 		pmp_priv->mode = MP_PACKET_TX;
3107 
3108 	} else if (bsetbt) {
3109 
3110 #ifdef CONFIG_BT_COEXIST
3111 		pch = input;
3112 		i = 0;
3113 
3114 		while ((token = strsep(&pch, ",")) != NULL) {
3115 			if (i > 3)
3116 				break;
3117 			tmp[i] = token;
3118 			i++;
3119 		}
3120 
3121 		if (tmp[1] == NULL) {
3122 			err = -EINVAL;
3123 			goto exit;
3124 		}
3125 
3126 		if (strcmp(tmp[1], "scbd") == 0) {
3127 			u16 org_val = 0x8002, pre_val, read_score_board_val;
3128 			u8 state;
3129 
3130 			pre_val = (rtw_read16(padapter,(0xaa))) & 0x7fff;
3131 
3132 			if (tmp[2] != NULL) {
3133 				state = simple_strtoul(tmp[2], &ptmp, 10);
3134 
3135 				if (state)
3136 						org_val = org_val | BIT6;
3137 				else
3138 						org_val = org_val & (~BIT6);
3139 
3140 				if (org_val != pre_val) {
3141 					pre_val = org_val;
3142 					rtw_write16(padapter, 0xaa, org_val);
3143 					RTW_INFO("%s,setbt scbd write org_val = 0x%x , pre_val = 0x%x\n", __func__, org_val, pre_val);
3144 				} else {
3145 					RTW_INFO("%s,setbt scbd org_val = 0x%x ,pre_val = 0x%x\n", __func__, org_val, pre_val);
3146 				}
3147 			} else {
3148 					read_score_board_val = (rtw_read16(padapter,(0xaa))) & 0x7fff;
3149 					RTW_INFO("%s,read_score_board_val = 0x%x\n", __func__, read_score_board_val);
3150 			}
3151 			goto exit;
3152 
3153 		} else if (strcmp(tmp[1], "testmode") == 0) {
3154 
3155 			if (tmp[2] == NULL) {
3156 				err = -EINVAL;
3157 				goto exit;
3158 			}
3159 
3160 			val = simple_strtoul(tmp[2], &ptmp, 16);
3161 			RTW_INFO("get tmp, type  %s, val =0x%x!\n", tmp[1], val);
3162 
3163 			if (tmp[2] != NULL) {
3164 				_rtw_memset(extra, 0, wrqu->length);
3165 				pch = extra;
3166 				ret = rtw_btcoex_btset_testmode(padapter, val);
3167 				if (!CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(ret, BT_STATUS_BT_OP_SUCCESS)) {
3168 					RTW_INFO("%s: BT_OP fail = 0x%x!\n", __FUNCTION__, val);
3169 					pch += sprintf(pch, "BT_OP fail  0x%x!\n", val);
3170 				} else
3171 					pch += sprintf(pch, "Set BT_OP 0x%x done!\n", val);
3172 			}
3173 
3174 		}
3175 #endif /* CONFIG_BT_COEXIST */
3176 	}
3177 
3178 exit:
3179 	if (setdata)
3180 		rtw_mfree(setdata, 1024);
3181 
3182 	wrqu->length = strlen(extra);
3183 	return err;
3184 
3185 }
3186 
3187 #if defined(CONFIG_RTL8723B)
rtw_mp_SetBT(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3188 int rtw_mp_SetBT(struct net_device *dev,
3189 		 struct iw_request_info *info,
3190 		 union iwreq_data *wrqu, char *extra)
3191 {
3192 	PADAPTER padapter = rtw_netdev_priv(dev);
3193 	struct hal_ops *pHalFunc = &padapter->hal_func;
3194 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
3195 
3196 	BT_REQ_CMD	BtReq;
3197 	PMPT_CONTEXT	pMptCtx = &(padapter->mppriv.mpt_ctx);
3198 	PBT_RSP_CMD	pBtRsp = (PBT_RSP_CMD)&pMptCtx->mptOutBuf[0];
3199 	char	input[128];
3200 	char *pch, *ptmp, *token, *tmp[2] = {0x00, 0x00};
3201 	u8 setdata[100];
3202 	u8 resetbt = 0x00;
3203 	u8 tempval, BTStatus;
3204 	u8 H2cSetbtmac[6];
3205 	u8 u1H2CBtMpOperParm[4] = {0x01};
3206 	int testmode = 1, ready = 1, trxparam = 1, setgen = 1, getgen = 1, testctrl = 1, testbt = 1, readtherm = 1, setbtmac = 1;
3207 	u32 i = 0, ii = 0, jj = 0, kk = 0, cnts = 0, status = 0;
3208 	PRT_MP_FIRMWARE pBTFirmware = NULL;
3209 
3210 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
3211 		return -EFAULT;
3212 
3213 	*(extra + wrqu->data.length) = '\0';
3214 	pch = extra;
3215 
3216 	if (strlen(extra) < 1)
3217 		return -EFAULT;
3218 
3219 	RTW_INFO("%s:iwpriv in=%s\n", __func__, extra);
3220 	ready = strncmp(extra, "ready", 5);
3221 	testmode = strncmp(extra, "testmode", 8); /* strncmp TRUE is 0*/
3222 	trxparam = strncmp(extra, "trxparam", 8);
3223 	setgen = strncmp(extra, "setgen", 6);
3224 	getgen = strncmp(extra, "getgen", 6);
3225 	testctrl = strncmp(extra, "testctrl", 8);
3226 	testbt = strncmp(extra, "testbt", 6);
3227 	readtherm = strncmp(extra, "readtherm", 9);
3228 	setbtmac = strncmp(extra, "setbtmac", 8);
3229 
3230 	if (strncmp(extra, "dlbt", 4) == 0) {
3231 		pHalData->LastHMEBoxNum = 0;
3232 		pHalData->bBTFWReady = _FALSE;
3233 		rtw_write8(padapter, 0xa3, 0x05);
3234 		BTStatus = rtw_read8(padapter, 0xa0);
3235 		RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __func__, BTStatus);
3236 		if (BTStatus != 0x04) {
3237 			pch += sprintf(pch, "BT Status not Active DLFW FAIL\n");
3238 			goto exit;
3239 		}
3240 
3241 		tempval = rtw_read8(padapter, 0x6B);
3242 		tempval |= BIT7;
3243 		rtw_write8(padapter, 0x6B, tempval);
3244 
3245 		/* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay*/
3246 		/* So don't write 0x6A[14]=1 and 0x6A[15]=0 together!*/
3247 		rtw_usleep_os(100);
3248 		/* disable BT power cut*/
3249 		/* 0x6A[14] = 0*/
3250 		tempval = rtw_read8(padapter, 0x6B);
3251 		tempval &= ~BIT6;
3252 		rtw_write8(padapter, 0x6B, tempval);
3253 		rtw_usleep_os(100);
3254 		MPT_PwrCtlDM(padapter, 0);
3255 		rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004));
3256 		rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF));
3257 		rtw_msleep_os(600);
3258 		rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010));
3259 		rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB));
3260 		rtw_msleep_os(1200);
3261 		pBTFirmware = (PRT_MP_FIRMWARE)rtw_zmalloc(sizeof(RT_MP_FIRMWARE));
3262 		if (pBTFirmware == NULL)
3263 			goto exit;
3264 		pHalData->bBTFWReady = _FALSE;
3265 		FirmwareDownloadBT(padapter, pBTFirmware);
3266 		if (pBTFirmware)
3267 			rtw_mfree((u8 *)pBTFirmware, sizeof(RT_MP_FIRMWARE));
3268 
3269 		RTW_INFO("Wait for FirmwareDownloadBT fw boot!\n");
3270 		rtw_msleep_os(2000);
3271 		_rtw_memset(extra, '\0', wrqu->data.length);
3272 		BtReq.opCodeVer = 1;
3273 		BtReq.OpCode = 0;
3274 		BtReq.paraLength = 0;
3275 		mptbt_BtControlProcess(padapter, &BtReq);
3276 		rtw_msleep_os(100);
3277 
3278 		RTW_INFO("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4], pMptCtx->mptOutBuf[5]);
3279 		if ((pMptCtx->mptOutBuf[4] == 0x00) && (pMptCtx->mptOutBuf[5] == 0x00)) {
3280 
3281 			if (padapter->mppriv.bTxBufCkFail == _TRUE)
3282 				pch += sprintf(pch, "check TxBuf Fail.\n");
3283 			else
3284 				pch += sprintf(pch, "download FW Fail.\n");
3285 		} else {
3286 			pch += sprintf(pch, "download FW OK.\n");
3287 			goto exit;
3288 		}
3289 		goto exit;
3290 	}
3291 	if (strncmp(extra, "dlfw", 4) == 0) {
3292 		pHalData->LastHMEBoxNum = 0;
3293 		pHalData->bBTFWReady = _FALSE;
3294 		rtw_write8(padapter, 0xa3, 0x05);
3295 		BTStatus = rtw_read8(padapter, 0xa0);
3296 		RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __func__, BTStatus);
3297 		if (BTStatus != 0x04) {
3298 			pch += sprintf(pch, "BT Status not Active DLFW FAIL\n");
3299 			goto exit;
3300 		}
3301 
3302 		tempval = rtw_read8(padapter, 0x6B);
3303 		tempval |= BIT7;
3304 		rtw_write8(padapter, 0x6B, tempval);
3305 
3306 		/* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay*/
3307 		/* So don't write 0x6A[14]=1 and 0x6A[15]=0 together!*/
3308 		rtw_usleep_os(100);
3309 		/* disable BT power cut*/
3310 		/* 0x6A[14] = 0*/
3311 		tempval = rtw_read8(padapter, 0x6B);
3312 		tempval &= ~BIT6;
3313 		rtw_write8(padapter, 0x6B, tempval);
3314 		rtw_usleep_os(100);
3315 
3316 		MPT_PwrCtlDM(padapter, 0);
3317 		rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004));
3318 		rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF));
3319 		rtw_msleep_os(600);
3320 		rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010));
3321 		rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB));
3322 		rtw_msleep_os(1200);
3323 
3324 #if defined(CONFIG_PLATFORM_SPRD) && (MP_DRIVER == 1)
3325 		/* Pull up BT reset pin.*/
3326 		RTW_INFO("%s: pull up BT reset pin when bt start mp test\n", __func__);
3327 		rtw_wifi_gpio_wlan_ctrl(WLAN_BT_PWDN_ON);
3328 #endif
3329 		RTW_INFO(" FirmwareDownload!\n");
3330 
3331 #if defined(CONFIG_RTL8723B)
3332 		status = rtl8723b_FirmwareDownload(padapter, _FALSE);
3333 #endif
3334 		RTW_INFO("Wait for FirmwareDownloadBT fw boot!\n");
3335 		rtw_msleep_os(1000);
3336 #ifdef CONFIG_BT_COEXIST
3337 		rtw_btcoex_HaltNotify(padapter);
3338 		RTW_INFO("SetBT btcoex HaltNotify !\n");
3339 		/*hal_btcoex1ant_SetAntPath(padapter);*/
3340 		rtw_btcoex_SetManualControl(padapter, _TRUE);
3341 #endif
3342 		_rtw_memset(extra, '\0', wrqu->data.length);
3343 		BtReq.opCodeVer = 1;
3344 		BtReq.OpCode = 0;
3345 		BtReq.paraLength = 0;
3346 		mptbt_BtControlProcess(padapter, &BtReq);
3347 		rtw_msleep_os(200);
3348 
3349 		RTW_INFO("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4], pMptCtx->mptOutBuf[5]);
3350 		if ((pMptCtx->mptOutBuf[4] == 0x00) && (pMptCtx->mptOutBuf[5] == 0x00)) {
3351 			if (padapter->mppriv.bTxBufCkFail == _TRUE)
3352 				pch += sprintf(pch, "check TxBuf Fail.\n");
3353 			else
3354 				pch += sprintf(pch, "download FW Fail.\n");
3355 		} else {
3356 #ifdef CONFIG_BT_COEXIST
3357 			rtw_btcoex_SwitchBtTRxMask(padapter);
3358 #endif
3359 			rtw_msleep_os(200);
3360 			pch += sprintf(pch, "download FW OK.\n");
3361 			goto exit;
3362 		}
3363 		goto exit;
3364 	}
3365 
3366 	if (strncmp(extra, "down", 4) == 0) {
3367 		RTW_INFO("SetBT down for to hal_init !\n");
3368 #ifdef CONFIG_BT_COEXIST
3369 		rtw_btcoex_SetManualControl(padapter, _FALSE);
3370 		rtw_btcoex_Initialize(padapter);
3371 #endif
3372 		pHalFunc->read_adapter_info(padapter);
3373 		pHalFunc->hal_deinit(padapter);
3374 		pHalFunc->hal_init(padapter);
3375 		rtw_pm_set_ips(padapter, IPS_NONE);
3376 		LeaveAllPowerSaveMode(padapter);
3377 		MPT_PwrCtlDM(padapter, 0);
3378 		rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004));
3379 		rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF));
3380 		rtw_msleep_os(600);
3381 		/*rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFE));*/
3382 		rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010));
3383 		rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB));
3384 		rtw_msleep_os(1200);
3385 		goto exit;
3386 	}
3387 	if (strncmp(extra, "disable", 7) == 0) {
3388 		RTW_INFO("SetBT disable !\n");
3389 		rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a) & 0xFFFFFFFB));
3390 		rtw_msleep_os(500);
3391 		goto exit;
3392 	}
3393 	if (strncmp(extra, "enable", 6) == 0) {
3394 		RTW_INFO("SetBT enable !\n");
3395 		rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a) | 0x00000004));
3396 		rtw_msleep_os(500);
3397 		goto exit;
3398 	}
3399 	if (strncmp(extra, "h2c", 3) == 0) {
3400 		RTW_INFO("SetBT h2c !\n");
3401 		pHalData->bBTFWReady = _TRUE;
3402 		rtw_hal_fill_h2c_cmd(padapter, 0x63, 1, u1H2CBtMpOperParm);
3403 		goto exit;
3404 	}
3405 	if (strncmp(extra, "2ant", 4) == 0) {
3406 		RTW_INFO("Set BT 2ant use!\n");
3407 		phy_set_mac_reg(padapter, 0x67, BIT5, 0x1);
3408 		rtw_write32(padapter, 0x948, 0000);
3409 
3410 		goto exit;
3411 	}
3412 
3413 	if (ready != 0 && testmode != 0 && trxparam != 0 && setgen != 0 && getgen != 0 && testctrl != 0 && testbt != 0 && readtherm != 0 && setbtmac != 0)
3414 		return -EFAULT;
3415 
3416 	if (testbt == 0) {
3417 		BtReq.opCodeVer = 1;
3418 		BtReq.OpCode = 6;
3419 		BtReq.paraLength = cnts / 2;
3420 		goto todo;
3421 	}
3422 	if (ready == 0) {
3423 		BtReq.opCodeVer = 1;
3424 		BtReq.OpCode = 0;
3425 		BtReq.paraLength = 0;
3426 		goto todo;
3427 	}
3428 
3429 	i = 0;
3430 	while ((token = strsep(&pch, ",")) != NULL) {
3431 		if (i > 1)
3432 			break;
3433 		tmp[i] = token;
3434 		i++;
3435 	}
3436 
3437 	if ((tmp[0] != NULL) && (tmp[1] != NULL)) {
3438 		cnts = strlen(tmp[1]);
3439 		if (cnts < 1)
3440 			return -EFAULT;
3441 
3442 		RTW_INFO("%s: cnts=%d\n", __func__, cnts);
3443 		RTW_INFO("%s: data=%s\n", __func__, tmp[1]);
3444 
3445 		for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) {
3446 			BtReq.pParamStart[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
3447 			/*			RTW_INFO("BtReq.pParamStart[%d]=0x%02x\n", jj, BtReq.pParamStart[jj]);*/
3448 		}
3449 	} else
3450 		return -EFAULT;
3451 
3452 	if (testmode == 0) {
3453 		BtReq.opCodeVer = 1;
3454 		BtReq.OpCode = 1;
3455 		BtReq.paraLength = 1;
3456 	}
3457 	if (trxparam == 0) {
3458 		BtReq.opCodeVer = 1;
3459 		BtReq.OpCode = 2;
3460 		BtReq.paraLength = cnts / 2;
3461 	}
3462 	if (setgen == 0) {
3463 		RTW_INFO("%s: BT_SET_GENERAL\n", __func__);
3464 		BtReq.opCodeVer = 1;
3465 		BtReq.OpCode = 3;/*BT_SET_GENERAL	3*/
3466 		BtReq.paraLength = cnts / 2;
3467 	}
3468 	if (getgen == 0) {
3469 		RTW_INFO("%s: BT_GET_GENERAL\n", __func__);
3470 		BtReq.opCodeVer = 1;
3471 		BtReq.OpCode = 4;/*BT_GET_GENERAL	4*/
3472 		BtReq.paraLength = cnts / 2;
3473 	}
3474 	if (readtherm == 0) {
3475 		RTW_INFO("%s: BT_GET_GENERAL\n", __func__);
3476 		BtReq.opCodeVer = 1;
3477 		BtReq.OpCode = 4;/*BT_GET_GENERAL	4*/
3478 		BtReq.paraLength = cnts / 2;
3479 	}
3480 
3481 	if (testctrl == 0) {
3482 		RTW_INFO("%s: BT_TEST_CTRL\n", __func__);
3483 		BtReq.opCodeVer = 1;
3484 		BtReq.OpCode = 5;/*BT_TEST_CTRL	5*/
3485 		BtReq.paraLength = cnts / 2;
3486 	}
3487 
3488 	RTW_INFO("%s: Req opCodeVer=%d OpCode=%d paraLength=%d\n",
3489 		 __func__, BtReq.opCodeVer, BtReq.OpCode, BtReq.paraLength);
3490 
3491 	if (BtReq.paraLength < 1)
3492 		goto todo;
3493 	for (i = 0; i < BtReq.paraLength; i++) {
3494 		RTW_INFO("%s: BtReq.pParamStart[%d] = 0x%02x\n",
3495 			 __func__, i, BtReq.pParamStart[i]);
3496 	}
3497 
3498 todo:
3499 	_rtw_memset(extra, '\0', wrqu->data.length);
3500 
3501 	if (pHalData->bBTFWReady == _FALSE) {
3502 		pch += sprintf(pch, "BTFWReady = FALSE.\n");
3503 		goto exit;
3504 	}
3505 
3506 	mptbt_BtControlProcess(padapter, &BtReq);
3507 
3508 	if (readtherm == 0) {
3509 		pch += sprintf(pch, "BT thermal=");
3510 		for (i = 4; i < pMptCtx->mptOutLen; i++) {
3511 			if ((pMptCtx->mptOutBuf[i] == 0x00) && (pMptCtx->mptOutBuf[i + 1] == 0x00))
3512 				goto exit;
3513 
3514 			pch += sprintf(pch, " %d ", (pMptCtx->mptOutBuf[i] & 0x1f));
3515 		}
3516 	} else {
3517 		for (i = 4; i < pMptCtx->mptOutLen; i++)
3518 			pch += sprintf(pch, " 0x%x ", pMptCtx->mptOutBuf[i]);
3519 	}
3520 
3521 exit:
3522 	wrqu->data.length = strlen(extra) + 1;
3523 	RTW_INFO("-%s: output len=%d data=%s\n", __func__, wrqu->data.length, extra);
3524 
3525 	return status;
3526 }
3527 
3528 #endif /*#ifdef CONFIG_RTL8723B*/
3529 
3530 #endif
3531