Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/net/wireless/realtek/rtw88/rtw8723x.c
25924 views
1
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2
/* Copyright 2024 Fiona Klute
3
*
4
* Based on code originally in rtw8723d.[ch],
5
* Copyright(c) 2018-2019 Realtek Corporation
6
*/
7
8
#include "main.h"
9
#include "debug.h"
10
#include "phy.h"
11
#include "reg.h"
12
#include "tx.h"
13
#include "rtw8723x.h"
14
15
static const struct rtw_hw_reg rtw8723x_txagc[] = {
16
[DESC_RATE1M] = { .addr = 0xe08, .mask = 0x0000ff00 },
17
[DESC_RATE2M] = { .addr = 0x86c, .mask = 0x0000ff00 },
18
[DESC_RATE5_5M] = { .addr = 0x86c, .mask = 0x00ff0000 },
19
[DESC_RATE11M] = { .addr = 0x86c, .mask = 0xff000000 },
20
[DESC_RATE6M] = { .addr = 0xe00, .mask = 0x000000ff },
21
[DESC_RATE9M] = { .addr = 0xe00, .mask = 0x0000ff00 },
22
[DESC_RATE12M] = { .addr = 0xe00, .mask = 0x00ff0000 },
23
[DESC_RATE18M] = { .addr = 0xe00, .mask = 0xff000000 },
24
[DESC_RATE24M] = { .addr = 0xe04, .mask = 0x000000ff },
25
[DESC_RATE36M] = { .addr = 0xe04, .mask = 0x0000ff00 },
26
[DESC_RATE48M] = { .addr = 0xe04, .mask = 0x00ff0000 },
27
[DESC_RATE54M] = { .addr = 0xe04, .mask = 0xff000000 },
28
[DESC_RATEMCS0] = { .addr = 0xe10, .mask = 0x000000ff },
29
[DESC_RATEMCS1] = { .addr = 0xe10, .mask = 0x0000ff00 },
30
[DESC_RATEMCS2] = { .addr = 0xe10, .mask = 0x00ff0000 },
31
[DESC_RATEMCS3] = { .addr = 0xe10, .mask = 0xff000000 },
32
[DESC_RATEMCS4] = { .addr = 0xe14, .mask = 0x000000ff },
33
[DESC_RATEMCS5] = { .addr = 0xe14, .mask = 0x0000ff00 },
34
[DESC_RATEMCS6] = { .addr = 0xe14, .mask = 0x00ff0000 },
35
[DESC_RATEMCS7] = { .addr = 0xe14, .mask = 0xff000000 },
36
};
37
38
static void __rtw8723x_lck(struct rtw_dev *rtwdev)
39
{
40
u32 lc_cal;
41
u8 val_ctx, rf_val;
42
int ret;
43
44
val_ctx = rtw_read8(rtwdev, REG_CTX);
45
if ((val_ctx & BIT_MASK_CTX_TYPE) != 0)
46
rtw_write8(rtwdev, REG_CTX, val_ctx & ~BIT_MASK_CTX_TYPE);
47
else
48
rtw_write8(rtwdev, REG_TXPAUSE, 0xFF);
49
lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);
50
51
rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal | BIT_LCK);
52
53
ret = read_poll_timeout(rtw_read_rf, rf_val, rf_val != 0x1,
54
10000, 1000000, false,
55
rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK);
56
if (ret)
57
rtw_warn(rtwdev, "failed to poll LCK status bit\n");
58
59
rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal);
60
if ((val_ctx & BIT_MASK_CTX_TYPE) != 0)
61
rtw_write8(rtwdev, REG_CTX, val_ctx);
62
else
63
rtw_write8(rtwdev, REG_TXPAUSE, 0x00);
64
}
65
66
#define DBG_EFUSE_VAL(rtwdev, map, name) \
67
rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x\n", \
68
(map)->name)
69
#define DBG_EFUSE_2BYTE(rtwdev, map, name) \
70
rtw_dbg(rtwdev, RTW_DBG_EFUSE, # name "=0x%02x%02x\n", \
71
(map)->name[0], (map)->name[1])
72
#define DBG_EFUSE_FIX(rtwdev, name) \
73
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "Fixed invalid EFUSE value: " \
74
# name "=0x%x\n", rtwdev->efuse.name)
75
76
static void rtw8723xe_efuse_debug(struct rtw_dev *rtwdev,
77
struct rtw8723x_efuse *map)
78
{
79
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->e.mac_addr);
80
DBG_EFUSE_2BYTE(rtwdev, map, e.vendor_id);
81
DBG_EFUSE_2BYTE(rtwdev, map, e.device_id);
82
DBG_EFUSE_2BYTE(rtwdev, map, e.sub_vendor_id);
83
DBG_EFUSE_2BYTE(rtwdev, map, e.sub_device_id);
84
}
85
86
static void rtw8723xu_efuse_debug(struct rtw_dev *rtwdev,
87
struct rtw8723x_efuse *map)
88
{
89
DBG_EFUSE_2BYTE(rtwdev, map, u.vendor_id);
90
DBG_EFUSE_2BYTE(rtwdev, map, u.product_id);
91
DBG_EFUSE_VAL(rtwdev, map, u.usb_option);
92
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->u.mac_addr);
93
}
94
95
static void rtw8723xs_efuse_debug(struct rtw_dev *rtwdev,
96
struct rtw8723x_efuse *map)
97
{
98
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "mac_addr=%pM\n", map->s.mac_addr);
99
}
100
101
static void __rtw8723x_debug_txpwr_limit(struct rtw_dev *rtwdev,
102
struct rtw_txpwr_idx *table,
103
int tx_path_count)
104
{
105
if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE))
106
return;
107
108
rtw_dbg(rtwdev, RTW_DBG_EFUSE,
109
"Power index table (2.4G):\n");
110
/* CCK base */
111
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "CCK base\n");
112
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF G0 G1 G2 G3 G4 G5\n");
113
for (int i = 0; i < tx_path_count; i++)
114
rtw_dbg(rtwdev, RTW_DBG_EFUSE,
115
"[%c]: %3u %3u %3u %3u %3u %3u\n",
116
'A' + i,
117
table[i].pwr_idx_2g.cck_base[0],
118
table[i].pwr_idx_2g.cck_base[1],
119
table[i].pwr_idx_2g.cck_base[2],
120
table[i].pwr_idx_2g.cck_base[3],
121
table[i].pwr_idx_2g.cck_base[4],
122
table[i].pwr_idx_2g.cck_base[5]);
123
/* CCK diff */
124
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "CCK diff\n");
125
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n");
126
for (int i = 0; i < tx_path_count; i++)
127
rtw_dbg(rtwdev, RTW_DBG_EFUSE,
128
"[%c]: %2d %2d %2d %2d\n",
129
'A' + i, 0 /* no diff for 1S */,
130
table[i].pwr_idx_2g.ht_2s_diff.cck,
131
table[i].pwr_idx_2g.ht_3s_diff.cck,
132
table[i].pwr_idx_2g.ht_4s_diff.cck);
133
/* BW40-1S base */
134
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW40-1S base\n");
135
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF G0 G1 G2 G3 G4\n");
136
for (int i = 0; i < tx_path_count; i++)
137
rtw_dbg(rtwdev, RTW_DBG_EFUSE,
138
"[%c]: %3u %3u %3u %3u %3u\n",
139
'A' + i,
140
table[i].pwr_idx_2g.bw40_base[0],
141
table[i].pwr_idx_2g.bw40_base[1],
142
table[i].pwr_idx_2g.bw40_base[2],
143
table[i].pwr_idx_2g.bw40_base[3],
144
table[i].pwr_idx_2g.bw40_base[4]);
145
/* OFDM diff */
146
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "OFDM diff\n");
147
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n");
148
for (int i = 0; i < tx_path_count; i++)
149
rtw_dbg(rtwdev, RTW_DBG_EFUSE,
150
"[%c]: %2d %2d %2d %2d\n",
151
'A' + i,
152
table[i].pwr_idx_2g.ht_1s_diff.ofdm,
153
table[i].pwr_idx_2g.ht_2s_diff.ofdm,
154
table[i].pwr_idx_2g.ht_3s_diff.ofdm,
155
table[i].pwr_idx_2g.ht_4s_diff.ofdm);
156
/* BW20 diff */
157
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW20 diff\n");
158
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n");
159
for (int i = 0; i < tx_path_count; i++)
160
rtw_dbg(rtwdev, RTW_DBG_EFUSE,
161
"[%c]: %2d %2d %2d %2d\n",
162
'A' + i,
163
table[i].pwr_idx_2g.ht_1s_diff.bw20,
164
table[i].pwr_idx_2g.ht_2s_diff.bw20,
165
table[i].pwr_idx_2g.ht_3s_diff.bw20,
166
table[i].pwr_idx_2g.ht_4s_diff.bw20);
167
/* BW40 diff */
168
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "BW40 diff\n");
169
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "RF 1S 2S 3S 4S\n");
170
for (int i = 0; i < tx_path_count; i++)
171
rtw_dbg(rtwdev, RTW_DBG_EFUSE,
172
"[%c]: %2d %2d %2d %2d\n",
173
'A' + i, 0 /* no diff for 1S */,
174
table[i].pwr_idx_2g.ht_2s_diff.bw40,
175
table[i].pwr_idx_2g.ht_3s_diff.bw40,
176
table[i].pwr_idx_2g.ht_4s_diff.bw40);
177
}
178
179
static void efuse_debug_dump(struct rtw_dev *rtwdev,
180
struct rtw8723x_efuse *map)
181
{
182
if (!rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE))
183
return;
184
185
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "EFUSE raw logical map:\n");
186
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1,
187
(u8 *)map, sizeof(struct rtw8723x_efuse), false);
188
rtw_dbg(rtwdev, RTW_DBG_EFUSE, "Parsed rtw8723x EFUSE data:\n");
189
DBG_EFUSE_VAL(rtwdev, map, rtl_id);
190
DBG_EFUSE_VAL(rtwdev, map, afe);
191
rtw8723x_debug_txpwr_limit(rtwdev, map->txpwr_idx_table, 4);
192
DBG_EFUSE_VAL(rtwdev, map, channel_plan);
193
DBG_EFUSE_VAL(rtwdev, map, xtal_k);
194
DBG_EFUSE_VAL(rtwdev, map, thermal_meter);
195
DBG_EFUSE_VAL(rtwdev, map, iqk_lck);
196
DBG_EFUSE_VAL(rtwdev, map, pa_type);
197
DBG_EFUSE_2BYTE(rtwdev, map, lna_type_2g);
198
DBG_EFUSE_2BYTE(rtwdev, map, lna_type_5g);
199
DBG_EFUSE_VAL(rtwdev, map, rf_board_option);
200
DBG_EFUSE_VAL(rtwdev, map, rf_feature_option);
201
DBG_EFUSE_VAL(rtwdev, map, rf_bt_setting);
202
DBG_EFUSE_VAL(rtwdev, map, eeprom_version);
203
DBG_EFUSE_VAL(rtwdev, map, eeprom_customer_id);
204
DBG_EFUSE_VAL(rtwdev, map, tx_bb_swing_setting_2g);
205
DBG_EFUSE_VAL(rtwdev, map, tx_pwr_calibrate_rate);
206
DBG_EFUSE_VAL(rtwdev, map, rf_antenna_option);
207
DBG_EFUSE_VAL(rtwdev, map, rfe_option);
208
DBG_EFUSE_2BYTE(rtwdev, map, country_code);
209
210
switch (rtw_hci_type(rtwdev)) {
211
case RTW_HCI_TYPE_PCIE:
212
rtw8723xe_efuse_debug(rtwdev, map);
213
break;
214
case RTW_HCI_TYPE_USB:
215
rtw8723xu_efuse_debug(rtwdev, map);
216
break;
217
case RTW_HCI_TYPE_SDIO:
218
rtw8723xs_efuse_debug(rtwdev, map);
219
break;
220
default:
221
/* unsupported now */
222
break;
223
}
224
}
225
226
static void rtw8723xe_efuse_parsing(struct rtw_efuse *efuse,
227
struct rtw8723x_efuse *map)
228
{
229
ether_addr_copy(efuse->addr, map->e.mac_addr);
230
}
231
232
static void rtw8723xu_efuse_parsing(struct rtw_efuse *efuse,
233
struct rtw8723x_efuse *map)
234
{
235
ether_addr_copy(efuse->addr, map->u.mac_addr);
236
}
237
238
static void rtw8723xs_efuse_parsing(struct rtw_efuse *efuse,
239
struct rtw8723x_efuse *map)
240
{
241
ether_addr_copy(efuse->addr, map->s.mac_addr);
242
}
243
244
/* Default power index table for RTL8703B/RTL8723D, used if EFUSE does
245
* not contain valid data. Replaces EFUSE data from offset 0x10 (start
246
* of txpwr_idx_table).
247
*/
248
static const u8 rtw8723x_txpwr_idx_table[] = {
249
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
250
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x02
251
};
252
253
static int __rtw8723x_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)
254
{
255
struct rtw_efuse *efuse = &rtwdev->efuse;
256
u8 *pwr = (u8 *)efuse->txpwr_idx_table;
257
struct rtw8723x_efuse *map;
258
bool valid = false;
259
int i;
260
261
map = (struct rtw8723x_efuse *)log_map;
262
efuse_debug_dump(rtwdev, map);
263
264
efuse->rfe_option = 0;
265
efuse->rf_board_option = map->rf_board_option;
266
efuse->crystal_cap = map->xtal_k;
267
efuse->pa_type_2g = map->pa_type;
268
efuse->lna_type_2g = map->lna_type_2g[0];
269
efuse->channel_plan = map->channel_plan;
270
efuse->country_code[0] = map->country_code[0];
271
efuse->country_code[1] = map->country_code[1];
272
efuse->bt_setting = map->rf_bt_setting;
273
efuse->regd = map->rf_board_option & 0x7;
274
efuse->thermal_meter[0] = map->thermal_meter;
275
efuse->thermal_meter_k = map->thermal_meter;
276
efuse->afe = map->afe;
277
278
for (i = 0; i < 4; i++)
279
efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i];
280
281
switch (rtw_hci_type(rtwdev)) {
282
case RTW_HCI_TYPE_PCIE:
283
rtw8723xe_efuse_parsing(efuse, map);
284
break;
285
case RTW_HCI_TYPE_USB:
286
rtw8723xu_efuse_parsing(efuse, map);
287
break;
288
case RTW_HCI_TYPE_SDIO:
289
rtw8723xs_efuse_parsing(efuse, map);
290
break;
291
default:
292
/* unsupported now */
293
return -EOPNOTSUPP;
294
}
295
296
/* If TX power index table in EFUSE is invalid, fall back to
297
* built-in table.
298
*/
299
for (i = 0; i < ARRAY_SIZE(rtw8723x_txpwr_idx_table); i++)
300
if (pwr[i] != 0xff) {
301
valid = true;
302
break;
303
}
304
if (!valid) {
305
for (i = 0; i < ARRAY_SIZE(rtw8723x_txpwr_idx_table); i++)
306
pwr[i] = rtw8723x_txpwr_idx_table[i];
307
rtw_dbg(rtwdev, RTW_DBG_EFUSE,
308
"Replaced invalid EFUSE TX power index table.");
309
rtw8723x_debug_txpwr_limit(rtwdev,
310
efuse->txpwr_idx_table, 2);
311
}
312
313
/* Override invalid antenna settings. */
314
if (efuse->bt_setting == 0xff) {
315
/* shared antenna */
316
efuse->bt_setting |= BIT(0);
317
/* RF path A */
318
efuse->bt_setting &= ~BIT(6);
319
DBG_EFUSE_FIX(rtwdev, bt_setting);
320
}
321
322
/* Override invalid board options: The coex code incorrectly
323
* assumes that if bits 6 & 7 are set the board doesn't
324
* support coex. Regd is also derived from rf_board_option and
325
* should be 0 if there's no valid data.
326
*/
327
if (efuse->rf_board_option == 0xff) {
328
efuse->regd = 0;
329
efuse->rf_board_option &= GENMASK(5, 0);
330
DBG_EFUSE_FIX(rtwdev, rf_board_option);
331
}
332
333
/* Override invalid crystal cap setting, default comes from
334
* vendor driver. Chip specific.
335
*/
336
if (efuse->crystal_cap == 0xff) {
337
efuse->crystal_cap = 0x20;
338
DBG_EFUSE_FIX(rtwdev, crystal_cap);
339
}
340
341
return 0;
342
}
343
344
#define BIT_CFENDFORM BIT(9)
345
#define BIT_WMAC_TCR_ERR0 BIT(12)
346
#define BIT_WMAC_TCR_ERR1 BIT(13)
347
#define BIT_TCR_CFG (BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 | \
348
BIT_WMAC_TCR_ERR1)
349
#define WLAN_RX_FILTER0 0xFFFF
350
#define WLAN_RX_FILTER1 0x400
351
#define WLAN_RX_FILTER2 0xFFFF
352
#define WLAN_RCR_CFG 0x700060CE
353
354
static int __rtw8723x_mac_init(struct rtw_dev *rtwdev)
355
{
356
rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG);
357
358
rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0);
359
rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1);
360
rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2);
361
rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG);
362
363
rtw_write32(rtwdev, REG_INT_MIG, 0);
364
rtw_write32(rtwdev, REG_MCUTST_1, 0x0);
365
366
rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA);
367
rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0);
368
369
return 0;
370
}
371
372
static int __rtw8723x_mac_postinit(struct rtw_dev *rtwdev)
373
{
374
rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN);
375
376
return 0;
377
}
378
379
static void __rtw8723x_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
380
{
381
u8 ldo_pwr;
382
383
ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3);
384
if (enable) {
385
ldo_pwr &= ~BIT_MASK_LDO25_VOLTAGE;
386
ldo_pwr |= (BIT_LDO25_VOLTAGE_V25 << 4) | BIT_LDO25_EN;
387
} else {
388
ldo_pwr &= ~BIT_LDO25_EN;
389
}
390
rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr);
391
}
392
393
static void
394
rtw8723x_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
395
{
396
struct rtw_hal *hal = &rtwdev->hal;
397
const struct rtw_hw_reg *txagc;
398
u8 rate, pwr_index;
399
int j;
400
401
for (j = 0; j < rtw_rate_size[rs]; j++) {
402
rate = rtw_rate_section[rs][j];
403
pwr_index = hal->tx_pwr_tbl[path][rate];
404
405
if (rate >= ARRAY_SIZE(rtw8723x_txagc)) {
406
rtw_warn(rtwdev, "rate 0x%x isn't supported\n", rate);
407
continue;
408
}
409
txagc = &rtw8723x_txagc[rate];
410
if (!txagc->addr) {
411
rtw_warn(rtwdev, "rate 0x%x isn't defined\n", rate);
412
continue;
413
}
414
415
rtw_write32_mask(rtwdev, txagc->addr, txagc->mask, pwr_index);
416
}
417
}
418
419
static void __rtw8723x_set_tx_power_index(struct rtw_dev *rtwdev)
420
{
421
struct rtw_hal *hal = &rtwdev->hal;
422
int rs, path;
423
424
for (path = 0; path < hal->rf_path_num; path++) {
425
for (rs = 0; rs <= RTW_RATE_SECTION_HT_1S; rs++)
426
rtw8723x_set_tx_power_index_by_rate(rtwdev, path, rs);
427
}
428
}
429
430
static void __rtw8723x_efuse_grant(struct rtw_dev *rtwdev, bool on)
431
{
432
if (on) {
433
rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
434
435
rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR);
436
rtw_write16_set(rtwdev, REG_SYS_CLKR, BIT_LOADER_CLK_EN | BIT_ANA8M);
437
} else {
438
rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
439
}
440
}
441
442
static void __rtw8723x_false_alarm_statistics(struct rtw_dev *rtwdev)
443
{
444
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
445
u32 cck_fa_cnt;
446
u32 ofdm_fa_cnt;
447
u32 crc32_cnt;
448
u32 val32;
449
450
/* hold counter */
451
rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 1);
452
rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 1);
453
rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, 1);
454
rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, 1);
455
456
cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0);
457
cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8;
458
459
val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N);
460
ofdm_fa_cnt = u32_get_bits(val32, BIT_MASK_OFDM_FF_CNT);
461
ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_SF_CNT);
462
val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N);
463
dm_info->ofdm_cca_cnt = u32_get_bits(val32, BIT_MASK_OFDM_CCA_CNT);
464
ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_PF_CNT);
465
val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N);
466
ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_RI_CNT);
467
ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_CRC_CNT);
468
val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N);
469
ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_MNS_CNT);
470
471
dm_info->cck_fa_cnt = cck_fa_cnt;
472
dm_info->ofdm_fa_cnt = ofdm_fa_cnt;
473
dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt;
474
475
dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N);
476
dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N);
477
crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N);
478
dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_ERR);
479
dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_OK);
480
crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N);
481
dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_ERR);
482
dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_OK);
483
dm_info->vht_err_cnt = 0;
484
dm_info->vht_ok_cnt = 0;
485
486
val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N);
487
dm_info->cck_cca_cnt = (u32_get_bits(val32, BIT_MASK_CCK_FA_MSB) << 8) |
488
u32_get_bits(val32, BIT_MASK_CCK_FA_LSB);
489
dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt;
490
491
/* reset counter */
492
rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 1);
493
rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 0);
494
rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 1);
495
rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 0);
496
rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 0);
497
rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 0);
498
rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 0);
499
rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 2);
500
rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 0);
501
rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 2);
502
rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 1);
503
rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 0);
504
}
505
506
/* IQK (IQ calibration) */
507
508
static
509
void __rtw8723x_iqk_backup_regs(struct rtw_dev *rtwdev,
510
struct rtw8723x_iqk_backup_regs *backup)
511
{
512
int i;
513
514
for (i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++)
515
backup->adda[i] = rtw_read32(rtwdev,
516
rtw8723x_common.iqk_adda_regs[i]);
517
518
for (i = 0; i < RTW8723X_IQK_MAC8_REG_NUM; i++)
519
backup->mac8[i] = rtw_read8(rtwdev,
520
rtw8723x_common.iqk_mac8_regs[i]);
521
for (i = 0; i < RTW8723X_IQK_MAC32_REG_NUM; i++)
522
backup->mac32[i] = rtw_read32(rtwdev,
523
rtw8723x_common.iqk_mac32_regs[i]);
524
525
for (i = 0; i < RTW8723X_IQK_BB_REG_NUM; i++)
526
backup->bb[i] = rtw_read32(rtwdev,
527
rtw8723x_common.iqk_bb_regs[i]);
528
529
backup->igia = rtw_read32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0);
530
backup->igib = rtw_read32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0);
531
532
backup->bb_sel_btg = rtw_read32(rtwdev, REG_BB_SEL_BTG);
533
}
534
535
static
536
void __rtw8723x_iqk_restore_regs(struct rtw_dev *rtwdev,
537
const struct rtw8723x_iqk_backup_regs *backup)
538
{
539
int i;
540
541
for (i = 0; i < RTW8723X_IQK_ADDA_REG_NUM; i++)
542
rtw_write32(rtwdev, rtw8723x_common.iqk_adda_regs[i],
543
backup->adda[i]);
544
545
for (i = 0; i < RTW8723X_IQK_MAC8_REG_NUM; i++)
546
rtw_write8(rtwdev, rtw8723x_common.iqk_mac8_regs[i],
547
backup->mac8[i]);
548
for (i = 0; i < RTW8723X_IQK_MAC32_REG_NUM; i++)
549
rtw_write32(rtwdev, rtw8723x_common.iqk_mac32_regs[i],
550
backup->mac32[i]);
551
552
for (i = 0; i < RTW8723X_IQK_BB_REG_NUM; i++)
553
rtw_write32(rtwdev, rtw8723x_common.iqk_bb_regs[i],
554
backup->bb[i]);
555
556
rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50);
557
rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, backup->igia);
558
559
rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, 0x50);
560
rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, backup->igib);
561
562
rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x01008c00);
563
rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x01008c00);
564
}
565
566
static
567
bool __rtw8723x_iqk_similarity_cmp(struct rtw_dev *rtwdev,
568
s32 result[][IQK_NR],
569
u8 c1, u8 c2)
570
{
571
u32 i, j, diff;
572
u32 bitmap = 0;
573
u8 candidate[PATH_NR] = {IQK_ROUND_INVALID, IQK_ROUND_INVALID};
574
bool ret = true;
575
576
s32 tmp1, tmp2;
577
578
for (i = 0; i < IQK_NR; i++) {
579
tmp1 = iqkxy_to_s32(result[c1][i]);
580
tmp2 = iqkxy_to_s32(result[c2][i]);
581
582
diff = abs(tmp1 - tmp2);
583
584
if (diff <= MAX_TOLERANCE)
585
continue;
586
587
if ((i == IQK_S1_RX_X || i == IQK_S0_RX_X) && !bitmap) {
588
if (result[c1][i] + result[c1][i + 1] == 0)
589
candidate[i / IQK_SX_NR] = c2;
590
else if (result[c2][i] + result[c2][i + 1] == 0)
591
candidate[i / IQK_SX_NR] = c1;
592
else
593
bitmap |= BIT(i);
594
} else {
595
bitmap |= BIT(i);
596
}
597
}
598
599
if (bitmap != 0)
600
goto check_sim;
601
602
for (i = 0; i < PATH_NR; i++) {
603
if (candidate[i] == IQK_ROUND_INVALID)
604
continue;
605
606
for (j = i * IQK_SX_NR; j < i * IQK_SX_NR + 2; j++)
607
result[IQK_ROUND_HYBRID][j] = result[candidate[i]][j];
608
ret = false;
609
}
610
611
return ret;
612
613
check_sim:
614
for (i = 0; i < IQK_NR; i++) {
615
j = i & ~1; /* 2 bits are a pair for IQ[X, Y] */
616
if (bitmap & GENMASK(j + 1, j))
617
continue;
618
619
result[IQK_ROUND_HYBRID][i] = result[c1][i];
620
}
621
622
return false;
623
}
624
625
static u8 __rtw8723x_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev)
626
{
627
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
628
u8 tx_rate = dm_info->tx_rate;
629
u8 limit_ofdm = 30;
630
631
switch (tx_rate) {
632
case DESC_RATE1M...DESC_RATE5_5M:
633
case DESC_RATE11M:
634
break;
635
case DESC_RATE6M...DESC_RATE48M:
636
limit_ofdm = 36;
637
break;
638
case DESC_RATE54M:
639
limit_ofdm = 34;
640
break;
641
case DESC_RATEMCS0...DESC_RATEMCS2:
642
limit_ofdm = 38;
643
break;
644
case DESC_RATEMCS3...DESC_RATEMCS4:
645
limit_ofdm = 36;
646
break;
647
case DESC_RATEMCS5...DESC_RATEMCS7:
648
limit_ofdm = 34;
649
break;
650
default:
651
rtw_warn(rtwdev, "pwrtrack unhandled tx_rate 0x%x\n", tx_rate);
652
break;
653
}
654
655
return limit_ofdm;
656
}
657
658
static
659
void __rtw8723x_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path,
660
u8 delta)
661
{
662
struct rtw_dm_info *dm_info = &rtwdev->dm_info;
663
const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev);
664
const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl;
665
const s8 *pwrtrk_xtal;
666
s8 xtal_cap;
667
668
if (dm_info->thermal_avg[therm_path] >
669
rtwdev->efuse.thermal_meter[therm_path])
670
pwrtrk_xtal = tbl->pwrtrk_xtal_p;
671
else
672
pwrtrk_xtal = tbl->pwrtrk_xtal_n;
673
674
xtal_cap = rtwdev->efuse.crystal_cap & 0x3F;
675
xtal_cap = clamp_t(s8, xtal_cap + pwrtrk_xtal[delta], 0, 0x3F);
676
rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL,
677
xtal_cap | (xtal_cap << 6));
678
}
679
680
static
681
void __rtw8723x_fill_txdesc_checksum(struct rtw_dev *rtwdev,
682
struct rtw_tx_pkt_info *pkt_info,
683
u8 *txdesc)
684
{
685
size_t words = 32 / 2; /* calculate the first 32 bytes (16 words) */
686
__le16 chksum = 0;
687
__le16 *data = (__le16 *)(txdesc);
688
struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)txdesc;
689
690
le32p_replace_bits(&tx_desc->w7, 0, RTW_TX_DESC_W7_TXDESC_CHECKSUM);
691
692
while (words--)
693
chksum ^= *data++;
694
695
chksum = ~chksum;
696
697
le32p_replace_bits(&tx_desc->w7, __le16_to_cpu(chksum),
698
RTW_TX_DESC_W7_TXDESC_CHECKSUM);
699
}
700
701
static void __rtw8723x_coex_cfg_init(struct rtw_dev *rtwdev)
702
{
703
/* enable TBTT nterrupt */
704
rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
705
706
/* BT report packet sample rate */
707
/* 0x790[5:0]=0x5 */
708
rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5);
709
710
/* enable BT counter statistics */
711
rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1);
712
713
/* enable PTA (3-wire function form BT side) */
714
rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN);
715
rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_PO_BT_PTA_PINS);
716
717
/* enable PTA (tx/rx signal form WiFi side) */
718
rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN);
719
}
720
721
const struct rtw8723x_common rtw8723x_common = {
722
.iqk_adda_regs = {
723
0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84,
724
0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec
725
},
726
.iqk_mac8_regs = {0x522, 0x550, 0x551},
727
.iqk_mac32_regs = {0x40},
728
.iqk_bb_regs = {
729
0xc04, 0xc08, 0x874, 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0xa04
730
},
731
732
.ltecoex_addr = {
733
.ctrl = REG_LTECOEX_CTRL,
734
.wdata = REG_LTECOEX_WRITE_DATA,
735
.rdata = REG_LTECOEX_READ_DATA,
736
},
737
.rf_sipi_addr = {
738
[RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read = 0x8a0,
739
.hssi_2 = 0x824, .lssi_read_pi = 0x8b8},
740
[RF_PATH_B] = { .hssi_1 = 0x828, .lssi_read = 0x8a4,
741
.hssi_2 = 0x82c, .lssi_read_pi = 0x8bc},
742
},
743
.dig = {
744
[0] = { .addr = 0xc50, .mask = 0x7f },
745
[1] = { .addr = 0xc50, .mask = 0x7f },
746
},
747
.dig_cck = {
748
[0] = { .addr = 0xa0c, .mask = 0x3f00 },
749
},
750
.prioq_addrs = {
751
.prio[RTW_DMA_MAPPING_EXTRA] = {
752
.rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3,
753
},
754
.prio[RTW_DMA_MAPPING_LOW] = {
755
.rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1,
756
},
757
.prio[RTW_DMA_MAPPING_NORMAL] = {
758
.rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1,
759
},
760
.prio[RTW_DMA_MAPPING_HIGH] = {
761
.rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2,
762
},
763
.wsize = false,
764
},
765
766
.lck = __rtw8723x_lck,
767
.read_efuse = __rtw8723x_read_efuse,
768
.mac_init = __rtw8723x_mac_init,
769
.mac_postinit = __rtw8723x_mac_postinit,
770
.cfg_ldo25 = __rtw8723x_cfg_ldo25,
771
.set_tx_power_index = __rtw8723x_set_tx_power_index,
772
.efuse_grant = __rtw8723x_efuse_grant,
773
.false_alarm_statistics = __rtw8723x_false_alarm_statistics,
774
.iqk_backup_regs = __rtw8723x_iqk_backup_regs,
775
.iqk_restore_regs = __rtw8723x_iqk_restore_regs,
776
.iqk_similarity_cmp = __rtw8723x_iqk_similarity_cmp,
777
.pwrtrack_get_limit_ofdm = __rtw8723x_pwrtrack_get_limit_ofdm,
778
.pwrtrack_set_xtal = __rtw8723x_pwrtrack_set_xtal,
779
.coex_cfg_init = __rtw8723x_coex_cfg_init,
780
.fill_txdesc_checksum = __rtw8723x_fill_txdesc_checksum,
781
.debug_txpwr_limit = __rtw8723x_debug_txpwr_limit,
782
};
783
EXPORT_SYMBOL(rtw8723x_common);
784
785
MODULE_AUTHOR("Realtek Corporation");
786
MODULE_AUTHOR("Fiona Klute <[email protected]>");
787
MODULE_DESCRIPTION("Common functions for Realtek 802.11n wireless 8723x drivers");
788
MODULE_LICENSE("Dual BSD/GPL");
789
790