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