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