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