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 #ifdef CONFIG_RTL8723F
1389 ther_path_addr[0] = EEPROM_THERMAL_METER_8723F;
1390 #endif
1391
1392 if (copy_from_user(extra, wrqu->pointer, wrqu->length))
1393 return -EFAULT;
1394
1395 if ((strncmp(extra, "write", 6) == 0)) {
1396 int i;
1397 u16 raw_cursize = 0, raw_maxsize = 0;
1398 #ifdef RTW_HALMAC
1399 raw_maxsize = efuse_GetavailableSize(padapter);
1400 #else
1401 efuse_GetCurrentSize(padapter, &raw_cursize);
1402 raw_maxsize = efuse_GetMaxSize(padapter);
1403 #endif
1404 RTW_INFO("[eFuse available raw size]= %d bytes\n", raw_maxsize - raw_cursize);
1405 if (2 > raw_maxsize - raw_cursize) {
1406 RTW_INFO("no available efuse!\n");
1407 return -EFAULT;
1408 }
1409
1410 for (i = 0; i < hal_spec->rf_reg_path_num; i++) {
1411 GetThermalMeter(padapter, i , &val[i]);
1412 if (ther_path_addr[i] != 0 && val[i] != 0) {
1413 if (rtw_efuse_map_write(padapter, ther_path_addr[i], cnt, &val[i]) == _FAIL) {
1414 RTW_INFO("Error efuse write thermal addr 0x%x ,val = 0x%x\n", ther_path_addr[i], val[i]);
1415 return -EFAULT;
1416 }
1417 } else {
1418 RTW_INFO("Error efuse write thermal Null addr,val \n");
1419 return -EFAULT;
1420 }
1421 }
1422 _rtw_memset(extra, 0, wrqu->length);
1423 sprintf(extra, " efuse write ok :%d", val[0]);
1424 } else {
1425 ret = sscanf(extra, "%d", &rfpath);
1426 if (ret < 1) {
1427 rfpath = RF_PATH_A;
1428 RTW_INFO("default thermal of path(%d)\n", rfpath);
1429 }
1430 if (rfpath >= hal_spec->rf_reg_path_num)
1431 return -EINVAL;
1432
1433 RTW_INFO("read thermal of path(%d)\n", rfpath);
1434 GetThermalMeter(padapter, rfpath, &val[0]);
1435
1436 _rtw_memset(extra, 0, wrqu->length);
1437 sprintf(extra, "%d", val[0]);
1438 }
1439 wrqu->length = strlen(extra);
1440
1441 return 0;
1442 }
1443
1444
1445
rtw_mp_reset_stats(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1446 int rtw_mp_reset_stats(struct net_device *dev,
1447 struct iw_request_info *info,
1448 struct iw_point *wrqu, char *extra)
1449 {
1450 struct mp_priv *pmp_priv;
1451 PADAPTER padapter = rtw_netdev_priv(dev);
1452
1453 pmp_priv = &padapter->mppriv;
1454
1455 pmp_priv->tx.sended = 0;
1456 pmp_priv->tx_pktcount = 0;
1457 pmp_priv->rx_pktcount = 0;
1458 pmp_priv->rx_pktcount_filter_out = 0;
1459 pmp_priv->rx_crcerrpktcount = 0;
1460
1461 rtw_reset_phy_rx_counters(padapter);
1462 rtw_reset_mac_rx_counters(padapter);
1463
1464 _rtw_memset(extra, 0, wrqu->length);
1465 sprintf(extra, "mp_reset_stats ok\n");
1466 wrqu->length = strlen(extra);
1467
1468 return 0;
1469 }
1470
1471
rtw_mp_dump(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1472 int rtw_mp_dump(struct net_device *dev,
1473 struct iw_request_info *info,
1474 struct iw_point *wrqu, char *extra)
1475 {
1476 struct mp_priv *pmp_priv;
1477 u8 input[RTW_IWD_MAX_LEN];
1478 PADAPTER padapter = rtw_netdev_priv(dev);
1479
1480 pmp_priv = &padapter->mppriv;
1481
1482 if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1483 return -EFAULT;
1484
1485 if (copy_from_user(input, wrqu->pointer, wrqu->length))
1486 return -EFAULT;
1487
1488 if (strncmp(input, "all", 4) == 0) {
1489 mac_reg_dump(RTW_DBGDUMP, padapter);
1490 bb_reg_dump(RTW_DBGDUMP, padapter);
1491 rf_reg_dump(RTW_DBGDUMP, padapter);
1492 }
1493 return 0;
1494 }
1495
1496
rtw_mp_phypara(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1497 int rtw_mp_phypara(struct net_device *dev,
1498 struct iw_request_info *info,
1499 struct iw_point *wrqu, char *extra)
1500 {
1501
1502 PADAPTER padapter = rtw_netdev_priv(dev);
1503 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1504 char input[RTW_IWD_MAX_LEN];
1505 u32 invalxcap = 0, ret = 0, bwrite_xcap = 0, hwxtaladdr = 0;
1506 u16 pgval;
1507
1508 if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1509 return -EFAULT;
1510
1511 if (copy_from_user(input, wrqu->pointer, wrqu->length))
1512 return -EFAULT;
1513
1514 RTW_INFO("%s:priv in=%s\n", __func__, input);
1515 bwrite_xcap = (strncmp(input, "write_xcap=", 11) == 0) ? 1 : 0;
1516
1517 if (bwrite_xcap == 1) {
1518 ret = sscanf(input, "write_xcap=%d", &invalxcap);
1519 invalxcap = invalxcap & 0x7f; /* xtal bit 0 ~6 */
1520 RTW_INFO("get crystal_cap %d\n", invalxcap);
1521
1522 if (IS_HARDWARE_TYPE_8822C(padapter) && ret == 1) {
1523 hwxtaladdr = 0x110;
1524 pgval = invalxcap | 0x80; /* reserved default bit7 on */
1525 pgval = pgval | pgval << 8; /* xtal xi/xo efuse 0x110 0x111 */
1526
1527 RTW_INFO("Get crystal_cap 0x%x\n", pgval);
1528 if (rtw_efuse_map_write(padapter, hwxtaladdr, 2, (u8*)&pgval) == _FAIL) {
1529 RTW_INFO("%s: rtw_efuse_map_write xcap error!!\n", __func__);
1530 sprintf(extra, "write xcap pgdata fail");
1531 ret = -EFAULT;
1532 } else
1533 sprintf(extra, "write xcap pgdata ok");
1534
1535 }
1536 } else {
1537 ret = sscanf(input, "xcap=%d", &invalxcap);
1538
1539 if (ret == 1) {
1540 pHalData->crystal_cap = (u8)invalxcap;
1541 RTW_INFO("%s:crystal_cap=%d\n", __func__, pHalData->crystal_cap);
1542
1543 if (rtw_phydm_set_crystal_cap(padapter, pHalData->crystal_cap) == _FALSE) {
1544 RTW_ERR("set crystal_cap failed\n");
1545 rtw_warn_on(1);
1546 }
1547 sprintf(extra, "Set xcap=%d", invalxcap);
1548 }
1549 }
1550
1551 wrqu->length = strlen(extra) + 1;
1552 return ret;
1553 }
1554
1555
rtw_mp_SetRFPath(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1556 int rtw_mp_SetRFPath(struct net_device *dev,
1557 struct iw_request_info *info,
1558 struct iw_point *wrqu, char *extra)
1559 {
1560 PADAPTER padapter = rtw_netdev_priv(dev);
1561 char input[RTW_IWD_MAX_LEN];
1562 int bMain = 1, bTurnoff = 1;
1563 #ifdef CONFIG_ANTENNA_DIVERSITY
1564 u8 ret = _TRUE;
1565 #endif
1566
1567 if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1568 return -EFAULT;
1569
1570 RTW_INFO("%s:iwpriv in=%s\n", __func__, input);
1571
1572 if (copy_from_user(input, wrqu->pointer, wrqu->length))
1573 return -EFAULT;
1574
1575 bMain = strncmp(input, "1", 2); /* strncmp TRUE is 0*/
1576 bTurnoff = strncmp(input, "0", 3); /* strncmp TRUE is 0*/
1577
1578 _rtw_memset(extra, 0, wrqu->length);
1579 #ifdef CONFIG_ANTENNA_DIVERSITY
1580 if (bMain == 0)
1581 ret = rtw_mp_set_antdiv(padapter, _TRUE);
1582 else
1583 ret = rtw_mp_set_antdiv(padapter, _FALSE);
1584 if (ret == _FALSE)
1585 RTW_INFO("%s:ANTENNA_DIVERSITY FAIL\n", __func__);
1586 #endif
1587
1588 if (bMain == 0) {
1589 MP_PHY_SetRFPathSwitch(padapter, _TRUE);
1590 RTW_INFO("%s:PHY_SetRFPathSwitch=TRUE\n", __func__);
1591 sprintf(extra, "mp_setrfpath Main\n");
1592
1593 } else if (bTurnoff == 0) {
1594 MP_PHY_SetRFPathSwitch(padapter, _FALSE);
1595 RTW_INFO("%s:PHY_SetRFPathSwitch=FALSE\n", __func__);
1596 sprintf(extra, "mp_setrfpath Aux\n");
1597 } else {
1598 bMain = MP_PHY_QueryRFPathSwitch(padapter);
1599 RTW_INFO("%s:Query RF Path = %s\n", __func__, (bMain ? "Main":"Aux"));
1600 sprintf(extra, "RF Path %s\n" , (bMain ? "1":"0"));
1601 }
1602
1603 wrqu->length = strlen(extra);
1604
1605 return 0;
1606 }
1607
1608
rtw_mp_switch_rf_path(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1609 int rtw_mp_switch_rf_path(struct net_device *dev,
1610 struct iw_request_info *info,
1611 struct iw_point *wrqu, char *extra)
1612 {
1613 PADAPTER padapter = rtw_netdev_priv(dev);
1614 struct mp_priv *pmp_priv;
1615 char input[RTW_IWD_MAX_LEN];
1616 char *pch;
1617 int bwlg = 1, bwla = 1, btg = 1, bbt=1;
1618 u8 ret = 0;
1619
1620 if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1621 return -EFAULT;
1622
1623 if (copy_from_user(input, wrqu->pointer, wrqu->length))
1624 return -EFAULT;
1625
1626 pmp_priv = &padapter->mppriv;
1627
1628 RTW_INFO("%s: in=%s\n", __func__, input);
1629
1630 _rtw_memset(extra, '\0', wrqu->length);
1631 pch = extra;
1632 #ifdef CONFIG_RTL8821C /* only support for 8821c wlg/wla/btg/bt RF switch path */
1633 if ((strncmp(input, "WLG", 3) == 0) || (strncmp(input, "1", 1) == 0)) {
1634 pmp_priv->rf_path_cfg = SWITCH_TO_WLG;
1635 pch += sprintf(pch, "switch rf path WLG\n");
1636
1637 } else if ((strncmp(input, "WLA", 3) == 0) || (strncmp(input, "2", 1) == 0)) {
1638 pmp_priv->rf_path_cfg = SWITCH_TO_WLA;
1639 pch += sprintf(pch, "switch rf path WLA\n");
1640
1641 } else if ((strncmp(input, "BTG", 3) == 0) || (strncmp(input, "0", 1) == 0)) {
1642 pmp_priv->rf_path_cfg = SWITCH_TO_BTG;
1643 pch += sprintf(pch, "switch rf path BTG\n");
1644
1645 } else if ((strncmp(input, "BT", 3) == 0) || (strncmp(input, "3", 1) == 0)) {
1646 pmp_priv->rf_path_cfg = SWITCH_TO_BT;
1647 pch += sprintf(pch, "switch rf path BT\n");
1648 } else {
1649 pmp_priv->rf_path_cfg = SWITCH_TO_WLG;
1650 pch += sprintf(pch, "Error input, default set WLG\n");
1651 return -EFAULT;
1652 }
1653
1654 mp_phy_switch_rf_path_set(padapter, &pmp_priv->rf_path_cfg);
1655 #endif
1656 wrqu->length = strlen(extra);
1657
1658 return ret;
1659
1660 }
rtw_mp_QueryDrv(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1661 int rtw_mp_QueryDrv(struct net_device *dev,
1662 struct iw_request_info *info,
1663 union iwreq_data *wrqu, char *extra)
1664 {
1665 PADAPTER padapter = rtw_netdev_priv(dev);
1666 char input[RTW_IWD_MAX_LEN];
1667 int qAutoLoad = 1;
1668
1669 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1670
1671 if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->data.length))
1672 return -EFAULT;
1673
1674 if (copy_from_user(input, wrqu->data.pointer, wrqu->data.length))
1675 return -EFAULT;
1676 RTW_INFO("%s:iwpriv in=%s\n", __func__, input);
1677
1678 qAutoLoad = strncmp(input, "autoload", 8); /* strncmp TRUE is 0*/
1679
1680 if (qAutoLoad == 0) {
1681 RTW_INFO("%s:qAutoLoad\n", __func__);
1682
1683 if (pHalData->bautoload_fail_flag)
1684 sprintf(extra, "fail");
1685 else
1686 sprintf(extra, "ok");
1687 }
1688 wrqu->data.length = strlen(extra) + 1;
1689 return 0;
1690 }
1691
1692
rtw_mp_PwrCtlDM(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1693 int rtw_mp_PwrCtlDM(struct net_device *dev,
1694 struct iw_request_info *info,
1695 struct iw_point *wrqu, char *extra)
1696 {
1697 PADAPTER padapter = rtw_netdev_priv(dev);
1698 u8 input[RTW_IWD_MAX_LEN];
1699 u8 pwrtrk_state = 0;
1700 u8 pwtk_type[5][25] = {"Thermal tracking off","Thermal tracking on",
1701 "TSSI tracking off","TSSI tracking on","TSSI calibration"};
1702
1703 if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1704 return -EFAULT;
1705
1706 if (copy_from_user(input, wrqu->pointer, wrqu->length))
1707 return -EFAULT;
1708
1709 input[wrqu->length - 1] = '\0';
1710 RTW_INFO("%s: in=%s\n", __func__, input);
1711
1712 if (wrqu->length == 2) {
1713 if(input[0] >= '0' && input[0] <= '4') {
1714 pwrtrk_state = rtw_atoi(input);
1715 MPT_PwrCtlDM(padapter, pwrtrk_state);
1716 sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1717 } else {
1718 sprintf(extra, "Error unknown number ! Please check your input number\n"
1719 " 0 : Thermal tracking off\n 1 : Thermal tracking on\n 2 : TSSI tracking off\n"
1720 " 3 : TSSI tracking on\n 4 : TSSI calibration\n");
1721 }
1722 wrqu->length = strlen(extra);
1723
1724 return 0;
1725 }
1726 if (strncmp(input, "start", 5) == 0 || strncmp(input, "thertrk on", 10) == 0) {/* strncmp TRUE is 0*/
1727 pwrtrk_state = 1;
1728 sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1729 } else if (strncmp(input, "thertrk off", 11) == 0 || strncmp(input, "stop", 5) == 0) {
1730 pwrtrk_state = 0;
1731 sprintf(extra, "PwrCtlDM stop %s\n" , pwtk_type[pwrtrk_state]);
1732 } else if (strncmp(input, "tssitrk off", 11) == 0){
1733 pwrtrk_state = 2;
1734 sprintf(extra, "PwrCtlDM stop %s\n" , pwtk_type[pwrtrk_state]);
1735 } else if (strncmp(input, "tssitrk on", 10) == 0){
1736 pwrtrk_state = 3;
1737 sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1738 } else if (strncmp(input, "tssik", 5) == 0){
1739 pwrtrk_state = 4;
1740 sprintf(extra, "PwrCtlDM start %s\n" , pwtk_type[pwrtrk_state]);
1741 } else {
1742 sprintf(extra, "Error input !!!\n"
1743 " thertrk off : Thermal tracking off\n thertrk on : Thermal tracking on\n"
1744 " tssitrk off : TSSI tracking off\n tssitrk on : TSSI tracking on\n tssik : TSSI calibration\n\n"
1745 " 0 : Thermal tracking off\n 1 : Thermal tracking on\n 2 : TSSI tracking off\n"
1746 " 3 : TSSI tracking on\n 4 : TSSI calibration\n");
1747 wrqu->length = strlen(extra);
1748 return 0;
1749 }
1750
1751 MPT_PwrCtlDM(padapter, pwrtrk_state);
1752 wrqu->length = strlen(extra);
1753
1754 return 0;
1755 }
1756
rtw_mp_iqk(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1757 int rtw_mp_iqk(struct net_device *dev,
1758 struct iw_request_info *info,
1759 struct iw_point *wrqu, char *extra)
1760 {
1761 PADAPTER padapter = rtw_netdev_priv(dev);
1762
1763 rtw_mp_trigger_iqk(padapter);
1764
1765 return 0;
1766 }
1767
rtw_mp_lck(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1768 int rtw_mp_lck(struct net_device *dev,
1769 struct iw_request_info *info,
1770 struct iw_point *wrqu, char *extra)
1771 {
1772 PADAPTER padapter = rtw_netdev_priv(dev);
1773
1774 rtw_mp_trigger_lck(padapter);
1775
1776 return 0;
1777 }
1778
rtw_mp_dpk(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1779 int rtw_mp_dpk(struct net_device *dev,
1780 struct iw_request_info *info,
1781 union iwreq_data *wrqu, char *extra)
1782 {
1783 PADAPTER padapter = rtw_netdev_priv(dev);
1784 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1785 struct dm_struct *pDM_Odm = &pHalData->odmpriv;
1786 struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
1787 char *pch;
1788
1789 u8 ips_mode = IPS_NUM; /* init invalid value */
1790 u8 lps_mode = PS_MODE_NUM; /* init invalid value */
1791
1792 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
1793 return -EFAULT;
1794
1795 *(extra + wrqu->data.length) = '\0';
1796 pch = extra;
1797
1798 if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
1799 pDM_Odm->dpk_info.is_dpk_enable = 0;
1800 halrf_dpk_enable_disable(pDM_Odm);
1801 pch += sprintf(pch, "set dpk off\n");
1802
1803 } else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
1804 pDM_Odm->dpk_info.is_dpk_enable = 1;
1805 halrf_dpk_enable_disable(pDM_Odm);
1806 pch += sprintf(pch, "set dpk on\n");
1807 } else {
1808 #ifdef CONFIG_LPS
1809 lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */
1810 rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
1811 #endif
1812 #ifdef CONFIG_IPS
1813 ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
1814 rtw_pm_set_ips(padapter, IPS_NONE);
1815 #endif
1816 rtw_mp_trigger_dpk(padapter);
1817 if (padapter->registrypriv.mp_mode == 0) {
1818 #ifdef CONFIG_IPS
1819 rtw_pm_set_ips(padapter, ips_mode);
1820 #endif /* CONFIG_IPS */
1821
1822 #ifdef CONFIG_LPS
1823 rtw_pm_set_lps(padapter, lps_mode);
1824 #endif /* CONFIG_LPS */
1825 }
1826 pch += sprintf(pch, "set dpk trigger\n");
1827 }
1828
1829 wrqu->data.length = strlen(extra);
1830
1831 return 0;
1832 }
1833
rtw_mp_get_tsside(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1834 int rtw_mp_get_tsside(struct net_device *dev,
1835 struct iw_request_info *info,
1836 struct iw_point *wrqu, char *extra)
1837 {
1838 PADAPTER padapter = rtw_netdev_priv(dev);
1839 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1840 struct dm_struct *pDM_Odm = &pHalData->odmpriv;
1841 char input[RTW_IWD_MAX_LEN];
1842 u8 rfpath;
1843 u32 tssi_de;
1844
1845 u8 legal_param_num = 1;
1846 int param_num;
1847 char pout_str_buf[7];
1848 u8 signed_flag = 0;
1849 int integer_num;
1850 u32 decimal_num;
1851 s32 pout;
1852 char *pextra;
1853 int i;
1854
1855 #ifdef CONFIG_RTL8723F
1856 /*
1857 * rtwpriv wlan0 mp_get_tsside rf_path pout
1858 * rf_path : 0 ~ 1
1859 * pout : -15.000 ~ 25.000
1860 * ex : rtwpriv wlan0 mp_get_tsside 0 -12.123
1861 */
1862 legal_param_num = 2;
1863 #endif
1864 if (wrqu->length > 128)
1865 return -EFAULT;
1866
1867 _rtw_memset(input, 0, sizeof(input));
1868
1869 if (copy_from_user(input, wrqu->pointer, wrqu->length))
1870 return -EFAULT;
1871
1872 param_num = sscanf(input, "%hhu %7s", &rfpath, pout_str_buf);
1873
1874 /* Check parameter format*/
1875 if(param_num != legal_param_num)
1876 goto invalid_param_format;
1877
1878 if(rfpath <0 || 3 < rfpath)
1879 goto invalid_param_format;
1880
1881 #ifdef CONFIG_RTL8723F
1882 /* Convert pout from floating-point to integer
1883 * For Floating-Point Precision, pout*1000
1884 */
1885 if(pout_str_buf[0] == '-')
1886 signed_flag = 1;
1887 i = sscanf(pout_str_buf, "%d.%3u", &integer_num, &decimal_num);
1888 pout = integer_num * 1000;
1889 if(i == 2) {
1890 /* Convert decimal number
1891 * ex : 0.1 => 100, -0.1 => 100
1892 */
1893 decimal_num = (decimal_num < 10) ? decimal_num * 100 : decimal_num;
1894 decimal_num = (decimal_num < 100) ? decimal_num * 10 : decimal_num;
1895 pout += ((pout < 0 || signed_flag == 1) ? -decimal_num : decimal_num);
1896 }
1897 if(pout < -15000 || 25000 < pout)
1898 goto invalid_param_format;
1899 #endif
1900
1901 #ifdef CONFIG_RTL8723F
1902 /* For Floating-Point Precision, pout */
1903 tssi_de = halrf_get_online_tssi_de(pDM_Odm, rfpath, pout);
1904 #else
1905 tssi_de = halrf_tssi_get_de(pDM_Odm, rfpath);
1906 #endif
1907
1908 if (rfpath == 0)
1909 sprintf(extra, "patha=%d hex=%02x", tssi_de, (u8)tssi_de);
1910 else if (rfpath == 1)
1911 sprintf(extra, "pathb=%d hex=%02x", tssi_de, (u8)tssi_de);
1912 else if (rfpath == 2)
1913 sprintf(extra, "pathc=%d hex=%02x", tssi_de, (u8)tssi_de);
1914 else if (rfpath == 3)
1915 sprintf(extra, "pathd=%d hex=%02x", tssi_de, (u8)tssi_de);
1916
1917 wrqu->length = strlen(extra);
1918 return 0;
1919
1920 invalid_param_format:
1921 sprintf(extra, "Invalid command format, please indicate RF path 0/1/2/3");
1922 #ifdef CONFIG_RTL8723F
1923 pextra = extra + strlen(extra);
1924 sprintf(pextra, " and pout value : -15.000 ~ 25.000\n");
1925 #endif
1926 wrqu->length = strlen(extra);
1927
1928 return 0;
1929 }
1930
rtw_mp_set_tsside(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)1931 int rtw_mp_set_tsside(struct net_device *dev,
1932 struct iw_request_info *info,
1933 struct iw_point *wrqu, char *extra)
1934 {
1935 u32 tsside_a = 0, tsside_b = 0, tsside_c = 0, tsside_d = 0;
1936 char input[RTW_IWD_MAX_LEN];
1937
1938 PADAPTER padapter = rtw_netdev_priv(dev);
1939 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1940 struct dm_struct *pDM_Odm = &pHalData->odmpriv;
1941
1942 if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
1943 return -EFAULT;
1944
1945 if (copy_from_user(input, wrqu->pointer, wrqu->length))
1946 return -EFAULT;
1947
1948 if (sscanf(input, "patha=%d", &tsside_a) == 1) {
1949 sprintf(extra, "Set TSSI DE path_A: %d", tsside_a);
1950 halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_a, RF_PATH_A);
1951 mpt_trigger_tssi_tracking(padapter, RF_PATH_A);
1952
1953 } else if (sscanf(input, "pathb=%d", &tsside_b) == 1) {
1954 sprintf(extra, "Set TSSI DE path_B: %d", tsside_b);
1955 halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_b, RF_PATH_B);
1956 mpt_trigger_tssi_tracking(padapter, RF_PATH_B);
1957
1958 } else if (sscanf(input, "pathc=%d", &tsside_c) == 1) {
1959 sprintf(extra, "Set TSSI DE path_C: %d", tsside_c);
1960 halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_c, RF_PATH_C);
1961 mpt_trigger_tssi_tracking(padapter, RF_PATH_C);
1962
1963 } else if (sscanf(input, "pathd=%d", &tsside_d) == 1) {
1964 sprintf(extra, "Set TSSI DE path_D: %d", tsside_d);
1965 halrf_tssi_set_de_for_tx_verify(pDM_Odm, tsside_d, RF_PATH_D);
1966 mpt_trigger_tssi_tracking(padapter, RF_PATH_D);
1967
1968 } else
1969 sprintf(extra, "Invalid command format, please input TSSI DE value within patha/b/c/d=xyz");
1970
1971 wrqu->length = strlen(extra);
1972
1973 return 0;
1974 }
1975
rtw_mp_getver(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1976 int rtw_mp_getver(struct net_device *dev,
1977 struct iw_request_info *info,
1978 union iwreq_data *wrqu, char *extra)
1979 {
1980 PADAPTER padapter = rtw_netdev_priv(dev);
1981 struct mp_priv *pmp_priv;
1982
1983 pmp_priv = &padapter->mppriv;
1984
1985 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
1986 return -EFAULT;
1987
1988 sprintf(extra, "rtwpriv=%d\n", RTWPRIV_VER_INFO);
1989 wrqu->data.length = strlen(extra);
1990 return 0;
1991 }
1992
1993
rtw_mp_mon(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)1994 int rtw_mp_mon(struct net_device *dev,
1995 struct iw_request_info *info,
1996 union iwreq_data *wrqu, char *extra)
1997 {
1998 PADAPTER padapter = rtw_netdev_priv(dev);
1999 struct mp_priv *pmp_priv = &padapter->mppriv;
2000 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2001 struct hal_ops *pHalFunc = &padapter->hal_func;
2002 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
2003 int bstart = 1, bstop = 1;
2004
2005 networkType = Ndis802_11Infrastructure;
2006 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2007 return -EFAULT;
2008
2009 *(extra + wrqu->data.length) = '\0';
2010 rtw_pm_set_ips(padapter, IPS_NONE);
2011 LeaveAllPowerSaveMode(padapter);
2012
2013 #ifdef CONFIG_MP_INCLUDED
2014 if (init_mp_priv(padapter) == _FAIL)
2015 RTW_INFO("%s: initialize MP private data Fail!\n", __func__);
2016 padapter->mppriv.channel = 6;
2017
2018 bstart = strncmp(extra, "start", 5); /* strncmp TRUE is 0*/
2019 bstop = strncmp(extra, "stop", 4); /* strncmp TRUE is 0*/
2020 if (bstart == 0) {
2021 mp_join(padapter, WIFI_FW_ADHOC_STATE);
2022 SetPacketRx(padapter, _TRUE, _FALSE);
2023 SetChannel(padapter);
2024 pmp_priv->rx_bindicatePkt = _TRUE;
2025 pmp_priv->bRTWSmbCfg = _TRUE;
2026 sprintf(extra, "monitor mode start\n");
2027 } else if (bstop == 0) {
2028 SetPacketRx(padapter, _FALSE, _FALSE);
2029 pmp_priv->rx_bindicatePkt = _FALSE;
2030 pmp_priv->bRTWSmbCfg = _FALSE;
2031 padapter->registrypriv.mp_mode = 1;
2032 pHalFunc->hal_deinit(padapter);
2033 padapter->registrypriv.mp_mode = 0;
2034 pHalFunc->hal_init(padapter);
2035 /*rtw_disassoc_cmd(padapter, 0, 0);*/
2036 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
2037 rtw_disassoc_cmd(padapter, 500, 0);
2038 rtw_indicate_disconnect(padapter, 0, _FALSE);
2039 /*rtw_free_assoc_resources_cmd(padapter, _TRUE, 0);*/
2040 }
2041 rtw_pm_set_ips(padapter, IPS_NORMAL);
2042 sprintf(extra, "monitor mode Stop\n");
2043 }
2044 #endif
2045 wrqu->data.length = strlen(extra);
2046 return 0;
2047 }
2048
rtw_mp_pretx_proc(PADAPTER padapter,u8 bStartTest,char * extra)2049 int rtw_mp_pretx_proc(PADAPTER padapter, u8 bStartTest, char *extra)
2050 {
2051 struct mp_priv *pmp_priv = &padapter->mppriv;
2052 char *pextra = extra;
2053
2054 switch (pmp_priv->mode) {
2055
2056 case MP_PACKET_TX:
2057 if (bStartTest == 0) {
2058 pmp_priv->tx.stop = 1;
2059 pmp_priv->mode = MP_ON;
2060 #ifdef CONFIG_RTL8822B
2061 rtw_write8(padapter, 0x838, 0x61);
2062 #endif
2063 sprintf(extra, "Stop continuous Tx");
2064 } else if (pmp_priv->tx.stop == 1) {
2065 pextra = extra + strlen(extra);
2066 pextra += sprintf(pextra, "\nStart continuous DA=ffffffffffff len=1500 count=%u\n", pmp_priv->tx.count);
2067 pmp_priv->tx.stop = 0;
2068 #ifdef CONFIG_RTL8822B
2069 rtw_write8(padapter, 0x838, 0x6d);
2070 #endif
2071 SetPacketTx(padapter);
2072 } else
2073 return -EFAULT;
2074 return 0;
2075 case MP_SINGLE_TONE_TX:
2076 if (bStartTest != 0)
2077 strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2078 SetSingleToneTx(padapter, (u8)bStartTest);
2079 break;
2080 case MP_CONTINUOUS_TX:
2081 if (bStartTest != 0)
2082 strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2083 SetContinuousTx(padapter, (u8)bStartTest);
2084 break;
2085 case MP_CARRIER_SUPPRISSION_TX:
2086 if (bStartTest != 0) {
2087 if (HwRateToMPTRate(pmp_priv->rateidx) <= MPT_RATE_11M)
2088 strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2089 else
2090 strcat(extra, "\nSpecify carrier suppression but not CCK rate");
2091 }
2092 SetCarrierSuppressionTx(padapter, (u8)bStartTest);
2093 break;
2094 case MP_SINGLE_CARRIER_TX:
2095 if (bStartTest != 0)
2096 strcat(extra, "\nStart continuous DA=ffffffffffff len=1500\n infinite=yes.");
2097 SetSingleCarrierTx(padapter, (u8)bStartTest);
2098 break;
2099
2100 default:
2101 sprintf(extra, "Error! Continuous-Tx is not on-going.");
2102 return -EFAULT;
2103 }
2104
2105 if (bStartTest == 1 && pmp_priv->mode != MP_ON) {
2106 struct mp_priv *pmp_priv = &padapter->mppriv;
2107
2108 if (pmp_priv->tx.stop == 0) {
2109 pmp_priv->tx.stop = 1;
2110 rtw_msleep_os(5);
2111 }
2112 #ifdef CONFIG_80211N_HT
2113 if(padapter->registrypriv.ht_enable &&
2114 is_supported_ht(padapter->registrypriv.wireless_mode))
2115 pmp_priv->tx.attrib.ht_en = 1;
2116 #endif
2117 pmp_priv->tx.stop = 0;
2118 pmp_priv->tx.count = 1;
2119 SetPacketTx(padapter);
2120 } else
2121 pmp_priv->mode = MP_ON;
2122
2123 #if defined(CONFIG_RTL8812A)
2124 if (IS_HARDWARE_TYPE_8812AU(padapter)) {
2125 /* <20130425, Kordan> Turn off OFDM Rx to prevent from CCA causing Tx hang.*/
2126 if (pmp_priv->mode == MP_PACKET_TX)
2127 phy_set_bb_reg(padapter, rCCAonSec_Jaguar, BIT3, 1);
2128 else
2129 phy_set_bb_reg(padapter, rCCAonSec_Jaguar, BIT3, 0);
2130 }
2131 #endif
2132
2133 return 0;
2134 }
2135
2136
rtw_mp_tx(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2137 int rtw_mp_tx(struct net_device *dev,
2138 struct iw_request_info *info,
2139 union iwreq_data *wrqu, char *extra)
2140 {
2141 PADAPTER padapter = rtw_netdev_priv(dev);
2142 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2143 struct mp_priv *pmp_priv = &padapter->mppriv;
2144 PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx);
2145 char *pextra = extra;
2146 u32 bandwidth = 0, sg = 0, channel = 6, txpower = 40, rate = 108, ant = 0, txmode = 1, count = 0;
2147 u8 bStartTest = 1, status = 0;
2148 #ifdef CONFIG_MP_VHT_HW_TX_MODE
2149 u8 Idx = 0, tmpU1B;
2150 #endif
2151 u16 antenna = 0;
2152
2153 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2154 return -EFAULT;
2155 RTW_INFO("extra = %s\n", extra);
2156 #ifdef CONFIG_CONCURRENT_MODE
2157 if (!is_primary_adapter(padapter)) {
2158 sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n");
2159 wrqu->data.length = strlen(extra);
2160 return 0;
2161 }
2162 #endif
2163
2164 if (strncmp(extra, "stop", 3) == 0) {
2165 bStartTest = 0; /* To set Stop*/
2166 pmp_priv->tx.stop = 1;
2167 sprintf(extra, "Stop continuous Tx");
2168 status = rtw_mp_pretx_proc(padapter, bStartTest, extra);
2169 wrqu->data.length = strlen(extra);
2170 return status;
2171 } else if (strncmp(extra, "count", 5) == 0) {
2172 if (sscanf(extra, "count=%d", &count) < 1)
2173 RTW_INFO("Got Count=%d]\n", count);
2174 pmp_priv->tx.count = count;
2175 return 0;
2176 } else if (strncmp(extra, "setting", 7) == 0) {
2177 _rtw_memset(extra, 0, wrqu->data.length);
2178 pextra += sprintf(pextra, "Current Setting :\n Channel:%d", pmp_priv->channel);
2179 pextra += sprintf(pextra, "\n Bandwidth:%d", pmp_priv->bandwidth);
2180 pextra += sprintf(pextra, "\n Rate index:%d", pmp_priv->rateidx);
2181 pextra += sprintf(pextra, "\n TxPower index:%d", pmp_priv->txpoweridx);
2182 pextra += sprintf(pextra, "\n Antenna TxPath:%d", pmp_priv->antenna_tx);
2183 pextra += sprintf(pextra, "\n Antenna RxPath:%d", pmp_priv->antenna_rx);
2184 pextra += sprintf(pextra, "\n MP Mode:%d", pmp_priv->mode);
2185 wrqu->data.length = strlen(extra);
2186 return 0;
2187 #ifdef CONFIG_MP_VHT_HW_TX_MODE
2188 } else if (strncmp(extra, "pmact", 5) == 0) {
2189 if (strncmp(extra, "pmact=", 6) == 0) {
2190 _rtw_memset(&pMptCtx->PMacTxInfo, 0, sizeof(pMptCtx->PMacTxInfo));
2191 if (strncmp(extra, "pmact=start", 11) == 0) {
2192 pMptCtx->PMacTxInfo.bEnPMacTx = _TRUE;
2193 sprintf(extra, "Set PMac Tx Mode start\n");
2194 } else {
2195 pMptCtx->PMacTxInfo.bEnPMacTx = _FALSE;
2196 sprintf(extra, "Set PMac Tx Mode Stop\n");
2197 }
2198 if (pMptCtx->bldpc == TRUE)
2199 pMptCtx->PMacTxInfo.bLDPC = _TRUE;
2200
2201 if (pMptCtx->bstbc == TRUE)
2202 pMptCtx->PMacTxInfo.bSTBC = _TRUE;
2203
2204 pMptCtx->PMacTxInfo.bSPreamble = pmp_priv->preamble;
2205 pMptCtx->PMacTxInfo.bSGI = pmp_priv->preamble;
2206 pMptCtx->PMacTxInfo.BandWidth = pmp_priv->bandwidth;
2207 pMptCtx->PMacTxInfo.TX_RATE = HwRateToMPTRate(pmp_priv->rateidx);
2208
2209 pMptCtx->PMacTxInfo.Mode = pMptCtx->HWTxmode;
2210
2211 pMptCtx->PMacTxInfo.NDP_sound = FALSE;/*(Adapter.PacketType == NDP_PKT)?TRUE:FALSE;*/
2212
2213 if (padapter->mppriv.pktInterval == 0)
2214 pMptCtx->PMacTxInfo.PacketPeriod = 100;
2215 else
2216 pMptCtx->PMacTxInfo.PacketPeriod = padapter->mppriv.pktInterval;
2217
2218 if (padapter->mppriv.pktLength < 1000)
2219 pMptCtx->PMacTxInfo.PacketLength = 1000;
2220 else
2221 pMptCtx->PMacTxInfo.PacketLength = padapter->mppriv.pktLength;
2222
2223 pMptCtx->PMacTxInfo.PacketPattern = rtw_random32() % 0xFF;
2224
2225 if (padapter->mppriv.tx_pktcount != 0)
2226 pMptCtx->PMacTxInfo.PacketCount = padapter->mppriv.tx_pktcount;
2227
2228 pMptCtx->PMacTxInfo.Ntx = 0;
2229 for (Idx = 16; Idx < 20; Idx++) {
2230 tmpU1B = (padapter->mppriv.antenna_tx >> Idx) & 1;
2231 if (tmpU1B)
2232 pMptCtx->PMacTxInfo.Ntx++;
2233 }
2234
2235 _rtw_memset(pMptCtx->PMacTxInfo.MacAddress, 0xFF, ETH_ALEN);
2236
2237 PMAC_Get_Pkt_Param(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2238
2239 if (MPT_IS_CCK_RATE(pMptCtx->PMacTxInfo.TX_RATE))
2240
2241 CCK_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2242 else {
2243 PMAC_Nsym_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2244 /* 24 BIT*/
2245 L_SIG_generator(pMptCtx->PMacPktInfo.N_sym, &pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2246 }
2247 /* 48BIT*/
2248 if (MPT_IS_HT_RATE(pMptCtx->PMacTxInfo.TX_RATE))
2249 HT_SIG_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2250 else if (MPT_IS_VHT_RATE(pMptCtx->PMacTxInfo.TX_RATE)) {
2251 /* 48BIT*/
2252 VHT_SIG_A_generator(&pMptCtx->PMacTxInfo, &pMptCtx->PMacPktInfo);
2253
2254 /* 26/27/29 BIT & CRC 8 BIT*/
2255 VHT_SIG_B_generator(&pMptCtx->PMacTxInfo);
2256
2257 /* 32 BIT*/
2258 VHT_Delimiter_generator(&pMptCtx->PMacTxInfo);
2259 }
2260
2261 mpt_ProSetPMacTx(padapter);
2262
2263 } else if (strncmp(extra, "pmact,mode=", 11) == 0) {
2264 int txmode = 0;
2265
2266 if (sscanf(extra, "pmact,mode=%d", &txmode) > 0) {
2267 if (txmode == 1) {
2268 pMptCtx->HWTxmode = CONTINUOUS_TX;
2269 sprintf(extra, "\t Config HW Tx mode = CONTINUOUS_TX\n");
2270 } else if (txmode == 2) {
2271 pMptCtx->HWTxmode = OFDM_Single_Tone_TX;
2272 sprintf(extra, "\t Config HW Tx mode = OFDM_Single_Tone_TX\n");
2273 } else {
2274 pMptCtx->HWTxmode = PACKETS_TX;
2275 sprintf(extra, "\t Config HW Tx mode = PACKETS_TX\n");
2276 }
2277 } else {
2278 pMptCtx->HWTxmode = PACKETS_TX;
2279 sprintf(extra, "\t Config HW Tx mode=\n 0 = PACKETS_TX\n 1 = CONTINUOUS_TX\n 2 = OFDM_Single_Tone_TX");
2280 }
2281 } else if (strncmp(extra, "pmact,", 6) == 0) {
2282 int PacketPeriod = 0, PacketLength = 0, PacketCout = 0;
2283 int bldpc = 0, bstbc = 0;
2284
2285 if (sscanf(extra, "pmact,period=%d", &PacketPeriod) > 0) {
2286 padapter->mppriv.pktInterval = PacketPeriod;
2287 RTW_INFO("PacketPeriod=%d\n", padapter->mppriv.pktInterval);
2288 sprintf(extra, "PacketPeriod [1~255]= %d\n", padapter->mppriv.pktInterval);
2289
2290 } else if (sscanf(extra, "pmact,length=%d", &PacketLength) > 0) {
2291 padapter->mppriv.pktLength = PacketLength;
2292 RTW_INFO("PacketPeriod=%d\n", padapter->mppriv.pktLength);
2293 sprintf(extra, "PacketLength[~65535]=%d\n", padapter->mppriv.pktLength);
2294
2295 } else if (sscanf(extra, "pmact,count=%d", &PacketCout) > 0) {
2296 padapter->mppriv.tx_pktcount = PacketCout;
2297 RTW_INFO("Packet Cout =%d\n", padapter->mppriv.tx_pktcount);
2298 sprintf(extra, "Packet Cout =%d\n", padapter->mppriv.tx_pktcount);
2299
2300 } else if (sscanf(extra, "pmact,ldpc=%d", &bldpc) > 0) {
2301 pMptCtx->bldpc = bldpc;
2302 RTW_INFO("Set LDPC =%d\n", pMptCtx->bldpc);
2303 sprintf(extra, "Set LDPC =%d\n", pMptCtx->bldpc);
2304
2305 } else if (sscanf(extra, "pmact,stbc=%d", &bstbc) > 0) {
2306 pMptCtx->bstbc = bstbc;
2307 RTW_INFO("Set STBC =%d\n", pMptCtx->bstbc);
2308 sprintf(extra, "Set STBC =%d\n", pMptCtx->bstbc);
2309 } else
2310 sprintf(extra, "\n period={1~255}\n length={1000~65535}\n count={0~}\n ldpc={0/1}\n stbc={0/1}");
2311
2312 }
2313
2314 wrqu->data.length = strlen(extra);
2315 return 0;
2316 #endif
2317 } else {
2318
2319 if (sscanf(extra, "ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d", &channel, &bandwidth, &rate, &txpower, &ant, &txmode) < 6) {
2320 RTW_INFO("Invalid format [ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d]\n", channel, bandwidth, rate, txpower, ant, txmode);
2321 _rtw_memset(extra, 0, wrqu->data.length);
2322 pextra += sprintf(pextra, "\n Please input correct format as bleow:\n");
2323 pextra += sprintf(pextra, "\t ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d\n", channel, bandwidth, rate, txpower, ant, txmode);
2324 pextra += sprintf(pextra, "\n [ ch : BGN = <1~14> , A or AC = <36~165> ]");
2325 pextra += sprintf(pextra, "\n [ bw : Bandwidth: 0 = 20M, 1 = 40M, 2 = 80M ]");
2326 pextra += sprintf(pextra, "\n [ rate : CCK: 1 2 5.5 11M X 2 = < 2 4 11 22 >]");
2327 pextra += sprintf(pextra, "\n [ OFDM: 6 9 12 18 24 36 48 54M X 2 = < 12 18 24 36 48 72 96 108>");
2328 pextra += sprintf(pextra, "\n [ HT 1S2SS MCS0 ~ MCS15 : < [MCS0]=128 ~ [MCS7]=135 ~ [MCS15]=143 >");
2329 pextra += sprintf(pextra, "\n [ HT 3SS MCS16 ~ MCS32 : < [MCS16]=144 ~ [MCS23]=151 ~ [MCS32]=159 >");
2330 pextra += sprintf(pextra, "\n [ VHT 1SS MCS0 ~ MCS9 : < [MCS0]=160 ~ [MCS9]=169 >");
2331 pextra += sprintf(pextra, "\n [ txpower : 1~63 power index");
2332 pextra += sprintf(pextra, "\n [ ant : <A = 1, B = 2, C = 4, D = 8> ,2T ex: AB=3 BC=6 CD=12");
2333 pextra += sprintf(pextra, "\n [ txmode : < 0 = CONTINUOUS_TX, 1 = PACKET_TX, 2 = SINGLE_TONE_TX, 3 = CARRIER_SUPPRISSION_TX, 4 = SINGLE_CARRIER_TX>\n");
2334 wrqu->data.length = strlen(extra);
2335 return status;
2336
2337 } else {
2338 char *pextra = extra;
2339 RTW_INFO("Got format [ch=%d,bw=%d,rate=%d,pwr=%d,ant=%d,tx=%d]\n", channel, bandwidth, rate, txpower, ant, txmode);
2340 _rtw_memset(extra, 0, wrqu->data.length);
2341 sprintf(extra, "Change Current channel %d to channel %d", padapter->mppriv.channel , channel);
2342 padapter->mppriv.channel = channel;
2343 SetChannel(padapter);
2344 pHalData->current_channel = channel;
2345
2346 if (bandwidth == 1)
2347 bandwidth = CHANNEL_WIDTH_40;
2348 else if (bandwidth == 2)
2349 bandwidth = CHANNEL_WIDTH_80;
2350 pextra = extra + strlen(pextra);
2351 pextra += sprintf(pextra, "\nChange Current Bandwidth %d to Bandwidth %d", padapter->mppriv.bandwidth, bandwidth);
2352 padapter->mppriv.bandwidth = (u8)bandwidth;
2353 padapter->mppriv.preamble = sg;
2354 SetBandwidth(padapter);
2355 pHalData->current_channel_bw = bandwidth;
2356
2357 pextra += sprintf(pextra, "\nSet power level :%d", txpower);
2358 padapter->mppriv.txpoweridx = (u8)txpower;
2359 pMptCtx->TxPwrLevel[RF_PATH_A] = (u8)txpower;
2360 pMptCtx->TxPwrLevel[RF_PATH_B] = (u8)txpower;
2361 pMptCtx->TxPwrLevel[RF_PATH_C] = (u8)txpower;
2362 pMptCtx->TxPwrLevel[RF_PATH_D] = (u8)txpower;
2363 SetTxPower(padapter);
2364
2365 RTW_INFO("%s: bw=%d sg=%d\n", __func__, bandwidth, sg);
2366
2367 if (rate <= 0x7f)
2368 rate = wifirate2_ratetbl_inx((u8)rate);
2369 else if (rate < 0xC8)
2370 rate = (rate - 0x80 + MPT_RATE_MCS0);
2371 /*HT rate 0x80(MCS0) ~ 0x8F(MCS15) ~ 0x9F(MCS31) 128~159
2372 VHT1SS~2SS rate 0xA0 (VHT1SS_MCS0 44) ~ 0xB3 (VHT2SS_MCS9 #63) 160~179
2373 VHT rate 0xB4 (VHT3SS_MCS0 64) ~ 0xC7 (VHT2SS_MCS9 #83) 180~199
2374 else
2375 VHT rate 0x90(VHT1SS_MCS0) ~ 0x99(VHT1SS_MCS9) 144~153
2376 rate =(rate - MPT_RATE_VHT1SS_MCS0);
2377 */
2378 RTW_INFO("%s: rate index=%d\n", __func__, rate);
2379 if (rate >= MPT_RATE_LAST)
2380 return -EINVAL;
2381 pextra += sprintf(pextra, "\nSet data rate to %d index %d", padapter->mppriv.rateidx, rate);
2382
2383 padapter->mppriv.rateidx = rate;
2384 pMptCtx->mpt_rate_index = rate;
2385 SetDataRate(padapter);
2386
2387 pextra += sprintf(pextra, "\nSet Antenna Path :%d", ant);
2388 switch (ant) {
2389 case 1:
2390 antenna = ANTENNA_A;
2391 break;
2392 case 2:
2393 antenna = ANTENNA_B;
2394 break;
2395 case 4:
2396 antenna = ANTENNA_C;
2397 break;
2398 case 8:
2399 antenna = ANTENNA_D;
2400 break;
2401 case 3:
2402 antenna = ANTENNA_AB;
2403 break;
2404 case 5:
2405 antenna = ANTENNA_AC;
2406 break;
2407 case 9:
2408 antenna = ANTENNA_AD;
2409 break;
2410 case 6:
2411 antenna = ANTENNA_BC;
2412 break;
2413 case 10:
2414 antenna = ANTENNA_BD;
2415 break;
2416 case 12:
2417 antenna = ANTENNA_CD;
2418 break;
2419 case 7:
2420 antenna = ANTENNA_ABC;
2421 break;
2422 case 14:
2423 antenna = ANTENNA_BCD;
2424 break;
2425 case 11:
2426 antenna = ANTENNA_ABD;
2427 break;
2428 case 15:
2429 antenna = ANTENNA_ABCD;
2430 break;
2431 }
2432 RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);
2433 padapter->mppriv.antenna_tx = antenna;
2434 padapter->mppriv.antenna_rx = antenna;
2435 pHalData->antenna_tx_path = antenna;
2436 SetAntenna(padapter);
2437
2438 if (txmode == 0)
2439 pmp_priv->mode = MP_CONTINUOUS_TX;
2440 else if (txmode == 1) {
2441 pmp_priv->mode = MP_PACKET_TX;
2442 pmp_priv->tx.count = count;
2443 } else if (txmode == 2)
2444 pmp_priv->mode = MP_SINGLE_TONE_TX;
2445 else if (txmode == 3)
2446 pmp_priv->mode = MP_CARRIER_SUPPRISSION_TX;
2447 else if (txmode == 4)
2448 pmp_priv->mode = MP_SINGLE_CARRIER_TX;
2449
2450 status = rtw_mp_pretx_proc(padapter, bStartTest, extra);
2451 }
2452
2453 }
2454
2455 wrqu->data.length = strlen(extra);
2456 return status;
2457 }
2458
2459
rtw_mp_rx(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2460 int rtw_mp_rx(struct net_device *dev,
2461 struct iw_request_info *info,
2462 union iwreq_data *wrqu, char *extra)
2463 {
2464 PADAPTER padapter = rtw_netdev_priv(dev);
2465 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2466 struct mp_priv *pmp_priv = &padapter->mppriv;
2467 char *pextra = extra;
2468 u32 bandwidth = 0, sg = 0, channel = 6, ant = 0;
2469 u16 antenna = 0;
2470 u8 bStartRx = 0;
2471
2472 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2473 return -EFAULT;
2474
2475 #ifdef CONFIG_CONCURRENT_MODE
2476 if (!is_primary_adapter(padapter)) {
2477 sprintf(extra, "Error: MP mode can't support Virtual Adapter, Please to use main Adapter.\n");
2478 wrqu->data.length = strlen(extra);
2479 return 0;
2480 }
2481 #endif
2482
2483 if (strncmp(extra, "stop", 4) == 0) {
2484 _rtw_memset(extra, 0, wrqu->data.length);
2485 SetPacketRx(padapter, bStartRx, _FALSE);
2486 pmp_priv->bmac_filter = _FALSE;
2487 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);
2488 wrqu->data.length = strlen(extra);
2489 return 0;
2490
2491 } else if (sscanf(extra, "ch=%d,bw=%d,ant=%d", &channel, &bandwidth, &ant) < 3) {
2492 RTW_INFO("Invalid format [ch=%d,bw=%d,ant=%d]\n", channel, bandwidth, ant);
2493 _rtw_memset(extra, 0, wrqu->data.length);
2494 pextra += sprintf(pextra, "\n Please input correct format as bleow:\n");
2495 pextra += sprintf(pextra, "\t ch=%d,bw=%d,ant=%d\n", channel, bandwidth, ant);
2496 pextra += sprintf(pextra, "\n [ ch : BGN = <1~14> , A or AC = <36~165> ]");
2497 pextra += sprintf(pextra, "\n [ bw : Bandwidth: 0 = 20M, 1 = 40M, 2 = 80M ]");
2498 pextra += sprintf(pextra, "\n [ ant : <A = 1, B = 2, C = 4, D = 8> ,2T ex: AB=3 BC=6 CD=12");
2499 wrqu->data.length = strlen(extra);
2500 return 0;
2501
2502 } else {
2503 char *pextra = extra;
2504 bStartRx = 1;
2505 RTW_INFO("Got format [ch=%d,bw=%d,ant=%d]\n", channel, bandwidth, ant);
2506 _rtw_memset(extra, 0, wrqu->data.length);
2507 sprintf(extra, "Change Current channel %d to channel %d", padapter->mppriv.channel , channel);
2508 padapter->mppriv.channel = channel;
2509 SetChannel(padapter);
2510 pHalData->current_channel = channel;
2511
2512 if (bandwidth == 1)
2513 bandwidth = CHANNEL_WIDTH_40;
2514 else if (bandwidth == 2)
2515 bandwidth = CHANNEL_WIDTH_80;
2516 pextra = extra + strlen(extra);
2517 pextra += sprintf(pextra, "\nChange Current Bandwidth %d to Bandwidth %d", padapter->mppriv.bandwidth, bandwidth);
2518 padapter->mppriv.bandwidth = (u8)bandwidth;
2519 padapter->mppriv.preamble = sg;
2520 SetBandwidth(padapter);
2521 pHalData->current_channel_bw = bandwidth;
2522
2523 pextra += sprintf(pextra, "\nSet Antenna Path :%d", ant);
2524 switch (ant) {
2525 case 1:
2526 antenna = ANTENNA_A;
2527 break;
2528 case 2:
2529 antenna = ANTENNA_B;
2530 break;
2531 case 4:
2532 antenna = ANTENNA_C;
2533 break;
2534 case 8:
2535 antenna = ANTENNA_D;
2536 break;
2537 case 3:
2538 antenna = ANTENNA_AB;
2539 break;
2540 case 5:
2541 antenna = ANTENNA_AC;
2542 break;
2543 case 9:
2544 antenna = ANTENNA_AD;
2545 break;
2546 case 6:
2547 antenna = ANTENNA_BC;
2548 break;
2549 case 10:
2550 antenna = ANTENNA_BD;
2551 break;
2552 case 12:
2553 antenna = ANTENNA_CD;
2554 break;
2555 case 7:
2556 antenna = ANTENNA_ABC;
2557 break;
2558 case 14:
2559 antenna = ANTENNA_BCD;
2560 break;
2561 case 11:
2562 antenna = ANTENNA_ABD;
2563 break;
2564 case 15:
2565 antenna = ANTENNA_ABCD;
2566 break;
2567 }
2568 RTW_INFO("%s: antenna=0x%x\n", __func__, antenna);
2569 padapter->mppriv.antenna_tx = antenna;
2570 padapter->mppriv.antenna_rx = antenna;
2571 pHalData->antenna_tx_path = antenna;
2572 SetAntenna(padapter);
2573
2574 strcat(extra, "\nstart Rx");
2575 SetPacketRx(padapter, bStartRx, _FALSE);
2576 }
2577 wrqu->data.length = strlen(extra);
2578 return 0;
2579 }
2580
2581
rtw_mp_hwtx(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2582 int rtw_mp_hwtx(struct net_device *dev,
2583 struct iw_request_info *info,
2584 union iwreq_data *wrqu, char *extra)
2585 {
2586 PADAPTER padapter = rtw_netdev_priv(dev);
2587 struct mp_priv *pmp_priv = &padapter->mppriv;
2588 PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx);
2589 char *pch;
2590
2591 #if defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8821B) || defined(CONFIG_RTL8822B) \
2592 || defined(CONFIG_RTL8821C) || defined(CONFIG_RTL8822C) || defined(CONFIG_RTL8723F)
2593 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2594 return -EFAULT;
2595 *(extra + wrqu->data.length) = '\0';
2596
2597 _rtw_memset(&pMptCtx->PMacTxInfo, 0, sizeof(RT_PMAC_TX_INFO));
2598 _rtw_memcpy((void *)&pMptCtx->PMacTxInfo, (void *)extra, sizeof(RT_PMAC_TX_INFO));
2599 _rtw_memset(extra, 0, wrqu->data.length);
2600 pch = extra;
2601
2602 if (pMptCtx->PMacTxInfo.bEnPMacTx == 1 && pmp_priv->mode != MP_ON) {
2603 pch += sprintf(pch, "MP Tx Running, Please Set PMac Tx Mode Stop\n");
2604 RTW_INFO("Error !!! MP Tx Running, Please Set PMac Tx Mode Stop\n");
2605 } else {
2606 RTW_INFO("To set MAC Tx mode\n");
2607 if (mpt_ProSetPMacTx(padapter))
2608 pch += sprintf(pch, "Set PMac Tx Mode OK\n");
2609 else
2610 pch += sprintf(pch, "Set PMac Tx Mode Error\n");
2611 }
2612 wrqu->data.length = strlen(extra);
2613 #endif
2614 return 0;
2615
2616 }
2617
rtw_mp_pwrlmt(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2618 int rtw_mp_pwrlmt(struct net_device *dev,
2619 struct iw_request_info *info,
2620 union iwreq_data *wrqu, char *extra)
2621 {
2622 PADAPTER padapter = rtw_netdev_priv(dev);
2623 struct registry_priv *registry_par = &padapter->registrypriv;
2624 char *pch;
2625
2626 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2627 return -EFAULT;
2628
2629 *(extra + wrqu->data.length) = '\0';
2630 pch = extra;
2631
2632 #if CONFIG_TXPWR_LIMIT
2633 if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
2634 padapter->registrypriv.RegEnableTxPowerLimit = 0;
2635 pch += sprintf(pch, "Turn off Power Limit\n");
2636
2637 } else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
2638 padapter->registrypriv.RegEnableTxPowerLimit = 1;
2639 pch += sprintf(pch, "Turn on Power Limit\n");
2640
2641 } else
2642 #endif
2643 pch += sprintf(pch, "Get Power Limit Status:%s\n", (registry_par->RegEnableTxPowerLimit == 1) ? "ON" : "OFF");
2644
2645
2646 wrqu->data.length = strlen(extra);
2647 return 0;
2648 }
2649
rtw_mp_pwrbyrate(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2650 int rtw_mp_pwrbyrate(struct net_device *dev,
2651 struct iw_request_info *info,
2652 union iwreq_data *wrqu, char *extra)
2653 {
2654 PADAPTER padapter = rtw_netdev_priv(dev);
2655
2656 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2657 return -EFAULT;
2658
2659 *(extra + wrqu->data.length) = '\0';
2660 if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
2661 padapter->registrypriv.RegEnableTxPowerByRate = 0;
2662 sprintf(extra, "Turn off Tx Power by Rate\n");
2663
2664 } else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
2665 padapter->registrypriv.RegEnableTxPowerByRate = 1;
2666 sprintf(extra, "Turn On Tx Power by Rate\n");
2667
2668 } else {
2669 sprintf(extra, "Get Power by Rate Status:%s\n", (padapter->registrypriv.RegEnableTxPowerByRate == 1) ? "ON" : "OFF");
2670 }
2671
2672 wrqu->data.length = strlen(extra);
2673 return 0;
2674 }
2675
2676
rtw_mp_dpk_track(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2677 int rtw_mp_dpk_track(struct net_device *dev,
2678 struct iw_request_info *info,
2679 union iwreq_data *wrqu, char *extra)
2680 {
2681 PADAPTER padapter = rtw_netdev_priv(dev);
2682 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2683 struct dm_struct *pDM_Odm = &pHalData->odmpriv;
2684 char *pch;
2685
2686 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2687 return -EFAULT;
2688
2689 *(extra + wrqu->data.length) = '\0';
2690 pch = extra;
2691
2692 if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
2693 halrf_set_dpk_track(pDM_Odm, FALSE);
2694 pch += sprintf(pch, "set dpk track off\n");
2695
2696 } else if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
2697 halrf_set_dpk_track(pDM_Odm, TRUE);
2698 pch += sprintf(pch, "set dpk track on\n");
2699 }
2700
2701 wrqu->data.length = strlen(extra);
2702 return 0;
2703 }
2704
2705
rtw_bt_efuse_mask_file(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2706 int rtw_bt_efuse_mask_file(struct net_device *dev,
2707 struct iw_request_info *info,
2708 union iwreq_data *wrqu, char *extra)
2709 {
2710 char *rtw_efuse_mask_file_path;
2711 u8 *pch;
2712 char *ptmp, tmp;
2713 u8 Status;
2714 PADAPTER padapter = rtw_netdev_priv(dev);
2715
2716 _rtw_memset(btmaskfileBuffer, 0x00, sizeof(btmaskfileBuffer));
2717
2718 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2719 return -EFAULT;
2720
2721 *(extra + wrqu->data.length) = '\0';
2722 ptmp = extra;
2723
2724 if (strncmp(extra, "data,", 5) == 0) {
2725 u8 count = 0;
2726 u8 i = 0;
2727
2728 pch = strsep(&ptmp, ",");
2729
2730 if ((pch == NULL) || (strlen(pch) == 0)) {
2731 RTW_INFO("%s: parameter error(no cmd)!\n", __func__);
2732 return -EFAULT;
2733 }
2734
2735 do {
2736 pch = strsep(&ptmp, ":");
2737 if ((pch == NULL) || (strlen(pch) == 0))
2738 break;
2739 if (strlen(pch) != 2
2740 || IsHexDigit(*pch) == _FALSE
2741 || IsHexDigit(*(pch + 1)) == _FALSE
2742 || sscanf(pch, "%hhx", &tmp) != 1
2743 ) {
2744 RTW_INFO("%s: invalid 8-bit hex! input format: data,01:23:45:67:89:ab:cd:ef...\n", __func__);
2745 return -EFAULT;
2746 }
2747 btmaskfileBuffer[count++] = tmp;
2748
2749 } while (count < 64);
2750
2751 _rtw_memset(extra, '\0' , strlen(extra));
2752
2753 for (i = 0; i < count; i++)
2754 ptmp += sprintf(ptmp, "%02x:", btmaskfileBuffer[i]);
2755
2756 padapter->registrypriv.bBTFileMaskEfuse = _TRUE;
2757
2758 ptmp += sprintf(ptmp, "\nLoad BT Efuse Mask data %d hex ok\n", count);
2759 wrqu->data.length = strlen(extra);
2760 return 0;
2761 }
2762 rtw_efuse_mask_file_path = extra;
2763
2764 if (rtw_is_file_readable(rtw_efuse_mask_file_path) == _TRUE) {
2765 RTW_INFO("%s do rtw_is_file_readable = %s! ,sizeof BT maskfileBuffer %zu\n", __func__, rtw_efuse_mask_file_path, sizeof(btmaskfileBuffer));
2766 Status = rtw_efuse_file_read(padapter, rtw_efuse_mask_file_path, btmaskfileBuffer, sizeof(btmaskfileBuffer));
2767 _rtw_memset(extra, '\0' , strlen(extra));
2768 if (Status == _TRUE) {
2769 padapter->registrypriv.bBTFileMaskEfuse = _TRUE;
2770 ptmp += sprintf(ptmp, "BT efuse mask file read OK\n");
2771 } else {
2772 padapter->registrypriv.bBTFileMaskEfuse = _FALSE;
2773 ptmp += sprintf(ptmp, "read BT efuse mask file FAIL\n");
2774 RTW_INFO("%s rtw_efuse_file_read BT mask fail!\n", __func__);
2775 }
2776 } else {
2777 padapter->registrypriv.bBTFileMaskEfuse = _FALSE;
2778 ptmp += sprintf(ptmp, "BT efuse mask file readable FAIL\n");
2779 RTW_INFO("%s rtw_is_file_readable BT Mask file fail!\n", __func__);
2780 }
2781 wrqu->data.length = strlen(extra);
2782 return 0;
2783 }
2784
2785
rtw_efuse_mask_file(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2786 int rtw_efuse_mask_file(struct net_device *dev,
2787 struct iw_request_info *info,
2788 union iwreq_data *wrqu, char *extra)
2789 {
2790 char *rtw_efuse_mask_file_path;
2791 u8 Status;
2792 PADAPTER padapter = rtw_netdev_priv(dev);
2793
2794 _rtw_memset(maskfileBuffer, 0x00, sizeof(maskfileBuffer));
2795
2796 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2797 return -EFAULT;
2798
2799 *(extra + wrqu->data.length) = '\0';
2800 if (strncmp(extra, "off", 3) == 0 && strlen(extra) < 4) {
2801 padapter->registrypriv.boffefusemask = 1;
2802 sprintf(extra, "Turn off Efuse Mask\n");
2803 wrqu->data.length = strlen(extra);
2804 return 0;
2805 }
2806 if (strncmp(extra, "on", 2) == 0 && strlen(extra) < 3) {
2807 padapter->registrypriv.boffefusemask = 0;
2808 sprintf(extra, "Turn on Efuse Mask\n");
2809 wrqu->data.length = strlen(extra);
2810 return 0;
2811 }
2812 if (strncmp(extra, "data,", 5) == 0) {
2813 u8 *pch;
2814 char *ptmp, tmp;
2815 u8 count = 0;
2816 u8 i = 0;
2817
2818 ptmp = extra;
2819 pch = strsep(&ptmp, ",");
2820
2821 if ((pch == NULL) || (strlen(pch) == 0)) {
2822 RTW_INFO("%s: parameter error(no cmd)!\n", __func__);
2823 return -EFAULT;
2824 }
2825
2826 do {
2827 pch = strsep(&ptmp, ":");
2828 if ((pch == NULL) || (strlen(pch) == 0))
2829 break;
2830 if (strlen(pch) != 2
2831 || IsHexDigit(*pch) == _FALSE
2832 || IsHexDigit(*(pch + 1)) == _FALSE
2833 || sscanf(pch, "%hhx", &tmp) != 1
2834 ) {
2835 RTW_INFO("%s: invalid 8-bit hex! input format: data,01:23:45:67:89:ab:cd:ef...\n", __func__);
2836 return -EFAULT;
2837 }
2838 maskfileBuffer[count++] = tmp;
2839
2840 } while (count < 64);
2841
2842 _rtw_memset(extra, '\0' , strlen(extra));
2843
2844 for (i = 0; i < count; i++)
2845 ptmp += sprintf(ptmp, "%02x:", maskfileBuffer[i]);
2846
2847 padapter->registrypriv.bFileMaskEfuse = _TRUE;
2848
2849 sprintf(ptmp, "\nLoad Efuse Mask data %d hex ok\n", count);
2850 wrqu->data.length = strlen(extra);
2851 return 0;
2852 }
2853 rtw_efuse_mask_file_path = extra;
2854
2855 if (rtw_is_file_readable(rtw_efuse_mask_file_path) == _TRUE) {
2856 RTW_INFO("%s do rtw_efuse_mask_file_read = %s! ,sizeof maskfileBuffer %zu\n", __func__, rtw_efuse_mask_file_path, sizeof(maskfileBuffer));
2857 Status = rtw_efuse_file_read(padapter, rtw_efuse_mask_file_path, maskfileBuffer, sizeof(maskfileBuffer));
2858 if (Status == _TRUE) {
2859 padapter->registrypriv.bFileMaskEfuse = _TRUE;
2860 sprintf(extra, "efuse mask file read OK\n");
2861 } else {
2862 padapter->registrypriv.bFileMaskEfuse = _FALSE;
2863 sprintf(extra, "read efuse mask file FAIL\n");
2864 RTW_INFO("%s rtw_efuse_file_read mask fail!\n", __func__);
2865 }
2866 } else {
2867 padapter->registrypriv.bFileMaskEfuse = _FALSE;
2868 sprintf(extra, "efuse mask file readable FAIL\n");
2869 RTW_INFO("%s rtw_is_file_readable fail!\n", __func__);
2870 }
2871 wrqu->data.length = strlen(extra);
2872 return 0;
2873 }
2874
2875
rtw_efuse_file_map(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2876 int rtw_efuse_file_map(struct net_device *dev,
2877 struct iw_request_info *info,
2878 union iwreq_data *wrqu, char *extra)
2879 {
2880 char *rtw_efuse_file_map_path;
2881 u8 Status;
2882 PEFUSE_HAL pEfuseHal;
2883 PADAPTER padapter = rtw_netdev_priv(dev);
2884 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2885 struct mp_priv *pmp_priv = &padapter->mppriv;
2886
2887 pEfuseHal = &pHalData->EfuseHal;
2888 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2889 return -EFAULT;
2890
2891 rtw_efuse_file_map_path = extra;
2892
2893 _rtw_memset(pEfuseHal->fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);
2894
2895 if (rtw_is_file_readable(rtw_efuse_file_map_path) == _TRUE) {
2896 RTW_INFO("%s do rtw_efuse_mask_file_read = %s!\n", __func__, rtw_efuse_file_map_path);
2897 Status = rtw_efuse_file_read(padapter, rtw_efuse_file_map_path, pEfuseHal->fakeEfuseModifiedMap, sizeof(pEfuseHal->fakeEfuseModifiedMap));
2898 if (Status == _TRUE) {
2899 pmp_priv->bloadefusemap = _TRUE;
2900 sprintf(extra, "efuse file file_read OK\n");
2901 } else {
2902 pmp_priv->bloadefusemap = _FALSE;
2903 sprintf(extra, "efuse file file_read FAIL\n");
2904 }
2905 } else {
2906 sprintf(extra, "efuse file readable FAIL\n");
2907 RTW_INFO("%s rtw_is_file_readable fail!\n", __func__);
2908 }
2909 wrqu->data.length = strlen(extra);
2910 return 0;
2911 }
2912
2913
rtw_efuse_file_map_store(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2914 int rtw_efuse_file_map_store(struct net_device *dev,
2915 struct iw_request_info *info,
2916 union iwreq_data *wrqu, char *extra)
2917 {
2918 char *rtw_efuse_file_map_path;
2919 u8 Status;
2920 u16 mapLen;
2921 PEFUSE_HAL pEfuseHal;
2922 PADAPTER padapter = rtw_netdev_priv(dev);
2923 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2924 struct mp_priv *pmp_priv = &padapter->mppriv;
2925
2926 pEfuseHal = &pHalData->EfuseHal;
2927 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2928 return -EFAULT;
2929
2930 rtw_efuse_file_map_path = extra;
2931 RTW_INFO("%s rtw_is_file_readable! %s\n", __func__, rtw_efuse_file_map_path);
2932
2933 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapLen, _FALSE);
2934
2935 if (mapLen != 0) {
2936 RTW_INFO("%s, efuse store path = %s! mapLen = %d\n", __func__, rtw_efuse_file_map_path, mapLen);
2937 Status = rtw_efuse_file_store(padapter, rtw_efuse_file_map_path, pEfuseHal->fakeEfuseModifiedMap, mapLen);
2938 if (Status) {
2939 sprintf(extra, "efuse file restore OK\n");
2940 } else {
2941 sprintf(extra, "efuse file restore FAIL\n");
2942 }
2943 } else {
2944 sprintf(extra, "efuse file readable FAIL\n");
2945 RTW_INFO("%s rtw_is_file_readable fail! map Len %d\n", __func__, mapLen);
2946 }
2947
2948 wrqu->data.length = strlen(extra);
2949 return 0;
2950 }
2951
rtw_bt_efuse_file_map(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)2952 int rtw_bt_efuse_file_map(struct net_device *dev,
2953 struct iw_request_info *info,
2954 union iwreq_data *wrqu, char *extra)
2955 {
2956 char *rtw_efuse_file_map_path;
2957 u8 Status;
2958 PEFUSE_HAL pEfuseHal;
2959 PADAPTER padapter = rtw_netdev_priv(dev);
2960 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2961 struct mp_priv *pmp_priv = &padapter->mppriv;
2962
2963 pEfuseHal = &pHalData->EfuseHal;
2964 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
2965 return -EFAULT;
2966
2967 rtw_efuse_file_map_path = extra;
2968
2969 _rtw_memset(pEfuseHal->fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2970
2971 if (rtw_is_file_readable(rtw_efuse_file_map_path) == _TRUE) {
2972 RTW_INFO("%s do rtw_efuse_mask_file_read = %s!\n", __func__, rtw_efuse_file_map_path);
2973 Status = rtw_efuse_file_read(padapter, rtw_efuse_file_map_path, pEfuseHal->fakeBTEfuseModifiedMap, sizeof(pEfuseHal->fakeBTEfuseModifiedMap));
2974 if (Status == _TRUE) {
2975 pmp_priv->bloadBTefusemap = _TRUE;
2976 sprintf(extra, "BT efuse file file_read OK\n");
2977 } else {
2978 pmp_priv->bloadBTefusemap = _FALSE;
2979 sprintf(extra, "BT efuse file file_read FAIL\n");
2980 }
2981 } else {
2982 sprintf(extra, "BT efuse file readable FAIL\n");
2983 RTW_INFO("%s rtw_is_file_readable fail!\n", __func__);
2984 }
2985 wrqu->data.length = strlen(extra);
2986 return 0;
2987 }
2988
2989
dump_buf(u8 * buf,u32 len)2990 static inline void dump_buf(u8 *buf, u32 len)
2991 {
2992 u32 i;
2993
2994 RTW_INFO("-----------------Len %d----------------\n", len);
2995 for (i = 0; i < len; i++)
2996 RTW_INFO("%2.2x-", *(buf + i));
2997 RTW_INFO("\n");
2998 }
2999
rtw_mp_link(struct net_device * dev,struct iw_request_info * info,struct iw_point * wrqu,char * extra)3000 int rtw_mp_link(struct net_device *dev,
3001 struct iw_request_info *info,
3002 struct iw_point *wrqu, char *extra)
3003 {
3004 PADAPTER padapter = rtw_netdev_priv(dev);
3005 struct mp_priv *pmp_priv;
3006 char input[RTW_IWD_MAX_LEN];
3007 int bgetrxdata = 0, btxdata = 0, bsetbt = 0;
3008 u8 err = 0;
3009 u32 i = 0, datalen = 0,jj, kk, waittime = 0;
3010 u16 val = 0x00, ret = 0;
3011 char *pextra = NULL;
3012 u8 *setdata = NULL;
3013 char *pch, *ptmp, *token, *tmp[4] = {0x00, 0x00, 0x00};
3014
3015 pmp_priv = &padapter->mppriv;
3016
3017 if (rtw_do_mp_iwdata_len_chk(__func__, wrqu->length))
3018 return -EFAULT;
3019
3020 if (copy_from_user(input, wrqu->pointer, wrqu->length))
3021 return -EFAULT;
3022
3023 _rtw_memset(extra, 0, wrqu->length);
3024
3025 RTW_INFO("%s: in=%s\n", __func__, input);
3026
3027 bgetrxdata = (strncmp(input, "rxdata", 6) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
3028 btxdata = (strncmp(input, "txdata", 6) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
3029 bsetbt = (strncmp(input, "setbt", 5) == 0) ? 1 : 0; /* strncmp TRUE is 0*/
3030
3031 if (bgetrxdata) {
3032 RTW_INFO("%s: in= 1 \n", __func__);
3033 if (pmp_priv->mplink_brx == _TRUE) {
3034 pch = extra;
3035 while (waittime < 100 && pmp_priv->mplink_brx == _FALSE) {
3036 if (pmp_priv->mplink_brx == _FALSE)
3037 rtw_msleep_os(10);
3038 else
3039 break;
3040 waittime++;
3041 }
3042 if (pmp_priv->mplink_brx == _TRUE) {
3043 pch += sprintf(pch, "\n");
3044
3045 for (i = 0; i < pmp_priv->mplink_rx_len; i ++) {
3046 pch += sprintf(pch, "%02x:", pmp_priv->mplink_buf[i]);
3047 }
3048 _rtw_memset(pmp_priv->mplink_buf, '\0' , sizeof(pmp_priv->mplink_buf));
3049 pmp_priv->mplink_brx = _FALSE;
3050 }
3051 }
3052 } else if (btxdata) {
3053 struct pkt_attrib *pattrib;
3054
3055 pch = input;
3056 setdata = rtw_zmalloc(1024);
3057 if (setdata == NULL) {
3058 err = -ENOMEM;
3059 goto exit;
3060 }
3061
3062 i = 0;
3063 while ((token = strsep(&pch, ",")) != NULL) {
3064 if (i > 2)
3065 break;
3066 tmp[i] = token;
3067 i++;
3068 }
3069
3070 /* tmp[0],[1],[2] */
3071 /* txdata,00e04c871200........... */
3072 if (strcmp(tmp[0], "txdata") == 0) {
3073 if ((tmp[1] == NULL)) {
3074 err = -EINVAL;
3075 goto exit;
3076 }
3077 }
3078
3079 datalen = strlen(tmp[1]);
3080 if (datalen % 2) {
3081 err = -EINVAL;
3082 goto exit;
3083 }
3084 datalen /= 2;
3085 if (datalen == 0) {
3086 err = -EINVAL;
3087 goto exit;
3088 }
3089
3090 RTW_INFO("%s: data len=%d\n", __FUNCTION__, datalen);
3091 RTW_INFO("%s: tx data=%s\n", __FUNCTION__, tmp[1]);
3092
3093 for (jj = 0, kk = 0; jj < datalen; jj++, kk += 2)
3094 setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
3095
3096 dump_buf(setdata, datalen);
3097 _rtw_memset(pmp_priv->mplink_buf, '\0' , sizeof(pmp_priv->mplink_buf));
3098 _rtw_memcpy(pmp_priv->mplink_buf, setdata, datalen);
3099
3100 pattrib = &pmp_priv->tx.attrib;
3101 pattrib->pktlen = datalen;
3102 pmp_priv->tx.count = 1;
3103 pmp_priv->tx.stop = 0;
3104 pmp_priv->mplink_btx = _TRUE;
3105 SetPacketTx(padapter);
3106 pmp_priv->mode = MP_PACKET_TX;
3107
3108 } else if (bsetbt) {
3109
3110 #ifdef CONFIG_BT_COEXIST
3111 pch = input;
3112 i = 0;
3113
3114 while ((token = strsep(&pch, ",")) != NULL) {
3115 if (i > 3)
3116 break;
3117 tmp[i] = token;
3118 i++;
3119 }
3120
3121 if (tmp[1] == NULL) {
3122 err = -EINVAL;
3123 goto exit;
3124 }
3125
3126 if (strcmp(tmp[1], "scbd") == 0) {
3127 u16 org_val = 0x8002, pre_val, read_score_board_val;
3128 u8 state;
3129
3130 pre_val = (rtw_read16(padapter,(0xaa))) & 0x7fff;
3131
3132 if (tmp[2] != NULL) {
3133 state = simple_strtoul(tmp[2], &ptmp, 10);
3134
3135 if (state)
3136 org_val = org_val | BIT6;
3137 else
3138 org_val = org_val & (~BIT6);
3139
3140 if (org_val != pre_val) {
3141 pre_val = org_val;
3142 rtw_write16(padapter, 0xaa, org_val);
3143 RTW_INFO("%s,setbt scbd write org_val = 0x%x , pre_val = 0x%x\n", __func__, org_val, pre_val);
3144 } else {
3145 RTW_INFO("%s,setbt scbd org_val = 0x%x ,pre_val = 0x%x\n", __func__, org_val, pre_val);
3146 }
3147 } else {
3148 read_score_board_val = (rtw_read16(padapter,(0xaa))) & 0x7fff;
3149 RTW_INFO("%s,read_score_board_val = 0x%x\n", __func__, read_score_board_val);
3150 }
3151 goto exit;
3152
3153 } else if (strcmp(tmp[1], "testmode") == 0) {
3154
3155 if (tmp[2] == NULL) {
3156 err = -EINVAL;
3157 goto exit;
3158 }
3159
3160 val = simple_strtoul(tmp[2], &ptmp, 16);
3161 RTW_INFO("get tmp, type %s, val =0x%x!\n", tmp[1], val);
3162
3163 if (tmp[2] != NULL) {
3164 _rtw_memset(extra, 0, wrqu->length);
3165 pch = extra;
3166 ret = rtw_btcoex_btset_testmode(padapter, val);
3167 if (!CHECK_STATUS_CODE_FROM_BT_MP_OPER_RET(ret, BT_STATUS_BT_OP_SUCCESS)) {
3168 RTW_INFO("%s: BT_OP fail = 0x%x!\n", __FUNCTION__, val);
3169 pch += sprintf(pch, "BT_OP fail 0x%x!\n", val);
3170 } else
3171 pch += sprintf(pch, "Set BT_OP 0x%x done!\n", val);
3172 }
3173
3174 }
3175 #endif /* CONFIG_BT_COEXIST */
3176 }
3177
3178 exit:
3179 if (setdata)
3180 rtw_mfree(setdata, 1024);
3181
3182 wrqu->length = strlen(extra);
3183 return err;
3184
3185 }
3186
3187 #if defined(CONFIG_RTL8723B)
rtw_mp_SetBT(struct net_device * dev,struct iw_request_info * info,union iwreq_data * wrqu,char * extra)3188 int rtw_mp_SetBT(struct net_device *dev,
3189 struct iw_request_info *info,
3190 union iwreq_data *wrqu, char *extra)
3191 {
3192 PADAPTER padapter = rtw_netdev_priv(dev);
3193 struct hal_ops *pHalFunc = &padapter->hal_func;
3194 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3195
3196 BT_REQ_CMD BtReq;
3197 PMPT_CONTEXT pMptCtx = &(padapter->mppriv.mpt_ctx);
3198 PBT_RSP_CMD pBtRsp = (PBT_RSP_CMD)&pMptCtx->mptOutBuf[0];
3199 char input[128];
3200 char *pch, *ptmp, *token, *tmp[2] = {0x00, 0x00};
3201 u8 setdata[100];
3202 u8 resetbt = 0x00;
3203 u8 tempval, BTStatus;
3204 u8 H2cSetbtmac[6];
3205 u8 u1H2CBtMpOperParm[4] = {0x01};
3206 int testmode = 1, ready = 1, trxparam = 1, setgen = 1, getgen = 1, testctrl = 1, testbt = 1, readtherm = 1, setbtmac = 1;
3207 u32 i = 0, ii = 0, jj = 0, kk = 0, cnts = 0, status = 0;
3208 PRT_MP_FIRMWARE pBTFirmware = NULL;
3209
3210 if (copy_from_user(extra, wrqu->data.pointer, wrqu->data.length))
3211 return -EFAULT;
3212
3213 *(extra + wrqu->data.length) = '\0';
3214 pch = extra;
3215
3216 if (strlen(extra) < 1)
3217 return -EFAULT;
3218
3219 RTW_INFO("%s:iwpriv in=%s\n", __func__, extra);
3220 ready = strncmp(extra, "ready", 5);
3221 testmode = strncmp(extra, "testmode", 8); /* strncmp TRUE is 0*/
3222 trxparam = strncmp(extra, "trxparam", 8);
3223 setgen = strncmp(extra, "setgen", 6);
3224 getgen = strncmp(extra, "getgen", 6);
3225 testctrl = strncmp(extra, "testctrl", 8);
3226 testbt = strncmp(extra, "testbt", 6);
3227 readtherm = strncmp(extra, "readtherm", 9);
3228 setbtmac = strncmp(extra, "setbtmac", 8);
3229
3230 if (strncmp(extra, "dlbt", 4) == 0) {
3231 pHalData->LastHMEBoxNum = 0;
3232 pHalData->bBTFWReady = _FALSE;
3233 rtw_write8(padapter, 0xa3, 0x05);
3234 BTStatus = rtw_read8(padapter, 0xa0);
3235 RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __func__, BTStatus);
3236 if (BTStatus != 0x04) {
3237 pch += sprintf(pch, "BT Status not Active DLFW FAIL\n");
3238 goto exit;
3239 }
3240
3241 tempval = rtw_read8(padapter, 0x6B);
3242 tempval |= BIT7;
3243 rtw_write8(padapter, 0x6B, tempval);
3244
3245 /* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay*/
3246 /* So don't write 0x6A[14]=1 and 0x6A[15]=0 together!*/
3247 rtw_usleep_os(100);
3248 /* disable BT power cut*/
3249 /* 0x6A[14] = 0*/
3250 tempval = rtw_read8(padapter, 0x6B);
3251 tempval &= ~BIT6;
3252 rtw_write8(padapter, 0x6B, tempval);
3253 rtw_usleep_os(100);
3254 MPT_PwrCtlDM(padapter, 0);
3255 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004));
3256 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF));
3257 rtw_msleep_os(600);
3258 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010));
3259 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB));
3260 rtw_msleep_os(1200);
3261 pBTFirmware = (PRT_MP_FIRMWARE)rtw_zmalloc(sizeof(RT_MP_FIRMWARE));
3262 if (pBTFirmware == NULL)
3263 goto exit;
3264 pHalData->bBTFWReady = _FALSE;
3265 FirmwareDownloadBT(padapter, pBTFirmware);
3266 if (pBTFirmware)
3267 rtw_mfree((u8 *)pBTFirmware, sizeof(RT_MP_FIRMWARE));
3268
3269 RTW_INFO("Wait for FirmwareDownloadBT fw boot!\n");
3270 rtw_msleep_os(2000);
3271 _rtw_memset(extra, '\0', wrqu->data.length);
3272 BtReq.opCodeVer = 1;
3273 BtReq.OpCode = 0;
3274 BtReq.paraLength = 0;
3275 mptbt_BtControlProcess(padapter, &BtReq);
3276 rtw_msleep_os(100);
3277
3278 RTW_INFO("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4], pMptCtx->mptOutBuf[5]);
3279 if ((pMptCtx->mptOutBuf[4] == 0x00) && (pMptCtx->mptOutBuf[5] == 0x00)) {
3280
3281 if (padapter->mppriv.bTxBufCkFail == _TRUE)
3282 pch += sprintf(pch, "check TxBuf Fail.\n");
3283 else
3284 pch += sprintf(pch, "download FW Fail.\n");
3285 } else {
3286 pch += sprintf(pch, "download FW OK.\n");
3287 goto exit;
3288 }
3289 goto exit;
3290 }
3291 if (strncmp(extra, "dlfw", 4) == 0) {
3292 pHalData->LastHMEBoxNum = 0;
3293 pHalData->bBTFWReady = _FALSE;
3294 rtw_write8(padapter, 0xa3, 0x05);
3295 BTStatus = rtw_read8(padapter, 0xa0);
3296 RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __func__, BTStatus);
3297 if (BTStatus != 0x04) {
3298 pch += sprintf(pch, "BT Status not Active DLFW FAIL\n");
3299 goto exit;
3300 }
3301
3302 tempval = rtw_read8(padapter, 0x6B);
3303 tempval |= BIT7;
3304 rtw_write8(padapter, 0x6B, tempval);
3305
3306 /* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay*/
3307 /* So don't write 0x6A[14]=1 and 0x6A[15]=0 together!*/
3308 rtw_usleep_os(100);
3309 /* disable BT power cut*/
3310 /* 0x6A[14] = 0*/
3311 tempval = rtw_read8(padapter, 0x6B);
3312 tempval &= ~BIT6;
3313 rtw_write8(padapter, 0x6B, tempval);
3314 rtw_usleep_os(100);
3315
3316 MPT_PwrCtlDM(padapter, 0);
3317 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004));
3318 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF));
3319 rtw_msleep_os(600);
3320 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010));
3321 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB));
3322 rtw_msleep_os(1200);
3323
3324 #if defined(CONFIG_PLATFORM_SPRD) && (MP_DRIVER == 1)
3325 /* Pull up BT reset pin.*/
3326 RTW_INFO("%s: pull up BT reset pin when bt start mp test\n", __func__);
3327 rtw_wifi_gpio_wlan_ctrl(WLAN_BT_PWDN_ON);
3328 #endif
3329 RTW_INFO(" FirmwareDownload!\n");
3330
3331 #if defined(CONFIG_RTL8723B)
3332 status = rtl8723b_FirmwareDownload(padapter, _FALSE);
3333 #endif
3334 RTW_INFO("Wait for FirmwareDownloadBT fw boot!\n");
3335 rtw_msleep_os(1000);
3336 #ifdef CONFIG_BT_COEXIST
3337 rtw_btcoex_HaltNotify(padapter);
3338 RTW_INFO("SetBT btcoex HaltNotify !\n");
3339 /*hal_btcoex1ant_SetAntPath(padapter);*/
3340 rtw_btcoex_SetManualControl(padapter, _TRUE);
3341 #endif
3342 _rtw_memset(extra, '\0', wrqu->data.length);
3343 BtReq.opCodeVer = 1;
3344 BtReq.OpCode = 0;
3345 BtReq.paraLength = 0;
3346 mptbt_BtControlProcess(padapter, &BtReq);
3347 rtw_msleep_os(200);
3348
3349 RTW_INFO("FirmwareDownloadBT ready = 0x%x 0x%x", pMptCtx->mptOutBuf[4], pMptCtx->mptOutBuf[5]);
3350 if ((pMptCtx->mptOutBuf[4] == 0x00) && (pMptCtx->mptOutBuf[5] == 0x00)) {
3351 if (padapter->mppriv.bTxBufCkFail == _TRUE)
3352 pch += sprintf(pch, "check TxBuf Fail.\n");
3353 else
3354 pch += sprintf(pch, "download FW Fail.\n");
3355 } else {
3356 #ifdef CONFIG_BT_COEXIST
3357 rtw_btcoex_SwitchBtTRxMask(padapter);
3358 #endif
3359 rtw_msleep_os(200);
3360 pch += sprintf(pch, "download FW OK.\n");
3361 goto exit;
3362 }
3363 goto exit;
3364 }
3365
3366 if (strncmp(extra, "down", 4) == 0) {
3367 RTW_INFO("SetBT down for to hal_init !\n");
3368 #ifdef CONFIG_BT_COEXIST
3369 rtw_btcoex_SetManualControl(padapter, _FALSE);
3370 rtw_btcoex_Initialize(padapter);
3371 #endif
3372 pHalFunc->read_adapter_info(padapter);
3373 pHalFunc->hal_deinit(padapter);
3374 pHalFunc->hal_init(padapter);
3375 rtw_pm_set_ips(padapter, IPS_NONE);
3376 LeaveAllPowerSaveMode(padapter);
3377 MPT_PwrCtlDM(padapter, 0);
3378 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) | 0x00000004));
3379 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) & 0xFFFFFFEF));
3380 rtw_msleep_os(600);
3381 /*rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a)& 0xFFFFFFFE));*/
3382 rtw_write32(padapter, 0x6b, (rtw_read32(padapter, 0x6b) | 0x00000010));
3383 rtw_write32(padapter, 0xcc, (rtw_read32(padapter, 0xcc) & 0xFFFFFFFB));
3384 rtw_msleep_os(1200);
3385 goto exit;
3386 }
3387 if (strncmp(extra, "disable", 7) == 0) {
3388 RTW_INFO("SetBT disable !\n");
3389 rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a) & 0xFFFFFFFB));
3390 rtw_msleep_os(500);
3391 goto exit;
3392 }
3393 if (strncmp(extra, "enable", 6) == 0) {
3394 RTW_INFO("SetBT enable !\n");
3395 rtw_write32(padapter, 0x6a, (rtw_read32(padapter, 0x6a) | 0x00000004));
3396 rtw_msleep_os(500);
3397 goto exit;
3398 }
3399 if (strncmp(extra, "h2c", 3) == 0) {
3400 RTW_INFO("SetBT h2c !\n");
3401 pHalData->bBTFWReady = _TRUE;
3402 rtw_hal_fill_h2c_cmd(padapter, 0x63, 1, u1H2CBtMpOperParm);
3403 goto exit;
3404 }
3405 if (strncmp(extra, "2ant", 4) == 0) {
3406 RTW_INFO("Set BT 2ant use!\n");
3407 phy_set_mac_reg(padapter, 0x67, BIT5, 0x1);
3408 rtw_write32(padapter, 0x948, 0000);
3409
3410 goto exit;
3411 }
3412
3413 if (ready != 0 && testmode != 0 && trxparam != 0 && setgen != 0 && getgen != 0 && testctrl != 0 && testbt != 0 && readtherm != 0 && setbtmac != 0)
3414 return -EFAULT;
3415
3416 if (testbt == 0) {
3417 BtReq.opCodeVer = 1;
3418 BtReq.OpCode = 6;
3419 BtReq.paraLength = cnts / 2;
3420 goto todo;
3421 }
3422 if (ready == 0) {
3423 BtReq.opCodeVer = 1;
3424 BtReq.OpCode = 0;
3425 BtReq.paraLength = 0;
3426 goto todo;
3427 }
3428
3429 i = 0;
3430 while ((token = strsep(&pch, ",")) != NULL) {
3431 if (i > 1)
3432 break;
3433 tmp[i] = token;
3434 i++;
3435 }
3436
3437 if ((tmp[0] != NULL) && (tmp[1] != NULL)) {
3438 cnts = strlen(tmp[1]);
3439 if (cnts < 1)
3440 return -EFAULT;
3441
3442 RTW_INFO("%s: cnts=%d\n", __func__, cnts);
3443 RTW_INFO("%s: data=%s\n", __func__, tmp[1]);
3444
3445 for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2) {
3446 BtReq.pParamStart[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
3447 /* RTW_INFO("BtReq.pParamStart[%d]=0x%02x\n", jj, BtReq.pParamStart[jj]);*/
3448 }
3449 } else
3450 return -EFAULT;
3451
3452 if (testmode == 0) {
3453 BtReq.opCodeVer = 1;
3454 BtReq.OpCode = 1;
3455 BtReq.paraLength = 1;
3456 }
3457 if (trxparam == 0) {
3458 BtReq.opCodeVer = 1;
3459 BtReq.OpCode = 2;
3460 BtReq.paraLength = cnts / 2;
3461 }
3462 if (setgen == 0) {
3463 RTW_INFO("%s: BT_SET_GENERAL\n", __func__);
3464 BtReq.opCodeVer = 1;
3465 BtReq.OpCode = 3;/*BT_SET_GENERAL 3*/
3466 BtReq.paraLength = cnts / 2;
3467 }
3468 if (getgen == 0) {
3469 RTW_INFO("%s: BT_GET_GENERAL\n", __func__);
3470 BtReq.opCodeVer = 1;
3471 BtReq.OpCode = 4;/*BT_GET_GENERAL 4*/
3472 BtReq.paraLength = cnts / 2;
3473 }
3474 if (readtherm == 0) {
3475 RTW_INFO("%s: BT_GET_GENERAL\n", __func__);
3476 BtReq.opCodeVer = 1;
3477 BtReq.OpCode = 4;/*BT_GET_GENERAL 4*/
3478 BtReq.paraLength = cnts / 2;
3479 }
3480
3481 if (testctrl == 0) {
3482 RTW_INFO("%s: BT_TEST_CTRL\n", __func__);
3483 BtReq.opCodeVer = 1;
3484 BtReq.OpCode = 5;/*BT_TEST_CTRL 5*/
3485 BtReq.paraLength = cnts / 2;
3486 }
3487
3488 RTW_INFO("%s: Req opCodeVer=%d OpCode=%d paraLength=%d\n",
3489 __func__, BtReq.opCodeVer, BtReq.OpCode, BtReq.paraLength);
3490
3491 if (BtReq.paraLength < 1)
3492 goto todo;
3493 for (i = 0; i < BtReq.paraLength; i++) {
3494 RTW_INFO("%s: BtReq.pParamStart[%d] = 0x%02x\n",
3495 __func__, i, BtReq.pParamStart[i]);
3496 }
3497
3498 todo:
3499 _rtw_memset(extra, '\0', wrqu->data.length);
3500
3501 if (pHalData->bBTFWReady == _FALSE) {
3502 pch += sprintf(pch, "BTFWReady = FALSE.\n");
3503 goto exit;
3504 }
3505
3506 mptbt_BtControlProcess(padapter, &BtReq);
3507
3508 if (readtherm == 0) {
3509 pch += sprintf(pch, "BT thermal=");
3510 for (i = 4; i < pMptCtx->mptOutLen; i++) {
3511 if ((pMptCtx->mptOutBuf[i] == 0x00) && (pMptCtx->mptOutBuf[i + 1] == 0x00))
3512 goto exit;
3513
3514 pch += sprintf(pch, " %d ", (pMptCtx->mptOutBuf[i] & 0x1f));
3515 }
3516 } else {
3517 for (i = 4; i < pMptCtx->mptOutLen; i++)
3518 pch += sprintf(pch, " 0x%x ", pMptCtx->mptOutBuf[i]);
3519 }
3520
3521 exit:
3522 wrqu->data.length = strlen(extra) + 1;
3523 RTW_INFO("-%s: output len=%d data=%s\n", __func__, wrqu->data.length, extra);
3524
3525 return status;
3526 }
3527
3528 #endif /*#ifdef CONFIG_RTL8723B*/
3529
3530 #endif
3531