1
2
3
4
5#include <linux/bcd.h>
6
7#include "main.h"
8#include "reg.h"
9#include "fw.h"
10#include "phy.h"
11#include "debug.h"
12
13struct phy_cfg_pair {
14 u32 addr;
15 u32 data;
16};
17
18union phy_table_tile {
19 struct rtw_phy_cond cond;
20 struct phy_cfg_pair cfg;
21};
22
23static const u32 db_invert_table[12][8] = {
24 {10, 13, 16, 20,
25 25, 32, 40, 50},
26 {64, 80, 101, 128,
27 160, 201, 256, 318},
28 {401, 505, 635, 800,
29 1007, 1268, 1596, 2010},
30 {316, 398, 501, 631,
31 794, 1000, 1259, 1585},
32 {1995, 2512, 3162, 3981,
33 5012, 6310, 7943, 10000},
34 {12589, 15849, 19953, 25119,
35 31623, 39811, 50119, 63098},
36 {79433, 100000, 125893, 158489,
37 199526, 251189, 316228, 398107},
38 {501187, 630957, 794328, 1000000,
39 1258925, 1584893, 1995262, 2511886},
40 {3162278, 3981072, 5011872, 6309573,
41 7943282, 1000000, 12589254, 15848932},
42 {19952623, 25118864, 31622777, 39810717,
43 50118723, 63095734, 79432823, 100000000},
44 {125892541, 158489319, 199526232, 251188643,
45 316227766, 398107171, 501187234, 630957345},
46 {794328235, 1000000000, 1258925412, 1584893192,
47 1995262315, 2511886432U, 3162277660U, 3981071706U}
48};
49
50u8 rtw_cck_rates[] = { DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M };
51u8 rtw_ofdm_rates[] = {
52 DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
53 DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
54 DESC_RATE48M, DESC_RATE54M
55};
56u8 rtw_ht_1s_rates[] = {
57 DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
58 DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
59 DESC_RATEMCS6, DESC_RATEMCS7
60};
61u8 rtw_ht_2s_rates[] = {
62 DESC_RATEMCS8, DESC_RATEMCS9, DESC_RATEMCS10,
63 DESC_RATEMCS11, DESC_RATEMCS12, DESC_RATEMCS13,
64 DESC_RATEMCS14, DESC_RATEMCS15
65};
66u8 rtw_vht_1s_rates[] = {
67 DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
68 DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
69 DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
70 DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
71 DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9
72};
73u8 rtw_vht_2s_rates[] = {
74 DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
75 DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
76 DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
77 DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
78 DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9
79};
80u8 *rtw_rate_section[RTW_RATE_SECTION_MAX] = {
81 rtw_cck_rates, rtw_ofdm_rates,
82 rtw_ht_1s_rates, rtw_ht_2s_rates,
83 rtw_vht_1s_rates, rtw_vht_2s_rates
84};
85EXPORT_SYMBOL(rtw_rate_section);
86
87u8 rtw_rate_size[RTW_RATE_SECTION_MAX] = {
88 ARRAY_SIZE(rtw_cck_rates),
89 ARRAY_SIZE(rtw_ofdm_rates),
90 ARRAY_SIZE(rtw_ht_1s_rates),
91 ARRAY_SIZE(rtw_ht_2s_rates),
92 ARRAY_SIZE(rtw_vht_1s_rates),
93 ARRAY_SIZE(rtw_vht_2s_rates)
94};
95EXPORT_SYMBOL(rtw_rate_size);
96
97static const u8 rtw_cck_size = ARRAY_SIZE(rtw_cck_rates);
98static const u8 rtw_ofdm_size = ARRAY_SIZE(rtw_ofdm_rates);
99static const u8 rtw_ht_1s_size = ARRAY_SIZE(rtw_ht_1s_rates);
100static const u8 rtw_ht_2s_size = ARRAY_SIZE(rtw_ht_2s_rates);
101static const u8 rtw_vht_1s_size = ARRAY_SIZE(rtw_vht_1s_rates);
102static const u8 rtw_vht_2s_size = ARRAY_SIZE(rtw_vht_2s_rates);
103
104enum rtw_phy_band_type {
105 PHY_BAND_2G = 0,
106 PHY_BAND_5G = 1,
107};
108
109static void rtw_phy_cck_pd_init(struct rtw_dev *rtwdev)
110{
111 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
112 u8 i, j;
113
114 for (i = 0; i <= RTW_CHANNEL_WIDTH_40; i++) {
115 for (j = 0; j < RTW_RF_PATH_MAX; j++)
116 dm_info->cck_pd_lv[i][j] = CCK_PD_LV0;
117 }
118
119 dm_info->cck_fa_avg = CCK_FA_AVG_RESET;
120}
121
122void rtw_phy_init(struct rtw_dev *rtwdev)
123{
124 struct rtw_chip_info *chip = rtwdev->chip;
125 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
126 u32 addr, mask;
127
128 dm_info->fa_history[3] = 0;
129 dm_info->fa_history[2] = 0;
130 dm_info->fa_history[1] = 0;
131 dm_info->fa_history[0] = 0;
132 dm_info->igi_bitmap = 0;
133 dm_info->igi_history[3] = 0;
134 dm_info->igi_history[2] = 0;
135 dm_info->igi_history[1] = 0;
136
137 addr = chip->dig[0].addr;
138 mask = chip->dig[0].mask;
139 dm_info->igi_history[0] = rtw_read32_mask(rtwdev, addr, mask);
140 rtw_phy_cck_pd_init(rtwdev);
141
142 dm_info->iqk.done = false;
143}
144EXPORT_SYMBOL(rtw_phy_init);
145
146void rtw_phy_dig_write(struct rtw_dev *rtwdev, u8 igi)
147{
148 struct rtw_chip_info *chip = rtwdev->chip;
149 struct rtw_hal *hal = &rtwdev->hal;
150 u32 addr, mask;
151 u8 path;
152
153 if (chip->dig_cck) {
154 const struct rtw_hw_reg *dig_cck = &chip->dig_cck[0];
155 rtw_write32_mask(rtwdev, dig_cck->addr, dig_cck->mask, igi >> 1);
156 }
157
158 for (path = 0; path < hal->rf_path_num; path++) {
159 addr = chip->dig[path].addr;
160 mask = chip->dig[path].mask;
161 rtw_write32_mask(rtwdev, addr, mask, igi);
162 }
163}
164
165static void rtw_phy_stat_false_alarm(struct rtw_dev *rtwdev)
166{
167 struct rtw_chip_info *chip = rtwdev->chip;
168
169 chip->ops->false_alarm_statistics(rtwdev);
170}
171
172#define RA_FLOOR_TABLE_SIZE 7
173#define RA_FLOOR_UP_GAP 3
174
175static u8 rtw_phy_get_rssi_level(u8 old_level, u8 rssi)
176{
177 u8 table[RA_FLOOR_TABLE_SIZE] = {20, 34, 38, 42, 46, 50, 100};
178 u8 new_level = 0;
179 int i;
180
181 for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++)
182 if (i >= old_level)
183 table[i] += RA_FLOOR_UP_GAP;
184
185 for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) {
186 if (rssi < table[i]) {
187 new_level = i;
188 break;
189 }
190 }
191
192 return new_level;
193}
194
195struct rtw_phy_stat_iter_data {
196 struct rtw_dev *rtwdev;
197 u8 min_rssi;
198};
199
200static void rtw_phy_stat_rssi_iter(void *data, struct ieee80211_sta *sta)
201{
202 struct rtw_phy_stat_iter_data *iter_data = data;
203 struct rtw_dev *rtwdev = iter_data->rtwdev;
204 struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
205 u8 rssi;
206
207 rssi = ewma_rssi_read(&si->avg_rssi);
208 si->rssi_level = rtw_phy_get_rssi_level(si->rssi_level, rssi);
209
210 rtw_fw_send_rssi_info(rtwdev, si);
211
212 iter_data->min_rssi = min_t(u8, rssi, iter_data->min_rssi);
213}
214
215static void rtw_phy_stat_rssi(struct rtw_dev *rtwdev)
216{
217 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
218 struct rtw_phy_stat_iter_data data = {};
219
220 data.rtwdev = rtwdev;
221 data.min_rssi = U8_MAX;
222 rtw_iterate_stas_atomic(rtwdev, rtw_phy_stat_rssi_iter, &data);
223
224 dm_info->pre_min_rssi = dm_info->min_rssi;
225 dm_info->min_rssi = data.min_rssi;
226}
227
228static void rtw_phy_stat_rate_cnt(struct rtw_dev *rtwdev)
229{
230 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
231
232 dm_info->last_pkt_count = dm_info->cur_pkt_count;
233 memset(&dm_info->cur_pkt_count, 0, sizeof(dm_info->cur_pkt_count));
234}
235
236static void rtw_phy_statistics(struct rtw_dev *rtwdev)
237{
238 rtw_phy_stat_rssi(rtwdev);
239 rtw_phy_stat_false_alarm(rtwdev);
240 rtw_phy_stat_rate_cnt(rtwdev);
241}
242
243#define DIG_PERF_FA_TH_LOW 250
244#define DIG_PERF_FA_TH_HIGH 500
245#define DIG_PERF_FA_TH_EXTRA_HIGH 750
246#define DIG_PERF_MAX 0x5a
247#define DIG_PERF_MID 0x40
248#define DIG_CVRG_FA_TH_LOW 2000
249#define DIG_CVRG_FA_TH_HIGH 4000
250#define DIG_CVRG_FA_TH_EXTRA_HIGH 5000
251#define DIG_CVRG_MAX 0x2a
252#define DIG_CVRG_MID 0x26
253#define DIG_CVRG_MIN 0x1c
254#define DIG_RSSI_GAIN_OFFSET 15
255
256static bool
257rtw_phy_dig_check_damping(struct rtw_dm_info *dm_info)
258{
259 u16 fa_lo = DIG_PERF_FA_TH_LOW;
260 u16 fa_hi = DIG_PERF_FA_TH_HIGH;
261 u16 *fa_history;
262 u8 *igi_history;
263 u8 damping_rssi;
264 u8 min_rssi;
265 u8 diff;
266 u8 igi_bitmap;
267 bool damping = false;
268
269 min_rssi = dm_info->min_rssi;
270 if (dm_info->damping) {
271 damping_rssi = dm_info->damping_rssi;
272 diff = min_rssi > damping_rssi ? min_rssi - damping_rssi :
273 damping_rssi - min_rssi;
274 if (diff > 3 || dm_info->damping_cnt++ > 20) {
275 dm_info->damping = false;
276 return false;
277 }
278
279 return true;
280 }
281
282 igi_history = dm_info->igi_history;
283 fa_history = dm_info->fa_history;
284 igi_bitmap = dm_info->igi_bitmap & 0xf;
285 switch (igi_bitmap) {
286 case 5:
287
288 if (igi_history[0] > igi_history[1] &&
289 igi_history[2] > igi_history[3] &&
290 igi_history[0] - igi_history[1] >= 2 &&
291 igi_history[2] - igi_history[3] >= 2 &&
292 fa_history[0] > fa_hi && fa_history[1] < fa_lo &&
293 fa_history[2] > fa_hi && fa_history[3] < fa_lo)
294 damping = true;
295 break;
296 case 9:
297
298 if (igi_history[0] > igi_history[1] &&
299 igi_history[3] > igi_history[2] &&
300 igi_history[0] - igi_history[1] >= 4 &&
301 igi_history[3] - igi_history[2] >= 2 &&
302 fa_history[0] > fa_hi && fa_history[1] < fa_lo &&
303 fa_history[2] < fa_lo && fa_history[3] > fa_hi)
304 damping = true;
305 break;
306 default:
307 return false;
308 }
309
310 if (damping) {
311 dm_info->damping = true;
312 dm_info->damping_cnt = 0;
313 dm_info->damping_rssi = min_rssi;
314 }
315
316 return damping;
317}
318
319static void rtw_phy_dig_get_boundary(struct rtw_dm_info *dm_info,
320 u8 *upper, u8 *lower, bool linked)
321{
322 u8 dig_max, dig_min, dig_mid;
323 u8 min_rssi;
324
325 if (linked) {
326 dig_max = DIG_PERF_MAX;
327 dig_mid = DIG_PERF_MID;
328
329 dig_min = 0x1c;
330 min_rssi = max_t(u8, dm_info->min_rssi, dig_min);
331 } else {
332 dig_max = DIG_CVRG_MAX;
333 dig_mid = DIG_CVRG_MID;
334 dig_min = DIG_CVRG_MIN;
335 min_rssi = dig_min;
336 }
337
338
339 dig_max = min_t(u8, dig_max, min_rssi + DIG_RSSI_GAIN_OFFSET);
340
341 *lower = clamp_t(u8, min_rssi, dig_min, dig_mid);
342 *upper = clamp_t(u8, *lower + DIG_RSSI_GAIN_OFFSET, dig_min, dig_max);
343}
344
345static void rtw_phy_dig_get_threshold(struct rtw_dm_info *dm_info,
346 u16 *fa_th, u8 *step, bool linked)
347{
348 u8 min_rssi, pre_min_rssi;
349
350 min_rssi = dm_info->min_rssi;
351 pre_min_rssi = dm_info->pre_min_rssi;
352 step[0] = 4;
353 step[1] = 3;
354 step[2] = 2;
355
356 if (linked) {
357 fa_th[0] = DIG_PERF_FA_TH_EXTRA_HIGH;
358 fa_th[1] = DIG_PERF_FA_TH_HIGH;
359 fa_th[2] = DIG_PERF_FA_TH_LOW;
360 if (pre_min_rssi > min_rssi) {
361 step[0] = 6;
362 step[1] = 4;
363 step[2] = 2;
364 }
365 } else {
366 fa_th[0] = DIG_CVRG_FA_TH_EXTRA_HIGH;
367 fa_th[1] = DIG_CVRG_FA_TH_HIGH;
368 fa_th[2] = DIG_CVRG_FA_TH_LOW;
369 }
370}
371
372static void rtw_phy_dig_recorder(struct rtw_dm_info *dm_info, u8 igi, u16 fa)
373{
374 u8 *igi_history;
375 u16 *fa_history;
376 u8 igi_bitmap;
377 bool up;
378
379 igi_bitmap = dm_info->igi_bitmap << 1 & 0xfe;
380 igi_history = dm_info->igi_history;
381 fa_history = dm_info->fa_history;
382
383 up = igi > igi_history[0];
384 igi_bitmap |= up;
385
386 igi_history[3] = igi_history[2];
387 igi_history[2] = igi_history[1];
388 igi_history[1] = igi_history[0];
389 igi_history[0] = igi;
390
391 fa_history[3] = fa_history[2];
392 fa_history[2] = fa_history[1];
393 fa_history[1] = fa_history[0];
394 fa_history[0] = fa;
395
396 dm_info->igi_bitmap = igi_bitmap;
397}
398
399static void rtw_phy_dig(struct rtw_dev *rtwdev)
400{
401 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
402 u8 upper_bound, lower_bound;
403 u8 pre_igi, cur_igi;
404 u16 fa_th[3], fa_cnt;
405 u8 level;
406 u8 step[3];
407 bool linked;
408
409 if (test_bit(RTW_FLAG_DIG_DISABLE, rtwdev->flags))
410 return;
411
412 if (rtw_phy_dig_check_damping(dm_info))
413 return;
414
415 linked = !!rtwdev->sta_cnt;
416
417 fa_cnt = dm_info->total_fa_cnt;
418 pre_igi = dm_info->igi_history[0];
419
420 rtw_phy_dig_get_threshold(dm_info, fa_th, step, linked);
421
422
423
424
425
426
427 cur_igi = pre_igi;
428 for (level = 0; level < 3; level++) {
429 if (fa_cnt > fa_th[level]) {
430 cur_igi += step[level];
431 break;
432 }
433 }
434 cur_igi -= 2;
435
436
437
438
439
440 rtw_phy_dig_get_boundary(dm_info, &upper_bound, &lower_bound, linked);
441 cur_igi = clamp_t(u8, cur_igi, lower_bound, upper_bound);
442
443
444
445
446 rtw_phy_dig_recorder(dm_info, cur_igi, fa_cnt);
447
448 if (cur_igi != pre_igi)
449 rtw_phy_dig_write(rtwdev, cur_igi);
450}
451
452static void rtw_phy_ra_info_update_iter(void *data, struct ieee80211_sta *sta)
453{
454 struct rtw_dev *rtwdev = data;
455 struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
456
457 rtw_update_sta_info(rtwdev, si);
458}
459
460static void rtw_phy_ra_info_update(struct rtw_dev *rtwdev)
461{
462 if (rtwdev->watch_dog_cnt & 0x3)
463 return;
464
465 rtw_iterate_stas_atomic(rtwdev, rtw_phy_ra_info_update_iter, rtwdev);
466}
467
468static void rtw_phy_dpk_track(struct rtw_dev *rtwdev)
469{
470 struct rtw_chip_info *chip = rtwdev->chip;
471
472 if (chip->ops->dpk_track)
473 chip->ops->dpk_track(rtwdev);
474}
475
476#define CCK_PD_FA_LV1_MIN 1000
477#define CCK_PD_FA_LV0_MAX 500
478
479static u8 rtw_phy_cck_pd_lv_unlink(struct rtw_dev *rtwdev)
480{
481 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
482 u32 cck_fa_avg = dm_info->cck_fa_avg;
483
484 if (cck_fa_avg > CCK_PD_FA_LV1_MIN)
485 return CCK_PD_LV1;
486
487 if (cck_fa_avg < CCK_PD_FA_LV0_MAX)
488 return CCK_PD_LV0;
489
490 return CCK_PD_LV_MAX;
491}
492
493#define CCK_PD_IGI_LV4_VAL 0x38
494#define CCK_PD_IGI_LV3_VAL 0x2a
495#define CCK_PD_IGI_LV2_VAL 0x24
496#define CCK_PD_RSSI_LV4_VAL 32
497#define CCK_PD_RSSI_LV3_VAL 32
498#define CCK_PD_RSSI_LV2_VAL 24
499
500static u8 rtw_phy_cck_pd_lv_link(struct rtw_dev *rtwdev)
501{
502 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
503 u8 igi = dm_info->igi_history[0];
504 u8 rssi = dm_info->min_rssi;
505 u32 cck_fa_avg = dm_info->cck_fa_avg;
506
507 if (igi > CCK_PD_IGI_LV4_VAL && rssi > CCK_PD_RSSI_LV4_VAL)
508 return CCK_PD_LV4;
509 if (igi > CCK_PD_IGI_LV3_VAL && rssi > CCK_PD_RSSI_LV3_VAL)
510 return CCK_PD_LV3;
511 if (igi > CCK_PD_IGI_LV2_VAL || rssi > CCK_PD_RSSI_LV2_VAL)
512 return CCK_PD_LV2;
513 if (cck_fa_avg > CCK_PD_FA_LV1_MIN)
514 return CCK_PD_LV1;
515 if (cck_fa_avg < CCK_PD_FA_LV0_MAX)
516 return CCK_PD_LV0;
517
518 return CCK_PD_LV_MAX;
519}
520
521static u8 rtw_phy_cck_pd_lv(struct rtw_dev *rtwdev)
522{
523 if (!rtw_is_assoc(rtwdev))
524 return rtw_phy_cck_pd_lv_unlink(rtwdev);
525 else
526 return rtw_phy_cck_pd_lv_link(rtwdev);
527}
528
529static void rtw_phy_cck_pd(struct rtw_dev *rtwdev)
530{
531 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
532 struct rtw_chip_info *chip = rtwdev->chip;
533 u32 cck_fa = dm_info->cck_fa_cnt;
534 u8 level;
535
536 if (rtwdev->hal.current_band_type != RTW_BAND_2G)
537 return;
538
539 if (dm_info->cck_fa_avg == CCK_FA_AVG_RESET)
540 dm_info->cck_fa_avg = cck_fa;
541 else
542 dm_info->cck_fa_avg = (dm_info->cck_fa_avg * 3 + cck_fa) >> 2;
543
544 level = rtw_phy_cck_pd_lv(rtwdev);
545
546 if (level >= CCK_PD_LV_MAX)
547 return;
548
549 if (chip->ops->cck_pd_set)
550 chip->ops->cck_pd_set(rtwdev, level);
551}
552
553static void rtw_phy_pwr_track(struct rtw_dev *rtwdev)
554{
555 rtwdev->chip->ops->pwr_track(rtwdev);
556}
557
558void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev)
559{
560
561 rtw_phy_statistics(rtwdev);
562 rtw_phy_dig(rtwdev);
563 rtw_phy_cck_pd(rtwdev);
564 rtw_phy_ra_info_update(rtwdev);
565 rtw_phy_dpk_track(rtwdev);
566 rtw_phy_pwr_track(rtwdev);
567}
568
569#define FRAC_BITS 3
570
571static u8 rtw_phy_power_2_db(s8 power)
572{
573 if (power <= -100 || power >= 20)
574 return 0;
575 else if (power >= 0)
576 return 100;
577 else
578 return 100 + power;
579}
580
581static u64 rtw_phy_db_2_linear(u8 power_db)
582{
583 u8 i, j;
584 u64 linear;
585
586 if (power_db > 96)
587 power_db = 96;
588 else if (power_db < 1)
589 return 1;
590
591
592 i = (power_db - 1) >> 3;
593 j = (power_db - 1) - (i << 3);
594
595 linear = db_invert_table[i][j];
596 linear = i > 2 ? linear << FRAC_BITS : linear;
597
598 return linear;
599}
600
601static u8 rtw_phy_linear_2_db(u64 linear)
602{
603 u8 i;
604 u8 j;
605 u32 dB;
606
607 if (linear >= db_invert_table[11][7])
608 return 96;
609
610 for (i = 0; i < 12; i++) {
611 if (i <= 2 && (linear << FRAC_BITS) <= db_invert_table[i][7])
612 break;
613 else if (i > 2 && linear <= db_invert_table[i][7])
614 break;
615 }
616
617 for (j = 0; j < 8; j++) {
618 if (i <= 2 && (linear << FRAC_BITS) <= db_invert_table[i][j])
619 break;
620 else if (i > 2 && linear <= db_invert_table[i][j])
621 break;
622 }
623
624 if (j == 0 && i == 0)
625 goto end;
626
627 if (j == 0) {
628 if (i != 3) {
629 if (db_invert_table[i][0] - linear >
630 linear - db_invert_table[i - 1][7]) {
631 i = i - 1;
632 j = 7;
633 }
634 } else {
635 if (db_invert_table[3][0] - linear >
636 linear - db_invert_table[2][7]) {
637 i = 2;
638 j = 7;
639 }
640 }
641 } else {
642 if (db_invert_table[i][j] - linear >
643 linear - db_invert_table[i][j - 1]) {
644 j = j - 1;
645 }
646 }
647end:
648 dB = (i << 3) + j + 1;
649
650 return dB;
651}
652
653u8 rtw_phy_rf_power_2_rssi(s8 *rf_power, u8 path_num)
654{
655 s8 power;
656 u8 power_db;
657 u64 linear;
658 u64 sum = 0;
659 u8 path;
660
661 for (path = 0; path < path_num; path++) {
662 power = rf_power[path];
663 power_db = rtw_phy_power_2_db(power);
664 linear = rtw_phy_db_2_linear(power_db);
665 sum += linear;
666 }
667
668 sum = (sum + (1 << (FRAC_BITS - 1))) >> FRAC_BITS;
669 switch (path_num) {
670 case 2:
671 sum >>= 1;
672 break;
673 case 3:
674 sum = ((sum) + ((sum) << 1) + ((sum) << 3)) >> 5;
675 break;
676 case 4:
677 sum >>= 2;
678 break;
679 default:
680 break;
681 }
682
683 return rtw_phy_linear_2_db(sum);
684}
685EXPORT_SYMBOL(rtw_phy_rf_power_2_rssi);
686
687u32 rtw_phy_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
688 u32 addr, u32 mask)
689{
690 struct rtw_hal *hal = &rtwdev->hal;
691 struct rtw_chip_info *chip = rtwdev->chip;
692 const u32 *base_addr = chip->rf_base_addr;
693 u32 val, direct_addr;
694
695 if (rf_path >= hal->rf_phy_num) {
696 rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
697 return INV_RF_DATA;
698 }
699
700 addr &= 0xff;
701 direct_addr = base_addr[rf_path] + (addr << 2);
702 mask &= RFREG_MASK;
703
704 val = rtw_read32_mask(rtwdev, direct_addr, mask);
705
706 return val;
707}
708EXPORT_SYMBOL(rtw_phy_read_rf);
709
710u32 rtw_phy_read_rf_sipi(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
711 u32 addr, u32 mask)
712{
713 struct rtw_hal *hal = &rtwdev->hal;
714 struct rtw_chip_info *chip = rtwdev->chip;
715 const struct rtw_rf_sipi_addr *rf_sipi_addr;
716 const struct rtw_rf_sipi_addr *rf_sipi_addr_a;
717 u32 val32;
718 u32 en_pi;
719 u32 r_addr;
720 u32 shift;
721
722 if (rf_path >= hal->rf_phy_num) {
723 rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
724 return INV_RF_DATA;
725 }
726
727 if (!chip->rf_sipi_read_addr) {
728 rtw_err(rtwdev, "rf_sipi_read_addr isn't defined\n");
729 return INV_RF_DATA;
730 }
731
732 rf_sipi_addr = &chip->rf_sipi_read_addr[rf_path];
733 rf_sipi_addr_a = &chip->rf_sipi_read_addr[RF_PATH_A];
734
735 addr &= 0xff;
736
737 val32 = rtw_read32(rtwdev, rf_sipi_addr->hssi_2);
738 val32 = (val32 & ~LSSI_READ_ADDR_MASK) | (addr << 23);
739 rtw_write32(rtwdev, rf_sipi_addr->hssi_2, val32);
740
741
742 val32 = rtw_read32(rtwdev, rf_sipi_addr_a->hssi_2);
743 rtw_write32(rtwdev, rf_sipi_addr_a->hssi_2, val32 & ~LSSI_READ_EDGE_MASK);
744 rtw_write32(rtwdev, rf_sipi_addr_a->hssi_2, val32 | LSSI_READ_EDGE_MASK);
745
746 udelay(120);
747
748 en_pi = rtw_read32_mask(rtwdev, rf_sipi_addr->hssi_1, BIT(8));
749 r_addr = en_pi ? rf_sipi_addr->lssi_read_pi : rf_sipi_addr->lssi_read;
750
751 val32 = rtw_read32_mask(rtwdev, r_addr, LSSI_READ_DATA_MASK);
752
753 shift = __ffs(mask);
754
755 return (val32 & mask) >> shift;
756}
757EXPORT_SYMBOL(rtw_phy_read_rf_sipi);
758
759bool rtw_phy_write_rf_reg_sipi(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
760 u32 addr, u32 mask, u32 data)
761{
762 struct rtw_hal *hal = &rtwdev->hal;
763 struct rtw_chip_info *chip = rtwdev->chip;
764 u32 *sipi_addr = chip->rf_sipi_addr;
765 u32 data_and_addr;
766 u32 old_data = 0;
767 u32 shift;
768
769 if (rf_path >= hal->rf_phy_num) {
770 rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
771 return false;
772 }
773
774 addr &= 0xff;
775 mask &= RFREG_MASK;
776
777 if (mask != RFREG_MASK) {
778 old_data = chip->ops->read_rf(rtwdev, rf_path, addr, RFREG_MASK);
779
780 if (old_data == INV_RF_DATA) {
781 rtw_err(rtwdev, "Write fail, rf is disabled\n");
782 return false;
783 }
784
785 shift = __ffs(mask);
786 data = ((old_data) & (~mask)) | (data << shift);
787 }
788
789 data_and_addr = ((addr << 20) | (data & 0x000fffff)) & 0x0fffffff;
790
791 rtw_write32(rtwdev, sipi_addr[rf_path], data_and_addr);
792
793 udelay(13);
794
795 return true;
796}
797EXPORT_SYMBOL(rtw_phy_write_rf_reg_sipi);
798
799bool rtw_phy_write_rf_reg(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
800 u32 addr, u32 mask, u32 data)
801{
802 struct rtw_hal *hal = &rtwdev->hal;
803 struct rtw_chip_info *chip = rtwdev->chip;
804 const u32 *base_addr = chip->rf_base_addr;
805 u32 direct_addr;
806
807 if (rf_path >= hal->rf_phy_num) {
808 rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path);
809 return false;
810 }
811
812 addr &= 0xff;
813 direct_addr = base_addr[rf_path] + (addr << 2);
814 mask &= RFREG_MASK;
815
816 rtw_write32_mask(rtwdev, direct_addr, mask, data);
817
818 udelay(1);
819
820 return true;
821}
822
823bool rtw_phy_write_rf_reg_mix(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
824 u32 addr, u32 mask, u32 data)
825{
826 if (addr != 0x00)
827 return rtw_phy_write_rf_reg(rtwdev, rf_path, addr, mask, data);
828
829 return rtw_phy_write_rf_reg_sipi(rtwdev, rf_path, addr, mask, data);
830}
831EXPORT_SYMBOL(rtw_phy_write_rf_reg_mix);
832
833void rtw_phy_setup_phy_cond(struct rtw_dev *rtwdev, u32 pkg)
834{
835 struct rtw_hal *hal = &rtwdev->hal;
836 struct rtw_efuse *efuse = &rtwdev->efuse;
837 struct rtw_phy_cond cond = {0};
838
839 cond.cut = hal->cut_version ? hal->cut_version : 15;
840 cond.pkg = pkg ? pkg : 15;
841 cond.plat = 0x04;
842 cond.rfe = efuse->rfe_option;
843
844 switch (rtw_hci_type(rtwdev)) {
845 case RTW_HCI_TYPE_USB:
846 cond.intf = INTF_USB;
847 break;
848 case RTW_HCI_TYPE_SDIO:
849 cond.intf = INTF_SDIO;
850 break;
851 case RTW_HCI_TYPE_PCIE:
852 default:
853 cond.intf = INTF_PCIE;
854 break;
855 }
856
857 hal->phy_cond = cond;
858
859 rtw_dbg(rtwdev, RTW_DBG_PHY, "phy cond=0x%08x\n", *((u32 *)&hal->phy_cond));
860}
861
862static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond)
863{
864 struct rtw_hal *hal = &rtwdev->hal;
865 struct rtw_phy_cond drv_cond = hal->phy_cond;
866
867 if (cond.cut && cond.cut != drv_cond.cut)
868 return false;
869
870 if (cond.pkg && cond.pkg != drv_cond.pkg)
871 return false;
872
873 if (cond.intf && cond.intf != drv_cond.intf)
874 return false;
875
876 if (cond.rfe != drv_cond.rfe)
877 return false;
878
879 return true;
880}
881
882void rtw_parse_tbl_phy_cond(struct rtw_dev *rtwdev, const struct rtw_table *tbl)
883{
884 const union phy_table_tile *p = tbl->data;
885 const union phy_table_tile *end = p + tbl->size / 2;
886 struct rtw_phy_cond pos_cond = {0};
887 bool is_matched = true, is_skipped = false;
888
889 BUILD_BUG_ON(sizeof(union phy_table_tile) != sizeof(struct phy_cfg_pair));
890
891 for (; p < end; p++) {
892 if (p->cond.pos) {
893 switch (p->cond.branch) {
894 case BRANCH_ENDIF:
895 is_matched = true;
896 is_skipped = false;
897 break;
898 case BRANCH_ELSE:
899 is_matched = is_skipped ? false : true;
900 break;
901 case BRANCH_IF:
902 case BRANCH_ELIF:
903 default:
904 pos_cond = p->cond;
905 break;
906 }
907 } else if (p->cond.neg) {
908 if (!is_skipped) {
909 if (check_positive(rtwdev, pos_cond)) {
910 is_matched = true;
911 is_skipped = true;
912 } else {
913 is_matched = false;
914 is_skipped = false;
915 }
916 } else {
917 is_matched = false;
918 }
919 } else if (is_matched) {
920 (*tbl->do_cfg)(rtwdev, tbl, p->cfg.addr, p->cfg.data);
921 }
922 }
923}
924EXPORT_SYMBOL(rtw_parse_tbl_phy_cond);
925
926#define bcd_to_dec_pwr_by_rate(val, i) bcd2bin(val >> (i * 8))
927
928static u8 tbl_to_dec_pwr_by_rate(struct rtw_dev *rtwdev, u32 hex, u8 i)
929{
930 if (rtwdev->chip->is_pwr_by_rate_dec)
931 return bcd_to_dec_pwr_by_rate(hex, i);
932
933 return (hex >> (i * 8)) & 0xFF;
934}
935
936static void
937rtw_phy_get_rate_values_of_txpwr_by_rate(struct rtw_dev *rtwdev,
938 u32 addr, u32 mask, u32 val, u8 *rate,
939 u8 *pwr_by_rate, u8 *rate_num)
940{
941 int i;
942
943 switch (addr) {
944 case 0xE00:
945 case 0x830:
946 rate[0] = DESC_RATE6M;
947 rate[1] = DESC_RATE9M;
948 rate[2] = DESC_RATE12M;
949 rate[3] = DESC_RATE18M;
950 for (i = 0; i < 4; ++i)
951 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
952 *rate_num = 4;
953 break;
954 case 0xE04:
955 case 0x834:
956 rate[0] = DESC_RATE24M;
957 rate[1] = DESC_RATE36M;
958 rate[2] = DESC_RATE48M;
959 rate[3] = DESC_RATE54M;
960 for (i = 0; i < 4; ++i)
961 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
962 *rate_num = 4;
963 break;
964 case 0xE08:
965 rate[0] = DESC_RATE1M;
966 pwr_by_rate[0] = bcd_to_dec_pwr_by_rate(val, 1);
967 *rate_num = 1;
968 break;
969 case 0x86C:
970 if (mask == 0xffffff00) {
971 rate[0] = DESC_RATE2M;
972 rate[1] = DESC_RATE5_5M;
973 rate[2] = DESC_RATE11M;
974 for (i = 1; i < 4; ++i)
975 pwr_by_rate[i - 1] =
976 tbl_to_dec_pwr_by_rate(rtwdev, val, i);
977 *rate_num = 3;
978 } else if (mask == 0x000000ff) {
979 rate[0] = DESC_RATE11M;
980 pwr_by_rate[0] = bcd_to_dec_pwr_by_rate(val, 0);
981 *rate_num = 1;
982 }
983 break;
984 case 0xE10:
985 case 0x83C:
986 rate[0] = DESC_RATEMCS0;
987 rate[1] = DESC_RATEMCS1;
988 rate[2] = DESC_RATEMCS2;
989 rate[3] = DESC_RATEMCS3;
990 for (i = 0; i < 4; ++i)
991 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
992 *rate_num = 4;
993 break;
994 case 0xE14:
995 case 0x848:
996 rate[0] = DESC_RATEMCS4;
997 rate[1] = DESC_RATEMCS5;
998 rate[2] = DESC_RATEMCS6;
999 rate[3] = DESC_RATEMCS7;
1000 for (i = 0; i < 4; ++i)
1001 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1002 *rate_num = 4;
1003 break;
1004 case 0xE18:
1005 case 0x84C:
1006 rate[0] = DESC_RATEMCS8;
1007 rate[1] = DESC_RATEMCS9;
1008 rate[2] = DESC_RATEMCS10;
1009 rate[3] = DESC_RATEMCS11;
1010 for (i = 0; i < 4; ++i)
1011 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1012 *rate_num = 4;
1013 break;
1014 case 0xE1C:
1015 case 0x868:
1016 rate[0] = DESC_RATEMCS12;
1017 rate[1] = DESC_RATEMCS13;
1018 rate[2] = DESC_RATEMCS14;
1019 rate[3] = DESC_RATEMCS15;
1020 for (i = 0; i < 4; ++i)
1021 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1022 *rate_num = 4;
1023 break;
1024 case 0x838:
1025 rate[0] = DESC_RATE1M;
1026 rate[1] = DESC_RATE2M;
1027 rate[2] = DESC_RATE5_5M;
1028 for (i = 1; i < 4; ++i)
1029 pwr_by_rate[i - 1] = tbl_to_dec_pwr_by_rate(rtwdev,
1030 val, i);
1031 *rate_num = 3;
1032 break;
1033 case 0xC20:
1034 case 0xE20:
1035 case 0x1820:
1036 case 0x1A20:
1037 rate[0] = DESC_RATE1M;
1038 rate[1] = DESC_RATE2M;
1039 rate[2] = DESC_RATE5_5M;
1040 rate[3] = DESC_RATE11M;
1041 for (i = 0; i < 4; ++i)
1042 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1043 *rate_num = 4;
1044 break;
1045 case 0xC24:
1046 case 0xE24:
1047 case 0x1824:
1048 case 0x1A24:
1049 rate[0] = DESC_RATE6M;
1050 rate[1] = DESC_RATE9M;
1051 rate[2] = DESC_RATE12M;
1052 rate[3] = DESC_RATE18M;
1053 for (i = 0; i < 4; ++i)
1054 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1055 *rate_num = 4;
1056 break;
1057 case 0xC28:
1058 case 0xE28:
1059 case 0x1828:
1060 case 0x1A28:
1061 rate[0] = DESC_RATE24M;
1062 rate[1] = DESC_RATE36M;
1063 rate[2] = DESC_RATE48M;
1064 rate[3] = DESC_RATE54M;
1065 for (i = 0; i < 4; ++i)
1066 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1067 *rate_num = 4;
1068 break;
1069 case 0xC2C:
1070 case 0xE2C:
1071 case 0x182C:
1072 case 0x1A2C:
1073 rate[0] = DESC_RATEMCS0;
1074 rate[1] = DESC_RATEMCS1;
1075 rate[2] = DESC_RATEMCS2;
1076 rate[3] = DESC_RATEMCS3;
1077 for (i = 0; i < 4; ++i)
1078 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1079 *rate_num = 4;
1080 break;
1081 case 0xC30:
1082 case 0xE30:
1083 case 0x1830:
1084 case 0x1A30:
1085 rate[0] = DESC_RATEMCS4;
1086 rate[1] = DESC_RATEMCS5;
1087 rate[2] = DESC_RATEMCS6;
1088 rate[3] = DESC_RATEMCS7;
1089 for (i = 0; i < 4; ++i)
1090 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1091 *rate_num = 4;
1092 break;
1093 case 0xC34:
1094 case 0xE34:
1095 case 0x1834:
1096 case 0x1A34:
1097 rate[0] = DESC_RATEMCS8;
1098 rate[1] = DESC_RATEMCS9;
1099 rate[2] = DESC_RATEMCS10;
1100 rate[3] = DESC_RATEMCS11;
1101 for (i = 0; i < 4; ++i)
1102 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1103 *rate_num = 4;
1104 break;
1105 case 0xC38:
1106 case 0xE38:
1107 case 0x1838:
1108 case 0x1A38:
1109 rate[0] = DESC_RATEMCS12;
1110 rate[1] = DESC_RATEMCS13;
1111 rate[2] = DESC_RATEMCS14;
1112 rate[3] = DESC_RATEMCS15;
1113 for (i = 0; i < 4; ++i)
1114 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1115 *rate_num = 4;
1116 break;
1117 case 0xC3C:
1118 case 0xE3C:
1119 case 0x183C:
1120 case 0x1A3C:
1121 rate[0] = DESC_RATEVHT1SS_MCS0;
1122 rate[1] = DESC_RATEVHT1SS_MCS1;
1123 rate[2] = DESC_RATEVHT1SS_MCS2;
1124 rate[3] = DESC_RATEVHT1SS_MCS3;
1125 for (i = 0; i < 4; ++i)
1126 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1127 *rate_num = 4;
1128 break;
1129 case 0xC40:
1130 case 0xE40:
1131 case 0x1840:
1132 case 0x1A40:
1133 rate[0] = DESC_RATEVHT1SS_MCS4;
1134 rate[1] = DESC_RATEVHT1SS_MCS5;
1135 rate[2] = DESC_RATEVHT1SS_MCS6;
1136 rate[3] = DESC_RATEVHT1SS_MCS7;
1137 for (i = 0; i < 4; ++i)
1138 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1139 *rate_num = 4;
1140 break;
1141 case 0xC44:
1142 case 0xE44:
1143 case 0x1844:
1144 case 0x1A44:
1145 rate[0] = DESC_RATEVHT1SS_MCS8;
1146 rate[1] = DESC_RATEVHT1SS_MCS9;
1147 rate[2] = DESC_RATEVHT2SS_MCS0;
1148 rate[3] = DESC_RATEVHT2SS_MCS1;
1149 for (i = 0; i < 4; ++i)
1150 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1151 *rate_num = 4;
1152 break;
1153 case 0xC48:
1154 case 0xE48:
1155 case 0x1848:
1156 case 0x1A48:
1157 rate[0] = DESC_RATEVHT2SS_MCS2;
1158 rate[1] = DESC_RATEVHT2SS_MCS3;
1159 rate[2] = DESC_RATEVHT2SS_MCS4;
1160 rate[3] = DESC_RATEVHT2SS_MCS5;
1161 for (i = 0; i < 4; ++i)
1162 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1163 *rate_num = 4;
1164 break;
1165 case 0xC4C:
1166 case 0xE4C:
1167 case 0x184C:
1168 case 0x1A4C:
1169 rate[0] = DESC_RATEVHT2SS_MCS6;
1170 rate[1] = DESC_RATEVHT2SS_MCS7;
1171 rate[2] = DESC_RATEVHT2SS_MCS8;
1172 rate[3] = DESC_RATEVHT2SS_MCS9;
1173 for (i = 0; i < 4; ++i)
1174 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1175 *rate_num = 4;
1176 break;
1177 case 0xCD8:
1178 case 0xED8:
1179 case 0x18D8:
1180 case 0x1AD8:
1181 rate[0] = DESC_RATEMCS16;
1182 rate[1] = DESC_RATEMCS17;
1183 rate[2] = DESC_RATEMCS18;
1184 rate[3] = DESC_RATEMCS19;
1185 for (i = 0; i < 4; ++i)
1186 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1187 *rate_num = 4;
1188 break;
1189 case 0xCDC:
1190 case 0xEDC:
1191 case 0x18DC:
1192 case 0x1ADC:
1193 rate[0] = DESC_RATEMCS20;
1194 rate[1] = DESC_RATEMCS21;
1195 rate[2] = DESC_RATEMCS22;
1196 rate[3] = DESC_RATEMCS23;
1197 for (i = 0; i < 4; ++i)
1198 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1199 *rate_num = 4;
1200 break;
1201 case 0xCE0:
1202 case 0xEE0:
1203 case 0x18E0:
1204 case 0x1AE0:
1205 rate[0] = DESC_RATEVHT3SS_MCS0;
1206 rate[1] = DESC_RATEVHT3SS_MCS1;
1207 rate[2] = DESC_RATEVHT3SS_MCS2;
1208 rate[3] = DESC_RATEVHT3SS_MCS3;
1209 for (i = 0; i < 4; ++i)
1210 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1211 *rate_num = 4;
1212 break;
1213 case 0xCE4:
1214 case 0xEE4:
1215 case 0x18E4:
1216 case 0x1AE4:
1217 rate[0] = DESC_RATEVHT3SS_MCS4;
1218 rate[1] = DESC_RATEVHT3SS_MCS5;
1219 rate[2] = DESC_RATEVHT3SS_MCS6;
1220 rate[3] = DESC_RATEVHT3SS_MCS7;
1221 for (i = 0; i < 4; ++i)
1222 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1223 *rate_num = 4;
1224 break;
1225 case 0xCE8:
1226 case 0xEE8:
1227 case 0x18E8:
1228 case 0x1AE8:
1229 rate[0] = DESC_RATEVHT3SS_MCS8;
1230 rate[1] = DESC_RATEVHT3SS_MCS9;
1231 for (i = 0; i < 2; ++i)
1232 pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i);
1233 *rate_num = 2;
1234 break;
1235 default:
1236 rtw_warn(rtwdev, "invalid tx power index addr 0x%08x\n", addr);
1237 break;
1238 }
1239}
1240
1241static void rtw_phy_store_tx_power_by_rate(struct rtw_dev *rtwdev,
1242 u32 band, u32 rfpath, u32 txnum,
1243 u32 regaddr, u32 bitmask, u32 data)
1244{
1245 struct rtw_hal *hal = &rtwdev->hal;
1246 u8 rate_num = 0;
1247 u8 rate;
1248 u8 rates[RTW_RF_PATH_MAX] = {0};
1249 s8 offset;
1250 s8 pwr_by_rate[RTW_RF_PATH_MAX] = {0};
1251 int i;
1252
1253 rtw_phy_get_rate_values_of_txpwr_by_rate(rtwdev, regaddr, bitmask, data,
1254 rates, pwr_by_rate, &rate_num);
1255
1256 if (WARN_ON(rfpath >= RTW_RF_PATH_MAX ||
1257 (band != PHY_BAND_2G && band != PHY_BAND_5G) ||
1258 rate_num > RTW_RF_PATH_MAX))
1259 return;
1260
1261 for (i = 0; i < rate_num; i++) {
1262 offset = pwr_by_rate[i];
1263 rate = rates[i];
1264 if (band == PHY_BAND_2G)
1265 hal->tx_pwr_by_rate_offset_2g[rfpath][rate] = offset;
1266 else if (band == PHY_BAND_5G)
1267 hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset;
1268 else
1269 continue;
1270 }
1271}
1272
1273void rtw_parse_tbl_bb_pg(struct rtw_dev *rtwdev, const struct rtw_table *tbl)
1274{
1275 const struct rtw_phy_pg_cfg_pair *p = tbl->data;
1276 const struct rtw_phy_pg_cfg_pair *end = p + tbl->size;
1277
1278 for (; p < end; p++) {
1279 if (p->addr == 0xfe || p->addr == 0xffe) {
1280 msleep(50);
1281 continue;
1282 }
1283 rtw_phy_store_tx_power_by_rate(rtwdev, p->band, p->rf_path,
1284 p->tx_num, p->addr, p->bitmask,
1285 p->data);
1286 }
1287}
1288EXPORT_SYMBOL(rtw_parse_tbl_bb_pg);
1289
1290static const u8 rtw_channel_idx_5g[RTW_MAX_CHANNEL_NUM_5G] = {
1291 36, 38, 40, 42, 44, 46, 48,
1292 52, 54, 56, 58, 60, 62, 64,
1293 100, 102, 104, 106, 108, 110, 112,
1294 116, 118, 120, 122, 124, 126, 128,
1295 132, 134, 136, 138, 140, 142, 144,
1296 149, 151, 153, 155, 157, 159, 161,
1297 165, 167, 169, 171, 173, 175, 177};
1298
1299static int rtw_channel_to_idx(u8 band, u8 channel)
1300{
1301 int ch_idx;
1302 u8 n_channel;
1303
1304 if (band == PHY_BAND_2G) {
1305 ch_idx = channel - 1;
1306 n_channel = RTW_MAX_CHANNEL_NUM_2G;
1307 } else if (band == PHY_BAND_5G) {
1308 n_channel = RTW_MAX_CHANNEL_NUM_5G;
1309 for (ch_idx = 0; ch_idx < n_channel; ch_idx++)
1310 if (rtw_channel_idx_5g[ch_idx] == channel)
1311 break;
1312 } else {
1313 return -1;
1314 }
1315
1316 if (ch_idx >= n_channel)
1317 return -1;
1318
1319 return ch_idx;
1320}
1321
1322static void rtw_phy_set_tx_power_limit(struct rtw_dev *rtwdev, u8 regd, u8 band,
1323 u8 bw, u8 rs, u8 ch, s8 pwr_limit)
1324{
1325 struct rtw_hal *hal = &rtwdev->hal;
1326 u8 max_power_index = rtwdev->chip->max_power_index;
1327 s8 ww;
1328 int ch_idx;
1329
1330 pwr_limit = clamp_t(s8, pwr_limit,
1331 -max_power_index, max_power_index);
1332 ch_idx = rtw_channel_to_idx(band, ch);
1333
1334 if (regd >= RTW_REGD_MAX || bw >= RTW_CHANNEL_WIDTH_MAX ||
1335 rs >= RTW_RATE_SECTION_MAX || ch_idx < 0) {
1336 WARN(1,
1337 "wrong txpwr_lmt regd=%u, band=%u bw=%u, rs=%u, ch_idx=%u, pwr_limit=%d\n",
1338 regd, band, bw, rs, ch_idx, pwr_limit);
1339 return;
1340 }
1341
1342 if (band == PHY_BAND_2G) {
1343 hal->tx_pwr_limit_2g[regd][bw][rs][ch_idx] = pwr_limit;
1344 ww = hal->tx_pwr_limit_2g[RTW_REGD_WW][bw][rs][ch_idx];
1345 ww = min_t(s8, ww, pwr_limit);
1346 hal->tx_pwr_limit_2g[RTW_REGD_WW][bw][rs][ch_idx] = ww;
1347 } else if (band == PHY_BAND_5G) {
1348 hal->tx_pwr_limit_5g[regd][bw][rs][ch_idx] = pwr_limit;
1349 ww = hal->tx_pwr_limit_5g[RTW_REGD_WW][bw][rs][ch_idx];
1350 ww = min_t(s8, ww, pwr_limit);
1351 hal->tx_pwr_limit_5g[RTW_REGD_WW][bw][rs][ch_idx] = ww;
1352 }
1353}
1354
1355
1356static void
1357rtw_xref_5g_txpwr_lmt(struct rtw_dev *rtwdev, u8 regd,
1358 u8 bw, u8 ch_idx, u8 rs_ht, u8 rs_vht)
1359{
1360 struct rtw_hal *hal = &rtwdev->hal;
1361 u8 max_power_index = rtwdev->chip->max_power_index;
1362 s8 lmt_ht = hal->tx_pwr_limit_5g[regd][bw][rs_ht][ch_idx];
1363 s8 lmt_vht = hal->tx_pwr_limit_5g[regd][bw][rs_vht][ch_idx];
1364
1365 if (lmt_ht == lmt_vht)
1366 return;
1367
1368 if (lmt_ht == max_power_index)
1369 hal->tx_pwr_limit_5g[regd][bw][rs_ht][ch_idx] = lmt_vht;
1370
1371 else if (lmt_vht == max_power_index)
1372 hal->tx_pwr_limit_5g[regd][bw][rs_vht][ch_idx] = lmt_ht;
1373}
1374
1375
1376static void
1377rtw_xref_txpwr_lmt_by_rs(struct rtw_dev *rtwdev, u8 regd, u8 bw, u8 ch_idx)
1378{
1379 u8 rs_idx, rs_ht, rs_vht;
1380 u8 rs_cmp[2][2] = {{RTW_RATE_SECTION_HT_1S, RTW_RATE_SECTION_VHT_1S},
1381 {RTW_RATE_SECTION_HT_2S, RTW_RATE_SECTION_VHT_2S} };
1382
1383 for (rs_idx = 0; rs_idx < 2; rs_idx++) {
1384 rs_ht = rs_cmp[rs_idx][0];
1385 rs_vht = rs_cmp[rs_idx][1];
1386
1387 rtw_xref_5g_txpwr_lmt(rtwdev, regd, bw, ch_idx, rs_ht, rs_vht);
1388 }
1389}
1390
1391
1392static void
1393rtw_xref_5g_txpwr_lmt_by_ch(struct rtw_dev *rtwdev, u8 regd, u8 bw)
1394{
1395 u8 ch_idx;
1396
1397 for (ch_idx = 0; ch_idx < RTW_MAX_CHANNEL_NUM_5G; ch_idx++)
1398 rtw_xref_txpwr_lmt_by_rs(rtwdev, regd, bw, ch_idx);
1399}
1400
1401
1402static void
1403rtw_xref_txpwr_lmt_by_bw(struct rtw_dev *rtwdev, u8 regd)
1404{
1405 u8 bw;
1406
1407 for (bw = RTW_CHANNEL_WIDTH_20; bw <= RTW_CHANNEL_WIDTH_40; bw++)
1408 rtw_xref_5g_txpwr_lmt_by_ch(rtwdev, regd, bw);
1409}
1410
1411
1412static void rtw_xref_txpwr_lmt(struct rtw_dev *rtwdev)
1413{
1414 u8 regd;
1415
1416 for (regd = 0; regd < RTW_REGD_MAX; regd++)
1417 rtw_xref_txpwr_lmt_by_bw(rtwdev, regd);
1418}
1419
1420void rtw_parse_tbl_txpwr_lmt(struct rtw_dev *rtwdev,
1421 const struct rtw_table *tbl)
1422{
1423 const struct rtw_txpwr_lmt_cfg_pair *p = tbl->data;
1424 const struct rtw_txpwr_lmt_cfg_pair *end = p + tbl->size;
1425
1426 for (; p < end; p++) {
1427 rtw_phy_set_tx_power_limit(rtwdev, p->regd, p->band,
1428 p->bw, p->rs, p->ch, p->txpwr_lmt);
1429 }
1430
1431 rtw_xref_txpwr_lmt(rtwdev);
1432}
1433EXPORT_SYMBOL(rtw_parse_tbl_txpwr_lmt);
1434
1435void rtw_phy_cfg_mac(struct rtw_dev *rtwdev, const struct rtw_table *tbl,
1436 u32 addr, u32 data)
1437{
1438 rtw_write8(rtwdev, addr, data);
1439}
1440EXPORT_SYMBOL(rtw_phy_cfg_mac);
1441
1442void rtw_phy_cfg_agc(struct rtw_dev *rtwdev, const struct rtw_table *tbl,
1443 u32 addr, u32 data)
1444{
1445 rtw_write32(rtwdev, addr, data);
1446}
1447EXPORT_SYMBOL(rtw_phy_cfg_agc);
1448
1449void rtw_phy_cfg_bb(struct rtw_dev *rtwdev, const struct rtw_table *tbl,
1450 u32 addr, u32 data)
1451{
1452 if (addr == 0xfe)
1453 msleep(50);
1454 else if (addr == 0xfd)
1455 mdelay(5);
1456 else if (addr == 0xfc)
1457 mdelay(1);
1458 else if (addr == 0xfb)
1459 usleep_range(50, 60);
1460 else if (addr == 0xfa)
1461 udelay(5);
1462 else if (addr == 0xf9)
1463 udelay(1);
1464 else
1465 rtw_write32(rtwdev, addr, data);
1466}
1467EXPORT_SYMBOL(rtw_phy_cfg_bb);
1468
1469void rtw_phy_cfg_rf(struct rtw_dev *rtwdev, const struct rtw_table *tbl,
1470 u32 addr, u32 data)
1471{
1472 if (addr == 0xffe) {
1473 msleep(50);
1474 } else if (addr == 0xfe) {
1475 usleep_range(100, 110);
1476 } else {
1477 rtw_write_rf(rtwdev, tbl->rf_path, addr, RFREG_MASK, data);
1478 udelay(1);
1479 }
1480}
1481EXPORT_SYMBOL(rtw_phy_cfg_rf);
1482
1483static void rtw_load_rfk_table(struct rtw_dev *rtwdev)
1484{
1485 struct rtw_chip_info *chip = rtwdev->chip;
1486 struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info;
1487
1488 if (!chip->rfk_init_tbl)
1489 return;
1490
1491 rtw_write32_mask(rtwdev, 0x1e24, BIT(17), 0x1);
1492 rtw_write32_mask(rtwdev, 0x1cd0, BIT(28), 0x1);
1493 rtw_write32_mask(rtwdev, 0x1cd0, BIT(29), 0x1);
1494 rtw_write32_mask(rtwdev, 0x1cd0, BIT(30), 0x1);
1495 rtw_write32_mask(rtwdev, 0x1cd0, BIT(31), 0x0);
1496
1497 rtw_load_table(rtwdev, chip->rfk_init_tbl);
1498
1499 dpk_info->is_dpk_pwr_on = true;
1500}
1501
1502void rtw_phy_load_tables(struct rtw_dev *rtwdev)
1503{
1504 struct rtw_chip_info *chip = rtwdev->chip;
1505 u8 rf_path;
1506
1507 rtw_load_table(rtwdev, chip->mac_tbl);
1508 rtw_load_table(rtwdev, chip->bb_tbl);
1509 rtw_load_table(rtwdev, chip->agc_tbl);
1510 rtw_load_rfk_table(rtwdev);
1511
1512 for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++) {
1513 const struct rtw_table *tbl;
1514
1515 tbl = chip->rf_tbl[rf_path];
1516 rtw_load_table(rtwdev, tbl);
1517 }
1518}
1519EXPORT_SYMBOL(rtw_phy_load_tables);
1520
1521static u8 rtw_get_channel_group(u8 channel)
1522{
1523 switch (channel) {
1524 default:
1525 WARN_ON(1);
1526 fallthrough;
1527 case 1:
1528 case 2:
1529 case 36:
1530 case 38:
1531 case 40:
1532 case 42:
1533 return 0;
1534 case 3:
1535 case 4:
1536 case 5:
1537 case 44:
1538 case 46:
1539 case 48:
1540 case 50:
1541 return 1;
1542 case 6:
1543 case 7:
1544 case 8:
1545 case 52:
1546 case 54:
1547 case 56:
1548 case 58:
1549 return 2;
1550 case 9:
1551 case 10:
1552 case 11:
1553 case 60:
1554 case 62:
1555 case 64:
1556 return 3;
1557 case 12:
1558 case 13:
1559 case 100:
1560 case 102:
1561 case 104:
1562 case 106:
1563 return 4;
1564 case 14:
1565 case 108:
1566 case 110:
1567 case 112:
1568 case 114:
1569 return 5;
1570 case 116:
1571 case 118:
1572 case 120:
1573 case 122:
1574 return 6;
1575 case 124:
1576 case 126:
1577 case 128:
1578 case 130:
1579 return 7;
1580 case 132:
1581 case 134:
1582 case 136:
1583 case 138:
1584 return 8;
1585 case 140:
1586 case 142:
1587 case 144:
1588 return 9;
1589 case 149:
1590 case 151:
1591 case 153:
1592 case 155:
1593 return 10;
1594 case 157:
1595 case 159:
1596 case 161:
1597 return 11;
1598 case 165:
1599 case 167:
1600 case 169:
1601 case 171:
1602 return 12;
1603 case 173:
1604 case 175:
1605 case 177:
1606 return 13;
1607 }
1608}
1609
1610static s8 rtw_phy_get_dis_dpd_by_rate_diff(struct rtw_dev *rtwdev, u16 rate)
1611{
1612 struct rtw_chip_info *chip = rtwdev->chip;
1613 s8 dpd_diff = 0;
1614
1615 if (!chip->en_dis_dpd)
1616 return 0;
1617
1618#define RTW_DPD_RATE_CHECK(_rate) \
1619 case DESC_RATE ## _rate: \
1620 if (DIS_DPD_RATE ## _rate & chip->dpd_ratemask) \
1621 dpd_diff = -6 * chip->txgi_factor; \
1622 break
1623
1624 switch (rate) {
1625 RTW_DPD_RATE_CHECK(6M);
1626 RTW_DPD_RATE_CHECK(9M);
1627 RTW_DPD_RATE_CHECK(MCS0);
1628 RTW_DPD_RATE_CHECK(MCS1);
1629 RTW_DPD_RATE_CHECK(MCS8);
1630 RTW_DPD_RATE_CHECK(MCS9);
1631 RTW_DPD_RATE_CHECK(VHT1SS_MCS0);
1632 RTW_DPD_RATE_CHECK(VHT1SS_MCS1);
1633 RTW_DPD_RATE_CHECK(VHT2SS_MCS0);
1634 RTW_DPD_RATE_CHECK(VHT2SS_MCS1);
1635 }
1636#undef RTW_DPD_RATE_CHECK
1637
1638 return dpd_diff;
1639}
1640
1641static u8 rtw_phy_get_2g_tx_power_index(struct rtw_dev *rtwdev,
1642 struct rtw_2g_txpwr_idx *pwr_idx_2g,
1643 enum rtw_bandwidth bandwidth,
1644 u8 rate, u8 group)
1645{
1646 struct rtw_chip_info *chip = rtwdev->chip;
1647 u8 tx_power;
1648 bool mcs_rate;
1649 bool above_2ss;
1650 u8 factor = chip->txgi_factor;
1651
1652 if (rate <= DESC_RATE11M)
1653 tx_power = pwr_idx_2g->cck_base[group];
1654 else
1655 tx_power = pwr_idx_2g->bw40_base[group];
1656
1657 if (rate >= DESC_RATE6M && rate <= DESC_RATE54M)
1658 tx_power += pwr_idx_2g->ht_1s_diff.ofdm * factor;
1659
1660 mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1661 (rate >= DESC_RATEVHT1SS_MCS0 &&
1662 rate <= DESC_RATEVHT2SS_MCS9);
1663 above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1664 (rate >= DESC_RATEVHT2SS_MCS0);
1665
1666 if (!mcs_rate)
1667 return tx_power;
1668
1669 switch (bandwidth) {
1670 default:
1671 WARN_ON(1);
1672 fallthrough;
1673 case RTW_CHANNEL_WIDTH_20:
1674 tx_power += pwr_idx_2g->ht_1s_diff.bw20 * factor;
1675 if (above_2ss)
1676 tx_power += pwr_idx_2g->ht_2s_diff.bw20 * factor;
1677 break;
1678 case RTW_CHANNEL_WIDTH_40:
1679
1680 if (above_2ss)
1681 tx_power += pwr_idx_2g->ht_2s_diff.bw40 * factor;
1682 break;
1683 }
1684
1685 return tx_power;
1686}
1687
1688static u8 rtw_phy_get_5g_tx_power_index(struct rtw_dev *rtwdev,
1689 struct rtw_5g_txpwr_idx *pwr_idx_5g,
1690 enum rtw_bandwidth bandwidth,
1691 u8 rate, u8 group)
1692{
1693 struct rtw_chip_info *chip = rtwdev->chip;
1694 u8 tx_power;
1695 u8 upper, lower;
1696 bool mcs_rate;
1697 bool above_2ss;
1698 u8 factor = chip->txgi_factor;
1699
1700 tx_power = pwr_idx_5g->bw40_base[group];
1701
1702 mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1703 (rate >= DESC_RATEVHT1SS_MCS0 &&
1704 rate <= DESC_RATEVHT2SS_MCS9);
1705 above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1706 (rate >= DESC_RATEVHT2SS_MCS0);
1707
1708 if (!mcs_rate) {
1709 tx_power += pwr_idx_5g->ht_1s_diff.ofdm * factor;
1710 return tx_power;
1711 }
1712
1713 switch (bandwidth) {
1714 default:
1715 WARN_ON(1);
1716 fallthrough;
1717 case RTW_CHANNEL_WIDTH_20:
1718 tx_power += pwr_idx_5g->ht_1s_diff.bw20 * factor;
1719 if (above_2ss)
1720 tx_power += pwr_idx_5g->ht_2s_diff.bw20 * factor;
1721 break;
1722 case RTW_CHANNEL_WIDTH_40:
1723
1724 if (above_2ss)
1725 tx_power += pwr_idx_5g->ht_2s_diff.bw40 * factor;
1726 break;
1727 case RTW_CHANNEL_WIDTH_80:
1728
1729 lower = pwr_idx_5g->bw40_base[group];
1730 upper = pwr_idx_5g->bw40_base[group + 1];
1731
1732 tx_power = (lower + upper) / 2;
1733 tx_power += pwr_idx_5g->vht_1s_diff.bw80 * factor;
1734 if (above_2ss)
1735 tx_power += pwr_idx_5g->vht_2s_diff.bw80 * factor;
1736 break;
1737 }
1738
1739 return tx_power;
1740}
1741
1742static s8 rtw_phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band,
1743 enum rtw_bandwidth bw, u8 rf_path,
1744 u8 rate, u8 channel, u8 regd)
1745{
1746 struct rtw_hal *hal = &rtwdev->hal;
1747 u8 *cch_by_bw = hal->cch_by_bw;
1748 s8 power_limit = (s8)rtwdev->chip->max_power_index;
1749 u8 rs;
1750 int ch_idx;
1751 u8 cur_bw, cur_ch;
1752 s8 cur_lmt;
1753
1754 if (regd > RTW_REGD_WW)
1755 return power_limit;
1756
1757 if (rate >= DESC_RATE1M && rate <= DESC_RATE11M)
1758 rs = RTW_RATE_SECTION_CCK;
1759 else if (rate >= DESC_RATE6M && rate <= DESC_RATE54M)
1760 rs = RTW_RATE_SECTION_OFDM;
1761 else if (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS7)
1762 rs = RTW_RATE_SECTION_HT_1S;
1763 else if (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15)
1764 rs = RTW_RATE_SECTION_HT_2S;
1765 else if (rate >= DESC_RATEVHT1SS_MCS0 && rate <= DESC_RATEVHT1SS_MCS9)
1766 rs = RTW_RATE_SECTION_VHT_1S;
1767 else if (rate >= DESC_RATEVHT2SS_MCS0 && rate <= DESC_RATEVHT2SS_MCS9)
1768 rs = RTW_RATE_SECTION_VHT_2S;
1769 else
1770 goto err;
1771
1772
1773 if (rs == RTW_RATE_SECTION_CCK || rs == RTW_RATE_SECTION_OFDM)
1774 bw = RTW_CHANNEL_WIDTH_20;
1775
1776
1777 if (rs == RTW_RATE_SECTION_HT_1S || rs == RTW_RATE_SECTION_HT_2S)
1778 bw = min_t(u8, bw, RTW_CHANNEL_WIDTH_40);
1779
1780
1781 for (cur_bw = RTW_CHANNEL_WIDTH_20; cur_bw <= bw; cur_bw++) {
1782 cur_ch = cch_by_bw[cur_bw];
1783
1784 ch_idx = rtw_channel_to_idx(band, cur_ch);
1785 if (ch_idx < 0)
1786 goto err;
1787
1788 cur_lmt = cur_ch <= RTW_MAX_CHANNEL_NUM_2G ?
1789 hal->tx_pwr_limit_2g[regd][cur_bw][rs][ch_idx] :
1790 hal->tx_pwr_limit_5g[regd][cur_bw][rs][ch_idx];
1791
1792 power_limit = min_t(s8, cur_lmt, power_limit);
1793 }
1794
1795 return power_limit;
1796
1797err:
1798 WARN(1, "invalid arguments, band=%d, bw=%d, path=%d, rate=%d, ch=%d\n",
1799 band, bw, rf_path, rate, channel);
1800 return (s8)rtwdev->chip->max_power_index;
1801}
1802
1803void rtw_get_tx_power_params(struct rtw_dev *rtwdev, u8 path, u8 rate, u8 bw,
1804 u8 ch, u8 regd, struct rtw_power_params *pwr_param)
1805{
1806 struct rtw_hal *hal = &rtwdev->hal;
1807 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
1808 struct rtw_txpwr_idx *pwr_idx;
1809 u8 group, band;
1810 u8 *base = &pwr_param->pwr_base;
1811 s8 *offset = &pwr_param->pwr_offset;
1812 s8 *limit = &pwr_param->pwr_limit;
1813 s8 *remnant = &pwr_param->pwr_remnant;
1814
1815 pwr_idx = &rtwdev->efuse.txpwr_idx_table[path];
1816 group = rtw_get_channel_group(ch);
1817
1818
1819 if (IS_CH_2G_BAND(ch)) {
1820 band = PHY_BAND_2G;
1821 *base = rtw_phy_get_2g_tx_power_index(rtwdev,
1822 &pwr_idx->pwr_idx_2g,
1823 bw, rate, group);
1824 *offset = hal->tx_pwr_by_rate_offset_2g[path][rate];
1825 } else {
1826 band = PHY_BAND_5G;
1827 *base = rtw_phy_get_5g_tx_power_index(rtwdev,
1828 &pwr_idx->pwr_idx_5g,
1829 bw, rate, group);
1830 *offset = hal->tx_pwr_by_rate_offset_5g[path][rate];
1831 }
1832
1833 *limit = rtw_phy_get_tx_power_limit(rtwdev, band, bw, path,
1834 rate, ch, regd);
1835 *remnant = (rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck :
1836 dm_info->txagc_remnant_ofdm);
1837}
1838
1839u8
1840rtw_phy_get_tx_power_index(struct rtw_dev *rtwdev, u8 rf_path, u8 rate,
1841 enum rtw_bandwidth bandwidth, u8 channel, u8 regd)
1842{
1843 struct rtw_power_params pwr_param = {0};
1844 u8 tx_power;
1845 s8 offset;
1846
1847 rtw_get_tx_power_params(rtwdev, rf_path, rate, bandwidth,
1848 channel, regd, &pwr_param);
1849
1850 tx_power = pwr_param.pwr_base;
1851 offset = min_t(s8, pwr_param.pwr_offset, pwr_param.pwr_limit);
1852
1853 if (rtwdev->chip->en_dis_dpd)
1854 offset += rtw_phy_get_dis_dpd_by_rate_diff(rtwdev, rate);
1855
1856 tx_power += offset + pwr_param.pwr_remnant;
1857
1858 if (tx_power > rtwdev->chip->max_power_index)
1859 tx_power = rtwdev->chip->max_power_index;
1860
1861 return tx_power;
1862}
1863EXPORT_SYMBOL(rtw_phy_get_tx_power_index);
1864
1865static void rtw_phy_set_tx_power_index_by_rs(struct rtw_dev *rtwdev,
1866 u8 ch, u8 path, u8 rs)
1867{
1868 struct rtw_hal *hal = &rtwdev->hal;
1869 u8 regd = rtwdev->regd.txpwr_regd;
1870 u8 *rates;
1871 u8 size;
1872 u8 rate;
1873 u8 pwr_idx;
1874 u8 bw;
1875 int i;
1876
1877 if (rs >= RTW_RATE_SECTION_MAX)
1878 return;
1879
1880 rates = rtw_rate_section[rs];
1881 size = rtw_rate_size[rs];
1882 bw = hal->current_band_width;
1883 for (i = 0; i < size; i++) {
1884 rate = rates[i];
1885 pwr_idx = rtw_phy_get_tx_power_index(rtwdev, path, rate,
1886 bw, ch, regd);
1887 hal->tx_pwr_tbl[path][rate] = pwr_idx;
1888 }
1889}
1890
1891
1892
1893
1894
1895
1896static void rtw_phy_set_tx_power_level_by_path(struct rtw_dev *rtwdev,
1897 u8 ch, u8 path)
1898{
1899 struct rtw_hal *hal = &rtwdev->hal;
1900 u8 rs;
1901
1902
1903 if (hal->current_band_type == RTW_BAND_2G)
1904 rs = RTW_RATE_SECTION_CCK;
1905 else
1906 rs = RTW_RATE_SECTION_OFDM;
1907
1908 for (; rs < RTW_RATE_SECTION_MAX; rs++)
1909 rtw_phy_set_tx_power_index_by_rs(rtwdev, ch, path, rs);
1910}
1911
1912void rtw_phy_set_tx_power_level(struct rtw_dev *rtwdev, u8 channel)
1913{
1914 struct rtw_chip_info *chip = rtwdev->chip;
1915 struct rtw_hal *hal = &rtwdev->hal;
1916 u8 path;
1917
1918 mutex_lock(&hal->tx_power_mutex);
1919
1920 for (path = 0; path < hal->rf_path_num; path++)
1921 rtw_phy_set_tx_power_level_by_path(rtwdev, channel, path);
1922
1923 chip->ops->set_tx_power_index(rtwdev);
1924 mutex_unlock(&hal->tx_power_mutex);
1925}
1926EXPORT_SYMBOL(rtw_phy_set_tx_power_level);
1927
1928static void
1929rtw_phy_tx_power_by_rate_config_by_path(struct rtw_hal *hal, u8 path,
1930 u8 rs, u8 size, u8 *rates)
1931{
1932 u8 rate;
1933 u8 base_idx, rate_idx;
1934 s8 base_2g, base_5g;
1935
1936 if (rs >= RTW_RATE_SECTION_VHT_1S)
1937 base_idx = rates[size - 3];
1938 else
1939 base_idx = rates[size - 1];
1940 base_2g = hal->tx_pwr_by_rate_offset_2g[path][base_idx];
1941 base_5g = hal->tx_pwr_by_rate_offset_5g[path][base_idx];
1942 hal->tx_pwr_by_rate_base_2g[path][rs] = base_2g;
1943 hal->tx_pwr_by_rate_base_5g[path][rs] = base_5g;
1944 for (rate = 0; rate < size; rate++) {
1945 rate_idx = rates[rate];
1946 hal->tx_pwr_by_rate_offset_2g[path][rate_idx] -= base_2g;
1947 hal->tx_pwr_by_rate_offset_5g[path][rate_idx] -= base_5g;
1948 }
1949}
1950
1951void rtw_phy_tx_power_by_rate_config(struct rtw_hal *hal)
1952{
1953 u8 path;
1954
1955 for (path = 0; path < RTW_RF_PATH_MAX; path++) {
1956 rtw_phy_tx_power_by_rate_config_by_path(hal, path,
1957 RTW_RATE_SECTION_CCK,
1958 rtw_cck_size, rtw_cck_rates);
1959 rtw_phy_tx_power_by_rate_config_by_path(hal, path,
1960 RTW_RATE_SECTION_OFDM,
1961 rtw_ofdm_size, rtw_ofdm_rates);
1962 rtw_phy_tx_power_by_rate_config_by_path(hal, path,
1963 RTW_RATE_SECTION_HT_1S,
1964 rtw_ht_1s_size, rtw_ht_1s_rates);
1965 rtw_phy_tx_power_by_rate_config_by_path(hal, path,
1966 RTW_RATE_SECTION_HT_2S,
1967 rtw_ht_2s_size, rtw_ht_2s_rates);
1968 rtw_phy_tx_power_by_rate_config_by_path(hal, path,
1969 RTW_RATE_SECTION_VHT_1S,
1970 rtw_vht_1s_size, rtw_vht_1s_rates);
1971 rtw_phy_tx_power_by_rate_config_by_path(hal, path,
1972 RTW_RATE_SECTION_VHT_2S,
1973 rtw_vht_2s_size, rtw_vht_2s_rates);
1974 }
1975}
1976
1977static void
1978__rtw_phy_tx_power_limit_config(struct rtw_hal *hal, u8 regd, u8 bw, u8 rs)
1979{
1980 s8 base;
1981 u8 ch;
1982
1983 for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_2G; ch++) {
1984 base = hal->tx_pwr_by_rate_base_2g[0][rs];
1985 hal->tx_pwr_limit_2g[regd][bw][rs][ch] -= base;
1986 }
1987
1988 for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_5G; ch++) {
1989 base = hal->tx_pwr_by_rate_base_5g[0][rs];
1990 hal->tx_pwr_limit_5g[regd][bw][rs][ch] -= base;
1991 }
1992}
1993
1994void rtw_phy_tx_power_limit_config(struct rtw_hal *hal)
1995{
1996 u8 regd, bw, rs;
1997
1998
1999 hal->cch_by_bw[RTW_CHANNEL_WIDTH_20] = 1;
2000
2001 for (regd = 0; regd < RTW_REGD_MAX; regd++)
2002 for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++)
2003 for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++)
2004 __rtw_phy_tx_power_limit_config(hal, regd, bw, rs);
2005}
2006
2007static void rtw_phy_init_tx_power_limit(struct rtw_dev *rtwdev,
2008 u8 regd, u8 bw, u8 rs)
2009{
2010 struct rtw_hal *hal = &rtwdev->hal;
2011 s8 max_power_index = (s8)rtwdev->chip->max_power_index;
2012 u8 ch;
2013
2014
2015 for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_2G; ch++)
2016 hal->tx_pwr_limit_2g[regd][bw][rs][ch] = max_power_index;
2017
2018
2019 for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_5G; ch++)
2020 hal->tx_pwr_limit_5g[regd][bw][rs][ch] = max_power_index;
2021}
2022
2023void rtw_phy_init_tx_power(struct rtw_dev *rtwdev)
2024{
2025 struct rtw_hal *hal = &rtwdev->hal;
2026 u8 regd, path, rate, rs, bw;
2027
2028
2029 for (path = 0; path < RTW_RF_PATH_MAX; path++) {
2030 for (rate = 0; rate < DESC_RATE_MAX; rate++) {
2031 hal->tx_pwr_by_rate_offset_2g[path][rate] = 0;
2032 hal->tx_pwr_by_rate_offset_5g[path][rate] = 0;
2033 }
2034 }
2035
2036
2037 for (regd = 0; regd < RTW_REGD_MAX; regd++)
2038 for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++)
2039 for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++)
2040 rtw_phy_init_tx_power_limit(rtwdev, regd, bw,
2041 rs);
2042}
2043
2044void rtw_phy_config_swing_table(struct rtw_dev *rtwdev,
2045 struct rtw_swing_table *swing_table)
2046{
2047 const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl;
2048 u8 channel = rtwdev->hal.current_channel;
2049
2050 if (IS_CH_2G_BAND(channel)) {
2051 if (rtwdev->dm_info.tx_rate <= DESC_RATE11M) {
2052 swing_table->p[RF_PATH_A] = tbl->pwrtrk_2g_ccka_p;
2053 swing_table->n[RF_PATH_A] = tbl->pwrtrk_2g_ccka_n;
2054 swing_table->p[RF_PATH_B] = tbl->pwrtrk_2g_cckb_p;
2055 swing_table->n[RF_PATH_B] = tbl->pwrtrk_2g_cckb_n;
2056 } else {
2057 swing_table->p[RF_PATH_A] = tbl->pwrtrk_2ga_p;
2058 swing_table->n[RF_PATH_A] = tbl->pwrtrk_2ga_n;
2059 swing_table->p[RF_PATH_B] = tbl->pwrtrk_2gb_p;
2060 swing_table->n[RF_PATH_B] = tbl->pwrtrk_2gb_n;
2061 }
2062 } else if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) {
2063 swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_1];
2064 swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_1];
2065 swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_1];
2066 swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_1];
2067 } else if (IS_CH_5G_BAND_3(channel)) {
2068 swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_2];
2069 swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_2];
2070 swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_2];
2071 swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_2];
2072 } else if (IS_CH_5G_BAND_4(channel)) {
2073 swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_3];
2074 swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_3];
2075 swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_3];
2076 swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_3];
2077 } else {
2078 swing_table->p[RF_PATH_A] = tbl->pwrtrk_2ga_p;
2079 swing_table->n[RF_PATH_A] = tbl->pwrtrk_2ga_n;
2080 swing_table->p[RF_PATH_B] = tbl->pwrtrk_2gb_p;
2081 swing_table->n[RF_PATH_B] = tbl->pwrtrk_2gb_n;
2082 }
2083}
2084EXPORT_SYMBOL(rtw_phy_config_swing_table);
2085
2086void rtw_phy_pwrtrack_avg(struct rtw_dev *rtwdev, u8 thermal, u8 path)
2087{
2088 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
2089
2090 ewma_thermal_add(&dm_info->avg_thermal[path], thermal);
2091 dm_info->thermal_avg[path] =
2092 ewma_thermal_read(&dm_info->avg_thermal[path]);
2093}
2094EXPORT_SYMBOL(rtw_phy_pwrtrack_avg);
2095
2096bool rtw_phy_pwrtrack_thermal_changed(struct rtw_dev *rtwdev, u8 thermal,
2097 u8 path)
2098{
2099 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
2100 u8 avg = ewma_thermal_read(&dm_info->avg_thermal[path]);
2101
2102 if (avg == thermal)
2103 return false;
2104
2105 return true;
2106}
2107EXPORT_SYMBOL(rtw_phy_pwrtrack_thermal_changed);
2108
2109u8 rtw_phy_pwrtrack_get_delta(struct rtw_dev *rtwdev, u8 path)
2110{
2111 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
2112 u8 therm_avg, therm_efuse, therm_delta;
2113
2114 therm_avg = dm_info->thermal_avg[path];
2115 therm_efuse = rtwdev->efuse.thermal_meter[path];
2116 therm_delta = abs(therm_avg - therm_efuse);
2117
2118 return min_t(u8, therm_delta, RTW_PWR_TRK_TBL_SZ - 1);
2119}
2120EXPORT_SYMBOL(rtw_phy_pwrtrack_get_delta);
2121
2122s8 rtw_phy_pwrtrack_get_pwridx(struct rtw_dev *rtwdev,
2123 struct rtw_swing_table *swing_table,
2124 u8 tbl_path, u8 therm_path, u8 delta)
2125{
2126 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
2127 const u8 *delta_swing_table_idx_pos;
2128 const u8 *delta_swing_table_idx_neg;
2129
2130 if (delta >= RTW_PWR_TRK_TBL_SZ) {
2131 rtw_warn(rtwdev, "power track table overflow\n");
2132 return 0;
2133 }
2134
2135 if (!swing_table) {
2136 rtw_warn(rtwdev, "swing table not configured\n");
2137 return 0;
2138 }
2139
2140 delta_swing_table_idx_pos = swing_table->p[tbl_path];
2141 delta_swing_table_idx_neg = swing_table->n[tbl_path];
2142
2143 if (!delta_swing_table_idx_pos || !delta_swing_table_idx_neg) {
2144 rtw_warn(rtwdev, "invalid swing table index\n");
2145 return 0;
2146 }
2147
2148 if (dm_info->thermal_avg[therm_path] >
2149 rtwdev->efuse.thermal_meter[therm_path])
2150 return delta_swing_table_idx_pos[delta];
2151 else
2152 return -delta_swing_table_idx_neg[delta];
2153}
2154EXPORT_SYMBOL(rtw_phy_pwrtrack_get_pwridx);
2155
2156bool rtw_phy_pwrtrack_need_iqk(struct rtw_dev *rtwdev)
2157{
2158 struct rtw_dm_info *dm_info = &rtwdev->dm_info;
2159 u8 delta_iqk;
2160
2161 delta_iqk = abs(dm_info->thermal_avg[0] - dm_info->thermal_meter_k);
2162 if (delta_iqk >= rtwdev->chip->iqk_threshold) {
2163 dm_info->thermal_meter_k = dm_info->thermal_avg[0];
2164 return true;
2165 }
2166 return false;
2167}
2168EXPORT_SYMBOL(rtw_phy_pwrtrack_need_iqk);
2169