1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include "../wifi.h"
16#include "../pci.h"
17#include "../ps.h"
18#include "../base.h"
19#include "reg.h"
20#include "def.h"
21#include "phy.h"
22#include "trx.h"
23#include "../btcoexist/halbt_precomp.h"
24#include "hw.h"
25#include "../efuse.h"
26
27static u32 _rtl8822be_phy_calculate_bit_shift(u32 bitmask);
28static void
29_rtl8822be_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
30
31static long _rtl8822be_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
32 enum wireless_mode wirelessmode,
33 u8 txpwridx);
34static void rtl8822be_phy_set_rf_on(struct ieee80211_hw *hw);
35static void rtl8822be_phy_set_io(struct ieee80211_hw *hw);
36
37static u8 cck_rates[] = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M};
38static u8 sizes_of_cck_retes = 4;
39static u8 ofdm_rates[] = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
40 DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
41 DESC_RATE48M, DESC_RATE54M};
42static u8 sizes_of_ofdm_retes = 8;
43static u8 ht_rates_1t[] = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
44 DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
45 DESC_RATEMCS6, DESC_RATEMCS7};
46static u8 sizes_of_ht_retes_1t = 8;
47static u8 ht_rates_2t[] = {DESC_RATEMCS8, DESC_RATEMCS9, DESC_RATEMCS10,
48 DESC_RATEMCS11, DESC_RATEMCS12, DESC_RATEMCS13,
49 DESC_RATEMCS14, DESC_RATEMCS15};
50static u8 sizes_of_ht_retes_2t = 8;
51static u8 vht_rates_1t[] = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
52 DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
53 DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
54 DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
55 DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
56static u8 vht_rates_2t[] = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
57 DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
58 DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
59 DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
60 DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
61static u8 sizes_of_vht_retes = 10;
62
63u32 rtl8822be_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
64 u32 bitmask)
65{
66 struct rtl_priv *rtlpriv = rtl_priv(hw);
67 u32 returnvalue, originalvalue, bitshift;
68
69 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
70 regaddr, bitmask);
71 originalvalue = rtl_read_dword(rtlpriv, regaddr);
72 bitshift = _rtl8822be_phy_calculate_bit_shift(bitmask);
73 returnvalue = (originalvalue & bitmask) >> bitshift;
74
75 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
76 bitmask, regaddr, originalvalue);
77
78 return returnvalue;
79}
80
81void rtl8822be_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
82 u32 data)
83{
84 struct rtl_priv *rtlpriv = rtl_priv(hw);
85 u32 originalvalue, bitshift;
86
87 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
88 "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, bitmask,
89 data);
90
91 if (bitmask != MASKDWORD) {
92 originalvalue = rtl_read_dword(rtlpriv, regaddr);
93 bitshift = _rtl8822be_phy_calculate_bit_shift(bitmask);
94 data = ((originalvalue & (~bitmask)) |
95 ((data << bitshift) & bitmask));
96 }
97
98 rtl_write_dword(rtlpriv, regaddr, data);
99
100 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
101 "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, bitmask,
102 data);
103}
104
105u32 rtl8822be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
106 u32 regaddr, u32 bitmask)
107{
108 struct rtl_priv *rtlpriv = rtl_priv(hw);
109 u32 readback_value ;
110 unsigned long flags;
111
112 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
113 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", regaddr, rfpath,
114 bitmask);
115
116 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
117
118 readback_value = rtlpriv->phydm.ops->phydm_read_rf_reg(
119 rtlpriv, rfpath, regaddr, bitmask);
120
121 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
122
123 return readback_value;
124}
125
126void rtl8822be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
127 u32 regaddr, u32 bitmask, u32 data)
128{
129 struct rtl_priv *rtlpriv = rtl_priv(hw);
130 unsigned long flags;
131
132 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
133 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
134 regaddr, bitmask, data, rfpath);
135
136 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
137
138 rtlpriv->phydm.ops->phydm_write_rf_reg(rtlpriv, rfpath, regaddr,
139 bitmask, data);
140
141 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
142
143 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
144 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
145 regaddr, bitmask, data, rfpath);
146}
147
148static u32 _rtl8822be_phy_calculate_bit_shift(u32 bitmask)
149{
150 u32 i;
151
152 for (i = 0; i <= 31; i++) {
153 if (((bitmask >> i) & 0x1) == 1)
154 break;
155 }
156 return i;
157}
158
159bool rtl8822be_halmac_cb_init_mac_register(struct rtl_priv *rtlpriv)
160{
161 return rtlpriv->phydm.ops->phydm_phy_mac_config(rtlpriv);
162}
163
164bool rtl8822be_phy_bb_config(struct ieee80211_hw *hw)
165{
166 bool rtstatus = true;
167 struct rtl_priv *rtlpriv = rtl_priv(hw);
168 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
169 u8 crystal_cap;
170
171
172 rtstatus = rtlpriv->phydm.ops->phydm_phy_bb_config(rtlpriv);
173
174
175 crystal_cap = rtlefuse->crystalcap & 0x3F;
176 rtl_set_bbreg(hw, REG_AFE_XTAL_CTRL_8822B, 0x7E000000, crystal_cap);
177 rtl_set_bbreg(hw, REG_AFE_PLL_CTRL_8822B, 0x7E, crystal_cap);
178
179
180
181 return rtstatus;
182}
183
184bool rtl8822be_phy_rf_config(struct ieee80211_hw *hw)
185{
186 struct rtl_priv *rtlpriv = rtl_priv(hw);
187 struct rtl_phy *rtlphy = &rtlpriv->phy;
188
189 if (rtlphy->rf_type == RF_1T1R)
190 rtlphy->num_total_rfpath = 1;
191 else
192 rtlphy->num_total_rfpath = 2;
193
194 return rtlpriv->phydm.ops->phydm_phy_rf_config(rtlpriv);
195}
196
197bool rtl8822be_halmac_cb_init_bb_rf_register(struct rtl_priv *rtlpriv)
198{
199 struct ieee80211_hw *hw = rtlpriv->hw;
200 enum radio_mask txpath, rxpath;
201 bool tx2path;
202 bool ret = false;
203
204 _rtl8822be_phy_init_bb_rf_register_definition(hw);
205
206 rtlpriv->halmac.ops->halmac_phy_power_switch(rtlpriv, 1);
207
208
209 rtlpriv->phydm.ops->phydm_parameter_init(rtlpriv, 0);
210
211
212 if (rtl8822be_phy_bb_config(hw) && rtl8822be_phy_rf_config(hw))
213 ret = true;
214
215
216 rtlpriv->phydm.ops->phydm_parameter_init(rtlpriv, 1);
217
218
219 txpath = RF_MASK_A | RF_MASK_B;
220 rxpath = RF_MASK_A | RF_MASK_B;
221 tx2path = false;
222 ret = rtlpriv->phydm.ops->phydm_trx_mode(rtlpriv, txpath, rxpath,
223 tx2path);
224
225 return ret;
226}
227
228static void _rtl8822be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
229{
230 struct rtl_priv *rtlpriv = rtl_priv(hw);
231 struct rtl_phy *rtlphy = &rtlpriv->phy;
232
233 u8 band, rfpath, txnum, rate;
234
235 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
236 for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath)
237 for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
238 for (rate = 0; rate < TX_PWR_BY_RATE_NUM_RATE;
239 ++rate)
240 rtlphy->tx_power_by_rate_offset
241 [band][rfpath][txnum][rate] = 0;
242}
243
244static void _rtl8822be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
245 u8 band, u8 path,
246 u8 rate_section, u8 txnum,
247 u8 value)
248{
249 struct rtl_priv *rtlpriv = rtl_priv(hw);
250 struct rtl_phy *rtlphy = &rtlpriv->phy;
251
252 if (path > RF90_PATH_D) {
253 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
254 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
255 path);
256 return;
257 }
258
259 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
260 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
261 "Invalid band %d in phy_SetTxPowerByRatBase()\n",
262 band);
263 return;
264 }
265
266 if (rate_section >= MAX_RATE_SECTION ||
267 (band == BAND_ON_5G && rate_section == CCK)) {
268 RT_TRACE(
269 rtlpriv, COMP_INIT, DBG_LOUD,
270 "Invalid rate_section %d in phy_SetTxPowerByRatBase()\n",
271 rate_section);
272 return;
273 }
274
275 if (band == BAND_ON_2_4G)
276 rtlphy->txpwr_by_rate_base_24g[path][txnum][rate_section] =
277 value;
278 else
279 rtlphy->txpwr_by_rate_base_5g[path][txnum][rate_section - 1] =
280 value;
281}
282
283static u8 _rtl8822be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
284 u8 band, u8 path, u8 txnum,
285 u8 rate_section)
286{
287 struct rtl_priv *rtlpriv = rtl_priv(hw);
288 struct rtl_phy *rtlphy = &rtlpriv->phy;
289 u8 value;
290
291 if (path > RF90_PATH_D) {
292 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
293 "Invalid Rf Path %d in phy_GetTxPowerByRatBase()\n",
294 path);
295 return 0;
296 }
297
298 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
299 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
300 "Invalid band %d in phy_GetTxPowerByRatBase()\n",
301 band);
302 return 0;
303 }
304
305 if (rate_section >= MAX_RATE_SECTION ||
306 (band == BAND_ON_5G && rate_section == CCK)) {
307 RT_TRACE(
308 rtlpriv, COMP_INIT, DBG_LOUD,
309 "Invalid rate_section %d in phy_GetTxPowerByRatBase()\n",
310 rate_section);
311 return 0;
312 }
313
314 if (band == BAND_ON_2_4G)
315 value = rtlphy->txpwr_by_rate_base_24g[path][txnum]
316 [rate_section];
317 else
318 value = rtlphy->txpwr_by_rate_base_5g[path][txnum]
319 [rate_section - 1];
320
321 return value;
322}
323
324static void _rtl8822be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
325{
326 struct rtl_priv *rtlpriv = rtl_priv(hw);
327 struct rtl_phy *rtlphy = &rtlpriv->phy;
328
329 struct {
330 enum rtl_desc_rate rate;
331 enum rate_section section;
332 } rate_sec_base[] = {
333 {DESC_RATE11M, CCK},
334 {DESC_RATE54M, OFDM},
335 {DESC_RATEMCS7, HT_MCS0_MCS7},
336 {DESC_RATEMCS15, HT_MCS8_MCS15},
337 {DESC_RATEVHT1SS_MCS7, VHT_1SSMCS0_1SSMCS9},
338 {DESC_RATEVHT2SS_MCS7, VHT_2SSMCS0_2SSMCS9},
339 };
340
341 u8 band, path, rs, tx_num, base;
342 u8 rate, section;
343
344 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
345 for (path = RF90_PATH_A; path <= RF90_PATH_B; path++) {
346 for (rs = 0; rs < MAX_RATE_SECTION; rs++) {
347 rate = rate_sec_base[rs].rate;
348 section = rate_sec_base[rs].section;
349
350 if (IS_1T_RATE(rate))
351 tx_num = RF_1TX;
352 else
353 tx_num = RF_2TX;
354
355 if (band == BAND_ON_5G &&
356 RX_HAL_IS_CCK_RATE(rate))
357 continue;
358
359 base = rtlphy->tx_power_by_rate_offset
360 [band][path][tx_num][rate];
361 _rtl8822be_phy_set_txpower_by_rate_base(
362 hw, band, path, section, tx_num, base);
363 }
364 }
365 }
366}
367
368static void __rtl8822be_phy_cross_reference_core(struct ieee80211_hw *hw,
369 u8 regulation, u8 bw,
370 u8 channel)
371{
372 struct rtl_priv *rtlpriv = rtl_priv(hw);
373 struct rtl_phy *rtlphy = &rtlpriv->phy;
374 u8 rs, ref_rs;
375 s8 pwrlmt, ref_pwrlmt;
376
377 for (rs = 0; rs < MAX_RATE_SECTION_NUM; ++rs) {
378
379 if (bw != HT_CHANNEL_WIDTH_20 && bw != HT_CHANNEL_WIDTH_20_40)
380 continue;
381
382 if (rs == HT_MCS0_MCS7)
383 ref_rs = VHT_1SSMCS0_1SSMCS9;
384 else if (rs == HT_MCS8_MCS15)
385 ref_rs = VHT_2SSMCS0_2SSMCS9;
386 else if (rs == VHT_1SSMCS0_1SSMCS9)
387 ref_rs = HT_MCS0_MCS7;
388 else if (rs == VHT_2SSMCS0_2SSMCS9)
389 ref_rs = HT_MCS8_MCS15;
390 else
391 continue;
392
393 ref_pwrlmt = rtlphy->txpwr_limit_5g[regulation][bw][ref_rs]
394 [channel][RF90_PATH_A];
395 if (ref_pwrlmt == MAX_POWER_INDEX)
396 continue;
397
398 pwrlmt = rtlphy->txpwr_limit_5g[regulation][bw][rs][channel]
399 [RF90_PATH_A];
400 if (pwrlmt != MAX_POWER_INDEX)
401 continue;
402
403 rtlphy->txpwr_limit_5g[regulation][bw][rs][channel]
404 [RF90_PATH_A] = ref_pwrlmt;
405 }
406}
407
408static void
409_rtl8822be_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw)
410{
411 u8 regulation, bw, channel;
412
413 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
414 for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
415 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G;
416 ++channel) {
417 __rtl8822be_phy_cross_reference_core(
418 hw, regulation, bw, channel);
419 }
420 }
421 }
422}
423
424static void __rtl8822be_txpwr_limit_to_index_2g(struct ieee80211_hw *hw,
425 u8 regulation, u8 bw,
426 u8 channel)
427{
428 struct rtl_priv *rtlpriv = rtl_priv(hw);
429 struct rtl_phy *rtlphy = &rtlpriv->phy;
430 u8 bw40_pwr_base_dbm2_4G;
431 u8 rate_section;
432 s8 temp_pwrlmt;
433 enum rf_tx_num txnum;
434 s8 temp_value;
435 u8 rf_path;
436
437 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM;
438 ++rate_section) {
439
440
441
442
443 temp_pwrlmt =
444 rtlphy->txpwr_limit_2_4g[regulation][bw][rate_section]
445 [channel][RF90_PATH_A];
446 txnum = IS_1T_RATESEC(rate_section) ? RF_1TX : RF_2TX;
447
448 if (temp_pwrlmt == MAX_POWER_INDEX)
449 continue;
450
451 for (rf_path = RF90_PATH_A; rf_path < MAX_RF_PATH_NUM;
452 ++rf_path) {
453 bw40_pwr_base_dbm2_4G =
454 _rtl8822be_phy_get_txpower_by_rate_base(
455 hw, BAND_ON_2_4G, rf_path, txnum,
456 rate_section);
457
458 temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G;
459 rtlphy->txpwr_limit_2_4g[regulation][bw][rate_section]
460 [channel][rf_path] = temp_value;
461
462 RT_TRACE(
463 rtlpriv, COMP_INIT, DBG_TRACE,
464 "TxPwrLimit_2_4G[regulation %d][bw %d][rateSection %d][channel %d] = %d\n(TxPwrLimit in dBm %d - BW40PwrLmt2_4G[channel %d][rfPath %d] %d)\n",
465 regulation, bw, rate_section, channel,
466 rtlphy->txpwr_limit_2_4g[regulation][bw]
467 [rate_section][channel]
468 [rf_path],
469 (temp_pwrlmt == 63) ? 0 : temp_pwrlmt / 2,
470 channel, rf_path, bw40_pwr_base_dbm2_4G);
471 }
472 }
473}
474
475static void __rtl8822be_txpwr_limit_to_index_5g(struct ieee80211_hw *hw,
476 u8 regulation, u8 bw,
477 u8 channel)
478{
479 struct rtl_priv *rtlpriv = rtl_priv(hw);
480 struct rtl_phy *rtlphy = &rtlpriv->phy;
481 u8 bw40_pwr_base_dbm5G;
482 u8 rate_section;
483 s8 temp_pwrlmt;
484 enum rf_tx_num txnum;
485 s8 temp_value;
486 u8 rf_path;
487
488 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM;
489 ++rate_section) {
490
491
492
493
494
495 temp_pwrlmt =
496 rtlphy->txpwr_limit_5g[regulation][bw][rate_section]
497 [channel][RF90_PATH_A];
498 txnum = IS_1T_RATESEC(rate_section) ? RF_1TX : RF_2TX;
499
500 if (temp_pwrlmt == MAX_POWER_INDEX)
501 continue;
502
503 for (rf_path = RF90_PATH_A; rf_path < MAX_RF_PATH_NUM;
504 ++rf_path) {
505 bw40_pwr_base_dbm5G =
506 _rtl8822be_phy_get_txpower_by_rate_base(
507 hw, BAND_ON_5G, rf_path, txnum,
508 rate_section);
509
510 temp_value = temp_pwrlmt - bw40_pwr_base_dbm5G;
511 rtlphy->txpwr_limit_5g[regulation][bw][rate_section]
512 [channel][rf_path] = temp_value;
513
514 RT_TRACE(
515 rtlpriv, COMP_INIT, DBG_TRACE,
516 "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfPath %d] %d)\n",
517 regulation, bw, rate_section, channel,
518 rtlphy->txpwr_limit_5g[regulation][bw]
519 [rate_section][channel]
520 [rf_path],
521 temp_pwrlmt, channel, rf_path,
522 bw40_pwr_base_dbm5G);
523 }
524 }
525}
526
527static void
528_rtl8822be_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw)
529{
530 struct rtl_priv *rtlpriv = rtl_priv(hw);
531 u8 regulation, bw, channel;
532
533 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "=====> %s()\n", __func__);
534
535 _rtl8822be_phy_cross_reference_ht_and_vht_txpower_limit(hw);
536
537 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
538 for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) {
539 for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G;
540 ++channel) {
541 __rtl8822be_txpwr_limit_to_index_2g(
542 hw, regulation, bw, channel);
543 }
544 }
545 }
546
547 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
548 for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
549 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G;
550 ++channel) {
551 __rtl8822be_txpwr_limit_to_index_5g(
552 hw, regulation, bw, channel);
553 }
554 }
555 }
556 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<===== %s()\n", __func__);
557}
558
559static void _rtl8822be_phy_init_txpower_limit(struct ieee80211_hw *hw)
560{
561 struct rtl_priv *rtlpriv = rtl_priv(hw);
562 struct rtl_phy *rtlphy = &rtlpriv->phy;
563 u8 i, j, k, l, m;
564
565 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "=====> %s()!\n", __func__);
566
567 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
568 for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j)
569 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
570 for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
571 for (l = 0; l < MAX_RF_PATH_NUM; ++l)
572 rtlphy->txpwr_limit_2_4g[i][j]
573 [k][m]
574 [l] =
575 MAX_POWER_INDEX;
576 }
577 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
578 for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j)
579 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
580 for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m)
581 for (l = 0; l < MAX_RF_PATH_NUM; ++l)
582 rtlphy->txpwr_limit_5g[i][j][k]
583 [m][l] =
584 MAX_POWER_INDEX;
585 }
586
587 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<===== %s()!\n", __func__);
588}
589
590static void
591_rtl8822be_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw)
592{
593 struct rtl_priv *rtlpriv = rtl_priv(hw);
594 struct rtl_phy *rtlphy = &rtlpriv->phy;
595
596 u8 base = 0, i = 0, value = 0, band = 0, path = 0, txnum = 0;
597
598 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) {
599 for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
600 for (txnum = RF_1TX; txnum <= RF_2TX; ++txnum) {
601
602 base = rtlphy->tx_power_by_rate_offset
603 [band][path][txnum]
604 [DESC_RATE11M];
605 for (i = 0; i < sizeof(cck_rates); ++i) {
606 value = rtlphy->tx_power_by_rate_offset
607 [band][path][txnum]
608 [cck_rates[i]];
609 rtlphy->tx_power_by_rate_offset
610 [band][path][txnum]
611 [cck_rates[i]] = value - base;
612 }
613
614
615 base = rtlphy->tx_power_by_rate_offset
616 [band][path][txnum]
617 [DESC_RATE54M];
618 for (i = 0; i < sizeof(ofdm_rates); ++i) {
619 value = rtlphy->tx_power_by_rate_offset
620 [band][path][txnum]
621 [ofdm_rates[i]];
622 rtlphy->tx_power_by_rate_offset
623 [band][path][txnum]
624 [ofdm_rates[i]] = value - base;
625 }
626
627
628 base = rtlphy->tx_power_by_rate_offset
629 [band][path][txnum]
630 [DESC_RATEMCS7];
631 for (i = 0; i < sizeof(ht_rates_1t); ++i) {
632 value = rtlphy->tx_power_by_rate_offset
633 [band][path][txnum]
634 [ht_rates_1t[i]];
635 rtlphy->tx_power_by_rate_offset
636 [band][path][txnum]
637 [ht_rates_1t[i]] = value - base;
638 }
639
640
641 base = rtlphy->tx_power_by_rate_offset
642 [band][path][txnum]
643 [DESC_RATEMCS15];
644 for (i = 0; i < sizeof(ht_rates_2t); ++i) {
645 value = rtlphy->tx_power_by_rate_offset
646 [band][path][txnum]
647 [ht_rates_2t[i]];
648 rtlphy->tx_power_by_rate_offset
649 [band][path][txnum]
650 [ht_rates_2t[i]] = value - base;
651 }
652
653
654 base = rtlphy->tx_power_by_rate_offset
655 [band][path][txnum]
656 [DESC_RATEVHT1SS_MCS7];
657 for (i = 0; i < sizeof(vht_rates_1t); ++i) {
658 value = rtlphy->tx_power_by_rate_offset
659 [band][path][txnum]
660 [vht_rates_1t[i]];
661 rtlphy->tx_power_by_rate_offset
662 [band][path][txnum]
663 [vht_rates_1t[i]] =
664 value - base;
665 }
666
667
668 base = rtlphy->tx_power_by_rate_offset
669 [band][path][txnum]
670 [DESC_RATEVHT2SS_MCS7];
671 for (i = 0; i < sizeof(vht_rates_2t); ++i) {
672 value = rtlphy->tx_power_by_rate_offset
673 [band][path][txnum]
674 [vht_rates_2t[i]];
675 rtlphy->tx_power_by_rate_offset
676 [band][path][txnum]
677 [vht_rates_2t[i]] =
678 value - base;
679 }
680 }
681 }
682 }
683
684 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, "<===%s()\n", __func__);
685}
686
687static void
688_rtl8822be_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
689{
690
691
692
693 _rtl8822be_phy_store_txpower_by_rate_base(hw);
694
695
696 _rtl8822be_phy_convert_txpower_dbm_to_relative_value(hw);
697}
698
699
700static bool _rtl8822be_get_integer_from_string(char *str, u8 *pint)
701{
702 u16 i = 0;
703 *pint = 0;
704
705 while (str[i] != '\0') {
706 if (str[i] >= '0' && str[i] <= '9') {
707 *pint *= 10;
708 *pint += (str[i] - '0');
709 } else {
710 return false;
711 }
712 ++i;
713 }
714
715 return true;
716}
717
718static bool _rtl8822be_eq_n_byte(u8 *str1, u8 *str2, u32 num)
719{
720 if (num == 0)
721 return false;
722 while (num > 0) {
723 num--;
724 if (str1[num] != str2[num])
725 return false;
726 }
727 return true;
728}
729
730static char _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
731 u8 band, u8 channel)
732{
733 struct rtl_priv *rtlpriv = rtl_priv(hw);
734 char channel_index = -1;
735 u8 i = 0;
736
737 if (band == BAND_ON_2_4G) {
738 channel_index = channel - 1;
739 } else if (band == BAND_ON_5G) {
740 for (i = 0; i < sizeof(rtl_channel5g) / sizeof(u8); ++i) {
741 if (rtl_channel5g[i] == channel)
742 channel_index = i;
743 }
744 } else {
745 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s",
746 band, __func__);
747 }
748
749 if (channel_index == -1)
750 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
751 "Invalid Channel %d of Band %d in %s", channel, band,
752 __func__);
753
754 return channel_index;
755}
756
757void rtl8822be_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
758 u8 *pband, u8 *pbandwidth,
759 u8 *prate_section, u8 *prf_path,
760 u8 *pchannel, u8 *ppower_limit)
761{
762 struct rtl_priv *rtlpriv = rtl_priv(hw);
763 struct rtl_phy *rtlphy = &rtlpriv->phy;
764 u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
765 u8 channel_index;
766 char power_limit = 0, prev_power_limit, ret;
767
768 if (!_rtl8822be_get_integer_from_string((char *)pchannel, &channel) ||
769 !_rtl8822be_get_integer_from_string((char *)ppower_limit,
770 &power_limit)) {
771 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
772 "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
773 channel, power_limit);
774 }
775
776 power_limit =
777 power_limit > MAX_POWER_INDEX ? MAX_POWER_INDEX : power_limit;
778
779 if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
780 regulation = 0;
781 else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
782 regulation = 1;
783 else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
784 regulation = 2;
785 else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
786 regulation = 3;
787
788 if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
789 rate_section = CCK;
790 else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
791 rate_section = OFDM;
792 else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
793 _rtl8822be_eq_n_byte(prf_path, (u8 *)("1T"), 2))
794 rate_section = HT_MCS0_MCS7;
795 else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
796 _rtl8822be_eq_n_byte(prf_path, (u8 *)("2T"), 2))
797 rate_section = HT_MCS8_MCS15;
798 else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
799 _rtl8822be_eq_n_byte(prf_path, (u8 *)("1T"), 2))
800 rate_section = VHT_1SSMCS0_1SSMCS9;
801 else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
802 _rtl8822be_eq_n_byte(prf_path, (u8 *)("2T"), 2))
803 rate_section = VHT_2SSMCS0_2SSMCS9;
804
805 if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
806 bandwidth = HT_CHANNEL_WIDTH_20;
807 else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
808 bandwidth = HT_CHANNEL_WIDTH_20_40;
809 else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
810 bandwidth = HT_CHANNEL_WIDTH_80;
811 else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
812 bandwidth = 3;
813
814 if (_rtl8822be_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
815 ret = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_2_4G,
816 channel);
817
818 if (ret == -1)
819 return;
820
821 channel_index = ret;
822
823 prev_power_limit =
824 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
825 [rate_section][channel_index]
826 [RF90_PATH_A];
827
828 if (power_limit < prev_power_limit)
829 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
830 [rate_section][channel_index]
831 [RF90_PATH_A] = power_limit;
832
833 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
834 "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
835 regulation, bandwidth, rate_section, channel_index,
836 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
837 [rate_section][channel_index]
838 [RF90_PATH_A]);
839 } else if (_rtl8822be_eq_n_byte(pband, (u8 *)("5G"), 2)) {
840 ret = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_5G,
841 channel);
842
843 if (ret == -1)
844 return;
845
846 channel_index = ret;
847
848 prev_power_limit =
849 rtlphy->txpwr_limit_5g[regulation][bandwidth]
850 [rate_section][channel_index]
851 [RF90_PATH_A];
852
853 if (power_limit < prev_power_limit)
854 rtlphy->txpwr_limit_5g[regulation][bandwidth]
855 [rate_section][channel_index]
856 [RF90_PATH_A] = power_limit;
857
858 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
859 "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
860 regulation, bandwidth, rate_section, channel,
861 rtlphy->txpwr_limit_5g[regulation][bandwidth]
862 [rate_section][channel_index]
863 [RF90_PATH_A]);
864
865 } else {
866 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
867 "Cannot recognize the band info in %s\n", pband);
868 return;
869 }
870}
871
872bool rtl8822be_load_txpower_by_rate(struct ieee80211_hw *hw)
873{
874 struct rtl_priv *rtlpriv = rtl_priv(hw);
875 bool rtstatus = true;
876
877 _rtl8822be_phy_init_tx_power_by_rate(hw);
878
879 rtstatus = rtlpriv->phydm.ops->phydm_load_txpower_by_rate(rtlpriv);
880
881 if (!rtstatus) {
882 pr_err("BB_PG Reg Fail!!\n");
883 return false;
884 }
885
886 _rtl8822be_phy_txpower_by_rate_configuration(hw);
887
888 return true;
889}
890
891bool rtl8822be_load_txpower_limit(struct ieee80211_hw *hw)
892{
893 struct rtl_priv *rtlpriv = rtl_priv(hw);
894 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
895 bool rtstatus = true;
896
897 _rtl8822be_phy_init_txpower_limit(hw);
898
899 if (rtlefuse->eeprom_regulatory == 1)
900 ;
901 else
902 return true;
903
904 rtstatus = rtlpriv->phydm.ops->phydm_load_txpower_limit(rtlpriv);
905
906 if (!rtstatus) {
907 pr_err("RF TxPwr Limit Fail!!\n");
908 return false;
909 }
910
911 _rtl8822be_phy_convert_txpower_limit_to_power_index(hw);
912
913 return true;
914}
915
916static void _rtl8822be_get_rate_values_of_tx_power_by_rate(
917 struct ieee80211_hw *hw, u32 reg_addr, u32 bit_mask, u32 value,
918 u8 *rate, s8 *pwr_by_rate_val, u8 *rate_num)
919{
920 struct rtl_priv *rtlpriv = rtl_priv(hw);
921 u8 i = 0;
922
923 switch (reg_addr) {
924 case 0xE00:
925 case 0x830:
926 rate[0] = DESC_RATE6M;
927 rate[1] = DESC_RATE9M;
928 rate[2] = DESC_RATE12M;
929 rate[3] = DESC_RATE18M;
930 for (i = 0; i < 4; ++i) {
931 pwr_by_rate_val[i] =
932 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
933 ((value >> (i * 8)) & 0xF));
934 }
935 *rate_num = 4;
936 break;
937
938 case 0xE04:
939 case 0x834:
940 rate[0] = DESC_RATE24M;
941 rate[1] = DESC_RATE36M;
942 rate[2] = DESC_RATE48M;
943 rate[3] = DESC_RATE54M;
944 for (i = 0; i < 4; ++i) {
945 pwr_by_rate_val[i] =
946 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
947 ((value >> (i * 8)) & 0xF));
948 }
949 *rate_num = 4;
950 break;
951
952 case 0xE08:
953 rate[0] = DESC_RATE1M;
954 pwr_by_rate_val[0] = (s8)((((value >> (8 + 4)) & 0xF)) * 10 +
955 ((value >> 8) & 0xF));
956 *rate_num = 1;
957 break;
958
959 case 0x86C:
960 if (bit_mask == 0xffffff00) {
961 rate[0] = DESC_RATE2M;
962 rate[1] = DESC_RATE5_5M;
963 rate[2] = DESC_RATE11M;
964 for (i = 1; i < 4; ++i) {
965 pwr_by_rate_val[i - 1] = (s8)(
966 (((value >> (i * 8 + 4)) & 0xF)) * 10 +
967 ((value >> (i * 8)) & 0xF));
968 }
969 *rate_num = 3;
970 } else if (bit_mask == 0x000000ff) {
971 rate[0] = DESC_RATE11M;
972 pwr_by_rate_val[0] = (s8)((((value >> 4) & 0xF)) * 10 +
973 (value & 0xF));
974 *rate_num = 1;
975 }
976 break;
977
978 case 0xE10:
979 case 0x83C:
980 rate[0] = DESC_RATEMCS0;
981 rate[1] = DESC_RATEMCS1;
982 rate[2] = DESC_RATEMCS2;
983 rate[3] = DESC_RATEMCS3;
984 for (i = 0; i < 4; ++i) {
985 pwr_by_rate_val[i] =
986 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
987 ((value >> (i * 8)) & 0xF));
988 }
989 *rate_num = 4;
990 break;
991
992 case 0xE14:
993 case 0x848:
994 rate[0] = DESC_RATEMCS4;
995 rate[1] = DESC_RATEMCS5;
996 rate[2] = DESC_RATEMCS6;
997 rate[3] = DESC_RATEMCS7;
998 for (i = 0; i < 4; ++i) {
999 pwr_by_rate_val[i] =
1000 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1001 ((value >> (i * 8)) & 0xF));
1002 }
1003 *rate_num = 4;
1004 break;
1005
1006 case 0xE18:
1007 case 0x84C:
1008 rate[0] = DESC_RATEMCS8;
1009 rate[1] = DESC_RATEMCS9;
1010 rate[2] = DESC_RATEMCS10;
1011 rate[3] = DESC_RATEMCS11;
1012 for (i = 0; i < 4; ++i) {
1013 pwr_by_rate_val[i] =
1014 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1015 ((value >> (i * 8)) & 0xF));
1016 }
1017 *rate_num = 4;
1018 break;
1019
1020 case 0xE1C:
1021 case 0x868:
1022 rate[0] = DESC_RATEMCS12;
1023 rate[1] = DESC_RATEMCS13;
1024 rate[2] = DESC_RATEMCS14;
1025 rate[3] = DESC_RATEMCS15;
1026 for (i = 0; i < 4; ++i) {
1027 pwr_by_rate_val[i] =
1028 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1029 ((value >> (i * 8)) & 0xF));
1030 }
1031 *rate_num = 4;
1032
1033 break;
1034
1035 case 0x838:
1036 rate[0] = DESC_RATE1M;
1037 rate[1] = DESC_RATE2M;
1038 rate[2] = DESC_RATE5_5M;
1039 for (i = 1; i < 4; ++i) {
1040 pwr_by_rate_val[i - 1] =
1041 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1042 ((value >> (i * 8)) & 0xF));
1043 }
1044 *rate_num = 3;
1045 break;
1046
1047 case 0xC20:
1048 case 0xE20:
1049 case 0x1820:
1050 case 0x1a20:
1051 rate[0] = DESC_RATE1M;
1052 rate[1] = DESC_RATE2M;
1053 rate[2] = DESC_RATE5_5M;
1054 rate[3] = DESC_RATE11M;
1055 for (i = 0; i < 4; ++i) {
1056 pwr_by_rate_val[i] =
1057 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1058 ((value >> (i * 8)) & 0xF));
1059 }
1060 *rate_num = 4;
1061 break;
1062
1063 case 0xC24:
1064 case 0xE24:
1065 case 0x1824:
1066 case 0x1a24:
1067 rate[0] = DESC_RATE6M;
1068 rate[1] = DESC_RATE9M;
1069 rate[2] = DESC_RATE12M;
1070 rate[3] = DESC_RATE18M;
1071 for (i = 0; i < 4; ++i) {
1072 pwr_by_rate_val[i] =
1073 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1074 ((value >> (i * 8)) & 0xF));
1075 }
1076 *rate_num = 4;
1077 break;
1078
1079 case 0xC28:
1080 case 0xE28:
1081 case 0x1828:
1082 case 0x1a28:
1083 rate[0] = DESC_RATE24M;
1084 rate[1] = DESC_RATE36M;
1085 rate[2] = DESC_RATE48M;
1086 rate[3] = DESC_RATE54M;
1087 for (i = 0; i < 4; ++i) {
1088 pwr_by_rate_val[i] =
1089 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1090 ((value >> (i * 8)) & 0xF));
1091 }
1092 *rate_num = 4;
1093 break;
1094
1095 case 0xC2C:
1096 case 0xE2C:
1097 case 0x182C:
1098 case 0x1a2C:
1099 rate[0] = DESC_RATEMCS0;
1100 rate[1] = DESC_RATEMCS1;
1101 rate[2] = DESC_RATEMCS2;
1102 rate[3] = DESC_RATEMCS3;
1103 for (i = 0; i < 4; ++i) {
1104 pwr_by_rate_val[i] =
1105 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1106 ((value >> (i * 8)) & 0xF));
1107 }
1108 *rate_num = 4;
1109 break;
1110
1111 case 0xC30:
1112 case 0xE30:
1113 case 0x1830:
1114 case 0x1a30:
1115 rate[0] = DESC_RATEMCS4;
1116 rate[1] = DESC_RATEMCS5;
1117 rate[2] = DESC_RATEMCS6;
1118 rate[3] = DESC_RATEMCS7;
1119 for (i = 0; i < 4; ++i) {
1120 pwr_by_rate_val[i] =
1121 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1122 ((value >> (i * 8)) & 0xF));
1123 }
1124 *rate_num = 4;
1125 break;
1126
1127 case 0xC34:
1128 case 0xE34:
1129 case 0x1834:
1130 case 0x1a34:
1131 rate[0] = DESC_RATEMCS8;
1132 rate[1] = DESC_RATEMCS9;
1133 rate[2] = DESC_RATEMCS10;
1134 rate[3] = DESC_RATEMCS11;
1135 for (i = 0; i < 4; ++i) {
1136 pwr_by_rate_val[i] =
1137 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1138 ((value >> (i * 8)) & 0xF));
1139 }
1140 *rate_num = 4;
1141 break;
1142
1143 case 0xC38:
1144 case 0xE38:
1145 case 0x1838:
1146 case 0x1a38:
1147 rate[0] = DESC_RATEMCS12;
1148 rate[1] = DESC_RATEMCS13;
1149 rate[2] = DESC_RATEMCS14;
1150 rate[3] = DESC_RATEMCS15;
1151 for (i = 0; i < 4; ++i) {
1152 pwr_by_rate_val[i] =
1153 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1154 ((value >> (i * 8)) & 0xF));
1155 }
1156 *rate_num = 4;
1157 break;
1158
1159 case 0xC3C:
1160 case 0xE3C:
1161 case 0x183C:
1162 case 0x1a3C:
1163 rate[0] = DESC_RATEVHT1SS_MCS0;
1164 rate[1] = DESC_RATEVHT1SS_MCS1;
1165 rate[2] = DESC_RATEVHT1SS_MCS2;
1166 rate[3] = DESC_RATEVHT1SS_MCS3;
1167 for (i = 0; i < 4; ++i) {
1168 pwr_by_rate_val[i] =
1169 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1170 ((value >> (i * 8)) & 0xF));
1171 }
1172 *rate_num = 4;
1173 break;
1174
1175 case 0xC40:
1176 case 0xE40:
1177 case 0x1840:
1178 case 0x1a40:
1179 rate[0] = DESC_RATEVHT1SS_MCS4;
1180 rate[1] = DESC_RATEVHT1SS_MCS5;
1181 rate[2] = DESC_RATEVHT1SS_MCS6;
1182 rate[3] = DESC_RATEVHT1SS_MCS7;
1183 for (i = 0; i < 4; ++i) {
1184 pwr_by_rate_val[i] =
1185 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1186 ((value >> (i * 8)) & 0xF));
1187 }
1188 *rate_num = 4;
1189 break;
1190
1191 case 0xC44:
1192 case 0xE44:
1193 case 0x1844:
1194 case 0x1a44:
1195 rate[0] = DESC_RATEVHT1SS_MCS8;
1196 rate[1] = DESC_RATEVHT1SS_MCS9;
1197 rate[2] = DESC_RATEVHT2SS_MCS0;
1198 rate[3] = DESC_RATEVHT2SS_MCS1;
1199 for (i = 0; i < 4; ++i) {
1200 pwr_by_rate_val[i] =
1201 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1202 ((value >> (i * 8)) & 0xF));
1203 }
1204 *rate_num = 4;
1205 break;
1206
1207 case 0xC48:
1208 case 0xE48:
1209 case 0x1848:
1210 case 0x1a48:
1211 rate[0] = DESC_RATEVHT2SS_MCS2;
1212 rate[1] = DESC_RATEVHT2SS_MCS3;
1213 rate[2] = DESC_RATEVHT2SS_MCS4;
1214 rate[3] = DESC_RATEVHT2SS_MCS5;
1215 for (i = 0; i < 4; ++i) {
1216 pwr_by_rate_val[i] =
1217 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1218 ((value >> (i * 8)) & 0xF));
1219 }
1220 *rate_num = 4;
1221 break;
1222
1223 case 0xC4C:
1224 case 0xE4C:
1225 case 0x184C:
1226 case 0x1a4C:
1227 rate[0] = DESC_RATEVHT2SS_MCS6;
1228 rate[1] = DESC_RATEVHT2SS_MCS7;
1229 rate[2] = DESC_RATEVHT2SS_MCS8;
1230 rate[3] = DESC_RATEVHT2SS_MCS9;
1231 for (i = 0; i < 4; ++i) {
1232 pwr_by_rate_val[i] =
1233 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1234 ((value >> (i * 8)) & 0xF));
1235 }
1236 *rate_num = 4;
1237 break;
1238
1239 default:
1240 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1241 "Invalid reg_addr 0x%x in %s()\n", reg_addr, __func__);
1242 break;
1243 }
1244}
1245
1246void rtl8822be_store_tx_power_by_rate(struct ieee80211_hw *hw, u32 band,
1247 u32 rfpath, u32 txnum, u32 regaddr,
1248 u32 bitmask, u32 data)
1249{
1250 struct rtl_priv *rtlpriv = rtl_priv(hw);
1251 struct rtl_phy *rtlphy = &rtlpriv->phy;
1252 u8 i = 0, rates[4] = {0}, rate_num = 0;
1253 s8 pwr_by_rate_val[4] = {0};
1254
1255 _rtl8822be_get_rate_values_of_tx_power_by_rate(
1256 hw, regaddr, bitmask, data, rates, pwr_by_rate_val, &rate_num);
1257
1258 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
1259 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n",
1260 band);
1261 band = BAND_ON_2_4G;
1262 }
1263 if (rfpath >= MAX_RF_PATH) {
1264 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n",
1265 rfpath);
1266 rfpath = MAX_RF_PATH - 1;
1267 }
1268 if (txnum >= MAX_RF_PATH) {
1269 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n",
1270 txnum);
1271 txnum = MAX_RF_PATH - 1;
1272 }
1273
1274 for (i = 0; i < rate_num; ++i) {
1275 u8 rate_idx = rates[i];
1276
1277 if (IS_1T_RATE(rates[i]))
1278 txnum = RF_1TX;
1279 else if (IS_2T_RATE(rates[i]))
1280 txnum = RF_2TX;
1281 else
1282 WARN_ON(1);
1283
1284 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_idx] =
1285 pwr_by_rate_val[i];
1286
1287 RT_TRACE(
1288 rtlpriv, COMP_INIT, DBG_LOUD,
1289 "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][rate_idx %d] = 0x%x\n",
1290 band, rfpath, txnum, rate_idx,
1291 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum]
1292 [rate_idx]);
1293 }
1294}
1295
1296static void
1297_rtl8822be_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
1298{
1299 struct rtl_priv *rtlpriv = rtl_priv(hw);
1300 struct rtl_phy *rtlphy = &rtlpriv->phy;
1301
1302 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
1303 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
1304
1305 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
1306 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
1307
1308 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
1309 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
1310
1311 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8822B;
1312 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8822B;
1313
1314 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8822BE;
1315 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8822BE;
1316
1317 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8822B;
1318 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8822B;
1319
1320 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8822B;
1321 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8822B;
1322}
1323
1324void rtl8822be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
1325{
1326 struct rtl_priv *rtlpriv = rtl_priv(hw);
1327 struct rtl_phy *rtlphy = &rtlpriv->phy;
1328 u8 txpwr_level;
1329 long txpwr_dbm;
1330
1331 txpwr_level = rtlphy->cur_cck_txpwridx;
1332 txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
1333 txpwr_level);
1334 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
1335 if (_rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
1336 txpwr_dbm)
1337 txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
1338 txpwr_level);
1339 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
1340 if (_rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
1341 txpwr_level) > txpwr_dbm)
1342 txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(
1343 hw, WIRELESS_MODE_N_24G, txpwr_level);
1344 *powerlevel = txpwr_dbm;
1345}
1346
1347static bool _rtl8822be_phy_get_chnl_index(u8 channel, u8 *chnl_index)
1348{
1349 u8 rtl_channel5g[CHANNEL_MAX_NUMBER_5G] = {
1350 36, 38, 40, 42, 44, 46, 48,
1351 52, 54, 56, 58, 60, 62, 64,
1352 100, 102, 104, 106, 108, 110, 112,
1353 116, 118, 120, 122, 124, 126, 128,
1354 132, 134, 136, 138, 140, 142, 144,
1355 149, 151, 153, 155, 157, 159, 161,
1356 165, 167, 169, 171, 173, 175, 177};
1357 u8 i = 0;
1358 bool in_24g = true;
1359
1360 if (channel <= 14) {
1361 in_24g = true;
1362 *chnl_index = channel - 1;
1363 } else {
1364 in_24g = false;
1365
1366 for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
1367 if (rtl_channel5g[i] == channel) {
1368 *chnl_index = i;
1369 return in_24g;
1370 }
1371 }
1372 }
1373 return in_24g;
1374}
1375
1376static char _rtl8822be_phy_get_world_wide_limit(char *limit_table)
1377{
1378 char min = limit_table[0];
1379 u8 i = 0;
1380
1381 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1382 if (limit_table[i] < min)
1383 min = limit_table[i];
1384 }
1385 return min;
1386}
1387
1388static char _rtl8822be_phy_get_txpower_limit(struct ieee80211_hw *hw, u8 band,
1389 enum ht_channel_width bandwidth,
1390 enum radio_path rf_path, u8 rate,
1391 u8 channel)
1392{
1393 struct rtl_priv *rtlpriv = rtl_priv(hw);
1394 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
1395 struct rtl_phy *rtlphy = &rtlpriv->phy;
1396 short regulation = -1, rate_section = -1, channel_index = -1;
1397 char power_limit = MAX_POWER_INDEX;
1398
1399 if (rtlefuse->eeprom_regulatory == 2)
1400 return MAX_POWER_INDEX;
1401
1402 regulation = TXPWR_LMT_WW;
1403
1404 switch (rate) {
1405 case DESC_RATE1M:
1406 case DESC_RATE2M:
1407 case DESC_RATE5_5M:
1408 case DESC_RATE11M:
1409 rate_section = CCK;
1410 break;
1411
1412 case DESC_RATE6M:
1413 case DESC_RATE9M:
1414 case DESC_RATE12M:
1415 case DESC_RATE18M:
1416 case DESC_RATE24M:
1417 case DESC_RATE36M:
1418 case DESC_RATE48M:
1419 case DESC_RATE54M:
1420 rate_section = OFDM;
1421 break;
1422
1423 case DESC_RATEMCS0:
1424 case DESC_RATEMCS1:
1425 case DESC_RATEMCS2:
1426 case DESC_RATEMCS3:
1427 case DESC_RATEMCS4:
1428 case DESC_RATEMCS5:
1429 case DESC_RATEMCS6:
1430 case DESC_RATEMCS7:
1431 rate_section = HT_MCS0_MCS7;
1432 break;
1433
1434 case DESC_RATEMCS8:
1435 case DESC_RATEMCS9:
1436 case DESC_RATEMCS10:
1437 case DESC_RATEMCS11:
1438 case DESC_RATEMCS12:
1439 case DESC_RATEMCS13:
1440 case DESC_RATEMCS14:
1441 case DESC_RATEMCS15:
1442 rate_section = HT_MCS8_MCS15;
1443 break;
1444
1445 case DESC_RATEVHT1SS_MCS0:
1446 case DESC_RATEVHT1SS_MCS1:
1447 case DESC_RATEVHT1SS_MCS2:
1448 case DESC_RATEVHT1SS_MCS3:
1449 case DESC_RATEVHT1SS_MCS4:
1450 case DESC_RATEVHT1SS_MCS5:
1451 case DESC_RATEVHT1SS_MCS6:
1452 case DESC_RATEVHT1SS_MCS7:
1453 case DESC_RATEVHT1SS_MCS8:
1454 case DESC_RATEVHT1SS_MCS9:
1455 rate_section = VHT_1SSMCS0_1SSMCS9;
1456 break;
1457
1458 case DESC_RATEVHT2SS_MCS0:
1459 case DESC_RATEVHT2SS_MCS1:
1460 case DESC_RATEVHT2SS_MCS2:
1461 case DESC_RATEVHT2SS_MCS3:
1462 case DESC_RATEVHT2SS_MCS4:
1463 case DESC_RATEVHT2SS_MCS5:
1464 case DESC_RATEVHT2SS_MCS6:
1465 case DESC_RATEVHT2SS_MCS7:
1466 case DESC_RATEVHT2SS_MCS8:
1467 case DESC_RATEVHT2SS_MCS9:
1468 rate_section = VHT_2SSMCS0_2SSMCS9;
1469 break;
1470
1471 default:
1472 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Wrong rate 0x%x\n",
1473 rate);
1474 break;
1475 }
1476
1477 if (band == BAND_ON_5G && rate_section == 0)
1478 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1479 "Wrong rate 0x%x: No CCK in 5G Band\n", rate);
1480
1481
1482
1483
1484 if (rate_section == 1)
1485 bandwidth = 0;
1486
1487
1488
1489
1490 if (rate_section == 0)
1491 bandwidth = 0;
1492
1493
1494
1495
1496 if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
1497 bandwidth == 2)
1498 bandwidth = 1;
1499
1500 if (band == BAND_ON_2_4G)
1501 channel_index = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(
1502 hw, BAND_ON_2_4G, channel);
1503 else if (band == BAND_ON_5G)
1504 channel_index = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(
1505 hw, BAND_ON_5G, channel);
1506 else if (band == BAND_ON_BOTH)
1507 ;
1508
1509 if (band >= BANDMAX || regulation == -1 || bandwidth == -1 ||
1510 rate_section == -1 || channel_index == -1) {
1511 RT_TRACE(
1512 rtlpriv, COMP_POWER, DBG_LOUD,
1513 "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
1514 band, regulation, bandwidth, rf_path, rate_section,
1515 channel_index);
1516 return MAX_POWER_INDEX;
1517 }
1518
1519 if (band == BAND_ON_2_4G) {
1520 char limits[10] = {0};
1521 u8 i = 0;
1522
1523 for (i = 0; i < 4; ++i)
1524 limits[i] = rtlphy->txpwr_limit_2_4g[i][bandwidth]
1525 [rate_section]
1526 [channel_index]
1527 [rf_path];
1528
1529 power_limit =
1530 (regulation == TXPWR_LMT_WW) ?
1531 _rtl8822be_phy_get_world_wide_limit(limits) :
1532 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1533 [rate_section]
1534 [channel_index]
1535 [rf_path];
1536
1537 } else if (band == BAND_ON_5G) {
1538 char limits[10] = {0};
1539 u8 i = 0;
1540
1541 for (i = 0; i < MAX_REGULATION_NUM; ++i)
1542 limits[i] =
1543 rtlphy->txpwr_limit_5g[i][bandwidth]
1544 [rate_section]
1545 [channel_index][rf_path];
1546
1547 power_limit =
1548 (regulation == TXPWR_LMT_WW) ?
1549 _rtl8822be_phy_get_world_wide_limit(limits) :
1550 rtlphy->txpwr_limit_5g[regulation]
1551 [channel_index]
1552 [rate_section]
1553 [channel_index][rf_path];
1554 } else {
1555 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1556 "No power limit table of the specified band\n");
1557 }
1558
1559 return power_limit;
1560}
1561
1562static char
1563_rtl8822be_phy_get_txpower_by_rate(struct ieee80211_hw *hw, u8 band, u8 path,
1564 u8 rate )
1565{
1566 struct rtl_priv *rtlpriv = rtl_priv(hw);
1567 struct rtl_phy *rtlphy = &rtlpriv->phy;
1568 u8 tx_num;
1569 char tx_pwr_diff = 0;
1570
1571 if (band != BAND_ON_2_4G && band != BAND_ON_5G)
1572 return tx_pwr_diff;
1573
1574 if (path > RF90_PATH_B)
1575 return tx_pwr_diff;
1576
1577 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1578 (rate >= DESC_RATEVHT2SS_MCS0 && rate <= DESC_RATEVHT2SS_MCS9))
1579 tx_num = RF_2TX;
1580 else
1581 tx_num = RF_1TX;
1582
1583 tx_pwr_diff = (char)(rtlphy->tx_power_by_rate_offset[band][path][tx_num]
1584 [rate] &
1585 0xff);
1586
1587 return tx_pwr_diff;
1588}
1589
1590u8 rtl8822be_get_txpower_index(struct ieee80211_hw *hw, u8 path, u8 rate,
1591 u8 bandwidth, u8 channel)
1592{
1593 struct rtl_priv *rtlpriv = rtl_priv(hw);
1594 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1595 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1596 u8 index = (channel - 1);
1597 u8 txpower = 0;
1598 bool in_24g = false;
1599 char limit;
1600 char powerdiff_byrate = 0;
1601
1602 if ((rtlhal->current_bandtype == BAND_ON_2_4G &&
1603 (channel > 14 || channel < 1)) ||
1604 (rtlhal->current_bandtype == BAND_ON_5G && channel <= 14)) {
1605 index = 0;
1606 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1607 "Illegal channel!!\n");
1608 }
1609
1610
1611 in_24g = _rtl8822be_phy_get_chnl_index(channel, &index);
1612 if (in_24g) {
1613 if (RX_HAL_IS_CCK_RATE(rate))
1614 txpower = rtlefuse->txpwrlevel_cck[path][index];
1615 else if (rate >= DESC_RATE6M)
1616 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
1617 else
1618 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1619 "invalid rate\n");
1620
1621 if (rate >= DESC_RATE6M && rate <= DESC_RATE54M &&
1622 !RX_HAL_IS_CCK_RATE(rate))
1623 txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
1624
1625 if (bandwidth == HT_CHANNEL_WIDTH_20) {
1626 if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1627 (rate >= DESC_RATEVHT1SS_MCS0 &&
1628 rate <= DESC_RATEVHT2SS_MCS9))
1629 txpower +=
1630 rtlefuse->txpwr_ht20diff[path][TX_1S];
1631 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1632 (rate >= DESC_RATEVHT2SS_MCS0 &&
1633 rate <= DESC_RATEVHT2SS_MCS9))
1634 txpower +=
1635 rtlefuse->txpwr_ht20diff[path][TX_2S];
1636 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1637 if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1638 (rate >= DESC_RATEVHT1SS_MCS0 &&
1639 rate <= DESC_RATEVHT2SS_MCS9))
1640 txpower +=
1641 rtlefuse->txpwr_ht40diff[path][TX_1S];
1642 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1643 (rate >= DESC_RATEVHT2SS_MCS0 &&
1644 rate <= DESC_RATEVHT2SS_MCS9))
1645 txpower +=
1646 rtlefuse->txpwr_ht40diff[path][TX_2S];
1647 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
1648 if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1649 (rate >= DESC_RATEVHT1SS_MCS0 &&
1650 rate <= DESC_RATEVHT2SS_MCS9))
1651 txpower +=
1652 rtlefuse->txpwr_ht40diff[path][TX_1S];
1653 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1654 (rate >= DESC_RATEVHT2SS_MCS0 &&
1655 rate <= DESC_RATEVHT2SS_MCS9))
1656 txpower +=
1657 rtlefuse->txpwr_ht40diff[path][TX_2S];
1658 }
1659
1660 } else {
1661 if (rate >= DESC_RATE6M)
1662 txpower = rtlefuse->txpwr_5g_bw40base[path][index];
1663 else
1664 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
1665 "INVALID Rate.\n");
1666
1667 if (rate >= DESC_RATE6M && rate <= DESC_RATE54M &&
1668 !RX_HAL_IS_CCK_RATE(rate))
1669 txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
1670
1671 if (bandwidth == HT_CHANNEL_WIDTH_20) {
1672 if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1673 (rate >= DESC_RATEVHT1SS_MCS0 &&
1674 rate <= DESC_RATEVHT2SS_MCS9))
1675 txpower += rtlefuse->txpwr_5g_bw20diff[path]
1676 [TX_1S];
1677 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1678 (rate >= DESC_RATEVHT2SS_MCS0 &&
1679 rate <= DESC_RATEVHT2SS_MCS9))
1680 txpower += rtlefuse->txpwr_5g_bw20diff[path]
1681 [TX_2S];
1682 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1683 if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1684 (rate >= DESC_RATEVHT1SS_MCS0 &&
1685 rate <= DESC_RATEVHT2SS_MCS9))
1686 txpower += rtlefuse->txpwr_5g_bw40diff[path]
1687 [TX_1S];
1688 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1689 (rate >= DESC_RATEVHT2SS_MCS0 &&
1690 rate <= DESC_RATEVHT2SS_MCS9))
1691 txpower += rtlefuse->txpwr_5g_bw40diff[path]
1692 [TX_2S];
1693 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
1694 u8 i = 0;
1695
1696 for (i = 0; i < sizeof(rtl_channel5g_80m) / sizeof(u8);
1697 ++i)
1698 if (rtl_channel5g_80m[i] == channel)
1699 index = i;
1700
1701 txpower = rtlefuse->txpwr_5g_bw80base[path][index];
1702
1703 if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1704 (rate >= DESC_RATEVHT1SS_MCS0 &&
1705 rate <= DESC_RATEVHT2SS_MCS9))
1706 txpower += rtlefuse->txpwr_5g_bw80diff[path]
1707 [TX_1S];
1708 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1709 (rate >= DESC_RATEVHT2SS_MCS0 &&
1710 rate <= DESC_RATEVHT2SS_MCS9))
1711 txpower += rtlefuse->txpwr_5g_bw80diff[path]
1712 [TX_2S];
1713 }
1714 }
1715
1716
1717 if (rtlefuse->eeprom_regulatory != 2)
1718 powerdiff_byrate = _rtl8822be_phy_get_txpower_by_rate(
1719 hw, (u8)(!in_24g), path, rate);
1720
1721
1722 if (rtlefuse->eeprom_regulatory == 1)
1723 limit = _rtl8822be_phy_get_txpower_limit(
1724 hw, (u8)(!in_24g), bandwidth, path, rate,
1725 channel);
1726 else
1727 limit = MAX_POWER_INDEX;
1728
1729
1730 powerdiff_byrate = powerdiff_byrate > limit ? limit : powerdiff_byrate;
1731
1732 txpower += powerdiff_byrate;
1733
1734 if (txpower > MAX_POWER_INDEX)
1735 txpower = MAX_POWER_INDEX;
1736
1737 return txpower;
1738}
1739
1740static void _rtl8822be_phy_set_txpower_index(struct ieee80211_hw *hw,
1741 u8 power_index, u8 path, u8 rate)
1742{
1743 struct rtl_priv *rtlpriv = rtl_priv(hw);
1744 u8 shift = 0;
1745 static u32 index;
1746
1747
1748
1749
1750
1751 shift = rate & 0x03;
1752 index |= ((u32)power_index << (shift * 8));
1753
1754 if (shift == 3) {
1755 rate = rate - 3;
1756
1757 if (!rtlpriv->phydm.ops->phydm_write_txagc(rtlpriv, index, path,
1758 rate)) {
1759 RT_TRACE(rtlpriv, COMP_TXAGC, DBG_LOUD,
1760 "%s(index:%d, rfpath:%d, rate:0x%02x) fail\n",
1761 __func__, index, path, rate);
1762
1763 WARN_ON(1);
1764 }
1765 index = 0;
1766 }
1767}
1768
1769static void _rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
1770 u8 *array, u8 path,
1771 u8 channel, u8 size)
1772{
1773 struct rtl_phy *rtlphy = &(rtl_priv(hw)->phy);
1774 u8 i;
1775 u8 power_index;
1776
1777 for (i = 0; i < size; i++) {
1778 power_index = rtl8822be_get_txpower_index(
1779 hw, path, array[i], rtlphy->current_chan_bw, channel);
1780 _rtl8822be_phy_set_txpower_index(hw, power_index, path,
1781 array[i]);
1782 }
1783}
1784
1785void rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
1786 u8 channel, u8 path)
1787{
1788 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1789
1790
1791
1792
1793
1794
1795 if (rtlhal->current_bandtype == BAND_ON_2_4G)
1796 _rtl8822be_phy_set_txpower_level_by_path(
1797 hw, cck_rates, path, channel, sizes_of_cck_retes);
1798 _rtl8822be_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
1799 sizes_of_ofdm_retes);
1800 _rtl8822be_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
1801 sizes_of_ht_retes_1t);
1802 _rtl8822be_phy_set_txpower_level_by_path(hw, ht_rates_2t, path, channel,
1803 sizes_of_ht_retes_2t);
1804 _rtl8822be_phy_set_txpower_level_by_path(hw, vht_rates_1t, path,
1805 channel, sizes_of_vht_retes);
1806 _rtl8822be_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
1807 channel, sizes_of_vht_retes);
1808}
1809
1810void rtl8822be_phy_set_tx_power_index_by_rs(struct ieee80211_hw *hw, u8 channel,
1811 u8 path, enum rate_section rs)
1812{
1813 struct {
1814 u8 *array;
1815 u8 size;
1816 } rs_ref[MAX_RATE_SECTION] = {
1817 {cck_rates, sizes_of_cck_retes},
1818 {ofdm_rates, sizes_of_ofdm_retes},
1819 {ht_rates_1t, sizes_of_ht_retes_1t},
1820 {ht_rates_2t, sizes_of_ht_retes_2t},
1821 {vht_rates_1t, sizes_of_vht_retes},
1822 {vht_rates_2t, sizes_of_vht_retes},
1823 };
1824
1825 if (rs >= MAX_RATE_SECTION)
1826 return;
1827
1828 _rtl8822be_phy_set_txpower_level_by_path(hw, rs_ref[rs].array, path,
1829 channel, rs_ref[rs].size);
1830}
1831
1832void rtl8822be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1833{
1834 struct rtl_priv *rtlpriv = rtl_priv(hw);
1835 struct rtl_phy *rtlphy = &rtlpriv->phy;
1836 u8 path = 0;
1837
1838 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
1839 rtl8822be_phy_set_txpower_level_by_path(hw, channel, path);
1840}
1841
1842static long _rtl8822be_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
1843 enum wireless_mode wirelessmode,
1844 u8 txpwridx)
1845{
1846 long offset;
1847 long pwrout_dbm;
1848
1849 switch (wirelessmode) {
1850 case WIRELESS_MODE_B:
1851 offset = -7;
1852 break;
1853 case WIRELESS_MODE_G:
1854 case WIRELESS_MODE_N_24G:
1855 offset = -8;
1856 break;
1857 default:
1858 offset = -8;
1859 break;
1860 }
1861 pwrout_dbm = txpwridx / 2 + offset;
1862 return pwrout_dbm;
1863}
1864
1865void rtl8822be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1866{
1867 struct rtl_priv *rtlpriv = rtl_priv(hw);
1868 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1869 enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1870
1871 if (!is_hal_stop(rtlhal)) {
1872 switch (operation) {
1873 case SCAN_OPT_BACKUP_BAND0:
1874 iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1875 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1876 (u8 *)&iotype);
1877
1878 break;
1879 case SCAN_OPT_BACKUP_BAND1:
1880 iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
1881 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1882 (u8 *)&iotype);
1883
1884 break;
1885 case SCAN_OPT_RESTORE:
1886 iotype = IO_CMD_RESUME_DM_BY_SCAN;
1887 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1888 (u8 *)&iotype);
1889 break;
1890 default:
1891 pr_err("Unknown Scan Backup operation.\n");
1892 break;
1893 }
1894 }
1895}
1896
1897static u8 _rtl8822be_phy_get_pri_ch_id(struct rtl_priv *rtlpriv)
1898{
1899 struct rtl_phy *rtlphy = &rtlpriv->phy;
1900 struct rtl_mac *mac = rtl_mac(rtlpriv);
1901 u8 pri_ch_idx = 0;
1902
1903 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
1904
1905 if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER &&
1906 mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER) {
1907 pri_ch_idx = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
1908
1909
1910
1911 } else if ((mac->cur_40_prime_sc ==
1912 HAL_PRIME_CHNL_OFFSET_UPPER) &&
1913 (mac->cur_80_prime_sc ==
1914 HAL_PRIME_CHNL_OFFSET_LOWER)) {
1915 pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ;
1916
1917
1918
1919 } else if ((mac->cur_40_prime_sc ==
1920 HAL_PRIME_CHNL_OFFSET_LOWER) &&
1921 (mac->cur_80_prime_sc ==
1922 HAL_PRIME_CHNL_OFFSET_UPPER)) {
1923 pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ;
1924
1925
1926
1927 } else if ((mac->cur_40_prime_sc ==
1928 HAL_PRIME_CHNL_OFFSET_UPPER) &&
1929 (mac->cur_80_prime_sc ==
1930 HAL_PRIME_CHNL_OFFSET_UPPER)) {
1931 pri_ch_idx = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
1932 } else {
1933 if (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)
1934 pri_ch_idx = VHT_DATA_SC_40_LOWER_OF_80MHZ;
1935 else if (mac->cur_80_prime_sc ==
1936 HAL_PRIME_CHNL_OFFSET_UPPER)
1937 pri_ch_idx = VHT_DATA_SC_40_UPPER_OF_80MHZ;
1938 }
1939 } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
1940
1941 if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER)
1942 pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ;
1943
1944 else if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)
1945 pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ;
1946 else
1947 ;
1948 }
1949
1950 return pri_ch_idx;
1951}
1952
1953void rtl8822be_phy_set_bw_mode(struct ieee80211_hw *hw,
1954 enum nl80211_channel_type ch_type)
1955{
1956 struct rtl_priv *rtlpriv = rtl_priv(hw);
1957 struct rtl_phy *rtlphy = &rtlpriv->phy;
1958 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1959 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1960 u8 tmp_bw = rtlphy->current_chan_bw;
1961
1962 if (rtlphy->set_bwmode_inprogress)
1963 return;
1964 rtlphy->set_bwmode_inprogress = true;
1965 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1966
1967 u8 pri_ch_idx = _rtl8822be_phy_get_pri_ch_id(rtlpriv);
1968
1969
1970 rtlpriv->halmac.ops->halmac_set_bandwidth(
1971 rtlpriv, rtlphy->current_channel, pri_ch_idx,
1972 rtlphy->current_chan_bw);
1973
1974
1975 rtlpriv->phydm.ops->phydm_switch_bandwidth(
1976 rtlpriv, pri_ch_idx, rtlphy->current_chan_bw);
1977
1978 if (!mac->act_scanning)
1979 rtlpriv->phydm.ops->phydm_iq_calibrate(rtlpriv);
1980
1981 rtlphy->set_bwmode_inprogress = false;
1982 } else {
1983 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1984 "FALSE driver sleep or unload\n");
1985 rtlphy->set_bwmode_inprogress = false;
1986 rtlphy->current_chan_bw = tmp_bw;
1987 }
1988}
1989
1990u8 rtl8822be_phy_sw_chnl(struct ieee80211_hw *hw)
1991{
1992 struct rtl_priv *rtlpriv = rtl_priv(hw);
1993 struct rtl_phy *rtlphy = &rtlpriv->phy;
1994 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1995 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1996 u32 timeout = 1000, timecount = 0;
1997 u8 channel = rtlphy->current_channel;
1998
1999 if (rtlphy->sw_chnl_inprogress)
2000 return 0;
2001 if (rtlphy->set_bwmode_inprogress)
2002 return 0;
2003
2004 if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
2005 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
2006 "sw_chnl_inprogress false driver sleep or unload\n");
2007 return 0;
2008 }
2009 while (rtlphy->lck_inprogress && timecount < timeout) {
2010 mdelay(50);
2011 timecount += 50;
2012 }
2013
2014 if (rtlphy->current_channel > 14)
2015 rtlhal->current_bandtype = BAND_ON_5G;
2016 else if (rtlphy->current_channel <= 14)
2017 rtlhal->current_bandtype = BAND_ON_2_4G;
2018
2019 if (rtlpriv->cfg->ops->get_btc_status())
2020 rtlpriv->btcoexist.btc_ops->btc_switch_band_notify(
2021 rtlpriv, rtlhal->current_bandtype, mac->act_scanning);
2022 else
2023 rtlpriv->btcoexist.btc_ops->btc_switch_band_notify_wifi_only(
2024 rtlpriv, rtlhal->current_bandtype, mac->act_scanning);
2025
2026 rtlpriv->phydm.ops->phydm_switch_band(rtlpriv, rtlphy->current_channel);
2027
2028 rtlphy->sw_chnl_inprogress = true;
2029 if (channel == 0)
2030 channel = 1;
2031
2032 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
2033 "switch to channel%d, band type is %d\n",
2034 rtlphy->current_channel, rtlhal->current_bandtype);
2035
2036 rtlpriv->phydm.ops->phydm_switch_channel(rtlpriv,
2037 rtlphy->current_channel);
2038
2039 rtlpriv->phydm.ops->phydm_clear_txpowertracking_state(rtlpriv);
2040
2041 rtl8822be_phy_set_txpower_level(hw, rtlphy->current_channel);
2042
2043 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
2044 rtlphy->sw_chnl_inprogress = false;
2045 return 1;
2046}
2047
2048bool rtl8822be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2049{
2050 struct rtl_priv *rtlpriv = rtl_priv(hw);
2051 struct rtl_phy *rtlphy = &rtlpriv->phy;
2052 bool postprocessing = false;
2053
2054 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2055 "-->IO Cmd(%#x), set_io_inprogress(%d)\n", iotype,
2056 rtlphy->set_io_inprogress);
2057 do {
2058 switch (iotype) {
2059 case IO_CMD_RESUME_DM_BY_SCAN:
2060 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2061 "[IO CMD] Resume DM after scan.\n");
2062 postprocessing = true;
2063 break;
2064 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2065 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
2066 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2067 "[IO CMD] Pause DM before scan.\n");
2068 postprocessing = true;
2069 break;
2070 default:
2071 pr_err("switch case not process\n");
2072 break;
2073 }
2074 } while (false);
2075 if (postprocessing && !rtlphy->set_io_inprogress) {
2076 rtlphy->set_io_inprogress = true;
2077 rtlphy->current_io_type = iotype;
2078 } else {
2079 return false;
2080 }
2081 rtl8822be_phy_set_io(hw);
2082 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2083 return true;
2084}
2085
2086static void rtl8822be_phy_set_io(struct ieee80211_hw *hw)
2087{
2088 struct rtl_priv *rtlpriv = rtl_priv(hw);
2089 struct rtl_phy *rtlphy = &rtlpriv->phy;
2090
2091 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2092 "--->Cmd(%#x), set_io_inprogress(%d)\n",
2093 rtlphy->current_io_type, rtlphy->set_io_inprogress);
2094 switch (rtlphy->current_io_type) {
2095 case IO_CMD_RESUME_DM_BY_SCAN:
2096 break;
2097 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2098 break;
2099 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
2100 break;
2101 default:
2102 pr_err("switch case not process\n");
2103 break;
2104 }
2105 rtlphy->set_io_inprogress = false;
2106 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "(%#x)\n",
2107 rtlphy->current_io_type);
2108}
2109
2110static void rtl8822be_phy_set_rf_on(struct ieee80211_hw *hw)
2111{
2112 struct rtl_priv *rtlpriv = rtl_priv(hw);
2113
2114 rtl_write_byte(rtlpriv, REG_SPS0_CTRL_8822B, 0x2b);
2115 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE3);
2116 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE2);
2117 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE3);
2118 rtl_write_byte(rtlpriv, REG_TXPAUSE_8822B, 0x00);
2119}
2120
2121static bool _rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2122 enum rf_pwrstate rfpwr_state)
2123{
2124 struct rtl_priv *rtlpriv = rtl_priv(hw);
2125 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2126 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2127 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2128 bool bresult = true;
2129 u8 i, queue_id;
2130 struct rtl8192_tx_ring *ring = NULL;
2131
2132 switch (rfpwr_state) {
2133 case ERFON:
2134 if (ppsc->rfpwr_state == ERFOFF &&
2135 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2136 bool rtstatus = false;
2137 u32 initialize_count = 0;
2138
2139 do {
2140 initialize_count++;
2141 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2142 "IPS Set eRf nic enable\n");
2143 rtstatus = rtl_ps_enable_nic(hw);
2144 } while ((!rtstatus) && (initialize_count < 10));
2145 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2146 } else {
2147 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2148 "Set ERFON slept:%d ms\n",
2149 jiffies_to_msecs(jiffies -
2150 ppsc->last_sleep_jiffies));
2151 ppsc->last_awake_jiffies = jiffies;
2152 rtl8822be_phy_set_rf_on(hw);
2153 }
2154 if (mac->link_state == MAC80211_LINKED)
2155 rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2156 else
2157 rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2158 break;
2159 case ERFOFF:
2160 for (queue_id = 0, i = 0;
2161 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2162 ring = &pcipriv->dev.tx_ring[queue_id];
2163 if (queue_id == BEACON_QUEUE ||
2164 skb_queue_len(&ring->queue) == 0) {
2165 queue_id++;
2166 continue;
2167 } else {
2168 RT_TRACE(
2169 rtlpriv, COMP_ERR, DBG_WARNING,
2170 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2171 (i + 1), queue_id,
2172 skb_queue_len(&ring->queue));
2173
2174 udelay(10);
2175 i++;
2176 }
2177 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2178 RT_TRACE(
2179 rtlpriv, COMP_ERR, DBG_WARNING,
2180 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2181 MAX_DOZE_WAITING_TIMES_9x, queue_id,
2182 skb_queue_len(&ring->queue));
2183 break;
2184 }
2185 }
2186
2187 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2188 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2189 "IPS Set eRf nic disable\n");
2190 rtl_ps_disable_nic(hw);
2191 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2192 } else {
2193 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2194 rtlpriv->cfg->ops->led_control(hw,
2195 LED_CTL_NO_LINK);
2196 } else {
2197 rtlpriv->cfg->ops->led_control(
2198 hw, LED_CTL_POWER_OFF);
2199 }
2200 }
2201 break;
2202 default:
2203 pr_err("switch case not process\n");
2204 bresult = false;
2205 break;
2206 }
2207 if (bresult)
2208 ppsc->rfpwr_state = rfpwr_state;
2209 return bresult;
2210}
2211
2212bool rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2213 enum rf_pwrstate rfpwr_state)
2214{
2215 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2216
2217 bool bresult = false;
2218
2219 if (rfpwr_state == ppsc->rfpwr_state)
2220 return bresult;
2221 bresult = _rtl8822be_phy_set_rf_power_state(hw, rfpwr_state);
2222 return bresult;
2223}
2224