Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nu11secur1ty
GitHub Repository: nu11secur1ty/Kali-Linux
Path: blob/master/ALFA-W1F1/RTL8814AU/hal/phydm/phydm_cfotracking.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
* The full GNU General Public License is included in this distribution in the
15
* file called LICENSE.
16
*
17
* Contact Information:
18
* wlanfae <[email protected]>
19
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20
* Hsinchu 300, Taiwan.
21
*
22
* Larry Finger <[email protected]>
23
*
24
*****************************************************************************/
25
#include "mp_precomp.h"
26
#include "phydm_precomp.h"
27
28
s32 phydm_get_cfo_hz(void *dm_void, u32 val, u8 bit_num, u8 frac_num)
29
{
30
s32 val_s = 0;
31
32
val_s = phydm_cnvrt_2_sign(val, bit_num);
33
34
if (frac_num == 10) /*@ (X*312500)/1024 ~= X*305*/
35
val_s *= 305;
36
else if (frac_num == 11) /*@ (X*312500)/2048 ~= X*152*/
37
val_s *= 152;
38
else if (frac_num == 12) /*@ (X*312500)/4096 ~= X*76*/
39
val_s *= 76;
40
41
return val_s;
42
}
43
44
#if (ODM_IC_11AC_SERIES_SUPPORT)
45
void phydm_get_cfo_info_ac(void *dm_void, struct phydm_cfo_rpt *cfo)
46
{
47
struct dm_struct *dm = (struct dm_struct *)dm_void;
48
u8 i = 0;
49
u32 val[4] = {0};
50
u32 val_1[4] = {0};
51
u32 val_2[4] = {0};
52
u32 val_tmp = 0;
53
54
val[0] = odm_read_4byte(dm, R_0xd0c);
55
val_1[0] = odm_read_4byte(dm, R_0xd10);
56
val_2[0] = odm_get_bb_reg(dm, R_0xd14, 0x1fff0000);
57
58
#if (defined(PHYDM_COMPILE_ABOVE_2SS))
59
val[1] = odm_read_4byte(dm, R_0xd4c);
60
val_1[1] = odm_read_4byte(dm, R_0xd50);
61
val_2[1] = odm_get_bb_reg(dm, R_0xd54, 0x1fff0000);
62
#endif
63
64
#if (defined(PHYDM_COMPILE_ABOVE_3SS))
65
val[2] = odm_read_4byte(dm, R_0xd8c);
66
val_1[2] = odm_read_4byte(dm, R_0xd90);
67
val_2[2] = odm_get_bb_reg(dm, R_0xd94, 0x1fff0000);
68
#endif
69
70
#if (defined(PHYDM_COMPILE_ABOVE_4SS))
71
val[3] = odm_read_4byte(dm, R_0xdcc);
72
val_1[3] = odm_read_4byte(dm, R_0xdd0);
73
val_2[3] = odm_get_bb_reg(dm, R_0xdd4, 0x1fff0000);
74
#endif
75
76
for (i = 0; i < dm->num_rf_path; i++) {
77
val_tmp = val[i] & 0xfff; /*@ Short CFO, S(12,11)*/
78
cfo->cfo_rpt_s[i] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
79
80
val_tmp = val[i] >> 16; /*@ Long CFO, S(13,12)*/
81
cfo->cfo_rpt_l[i] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
82
83
val_tmp = val_1[i] & 0x7ff; /*@ SCFO, S(11,10)*/
84
cfo->cfo_rpt_sec[i] = phydm_get_cfo_hz(dm, val_tmp, 11, 10);
85
86
val_tmp = val_1[i] >> 16; /*@ Acq CFO, S(13,12)*/
87
cfo->cfo_rpt_acq[i] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
88
89
val_tmp = val_2[i]; /*@ End CFO, S(13,12)*/
90
cfo->cfo_rpt_end[i] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
91
}
92
}
93
#endif
94
95
#if (ODM_IC_11N_SERIES_SUPPORT)
96
void phydm_get_cfo_info_n(void *dm_void, struct phydm_cfo_rpt *cfo)
97
{
98
struct dm_struct *dm = (struct dm_struct *)dm_void;
99
u32 val[5] = {0};
100
u32 val_tmp = 0;
101
102
odm_set_bb_reg(dm, R_0xd00, BIT(26), 1);
103
104
val[0] = odm_read_4byte(dm, R_0xdac); /*@ Short CFO*/
105
val[1] = odm_read_4byte(dm, R_0xdb0); /*@ Long CFO*/
106
val[2] = odm_read_4byte(dm, R_0xdb8); /*@ Sec CFO*/
107
val[3] = odm_read_4byte(dm, R_0xde0); /*@ Acq CFO*/
108
val[4] = odm_read_4byte(dm, R_0xdbc); /*@ End CFO*/
109
110
/*@[path-A]*/
111
if (dm->support_ic_type & (ODM_RTL8721D | ODM_RTL8710C)) {
112
val_tmp = (val[0] & 0x0fff0000) >> 16; /*@ Short CFO, S(12,11)*/
113
cfo->cfo_rpt_s[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
114
val_tmp = (val[1] & 0x0fff0000) >> 16; /*@ Long CFO, S(12,11)*/
115
cfo->cfo_rpt_l[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
116
val_tmp = (val[2] & 0x0fff0000) >> 16; /*@ Sec CFO, S(12,11)*/
117
cfo->cfo_rpt_sec[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
118
val_tmp = (val[3] & 0x0fff0000) >> 16; /*@ Acq CFO, S(12,11)*/
119
cfo->cfo_rpt_acq[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
120
val_tmp = (val[4] & 0x0fff0000) >> 16; /*@ Acq CFO, S(12,11)*/
121
cfo->cfo_rpt_end[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
122
} else {
123
val_tmp = (val[0] & 0x0fff0000) >> 16; /*@ Short CFO, S(12,11)*/
124
cfo->cfo_rpt_s[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
125
val_tmp = (val[1] & 0x1fff0000) >> 16; /*@ Long CFO, S(13,12)*/
126
cfo->cfo_rpt_l[0] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
127
val_tmp = (val[2] & 0x7ff0000) >> 16; /*@ Sec CFO, S(11,10)*/
128
cfo->cfo_rpt_sec[0] = phydm_get_cfo_hz(dm, val_tmp, 11, 10);
129
val_tmp = (val[3] & 0x1fff0000) >> 16; /*@ Acq CFO, S(13,12)*/
130
cfo->cfo_rpt_acq[0] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
131
val_tmp = (val[4] & 0x1fff0000) >> 16; /*@ Acq CFO, S(13,12)*/
132
cfo->cfo_rpt_end[0] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
133
}
134
135
#if (defined(PHYDM_COMPILE_ABOVE_2SS))
136
/*@[path-B]*/
137
val_tmp = val[0] & 0xfff; /*@ Short CFO, S(12,11)*/
138
cfo->cfo_rpt_s[1] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
139
val_tmp = val[1] & 0x1fff; /*@ Long CFO, S(13,12)*/
140
cfo->cfo_rpt_l[1] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
141
val_tmp = val[2] & 0x7ff; /*@ Sec CFO, S(11,10)*/
142
cfo->cfo_rpt_sec[1] = phydm_get_cfo_hz(dm, val_tmp, 11, 10);
143
val_tmp = val[3] & 0x1fff; /*@ Acq CFO, S(13,12)*/
144
cfo->cfo_rpt_acq[1] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
145
val_tmp = val[4] & 0x1fff; /*@ Acq CFO, S(13,12)*/
146
cfo->cfo_rpt_end[1] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
147
#endif
148
}
149
150
void phydm_set_atc_status(void *dm_void, boolean atc_status)
151
{
152
struct dm_struct *dm = (struct dm_struct *)dm_void;
153
struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
154
u32 reg_tmp = 0;
155
u32 mask_tmp = 0;
156
157
PHYDM_DBG(dm, DBG_CFO_TRK, "[%s]ATC_en=%d\n", __func__, atc_status);
158
159
if (cfo_track->is_atc_status == atc_status)
160
return;
161
162
reg_tmp = ODM_REG(BB_ATC, dm);
163
mask_tmp = ODM_BIT(BB_ATC, dm);
164
odm_set_bb_reg(dm, reg_tmp, mask_tmp, atc_status);
165
cfo_track->is_atc_status = atc_status;
166
}
167
168
boolean
169
phydm_get_atc_status(void *dm_void)
170
{
171
boolean atc_status = false;
172
struct dm_struct *dm = (struct dm_struct *)dm_void;
173
u32 reg_tmp = 0;
174
u32 mask_tmp = 0;
175
176
reg_tmp = ODM_REG(BB_ATC, dm);
177
mask_tmp = ODM_BIT(BB_ATC, dm);
178
179
atc_status = (boolean)odm_get_bb_reg(dm, reg_tmp, mask_tmp);
180
181
PHYDM_DBG(dm, DBG_CFO_TRK, "[%s]atc_status=%d\n", __func__, atc_status);
182
return atc_status;
183
}
184
#endif
185
186
void phydm_get_cfo_info(void *dm_void, struct phydm_cfo_rpt *cfo)
187
{
188
struct dm_struct *dm = (struct dm_struct *)dm_void;
189
190
switch (dm->ic_ip_series) {
191
#if (ODM_IC_11N_SERIES_SUPPORT)
192
case PHYDM_IC_N:
193
phydm_get_cfo_info_n(dm, cfo);
194
break;
195
#endif
196
#if (ODM_IC_11AC_SERIES_SUPPORT)
197
case PHYDM_IC_AC:
198
phydm_get_cfo_info_ac(dm, cfo);
199
break;
200
#endif
201
default:
202
break;
203
}
204
}
205
206
boolean
207
phydm_set_crystal_cap_reg(void *dm_void, u8 crystal_cap)
208
{
209
struct dm_struct *dm = (struct dm_struct *)dm_void;
210
struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
211
u32 reg_val = 0;
212
213
if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B |
214
ODM_RTL8195B | ODM_RTL8812F | ODM_RTL8721D | ODM_RTL8710C)) {
215
crystal_cap &= 0x7F;
216
reg_val = crystal_cap | (crystal_cap << 7);
217
} else {
218
crystal_cap &= 0x3F;
219
reg_val = crystal_cap | (crystal_cap << 6);
220
}
221
222
cfo_track->crystal_cap = crystal_cap;
223
224
if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8188F)) {
225
#if (RTL8188E_SUPPORT || RTL8188F_SUPPORT)
226
/* write 0x24[22:17] = 0x24[16:11] = crystal_cap */
227
odm_set_mac_reg(dm, R_0x24, 0x7ff800, reg_val);
228
#endif
229
}
230
#if (RTL8812A_SUPPORT)
231
else if (dm->support_ic_type & ODM_RTL8812) {
232
/* write 0x2C[30:25] = 0x2C[24:19] = crystal_cap */
233
odm_set_mac_reg(dm, R_0x2c, 0x7FF80000, reg_val);
234
}
235
#endif
236
#if (RTL8703B_SUPPORT || RTL8723B_SUPPORT || RTL8192E_SUPPORT ||\
237
RTL8821A_SUPPORT || RTL8723D_SUPPORT)
238
else if ((dm->support_ic_type &
239
(ODM_RTL8703B | ODM_RTL8723B | ODM_RTL8192E | ODM_RTL8821 |
240
ODM_RTL8723D))) {
241
/* @0x2C[23:18] = 0x2C[17:12] = crystal_cap */
242
odm_set_mac_reg(dm, R_0x2c, 0x00FFF000, reg_val);
243
}
244
#endif
245
#if (RTL8814A_SUPPORT)
246
else if (dm->support_ic_type & ODM_RTL8814A) {
247
/* write 0x2C[26:21] = 0x2C[20:15] = crystal_cap */
248
odm_set_mac_reg(dm, R_0x2c, 0x07FF8000, reg_val);
249
}
250
#endif
251
#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT || RTL8197F_SUPPORT ||\
252
RTL8192F_SUPPORT || RTL8197G_SUPPORT)
253
else if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C |
254
ODM_RTL8197F | ODM_RTL8192F | ODM_RTL8197G)) {
255
/* write 0x24[30:25] = 0x28[6:1] = crystal_cap */
256
odm_set_mac_reg(dm, R_0x24, 0x7e000000, crystal_cap);
257
odm_set_mac_reg(dm, R_0x28, 0x7e, crystal_cap);
258
}
259
#endif
260
#if (RTL8710B_SUPPORT)
261
else if (dm->support_ic_type & (ODM_RTL8710B)) {
262
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
263
/* write 0x60[29:24] = 0x60[23:18] = crystal_cap */
264
HAL_SetSYSOnReg(dm->adapter, R_0x60, 0x3FFC0000, reg_val);
265
#endif
266
}
267
#endif
268
#if (RTL8195B_SUPPORT)
269
else if (dm->support_ic_type & ODM_RTL8195B) {
270
phydm_set_crystalcap(dm, (u8)(reg_val & 0x7f));
271
}
272
#endif
273
#if (RTL8721D_SUPPORT)
274
else if (dm->support_ic_type & (ODM_RTL8721D)) {
275
/* write 0x4800_0228[30:24] crystal_cap */
276
/*HAL_SetSYSOnReg(dm->adapter, */
277
/*REG_SYS_XTAL_8721d, 0x7F000000, crystal_cap);*/
278
u32 temp_val = HAL_READ32(SYSTEM_CTRL_BASE_LP,
279
REG_SYS_EFUSE_SYSCFG2);
280
temp_val = ((crystal_cap << 24) & 0x7F000000)
281
| (temp_val & (~0x7F000000));
282
HAL_WRITE32(SYSTEM_CTRL_BASE_LP, REG_SYS_EFUSE_SYSCFG2,
283
temp_val);
284
}
285
#endif
286
#if (RTL8710C_SUPPORT)
287
else if (dm->support_ic_type & (ODM_RTL8710C)) {
288
/* write MAC reg 0x28[13:7][6:0] crystal_cap */
289
phydm_set_crystalcap(dm, (u8)(reg_val & 0x7f));
290
}
291
#endif
292
293
#if (RTL8822C_SUPPORT || RTL8814B_SUPPORT || RTL8812F_SUPPORT)
294
else if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B |
295
ODM_RTL8812F)) {
296
/* write 0x1040[23:17] = 0x1040[16:10] = crystal_cap */
297
odm_set_mac_reg(dm, R_0x1040, 0x00FFFC00, reg_val);
298
} else {
299
return false;
300
}
301
#endif
302
return true;
303
}
304
305
void phydm_set_crystal_cap(void *dm_void, u8 crystal_cap)
306
{
307
struct dm_struct *dm = (struct dm_struct *)dm_void;
308
struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
309
310
if (cfo_track->crystal_cap == crystal_cap)
311
return;
312
313
if (phydm_set_crystal_cap_reg(dm, crystal_cap))
314
PHYDM_DBG(dm, DBG_CFO_TRK, "Set crystal_cap = 0x%x\n",
315
cfo_track->crystal_cap);
316
else
317
PHYDM_DBG(dm, DBG_CFO_TRK, "Set fail\n");
318
}
319
320
void phydm_cfo_tracking_reset(void *dm_void)
321
{
322
struct dm_struct *dm = (struct dm_struct *)dm_void;
323
struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
324
325
PHYDM_DBG(dm, DBG_CFO_TRK, "%s ======>\n", __func__);
326
327
if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8195B |
328
ODM_RTL8812F))
329
cfo_track->def_x_cap = cfo_track->crystal_cap_default & 0x7f;
330
else
331
cfo_track->def_x_cap = cfo_track->crystal_cap_default & 0x3f;
332
333
cfo_track->is_adjust = true;
334
335
if (cfo_track->crystal_cap > cfo_track->def_x_cap) {
336
phydm_set_crystal_cap(dm, cfo_track->crystal_cap - 1);
337
PHYDM_DBG(dm, DBG_CFO_TRK, "approch to Init-val (0x%x)\n",
338
cfo_track->crystal_cap);
339
340
} else if (cfo_track->crystal_cap < cfo_track->def_x_cap) {
341
phydm_set_crystal_cap(dm, cfo_track->crystal_cap + 1);
342
PHYDM_DBG(dm, DBG_CFO_TRK, "approch to init-val 0x%x\n",
343
cfo_track->crystal_cap);
344
}
345
346
#if ODM_IC_11N_SERIES_SUPPORT
347
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
348
if (dm->support_ic_type & ODM_IC_11N_SERIES)
349
phydm_set_atc_status(dm, true);
350
#endif
351
#endif
352
}
353
354
void phydm_cfo_tracking_init(void *dm_void)
355
{
356
struct dm_struct *dm = (struct dm_struct *)dm_void;
357
struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
358
359
PHYDM_DBG(dm, DBG_CFO_TRK, "[%s]=========>\n", __func__);
360
if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B | ODM_RTL8195B |
361
ODM_RTL8812F))
362
cfo_track->crystal_cap = cfo_track->crystal_cap_default & 0x7f;
363
else
364
cfo_track->crystal_cap = cfo_track->crystal_cap_default & 0x3f;
365
366
cfo_track->def_x_cap = cfo_track->crystal_cap;
367
cfo_track->is_adjust = true;
368
PHYDM_DBG(dm, DBG_CFO_TRK, "crystal_cap=0x%x\n", cfo_track->def_x_cap);
369
370
#if (RTL8822B_SUPPORT || RTL8821C_SUPPORT)
371
/* @Crystal cap. control by WiFi */
372
if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C))
373
odm_set_mac_reg(dm, R_0x10, 0x40, 0x1);
374
#endif
375
}
376
377
void phydm_cfo_tracking(void *dm_void)
378
{
379
struct dm_struct *dm = (struct dm_struct *)dm_void;
380
struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
381
s32 cfo_avg = 0, cfo_path_sum = 0, cfo_abs = 0;
382
u32 cfo_rpt_sum = 0, cfo_khz_avg[4] = {0};
383
s8 crystal_cap = cfo_track->crystal_cap;
384
u8 i = 0, valid_path_cnt = 0;
385
386
if (!(dm->support_ability & ODM_BB_CFO_TRACKING))
387
return;
388
389
PHYDM_DBG(dm, DBG_CFO_TRK, "%s ======>\n", __func__);
390
391
if (!dm->is_linked || !dm->is_one_entry_only) {
392
phydm_cfo_tracking_reset(dm);
393
PHYDM_DBG(dm, DBG_CFO_TRK, "is_linked=%d, one_entry_only=%d\n",
394
dm->is_linked, dm->is_one_entry_only);
395
396
} else {
397
/* No new packet */
398
if (cfo_track->packet_count == cfo_track->packet_count_pre) {
399
PHYDM_DBG(dm, DBG_CFO_TRK, "Pkt cnt doesn't change\n");
400
return;
401
}
402
cfo_track->packet_count_pre = cfo_track->packet_count;
403
404
/*@Calculate CFO */
405
for (i = 0; i < dm->num_rf_path; i++) {
406
if (!(dm->rx_ant_status & BIT(i)))
407
continue;
408
409
valid_path_cnt++;
410
411
if (cfo_track->CFO_tail[i] < 0)
412
cfo_abs = 0 - cfo_track->CFO_tail[i];
413
else
414
cfo_abs = cfo_track->CFO_tail[i];
415
416
cfo_rpt_sum = (u32)CFO_HW_RPT_2_KHZ(cfo_abs);
417
cfo_khz_avg[i] = PHYDM_DIV(cfo_rpt_sum,
418
cfo_track->CFO_cnt[i]);
419
420
PHYDM_DBG(dm, DBG_CFO_TRK,
421
"[Path-%d] CFO_sum=((%d)), cnt=((%d)), CFO_avg=((%s%d))kHz\n",
422
i, cfo_rpt_sum, cfo_track->CFO_cnt[i],
423
((cfo_track->CFO_tail[i] < 0) ? "-" : " "),
424
cfo_khz_avg[i]);
425
426
if (cfo_track->CFO_tail[i] < 0)
427
cfo_path_sum += (0 - (s32)cfo_khz_avg[i]);
428
else
429
cfo_path_sum += (s32)cfo_khz_avg[i];
430
}
431
432
if (valid_path_cnt >= 2)
433
cfo_avg = cfo_path_sum / valid_path_cnt;
434
else
435
cfo_avg = cfo_path_sum;
436
437
cfo_track->CFO_ave_pre = cfo_avg;
438
439
PHYDM_DBG(dm, DBG_CFO_TRK, "path_cnt=%d, CFO_avg_path=%d kHz\n",
440
valid_path_cnt, cfo_avg);
441
442
/*reset counter*/
443
for (i = 0; i < dm->num_rf_path; i++) {
444
cfo_track->CFO_tail[i] = 0;
445
cfo_track->CFO_cnt[i] = 0;
446
}
447
448
/* To adjust crystal cap or not */
449
if (!cfo_track->is_adjust) {
450
if (cfo_avg > CFO_TRK_ENABLE_TH ||
451
cfo_avg < (-CFO_TRK_ENABLE_TH))
452
cfo_track->is_adjust = true;
453
} else {
454
if (cfo_avg <= CFO_TRK_STOP_TH &&
455
cfo_avg >= (-CFO_TRK_STOP_TH))
456
cfo_track->is_adjust = false;
457
}
458
459
#ifdef ODM_CONFIG_BT_COEXIST
460
/*@BT case: Disable CFO tracking */
461
if (dm->bt_info_table.is_bt_enabled) {
462
cfo_track->is_adjust = false;
463
phydm_set_crystal_cap(dm, cfo_track->def_x_cap);
464
PHYDM_DBG(dm, DBG_CFO_TRK, "[BT]Disable CFO_track\n");
465
}
466
#endif
467
468
/*@Adjust Crystal Cap. */
469
if (cfo_track->is_adjust) {
470
if (cfo_avg > CFO_TRK_STOP_TH)
471
crystal_cap += 1;
472
else if (cfo_avg < (-CFO_TRK_STOP_TH))
473
crystal_cap -= 1;
474
475
if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B |
476
ODM_RTL8195B | ODM_RTL8812F)) {
477
if (crystal_cap > 0x7F)
478
crystal_cap = 0x7F;
479
} else {
480
if (crystal_cap > 0x3F)
481
crystal_cap = 0x3F;
482
}
483
if (crystal_cap < 0)
484
crystal_cap = 0;
485
486
phydm_set_crystal_cap(dm, (u8)crystal_cap);
487
}
488
489
PHYDM_DBG(dm, DBG_CFO_TRK, "X_cap{Curr,Default}={0x%x,0x%x}\n",
490
cfo_track->crystal_cap, cfo_track->def_x_cap);
491
492
/* @Dynamic ATC switch */
493
#if ODM_IC_11N_SERIES_SUPPORT
494
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
495
if (dm->support_ic_type & ODM_IC_11N_SERIES) {
496
if (cfo_avg < CFO_TH_ATC && cfo_avg > -CFO_TH_ATC)
497
phydm_set_atc_status(dm, false);
498
else
499
phydm_set_atc_status(dm, true);
500
501
}
502
#endif
503
#endif
504
}
505
}
506
507
void phydm_parsing_cfo(void *dm_void, void *pktinfo_void, s8 *pcfotail,
508
u8 num_ss)
509
{
510
struct dm_struct *dm = (struct dm_struct *)dm_void;
511
struct phydm_perpkt_info_struct *pktinfo = NULL;
512
struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
513
boolean valid_info = false;
514
u8 i = 0;
515
516
if (!(dm->support_ability & ODM_BB_CFO_TRACKING))
517
return;
518
519
pktinfo = (struct phydm_perpkt_info_struct *)pktinfo_void;
520
521
#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE | ODM_IOT))
522
if (pktinfo->is_packet_match_bssid)
523
valid_info = true;
524
#else
525
if (dm->number_active_client == 1)
526
valid_info = true;
527
#endif
528
if (valid_info) {
529
if (num_ss > dm->num_rf_path) /*@For fool proof*/
530
num_ss = dm->num_rf_path;
531
#if 0
532
PHYDM_DBG(dm, DBG_CFO_TRK, "num_ss=%d, num_rf_path=%d\n",
533
num_ss, dm->num_rf_path);
534
#endif
535
536
/* @ Update CFO report for path-A & path-B */
537
/* Only paht-A and path-B have CFO tail and short CFO */
538
for (i = 0; i < dm->num_rf_path; i++) {
539
if (!(dm->rx_ant_status & BIT(i)))
540
continue;
541
cfo_track->CFO_tail[i] += pcfotail[i];
542
cfo_track->CFO_cnt[i]++;
543
#if 0
544
PHYDM_DBG(dm, DBG_CFO_TRK,
545
"[ID %d][path %d][rate 0x%x] CFO_tail = ((%d)), CFO_tail_sum = ((%d)), CFO_cnt = ((%d))\n",
546
pktinfo->station_id, i, pktinfo->data_rate,
547
pcfotail[i], cfo_track->CFO_tail[i],
548
cfo_track->CFO_cnt[i]);
549
#endif
550
}
551
552
/* @ Update packet counter */
553
if (cfo_track->packet_count == 0xffffffff)
554
cfo_track->packet_count = 0;
555
else
556
cfo_track->packet_count++;
557
}
558
}
559
560
#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
561
void phy_Init_crystal_capacity(void *dm_void, u8 crystal_cap)
562
{
563
struct dm_struct *dm = (struct dm_struct *)dm_void;
564
565
if (!phydm_set_crystal_cap_reg(dm, crystal_cap))
566
RT_TRACE_F(COMP_INIT, DBG_SERIOUS,
567
("Crystal is not initialized!\n"));
568
}
569
#endif
570
571
void phydm_cfo_tracking_debug(void *dm_void, char input[][16], u32 *_used,
572
char *output, u32 *_out_len)
573
{
574
struct dm_struct *dm = (struct dm_struct *)dm_void;
575
struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
576
char help[] = "-h";
577
u32 var1[10] = {0};
578
u32 used = *_used;
579
u32 out_len = *_out_len;
580
581
if ((strcmp(input[1], help) == 0)) {
582
PDM_SNPF(out_len, used, output + used, out_len - used,
583
"set Xcap: {1}\n");
584
PDM_SNPF(out_len, used, output + used, out_len - used,
585
"show Xcap: {100}\n");
586
} else {
587
PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]);
588
589
if (var1[0] == 1) {
590
PHYDM_SSCANF(input[2], DCMD_HEX, &var1[1]);
591
phydm_set_crystal_cap(dm, (u8)var1[1]);
592
PDM_SNPF(out_len, used, output + used, out_len - used,
593
"Set X_cap=0x%x\n", cfo_track->crystal_cap);
594
} else if (var1[0] == 100) {
595
PDM_SNPF(out_len, used, output + used, out_len - used,
596
"X_cap=0x%x\n", cfo_track->crystal_cap);
597
}
598
}
599
*_used = used;
600
*_out_len = out_len;
601
}
602
603
604