xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852be/os_dep/linux/ioctl_mp.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2019 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 
20 #define RTW_IWD_MAX_LEN	128
21 
22 /*
23  * Input Format: %s,%d,%d
24  *	%s is width, could be
25  *		"b" for 1 byte
26  *		"w" for WORD (2 bytes)
27  *		"dw" for DWORD (4 bytes)
28  *	1st %d is address(offset)
29  *	2st %d is data to write
30  */
31 
rtw_mp_write_reg(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)32 int rtw_mp_write_reg(struct net_device *dev,
33 		     struct iw_request_info *info,
34 		     struct iw_point *wrqu, char *extra)
35 {
36 	char *pch, *pnext;
37 	char *width_str;
38 	char width;
39 	u32 addr, data;
40 	int ret;
41 	_adapter *padapter = rtw_netdev_priv(dev);
42 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
43 	char input[RTW_IWD_MAX_LEN];
44 	struct rtw_mp_reg_arg	reg_arg;
45 
46 	_rtw_memset(input, 0, sizeof(input));
47 
48 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
49 		return -EFAULT;
50 
51 	input[wrqu->length] = '\0';
52 
53 	_rtw_memset(extra, 0, wrqu->length);
54 
55 	pch = input;
56 
57 	pnext = strpbrk(pch, " ,.-");
58 	if (pnext == NULL)
59 		return -EINVAL;
60 	*pnext = 0;
61 	width_str = pch;
62 
63 	pch = pnext + 1;
64 	pnext = strpbrk(pch, " ,.-");
65 	if (pnext == NULL)
66 		return -EINVAL;
67 	*pnext = 0;
68 
69 	ret = sscanf(pch, "%x", &addr);
70 
71 	pch = pnext + 1;
72 	pnext = strpbrk(pch, " ,.-");
73 	if ((pch - input) >= wrqu->length)
74 		return -EINVAL;
75 
76 	ret = sscanf(pch, "%x", &data);
77 	RTW_INFO("data=%x,addr=%x\n", (u32)data, (u32)addr);
78 	ret = 0;
79 	width = width_str[0];
80 	switch (width) {
81 	case 'b':
82 		/* 1 byte*/
83 		if (data > 0xFF) {
84 			ret = -EINVAL;
85 			break;
86 		}
87 		reg_arg.io_offset = addr;
88 		reg_arg.io_type = 1;
89 		reg_arg.io_value = (u8)data;
90 
91 		if (rtw_mp_phl_reg(padapter, &reg_arg, RTW_MP_REG_CMD_WRITE_BB))
92 			RTW_INFO("write data=%x,addr=%x OK\n", (u8)data, addr);
93 		else
94 			RTW_INFO("write data=%x,addr=%x fail\n", (u8)data, addr);
95 		break;
96 	case 'w':
97 		/* 2 bytes*/
98 		if (data > 0xFFFF) {
99 			ret = -EINVAL;
100 			break;
101 		}
102 		reg_arg.io_offset = addr;
103 		reg_arg.io_type = 2;
104 		reg_arg.io_value = (u16)data;
105 
106 		if (rtw_mp_phl_reg(padapter, &reg_arg, RTW_MP_REG_CMD_WRITE_BB))
107 			RTW_INFO("write data=%x,addr=%x OK\n", (u16)data, addr);
108 		else
109 			RTW_INFO("write data=%x,addr=%x fail\n", (u16)data, addr);
110 		break;
111 	case 'd':
112 		/* 4 bytes*/
113 		reg_arg.io_offset = addr;
114 		reg_arg.io_type = 4;
115 		reg_arg.io_value = data;
116 
117 		if (rtw_mp_phl_reg(padapter, &reg_arg, RTW_MP_REG_CMD_WRITE_BB))
118 			RTW_INFO("write data=%x,addr=%x OK\n", data, addr);
119 		else
120 			RTW_INFO("write data=%x,addr=%x fail\n", data, addr);
121 		break;
122 	default:
123 		ret = -EINVAL;
124 		break;
125 	}
126 
127 	return ret;
128 }
129 
130 
131 /*
132  * Input Format: %s,%d
133  *	%s is width, could be
134  *		"b" for 1 byte
135  *		"w" for WORD (2 bytes)
136  *		"dw" for DWORD (4 bytes)
137  *	%d is address(offset)
138  *
139  * Return:
140  *	%d for data readed
141  */
rtw_mp_read_reg(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)142 int rtw_mp_read_reg(struct net_device *dev,
143 		    struct iw_request_info *info,
144 		    struct iw_point *wrqu, char *extra)
145 {
146 	char input[RTW_IWD_MAX_LEN];
147 	char *pch, *pnext;
148 	char *width_str;
149 	char width;
150 	char data[20], tmp[20];
151 	u32 addr = 0, strtout = 0;
152 	u32 i = 0, j = 0, ret = 0, data32 = 0;
153 	_adapter *padapter = rtw_netdev_priv(dev);
154 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
155 	struct rtw_mp_reg_arg	reg_arg;
156 
157 	char *pextra = extra;
158 
159 	if (wrqu->length > 128)
160 		return -EFAULT;
161 
162 	_rtw_memset(input, 0, sizeof(input));
163 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
164 		return -EFAULT;
165 
166 	input[wrqu->length] = '\0';
167 	_rtw_memset(extra, 0, wrqu->length);
168 	_rtw_memset(data, '\0', sizeof(data));
169 	_rtw_memset(tmp, '\0', sizeof(tmp));
170 	pch = input;
171 	pnext = strpbrk(pch, " ,.-");
172 	if (pnext == NULL)
173 		return -EINVAL;
174 	*pnext = 0;
175 	width_str = pch;
176 
177 	pch = pnext + 1;
178 
179 	ret = sscanf(pch, "%x", &addr);
180 
181 	ret = 0;
182 	width = width_str[0];
183 
184 	switch (width) {
185 	case 'b':
186 		reg_arg.io_offset = addr;
187 		reg_arg.io_type = 1;
188 
189 		if (rtw_mp_phl_reg(padapter, &reg_arg, RTW_MP_REG_CMD_READ_BB)) {
190 			data32 = reg_arg.io_value; //rtw_phl_read8(dvobj->phl, addr);
191 			RTW_INFO("reg=%x\n", data32);
192 			sprintf(extra, "%d", data32);
193 		} else
194 			sprintf(extra, "reg io fail\n");
195 
196 		wrqu->length = strlen(extra);
197 		break;
198 	case 'w':
199 		/* 2 bytes*/
200 		reg_arg.io_offset = addr;
201 		reg_arg.io_type = 2;
202 
203 		if (rtw_mp_phl_reg(padapter, &reg_arg, RTW_MP_REG_CMD_READ_BB)) {
204 			sprintf(data, "%04x", reg_arg.io_value);
205 			RTW_INFO("reg=%s\n", data);
206 		} else
207 			sprintf(extra, "reg io fail\n");
208 
209 		for (i = 0 ; i <= strlen(data) ; i++) {
210 			if (i % 2 == 0) {
211 				tmp[j] = ' ';
212 				j++;
213 			}
214 			if (data[i] != '\0')
215 				tmp[j] = data[i];
216 
217 			j++;
218 		}
219 		tmp[j]='\0';
220 
221 		pch = tmp;
222 		RTW_INFO("pch=%s", pch);
223 
224 		while (*pch != '\0') {
225 			pnext = strpbrk(pch, " ");
226 			if (!pnext || ((pnext - tmp) > 4))
227 				break;
228 
229 			pnext++;
230 			if (*pnext != '\0') {
231 				/*strtout = simple_strtoul(pnext , &ptmp, 16);*/
232 				ret = sscanf(pnext, "%x", &strtout);
233 				pextra += sprintf(pextra, " %d", strtout);
234 			} else
235 				break;
236 			pch = pnext;
237 		}
238 		wrqu->length = strlen(extra);
239 		break;
240 	case 'd':
241 		/* 4 bytes */
242 		reg_arg.io_offset = addr;
243 		reg_arg.io_type = 4;
244 
245 		if (rtw_mp_phl_reg(padapter, &reg_arg, RTW_MP_REG_CMD_READ_BB)) {
246 			sprintf(data, "%08x", reg_arg.io_value);
247 			RTW_INFO("reg=%s\n", data);
248 		} else
249 			sprintf(extra, "reg io fail\n");
250 
251 		/*add read data format blank*/
252 		for (i = 0 ; i <= strlen(data) ; i++) {
253 			if (i % 2 == 0) {
254 				tmp[j] = ' ';
255 				j++;
256 			}
257 			if (data[i] != '\0')
258 				tmp[j] = data[i];
259 
260 			j++;
261 		}
262 
263 		pch = tmp;
264 		RTW_INFO("pch=%s", pch);
265 
266 		while (*pch != '\0') {
267 			pnext = strpbrk(pch, " ");
268 			if (!pnext)
269 				break;
270 
271 			pnext++;
272 			if (*pnext != '\0') {
273 				ret = sscanf(pnext, "%x", &strtout);
274 				pextra += sprintf(pextra, " %d", strtout);
275 			} else
276 				break;
277 			pch = pnext;
278 		}
279 		wrqu->length = strlen(extra);
280 		break;
281 
282 	default:
283 		wrqu->length = 0;
284 		ret = -EINVAL;
285 		break;
286 	}
287 
288 	return ret;
289 }
290 
291 
292 /*
293  * Input Format: %d,%x,%x
294  *	%d is RF path, should be smaller than MAX_RF_PATH_NUMS
295  *	1st %x is address(offset)
296  *	2st %x is data to write
297  */
rtw_mp_write_rf(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)298 int rtw_mp_write_rf(struct net_device *dev,
299 		    struct iw_request_info *info,
300 		    struct iw_point *wrqu, char *extra)
301 {
302 
303 	u32 path, addr, data;
304 	int ret;
305 	_adapter *padapter = rtw_netdev_priv(dev);
306 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
307 	char input[RTW_IWD_MAX_LEN];
308 
309 
310 	_rtw_memset(input, 0, wrqu->length);
311 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
312 		return -EFAULT;
313 
314 
315 	ret = sscanf(input, "%d,%x,%x", &path, &addr, &data);
316 	if (ret < 3)
317 		return -EINVAL;
318 
319 	if (path >= GET_HAL_RFPATH_NUM(adapter_to_dvobj(padapter)))
320 		return -EINVAL;
321 	if (addr > 0xFF)
322 		return -EINVAL;
323 	if (data > 0xFFFFF)
324 		return -EINVAL;
325 
326 	_rtw_memset(extra, 0, wrqu->length);
327 
328 	rtw_phl_write_rfreg(GET_PHL_INFO(dvobj), path, addr, 0xFFFFF, data);
329 
330 	sprintf(extra, "write_rf completed\n");
331 	wrqu->length = strlen(extra);
332 
333 	return 0;
334 }
335 
336 
337 /*
338  * Input Format: %d,%x
339  *	%d is RF path, should be smaller than MAX_RF_PATH_NUMS
340  *	%x is address(offset)
341  *
342  * Return:
343  *	%d for data readed
344  */
rtw_mp_read_rf(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)345 int rtw_mp_read_rf(struct net_device *dev,
346 		   struct iw_request_info *info,
347 		   struct iw_point *wrqu, char *extra)
348 {
349 	char input[RTW_IWD_MAX_LEN];
350 	char *pch, *pnext;
351 	char data[20], tmp[20];
352 	u32 path, addr, strtou;
353 	u32 ret, i = 0 , j = 0;
354 	_adapter *padapter = rtw_netdev_priv(dev);
355 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
356 	char *pextra = extra;
357 
358 	if (wrqu->length > 128)
359 		return -EFAULT;
360 	_rtw_memset(input, 0, wrqu->length);
361 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
362 		return -EFAULT;
363 
364 	ret = sscanf(input, "%d,%x", &path, &addr);
365 	if (ret < 2)
366 		return -EINVAL;
367 
368 	if (path >= GET_HAL_RFPATH_NUM(adapter_to_dvobj(padapter)))
369 		return -EINVAL;
370 
371 	_rtw_memset(extra, 0, wrqu->length);
372 
373 	sprintf(data, "%08x",  rtw_phl_read_rfreg(GET_PHL_INFO(dvobj), path, addr , 0xFFFFF));
374 	/*add read data format blank*/
375 	for (i = 0 ; i <= strlen(data) ; i++) {
376 		if (i % 2 == 0) {
377 			tmp[j] = ' ';
378 			j++;
379 		}
380 		tmp[j] = data[i];
381 		j++;
382 	}
383 	pch = tmp;
384 	RTW_INFO("pch=%s", pch);
385 
386 	while (*pch != '\0') {
387 		pnext = strpbrk(pch, " ");
388 		if (!pnext)
389 			break;
390 		pnext++;
391 		if (*pnext != '\0') {
392 			/*strtou =simple_strtoul(pnext , &ptmp, 16);*/
393 			ret = sscanf(pnext, "%x", &strtou);
394 			pextra += sprintf(pextra, " %d", strtou);
395 		} else
396 			break;
397 		pch = pnext;
398 	}
399 	wrqu->length = strlen(extra);
400 
401 	return 0;
402 }
403 
404 
rtw_mp_start(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)405 int rtw_mp_start(struct net_device *dev,
406 		 struct iw_request_info *info,
407 		 struct iw_point *wrqu, char *extra)
408 {
409 	int ret = 0;
410 	_adapter *padapter = rtw_netdev_priv(dev);
411 	struct mp_priv *pmppriv = &padapter->mppriv;
412 	char *pextra = NULL;
413 
414 	pmppriv->bprocess_mp_mode = _TRUE;
415 
416 	if (pmppriv->mode == MP_ON) {
417 		sprintf(extra, "Already mp_start\n");
418 		wrqu->length = strlen(extra);
419 		return ret;
420 	}
421 
422 	rtw_set_scan_deny(padapter, 5000);
423 	rtw_mi_scan_abort(padapter, _TRUE);
424 
425 	if (rtw_mp_cmd(padapter, MP_START, RTW_CMDF_WAIT_ACK) != _SUCCESS)
426 		ret = -EPERM;
427 
428 	_rtw_memset(extra, 0, wrqu->length);
429 	pextra = extra;
430 	pextra += sprintf(extra, "mp_start %s\n", ret == 0 ? "ok" : "fail");
431 	pextra += sprintf(pextra, "EFUSE:%s\n",
432 		RTW_EFUSE_FROM2STR(rtw_efuse_get_map_from(padapter)));
433 	wrqu->length = strlen(extra);
434 
435 	return ret;
436 }
437 
rtw_mp_stop(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)438 int rtw_mp_stop(struct net_device *dev,
439 		struct iw_request_info *info,
440 		struct iw_point *wrqu, char *extra)
441 {
442 	int ret = 0;
443 	u8 status = 0;
444 	_adapter *padapter = rtw_netdev_priv(dev);
445 	struct mp_priv *pmppriv = &padapter->mppriv;
446 
447 
448 	if (rtw_mp_cmd(padapter, MP_STOP, RTW_CMDF_WAIT_ACK) != _SUCCESS)
449 		ret = -EPERM;
450 
451 	if (pmppriv->mode != MP_OFF)
452 		return -EPERM;
453 
454 	_rtw_memset(extra, 0, wrqu->length);
455 	sprintf(extra, "mp_stop ok\n");
456 	wrqu->length = strlen(extra);
457 
458 	pmppriv->bprocess_mp_mode = _FALSE;
459 
460 	return ret;
461 }
462 
463 
rtw_mp_rate(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)464 int rtw_mp_rate(struct net_device *dev,
465 		struct iw_request_info *info,
466 		struct iw_point *wrqu, char *extra)
467 {
468 	u16 rate = MPT_RATE_1M;
469 	u8		input[RTW_IWD_MAX_LEN];
470 	_adapter *padapter = rtw_netdev_priv(dev);
471 	struct mp_priv *pmp_priv = (struct mp_priv *)&padapter->mppriv;
472 	PMPT_CONTEXT		pMptCtx = &(padapter->mppriv.mpt_ctx);
473 	u8 tx_nss = get_phy_tx_nss(padapter);
474 	char *pextra = extra;
475 	u8 path_i = 0, i = 0;
476 	u16 pwr_dbm = 0;
477 
478 	_rtw_memset(input, 0, sizeof(input));
479 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
480 		return -EFAULT;
481 
482 	input[wrqu->length] = '\0';
483 	rate = rtw_mp_rate_parse(padapter, input);
484 	padapter->mppriv.rateidx = rate;
485 
486 	if (rate == 0 && strcmp(input, "1M") != 0) {
487 		rate = rtw_atoi(input);
488 #ifndef CONFIG_80211AX_HE
489 		padapter->mppriv.rateidx = mrate_to_hwrate(rate);
490 #endif
491 		/*if (rate <= 0x7f)
492 			rate = wifirate2_ratetbl_inx((u8)rate);
493 		else if (rate < 0xC8)
494 			rate = (rate - 0x79 + MPT_RATE_MCS0);
495 		HT  rate 0x80(MCS0)  ~ 0x8F(MCS15) ~ 0x9F(MCS31) 128~159
496 		VHT1SS~2SS rate 0xA0 (VHT1SS_MCS0 44) ~ 0xB3 (VHT2SS_MCS9 #63) 160~179
497 		VHT rate 0xB4 (VHT3SS_MCS0 64) ~ 0xC7 (VHT2SS_MCS9 #83) 180~199
498 		else
499 		VHT rate 0x90(VHT1SS_MCS0) ~ 0x99(VHT1SS_MCS9) 144~153
500 		rate =(rate - MPT_RATE_VHT1SS_MCS0);
501 		*/
502 	}
503 	_rtw_memset(extra, 0, wrqu->length);
504 
505 	pextra += sprintf(pextra, "Set data rate to %s index %d\n" , input, padapter->mppriv.rateidx);
506 	RTW_INFO("%s: %s rate index=%d\n", __func__, input, padapter->mppriv.rateidx);
507 	pextra += sprintf(pextra, "PPDU Type %s\n",
508 								PPDU_TYPE_STR(pmp_priv->rtw_mp_pmact_ppdu_type));
509 	pextra += sprintf(pextra, "CMD: [mp_plcp_datappdu=%%d]\nPLCP (PPDU Type):\n");
510 	for (i = pmp_priv->rtw_mp_pmact_ppdu_type; i <= RTW_MP_TYPE_HE_TB; i++)
511 		pextra += sprintf(pextra, "%d:%s\n", i,PPDU_TYPE_STR(i));
512 
513 	SetDataRate(padapter);
514 #if 0
515 	for (path_i = 0 ; path_i < tx_nss; path_i++) {
516 		pwr_dbm = rtw_mp_get_pwrtab_dbm(padapter, path_i);
517 		pextra += sprintf(pextra, "Path%d Pwrdbm:%d" , path_i, pwr_dbm);
518 	}
519 #endif
520 	wrqu->length = strlen(extra);
521 	return 0;
522 }
523 
524 
rtw_mp_channel(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)525 int rtw_mp_channel(struct net_device *dev,
526 		   struct iw_request_info *info,
527 		   struct iw_point *wrqu, char *extra)
528 {
529 	_adapter *padapter = rtw_netdev_priv(dev);
530 	struct mp_priv *pmp_priv = (struct mp_priv *)&padapter->mppriv;
531 	u8		input[RTW_IWD_MAX_LEN];
532 	u32	channel = 1;
533 
534 	_rtw_memset(input, 0, sizeof(input));
535 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
536 		return -EFAULT;
537 
538 	input[wrqu->length] = '\0';
539 	channel = rtw_atoi(input);
540 
541 	_rtw_memset(extra, 0, wrqu->length);
542 	sprintf(extra, "Change channel %d to channel %d", pmp_priv->channel, channel);
543 	pmp_priv->channel = channel;
544 	//pHalData->current_channel = channel; //aka struct rtw_phl_com_t
545 	SetChannel(padapter);
546 
547 	wrqu->length = strlen(extra);
548 	return 0;
549 }
550 
rtw_mp_update_trxsc(_adapter * padapter)551 static void rtw_mp_update_trxsc(_adapter *padapter) {
552 	struct mp_priv *pmp_priv = (struct mp_priv *)&padapter->mppriv;
553 	u8 trxsc_offset = pmp_priv->rtw_mp_trxsc;
554 
555 	switch (trxsc_offset) {
556 	case 0:
557 		pmp_priv->rtw_mp_data_bandwidth = pmp_priv->bandwidth;
558 		RTW_INFO("%s:TRXSC %d, MP bandwidth = %d\n", __func__, trxsc_offset, pmp_priv->bandwidth);
559 		break;
560 	case 1:
561 	case 2:
562 	case 3:
563 	case 4:
564 		pmp_priv->rtw_mp_data_bandwidth = CHANNEL_WIDTH_20;
565 		RTW_INFO("%s:TRXSC %d, MP bandwidth = %d\n", __func__, trxsc_offset, pmp_priv->bandwidth);
566 		break;
567 	case 9:
568 	case 10:
569 	case 11:
570 	case 12:
571 		pmp_priv->rtw_mp_data_bandwidth = CHANNEL_WIDTH_40;
572 		RTW_INFO("%s:TRXSC %d, MP bandwidth = %d\n", __func__, trxsc_offset, pmp_priv->bandwidth);
573 		break;
574 	case 13:
575 	case 14:
576 		pmp_priv->rtw_mp_data_bandwidth = CHANNEL_WIDTH_40;
577 		RTW_INFO("%s:TRXSC %d, MP bandwidth = %d\n", __func__, trxsc_offset, pmp_priv->bandwidth);
578 		break;
579 	}
580 }
581 
rtw_mp_trxsc_offset(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)582 int rtw_mp_trxsc_offset(struct net_device *dev,
583 		   struct iw_request_info *info,
584 		   struct iw_point *wrqu, char *extra)
585 {
586 
587 	_adapter *padapter = rtw_netdev_priv(dev);
588 	struct mp_priv *pmp_priv = (struct mp_priv *)&padapter->mppriv;
589 	u8		input[RTW_IWD_MAX_LEN];
590 	u32	trxsc_offset = 0;
591 
592 	_rtw_memset(input, 0, sizeof(input));
593 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
594 		return -EFAULT;
595 
596 	input[wrqu->length] = '\0';
597 	trxsc_offset = rtw_atoi(input);
598 	RTW_INFO("%s: ch offset = %d\n", __func__, trxsc_offset);
599 
600 	pmp_priv->rtw_mp_trxsc = trxsc_offset;
601 	rtw_mp_update_trxsc(padapter);
602 	_rtw_memset(extra, 0, wrqu->length);
603 	sprintf(extra, "change TRXSC to %d, current Bandwidth=%d\n",
604 						pmp_priv->rtw_mp_trxsc, pmp_priv->bandwidth);
605 
606 	wrqu->length = strlen(extra);
607 	return 0;
608 }
609 
610 
rtw_mp_bandwidth(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)611 int rtw_mp_bandwidth(struct net_device *dev,
612 		     struct iw_request_info *info,
613 		     struct iw_point *wrqu, char *extra)
614 {
615 	u8 bandwidth = 0, sg = 0;
616 	_adapter *padapter = rtw_netdev_priv(dev);
617 	struct mp_priv *pmp_priv = (struct mp_priv *)&padapter->mppriv;
618 	u8		input[RTW_IWD_MAX_LEN];
619 
620 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
621 		return -EFAULT;
622 
623 	if (sscanf(input, "40M=%hhd,shortGI=%hhd", &bandwidth, &sg) > 0)
624 		RTW_INFO("%s: bw=%d sg=%d\n", __func__, bandwidth , sg);
625 #if 0
626 	if (bandwidth == 1 && rtw_hw_chk_bw_cap(adapter_to_dvobj(padapter), BW_CAP_40M))
627 		bandwidth = CHANNEL_WIDTH_40;
628 	else if (bandwidth == 2 && rtw_hw_chk_bw_cap(adapter_to_dvobj(padapter), BW_CAP_80M))
629 		bandwidth = CHANNEL_WIDTH_80;
630 	else
631 		bandwidth = CHANNEL_WIDTH_20;
632 #else
633 	rtw_adjust_chbw(padapter, pmp_priv->channel, &bandwidth, &pmp_priv->prime_channel_offset);
634 
635 	pmp_priv->bandwidth = (u8)bandwidth;
636 	pmp_priv->preamble = sg;
637 	_rtw_memset(extra, 0, wrqu->length);
638 	sprintf(extra, "Change BW %d to BW %d\n", pmp_priv->bandwidth , bandwidth);
639 
640 	SetBandwidth(padapter);
641 	rtw_mp_update_trxsc(padapter);
642 #endif
643 	wrqu->length = strlen(extra);
644 
645 	return 0;
646 }
647 
648 
rtw_mp_txpower_index(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)649 int rtw_mp_txpower_index(struct net_device *dev,
650 			 struct iw_request_info *info,
651 			 struct iw_point *wrqu, char *extra)
652 {
653 	_adapter *padapter = rtw_netdev_priv(dev);
654 	char input[RTW_IWD_MAX_LEN];
655 	u32 rfpath = 0 ;
656 	u32 txpower_inx = 0, tarpowerdbm = 0;
657 	char *pextra = extra;
658 	u8 rf_type = GET_HAL_RFPATH(adapter_to_dvobj(padapter));
659 
660 	if (wrqu->length > 128)
661 		return -EFAULT;
662 
663 	_rtw_memset(input, 0, sizeof(input));
664 
665 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
666 		return -EFAULT;
667 
668 	input[wrqu->length] = '\0';
669 	_rtw_memset(extra, 0, strlen(extra));
670 
671 	if (wrqu->length == 2) {
672 #ifndef CONFIG_80211AX_HE
673 		if (input[0] != '\0' ) {
674 			rfpath = rtw_atoi(input);
675 			txpower_inx = mpt_ProQueryCalTxPower(padapter, rfpath);
676 		}
677 #endif
678 		pextra += sprintf(pextra, " %d\n", txpower_inx);
679 		tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, rfpath);
680 		if (tarpowerdbm > 0)
681 			pextra += sprintf(pextra, "\t\t dBm:%d", tarpowerdbm);
682 	} else {
683 #ifndef CONFIG_80211AX_HE
684 		txpower_inx = mpt_ProQueryCalTxPower(padapter, 0);
685 		pextra += sprintf(pextra, "patha=%d", txpower_inx);
686 		if (rf_type > RF_1T2R) {
687 			txpower_inx = mpt_ProQueryCalTxPower(padapter, 1);
688 			pextra += sprintf(pextra, ",pathb=%d", txpower_inx);
689 		}
690 		if (rf_type > RF_2T4R) {
691 			txpower_inx = mpt_ProQueryCalTxPower(padapter, 2);
692 			pextra += sprintf(pextra, ",pathc=%d", txpower_inx);
693 		}
694 		if (rf_type > RF_3T4R) {
695 			txpower_inx = mpt_ProQueryCalTxPower(padapter, 3);
696 			pextra += sprintf(pextra, ",pathd=%d", txpower_inx);
697 		}
698 #endif
699 		tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, 0);
700 		pextra += sprintf(pextra, "\n\t\t\tpatha dBm=%d", tarpowerdbm);
701 		if (rf_type > RF_1T2R) {
702 			tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, 1);
703 			pextra += sprintf(pextra, ",pathb dBm=%d", tarpowerdbm);
704 		}
705 		if (rf_type > RF_2T4R) {
706 			tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, 2);
707 			pextra += sprintf(pextra, ",pathc dBm=%d", tarpowerdbm);
708 		}
709 		if (rf_type > RF_3T4R) {
710 			tarpowerdbm = mpt_get_tx_power_finalabs_val(padapter, 3);
711 			pextra += sprintf(pextra, ",pathd dBm=%d", tarpowerdbm);
712 		}
713 	}
714 
715 	wrqu->length = strlen(extra);
716 
717 	return 0;
718 }
719 
720 
rtw_mp_txpower(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)721 int rtw_mp_txpower(struct net_device *dev,
722 		   struct iw_request_info *info,
723 		   struct iw_point *wrqu, char *extra)
724 {
725 	u32 idx_a = 0, idx_b = 0, idx_c = 0, idx_d = 0;
726 	int MsetPower = 1;
727 	char pout_str_buf[7];
728 	u8		input[RTW_IWD_MAX_LEN];
729 	u8 rfpath_i = 0;
730 	u16 agc_cw_val = 0;
731 	_adapter *padapter = rtw_netdev_priv(dev);
732 	struct mp_priv *pmppriv = &padapter ->mppriv;
733 	u8 tx_nss = get_phy_tx_nss(padapter);
734 	char *pextra = extra;
735 
736 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
737 		return -EFAULT;
738 
739 	MsetPower = strncmp(input, "off", 3);
740 	if (MsetPower == 0) {
741 		pmppriv->bSetTxPower = 0;
742 		sprintf(pextra, "MP Set power off");
743 	} else {
744 		if (sscanf(input, "patha=%d,pathb=%d,pathc=%d,pathd=%d", &idx_a, &idx_b, &idx_c, &idx_d) >= 1) {
745 				pextra += sprintf(pextra, "Set power offset path_A:%d path_B:%d path_C:%d path_D:%d\n", idx_a , idx_b , idx_c , idx_d);
746 				pmppriv->path_pwr_offset[RF_PATH_A] = (u8)idx_a;
747 				pmppriv->path_pwr_offset[RF_PATH_B] = (u8)idx_b;
748 				pmppriv->path_pwr_offset[RF_PATH_C] = (u8)idx_c;
749 				pmppriv->path_pwr_offset[RF_PATH_D]  = (u8)idx_d;
750 				pmppriv->bSetTxPower = 1;
751 		} else if (strncmp(input, "dbm", 3) == 0) {
752 			u8 signed_flag = 0;
753 			u8 ret = 0xff;
754 			int int_num = 0;
755 			u32 dec_num = 0;
756 			s16 pout = 0;
757 			int i;
758 			u32 poutdbm = 0;
759 			s32 db_temp = 0;
760 			s16 pset = 0;
761 			u8 rfpath;
762 
763 			if (sscanf(input, "dbm=%7s", pout_str_buf) == 1) {
764 				ret = 0;
765 			} else {
766 				sprintf(extra, "[dbm = -30 ~ 30.00]");
767 				goto invalid_param_format;
768 			}
769 
770 			if(pout_str_buf[0] == '-')
771 				signed_flag = 1;
772 			i = sscanf(pout_str_buf, "%d.%3u", &int_num, &dec_num);
773 			RTW_INFO("%s: pars input =%d.%d\n", __func__, int_num, dec_num);
774 
775 			if(i == 2)
776 				dec_num = (dec_num < 10) ? dec_num * 10 : dec_num;
777 
778 			if (int_num >= 30 || ret == 0xff || dec_num > 99 || (dec_num % 25 != 0)) {
779 				sprintf(extra, "CMD Format:[dbm= -30.00 ~ 30.00]\n"
780 					" each scale step value must 0.25 or -0.25\n");
781 				goto invalid_param_format;
782 			}
783 
784 			pset = int_num * TX_POWER_BASE + ((dec_num * TX_POWER_BASE) / 100);
785 			RTW_INFO("%s: pset=%d\n", __func__, pset);
786 			pset = ((pset < 0 || signed_flag == 1) ? -pset : pset);
787 
788 
789 			pextra += sprintf(pextra, "Set power dbm :%d.%d\n", int_num, dec_num);
790 			pmppriv->txpowerdbm = pset;
791 			pmppriv->bSetTxPower = 1;
792 		} else {
793 			pextra += sprintf(pextra, "Invalid format on line %s\n", input);
794 			RTW_INFO("Invalid format on line %s\n", input );
795 			wrqu->length = strlen(extra);
796 			return 0;
797 		}
798 
799 		for (rfpath_i = 0 ; rfpath_i < tx_nss; rfpath_i ++) {
800 				agc_cw_val = rtw_mp_txpower_dbm(padapter, rfpath_i);
801 				pextra += sprintf(pextra, "Path:%d PwrAGC:%d\n", rfpath_i,agc_cw_val);
802 		}
803 	}
804 
805 invalid_param_format:
806 	wrqu->length = strlen(extra);
807 	return 0;
808 }
809 
810 
rtw_mp_ant_tx(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)811 int rtw_mp_ant_tx(struct net_device *dev,
812 		  struct iw_request_info *info,
813 		  struct iw_point *wrqu, char *extra)
814 {
815 	u8 i;
816 	u8		input[RTW_IWD_MAX_LEN];
817 	u8 antenna = 0;
818 	u16 pwr_dbm = 0;
819 	_adapter *padapter = rtw_netdev_priv(dev);
820 	char *pextra = extra;
821 
822 	_rtw_memset(input, 0, sizeof(input));
823 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
824 		return -EFAULT;
825 
826 	input[wrqu->length] = '\0';
827 	pextra += sprintf(pextra, "switch Tx antenna to %s\n", input);
828 
829 	for (i = 0; i < strlen(input); i++) {
830 		switch (input[i]) {
831 		case 'a':
832 			antenna |= MP_ANTENNA_A;
833 			break;
834 		case 'b':
835 			antenna |= MP_ANTENNA_B;
836 			break;
837 		case 'c':
838 			antenna |= MP_ANTENNA_C;
839 			break;
840 		case 'd':
841 			antenna |= MP_ANTENNA_D;
842 			break;
843 		}
844 	}
845 	/*antenna |= BIT(extra[i]-'a');*/
846 	RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);
847 	padapter->mppriv.antenna_trx = antenna;
848 
849 	SetAntenna(padapter);
850 	pwr_dbm = rtw_mp_get_pwrtab_dbm(padapter, antenna);
851 	pextra += sprintf(pextra, "read pwr dbm:%d", pwr_dbm);
852 
853 	wrqu->length = strlen(extra);
854 	return 0;
855 }
856 
857 
rtw_mp_ant_rx(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)858 int rtw_mp_ant_rx(struct net_device *dev,
859 		  struct iw_request_info *info,
860 		  struct iw_point *wrqu, char *extra)
861 {
862 	u8 i;
863 	u16 antenna = 0;
864 	u8		input[RTW_IWD_MAX_LEN];
865 	_adapter *padapter = rtw_netdev_priv(dev);
866 
867 	_rtw_memset(input, 0, sizeof(input));
868 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
869 		return -EFAULT;
870 
871 	input[wrqu->length] = '\0';
872 	/*RTW_INFO("%s: input=%s\n", __func__, input);*/
873 	_rtw_memset(extra, 0, wrqu->length);
874 
875 	sprintf(extra, "switch Rx antenna to %s", input);
876 	for (i = 0; i < strlen(input); i++) {
877 		switch (input[i]) {
878 		case 'a':
879 			antenna |= MP_ANTENNA_A;
880 			break;
881 		case 'b':
882 			antenna |= MP_ANTENNA_B;
883 			break;
884 		case 'c':
885 			antenna |= MP_ANTENNA_C;
886 			break;
887 		case 'd':
888 			antenna |= MP_ANTENNA_D;
889 			break;
890 		}
891 	}
892 	RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);
893 
894 	padapter->mppriv.antenna_trx = antenna;
895 	SetAntenna(padapter);
896 	wrqu->length = strlen(extra);
897 
898 	return 0;
899 }
900 
901 
rtw_set_ctx_destAddr(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)902 int rtw_set_ctx_destAddr(struct net_device *dev,
903 			 struct iw_request_info *info,
904 			 struct iw_point *wrqu, char *extra)
905 {
906 	int jj, kk = 0;
907 
908 	struct pkt_attrib *pattrib;
909 	struct mp_priv *pmp_priv;
910 	_adapter *padapter = rtw_netdev_priv(dev);
911 
912 	pmp_priv = &padapter->mppriv;
913 	pattrib = &pmp_priv->tx.attrib;
914 
915 	if (strlen(extra) < 5)
916 		return _FAIL;
917 
918 	RTW_INFO("%s: in=%s\n", __func__, extra);
919 	for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
920 		pattrib->dst[jj] = key_2char2num(extra[kk], extra[kk + 1]);
921 
922 	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]);
923 	return 0;
924 }
925 
926 
927 
rtw_mp_ctx(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)928 int rtw_mp_ctx(struct net_device *dev,
929 	       struct iw_request_info *info,
930 	       struct iw_point *wrqu, char *extra)
931 {
932 	u32 pkTx = 1;
933 	int countPkTx = 1, cotuTx = 1, CarrSprTx = 1, scTx = 1, sgleTx = 1, stop = 1, payload = 1;
934 	u32 bStartTest = 1;
935 	u32 count = 0, pktinterval = 0, pktlen = 0;
936 	u8 status;
937 	u8 tx_shape_idx = 255;
938 
939 	struct mp_priv *pmp_priv;
940 	struct pkt_attrib *pattrib;
941 	_adapter *padapter = rtw_netdev_priv(dev);
942 
943 	pmp_priv = &padapter->mppriv;
944 	pattrib = &pmp_priv->tx.attrib;
945 
946 	if (padapter->registrypriv.mp_mode != 1 ) {
947 		sprintf(extra, "Error: can't tx ,not in MP mode. \n");
948 		wrqu->length = strlen(extra);
949 		return 0;
950 	}
951 
952 	if (copy_from_user(extra, wrqu->pointer, wrqu->length))
953 		return -EFAULT;
954 
955 	*(extra + wrqu->length) = '\0';
956 	RTW_INFO("%s: in=%s\n", __func__, extra);
957 #ifdef CONFIG_CONCURRENT_MODE
958 	if (!is_primary_adapter(padapter)) {
959 		sprintf(extra, "Error: MP mode can't support Virtual adapter, Please to use main adapter.\n");
960 		wrqu->length = strlen(extra);
961 		return 0;
962 	}
963 #endif
964 	countPkTx = strncmp(extra, "count=", 5); /* strncmp TRUE is 0*/
965 	cotuTx = strncmp(extra, "background", 20);
966 	CarrSprTx = strncmp(extra, "background,cs", 20);
967 	scTx = strncmp(extra, "background,sc", 20);
968 	sgleTx = strncmp(extra, "background,stone", 20);
969 	pkTx = strncmp(extra, "background,pkt", 20);
970 	stop = strncmp(extra, "stop", 4);
971 	payload = strncmp(extra, "payload=", 8);
972 
973 	if (sscanf(extra, "count=%d,pkt", &count) > 0)
974 		RTW_INFO("count= %d\n", count);
975 	if (sscanf(extra, "pktinterval=%d", &pktinterval) > 0)
976 		RTW_INFO("pktinterval= %d\n", pktinterval);
977 	if (sscanf(extra, "pktlen=%d", &pktlen) > 0)
978 		RTW_INFO("pktlen= %d\n", pktlen);
979 	if (sscanf(extra, "tx_shape=%hhd", &tx_shape_idx) > 0)
980 		RTW_INFO("tx_shape=%d\n", tx_shape_idx);
981 
982 	if (payload == 0) {
983 			payload = MP_TX_Payload_default_random;
984 			if (strncmp(extra, "payload=prbs9", 14) == 0) {
985 				payload = MP_TX_Payload_prbs9;
986 				sprintf(extra, "config payload PRBS9\n");
987 			} else {
988 				if (sscanf(extra, "payload=%x", &payload) > 0){
989 					RTW_INFO("payload= %x\n", payload);
990 					sprintf(extra, "config payload setting = %x\n"
991 									"1. input payload=[]:\n		"
992 									"[0]: 00, [1]: A5, [2]: 5A, [3]: FF, [4]: PRBS-9, [5]: Random\n"
993 									"2. specified a hex payload: payload=0xee\n", payload);
994 				 }
995 			}
996 			pmp_priv->tx.payload = payload;
997 			wrqu->length = strlen(extra);
998 			return 0;
999 	}
1000 
1001 	if (_rtw_memcmp(extra, "destmac=", 8)) {
1002 		wrqu->length -= 8;
1003 		rtw_set_ctx_destAddr(dev, info, wrqu, &extra[8]);
1004 		sprintf(extra, "Set dest mac OK !\n");
1005 		return 0;
1006 	}
1007 	/*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);*/
1008 	_rtw_memset(extra, '\0', strlen(extra));
1009 
1010 	if (pktinterval != 0) {
1011 		sprintf(extra, "Pkt Interval = %d", pktinterval);
1012 		padapter->mppriv.pktInterval = pktinterval;
1013 		wrqu->length = strlen(extra);
1014 		return 0;
1015 
1016 	} else if (pktlen != 0) {
1017 		sprintf(extra, "Pkt len = %d", pktlen);
1018 		pattrib->pktlen = pktlen;
1019 		wrqu->length = strlen(extra);
1020 		return 0;
1021 
1022 	} else if (tx_shape_idx != 255) {
1023 		padapter->mppriv.tx_shape_idx = tx_shape_idx;
1024 
1025 		if (rtw_mp_set_tx_shape_idx(padapter))
1026 			sprintf(extra, "tx_shape idx = %d\n", tx_shape_idx);
1027 		else
1028 			sprintf(extra, "tx_shape %d Error\n", tx_shape_idx);
1029 
1030 		RTW_INFO("in tx_shape=%d\n", tx_shape_idx);
1031 		wrqu->length = strlen(extra);
1032 		return 0;
1033 
1034 	} else if (stop == 0) {
1035 		bStartTest = 0; /* To set Stop*/
1036 		pmp_priv->tx.stop = 1;
1037 		sprintf(extra, "Stop continuous Tx");
1038 	} else {
1039 		bStartTest = 1;
1040 
1041 		if (pmp_priv->mode != MP_ON) {
1042 			if (pmp_priv->tx.stop != 1) {
1043 				RTW_INFO("%s:Error MP_MODE %d != ON\n", __func__, pmp_priv->mode);
1044 				return	-EFAULT;
1045 			}
1046 		}
1047 	}
1048 
1049 	pmp_priv->tx.count = count;
1050 
1051 	if (pkTx == 0 || countPkTx == 0)
1052 		pmp_priv->mode = MP_PACKET_TX;
1053 	if (sgleTx == 0)
1054 		pmp_priv->mode = MP_SINGLE_TONE_TX;
1055 	if (cotuTx == 0)
1056 		pmp_priv->mode = MP_CONTINUOUS_TX;
1057 	if (CarrSprTx == 0)
1058 		pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX;
1059 	if (scTx == 0)
1060 		pmp_priv->mode = MP_SINGLE_CARRIER_TX;
1061 
1062 	status = rtw_mp_pretx_proc(padapter, bStartTest, extra);
1063 
1064 	if (stop == 0)
1065 		pmp_priv->mode = MP_ON;
1066 
1067 	wrqu->length = strlen(extra);
1068 	return status;
1069 }
1070 
1071 
1072 
rtw_mp_disable_bt_coexist(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1073 int rtw_mp_disable_bt_coexist(struct net_device *dev,
1074 			      struct iw_request_info *info,
1075 			      union iwreq_data *wrqu, char *extra)
1076 {
1077 #ifdef CONFIG_BTC
1078 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1079 
1080 #endif
1081 	u8 input[RTW_IWD_MAX_LEN];
1082 	u32 bt_coexist;
1083 
1084 	_rtw_memset(input, 0, sizeof(input));
1085 
1086 	if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
1087 		return -EFAULT;
1088 
1089 	input[wrqu->data.length] = '\0';
1090 
1091 	bt_coexist = rtw_atoi(input);
1092 
1093 #if 0
1094 	if (bt_coexist == 0) {
1095 		RTW_INFO("Set OID_RT_SET_DISABLE_BT_COEXIST: disable BT_COEXIST\n");
1096 #ifdef CONFIG_BTC
1097 		rtw_btcoex_HaltNotify(padapter);
1098 		rtw_btcoex_SetManualControl(padapter, _TRUE);
1099 		/* Force to switch Antenna to WiFi*/
1100 		rtw_write16(padapter, 0x870, 0x300);
1101 		rtw_write16(padapter, 0x860, 0x110);
1102 #endif
1103 		/* CONFIG_BTC */
1104 	} else {
1105 #ifdef CONFIG_BTC
1106 		rtw_btcoex_SetManualControl(padapter, _FALSE);
1107 #endif
1108 	}
1109 #endif
1110 
1111 	return 0;
1112 }
1113 
1114 
rtw_mp_arx(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1115 int rtw_mp_arx(struct net_device *dev,
1116 				struct iw_request_info *info,
1117 				struct iw_point *wrqu, char *extra)
1118 {
1119 	_adapter *padapter = rtw_netdev_priv(dev);
1120 	struct mp_priv *pmppriv = &padapter->mppriv;
1121 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1122 	u8	input[RTW_IWD_MAX_LEN];
1123 	u32	ret;
1124 	char *pch, *token, *tmp[2] = {0x00, 0x00};
1125 	u32 i = 0, jj = 0, kk = 0, cnts = 0;
1126 
1127 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1128 		return -EFAULT;
1129 
1130 	RTW_INFO("%s: %s\n", __func__, input);
1131 	if (strncmp(input, "setbssid=", 8) == 0) {
1132 		pch = input;
1133 		while ((token = strsep(&pch, "=")) != NULL) {
1134 			if (i > 1)
1135 				break;
1136 			tmp[i] = token;
1137 			i++;
1138 		}
1139 		if ((tmp[0] != NULL) && (tmp[1] != NULL)) {
1140 			cnts = strlen(tmp[1]) / 2;
1141 			if (cnts < 1)
1142 				return -EFAULT;
1143 			RTW_INFO("%s: cnts=%d\n", __func__, cnts);
1144 			RTW_INFO("%s: data=%s\n", __func__, tmp[1]);
1145 			for (jj = 0, kk = 0; jj < cnts ; jj++, kk += 2) {
1146 				pmppriv->network_macaddr[jj] =
1147 					key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
1148 				RTW_INFO("network_macaddr[%d]=%x\n",
1149 					jj, pmppriv->network_macaddr[jj]);
1150 			}
1151 		} else
1152 			return -EFAULT;
1153 
1154 		pmppriv->bSetRxBssid = _TRUE;
1155 	} else if (strncmp(input, "frametype", 9) == 0) {
1156 		if (strncmp(input, "frametype beacon", 16) == 0)
1157 			pmppriv->brx_filter_beacon = _TRUE;
1158 		else
1159 			pmppriv->brx_filter_beacon = _FALSE;
1160 
1161 	} else if (strncmp(input, "accept_mac", 10) == 0) {
1162 		pmppriv->bmac_filter = _TRUE;
1163 		pch = input;
1164 		while ((token = strsep(&pch, "=")) != NULL) {
1165 			if (i > 1)
1166 				break;
1167 			tmp[i] = token;
1168 			i++;
1169 		}
1170 		if ((tmp[0] != NULL) && (tmp[1] != NULL)) {
1171 			cnts = strlen(tmp[1]) / 2;
1172 			if (cnts < 1)
1173 				return -EFAULT;
1174 			RTW_INFO("%s: cnts=%d\n", __func__, cnts);
1175 			RTW_INFO("%s: data=%s\n", __func__, tmp[1]);
1176 			for (jj = 0, kk = 0; jj < cnts ; jj++, kk += 2) {
1177 				pmppriv->mac_filter[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
1178 				RTW_INFO("%s mac_filter[%d]=%x\n", __func__, jj, pmppriv->mac_filter[jj]);
1179 			}
1180 		} else
1181 			return -EFAULT;
1182 
1183 	} else if (strncmp(input, "start", 5) == 0) {
1184 		sprintf(extra, "start");
1185 
1186 	} else if (strncmp(input, "stop", 5) == 0) {
1187 		struct rtw_mp_rx_arg rx_arg;
1188 
1189 		_rtw_memset((void *)&rx_arg, 0, sizeof(struct rtw_mp_rx_arg));
1190 		rtw_mp_phl_query_rx(padapter, &rx_arg, 2);
1191 		if (rx_arg.cmd_ok) {
1192 			pmppriv->rx_pktcount = rx_arg.rx_ok;
1193 			pmppriv->rx_crcerrpktcount = rx_arg.rx_err;
1194 			RTW_INFO("phl_query_rx rx_ok=%d rx_err=%d\n",
1195 				pmppriv->rx_pktcount, pmppriv->rx_crcerrpktcount);
1196 		} else
1197 			RTW_WARN("phl_query_rx Fail !!!");
1198 
1199 		pmppriv->bmac_filter = _FALSE;
1200 		pmppriv->bSetRxBssid = _FALSE;
1201 		sprintf(extra, "Received packet OK:%d CRC error:%d ,Filter out:%d",
1202 			pmppriv->rx_pktcount, pmppriv->rx_crcerrpktcount,
1203 			pmppriv->rx_pktcount_filter_out);
1204 
1205 	} else if (strncmp(input, "phy", 3) == 0) {
1206 		struct rtw_mp_rx_arg rx_arg;
1207 
1208 		_rtw_memset((void *)&rx_arg, 0, sizeof(struct rtw_mp_rx_arg));
1209 		rtw_mp_phl_query_rx(padapter, &rx_arg, 0);
1210 		if (rx_arg.cmd_ok)
1211 			sprintf(extra, "Phy Received packet OK:%d CRC error:%d",
1212 					rx_arg.rx_ok, rx_arg.rx_err);
1213 		else
1214 			sprintf(extra, "PHL Phy Query Fail !!!");
1215 
1216 	} else if (strncmp(input, "mac", 3) == 0) {
1217 		struct rtw_mp_rx_arg rx_arg;
1218 
1219 		_rtw_memset((void *)&rx_arg, 0, sizeof(struct rtw_mp_rx_arg));
1220 		rtw_mp_phl_query_rx(padapter, &rx_arg, 1);
1221 		if (rx_arg.cmd_ok)
1222 			sprintf(extra, "Mac Received packet OK:%d CRC error:%d",
1223 					rx_arg.rx_ok, rx_arg.rx_err);
1224 		else
1225 			sprintf(extra, "Mac Phy Query Fail !!!");
1226 
1227 	} else if (strncmp(input, "mon=", 4) == 0) {
1228 		int bmon = 0;
1229 		ret = sscanf(input, "mon=%d", &bmon);
1230 
1231 		if (bmon == 1) {
1232 			pmppriv->rx_bindicatePkt = _TRUE;
1233 			sprintf(extra, "Indicating Receive Packet to network start\n");
1234 		} else {
1235 			pmppriv->rx_bindicatePkt = _FALSE;
1236 			sprintf(extra, "Indicating Receive Packet to network Stop\n");
1237 		}
1238 	} else if (strncmp(input, "loopbk", 6) == 0) {
1239 		u32 val32 = rtw_phl_read32(dvobj->phl, 0xCC20);
1240 		val32 |= BIT0;
1241 		rtw_phl_write32(dvobj->phl, 0xCC20 , val32);
1242 		pmppriv->bloopback = _TRUE;
1243 		sprintf(extra , "Enter MAC LoopBack mode\n");
1244 
1245 	} else if (strncmp(input, "gain", 4) == 0) {
1246 		struct rtw_mp_rx_arg rx_arg;
1247 		u32 gain_val = 0xff;
1248 		u8 path_num = 0;
1249 		u8 rf_path = 0xff;
1250 		u8 iscck = 0xff;
1251 		u8 *pch = extra;
1252 
1253 		switch (input[4]) {
1254 		case 'a':
1255 			rf_path = RF_PATH_A;
1256 			break;
1257 		case 'b':
1258 			rf_path = RF_PATH_B;
1259 			break;
1260 		case 'c':
1261 			rf_path = RF_PATH_C;
1262 			break;
1263 		case 'd':
1264 			rf_path = RF_PATH_D;
1265 			break;
1266 		}
1267 
1268 		if ((sscanf(input + 5, "=0x%x,iscck=%hhd", &gain_val, &iscck) == 2) ||
1269 			(sscanf(input + 5, "=%d,iscck=%hhd", &gain_val, &iscck) == 2))
1270 			RTW_INFO("%s: read gain = %d , is cck =%d\n", __func__, gain_val, iscck);
1271 
1272 		else if ((sscanf(input + 4, "=0x%x", &gain_val) == 1) ||
1273 				(sscanf(input + 4, "=%d", &gain_val) == 1))
1274 				iscck = (u8)rtw_mp_is_cck_rate(pmppriv->rateidx);
1275 		else {
1276 				sprintf(pch, "error format: gain=[Dec/Hex]\n"
1277 						"\t\tgaina or gainb=[Dec/Hex],iscck=0/1\n");
1278 				wrqu->length = strlen(pch) + 1;
1279 				return 0;
1280 		}
1281 
1282 		if (rf_path == 0xff) {
1283 			rf_path = RF_PATH_A;
1284 			path_num = GET_HAL_RFPATH_NUM(adapter_to_dvobj(padapter)) - 1;
1285 		} else
1286 			path_num = rf_path;
1287 
1288 		if (gain_val == 0xff || iscck == 0xff) {
1289 			sprintf(extra, "error format: gaina or gainb=%d,iscck=%d\n", gain_val, iscck);
1290 			wrqu->length = strlen(extra) + 1;
1291 			return 0;
1292 		}
1293 
1294 		for (; rf_path <= path_num ; rf_path++) {
1295 			RTW_INFO("%s:set Path:%d gain_offset=%d iscck=%d\n",
1296 					__func__, rf_path, gain_val, iscck);
1297 
1298 			_rtw_memset((void *)&rx_arg, 0, sizeof(struct rtw_mp_rx_arg));
1299 			rx_arg.offset = (s8)gain_val;
1300 			rx_arg.iscck = iscck;
1301 			rtw_mp_phl_rx_gain_offset(padapter, &rx_arg, rf_path);
1302 
1303 			if (rx_arg.cmd_ok)
1304 				pch += sprintf(pch, "Path %s: 0x%hhx Rx Gain offset OK\n\t\t",
1305 				(rf_path == RF_PATH_A) ? "A":(rf_path == RF_PATH_B) ? "B":
1306 				(rf_path == RF_PATH_C) ? "C":"D", gain_val);
1307 		}
1308 	} else if (strncmp(input, "rssi", 4) == 0) {
1309 		struct rtw_mp_rx_arg rx_arg;
1310 		u8 rssi_path = 0, all_path_num = 0;
1311 		char *pcar = extra;
1312 		u8 i = 0;
1313 
1314 		if (strncmp(input, "rssi a", 6) == 0)
1315 			rssi_path = 0;
1316 		else if (strncmp(input, "rssi b", 6) == 0)
1317 			rssi_path = 1;
1318 		else
1319 			all_path_num = GET_HAL_RFPATH_NUM(adapter_to_dvobj(padapter));
1320 
1321 		if (all_path_num > 1) {
1322 			rssi_path = 0;
1323 			all_path_num = all_path_num - 1;
1324 		} else
1325 			all_path_num = rssi_path;
1326 
1327 		RTW_INFO("%s:Query RSSI Path:%d to %d\n", __func__, rssi_path, all_path_num);
1328 		_rtw_memset((void *)&rx_arg, 0, sizeof(struct rtw_mp_rx_arg));
1329 
1330 		for (i = rssi_path ; i <= all_path_num; i++) {
1331 			rx_arg.rf_path = i;
1332 
1333 			rtw_mp_phl_rx_rssi(padapter, &rx_arg);
1334 			if (rx_arg.cmd_ok) {
1335 				int result_int = 0;
1336 				int result_dec = 0;
1337 
1338 				result_int = (rx_arg.rssi / 2) -110;
1339 				result_dec = (rx_arg.rssi % 2);
1340 				if (result_dec == 1) {
1341 					result_dec = (result_dec * 10) / 2;
1342 					result_int += 1;
1343 				}
1344 				pcar += sprintf(pcar, "Path%d RSSI=%d.%d ", i, result_int, result_dec);
1345 			} else
1346 				pcar += sprintf(pcar, "Path%d RSSI Fail\n", i);
1347 
1348 		}
1349 	} else if (strncmp(input, "physts", 6) == 0) {
1350 		struct rtw_mp_rx_arg rx_arg;
1351 		bool bon;
1352 
1353 		if (strncmp(input, "physts on", 9) == 0)
1354 			bon = true;
1355 		else
1356 			bon = false;
1357 
1358 		_rtw_memset((void *)&rx_arg, 0, sizeof(struct rtw_mp_rx_arg));
1359 		rtw_mp_phl_rx_physts(padapter, &rx_arg, bon);
1360 		if (rx_arg.cmd_ok)
1361 			sprintf(extra, "start OK" );
1362 		else
1363 			sprintf(extra, "start Fail");
1364 	}
1365 
1366 	wrqu->length = strlen(extra) + 1;
1367 
1368 	return 0;
1369 }
1370 
1371 
rtw_mp_trx_query(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1372 int rtw_mp_trx_query(struct net_device *dev,
1373 		     struct iw_request_info *info,
1374 		     struct iw_point *wrqu, char *extra)
1375 {
1376 	u32 txok, txfail, rxok, rxfail, rxfilterout;
1377 	_adapter *padapter = rtw_netdev_priv(dev);
1378 	struct mp_priv *pmp_priv = (struct mp_priv *)&padapter->mppriv;
1379 
1380 
1381 	if (pmp_priv->rtw_mp_tx_method == RTW_MP_PMACT_TX)
1382 		rtw_phl_mp_tx_cmd(padapter, RTW_MP_TX_CMD_PHY_OK, pmp_priv->rtw_mp_tx_method, _FALSE);
1383 
1384 	txok = padapter->mppriv.tx.sended;
1385 	txfail = 0;
1386 	rxok = padapter->mppriv.rx_pktcount;
1387 	rxfail = padapter->mppriv.rx_crcerrpktcount;
1388 	rxfilterout = padapter->mppriv.rx_pktcount_filter_out;
1389 
1390 	_rtw_memset(extra, '\0', 128);
1391 
1392 	sprintf(extra, "Tx OK:%d, Tx Fail:%d, Rx OK:%d, CRC error:%d ,Rx Filter out:%d\n", txok, txfail, rxok, rxfail, rxfilterout);
1393 
1394 	wrqu->length = strlen(extra) + 1;
1395 
1396 	return 0;
1397 }
1398 
1399 
rtw_mp_pwrtrk(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1400 int rtw_mp_pwrtrk(struct net_device *dev,
1401 		  struct iw_request_info *info,
1402 		  struct iw_point *wrqu, char *extra)
1403 {
1404 	u8 enable;
1405 	u32 thermal;
1406 	s32 ret = 0;
1407 	_adapter *padapter = rtw_netdev_priv(dev);
1408 	struct mp_priv *pmp_priv = (struct mp_priv *)&padapter->mppriv;
1409 	u8 input[RTW_IWD_MAX_LEN];
1410 
1411 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1412 		return -EFAULT;
1413 
1414 	_rtw_memset(extra, 0, wrqu->length);
1415 
1416 	enable = RTW_MP_TSSI_OFF;
1417 	if (wrqu->length > 1) {
1418 		/* not empty string*/
1419 		if (strncmp(input, "off", 3) == 0) {
1420 			enable = RTW_MP_TSSI_OFF;
1421 			sprintf(extra, "TSSI power tracking off");
1422 		} else if (strncmp(input, "on", 2) == 0) {
1423 			enable = RTW_MP_TSSI_ON;
1424 			sprintf(extra, "TSSI power tracking on");
1425 		} else if (strncmp(input, "cal", 3) == 0) {
1426 			enable = RTW_MP_TSSI_CAL;
1427 			sprintf(extra, "TSSI cal");
1428 		} else {
1429 			input[wrqu->length] = '\0';
1430 			enable = rtw_atoi(input);
1431 			sprintf(extra, "TSSI power tracking %d", enable);
1432 		}
1433 
1434 		if (enable <= RTW_MP_TSSI_CAL)
1435 			ret = rtw_mp_set_tssi_pwrtrk(padapter, enable);
1436 
1437 		if (ret == false)
1438 			sprintf(extra, "set TSSI power tracking fail");
1439 		else
1440 			pmp_priv->tssi_mode = enable;
1441 	} else {
1442 		enable = rtw_mp_get_tssi_pwrtrk(padapter);
1443 		sprintf(extra, "Get TSSI state: %d\n\
1444 		incput (int/str): [0]:off / [1]:on / [2]:cal for TSSI Tracking", enable);
1445 	}
1446 	wrqu->length = strlen(extra);
1447 
1448 	return 0;
1449 }
1450 
rtw_mp_psd(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1451 int rtw_mp_psd(struct net_device *dev,
1452 	       struct iw_request_info *info,
1453 	       struct iw_point *wrqu, char *extra)
1454 {
1455 	_adapter *padapter = rtw_netdev_priv(dev);
1456 	u8		input[RTW_IWD_MAX_LEN];
1457 
1458 	_rtw_memset(input, 0, sizeof(input));
1459 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1460 		return -EFAULT;
1461 
1462 	input[wrqu->length] = '\0';
1463 	strcpy(extra, input);
1464 
1465 	wrqu->length = mp_query_psd(padapter, extra);
1466 
1467 	return 0;
1468 }
1469 
rtw_mp_uuid(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1470 int rtw_mp_uuid(struct net_device *dev,
1471 		struct iw_request_info *info,
1472 		struct iw_point *wrqu, char *extra)
1473 {
1474 	_adapter *padapter = rtw_netdev_priv(dev);
1475 	u32 uuid;
1476 
1477 	if (copy_from_user(extra, wrqu->pointer, wrqu->length))
1478 		return -EFAULT;
1479 
1480 	GetUuid(padapter, &uuid);
1481 
1482 	_rtw_memset(extra, 0, wrqu->length);
1483 	sprintf(extra, "%d", uuid);
1484 
1485 	wrqu->length = strlen(extra);
1486 
1487 	return 0;
1488 }
1489 
rtw_mp_thermal(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1490 int rtw_mp_thermal(struct net_device *dev,
1491 		   struct iw_request_info *info,
1492 		   struct iw_point *wrqu, char *extra)
1493 {
1494 	u8 val[4] = {0};
1495 	u8 ret = 0;
1496 	u16 ther_path_addr[4] = {0};
1497 	u16 cnt = 1;
1498 	_adapter *padapter = rtw_netdev_priv(dev);
1499 	int rfpath = RF_PATH_A;
1500 
1501 	if (copy_from_user(extra, wrqu->pointer, wrqu->length))
1502 		return -EFAULT;
1503 
1504 	if ((strncmp(extra, "write", 6) == 0)) {
1505 #if 0
1506 		int i;
1507 		u16 raw_cursize = 0, raw_maxsize = 0;
1508 
1509 		raw_maxsize = efuse_GetavailableSize(padapter);
1510 		RTW_INFO("[eFuse available raw size]= %d bytes\n", raw_maxsize - raw_cursize);
1511 		if (2 > raw_maxsize - raw_cursize) {
1512 			RTW_INFO("no available efuse!\n");
1513 			return -EFAULT;
1514 		}
1515 
1516 		for (i = 0; i < GET_HAL_RFPATH_NUM(adapter_to_dvobj(padapter)); i++) {
1517 				GetThermalMeter(padapter, i , &val[i]);
1518 				if (ther_path_addr[i] != 0 && val[i] != 0) {
1519 					if (rtw_efuse_map_write(padapter, ther_path_addr[i], cnt, &val[i]) == _FAIL) {
1520 						RTW_INFO("Error efuse write thermal addr 0x%x ,val = 0x%x\n", ther_path_addr[i], val[i]);
1521 						return -EFAULT;
1522 					}
1523 				} else {
1524 						RTW_INFO("Error efuse write thermal Null addr,val \n");
1525 						return -EFAULT;
1526 				}
1527 		}
1528 #endif
1529 		_rtw_memset(extra, 0, wrqu->length);
1530 		sprintf(extra, " efuse write ok :%d", val[0]);
1531 	} else {
1532 		ret = sscanf(extra, "%d", &rfpath);
1533 		if (ret < 1) {
1534 			rfpath = RF_PATH_A;
1535 			RTW_INFO("default thermal of path(%d)\n", rfpath);
1536 		}
1537 		if (rfpath >= GET_HAL_RFPATH_NUM(adapter_to_dvobj(padapter)))
1538 			return -EINVAL;
1539 
1540 		RTW_INFO("read thermal of path(%d)\n", rfpath);
1541 		GetThermalMeter(padapter, rfpath, &val[0]);
1542 
1543 		_rtw_memset(extra, 0, wrqu->length);
1544 		sprintf(extra, "%d [0x%hhx]", val[0], val[0]);
1545 	}
1546 
1547 	wrqu->length = strlen(extra);
1548 
1549 	return 0;
1550 }
1551 
1552 
1553 
rtw_mp_reset_stats(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1554 int rtw_mp_reset_stats(struct net_device *dev,
1555 		       struct iw_request_info *info,
1556 		       struct iw_point *wrqu, char *extra)
1557 {
1558 	struct mp_priv *pmp_priv;
1559 	_adapter *padapter = rtw_netdev_priv(dev);
1560 
1561 	pmp_priv = &padapter->mppriv;
1562 
1563 	pmp_priv->tx.sended = 0;
1564 	pmp_priv->tx_pktcount = 0;
1565 	pmp_priv->rx_pktcount = 0;
1566 	pmp_priv->rx_pktcount_filter_out = 0;
1567 	pmp_priv->rx_crcerrpktcount = 0;
1568 
1569 	rtw_mp_reset_phy_count(padapter);
1570 
1571 	_rtw_memset(extra, 0, wrqu->length);
1572 	sprintf(extra, "mp_reset_stats ok\n");
1573 	wrqu->length = strlen(extra);
1574 
1575 	return 0;
1576 }
1577 
1578 
rtw_mp_dump(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1579 int rtw_mp_dump(struct net_device *dev,
1580 		struct iw_request_info *info,
1581 		struct iw_point *wrqu, char *extra)
1582 {
1583 	struct mp_priv *pmp_priv;
1584 	u8		input[RTW_IWD_MAX_LEN];
1585 	_adapter *padapter = rtw_netdev_priv(dev);
1586 
1587 	pmp_priv = &padapter->mppriv;
1588 
1589 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1590 		return -EFAULT;
1591 
1592 	if (strncmp(input, "all", 4) == 0) {
1593 		//mac_reg_dump(RTW_DBGDUMP, padapter);
1594 		//bb_reg_dump(RTW_DBGDUMP, padapter);
1595 		//rf_reg_dump(RTW_DBGDUMP, padapter);
1596 	}
1597 	return 0;
1598 }
1599 
1600 
rtw_mp_phypara(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1601 int rtw_mp_phypara(struct net_device *dev,
1602 		   struct iw_request_info *info,
1603 		   struct iw_point *wrqu, char *extra)
1604 {
1605 
1606 	_adapter *padapter = rtw_netdev_priv(dev);
1607 	char	input[RTW_IWD_MAX_LEN];
1608 	u32		invalxcap = 0, ret = 0;
1609 
1610 
1611 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1612 		return -EFAULT;
1613 
1614 	RTW_INFO("%s:priv in=%s\n", __func__, input);
1615 
1616 	if (strncmp(input, "xcap=", 5) == 0) {
1617 		if ((sscanf(input+4, "=0x%x", &invalxcap) == 1) ||
1618 			(sscanf(input+4, "=%d", &invalxcap) == 1)) {
1619 			if (invalxcap < 255) {
1620 				rtw_mp_set_crystal_cap(padapter, invalxcap);
1621 				sprintf(extra, "Set xcap = %d [0x%hhx]", invalxcap, invalxcap);
1622 			} else
1623 				sprintf(extra, "Error formats , inpunt value over 255 !\n");
1624 
1625 			wrqu->length = strlen(extra);
1626 			return ret;
1627 		}
1628 	}
1629 
1630 	sprintf(extra, "Error formats , inpunt [xcap=%%d/0x%%x]\n");
1631 
1632 	wrqu->length = strlen(extra);
1633 	return ret;
1634 }
1635 
1636 
rtw_mp_SetRFPath(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1637 int rtw_mp_SetRFPath(struct net_device *dev,
1638 		     struct iw_request_info *info,
1639 		     struct iw_point *wrqu, char *extra)
1640 {
1641 	_adapter *padapter = rtw_netdev_priv(dev);
1642 	char	input[RTW_IWD_MAX_LEN];
1643 	int		bMain = 1, bTurnoff = 1;
1644 #ifdef CONFIG_ANTENNA_DIVERSITY
1645 	u8 ret = _TRUE;
1646 #endif
1647 
1648 	RTW_INFO("%s:iwpriv in=%s\n", __func__, input);
1649 
1650 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1651 		return -EFAULT;
1652 #if 0
1653 	bMain = strncmp(input, "1", 2); /* strncmp TRUE is 0*/
1654 	bTurnoff = strncmp(input, "0", 3); /* strncmp TRUE is 0*/
1655 
1656 	_rtw_memset(extra, 0, wrqu->length);
1657 #ifdef CONFIG_ANTENNA_DIVERSITY
1658 	if (bMain == 0)
1659 		ret = rtw_mp_set_antdiv(padapter, _TRUE);
1660 	else
1661 		ret = rtw_mp_set_antdiv(padapter, _FALSE);
1662 	if (ret == _FALSE)
1663 		RTW_INFO("%s:ANTENNA_DIVERSITY FAIL\n", __func__);
1664 #endif
1665 
1666 	if (bMain == 0) {
1667 		MP_PHY_SetRFPathSwitch(padapter, _TRUE);
1668 		RTW_INFO("%s:PHY_SetRFPathSwitch=TRUE\n", __func__);
1669 		sprintf(extra, "mp_setrfpath Main\n");
1670 
1671 	} else if (bTurnoff == 0) {
1672 		MP_PHY_SetRFPathSwitch(padapter, _FALSE);
1673 		RTW_INFO("%s:PHY_SetRFPathSwitch=FALSE\n", __func__);
1674 		sprintf(extra, "mp_setrfpath Aux\n");
1675 	} else {
1676 		bMain = MP_PHY_QueryRFPathSwitch(padapter);
1677 		RTW_INFO("%s:Query RF Path = %s\n", __func__, (bMain ? "Main":"Aux"));
1678 		sprintf(extra, "RF Path %s\n" , (bMain ? "1":"0"));
1679 	}
1680 #endif
1681 	wrqu->length = strlen(extra);
1682 
1683 	return 0;
1684 }
1685 
1686 
rtw_mp_switch_rf_path(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1687 int rtw_mp_switch_rf_path(struct net_device *dev,
1688 			struct iw_request_info *info,
1689 			struct iw_point *wrqu, char *extra)
1690 {
1691 	_adapter *padapter = rtw_netdev_priv(dev);
1692 	struct mp_priv *pmp_priv;
1693 	char	input[RTW_IWD_MAX_LEN];
1694 	int		bwlg = 1, bwla = 1, btg = 1, bbt=1;
1695 	u8 ret = 0;
1696 
1697 
1698 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1699 		return -EFAULT;
1700 
1701 	pmp_priv = &padapter->mppriv;
1702 
1703 	RTW_INFO("%s: in=%s\n", __func__, input);
1704 
1705 #ifdef CONFIG_RTL8821C /* only support for 8821c wlg/wla/btg/bt RF switch path */
1706 	if ((strncmp(input, "WLG", 3) == 0) || (strncmp(input, "1", 1) == 0)) {
1707 		pmp_priv->rf_path_cfg = SWITCH_TO_WLG;
1708 		sprintf(extra, "switch rf path WLG\n");
1709 
1710 	} else if ((strncmp(input, "WLA", 3) == 0) || (strncmp(input, "2", 1) == 0)) {
1711 		pmp_priv->rf_path_cfg = SWITCH_TO_WLA;
1712 		sprintf(extra, "switch rf path WLA\n");
1713 
1714 	} else if ((strncmp(input, "BTG", 3) == 0) || (strncmp(input, "0", 1) == 0)) {
1715 		pmp_priv->rf_path_cfg = SWITCH_TO_BTG;
1716 		sprintf(extra, "switch rf path BTG\n");
1717 
1718 	} else if ((strncmp(input, "BT", 3) == 0) || (strncmp(input, "3", 1) == 0)) {
1719 		pmp_priv->rf_path_cfg = SWITCH_TO_BT;
1720 		sprintf(extra, "switch rf path BT\n");
1721 	} else {
1722 		pmp_priv->rf_path_cfg = SWITCH_TO_WLG;
1723 		sprintf(extra, "Error input, default set WLG\n");
1724 		return -EFAULT;
1725 	}
1726 
1727 	mp_phy_switch_rf_path_set(padapter, &pmp_priv->rf_path_cfg);
1728 #endif
1729 	wrqu->length = strlen(extra);
1730 
1731 	return ret;
1732 
1733 }
rtw_mp_QueryDrv(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1734 int rtw_mp_QueryDrv(struct net_device *dev,
1735 		    struct iw_request_info *info,
1736 		    union iwreq_data *wrqu, char *extra)
1737 {
1738 	_adapter *padapter = rtw_netdev_priv(dev);
1739 	char	input[RTW_IWD_MAX_LEN];
1740 	int	qAutoLoad = 1;
1741 	//struct efuse_info *efuse = adapter_to_efuse(padapter);
1742 
1743 	if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
1744 		return -EFAULT;
1745 	RTW_INFO("%s:iwpriv in=%s\n", __func__, input);
1746 
1747 	qAutoLoad = strncmp(input, "autoload", 8); /* strncmp TRUE is 0*/
1748 
1749 	if (qAutoLoad == 0) {
1750 		RTW_INFO("%s:qAutoLoad\n", __func__);
1751 
1752 		//if (efuse->is_autoload_fail)
1753 		//	sprintf(extra, "fail");
1754 		//else
1755 		//	sprintf(extra, "ok");
1756 	}
1757 	wrqu->data.length = strlen(extra) + 1;
1758 	return 0;
1759 }
1760 
1761 
rtw_mp_PwrCtlDM(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1762 int rtw_mp_PwrCtlDM(struct net_device *dev,
1763 		    struct iw_request_info *info,
1764 		    struct iw_point *wrqu, char *extra)
1765 {
1766 	_adapter *padapter = rtw_netdev_priv(dev);
1767 	u8		input[RTW_IWD_MAX_LEN];
1768 	u8		pwrtrk_state = 0;
1769 	u8		pwtk_type[5][25] = {"Thermal tracking off","Thermal tracking on",
1770 					"TSSI tracking off","TSSI tracking on","TSSI calibration"};
1771 
1772 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1773 		return -EFAULT;
1774 
1775 	input[wrqu->length] = '\0';
1776 	RTW_INFO("%s: in=%s\n", __func__, input);
1777 
1778 	if (wrqu->length == 2) {
1779 		if(input[0] >= '0' && input[0] <= '4') {
1780 			pwrtrk_state = rtw_atoi(input);
1781 			/*MPT_PwrCtlDM(padapter, pwrtrk_state);*/
1782 			sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1783 		} else {
1784 			sprintf(extra, "Error unknown number ! Please check your input number\n"
1785 				" 0 : Thermal tracking off\n 1 : Thermal tracking on\n 2 : TSSI tracking off\n"
1786 				" 3 : TSSI tracking on\n 4 : TSSI calibration\n");
1787 		}
1788 		wrqu->length = strlen(extra);
1789 
1790 		return 0;
1791 	}
1792 	if (strncmp(input, "start", 5) == 0 || strncmp(input, "thertrk on", 10) == 0) {/* strncmp TRUE is 0*/
1793 		pwrtrk_state = 1;
1794 		sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1795 	} else if (strncmp(input, "thertrk off", 11) == 0 || strncmp(input, "stop", 5) == 0) {
1796 		pwrtrk_state = 0;
1797 		sprintf(extra, "PwrCtlDM stop %s\n" , pwtk_type[pwrtrk_state]);
1798 	} else if (strncmp(input, "tssitrk off", 11) == 0){
1799 		pwrtrk_state = 2;
1800 		sprintf(extra, "PwrCtlDM stop %s\n" , pwtk_type[pwrtrk_state]);
1801 	} else if (strncmp(input, "tssitrk on", 10) == 0){
1802 		pwrtrk_state = 3;
1803 		sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1804 	} else if (strncmp(input, "tssik", 5) == 0){
1805 		pwrtrk_state = 4;
1806 		sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1807 	} else {
1808 		pwrtrk_state = 0;
1809 		sprintf(extra, "Error input, default PwrCtlDM stop\n"
1810 			" thertrk off : Thermal tracking off\n thertrk on : Thermal tracking on\n"
1811 			" tssitrk off : TSSI tracking off\n tssitrk on : TSSI tracking on\n tssik : TSSI calibration\n\n"
1812 			" 0 : Thermal tracking off\n 1 : Thermal tracking on\n 2 : TSSI tracking off\n"
1813 			" 3 : TSSI tracking on\n 4 : TSSI calibration\n");
1814 	}
1815 
1816 	/*MPT_PwrCtlDM(padapter, pwrtrk_state);*/
1817 	wrqu->length = strlen(extra);
1818 
1819 	return 0;
1820 }
1821 
rtw_mp_iqk(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1822 int rtw_mp_iqk(struct net_device *dev,
1823 		 struct iw_request_info *info,
1824 		 struct iw_point *wrqu, char *extra)
1825 {
1826 	_adapter *padapter = rtw_netdev_priv(dev);
1827 
1828 	rtw_mp_trigger_iqk(padapter);
1829 
1830 	return 0;
1831 }
1832 
rtw_mp_lck(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1833 int rtw_mp_lck(struct net_device *dev,
1834 		 struct iw_request_info *info,
1835 		 struct iw_point *wrqu, char *extra)
1836 {
1837 	_adapter *padapter = rtw_netdev_priv(dev);
1838 
1839 	rtw_mp_trigger_lck(padapter);
1840 
1841 	return 0;
1842 }
1843 
rtw_mp_dpk(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1844 int rtw_mp_dpk(struct net_device *dev,
1845 			struct iw_request_info *info,
1846 			union iwreq_data *wrqu, char *extra)
1847 {
1848 	_adapter *padapter = rtw_netdev_priv(dev);
1849 	//struct dm_struct *phydm = adapter_to_phydm(padapter);
1850 	struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
1851 
1852 	u8 ips_mode = IPS_NUM; /* init invalid value */
1853 	u8 lps_mode = PM_PS_MODE_NUM; /* init invalid value */
1854 
1855 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
1856 		return -EFAULT;
1857 
1858 	*(extra + wrqu->data.length) = '\0';
1859 
1860 	if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
1861 			//phydm->dpk_info.is_dpk_enable = 0;
1862 			//halrf_dpk_enable_disable(phydm);
1863 			sprintf(extra, "set dpk off\n");
1864 
1865 	} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
1866 			//phydm->dpk_info.is_dpk_enable = 1;
1867 			//halrf_dpk_enable_disable(phydm);
1868 			sprintf(extra, "set dpk on\n");
1869 	} else	{
1870 #ifdef CONFIG_LPS
1871 			lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */
1872 			rtw_pm_set_lps(padapter, PM_PS_MODE_ACTIVE);
1873 #endif
1874 #ifdef CONFIG_IPS
1875 			ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
1876 			rtw_pm_set_ips(padapter, IPS_NONE);
1877 #endif
1878 			rtw_mp_trigger_dpk(padapter);
1879 	if (padapter->registrypriv.mp_mode == 0) {
1880 #ifdef CONFIG_IPS
1881 			rtw_pm_set_ips(padapter, ips_mode);
1882 #endif /* CONFIG_IPS */
1883 
1884 #ifdef CONFIG_LPS
1885 			rtw_pm_set_lps(padapter, lps_mode);
1886 #endif /* CONFIG_LPS */
1887 	}
1888 			sprintf(extra, "set dpk trigger\n");
1889 	}
1890 
1891 	wrqu->data.length = strlen(extra);
1892 
1893 	return 0;
1894 }
1895 
rtw_mp_get_tsside(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1896 int rtw_mp_get_tsside(struct net_device *dev,
1897 			 struct iw_request_info *info,
1898 			 struct iw_point *wrqu, char *extra)
1899 {
1900 	_adapter *padapter = rtw_netdev_priv(dev);
1901 	char input[RTW_IWD_MAX_LEN];
1902 	u8 rfpath = 0xff;
1903 	s8 tssi_de = 0;
1904 	char pout_str_buf[7];
1905 	char tgr_str_buf[7];
1906 	u8 pout_signed_flag = 0 , tgrpwr_signed_flag = 0;
1907 	int int_num = 0;
1908 	u32 dec_num = 0;
1909 	s32 pout = 0;
1910 	s32 tgrpwr = 0;
1911 	int i;
1912 
1913 	if (wrqu->length > 128)
1914 		return -EFAULT;
1915 
1916 	_rtw_memset(input, 0, sizeof(input));
1917 
1918 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
1919 		return -EFAULT;
1920 	input[wrqu->length] = '\0';
1921 
1922 	if (wrqu->length == 2) {
1923 		rfpath = rtw_atoi(input);
1924 		if (rfpath >= 0 && rfpath <= 3) {
1925 			tssi_de = rtw_mp_get_tssi_de(padapter, rfpath);
1926 		} else
1927 			sprintf(extra, "Invalid command format, please indicate RF path 0/1/2/3");
1928 
1929 	} else if (sscanf(input + 1, "dbm=%7s pwr=%7s", tgr_str_buf , pout_str_buf) == 2) {
1930 		/*
1931 		* rtwpriv wlan0 mp_get_tsside adbm=12 pwr=12
1932 		* [adbm] target power [pwr] output power
1933 		* rf_path : 0 = adbm , 1 = bdbm
1934 		* dbm : -15.00 ~ 25.00
1935 		* pwr : -15.00 ~ 25.00
1936 		* ex : rtwpriv wlan0 mp_get_tsside adbm=16 pwr=14.25
1937 		*/
1938 		RTW_INFO("%s: in=tgr_str %s  pout_str %s\n", __func__, tgr_str_buf , pout_str_buf);
1939 		switch (input[0]) {
1940 		case 'a':
1941 			rfpath = RF_PATH_A;
1942 			break;
1943 		case 'b':
1944 			rfpath = RF_PATH_B;
1945 			break;
1946 		case 'c':
1947 			rfpath = RF_PATH_C;
1948 			break;
1949 		case 'd':
1950 			rfpath = RF_PATH_D;
1951 			break;
1952 		default:
1953 			goto error;
1954 			break;
1955 		}
1956 
1957 		if(pout_str_buf[0] == '-')
1958 			pout_signed_flag = 1;
1959 
1960 		i = sscanf(pout_str_buf, "%d.%2u", &int_num, &dec_num);
1961 		pout = int_num * 100;
1962 		RTW_DBG("%s:pout %d int %d dec %d\n", __func__, pout, int_num , dec_num);
1963 
1964 		if (i == 2) {
1965 			/* Convert decimal number
1966 			 * ex : 0.1 => 100, -0.1 => 100*/
1967 			dec_num = (dec_num < 1) ? dec_num * 10 : dec_num;
1968 			dec_num = (dec_num < 10) ? dec_num * 1 : dec_num;
1969 			pout += ((pout < 0 || pout_signed_flag == 1) ? -dec_num : dec_num);
1970 		}
1971 		if (pout < -1500 || 2500 < pout)
1972 			goto error;
1973 		RTW_INFO("%s:pout %d\n", __func__, pout);
1974 
1975 		if (tgr_str_buf[0] == '-')
1976 			tgrpwr_signed_flag = 1;
1977 
1978 		int_num = 0;
1979 		dec_num = 0;
1980 
1981 		i = sscanf(tgr_str_buf, "%d.%2u", &int_num, &dec_num);
1982 		tgrpwr = int_num * 100;
1983 		RTW_DBG("%s:tgrpwr %d int %d dec %d\n", __func__, tgrpwr, int_num , dec_num);
1984 
1985 		if (i == 2) {
1986 			/* Convert decimal number
1987 			 * ex : 0.1 => 100, -0.1 => 100*/
1988 			dec_num = (dec_num < 1) ? dec_num * 10 : dec_num;
1989 			dec_num = (dec_num < 10) ? dec_num * 1 : dec_num;
1990 			tgrpwr += ((tgrpwr < 0 || tgrpwr_signed_flag == 1) ? -dec_num : dec_num);
1991 		}
1992 		if (tgrpwr < -1500 || 2500 < tgrpwr)
1993 			goto error;
1994 		RTW_INFO("%s:tgrpwr %d\n", __func__, tgrpwr);
1995 
1996 		tssi_de = (s8)rtw_mp_get_online_tssi_de(padapter, pout, tgrpwr, rfpath);
1997 	}
1998 
1999 	if (rfpath == 0)
2000 		sprintf(extra, "patha=%d hex:%x", tssi_de, (u8)tssi_de);
2001 	else if (rfpath == 1)
2002 		sprintf(extra, "pathb=%d hex:%x", tssi_de, (u8)tssi_de);
2003 	else if (rfpath == 2)
2004 		sprintf(extra, "pathc=%d hex:%x", tssi_de, (u8)tssi_de);
2005 	else if (rfpath == 3)
2006 		sprintf(extra, "pathd=%d hex:%x", tssi_de, (u8)tssi_de);
2007 	else
2008 		goto error;
2009 
2010 	wrqu->length = strlen(extra);
2011 	return 0;
2012 error:
2013 
2014 	sprintf(extra, "Invalid command format, please indicate RF path mp_get_tsside [0/1/2/3]\n\
2015 			GET ONLINE TSSI DE:\n\
2016 			mp_get_tsside adbm=-15.00 ~ 25.00 pwr=-15.00 ~ 25.00\n\
2017 			mp_get_tsside bdbm=-15.00 ~ 25.00 pwr=-15.00 ~ 25.00\n");
2018 	wrqu->length = strlen(extra);
2019 
2020 	return 0;
2021 }
2022 
rtw_mp_set_tsside(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)2023 int rtw_mp_set_tsside(struct net_device *dev,
2024 		   struct iw_request_info *info,
2025 		   struct iw_point *wrqu, char *extra)
2026 {
2027 	int tsside_val = 0;
2028 	u8 rf_path = RF_PATH_A;
2029 	char input[RTW_IWD_MAX_LEN];
2030 
2031 	_adapter *padapter = rtw_netdev_priv(dev);
2032 
2033 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
2034 		return -EFAULT;
2035 
2036 	RTW_INFO("%s:input =[%s]\n", __func__, input);
2037 
2038 	switch (input[4]) {
2039 	case 'a':
2040 		rf_path = RF_PATH_A;
2041 		break;
2042 	case 'b':
2043 		rf_path = RF_PATH_B;
2044 		break;
2045 	case 'c':
2046 		rf_path = RF_PATH_C;
2047 		break;
2048 	case 'd':
2049 		rf_path = RF_PATH_D;
2050 		break;
2051 	default:
2052 		goto exit_err;
2053 	}
2054 
2055 	if ((sscanf(input+5, "=0x%x", &tsside_val) == 1) ||
2056 		(sscanf(input+5, "=%d", &tsside_val) == 1)) {
2057 
2058 		RTW_INFO("%s:got tsside val =[%d] 0x%x\n", __func__, tsside_val, (u32)tsside_val);
2059 		if (tsside_val > 255)
2060 			sprintf(extra, "Error TSSI DE value: %d" , tsside_val);
2061 		else {
2062 			sprintf(extra, "Set TSSI DE path_%s: %d",
2063 				rf_path == RF_PATH_A ? "A" : rf_path == RF_PATH_B ? "B" :
2064 				rf_path == RF_PATH_C ? "C":"D", tsside_val);
2065 			rtw_mp_set_tsside2verify(padapter, (u32)tsside_val, rf_path);
2066 		}
2067 	} else
2068 		goto exit_err;
2069 
2070 	wrqu->length = strlen(extra);
2071 
2072 	return 0;
2073 
2074 exit_err:
2075 	sprintf(extra, "Invalid command format,\n\t\t"
2076 			"please input TSSI DE value within patha/b/c/d=[decimal] or [hex:0xXX]");
2077 
2078 	wrqu->length = strlen(extra);
2079 
2080 	return 0;
2081 }
2082 
rtw_mp_getver(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2083 int rtw_mp_getver(struct net_device *dev,
2084 		  struct iw_request_info *info,
2085 		  union iwreq_data *wrqu, char *extra)
2086 {
2087 	_adapter *padapter = rtw_netdev_priv(dev);
2088 	struct mp_priv *pmp_priv;
2089 
2090 	pmp_priv = &padapter->mppriv;
2091 
2092 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2093 		return -EFAULT;
2094 
2095 	sprintf(extra, "rtwpriv=%d\n", RTWPRIV_VER_INFO);
2096 	wrqu->data.length = strlen(extra);
2097 	return 0;
2098 }
2099 
2100 
rtw_mp_mon(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2101 int rtw_mp_mon(struct net_device *dev,
2102 	       struct iw_request_info *info,
2103 	       union iwreq_data *wrqu, char *extra)
2104 {
2105 	_adapter *padapter = rtw_netdev_priv(dev);
2106 	struct mp_priv *pmp_priv = &padapter->mppriv;
2107 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2108 	//struct hal_ops *pHalFunc = &hal->hal_func;
2109 	NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
2110 	int bstart = 1, bstop = 1;
2111 
2112 	networkType = Ndis802_11Infrastructure;
2113 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2114 		return -EFAULT;
2115 
2116 	*(extra + wrqu->data.length) = '\0';
2117 	rtw_pm_set_ips(padapter, IPS_NONE);
2118 	LeaveAllPowerSaveMode(padapter);
2119 
2120 #if 0 //def CONFIG_MP_INCLUDED
2121 	if (init_mp_priv(padapter) == _FAIL)
2122 		RTW_INFO("%s: initialize MP private data Fail!\n", __func__);
2123 	padapter->mppriv.channel = 6;
2124 
2125 	bstart = strncmp(extra, "start", 5); /* strncmp TRUE is 0*/
2126 	bstop = strncmp(extra, "stop", 4); /* strncmp TRUE is 0*/
2127 	if (bstart == 0) {
2128 		mp_join(padapter, WIFI_FW_ADHOC_STATE);
2129 		SetPacketRx(padapter, _TRUE, _FALSE);
2130 		SetChannel(padapter);
2131 		pmp_priv->rx_bindicatePkt = _TRUE;
2132 		pmp_priv->bRTWSmbCfg = _TRUE;
2133 		sprintf(extra, "monitor mode start\n");
2134 	} else if (bstop == 0) {
2135 		SetPacketRx(padapter, _FALSE, _FALSE);
2136 		pmp_priv->rx_bindicatePkt = _FALSE;
2137 		pmp_priv->bRTWSmbCfg = _FALSE;
2138 		padapter->registrypriv.mp_mode = 1;
2139 		pHalFunc->hal_deinit(padapter);
2140 		padapter->registrypriv.mp_mode = 0;
2141 		pHalFunc->hal_init(padapter);
2142 		/*rtw_disassoc_cmd(padapter, 0, 0);*/
2143 		if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
2144 			rtw_disassoc_cmd(padapter, 500, 0);
2145 			rtw_indicate_disconnect(padapter, 0, _FALSE);
2146 			/*rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);*/
2147 		}
2148 		rtw_pm_set_ips(padapter, IPS_NORMAL);
2149 		sprintf(extra, "monitor mode Stop\n");
2150 	}
2151 #endif
2152 	wrqu->data.length = strlen(extra);
2153 	return 0;
2154 }
2155 
rtw_mp_pretx_proc(_adapter * padapter,u8 bstart,char * extra)2156 int rtw_mp_pretx_proc(_adapter *padapter, u8 bstart, char *extra)
2157 {
2158 	struct mp_priv *pmp_priv = &padapter->mppriv;
2159 	char *pextra = extra;
2160 
2161 	switch (pmp_priv->mode) {
2162 
2163 	case MP_PACKET_TX:
2164 		if (bstart == 0) {
2165 			pmp_priv->tx.stop = 1;
2166 			pmp_priv->mode = MP_ON;
2167 			sprintf(extra, "Stop continuous Tx");
2168 		} else if (pmp_priv->tx.stop == 1) {
2169 			pextra = extra + strlen(extra);
2170 			pextra += sprintf(pextra, "\nStart continuous DA=ffffffffffff len=1500 count=%u\n", pmp_priv->tx.count);
2171 			pmp_priv->tx.stop = 0;
2172 			/*SetPacketTx(padapter);*/
2173 		} else
2174 			return -EFAULT;
2175 		rtw_set_phl_packet_tx(padapter, bstart);
2176 		return 0;
2177 	case MP_SINGLE_TONE_TX:
2178 		if (bstart != 0)
2179 			strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2180 
2181 		rtw_mp_singletone_tx(padapter, (u8)bstart);
2182 		break;
2183 	case MP_CONTINUOUS_TX:
2184 		if (bstart != 0)
2185 			strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2186 		rtw_mp_continuous_tx(padapter, (u8)bstart);
2187 		break;
2188 	case MP_CARRIER_SUPPRISSION_TX:
2189 		if (bstart != 0) {
2190 			if (rtw_mp_hwrate2mptrate(pmp_priv->rateidx) <= MPT_RATE_11M)
2191 				strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2192 			else
2193 				strcat(extra, "\nSpecify carrier suppression but not CCK rate");
2194 		}
2195 		rtw_mp_carriersuppr_tx(padapter, (u8)bstart);
2196 		break;
2197 	case MP_SINGLE_CARRIER_TX:
2198 		if (bstart != 0)
2199 			strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2200 		rtw_mp_singlecarrier_tx(padapter, (u8)bstart);
2201 		break;
2202 	default:
2203 		sprintf(extra, "Error! Continuous-Tx is not on-going.");
2204 		return -EFAULT;
2205 	}
2206 
2207 	if (bstart == 1 && pmp_priv->mode != MP_ON) {
2208 		struct mp_priv *pmp_priv = &padapter->mppriv;
2209 
2210 		if (pmp_priv->tx.stop == 0) {
2211 			pmp_priv->tx.stop = 1;
2212 			rtw_msleep_os(5);
2213 		}
2214 #ifdef CONFIG_80211N_HT
2215 		if(padapter->registrypriv.ht_enable &&
2216 			is_supported_ht(padapter->registrypriv.wireless_mode))
2217 			pmp_priv->tx.attrib.ht_en = 1;
2218 #endif
2219 		pmp_priv->tx.stop = 0;
2220 		pmp_priv->tx.count = 1;
2221 		if (pmp_priv->rtw_mp_tx_method == RTW_MP_PMACT_TX) {
2222 			pmp_priv->rtw_mp_tx_method = RTW_MP_TMACT_TX;
2223 			rtw_set_phl_packet_tx(padapter, bstart); /* send 1 pkt for trigger HW non-pkt Tx*/
2224 			pmp_priv->rtw_mp_tx_method = RTW_MP_PMACT_TX;
2225 		}
2226 		/*SetPacketTx(padapter);*/
2227 	} else
2228 		pmp_priv->mode = MP_ON;
2229 
2230 	return 0;
2231 }
2232 
2233 
rtw_mp_tx(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2234 int rtw_mp_tx(struct net_device *dev,
2235 	      struct iw_request_info *info,
2236 	      union iwreq_data *wrqu, char *extra)
2237 {
2238 	_adapter *padapter = rtw_netdev_priv(dev);
2239 	struct mp_priv *pmp_priv = &padapter->mppriv;
2240 	PMPT_CONTEXT		pMptCtx = &(padapter->mppriv.mpt_ctx);
2241 	char *pextra = extra;
2242 	u32 bandwidth = 0, sg = 0, channel = 6, txpower = 40, rate = 108, ant = 0, txmode = 1, count = 0;
2243 	u8 bStartTest = 1, status = 0;
2244 #ifdef CONFIG_MP_VHT_HW_TX_MODE
2245 	u8 Idx = 0, tmpU1B;
2246 #endif
2247 	u16 antenna = 0;
2248 
2249 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2250 		return -EFAULT;
2251 	RTW_INFO("extra = %s\n", extra);
2252 #if 0
2253 #ifdef CONFIG_CONCURRENT_MODE
2254 	if (!is_primary_adapter(padapter)) {
2255 		sprintf(extra, "Error: MP mode can't support Virtual adapter, Please to use main adapter.\n");
2256 		wrqu->data.length = strlen(extra);
2257 		return 0;
2258 	}
2259 #endif
2260 
2261 	if (strncmp(extra, "stop", 3) == 0) {
2262 		bStartTest = 0; /* To set Stop*/
2263 		pmp_priv->tx.stop = 1;
2264 		sprintf(extra, "Stop continuous Tx");
2265 		status = rtw_mp_pretx_proc(padapter, bStartTest, extra);
2266 		wrqu->data.length = strlen(extra);
2267 		return status;
2268 	} else if (strncmp(extra, "count", 5) == 0) {
2269 		if (sscanf(extra, "count=%d", &count) < 1)
2270 			RTW_INFO("Got Count=%d]\n", count);
2271 		pmp_priv->tx.count = count;
2272 		return 0;
2273 	} else if (strncmp(extra, "setting", 7) == 0) {
2274 		_rtw_memset(extra, 0, wrqu->data.length);
2275 		pextra += sprintf(pextra, "Current Setting :\n Channel:%d", pmp_priv->channel);
2276 		pextra += sprintf(pextra, "\n Bandwidth:%d", pmp_priv->bandwidth);
2277 		pextra += sprintf(pextra, "\n Rate index:%d", pmp_priv->rateidx);
2278 		pextra += sprintf(pextra, "\n TxPower index:%d", pmp_priv->txpoweridx);
2279 		pextra += sprintf(pextra, "\n Antenna TxPath:%d", pmp_priv->antenna_tx);
2280 		pextra += sprintf(pextra, "\n Antenna RxPath:%d", pmp_priv->antenna_rx);
2281 		pextra += sprintf(pextra, "\n MP Mode:%d", pmp_priv->mode);
2282 		wrqu->data.length = strlen(extra);
2283 		return 0;
2284 #ifdef CONFIG_MP_VHT_HW_TX_MODE
2285 	} else if (strncmp(extra, "pmact", 5) == 0) {
2286 		if (strncmp(extra, "pmact=", 6) == 0) {
2287 			_rtw_memset(&pMptCtx->PMacTxInfo, 0, sizeof(pMptCtx->PMacTxInfo));
2288 			if (strncmp(extra, "pmact=start", 11) == 0) {
2289 				pMptCtx->PMacTxInfo.bEnPMacTx = _TRUE;
2290 				sprintf(extra, "Set PMac Tx Mode start\n");
2291 			} else {
2292 				pMptCtx->PMacTxInfo.bEnPMacTx = _FALSE;
2293 				sprintf(extra, "Set PMac Tx Mode Stop\n");
2294 			}
2295 			if (pMptCtx->bldpc == TRUE)
2296 				pMptCtx->PMacTxInfo.bLDPC = _TRUE;
2297 
2298 			if (pMptCtx->bstbc == TRUE)
2299 				pMptCtx->PMacTxInfo.bSTBC = _TRUE;
2300 
2301 			pMptCtx->PMacTxInfo.bSPreamble = pmp_priv->preamble;
2302 			pMptCtx->PMacTxInfo.bSGI = pmp_priv->preamble;
2303 			pMptCtx->PMacTxInfo.BandWidth = pmp_priv->bandwidth;
2304 			pMptCtx->PMacTxInfo.TX_RATE = HwRateToMPTRate(pmp_priv->rateidx);
2305 
2306 			pMptCtx->PMacTxInfo.Mode = pMptCtx->HWTxmode;
2307 
2308 			pMptCtx->PMacTxInfo.NDP_sound = FALSE;/*(adapter.PacketType == NDP_PKT)?TRUE:FALSE;*/
2309 
2310 			if (padapter->mppriv.pktInterval == 0)
2311 				pMptCtx->PMacTxInfo.PacketPeriod = 100;
2312 			else
2313 				pMptCtx->PMacTxInfo.PacketPeriod = padapter->mppriv.pktInterval;
2314 
2315 			if (padapter->mppriv.pktLength < 1000)
2316 				pMptCtx->PMacTxInfo.PacketLength = 1000;
2317 			else
2318 				pMptCtx->PMacTxInfo.PacketLength = padapter->mppriv.pktLength;
2319 
2320 			pMptCtx->PMacTxInfo.PacketPattern  = rtw_random32() % 0xFF;
2321 
2322 			if (padapter->mppriv.tx_pktcount != 0)
2323 				pMptCtx->PMacTxInfo.PacketCount = padapter->mppriv.tx_pktcount;
2324 
2325 			pMptCtx->PMacTxInfo.Ntx = 0;
2326 			for (Idx = 16; Idx < 20; Idx++) {
2327 				tmpU1B = (padapter->mppriv.antenna_tx >> Idx) & 1;
2328 				if (tmpU1B)
2329 					pMptCtx->PMacTxInfo.Ntx++;
2330 			}
2331 
2332 			_rtw_memset(pMptCtx->PMacTxInfo.MacAddress, 0xFF, ETH_ALEN);
2333 
2334 			PMAC_Get_Pkt_Param(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2335 
2336 			if (MPT_IS_CCK_RATE(pMptCtx->PMacTxInfo.TX_RATE))
2337 
2338 				CCK_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2339 			else {
2340 				PMAC_Nsym_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2341 				/* 24 BIT*/
2342 				L_SIG_generator(pMptCtx->PMacPktInfo.N_sym, &pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2343 			}
2344 			/*	48BIT*/
2345 			if (MPT_IS_HT_RATE(pMptCtx->PMacTxInfo.TX_RATE))
2346 				HT_SIG_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2347 			else if (MPT_IS_VHT_RATE(pMptCtx->PMacTxInfo.TX_RATE)) {
2348 				/*	48BIT*/
2349 				VHT_SIG_A_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2350 
2351 				/*	26/27/29 BIT  & CRC 8 BIT*/
2352 				VHT_SIG_B_generator(&pMptCtx->PMacTxInfo);
2353 
2354 				/* 32 BIT*/
2355 				VHT_Delimiter_generator(&pMptCtx->PMacTxInfo);
2356 			}
2357 
2358 			mpt_ProSetPMacTx(padapter);
2359 
2360 		} else if (strncmp(extra, "pmact,mode=", 11) == 0) {
2361 			int txmode = 0;
2362 
2363 			if (sscanf(extra, "pmact,mode=%d", &txmode) > 0) {
2364 				if (txmode == 1) {
2365 					pMptCtx->HWTxmode = CONTINUOUS_TX;
2366 					sprintf(extra, "\t Config HW Tx mode = CONTINUOUS_TX\n");
2367 				} else if (txmode == 2) {
2368 					pMptCtx->HWTxmode = OFDM_Single_Tone_TX;
2369 					sprintf(extra, "\t Config HW Tx mode = OFDM_Single_Tone_TX\n");
2370 				} else {
2371 					pMptCtx->HWTxmode = PACKETS_TX;
2372 					sprintf(extra, "\t Config HW Tx mode = PACKETS_TX\n");
2373 				}
2374 			} else {
2375 				pMptCtx->HWTxmode = PACKETS_TX;
2376 				sprintf(extra, "\t Config HW Tx mode=\n 0 = PACKETS_TX\n 1 = CONTINUOUS_TX\n 2 = OFDM_Single_Tone_TX");
2377 			}
2378 		} else if (strncmp(extra, "pmact,", 6) == 0) {
2379 			int PacketPeriod = 0, PacketLength = 0, PacketCout = 0;
2380 			int bldpc = 0, bstbc = 0;
2381 
2382 			if (sscanf(extra, "pmact,period=%d", &PacketPeriod) > 0) {
2383 				padapter->mppriv.pktInterval = PacketPeriod;
2384 				RTW_INFO("PacketPeriod=%d\n", padapter->mppriv.pktInterval);
2385 				sprintf(extra, "PacketPeriod [1~255]= %d\n", padapter->mppriv.pktInterval);
2386 
2387 			} else if (sscanf(extra, "pmact,length=%d", &PacketLength) > 0) {
2388 				padapter->mppriv.pktLength = PacketLength;
2389 				RTW_INFO("PacketPeriod=%d\n", padapter->mppriv.pktLength);
2390 				sprintf(extra, "PacketLength[~65535]=%d\n", padapter->mppriv.pktLength);
2391 
2392 			} else if (sscanf(extra, "pmact,count=%d", &PacketCout) > 0) {
2393 				padapter->mppriv.tx_pktcount = PacketCout;
2394 				RTW_INFO("Packet Cout =%d\n", padapter->mppriv.tx_pktcount);
2395 				sprintf(extra, "Packet Cout =%d\n", padapter->mppriv.tx_pktcount);
2396 
2397 			} else if (sscanf(extra, "pmact,ldpc=%d", &bldpc) > 0) {
2398 				pMptCtx->bldpc = bldpc;
2399 				RTW_INFO("Set LDPC =%d\n", pMptCtx->bldpc);
2400 				sprintf(extra, "Set LDPC =%d\n", pMptCtx->bldpc);
2401 
2402 			} else if (sscanf(extra, "pmact,stbc=%d", &bstbc) > 0) {
2403 				pMptCtx->bstbc = bstbc;
2404 				RTW_INFO("Set STBC =%d\n", pMptCtx->bstbc);
2405 				sprintf(extra, "Set STBC =%d\n", pMptCtx->bstbc);
2406 			} else
2407 				sprintf(extra, "\n period={1~255}\n length={1000~65535}\n count={0~}\n ldpc={0/1}\n stbc={0/1}");
2408 
2409 		}
2410 
2411 		wrqu->data.length = strlen(extra);
2412 		return 0;
2413 #endif
2414 	} else {
2415 
2416 		if (sscanf(extra, "ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d", &channel, &bandwidth, &rate, &txpower, &ant, &txmode) < 6) {
2417 			RTW_INFO("Invalid format [ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d]\n", channel, bandwidth, rate, txpower, ant, txmode);
2418 			_rtw_memset(extra, 0, wrqu->data.length);
2419 			pextra += sprintf(pextra, "\n Please input correct format as bleow:\n");
2420 			pextra += sprintf(pextra, "\t ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d\n", channel, bandwidth, rate, txpower, ant, txmode);
2421 			pextra += sprintf(pextra, "\n [ ch : BGN = <1~14> , A or AC = <36~165> ]");
2422 			pextra += sprintf(pextra, "\n [ bw : Bandwidth: 0 = 20M, 1 = 40M, 2 = 80M ]");
2423 			pextra += sprintf(pextra, "\n [ rate :	CCK: 1 2 5.5 11M X 2 = < 2 4 11 22 >]");
2424 			pextra += sprintf(pextra, "\n [		OFDM: 6 9 12 18 24 36 48 54M X 2 = < 12 18 24 36 48 72 96 108>");
2425 			pextra += sprintf(pextra, "\n [		HT 1S2SS MCS0 ~ MCS15 : < [MCS0]=128 ~ [MCS7]=135 ~ [MCS15]=143 >");
2426 			pextra += sprintf(pextra, "\n [		HT 3SS MCS16 ~ MCS32 : < [MCS16]=144 ~ [MCS23]=151 ~ [MCS32]=159 >");
2427 			pextra += sprintf(pextra, "\n [		VHT 1SS MCS0 ~ MCS9 : < [MCS0]=160 ~ [MCS9]=169 >");
2428 			pextra += sprintf(pextra, "\n [ txpower : 1~63 power index");
2429 			pextra += sprintf(pextra, "\n [ ant : <A = 1, B = 2, C = 4, D = 8> ,2T ex: AB=3 BC=6 CD=12");
2430 			pextra += sprintf(pextra, "\n [ txmode : < 0 = CONTINUOUS_TX, 1 = PACKET_TX, 2 = SINGLE_TONE_TX, 3 = CARRIER_SUPPRISSION_TX, 4 = SINGLE_CARRIER_TX>\n");
2431 			wrqu->data.length = strlen(extra);
2432 			return status;
2433 
2434 		} else {
2435 			char *pextra = extra;
2436 			RTW_INFO("Got format [ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d]\n", channel, bandwidth, rate, txpower, ant, txmode);
2437 			_rtw_memset(extra, 0, wrqu->data.length);
2438 			sprintf(extra, "Change Current channel %d to channel %d", padapter->mppriv.channel , channel);
2439 			padapter->mppriv.channel = channel;
2440 			SetChannel(padapter);
2441 			pHalData->current_channel = channel;
2442 
2443 			if (bandwidth == 1)
2444 				bandwidth = CHANNEL_WIDTH_40;
2445 			else if (bandwidth == 2)
2446 				bandwidth = CHANNEL_WIDTH_80;
2447 			pextra = extra + strlen(pextra);
2448 			pextra += sprintf(pextra, "\nChange Current Bandwidth %d to Bandwidth %d", padapter->mppriv.bandwidth, bandwidth);
2449 			padapter->mppriv.bandwidth = (u8)bandwidth;
2450 			padapter->mppriv.preamble = sg;
2451 			SetBandwidth(padapter);
2452 			pHalData->current_channel_bw = bandwidth;
2453 
2454 			pextra += sprintf(pextra, "\nSet power level :%d", txpower);
2455 			padapter->mppriv.txpoweridx = (u8)txpower;
2456 			pMptCtx->TxPwrLevel[RF_PATH_A] = (u8)txpower;
2457 			pMptCtx->TxPwrLevel[RF_PATH_B] = (u8)txpower;
2458 			pMptCtx->TxPwrLevel[RF_PATH_C] = (u8)txpower;
2459 			pMptCtx->TxPwrLevel[RF_PATH_D]  = (u8)txpower;
2460 			SetTxPower(padapter);
2461 
2462 			RTW_INFO("%s: bw=%d sg=%d\n", __func__, bandwidth, sg);
2463 
2464 			if (rate <= 0x7f)
2465 				rate = wifirate2_ratetbl_inx((u8)rate);
2466 			else if (rate < 0xC8)
2467 				rate = (rate - 0x80 + MPT_RATE_MCS0);
2468 			/*HT  rate 0x80(MCS0)  ~ 0x8F(MCS15) ~ 0x9F(MCS31) 128~159
2469 			VHT1SS~2SS rate 0xA0 (VHT1SS_MCS0 44) ~ 0xB3 (VHT2SS_MCS9 #63) 160~179
2470 			VHT rate 0xB4 (VHT3SS_MCS0 64) ~ 0xC7 (VHT2SS_MCS9 #83) 180~199
2471 			else
2472 			VHT rate 0x90(VHT1SS_MCS0) ~ 0x99(VHT1SS_MCS9) 144~153
2473 			rate =(rate - MPT_RATE_VHT1SS_MCS0);
2474 			*/
2475 			RTW_INFO("%s: rate index=%d\n", __func__, rate);
2476 			if (rate >= MPT_RATE_LAST)
2477 				return -EINVAL;
2478 			pextra += sprintf(pextra, "\nSet data rate to %d index %d", padapter->mppriv.rateidx, rate);
2479 
2480 			padapter->mppriv.rateidx = rate;
2481 			pMptCtx->mpt_rate_index = rate;
2482 			SetDataRate(padapter);
2483 
2484 			pextra += sprintf(pextra, "\nSet Antenna Path :%d", ant);
2485 			switch (ant) {
2486 			case 1:
2487 				antenna = ANTENNA_A;
2488 				break;
2489 			case 2:
2490 				antenna = ANTENNA_B;
2491 				break;
2492 			case 4:
2493 				antenna = ANTENNA_C;
2494 				break;
2495 			case 8:
2496 				antenna = ANTENNA_D;
2497 				break;
2498 			case 3:
2499 				antenna = ANTENNA_AB;
2500 				break;
2501 			case 5:
2502 				antenna = ANTENNA_AC;
2503 				break;
2504 			case 9:
2505 				antenna = ANTENNA_AD;
2506 				break;
2507 			case 6:
2508 				antenna = ANTENNA_BC;
2509 				break;
2510 			case 10:
2511 				antenna = ANTENNA_BD;
2512 				break;
2513 			case 12:
2514 				antenna = ANTENNA_CD;
2515 				break;
2516 			case 7:
2517 				antenna = ANTENNA_ABC;
2518 				break;
2519 			case 14:
2520 				antenna = ANTENNA_BCD;
2521 				break;
2522 			case 11:
2523 				antenna = ANTENNA_ABD;
2524 				break;
2525 			case 15:
2526 				antenna = ANTENNA_ABCD;
2527 				break;
2528 			}
2529 			RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);
2530 			padapter->mppriv.antenna_tx = antenna;
2531 			padapter->mppriv.antenna_rx = antenna;
2532 			pHalData->antenna_tx_path = antenna;
2533 			SetAntenna(padapter);
2534 
2535 			if (txmode == 0)
2536 				pmp_priv->mode = MP_CONTINUOUS_TX;
2537 			else if (txmode == 1) {
2538 				pmp_priv->mode = MP_PACKET_TX;
2539 				pmp_priv->tx.count = count;
2540 			} else if (txmode == 2)
2541 				pmp_priv->mode = MP_SINGLE_TONE_TX;
2542 			else if (txmode == 3)
2543 				pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX;
2544 			else if (txmode == 4)
2545 				pmp_priv->mode = MP_SINGLE_CARRIER_TX;
2546 
2547 			status = rtw_mp_pretx_proc(padapter, bStartTest, extra);
2548 		}
2549 
2550 	}
2551 #endif
2552 	wrqu->data.length = strlen(extra);
2553 	return status;
2554 }
2555 
2556 
rtw_mp_rx(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2557 int rtw_mp_rx(struct net_device *dev,
2558 	      struct iw_request_info *info,
2559 	      union iwreq_data *wrqu, char *extra)
2560 {
2561 	_adapter *padapter = rtw_netdev_priv(dev);
2562 	struct mp_priv *pmp_priv = &padapter->mppriv;
2563 	char *pextra = extra;
2564 	u32 bandwidth = 0, sg = 0, channel = 6, ant = 0;
2565 	u16 antenna = 0;
2566 	u8 bStartRx = 0;
2567 
2568 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2569 		return -EFAULT;
2570 #if 0
2571 #ifdef CONFIG_CONCURRENT_MODE
2572 	if (!is_primary_adapter(padapter)) {
2573 		sprintf(extra, "Error: MP mode can't support Virtual adapter, Please to use main adapter.\n");
2574 		wrqu->data.length = strlen(extra);
2575 		return 0;
2576 	}
2577 #endif
2578 
2579 	if (strncmp(extra, "stop", 4) == 0) {
2580 		_rtw_memset(extra, 0, wrqu->data.length);
2581 		SetPacketRx(padapter, bStartRx, _FALSE);
2582 		pmp_priv->bmac_filter = _FALSE;
2583 		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);
2584 		wrqu->data.length = strlen(extra);
2585 		return 0;
2586 
2587 	} else if (sscanf(extra, "ch=%d,bw=%d,ant=%d", &channel, &bandwidth, &ant) < 3) {
2588 		RTW_INFO("Invalid format [ch=%d,bw=%d,ant=%d]\n", channel, bandwidth, ant);
2589 		_rtw_memset(extra, 0, wrqu->data.length);
2590 		pextra += sprintf(pextra, "\n Please input correct format as bleow:\n");
2591 		pextra += sprintf(pextra, "\t ch=%d,bw=%d,ant=%d\n", channel, bandwidth, ant);
2592 		pextra += sprintf(pextra, "\n [ ch : BGN = <1~14> , A or AC = <36~165> ]");
2593 		pextra += sprintf(pextra, "\n [ bw : Bandwidth: 0 = 20M, 1 = 40M, 2 = 80M ]");
2594 		pextra += sprintf(pextra, "\n [ ant : <A = 1, B = 2, C = 4, D = 8> ,2T ex: AB=3 BC=6 CD=12");
2595 		wrqu->data.length = strlen(extra);
2596 		return 0;
2597 
2598 	} else {
2599 		char *pextra = extra;
2600 		bStartRx = 1;
2601 		RTW_INFO("Got format [ch=%d,bw=%d,ant=%d]\n", channel, bandwidth, ant);
2602 		_rtw_memset(extra, 0, wrqu->data.length);
2603 		sprintf(extra, "Change Current channel %d to channel %d", padapter->mppriv.channel , channel);
2604 		padapter->mppriv.channel = channel;
2605 		SetChannel(padapter);
2606 		pHalData->current_channel = channel;
2607 
2608 		if (bandwidth == 1)
2609 			bandwidth = CHANNEL_WIDTH_40;
2610 		else if (bandwidth == 2)
2611 			bandwidth = CHANNEL_WIDTH_80;
2612 		pextra = extra + strlen(extra);
2613 		pextra += sprintf(pextra, "\nChange Current Bandwidth %d to Bandwidth %d", padapter->mppriv.bandwidth, bandwidth);
2614 		padapter->mppriv.bandwidth = (u8)bandwidth;
2615 		padapter->mppriv.preamble = sg;
2616 		SetBandwidth(padapter);
2617 		pHalData->current_channel_bw = bandwidth;
2618 
2619 		pextra += sprintf(pextra, "\nSet Antenna Path :%d", ant);
2620 		switch (ant) {
2621 		case 1:
2622 			antenna = ANTENNA_A;
2623 			break;
2624 		case 2:
2625 			antenna = ANTENNA_B;
2626 			break;
2627 		case 4:
2628 			antenna = ANTENNA_C;
2629 			break;
2630 		case 8:
2631 			antenna = ANTENNA_D;
2632 			break;
2633 		case 3:
2634 			antenna = ANTENNA_AB;
2635 			break;
2636 		case 5:
2637 			antenna = ANTENNA_AC;
2638 			break;
2639 		case 9:
2640 			antenna = ANTENNA_AD;
2641 			break;
2642 		case 6:
2643 			antenna = ANTENNA_BC;
2644 			break;
2645 		case 10:
2646 			antenna = ANTENNA_BD;
2647 			break;
2648 		case 12:
2649 			antenna = ANTENNA_CD;
2650 			break;
2651 		case 7:
2652 			antenna = ANTENNA_ABC;
2653 			break;
2654 		case 14:
2655 			antenna = ANTENNA_BCD;
2656 			break;
2657 		case 11:
2658 			antenna = ANTENNA_ABD;
2659 			break;
2660 		case 15:
2661 			antenna = ANTENNA_ABCD;
2662 			break;
2663 		}
2664 		RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);
2665 		padapter->mppriv.antenna_tx = antenna;
2666 		padapter->mppriv.antenna_rx = antenna;
2667 		pHalData->antenna_tx_path = antenna;
2668 		SetAntenna(padapter);
2669 
2670 		strcat(extra, "\nstart Rx");
2671 		SetPacketRx(padapter, bStartRx, _FALSE);
2672 	}
2673 #endif
2674 	wrqu->data.length = strlen(extra);
2675 	return 0;
2676 }
2677 
2678 
rtw_mp_hwtx(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2679 int rtw_mp_hwtx(struct net_device *dev,
2680 		struct iw_request_info *info,
2681 		union iwreq_data *wrqu, char *extra)
2682 {
2683 	_adapter *padapter = rtw_netdev_priv(dev);
2684 	struct mp_priv *pmp_priv = &padapter->mppriv;
2685 	PMPT_CONTEXT mpt_ctx = &(padapter->mppriv.mpt_ctx);
2686 
2687 #if defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C)
2688 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2689 		return -EFAULT;
2690 	*(extra + wrqu->data.length) = '\0';
2691 
2692 	_rtw_memset(&mpt_ctx->PMacTxInfo, 0, sizeof(RT_PMAC_TX_INFO));
2693 	_rtw_memcpy((void *)&mpt_ctx->PMacTxInfo, (void *)extra, sizeof(RT_PMAC_TX_INFO));
2694 	_rtw_memset(extra, 0, wrqu->data.length);
2695 
2696 	if (mpt_ctx->PMacTxInfo.bEnPMacTx == 1 && pmp_priv->mode != MP_ON) {
2697 		sprintf(extra, "MP Tx Running, Please Set PMac Tx Mode Stop\n");
2698 		RTW_INFO("Error !!! MP Tx Running, Please Set PMac Tx Mode Stop\n");
2699 	} else {
2700 		RTW_INFO("To set MAC Tx mode\n");
2701 		mpt_ProSetPMacTx(padapter);
2702 		sprintf(extra, "Set PMac Tx Mode OK\n");
2703 	}
2704 	wrqu->data.length = strlen(extra);
2705 #endif
2706 	return 0;
2707 
2708 }
2709 
rtw_mp_pwrlmt(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2710 int rtw_mp_pwrlmt(struct net_device *dev,
2711 			struct iw_request_info *info,
2712 			union iwreq_data *wrqu, char *extra)
2713 {
2714 	_adapter *padapter = rtw_netdev_priv(dev);
2715 	struct registry_priv  *registry_par = &padapter->registrypriv;
2716 	u8 pwrlimtstat = 0;
2717 
2718 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2719 		return -EFAULT;
2720 
2721 	*(extra + wrqu->data.length) = '\0';
2722 #if CONFIG_TXPWR_LIMIT
2723 	if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
2724 		if (rtw_mpt_set_power_limit_en(padapter, _FALSE))
2725 			sprintf(extra, "Turn off Power Limit\n");
2726 		else
2727 			sprintf(extra, "Turn off Power Limit Fail\n");
2728 	} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
2729 		if (rtw_mpt_set_power_limit_en(padapter, _TRUE))
2730 			sprintf(extra, "Turn on Power Limit\n");
2731 		else
2732 			sprintf(extra, "Turn on Power Limit Fail\n");
2733 	} else
2734 #endif
2735 	{
2736 		sprintf(extra, "PHL PWRLMT:%s\n",
2737 			(rtw_mpt_get_power_limit_en(padapter) == _TRUE) ?"ON" :"OFF");
2738 	}
2739 	wrqu->data.length = strlen(extra);
2740 	return 0;
2741 }
2742 
rtw_mp_dpk_track(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2743 int rtw_mp_dpk_track(struct net_device *dev,
2744 			struct iw_request_info *info,
2745 			union iwreq_data *wrqu, char *extra)
2746 {
2747 	_adapter *padapter = rtw_netdev_priv(dev);
2748 	//struct dm_struct *phydm = adapter_to_phydm(padapter);
2749 
2750 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2751 		return -EFAULT;
2752 
2753 	*(extra + wrqu->data.length) = '\0';
2754 
2755 	if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
2756 		//halrf_set_dpk_track(phydm, FALSE);
2757 		sprintf(extra, "set dpk track off\n");
2758 
2759 	} else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
2760 		//halrf_set_dpk_track(phydm, TRUE);
2761 		sprintf(extra, "set dpk track on\n");
2762 	}
2763 
2764 	wrqu->data.length = strlen(extra);
2765 	return 0;
2766 }
2767 
rtw_mp_set_phl_io(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)2768 int rtw_mp_set_phl_io(struct net_device *dev,
2769 			 struct iw_request_info *info,
2770 			 struct iw_point *wrqu, char *extra)
2771 {
2772 	_adapter *padapter = rtw_netdev_priv(dev);
2773 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
2774 	struct phl_info_t *phl_info = (struct phl_info_t *)(dvobj->phl);
2775 	struct rtw_mp_cmd_arg *cmd_arg = NULL;
2776 	struct rtw_mp_test_cmdbuf *pcmdbuf = NULL;
2777 	u16 i = 0;
2778 
2779 	if (copy_from_user(extra, wrqu->pointer, wrqu->length))
2780 			return -EFAULT;
2781 
2782 	RTW_INFO("%s, wrqu->length %d !!!\n", __func__, wrqu->length);
2783 
2784 	rtw_phl_test_submodule_cmd_process(rtw_phl_get_com(phl_info), (void*)extra, wrqu->length);
2785 	pcmdbuf = (struct rtw_mp_test_cmdbuf *)extra;
2786 	while (1) {
2787 		if (pcmdbuf) {
2788 			cmd_arg = (struct rtw_mp_cmd_arg *)pcmdbuf->buf;
2789 			rtw_phl_test_submodule_get_rpt(rtw_phl_get_com(phl_info), (void *)extra, wrqu->length);
2790 		}
2791 		if (cmd_arg != NULL && cmd_arg->cmd_ok) {
2792 			RTW_INFO("%s,GET CMD OK !!!\n", __func__);
2793 			break;
2794 		} else {
2795 			i++;
2796 			rtw_msleep_os(100);
2797 			if (i == 3) {
2798 				RTW_INFO("%s,GET CMD FAIL !!!\n", __func__);
2799 				break;
2800 			}
2801 		}
2802 	}
2803 
2804 	if (copy_to_user(wrqu->pointer, extra, wrqu->length))
2805 		return -EFAULT;
2806 
2807 	return 0;
2808 }
2809 
rtw_mp_get_phl_io(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)2810 int rtw_mp_get_phl_io(struct net_device *dev,
2811 			 struct iw_request_info *info,
2812 			 struct iw_point *wrqu, char *extra)
2813 {
2814 	_adapter *padapter = rtw_netdev_priv(dev);
2815 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
2816 	struct phl_info_t *phl_info = (struct phl_info_t *)(padapter->dvobj->phl);
2817 
2818 	if (copy_from_user(extra, wrqu->pointer, wrqu->length))
2819 			return -EFAULT;
2820 	*(extra + wrqu->length) = '\0';
2821 
2822 	rtw_phl_test_submodule_get_rpt(rtw_phl_get_com(phl_info), (void *)&extra, wrqu->length);
2823 
2824 	wrqu->length = strlen(extra);
2825 
2826 	return 0;
2827 }
2828 
rtw_mp_tx_pattern_idx(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2829 int rtw_mp_tx_pattern_idx(struct net_device *dev,
2830 			 struct iw_request_info *info,
2831 			 union iwreq_data *wrqu, char *extra)
2832 {
2833 	_adapter *padapter = rtw_netdev_priv(dev);
2834 	struct mp_priv *pmp_priv = (struct mp_priv *)&padapter->mppriv;
2835 
2836 	u32 tx_patt_idx = 0;
2837 	u32 ppdu_type = 0;
2838 
2839 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2840 		return -EFAULT;
2841 
2842 	if (sscanf(extra, "index=%d,type=%d", &tx_patt_idx, &ppdu_type) > 0) {
2843 		RTW_INFO("%s: tx_patt_idx=%d ,ppdu_type=%d\n", __func__, tx_patt_idx , ppdu_type);
2844 		pmp_priv->rtw_mp_pmact_patt_idx = tx_patt_idx;
2845 		pmp_priv->rtw_mp_pmact_ppdu_type = ppdu_type;
2846 		rtw_phl_mp_tx_cmd(padapter, RTW_MP_TX_CONFIG_PLCP_PATTERN, pmp_priv->rtw_mp_tx_method, _TRUE);
2847 		_rtw_memset(extra, 0, wrqu->data.length);
2848 		sprintf(extra, "Config Tx Pattern idx %d to %d", pmp_priv->rtw_mp_pmact_patt_idx, tx_patt_idx);
2849 	} else if ((strncmp(extra, "stop", 4) == 0)) {
2850 		rtw_phl_mp_tx_cmd(padapter, RTW_MP_TX_CONFIG_PLCP_PATTERN, pmp_priv->rtw_mp_tx_method, _FALSE);
2851 		_rtw_memset(extra, 0, wrqu->data.length);
2852 		sprintf(extra, "Config Tx Pattern Stop");
2853 	} else {
2854 		u8 *pstr = extra;
2855 		_rtw_memset(pstr, 0, wrqu->data.length);
2856 	}
2857 	wrqu->data.length = strlen(extra);
2858 	return 0;
2859 }
2860 
rtw_mp_tx_plcp_tx_data(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2861 int rtw_mp_tx_plcp_tx_data(struct net_device *dev,
2862 			 struct iw_request_info *info,
2863 			 union iwreq_data *wrqu, char *extra)
2864 {
2865 	_adapter *padapter = rtw_netdev_priv(dev);
2866 	struct mp_priv *pmp_priv = (struct mp_priv *)&padapter->mppriv;
2867 	u8 user_idx = pmp_priv->mp_plcp_useridx;
2868 
2869 
2870 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2871 		return -EFAULT;
2872 
2873 	if ((strncmp(extra, "ppdu", 4) == 0)) {
2874 		u32 ppdu_type = 0;
2875 
2876 		if (sscanf(extra, "ppdu=%d", &ppdu_type) > 0) {
2877 				u8 *pextra = extra;
2878 
2879 				RTW_INFO("%s: ppdu_type=%d\n", __func__, ppdu_type);
2880 				_rtw_memset(extra, 0, wrqu->data.length);
2881 
2882 				pextra += sprintf(pextra, "Config PPDU Type %s to %s\n",
2883 						PPDU_TYPE_STR(pmp_priv->rtw_mp_pmact_ppdu_type), PPDU_TYPE_STR(ppdu_type));
2884 				pmp_priv->rtw_mp_pmact_ppdu_type = ppdu_type;
2885 
2886 				rtw_update_giltf(padapter);
2887 				rtw_mp_update_coding(padapter);
2888 
2889 				if (ppdu_type >= RTW_MP_TYPE_HE_MU_OFDMA) {
2890 					u8 ru_num = 0 , rualloc_num = 0 ,i = 0;
2891 
2892 					ru_num = rtw_mp_update_ru_tone(padapter);
2893 					rualloc_num = rtw_mp_update_ru_alloc(padapter);
2894 					pextra += sprintf(pextra, "\nCurrent [%s] RU Alloc index:%d\n",
2895 												RU_TONE_STR(pmp_priv->rtw_mp_ru_tone),
2896 												pmp_priv->mp_plcp_user[user_idx].ru_alloc);
2897 
2898 					pextra += sprintf(pextra, "RU Alloc list:[");
2899 					for (i = 0;i <= rualloc_num - 1; i++)
2900 						pextra += sprintf(pextra, "%d ", pmp_priv->ru_alloc_list[i]);
2901 					pextra += sprintf(pextra, "]\n");
2902 
2903 					pextra += sprintf(pextra, "\nRU Tone support list(Refer Coding:%s):\n",
2904 												(pmp_priv->mp_plcp_user[user_idx].coding ? "LDPC":"BCC"));
2905 					for (i = 0;i <= ru_num; i++)
2906 						pextra += sprintf(pextra, "%d : [%s]\n",
2907 												pmp_priv->ru_tone_sel_list[i],
2908 												RU_TONE_STR(pmp_priv->ru_tone_sel_list[i]));
2909 					pextra += sprintf(pextra, "\n\nCodingCMD:[mp_plcp_user coding=%%d] (0:BCC 1:LDPC )");
2910 					pextra += sprintf(pextra, "\nRU Tone CMD:[ mp_plcp_user ru_tone=%%d ]");
2911 					pextra += sprintf(pextra, "\nRU Alloc CMD:[ mp_plcp_user ru_alloc=%%d ]");
2912 				}
2913 		} else {
2914 			u8 *pstr = extra;
2915 			_rtw_memset(pstr, 0, wrqu->data.length);
2916 			pstr += sprintf(pstr, "CMD: [mp_plcp_datappdu=%%d]\nPLCP (PPDU Type):\n\
2917 0:CCK\n1:LEGACY\n2:HT_MF\n3:HT_GF\n4:VHT\n5:HE_SU\n6:HE_ER_SU\n7:HE_MU_OFDMA\n8:HE_TB\n");
2918 			}
2919 	}else if ((strncmp(extra, "preamble", 8) == 0)) {
2920 		u8 preamble = 0;
2921 
2922 		if (sscanf(extra, "preamble=%hhd", &preamble) > 0) {
2923 			RTW_INFO("%s: preamble=%d\n", __func__, preamble);
2924 			_rtw_memset(extra, 0, wrqu->data.length);
2925 
2926 			if (rtw_mp_is_cck_rate(pmp_priv->rateidx)) {
2927 				pmp_priv->preamble = preamble;
2928 				sprintf(extra, "Config Preamble %d to %d", pmp_priv->preamble, preamble);
2929 			} else
2930 				sprintf(extra, "Error !!! only B mode Rate for Preamble!\n");
2931 		} else
2932 			sprintf(extra, "Error format ! input 'preamble=[num]'\n");
2933 
2934 	} else if ((strncmp(extra, "stbc", 4) == 0)) {
2935 		u8 stbc = 0;
2936 
2937 		if (sscanf(extra, "stbc=%hhd", &stbc) > 0) {
2938 				RTW_INFO("%s: stbc=%d\n", __func__, stbc);
2939 				_rtw_memset(extra, 0, wrqu->data.length);
2940 				sprintf(extra, "Config STBC enable: %d to %d", pmp_priv->rtw_mp_stbc, stbc);
2941 				pmp_priv->rtw_mp_stbc = stbc;
2942 				if (pmp_priv->rtw_mp_stbc)
2943 					pmp_priv->mp_plcp_user[user_idx].dcm = 0;
2944 		} else {
2945 			_rtw_memset(extra, 0, wrqu->data.length);
2946 			sprintf(extra, "input [stbc=0/1]");
2947 		}
2948 
2949 	} else if ((strncmp(extra, "giltf", 5) == 0)) {
2950 		u8 idx = 0;
2951 		u8 giltf_num = rtw_update_giltf(padapter);
2952 
2953 		if (sscanf(extra, "giltf=%hhd", &idx) > 0) {
2954 			u8 gi = 0, ltf = 0;
2955 
2956 			RTW_INFO("%s: gi+ltf=%d\n", __func__, idx);
2957 			_rtw_memset(extra, 0, wrqu->data.length);
2958 
2959 			if (giltf_num != 0 && idx <= giltf_num) {
2960 				gi = pmp_priv->st_giltf[idx].gi;
2961 				ltf = pmp_priv->st_giltf[idx].ltf;
2962 				sprintf(extra, "Config GI+LTF to %s ", pmp_priv->st_giltf[idx].type_str);
2963 				pmp_priv->rtw_mp_plcp_gi = gi;
2964 				pmp_priv->rtw_mp_plcp_ltf = ltf;
2965 				RTW_INFO("%s: gi=%d ltf=%d\n", __func__, gi, ltf);
2966 			} else
2967 				sprintf(extra, "Not support GI+LTF index\n");
2968 
2969 		} else {
2970 			u8 *pextra = extra;
2971 			u8 i = 0;
2972 
2973 			if (giltf_num > 0) {
2974 				pextra += sprintf(pextra, "GI + LTF list:\n");
2975 				for (i = 0;i <= giltf_num; i++)
2976 							pextra += sprintf(pextra, "%d:[%s]\n", i, pmp_priv->st_giltf[i].type_str);
2977 			}
2978 			sprintf(pextra, "PPDU Type Not support GI+LTF.");
2979 		}
2980 
2981 	} else if ((strncmp(extra, "tx_time", 7) == 0)) {
2982 			u32 tx_time = 0;
2983 
2984 			if (sscanf(extra, "tx_time=%d", &tx_time) > 0) {
2985 				u32 tmp_tx_time = (tx_time * 10) / 4;
2986 
2987 				pmp_priv->rtw_mp_plcp_tx_time = tmp_tx_time;
2988 				pmp_priv->rtw_mp_plcp_tx_mode = 1;
2989 				sprintf(extra, "Config Tx Time:%d us", pmp_priv->rtw_mp_plcp_tx_time);
2990 			}
2991 
2992 	} else if ((strncmp(extra, "tx_len", 6) == 0)) {
2993 			u32 tx_len = 0;
2994 
2995 			if (sscanf(extra, "tx_len=%d", &tx_len) > 0) {
2996 				pmp_priv->mp_plcp_user[user_idx].plcp_txlen = tx_len;
2997 				pmp_priv->rtw_mp_plcp_tx_mode = 0;
2998 				sprintf(extra, "Config Tx Len:%d", pmp_priv->mp_plcp_user[user_idx].plcp_txlen);
2999 		}
3000 
3001 	} else if ((strncmp(extra, "he_sigb", 7) == 0)) {
3002 			u32 he_sigb = 0;
3003 
3004 			if (sscanf(extra, "he_sigb=%d", &he_sigb) > 0) {
3005 				if (he_sigb <= 5) {
3006 					pmp_priv->rtw_mp_he_sigb = he_sigb;
3007 					sprintf(extra, "Config HE SIGB:%d", he_sigb);
3008 				} else
3009 					sprintf(extra, "Error Config HE SIGB:[%d] (0~5)", he_sigb);
3010 			} else {
3011 				u8 *pstr = extra;
3012 
3013 				_rtw_memset(pstr, 0, wrqu->data.length);
3014 				pstr += sprintf(pstr, "invalid CMD Format! input: he_sigb=[Num]\n\
3015 					PLCP (HE SIGB):\n0\n\1\n2\n\3\n\4\n\5\n");
3016 			}
3017 
3018 	} else if ((strncmp(extra, "he_sigb_dcm", 7) == 0)) {
3019 			u32 he_sigb_dcm = 0;
3020 
3021 			if (sscanf(extra, "he_sigb_dcm=%d", &he_sigb_dcm) > 0) {
3022 				if (he_sigb_dcm <= 1) {
3023 					pmp_priv->rtw_mp_he_sigb_dcm = he_sigb_dcm;
3024 					sprintf(extra, "Config HE SIGB DCM:%d", he_sigb_dcm);
3025 				} else
3026 					sprintf(extra, "Error Config HE SIGB:[%d] (0:Disable 1:Enable)", he_sigb_dcm);
3027 
3028 			} else {
3029 				u8 *pstr = extra;
3030 
3031 				_rtw_memset(pstr, 0, wrqu->data.length);
3032 				pstr += sprintf(pstr, "invalid CMD Format! input: he_sigb_dcm=[Num]\n\
3033 					PLCP (HE SIGB DCM):\n0:Disable\n1:Enable");
3034 			}
3035 
3036 	} else if ((strncmp(extra, "er_su_ru106en", 7) == 0)) {
3037 			u32 ru106en = 0;
3038 
3039 			if (sscanf(extra, "er_su_ru106en=%d", &ru106en) > 0) {
3040 				if (ru106en <= 1) {
3041 					pmp_priv->rtw_mp_he_er_su_ru_106_en = ru106en;
3042 					sprintf(extra, "Config he_er_su_ru106:%d", ru106en);
3043 				} else
3044 					sprintf(extra, "Error!!! Config HE ER SU RU106 Enable:[%d] (0:Disable 1:Enable)",
3045 										ru106en);
3046 			} else {
3047 				u8 *pstr = extra;
3048 
3049 				_rtw_memset(pstr, 0, wrqu->data.length);
3050 				pstr += sprintf(pstr, "Error!!! Config HE ER SU RU106 Enable: Input number[ 0:Disable 1:Enable ]");
3051 			}
3052 
3053 	} else if ((strncmp(extra, "ru_tone", 7) == 0)) {
3054 		u32 ru_tone = 0;
3055 
3056 		if (sscanf(extra, "ru_tone=%d", &ru_tone) > 0) {
3057 				RTW_INFO("%s: RU Tone=%d\n", __func__, ru_tone);
3058 				_rtw_memset(extra, 0, wrqu->data.length);
3059 				sprintf(extra, "Config RU tone %d to %d", pmp_priv->rtw_mp_ru_tone, ru_tone);
3060 				pmp_priv->rtw_mp_ru_tone = ru_tone;
3061 		} else {
3062 			_rtw_memset(extra, 0, wrqu->data.length);
3063 			sprintf(extra, "Error!!!\tinput , [ru_tone= number]");
3064 		}
3065 
3066 	} else {
3067 				char *pstr = extra;
3068 				u8 ppdu_idx = pmp_priv->rtw_mp_pmact_ppdu_type;
3069 
3070 				if (ppdu_idx < RTW_MP_TYPE_HT_MF) {
3071 						pstr += sprintf(pstr, "invalid PPDU Type ! input :ppdu=[Num] over the HT\n");
3072 				} else {
3073 					u8 i = 0;
3074 					u8 num = rtw_update_giltf(padapter);
3075 
3076 					_rtw_memset(extra, 0, wrqu->data.length);
3077 					pstr += sprintf(pstr, "invalid CMD Format !! please input: giltf=[Num]\n");
3078 					pstr += sprintf(pstr, "PPDU %s GI+LTF:\n", PPDU_TYPE_STR(ppdu_idx));
3079 					for (i = 0; i <= num; i++)
3080 						pstr += sprintf(pstr, "[%d]: %s\n" ,i , pmp_priv->st_giltf[i].type_str);
3081 				}
3082 		}
3083 	wrqu->data.length = strlen(extra);
3084 	return 0;
3085 }
3086 
rtw_mp_tx_plcp_tx_user(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3087 int rtw_mp_tx_plcp_tx_user(struct net_device *dev,
3088 			 struct iw_request_info *info,
3089 			 union iwreq_data *wrqu, char *extra)
3090 {
3091 	_adapter *padapter = rtw_netdev_priv(dev);
3092 	struct mp_priv *mpprv = (struct mp_priv *)&padapter->mppriv;
3093 
3094 	u32 tx_mcs = 0;
3095 	u8 user_idx = mpprv->mp_plcp_useridx;
3096 
3097 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
3098 		return -EFAULT;
3099 
3100 	if (sscanf(extra, "mcs=%d", &tx_mcs) > 0) {
3101 		RTW_INFO("%s: mcs=%d\n", __func__, tx_mcs);
3102 		mpprv->mp_plcp_user[user_idx].plcp_mcs = tx_mcs;
3103 		_rtw_memset(extra, 0, wrqu->data.length);
3104 		sprintf(extra, "Config PLCP MCS idx %d to %d",
3105 						mpprv->mp_plcp_user[user_idx].plcp_mcs, tx_mcs);
3106 
3107 	} else if ((strncmp(extra, "dcm", 3) == 0)) {
3108 		u8 dcm = 0;
3109 
3110 		if (sscanf(extra, "dcm=%hhd", &dcm) > 0) {
3111 				RTW_INFO("%s: dcm=%d\n", __func__, dcm);
3112 				_rtw_memset(extra, 0, wrqu->data.length);
3113 				sprintf(extra, "Config DCM enable: %d to %d", mpprv->mp_plcp_user[user_idx].dcm, dcm);
3114 				mpprv->mp_plcp_user[user_idx].dcm = dcm;
3115 
3116 				if (mpprv->mp_plcp_user[user_idx].dcm)
3117 						mpprv->rtw_mp_stbc = 0;
3118 		} else {
3119 			_rtw_memset(extra, 0, wrqu->data.length);
3120 			sprintf(extra, "Error !!! input [dcm=0/1]");
3121 		}
3122 
3123 	} else if ((strncmp(extra, "coding", 6) == 0)) {
3124 		u8 coding = 0;
3125 
3126 		if (sscanf(extra, "coding=%hhd", &coding) > 0) {
3127 
3128 				RTW_INFO("%s: coding=%d\n", __func__, coding);
3129 				_rtw_memset(extra, 0, wrqu->data.length);
3130 				mpprv->mp_plcp_user[user_idx].coding = coding;
3131 				rtw_mp_update_coding(padapter);
3132 				sprintf(extra, "Config coding to %s",
3133 								(mpprv->mp_plcp_user[user_idx].coding?"LDPC":"BCC"));
3134 		} else {
3135 			_rtw_memset(extra, 0, wrqu->data.length);
3136 			sprintf(extra, "Error !!!\n0:BCC 1:LDPC \t input Number [coding=0/1]");
3137 		}
3138 
3139 	} else if ((strncmp(extra, "ru_alloc", 8) == 0)) {
3140 		u32 ru_alloc = 0;
3141 
3142 		if (sscanf(extra, "ru_alloc=%d", &ru_alloc) > 0) {
3143 
3144 				RTW_INFO("%s: RU alloc=%d\n", __func__, ru_alloc);
3145 				_rtw_memset(extra, 0, wrqu->data.length);
3146 				sprintf(extra, "Config RU alloc %d to %d",
3147 								mpprv->mp_plcp_user[user_idx].ru_alloc, ru_alloc);
3148 				mpprv->mp_plcp_user[user_idx].ru_alloc = ru_alloc;
3149 		} else {
3150 			_rtw_memset(extra, 0, wrqu->data.length);
3151 			sprintf(extra, "Error!!!\tinput , [ru_alloc= number]");
3152 		}
3153 
3154 	} else if ((strncmp(extra, "txuser", 6) == 0)) {
3155 		u32 txuser = 0;
3156 
3157 		if (sscanf(extra, "txuser=%d", &txuser) > 0) {
3158 				RTW_INFO("%s: Sel User idx=%d\n", __func__, txuser);
3159 				_rtw_memset(extra, 0, wrqu->data.length);
3160 				sprintf(extra, "config Tx User %d to %d", mpprv->rtw_mp_plcp_tx_user, txuser);
3161 				mpprv->rtw_mp_plcp_tx_user = txuser;
3162 		} else {
3163 			_rtw_memset(extra, 0, wrqu->data.length);
3164 			sprintf(extra, "Error!!!\tinput , [txuser= number]");
3165 		}
3166 
3167 	} else if ((strncmp(extra, "user", 4) == 0)) {
3168 		u32 user_idx = 0;
3169 
3170 		if (sscanf(extra, "user=%d", &user_idx) > 0) {
3171 				RTW_INFO("%s: Sel User idx=%d\n", __func__, user_idx);
3172 				_rtw_memset(extra, 0, wrqu->data.length);
3173 				sprintf(extra, "select User idx %d to %d", mpprv->mp_plcp_useridx, user_idx);
3174 				mpprv->mp_plcp_useridx = user_idx;
3175 		} else {
3176 			_rtw_memset(extra, 0, wrqu->data.length);
3177 			sprintf(extra, "Error!!!\tinput , [user= number]");
3178 		}
3179 
3180 	} else if ((strncmp(extra, "tx_len", 6) == 0)) {
3181 			u32 tx_len = 0;
3182 
3183 			if (sscanf(extra, "tx_len=%d", &tx_len) > 0) {
3184 				mpprv->mp_plcp_user[user_idx].plcp_txlen = tx_len;
3185 				mpprv->rtw_mp_plcp_tx_mode = 0;
3186 				sprintf(extra, "Config Tx Len:%d", mpprv->mp_plcp_user[user_idx].plcp_txlen);
3187 		}
3188 
3189 	} else {
3190 		u8 *pstr = extra;
3191 		_rtw_memset(pstr, 0, wrqu->data.length);
3192 
3193 		pstr += sprintf(pstr, "invalid CMD Format!\n \
3194 		\t input :\n\
3195 		\t user=%%d\n\
3196 		\t mcs=%%d\n\
3197 		\t dcm=%%d,\n\
3198 		\t coding=%%d\n\
3199 		\t ru_alloc=%%d\n");
3200 	}
3201 	wrqu->data.length = strlen(extra);
3202 	return 0;
3203 }
3204 
rtw_mp_tx_method(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3205 int rtw_mp_tx_method(struct net_device *dev,
3206 			 struct iw_request_info *info,
3207 			 union iwreq_data *wrqu, char *extra)
3208 {
3209 	_adapter *padapter = rtw_netdev_priv(dev);
3210 	struct mp_priv *pmp_priv = (struct mp_priv *)&padapter->mppriv;
3211 
3212 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
3213 		return -EFAULT;
3214 
3215 	if ((strncmp(extra, "PMACT", 5) == 0)) {
3216 		pmp_priv->rtw_mp_tx_method = RTW_MP_PMACT_TX;
3217 		sprintf(extra, "set PMACT OK");
3218 	} else if ((strncmp(extra, "TMACT", 5) == 0)) {
3219 		pmp_priv->rtw_mp_tx_method = RTW_MP_TMACT_TX;
3220 		rtw_phl_mp_tx_cmd(padapter, RTW_MP_TX_MODE_SWITCH, pmp_priv->rtw_mp_tx_method, _FALSE);
3221 		sprintf(extra, "set TMACT OK");
3222 	} else if ((strncmp(extra, "FWPMACT", 7) == 0)) {
3223 		pmp_priv->rtw_mp_tx_method = RTW_MP_FW_PMACT_TX;
3224 		rtw_phl_mp_tx_cmd(padapter, RTW_MP_TX_MODE_SWITCH, pmp_priv->rtw_mp_tx_method, _FALSE);
3225 		sprintf(extra, "set FWPMACT OK");
3226 	}
3227 	wrqu->data.length = strlen(extra);
3228 	return 0;
3229 }
3230 
rtw_mp_config_phy(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3231 int rtw_mp_config_phy(struct net_device *dev,
3232 			 struct iw_request_info *info,
3233 			 union iwreq_data *wrqu, char *extra)
3234 {
3235 	_adapter *padapter = rtw_netdev_priv(dev);
3236 	struct mp_priv *pmp_priv = (struct mp_priv *)&padapter->mppriv;
3237 	u8	set_phy = 0;
3238 
3239 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
3240 		return -EFAULT;
3241 
3242 	extra[wrqu->data.length] = '\0';
3243 	set_phy = rtw_atoi(extra);
3244 
3245 	if (set_phy < 2) {
3246 		sprintf(extra, "set current phy %d to %d", pmp_priv->rtw_mp_cur_phy, set_phy);
3247 		pmp_priv->rtw_mp_cur_phy = set_phy;
3248 		rtw_mp_phl_config_arg(padapter, RTW_MP_CONFIG_CMD_SET_PHY_INDEX);
3249 	} else
3250 		sprintf(extra, "Not suuport phy %d", set_phy);
3251 
3252 	wrqu->data.length = strlen(extra);
3253 	return 0;
3254 }
3255 
rtw_mp_phl_rfk(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3256 int rtw_mp_phl_rfk(struct net_device *dev,
3257 			 struct iw_request_info *info,
3258 			 union iwreq_data *wrqu, char *extra)
3259 {
3260 	_adapter *padapter = rtw_netdev_priv(dev);
3261 	struct mp_priv *pmp_priv = (struct mp_priv *)&padapter->mppriv;
3262 	u8 k_type = RTW_MP_CAL_MAX;
3263 	u8 k_cap_ctrl = false;
3264 	u8 k_cap_on = false;
3265 
3266 	if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
3267 		return -EFAULT;
3268 
3269 	if (strncmp(extra, "iqk", 3) == 0) {
3270 		k_type = RTW_MP_CAL_IQK;
3271 
3272 		if (strncmp(extra, "iqk on", 6) == 0) {
3273 			k_cap_ctrl = true;
3274 			k_cap_on = true;
3275 			sprintf(extra, "set iqk on");
3276 
3277 		} else if ((strncmp(extra, "iqk off", 7) == 0)) {
3278 			k_cap_ctrl = true;
3279 			k_cap_on = false;
3280 			sprintf(extra, "set iqk off");
3281 		} else
3282 			sprintf(extra, "set iqk trigger");
3283 
3284 	} else if (strncmp(extra, "dpk", 3) == 0) {
3285 		k_type = RTW_MP_CAL_DPK;
3286 		if (strncmp(extra, "dpk on", 6) == 0) {
3287 			k_cap_ctrl = true;
3288 			k_cap_on = true;
3289 			sprintf(extra, "set dpk on");
3290 		} else if ((strncmp(extra, "dpk off", 7) == 0)) {
3291 			k_cap_ctrl = true;
3292 			k_cap_on = false;
3293 			sprintf(extra, "set dpk off");
3294 		} else
3295 			sprintf(extra, "set dpk trigger");
3296 
3297 	} else if (strncmp(extra, "chk", 3) == 0) {
3298 		k_type = RTW_MP_CAL_CHL_RFK;
3299 		if (strncmp(extra, "chk on", 6) == 0) {
3300 			k_cap_ctrl = true;
3301 			k_cap_on = true;
3302 			sprintf(extra, "set chk on");
3303 		} else if ((strncmp(extra, "chk off", 7) == 0)) {
3304 			k_cap_ctrl = true;
3305 			k_cap_on = false;
3306 			sprintf(extra, "set chk off");
3307 		} else
3308 			sprintf(extra, "set chk trigger");
3309 
3310 	} else if (strncmp(extra, "dack", 3) == 0) {
3311 		k_type = RTW_MP_CAL_DACK;
3312 		if (strncmp(extra, "dack on", 6) == 0) {
3313 			k_cap_ctrl = true;
3314 			k_cap_on = true;
3315 			sprintf(extra, "set dack on");
3316 		} else if ((strncmp(extra, "dack off", 7) == 0)) {
3317 			k_cap_ctrl = true;
3318 			k_cap_on = false;
3319 			sprintf(extra, "set dack off");
3320 		} else
3321 			sprintf(extra, "set dack trigger");
3322 
3323 	} else if (strncmp(extra, "lck", 3) == 0) {
3324 		k_type = RTW_MP_CAL_LCK;
3325 		if (strncmp(extra, "lck on", 6) == 0) {
3326 			k_cap_ctrl = true;
3327 			k_cap_on = true;
3328 			sprintf(extra, "set lck on");
3329 		} else if ((strncmp(extra, "lck off", 7) == 0)) {
3330 			k_cap_ctrl = true;
3331 			k_cap_on = false;
3332 			sprintf(extra, "set lck off");
3333 		} else
3334 			sprintf(extra, "set lck trigger");
3335 
3336 	} else if (strncmp(extra, "dpk_trk", 7) == 0) {
3337 		k_type = RTW_MP_CAL_DPK_TRACK;
3338 		if (strncmp(extra, "dpk_trk on", 10) == 0) {
3339 			k_cap_ctrl = true;
3340 			k_cap_on = true;
3341 			sprintf(extra, "set dpk_trk on");
3342 		} else if ((strncmp(extra, "dpk_trk off", 11) == 0)) {
3343 			k_cap_ctrl = true;
3344 			k_cap_on = false;
3345 			sprintf(extra, "set dpk_trk off");
3346 		}
3347 
3348 	} else if (strncmp(extra, "tssi", 4) == 0) {
3349 		k_type = RTW_MP_CAL_TSSI;
3350 		if (strncmp(extra, "tssi on", 7) == 0) {
3351 			k_cap_ctrl = true;
3352 			k_cap_on = true;
3353 			sprintf(extra, "set tssi on");
3354 		} else if ((strncmp(extra, "tssi off", 8) == 0)) {
3355 			k_cap_ctrl = true;
3356 			k_cap_on = false;
3357 			sprintf(extra, "set tssi off");
3358 		} else
3359 			sprintf(extra, "set tssi trigger");
3360 
3361 	} else if (strncmp(extra, "gapk", 4) == 0) {
3362 		k_type = RTW_MP_CAL_GAPK;
3363 		if (strncmp(extra, "gapk on", 7) == 0) {
3364 			k_cap_ctrl = true;
3365 			k_cap_on = true;
3366 			sprintf(extra, "set gapk on");
3367 		} else if ((strncmp(extra, "gapk off", 8) == 0)) {
3368 			k_cap_ctrl = true;
3369 			k_cap_on = false;
3370 			sprintf(extra, "set gapk off");
3371 		} else
3372 			sprintf(extra, "set gapk trigger");
3373 
3374 	} else
3375 		sprintf(extra, "Error! CMD Format:\n\
3376 				[trigger K] or Set K on/off\n\
3377 				chk\\chk on/off\n\
3378 				dack\\dack on/off\n\
3379 				iqk\\iqk on/off\n\
3380 				lck\\lck on/off\n\
3381 				dpk\\dpk on/off\n\
3382 				dpk_trk on/off\n\
3383 				tssi\\tssi on/off\n\
3384 				gapk\\gapk on/off\n");
3385 
3386 	if (k_cap_ctrl) {
3387 		rtw_mp_cal_capab(padapter, k_type, k_cap_on);
3388 	} else if (k_type < RTW_MP_CAL_MAX)
3389 		rtw_mp_cal_trigger(padapter, k_type);
3390 
3391 	wrqu->data.length = strlen(extra);
3392 	return 0;
3393 }
3394 
rtw_mp_phl_btc_path(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3395 int rtw_mp_phl_btc_path(struct net_device *dev,
3396 			 struct iw_request_info *info,
3397 			 union iwreq_data *wrqu, char *extra)
3398 {
3399 	_adapter *padapter = rtw_netdev_priv(dev);
3400 	struct mp_priv *pmp_priv = (struct mp_priv *)&padapter->mppriv;
3401 	u8 btc_mode = 0;
3402 
3403 	if (strncmp(extra, "normal", 6) == 0) {
3404 
3405 		btc_mode = BTC_MODE_NORMAL;
3406 		RTW_INFO("set BTC Path Normal");
3407 	} else if (strncmp(extra, "wl", 2) == 0 || strncmp(extra, "WL", 2) == 0) {
3408 
3409 		btc_mode = BTC_MODE_WL;
3410 		RTW_INFO("set BTC Path WL");
3411 	} else if (strncmp(extra, "bt", 2) == 0 || strncmp(extra, "BT", 2) == 0) {
3412 
3413 		btc_mode = BTC_MODE_BT;
3414 		RTW_INFO("set BTC Path BT");
3415 	} else {
3416 		btc_mode = BTC_MODE_WL;
3417 		RTW_INFO("Default set BTC Path WL");
3418 	}
3419 
3420 	pmp_priv->btc_path = btc_mode;
3421 	if (rtw_mp_phl_config_arg(padapter, RTW_MP_CONFIG_CMD_SWITCH_BT_PATH)) {
3422 		sprintf(extra, "set BTC Path %s",
3423 				(btc_mode == 0)? "Normal":((btc_mode == 1)? "WL":
3424 				((btc_mode == 2)? "BT":"DEFAULT WL")));
3425 
3426 	} else
3427 		sprintf(extra, "set BTC Path Fail");
3428 	wrqu->data.length = strlen(extra);
3429 	return 0;
3430 }
3431 
rtw_mp_get_he(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3432 int rtw_mp_get_he(struct net_device *dev,
3433 			 struct iw_request_info *info,
3434 			 union iwreq_data *wrqu, char *extra)
3435 {
3436 	_adapter *padapter = rtw_netdev_priv(dev);
3437 	struct registry_priv *regsty = &padapter->registrypriv;
3438 #ifdef CONFIG_80211AX_HE
3439 	if (!REGSTY_IS_11AX_ENABLE(regsty) ||
3440 		!is_supported_he(regsty->wireless_mode))
3441 		sprintf(extra, "false");
3442 	 else
3443 		sprintf(extra, "true");
3444 #endif
3445 	wrqu->data.length = strlen(extra);
3446 	return 0;
3447 }
3448 
dump_buf(u8 * buf,u32 len)3449 static inline void dump_buf(u8 *buf, u32 len)
3450 {
3451 	u32 i;
3452 
3453 	RTW_INFO("-----------------Len %d----------------\n", len);
3454 	for (i = 0; i < len; i++)
3455 		RTW_INFO("%2.2x-", *(buf + i));
3456 	RTW_INFO("\n");
3457 }
3458 
rtw_mp_link(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)3459 int rtw_mp_link(struct net_device *dev,
3460 			struct iw_request_info *info,
3461 			struct iw_point *wrqu, char *extra)
3462 {
3463 	_adapter *padapter = rtw_netdev_priv(dev);
3464 	struct mp_priv *pmp_priv;
3465 	char	input[RTW_IWD_MAX_LEN];
3466 	int		bgetrxdata = 0, btxdata = 0, bsetbt = 0;
3467 	int err = 0;
3468 	u32 i = 0, datalen = 0,jj, kk, waittime = 0;
3469 	u16 val = 0x00, ret = 0;
3470 	char *pextra = NULL;
3471 	u8 *setdata = NULL;
3472 	char *pch, *ptmp, *token, *tmp[4] = {0x00, 0x00, 0x00};
3473 
3474 	pmp_priv = &padapter->mppriv;
3475 
3476 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
3477 		return -EFAULT;
3478 
3479 	_rtw_memset(extra, 0, wrqu->length);
3480 
3481 	RTW_INFO("%s: in=%s\n", __func__, input);
3482 
3483 	bgetrxdata =  (strncmp(input, "rxdata", 6) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
3484 	btxdata =  (strncmp(input, "txdata", 6) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
3485 	bsetbt =  (strncmp(input, "setbt", 5) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
3486 
3487 	if (bgetrxdata) {
3488 		RTW_INFO("%s: in= 1 \n", __func__);
3489 		if (pmp_priv->mplink_brx == _TRUE) {
3490 
3491 				while (waittime < 100 && pmp_priv->mplink_brx == _FALSE) {
3492 						if (pmp_priv->mplink_brx == _FALSE)
3493 							rtw_msleep_os(10);
3494 						else
3495 							break;
3496 						waittime++;
3497 				}
3498 				if (pmp_priv->mplink_brx == _TRUE) {
3499 					sprintf(extra, "\n");
3500 					pextra = extra + strlen(extra);
3501 					for (i = 0; i < pmp_priv->mplink_rx_len; i ++) {
3502 						pextra += sprintf(pextra, "%02x:", pmp_priv->mplink_buf[i]);
3503 					}
3504 					_rtw_memset(pmp_priv->mplink_buf, '\0' , sizeof(pmp_priv->mplink_buf));
3505 					pmp_priv->mplink_brx = _FALSE;
3506 				}
3507 		}
3508 	} else if (btxdata) {
3509 		struct pkt_attrib *pattrib;
3510 
3511 		pch = input;
3512 		setdata = rtw_zmalloc(1024);
3513 		if (setdata == NULL) {
3514 			err = -ENOMEM;
3515 			goto exit;
3516 		}
3517 
3518 		i = 0;
3519 		while ((token = strsep(&pch, ",")) != NULL) {
3520 			if (i > 2)
3521 				break;
3522 			tmp[i] = token;
3523 			i++;
3524 		}
3525 
3526 		/* tmp[0],[1],[2] */
3527 		/* txdata,00e04c871200........... */
3528 		if (strcmp(tmp[0], "txdata") == 0) {
3529 			if (tmp[1] == NULL) {
3530 				err = -EINVAL;
3531 				goto exit;
3532 			}
3533 		}
3534 
3535 		datalen = strlen(tmp[1]);
3536 		if (datalen % 2) {
3537 			err = -EINVAL;
3538 			goto exit;
3539 		}
3540 		datalen /= 2;
3541 		if (datalen == 0) {
3542 			err = -EINVAL;
3543 			goto exit;
3544 		}
3545 
3546 		RTW_INFO("%s: data len=%d\n", __FUNCTION__, datalen);
3547 		RTW_INFO("%s: tx data=%s\n", __FUNCTION__, tmp[1]);
3548 
3549 		for (jj = 0, kk = 0; jj < datalen; jj++, kk += 2)
3550 			setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
3551 
3552 		dump_buf(setdata, datalen);
3553 		_rtw_memset(pmp_priv->mplink_buf, '\0' , sizeof(pmp_priv->mplink_buf));
3554 		_rtw_memcpy(pmp_priv->mplink_buf, setdata, datalen);
3555 
3556 		pattrib = &pmp_priv->tx.attrib;
3557 		pattrib->pktlen = datalen;
3558 		pmp_priv->tx.count = 1;
3559 		pmp_priv->tx.stop = 0;
3560 		pmp_priv->mplink_btx = _TRUE;
3561 		rtw_mp_set_packet_tx(padapter);
3562 		pmp_priv->mode = MP_PACKET_TX;
3563 
3564 	} else if (bsetbt) {
3565 
3566 #if 0
3567 #ifdef CONFIG_BTC
3568 		pch = input;
3569 		i = 0;
3570 
3571 		while ((token = strsep(&pch, ",")) != NULL) {
3572 			if (i > 3)
3573 				break;
3574 			tmp[i] = token;
3575 			i++;
3576 		}
3577 
3578 		if (tmp[1] == NULL) {
3579 			err = -EINVAL;
3580 			goto exit;
3581 		}
3582 
3583 		if (strcmp(tmp[1], "scbd") == 0) {
3584 			u16 org_val = 0x8002, pre_val, read_score_board_val;
3585 			u8 state;
3586 
3587 			pre_val = (rtw_read16(padapter,(0xaa))) & 0x7fff;
3588 
3589 			if (tmp[2] != NULL) {
3590 				state = simple_strtoul(tmp[2], &ptmp, 10);
3591 
3592 				if (state)
3593 						org_val = org_val | BIT6;
3594 				else
3595 						org_val = org_val & (~BIT6);
3596 
3597 				if (org_val != pre_val) {
3598 					pre_val = org_val;
3599 					rtw_write16(padapter, 0xaa, org_val);
3600 					RTW_INFO("%s,setbt scbd write org_val = 0x%x , pre_val = 0x%x\n", __func__, org_val, pre_val);
3601 				} else {
3602 					RTW_INFO("%s,setbt scbd org_val = 0x%x ,pre_val = 0x%x\n", __func__, org_val, pre_val);
3603 				}
3604 			} else {
3605 					read_score_board_val = (rtw_read16(padapter,(0xaa))) & 0x7fff;
3606 					RTW_INFO("%s,read_score_board_val = 0x%x\n", __func__, read_score_board_val);
3607 			}
3608 			goto exit;
3609 
3610 		} else if (strcmp(tmp[1], "testmode") == 0) {
3611 
3612 			if (tmp[2] == NULL) {
3613 				err = -EINVAL;
3614 				goto exit;
3615 			}
3616 
3617 			val = simple_strtoul(tmp[2], &ptmp, 16);
3618 			RTW_INFO("get tmp, type  %s, val =0x%x!\n", tmp[1], val);
3619 
3620 			if (tmp[2] != NULL) {
3621 				_rtw_memset(extra, 0, wrqu->length);
3622 				ret = rtw_btcoex_btset_testmode(padapter, val);
3623 				if (!CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(ret, BT_STATUS_BT_OP_SUCCESS)) {
3624 					RTW_INFO("%s: BT_OP fail = 0x%x!\n", __FUNCTION__, val);
3625 					sprintf(extra, "BT_OP fail  0x%x!\n", val);
3626 				} else
3627 					sprintf(extra, "Set BT_OP 0x%x done!\n", val);
3628 			}
3629 
3630 		}
3631 #endif /* CONFIG_BTC */
3632 #endif
3633 	}
3634 
3635 exit:
3636 	if (setdata)
3637 		rtw_mfree(setdata, 1024);
3638 
3639 	wrqu->length = strlen(extra);
3640 	return err;
3641 
3642 }
3643 
rtw_mp_gpio(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)3644 int rtw_mp_gpio(struct net_device *dev,
3645 		struct iw_request_info *info,
3646 		struct iw_point *wrqu, char *extra)
3647 {
3648 	_adapter *padapter = rtw_netdev_priv(dev);
3649 	struct mp_priv *pmp_priv = (struct mp_priv *)&padapter->mppriv;
3650 	char input[RTW_IWD_MAX_LEN];
3651 	u8 gpio_id, gpio_enable;
3652 	int ret = 0;
3653 
3654 	if (wrqu->length > 128)
3655 		return -EFAULT;
3656 
3657 	_rtw_memset(input, 0, sizeof(input));
3658 
3659 	if (copy_from_user(input, wrqu->pointer, wrqu->length))
3660 		return -EFAULT;
3661 	input[wrqu->length] = '\0';
3662 
3663 	RTW_INFO("%s: input = %s\n", __func__, input);
3664 	_rtw_memset(extra, 0, wrqu->length);
3665 
3666 	ret = sscanf(input, "%hhd,%hhd", &gpio_id, &gpio_enable);
3667 	if (ret < 2){
3668 		return -EINVAL;
3669 	}
3670 	else if (gpio_id < 0 || gpio_id > 15) {
3671 		return -EINVAL;
3672 	}
3673 	else if (gpio_enable != 0 && gpio_enable != 1) {
3674 		return -EINVAL;
3675 	}
3676 
3677 	RTW_INFO("%s: gpio_id = %hhd, gpio_enable = %hhd\n", __func__, gpio_id , gpio_enable);
3678 
3679 	pmp_priv->gpio_id = gpio_id;
3680 	pmp_priv->gpio_enable = gpio_enable;
3681 
3682 	SetGpio(padapter);
3683 
3684 	sprintf(extra, "Set gpio_id:%d, gpio_enable:%d => done\n", gpio_id, gpio_enable);
3685 	wrqu->length = strlen(extra);
3686 
3687 	return 0;
3688 }
3689 
rtw_priv_mp_get(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wdata,char * extra)3690 int rtw_priv_mp_get(struct net_device *dev,
3691 			   struct iw_request_info *info,
3692 			   union iwreq_data *wdata, char *extra)
3693 {
3694 
3695 	struct iw_point *wrqu = (struct iw_point *)wdata;
3696 	u32 subcmd = wrqu->flags;
3697 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3698 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3699 	int status = 0;
3700 	u8 i = 0;
3701 	char *pch = extra;
3702 
3703 	if (!is_primary_adapter(padapter)) {
3704 		RTW_INFO("MP mode only primary Adapter support, iface id = %d,\n", padapter->iface_id);
3705 		RTW_INFO("***Please use Primary Adapter:["ADPT_FMT"]***\n", ADPT_ARG(GET_PRIMARY_ADAPTER(padapter)));
3706 		pch +=sprintf(pch, "Only primary Adapter support MP CMD\n");
3707 		pch +=sprintf(pch, "Please use Primary Adapter:"ADPT_FMT"", ADPT_ARG(GET_PRIMARY_ADAPTER(padapter)));
3708 		wrqu->length = strlen(extra);
3709 		return status;
3710 	}
3711 	for (i = 0; i < dvobj->iface_nums; i++) {
3712 		_adapter *iface = dvobj->padapters[i];
3713 
3714 		if (iface == NULL)
3715 			continue;
3716 		if (rtw_is_adapter_up(iface) == _FALSE)
3717 			continue;
3718 		if (MLME_IS_AP(iface)) {
3719 			RTW_INFO("Adapter:["ADPT_FMT"], Please Leave AP mode or Down Interface\n", ADPT_ARG(iface));
3720 			pch += sprintf(pch, "Check Adapter:"ADPT_FMT",\n\
3721 								Please Leave AP mode or Down Interface\n", ADPT_ARG(iface));
3722 			wrqu->length = strlen(extra);
3723 			return status;
3724 		}
3725 	}
3726 
3727 	RTW_INFO("%s mutx in %d\n", __func__, subcmd);
3728 
3729 	switch (subcmd) {
3730 	case MP_START:
3731 		RTW_INFO("set case mp_start\n");
3732 		status = rtw_mp_start(dev, info, wrqu, extra);
3733 		break;
3734 	case MP_STOP:
3735 		RTW_INFO("set case mp_stop\n");
3736 		status = rtw_mp_stop(dev, info, wrqu, extra);
3737 		break;
3738 	case MP_BANDWIDTH:
3739 		RTW_INFO("set case mp_bandwidth\n");
3740 		status = rtw_mp_bandwidth(dev, info, wrqu, extra);
3741 		break;
3742 	case MP_RESET_STATS:
3743 		RTW_INFO("set case MP_RESET_STATS\n");
3744 		status = rtw_mp_reset_stats(dev, info, wrqu, extra);
3745 		break;
3746 	case MP_SetRFPathSwh:
3747 		RTW_INFO("set MP_SetRFPathSwitch\n");
3748 		status = rtw_mp_SetRFPath(dev, info, wrqu, extra);
3749 		break;
3750 	case WRITE_REG:
3751 		status = rtw_mp_write_reg(dev, info, wrqu, extra);
3752 		break;
3753 	case WRITE_RF:
3754 		status = rtw_mp_write_rf(dev, info, wrqu, extra);
3755 		break;
3756 	case MP_PHYPARA:
3757 		RTW_INFO("mp_get  MP_PHYPARA\n");
3758 		status = rtw_mp_phypara(dev, info, wrqu, extra);
3759 		break;
3760 	case MP_CHANNEL:
3761 		RTW_INFO("set case mp_channel\n");
3762 		status = rtw_mp_channel(dev , info, wrqu, extra);
3763 		break;
3764 	case MP_TRXSC_OFFSET:
3765 		RTW_INFO("set case rtw_mp_trxsc_offset\n");
3766 		status = rtw_mp_trxsc_offset(dev , info, wrqu, extra);
3767 		break;
3768 	case READ_REG:
3769 		RTW_INFO("mp_get  READ_REG\n");
3770 		status = rtw_mp_read_reg(dev, info, wrqu, extra);
3771 		break;
3772 	case READ_RF:
3773 		RTW_INFO("mp_get  READ_RF\n");
3774 		status = rtw_mp_read_rf(dev, info, wrqu, extra);
3775 		break;
3776 	case MP_RATE:
3777 		RTW_INFO("set case mp_rate\n");
3778 		status = rtw_mp_rate(dev, info, wrqu, extra);
3779 		break;
3780 	case MP_TXPOWER:
3781 		RTW_INFO("set case MP_TXPOWER\n");
3782 		status = rtw_mp_txpower(dev, info, wrqu, extra);
3783 		break;
3784 	case MP_ANT_TX:
3785 		RTW_INFO("set case MP_ANT_TX\n");
3786 		status = rtw_mp_ant_tx(dev, info, wrqu, extra);
3787 		break;
3788 	case MP_ANT_RX:
3789 		RTW_INFO("set case MP_ANT_RX\n");
3790 		status = rtw_mp_ant_rx(dev, info, wrqu, extra);
3791 		break;
3792 	case MP_QUERY:
3793 		status = rtw_mp_trx_query(dev, info, wrqu, extra);
3794 		break;
3795 	case MP_CTX:
3796 		RTW_INFO("set case MP_CTX\n");
3797 		status = rtw_mp_ctx(dev, info, wrqu, extra);
3798 		break;
3799 	case MP_ARX:
3800 		RTW_INFO("set case MP_ARX\n");
3801 		status = rtw_mp_arx(dev, info, wrqu, extra);
3802 		break;
3803 	case MP_DUMP:
3804 		RTW_INFO("set case MP_DUMP\n");
3805 		status = rtw_mp_dump(dev, info, wrqu, extra);
3806 		break;
3807 	case MP_PSD:
3808 		RTW_INFO("set case MP_PSD\n");
3809 		status = rtw_mp_psd(dev, info, wrqu, extra);
3810 		break;
3811 	case MP_THER:
3812 		RTW_INFO("set case MP_THER\n");
3813 		status = rtw_mp_thermal(dev, info, wrqu, extra);
3814 		break;
3815 	case MP_PwrCtlDM:
3816 		RTW_INFO("set MP_PwrCtlDM\n");
3817 		status = rtw_mp_PwrCtlDM(dev, info, wrqu, extra);
3818 		break;
3819 	case MP_QueryDrvStats:
3820 		RTW_INFO("mp_get MP_QueryDrvStats\n");
3821 		status = rtw_mp_QueryDrv(dev, info, wdata, extra);
3822 		break;
3823 	case MP_PWRTRK:
3824 		RTW_INFO("set case MP_PWRTRK\n");
3825 		status = rtw_mp_pwrtrk(dev, info, wrqu, extra);
3826 		break;
3827 	case MP_SET_TSSIDE:
3828 		RTW_INFO("set case MP_TSSI_DE\n");
3829 		status = rtw_mp_set_tsside(dev, info, wrqu, extra);
3830 		break;
3831 	case EFUSE_SET:
3832 		RTW_INFO("set case efuse set\n");
3833 		status = rtw_ioctl_efuse_set(dev, info, wdata, extra);
3834 		break;
3835 	case EFUSE_GET:
3836 		RTW_INFO("efuse get EFUSE_GET\n");
3837 		status = rtw_ioctl_efuse_get(dev, info, wdata, extra);
3838 		break;
3839 	case MP_GET_TXPOWER_INX:
3840 		RTW_INFO("mp_get MP_GET_TXPOWER_INX\n");
3841 		status = rtw_mp_txpower_index(dev, info, wrqu, extra);
3842 		break;
3843 	case MP_GETVER:
3844 		RTW_INFO("mp_get MP_GETVER\n");
3845 		status = rtw_mp_getver(dev, info, wdata, extra);
3846 		break;
3847 	case MP_MON:
3848 		RTW_INFO("mp_get MP_MON\n");
3849 		status = rtw_mp_mon(dev, info, wdata, extra);
3850 		break;
3851 	case EFUSE_BT_MASK:
3852 		RTW_INFO("mp_get EFUSE_BT_MASK\n");
3853 		status = rtw_ioctl_efuse_bt_file_mask_load(dev, info, wdata, extra);
3854 		break;
3855 	case EFUSE_MASK:
3856 		RTW_INFO("mp_get EFUSE_MASK\n");
3857 		status = rtw_ioctl_efuse_file_mask_load(dev, info, wdata, extra);
3858 		break;
3859 	case EFUSE_FILE:
3860 		RTW_INFO("mp_get EFUSE_FILE\n");
3861 		status = rtw_ioctl_efuse_file_map_load(dev, info, wdata, extra);
3862 		break;
3863 	case EFUSE_FILE_STORE:
3864 		RTW_INFO("mp_get EFUSE_FILE_STORE\n");
3865 		/*status = rtw_efuse_file_map_store(dev, info, wdata, extra);*/
3866 		break;
3867 	case MP_TX:
3868 		RTW_INFO("mp_get MP_TX\n");
3869 		status = rtw_mp_tx(dev, info, wdata, extra);
3870 		break;
3871 	case MP_RX:
3872 		RTW_INFO("mp_get MP_RX\n");
3873 		status = rtw_mp_rx(dev, info, wdata, extra);
3874 		break;
3875 	case MP_HW_TX_MODE:
3876 		RTW_INFO("mp_get MP_HW_TX_MODE\n");
3877 		status = rtw_mp_hwtx(dev, info, wdata, extra);
3878 		break;
3879 	case MP_GET_TSSIDE:
3880 		RTW_INFO("mp_get TSSI_DE\n");
3881 		status = rtw_mp_get_tsside(dev, info, wrqu, extra);
3882 		break;
3883 #ifdef CONFIG_RTW_CUSTOMER_STR
3884 	case MP_CUSTOMER_STR:
3885 		RTW_INFO("customer str\n");
3886 		status = rtw_mp_customer_str(dev, info, wdata, extra);
3887 		break;
3888 #endif
3889 	case MP_PWRLMT:
3890 		RTW_INFO("mp_get MP_SETPWRLMT\n");
3891 		status = rtw_mp_pwrlmt(dev, info, wdata, extra);
3892 		break;
3893 	case  BT_EFUSE_FILE:
3894 		RTW_INFO("mp_get BT EFUSE_FILE\n");
3895 		status = rtw_ioctl_efuse_bt_file_map_load(dev, info, wdata, extra);
3896 		break;
3897 	case MP_SWRFPath:
3898 		RTW_INFO("mp_get MP_SWRFPath\n");
3899 		status = rtw_mp_switch_rf_path(dev, info, wrqu, extra);
3900 		break;
3901 	case MP_LINK:
3902 		RTW_INFO("mp_get MP_LINK\n");
3903 		status = rtw_mp_link(dev, info, wrqu, extra);
3904 		break;
3905 	case MP_DPK_TRK:
3906 		RTW_INFO("mp_get MP_DPK_TRK\n");
3907 		status = rtw_mp_dpk_track(dev, info, wdata, extra);
3908 		break;
3909 	case MP_DPK:
3910 		RTW_INFO("set MP_DPK\n");
3911 		status = rtw_mp_dpk(dev, info, wdata, extra);
3912 		break;
3913 	case MP_GET_PHL_TEST:
3914 		RTW_INFO("mp_get MP_GET_PHL_TEST\n");
3915 		status = rtw_mp_get_phl_io(dev, info, wrqu, extra);
3916 		break;
3917 	case MP_SET_PHL_TEST:
3918 		RTW_INFO("mp_get MP_SET_PHL_TEST\n");
3919 		status = rtw_mp_set_phl_io(dev, info, wrqu, extra);
3920 		break;
3921 	case MP_SET_PHL_TX_PATTERN:
3922 		RTW_INFO("mp_get MP_SET_PHL_TEST\n");
3923 		status = rtw_mp_tx_pattern_idx(dev, info, wdata, extra);
3924 		break;
3925 	case MP_SET_PHL_PLCP_TX_DATA:
3926 		RTW_INFO("mp_get MP_SET_PHL_PLCP_TX_DATA\n");
3927 		status = rtw_mp_tx_plcp_tx_data(dev, info, wdata, extra);
3928 		break;
3929 	case MP_SET_PHL_PLCP_TX_USER:
3930 		RTW_INFO("mp_get MP_SET_PHL_PLCP_TX_USER\n");
3931 		status = rtw_mp_tx_plcp_tx_user(dev, info, wdata, extra);
3932 		break;
3933 	case MP_SET_PHL_TX_METHOD:
3934 		RTW_INFO("mp_get MP_SET_PHL_TX_METHOD\n");
3935 		status = rtw_mp_tx_method(dev, info, wdata, extra);
3936 		break;
3937 	case MP_SET_PHL_CONIFG_PHY_NUM:
3938 		RTW_INFO("mp_get MP_SET_PHL_CONIFG_PHY_NUM\n");
3939 		status = rtw_mp_config_phy(dev, info, wdata, extra);
3940 		break;
3941 	case MP_PHL_RFK:
3942 		RTW_INFO("mp_get MP_PHL_RFK\n");
3943 		status = rtw_mp_phl_rfk(dev, info, wdata, extra);
3944 		break;
3945 	case MP_PHL_BTC_PATH:
3946 		RTW_INFO("mp_get MP_PHL_BTC_PATH\n");
3947 		status = rtw_mp_phl_btc_path(dev, info, wdata, extra);
3948 		break;
3949 	case MP_GET_HE:
3950 		RTW_INFO("mp_get MP_GET_HE\n");
3951 		status = rtw_mp_get_he(dev, info, wdata, extra);
3952 		break;
3953 	case MP_UUID:
3954 		RTW_INFO("set case MP_UUID\n");
3955 		status = rtw_mp_uuid(dev, info, wrqu, extra);
3956 		break;
3957 	case MP_GPIO:
3958 		RTW_INFO("set case MP_GPIO\n");
3959 		status = rtw_mp_gpio(dev, info, wrqu, extra);
3960 		break;
3961 	default:
3962 		status = -EIO;
3963 	}
3964 
3965 	return status;
3966 }
3967 
rtw_priv_mp_set(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wdata,char * extra)3968 int rtw_priv_mp_set(struct net_device *dev,
3969 			   struct iw_request_info *info,
3970 			   union iwreq_data *wdata, char *extra)
3971 {
3972 
3973 	struct iw_point *wrqu = (struct iw_point *)wdata;
3974 	u32 subcmd = wrqu->flags;
3975 	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3976 	int status = 0;
3977 
3978 #ifdef CONFIG_CONCURRENT_MODE
3979 	if (!is_primary_adapter(padapter)) {
3980 		RTW_INFO("MP mode only primary Adapter support\n");
3981 		return -EIO;
3982 	}
3983 #endif
3984 
3985 	RTW_INFO("%s mutx in %d\n", __func__, subcmd);
3986 	//_enter_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);
3987 	switch (subcmd) {
3988 	case MP_DISABLE_BT_COEXIST:
3989 		RTW_INFO("set case MP_DISABLE_BT_COEXIST\n");
3990 		status = rtw_mp_disable_bt_coexist(dev, info, wdata, extra);
3991 		break;
3992 	case MP_IQK:
3993 		RTW_INFO("set MP_IQK\n");
3994 		status = rtw_mp_iqk(dev, info, wrqu, extra);
3995 		break;
3996 	case MP_LCK:
3997 		RTW_INFO("set MP_LCK\n");
3998 		status = rtw_mp_lck(dev, info, wrqu, extra);
3999 	break;
4000 
4001 	default:
4002 		status = -EIO;
4003 	}
4004 	//_exit_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);
4005 	RTW_INFO("%s mutx done %d\n", __func__, subcmd);
4006 
4007 	return status;
4008 }
4009 
4010 #endif
4011