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