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