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