1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2016 Realtek Corporation.
7 * wlanfae <wlanfae@realtek.com>
8 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
11 * Larry Finger <Larry.Finger@lwfinger.net>
13 *****************************************************************************/
23 #include "../btcoexist/halbt_precomp.h"
27 static u32 _rtl8822be_phy_calculate_bit_shift(u32 bitmask);
29 _rtl8822be_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
31 static long _rtl8822be_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
32 enum wireless_mode wirelessmode,
34 static void rtl8822be_phy_set_rf_on(struct ieee80211_hw *hw);
35 static void rtl8822be_phy_set_io(struct ieee80211_hw *hw);
37 static u8 cck_rates[] = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M};
38 static u8 sizes_of_cck_retes = 4;
39 static u8 ofdm_rates[] = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
40 DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
41 DESC_RATE48M, DESC_RATE54M};
42 static u8 sizes_of_ofdm_retes = 8;
43 static u8 ht_rates_1t[] = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
44 DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
45 DESC_RATEMCS6, DESC_RATEMCS7};
46 static u8 sizes_of_ht_retes_1t = 8;
47 static u8 ht_rates_2t[] = {DESC_RATEMCS8, DESC_RATEMCS9, DESC_RATEMCS10,
48 DESC_RATEMCS11, DESC_RATEMCS12, DESC_RATEMCS13,
49 DESC_RATEMCS14, DESC_RATEMCS15};
50 static u8 sizes_of_ht_retes_2t = 8;
51 static 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};
56 static 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};
61 static u8 sizes_of_vht_retes = 10;
63 u32 rtl8822be_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
66 struct rtl_priv *rtlpriv = rtl_priv(hw);
67 u32 returnvalue, originalvalue, bitshift;
69 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
71 originalvalue = rtl_read_dword(rtlpriv, regaddr);
72 bitshift = _rtl8822be_phy_calculate_bit_shift(bitmask);
73 returnvalue = (originalvalue & bitmask) >> bitshift;
75 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
76 bitmask, regaddr, originalvalue);
81 void rtl8822be_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
84 struct rtl_priv *rtlpriv = rtl_priv(hw);
85 u32 originalvalue, bitshift;
87 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
88 "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, bitmask,
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));
98 rtl_write_dword(rtlpriv, regaddr, data);
100 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
101 "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, bitmask,
105 u32 rtl8822be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
106 u32 regaddr, u32 bitmask)
108 struct rtl_priv *rtlpriv = rtl_priv(hw);
109 u32 /*original_value,*/ readback_value /*, bitshift*/;
112 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
113 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", regaddr, rfpath,
116 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
118 readback_value = rtlpriv->phydm.ops->phydm_read_rf_reg(
119 rtlpriv, rfpath, regaddr, bitmask);
121 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
123 return readback_value;
126 void rtl8822be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
127 u32 regaddr, u32 bitmask, u32 data)
129 struct rtl_priv *rtlpriv = rtl_priv(hw);
132 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
133 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
134 regaddr, bitmask, data, rfpath);
136 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
138 rtlpriv->phydm.ops->phydm_write_rf_reg(rtlpriv, rfpath, regaddr,
141 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
143 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
144 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
145 regaddr, bitmask, data, rfpath);
148 static u32 _rtl8822be_phy_calculate_bit_shift(u32 bitmask)
152 for (i = 0; i <= 31; i++) {
153 if (((bitmask >> i) & 0x1) == 1)
159 bool rtl8822be_halmac_cb_init_mac_register(struct rtl_priv *rtlpriv)
161 return rtlpriv->phydm.ops->phydm_phy_mac_config(rtlpriv);
164 bool rtl8822be_phy_bb_config(struct ieee80211_hw *hw)
166 bool rtstatus = true;
167 struct rtl_priv *rtlpriv = rtl_priv(hw);
168 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
172 rtstatus = rtlpriv->phydm.ops->phydm_phy_bb_config(rtlpriv);
174 /* write 0x28[6:1] = 0x24[30:25] = CrystalCap */
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);
179 /*rtlphy->reg_837 = rtl_read_byte(rtlpriv, 0x837);*/ /*unused*/
184 bool rtl8822be_phy_rf_config(struct ieee80211_hw *hw)
186 struct rtl_priv *rtlpriv = rtl_priv(hw);
187 struct rtl_phy *rtlphy = &rtlpriv->phy;
189 if (rtlphy->rf_type == RF_1T1R)
190 rtlphy->num_total_rfpath = 1;
192 rtlphy->num_total_rfpath = 2;
194 return rtlpriv->phydm.ops->phydm_phy_rf_config(rtlpriv);
197 bool rtl8822be_halmac_cb_init_bb_rf_register(struct rtl_priv *rtlpriv)
199 struct ieee80211_hw *hw = rtlpriv->hw;
200 enum radio_mask txpath, rxpath;
204 _rtl8822be_phy_init_bb_rf_register_definition(hw);
206 rtlpriv->halmac.ops->halmac_phy_power_switch(rtlpriv, 1);
208 /* beofre bb/rf config */
209 rtlpriv->phydm.ops->phydm_parameter_init(rtlpriv, 0);
211 /* do bb/rf config */
212 if (rtl8822be_phy_bb_config(hw) && rtl8822be_phy_rf_config(hw))
215 /* after bb/rf config */
216 rtlpriv->phydm.ops->phydm_parameter_init(rtlpriv, 1);
218 /* set trx mode (keep it to be last, r17376) */
219 txpath = RF_MASK_A | RF_MASK_B;
220 rxpath = RF_MASK_A | RF_MASK_B;
222 return rtlpriv->phydm.ops->phydm_trx_mode(rtlpriv, txpath, rxpath,
226 static void _rtl8822be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
228 struct rtl_priv *rtlpriv = rtl_priv(hw);
229 struct rtl_phy *rtlphy = &rtlpriv->phy;
231 u8 band, rfpath, txnum, rate;
233 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
234 for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath)
235 for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
236 for (rate = 0; rate < TX_PWR_BY_RATE_NUM_RATE;
238 rtlphy->tx_power_by_rate_offset
239 [band][rfpath][txnum][rate] = 0;
242 static void _rtl8822be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
244 u8 rate_section, u8 txnum,
247 struct rtl_priv *rtlpriv = rtl_priv(hw);
248 struct rtl_phy *rtlphy = &rtlpriv->phy;
250 if (path > RF90_PATH_D) {
251 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
252 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
257 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
258 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
259 "Invalid band %d in phy_SetTxPowerByRatBase()\n",
264 if (rate_section >= MAX_RATE_SECTION ||
265 (band == BAND_ON_5G && rate_section == CCK)) {
267 rtlpriv, COMP_INIT, DBG_LOUD,
268 "Invalid rate_section %d in phy_SetTxPowerByRatBase()\n",
273 if (band == BAND_ON_2_4G)
274 rtlphy->txpwr_by_rate_base_24g[path][txnum][rate_section] =
276 else /* BAND_ON_5G */
277 rtlphy->txpwr_by_rate_base_5g[path][txnum][rate_section - 1] =
281 static u8 _rtl8822be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
282 u8 band, u8 path, u8 txnum,
285 struct rtl_priv *rtlpriv = rtl_priv(hw);
286 struct rtl_phy *rtlphy = &rtlpriv->phy;
289 if (path > RF90_PATH_D) {
290 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
291 "Invalid Rf Path %d in phy_GetTxPowerByRatBase()\n",
296 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
297 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
298 "Invalid band %d in phy_GetTxPowerByRatBase()\n",
303 if (rate_section >= MAX_RATE_SECTION ||
304 (band == BAND_ON_5G && rate_section == CCK)) {
306 rtlpriv, COMP_INIT, DBG_LOUD,
307 "Invalid rate_section %d in phy_GetTxPowerByRatBase()\n",
312 if (band == BAND_ON_2_4G)
313 value = rtlphy->txpwr_by_rate_base_24g[path][txnum]
315 else /* BAND_ON_5G */
316 value = rtlphy->txpwr_by_rate_base_5g[path][txnum]
322 static void _rtl8822be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
324 struct rtl_priv *rtlpriv = rtl_priv(hw);
325 struct rtl_phy *rtlphy = &rtlpriv->phy;
328 enum rtl_desc_rate rate;
329 enum rate_section section;
330 } rate_sec_base[] = {
332 {DESC_RATE54M, OFDM},
333 {DESC_RATEMCS7, HT_MCS0_MCS7},
334 {DESC_RATEMCS15, HT_MCS8_MCS15},
335 {DESC_RATEVHT1SS_MCS7, VHT_1SSMCS0_1SSMCS9},
336 {DESC_RATEVHT2SS_MCS7, VHT_2SSMCS0_2SSMCS9},
339 u8 band, path, rs, tx_num, base;
342 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
343 for (path = RF90_PATH_A; path <= RF90_PATH_B; path++) {
344 for (rs = 0; rs < MAX_RATE_SECTION; rs++) {
345 rate = rate_sec_base[rs].rate;
346 section = rate_sec_base[rs].section;
348 if (IS_1T_RATE(rate))
353 if (band == BAND_ON_5G &&
354 RX_HAL_IS_CCK_RATE(rate))
357 base = rtlphy->tx_power_by_rate_offset
358 [band][path][tx_num][rate];
359 _rtl8822be_phy_set_txpower_by_rate_base(
360 hw, band, path, section, tx_num, base);
366 static void __rtl8822be_phy_cross_reference_core(struct ieee80211_hw *hw,
367 u8 regulation, u8 bw,
370 struct rtl_priv *rtlpriv = rtl_priv(hw);
371 struct rtl_phy *rtlphy = &rtlpriv->phy;
373 s8 pwrlmt, ref_pwrlmt;
375 for (rs = 0; rs < MAX_RATE_SECTION_NUM; ++rs) {
376 /*5G 20M 40M VHT and HT can cross reference*/
377 if (bw != HT_CHANNEL_WIDTH_20 && bw != HT_CHANNEL_WIDTH_20_40)
380 if (rs == HT_MCS0_MCS7)
381 ref_rs = VHT_1SSMCS0_1SSMCS9;
382 else if (rs == HT_MCS8_MCS15)
383 ref_rs = VHT_2SSMCS0_2SSMCS9;
384 else if (rs == VHT_1SSMCS0_1SSMCS9)
385 ref_rs = HT_MCS0_MCS7;
386 else if (rs == VHT_2SSMCS0_2SSMCS9)
387 ref_rs = HT_MCS8_MCS15;
391 ref_pwrlmt = rtlphy->txpwr_limit_5g[regulation][bw][ref_rs]
392 [channel][RF90_PATH_A];
393 if (ref_pwrlmt == MAX_POWER_INDEX)
396 pwrlmt = rtlphy->txpwr_limit_5g[regulation][bw][rs][channel]
398 if (pwrlmt != MAX_POWER_INDEX)
401 rtlphy->txpwr_limit_5g[regulation][bw][rs][channel]
402 [RF90_PATH_A] = ref_pwrlmt;
407 _rtl8822be_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw)
409 u8 regulation, bw, channel;
411 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
412 for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
413 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G;
415 __rtl8822be_phy_cross_reference_core(
416 hw, regulation, bw, channel);
422 static void __rtl8822be_txpwr_limit_to_index_2g(struct ieee80211_hw *hw,
423 u8 regulation, u8 bw,
426 struct rtl_priv *rtlpriv = rtl_priv(hw);
427 struct rtl_phy *rtlphy = &rtlpriv->phy;
428 u8 bw40_pwr_base_dbm2_4G;
431 enum rf_tx_num txnum;
435 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM;
437 /* obtain the base dBm values in 2.4G band
438 * CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15
442 rtlphy->txpwr_limit_2_4g[regulation][bw][rate_section]
443 [channel][RF90_PATH_A];
444 txnum = IS_1T_RATESEC(rate_section) ? RF_1TX : RF_2TX;
446 if (temp_pwrlmt == MAX_POWER_INDEX)
449 for (rf_path = RF90_PATH_A; rf_path < MAX_RF_PATH_NUM;
451 bw40_pwr_base_dbm2_4G =
452 _rtl8822be_phy_get_txpower_by_rate_base(
453 hw, BAND_ON_2_4G, rf_path, txnum,
456 temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G;
457 rtlphy->txpwr_limit_2_4g[regulation][bw][rate_section]
458 [channel][rf_path] = temp_value;
461 rtlpriv, COMP_INIT, DBG_TRACE,
462 "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",
463 regulation, bw, rate_section, channel,
464 rtlphy->txpwr_limit_2_4g[regulation][bw]
465 [rate_section][channel]
467 (temp_pwrlmt == 63) ? 0 : temp_pwrlmt / 2,
468 channel, rf_path, bw40_pwr_base_dbm2_4G);
473 static void __rtl8822be_txpwr_limit_to_index_5g(struct ieee80211_hw *hw,
474 u8 regulation, u8 bw,
477 struct rtl_priv *rtlpriv = rtl_priv(hw);
478 struct rtl_phy *rtlphy = &rtlpriv->phy;
479 u8 bw40_pwr_base_dbm5G;
482 enum rf_tx_num txnum;
486 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM;
488 /* obtain the base dBm values in 5G band
489 * OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15,
490 * VHT => 1SSMCS7, VHT 2T => 2SSMCS7
494 rtlphy->txpwr_limit_5g[regulation][bw][rate_section]
495 [channel][RF90_PATH_A];
496 txnum = IS_1T_RATESEC(rate_section) ? RF_1TX : RF_2TX;
498 if (temp_pwrlmt == MAX_POWER_INDEX)
501 for (rf_path = RF90_PATH_A; rf_path < MAX_RF_PATH_NUM;
503 bw40_pwr_base_dbm5G =
504 _rtl8822be_phy_get_txpower_by_rate_base(
505 hw, BAND_ON_5G, rf_path, txnum,
508 temp_value = temp_pwrlmt - bw40_pwr_base_dbm5G;
509 rtlphy->txpwr_limit_5g[regulation][bw][rate_section]
510 [channel][rf_path] = temp_value;
513 rtlpriv, COMP_INIT, DBG_TRACE,
514 "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfPath %d] %d)\n",
515 regulation, bw, rate_section, channel,
516 rtlphy->txpwr_limit_5g[regulation][bw]
517 [rate_section][channel]
519 temp_pwrlmt, channel, rf_path,
520 bw40_pwr_base_dbm5G);
526 _rtl8822be_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw)
528 struct rtl_priv *rtlpriv = rtl_priv(hw);
529 u8 regulation, bw, channel;
531 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "=====> %s()\n", __func__);
533 _rtl8822be_phy_cross_reference_ht_and_vht_txpower_limit(hw);
535 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
536 for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) {
537 for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G;
539 __rtl8822be_txpwr_limit_to_index_2g(
540 hw, regulation, bw, channel);
545 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
546 for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
547 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G;
549 __rtl8822be_txpwr_limit_to_index_5g(
550 hw, regulation, bw, channel);
554 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<===== %s()\n", __func__);
557 static void _rtl8822be_phy_init_txpower_limit(struct ieee80211_hw *hw)
559 struct rtl_priv *rtlpriv = rtl_priv(hw);
560 struct rtl_phy *rtlphy = &rtlpriv->phy;
563 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "=====> %s()!\n", __func__);
565 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
566 for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j)
567 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
568 for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
569 for (l = 0; l < MAX_RF_PATH_NUM; ++l)
570 rtlphy->txpwr_limit_2_4g[i][j]
575 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
576 for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j)
577 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
578 for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m)
579 for (l = 0; l < MAX_RF_PATH_NUM; ++l)
580 rtlphy->txpwr_limit_5g[i][j][k]
585 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<===== %s()!\n", __func__);
589 _rtl8822be_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw)
591 struct rtl_priv *rtlpriv = rtl_priv(hw);
592 struct rtl_phy *rtlphy = &rtlpriv->phy;
594 u8 base = 0, i = 0, value = 0, band = 0, path = 0, txnum = 0;
596 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) {
597 for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
598 for (txnum = RF_1TX; txnum <= RF_2TX; ++txnum) {
600 base = rtlphy->tx_power_by_rate_offset
603 for (i = 0; i < sizeof(cck_rates); ++i) {
604 value = rtlphy->tx_power_by_rate_offset
607 rtlphy->tx_power_by_rate_offset
609 [cck_rates[i]] = value - base;
613 base = rtlphy->tx_power_by_rate_offset
616 for (i = 0; i < sizeof(ofdm_rates); ++i) {
617 value = rtlphy->tx_power_by_rate_offset
620 rtlphy->tx_power_by_rate_offset
622 [ofdm_rates[i]] = value - base;
626 base = rtlphy->tx_power_by_rate_offset
629 for (i = 0; i < sizeof(ht_rates_1t); ++i) {
630 value = rtlphy->tx_power_by_rate_offset
633 rtlphy->tx_power_by_rate_offset
635 [ht_rates_1t[i]] = value - base;
639 base = rtlphy->tx_power_by_rate_offset
642 for (i = 0; i < sizeof(ht_rates_2t); ++i) {
643 value = rtlphy->tx_power_by_rate_offset
646 rtlphy->tx_power_by_rate_offset
648 [ht_rates_2t[i]] = value - base;
652 base = rtlphy->tx_power_by_rate_offset
654 [DESC_RATEVHT1SS_MCS7];
655 for (i = 0; i < sizeof(vht_rates_1t); ++i) {
656 value = rtlphy->tx_power_by_rate_offset
659 rtlphy->tx_power_by_rate_offset
666 base = rtlphy->tx_power_by_rate_offset
668 [DESC_RATEVHT2SS_MCS7];
669 for (i = 0; i < sizeof(vht_rates_2t); ++i) {
670 value = rtlphy->tx_power_by_rate_offset
673 rtlphy->tx_power_by_rate_offset
682 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, "<===%s()\n", __func__);
686 _rtl8822be_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
688 /* copy rate_section from
689 * tx_power_by_rate_offset[][rate] to txpwr_by_rate_base_24g/_5g[][rs]
691 _rtl8822be_phy_store_txpower_by_rate_base(hw);
693 /* convert tx_power_by_rate_offset[] to relative value */
694 _rtl8822be_phy_convert_txpower_dbm_to_relative_value(hw);
697 /* string is in decimal */
698 static bool _rtl8822be_get_integer_from_string(char *str, u8 *pint)
703 while (str[i] != '\0') {
704 if (str[i] >= '0' && str[i] <= '9') {
706 *pint += (str[i] - '0');
716 static bool _rtl8822be_eq_n_byte(u8 *str1, u8 *str2, u32 num)
722 if (str1[num] != str2[num])
728 static char _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
731 struct rtl_priv *rtlpriv = rtl_priv(hw);
732 char channel_index = -1;
735 if (band == BAND_ON_2_4G) {
736 channel_index = channel - 1;
737 } else if (band == BAND_ON_5G) {
738 for (i = 0; i < sizeof(rtl_channel5g) / sizeof(u8); ++i) {
739 if (rtl_channel5g[i] == channel)
743 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s",
747 if (channel_index == -1)
748 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
749 "Invalid Channel %d of Band %d in %s", channel, band,
752 return channel_index;
755 void rtl8822be_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
756 u8 *pband, u8 *pbandwidth,
757 u8 *prate_section, u8 *prf_path,
758 u8 *pchannel, u8 *ppower_limit)
760 struct rtl_priv *rtlpriv = rtl_priv(hw);
761 struct rtl_phy *rtlphy = &rtlpriv->phy;
762 u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
764 char power_limit = 0, prev_power_limit, ret;
766 if (!_rtl8822be_get_integer_from_string((char *)pchannel, &channel) ||
767 !_rtl8822be_get_integer_from_string((char *)ppower_limit,
769 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
770 "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
771 channel, power_limit);
775 power_limit > MAX_POWER_INDEX ? MAX_POWER_INDEX : power_limit;
777 if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
779 else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
781 else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
783 else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
786 if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
788 else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
790 else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
791 _rtl8822be_eq_n_byte(prf_path, (u8 *)("1T"), 2))
792 rate_section = HT_MCS0_MCS7;
793 else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
794 _rtl8822be_eq_n_byte(prf_path, (u8 *)("2T"), 2))
795 rate_section = HT_MCS8_MCS15;
796 else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
797 _rtl8822be_eq_n_byte(prf_path, (u8 *)("1T"), 2))
798 rate_section = VHT_1SSMCS0_1SSMCS9;
799 else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
800 _rtl8822be_eq_n_byte(prf_path, (u8 *)("2T"), 2))
801 rate_section = VHT_2SSMCS0_2SSMCS9;
803 if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
804 bandwidth = HT_CHANNEL_WIDTH_20;
805 else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
806 bandwidth = HT_CHANNEL_WIDTH_20_40;
807 else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
808 bandwidth = HT_CHANNEL_WIDTH_80;
809 else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
812 if (_rtl8822be_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
813 ret = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_2_4G,
822 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
823 [rate_section][channel_index]
826 if (power_limit < prev_power_limit)
827 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
828 [rate_section][channel_index]
829 [RF90_PATH_A] = power_limit;
831 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
832 "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
833 regulation, bandwidth, rate_section, channel_index,
834 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
835 [rate_section][channel_index]
837 } else if (_rtl8822be_eq_n_byte(pband, (u8 *)("5G"), 2)) {
838 ret = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_5G,
847 rtlphy->txpwr_limit_5g[regulation][bandwidth]
848 [rate_section][channel_index]
851 if (power_limit < prev_power_limit)
852 rtlphy->txpwr_limit_5g[regulation][bandwidth]
853 [rate_section][channel_index]
854 [RF90_PATH_A] = power_limit;
856 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
857 "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
858 regulation, bandwidth, rate_section, channel,
859 rtlphy->txpwr_limit_5g[regulation][bandwidth]
860 [rate_section][channel_index]
864 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
865 "Cannot recognize the band info in %s\n", pband);
870 bool rtl8822be_load_txpower_by_rate(struct ieee80211_hw *hw)
872 struct rtl_priv *rtlpriv = rtl_priv(hw);
873 bool rtstatus = true;
875 _rtl8822be_phy_init_tx_power_by_rate(hw);
877 rtstatus = rtlpriv->phydm.ops->phydm_load_txpower_by_rate(rtlpriv);
880 pr_err("BB_PG Reg Fail!!\n");
884 _rtl8822be_phy_txpower_by_rate_configuration(hw);
889 bool rtl8822be_load_txpower_limit(struct ieee80211_hw *hw)
891 struct rtl_priv *rtlpriv = rtl_priv(hw);
892 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
893 bool rtstatus = true;
895 _rtl8822be_phy_init_txpower_limit(hw);
897 if (rtlefuse->eeprom_regulatory == 1)
902 rtstatus = rtlpriv->phydm.ops->phydm_load_txpower_limit(rtlpriv);
905 pr_err("RF TxPwr Limit Fail!!\n");
909 _rtl8822be_phy_convert_txpower_limit_to_power_index(hw);
914 static void _rtl8822be_get_rate_values_of_tx_power_by_rate(
915 struct ieee80211_hw *hw, u32 reg_addr, u32 bit_mask, u32 value,
916 u8 *rate, s8 *pwr_by_rate_val, u8 *rate_num)
918 struct rtl_priv *rtlpriv = rtl_priv(hw);
919 u8 /*index = 0,*/ i = 0;
922 case 0xE00: /*rTxAGC_A_Rate18_06:*/
923 case 0x830: /*rTxAGC_B_Rate18_06:*/
924 rate[0] = DESC_RATE6M;
925 rate[1] = DESC_RATE9M;
926 rate[2] = DESC_RATE12M;
927 rate[3] = DESC_RATE18M;
928 for (i = 0; i < 4; ++i) {
930 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
931 ((value >> (i * 8)) & 0xF));
936 case 0xE04: /*rTxAGC_A_Rate54_24:*/
937 case 0x834: /*rTxAGC_B_Rate54_24:*/
938 rate[0] = DESC_RATE24M;
939 rate[1] = DESC_RATE36M;
940 rate[2] = DESC_RATE48M;
941 rate[3] = DESC_RATE54M;
942 for (i = 0; i < 4; ++i) {
944 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
945 ((value >> (i * 8)) & 0xF));
950 case 0xE08: /*rTxAGC_A_CCK1_Mcs32:*/
951 rate[0] = DESC_RATE1M;
952 pwr_by_rate_val[0] = (s8)((((value >> (8 + 4)) & 0xF)) * 10 +
953 ((value >> 8) & 0xF));
957 case 0x86C: /*rTxAGC_B_CCK11_A_CCK2_11:*/
958 if (bit_mask == 0xffffff00) {
959 rate[0] = DESC_RATE2M;
960 rate[1] = DESC_RATE5_5M;
961 rate[2] = DESC_RATE11M;
962 for (i = 1; i < 4; ++i) {
963 pwr_by_rate_val[i - 1] = (s8)(
964 (((value >> (i * 8 + 4)) & 0xF)) * 10 +
965 ((value >> (i * 8)) & 0xF));
968 } else if (bit_mask == 0x000000ff) {
969 rate[0] = DESC_RATE11M;
970 pwr_by_rate_val[0] = (s8)((((value >> 4) & 0xF)) * 10 +
976 case 0xE10: /*rTxAGC_A_Mcs03_Mcs00:*/
977 case 0x83C: /*rTxAGC_B_Mcs03_Mcs00:*/
978 rate[0] = DESC_RATEMCS0;
979 rate[1] = DESC_RATEMCS1;
980 rate[2] = DESC_RATEMCS2;
981 rate[3] = DESC_RATEMCS3;
982 for (i = 0; i < 4; ++i) {
984 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
985 ((value >> (i * 8)) & 0xF));
990 case 0xE14: /*rTxAGC_A_Mcs07_Mcs04:*/
991 case 0x848: /*rTxAGC_B_Mcs07_Mcs04:*/
992 rate[0] = DESC_RATEMCS4;
993 rate[1] = DESC_RATEMCS5;
994 rate[2] = DESC_RATEMCS6;
995 rate[3] = DESC_RATEMCS7;
996 for (i = 0; i < 4; ++i) {
998 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
999 ((value >> (i * 8)) & 0xF));
1004 case 0xE18: /*rTxAGC_A_Mcs11_Mcs08:*/
1005 case 0x84C: /*rTxAGC_B_Mcs11_Mcs08:*/
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_val[i] =
1012 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1013 ((value >> (i * 8)) & 0xF));
1018 case 0xE1C: /*rTxAGC_A_Mcs15_Mcs12:*/
1019 case 0x868: /*rTxAGC_B_Mcs15_Mcs12:*/
1020 rate[0] = DESC_RATEMCS12;
1021 rate[1] = DESC_RATEMCS13;
1022 rate[2] = DESC_RATEMCS14;
1023 rate[3] = DESC_RATEMCS15;
1024 for (i = 0; i < 4; ++i) {
1025 pwr_by_rate_val[i] =
1026 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1027 ((value >> (i * 8)) & 0xF));
1033 case 0x838: /*rTxAGC_B_CCK1_55_Mcs32:*/
1034 rate[0] = DESC_RATE1M;
1035 rate[1] = DESC_RATE2M;
1036 rate[2] = DESC_RATE5_5M;
1037 for (i = 1; i < 4; ++i) {
1038 pwr_by_rate_val[i - 1] =
1039 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1040 ((value >> (i * 8)) & 0xF));
1049 rate[0] = DESC_RATE1M;
1050 rate[1] = DESC_RATE2M;
1051 rate[2] = DESC_RATE5_5M;
1052 rate[3] = DESC_RATE11M;
1053 for (i = 0; i < 4; ++i) {
1054 pwr_by_rate_val[i] =
1055 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1056 ((value >> (i * 8)) & 0xF));
1065 rate[0] = DESC_RATE6M;
1066 rate[1] = DESC_RATE9M;
1067 rate[2] = DESC_RATE12M;
1068 rate[3] = DESC_RATE18M;
1069 for (i = 0; i < 4; ++i) {
1070 pwr_by_rate_val[i] =
1071 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1072 ((value >> (i * 8)) & 0xF));
1081 rate[0] = DESC_RATE24M;
1082 rate[1] = DESC_RATE36M;
1083 rate[2] = DESC_RATE48M;
1084 rate[3] = DESC_RATE54M;
1085 for (i = 0; i < 4; ++i) {
1086 pwr_by_rate_val[i] =
1087 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1088 ((value >> (i * 8)) & 0xF));
1097 rate[0] = DESC_RATEMCS0;
1098 rate[1] = DESC_RATEMCS1;
1099 rate[2] = DESC_RATEMCS2;
1100 rate[3] = DESC_RATEMCS3;
1101 for (i = 0; i < 4; ++i) {
1102 pwr_by_rate_val[i] =
1103 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1104 ((value >> (i * 8)) & 0xF));
1113 rate[0] = DESC_RATEMCS4;
1114 rate[1] = DESC_RATEMCS5;
1115 rate[2] = DESC_RATEMCS6;
1116 rate[3] = DESC_RATEMCS7;
1117 for (i = 0; i < 4; ++i) {
1118 pwr_by_rate_val[i] =
1119 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1120 ((value >> (i * 8)) & 0xF));
1129 rate[0] = DESC_RATEMCS8;
1130 rate[1] = DESC_RATEMCS9;
1131 rate[2] = DESC_RATEMCS10;
1132 rate[3] = DESC_RATEMCS11;
1133 for (i = 0; i < 4; ++i) {
1134 pwr_by_rate_val[i] =
1135 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1136 ((value >> (i * 8)) & 0xF));
1145 rate[0] = DESC_RATEMCS12;
1146 rate[1] = DESC_RATEMCS13;
1147 rate[2] = DESC_RATEMCS14;
1148 rate[3] = DESC_RATEMCS15;
1149 for (i = 0; i < 4; ++i) {
1150 pwr_by_rate_val[i] =
1151 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1152 ((value >> (i * 8)) & 0xF));
1161 rate[0] = DESC_RATEVHT1SS_MCS0;
1162 rate[1] = DESC_RATEVHT1SS_MCS1;
1163 rate[2] = DESC_RATEVHT1SS_MCS2;
1164 rate[3] = DESC_RATEVHT1SS_MCS3;
1165 for (i = 0; i < 4; ++i) {
1166 pwr_by_rate_val[i] =
1167 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1168 ((value >> (i * 8)) & 0xF));
1177 rate[0] = DESC_RATEVHT1SS_MCS4;
1178 rate[1] = DESC_RATEVHT1SS_MCS5;
1179 rate[2] = DESC_RATEVHT1SS_MCS6;
1180 rate[3] = DESC_RATEVHT1SS_MCS7;
1181 for (i = 0; i < 4; ++i) {
1182 pwr_by_rate_val[i] =
1183 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1184 ((value >> (i * 8)) & 0xF));
1193 rate[0] = DESC_RATEVHT1SS_MCS8;
1194 rate[1] = DESC_RATEVHT1SS_MCS9;
1195 rate[2] = DESC_RATEVHT2SS_MCS0;
1196 rate[3] = DESC_RATEVHT2SS_MCS1;
1197 for (i = 0; i < 4; ++i) {
1198 pwr_by_rate_val[i] =
1199 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1200 ((value >> (i * 8)) & 0xF));
1209 rate[0] = DESC_RATEVHT2SS_MCS2;
1210 rate[1] = DESC_RATEVHT2SS_MCS3;
1211 rate[2] = DESC_RATEVHT2SS_MCS4;
1212 rate[3] = DESC_RATEVHT2SS_MCS5;
1213 for (i = 0; i < 4; ++i) {
1214 pwr_by_rate_val[i] =
1215 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1216 ((value >> (i * 8)) & 0xF));
1225 rate[0] = DESC_RATEVHT2SS_MCS6;
1226 rate[1] = DESC_RATEVHT2SS_MCS7;
1227 rate[2] = DESC_RATEVHT2SS_MCS8;
1228 rate[3] = DESC_RATEVHT2SS_MCS9;
1229 for (i = 0; i < 4; ++i) {
1230 pwr_by_rate_val[i] =
1231 (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1232 ((value >> (i * 8)) & 0xF));
1238 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1239 "Invalid reg_addr 0x%x in %s()\n", reg_addr, __func__);
1244 void rtl8822be_store_tx_power_by_rate(struct ieee80211_hw *hw, u32 band,
1245 u32 rfpath, u32 txnum, u32 regaddr,
1246 u32 bitmask, u32 data)
1248 struct rtl_priv *rtlpriv = rtl_priv(hw);
1249 struct rtl_phy *rtlphy = &rtlpriv->phy;
1250 u8 i = 0, rates[4] = {0}, rate_num = 0;
1251 s8 pwr_by_rate_val[4] = {0};
1253 _rtl8822be_get_rate_values_of_tx_power_by_rate(
1254 hw, regaddr, bitmask, data, rates, pwr_by_rate_val, &rate_num);
1256 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
1257 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n",
1259 band = BAND_ON_2_4G;
1261 if (rfpath >= MAX_RF_PATH) {
1262 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n",
1264 rfpath = MAX_RF_PATH - 1;
1266 if (txnum >= MAX_RF_PATH) {
1267 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n",
1269 txnum = MAX_RF_PATH - 1;
1272 for (i = 0; i < rate_num; ++i) {
1273 u8 rate_idx = rates[i];
1275 if (IS_1T_RATE(rates[i]))
1277 else if (IS_2T_RATE(rates[i]))
1282 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_idx] =
1286 rtlpriv, COMP_INIT, DBG_LOUD,
1287 "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][rate_idx %d] = 0x%x\n",
1288 band, rfpath, txnum, rate_idx,
1289 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum]
1295 _rtl8822be_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
1297 struct rtl_priv *rtlpriv = rtl_priv(hw);
1298 struct rtl_phy *rtlphy = &rtlpriv->phy;
1300 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
1301 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
1303 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
1304 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
1306 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
1307 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
1309 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8822B;
1310 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8822B;
1312 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8822BE;
1313 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8822BE;
1315 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8822B;
1316 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8822B;
1318 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8822B;
1319 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8822B;
1322 void rtl8822be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
1324 struct rtl_priv *rtlpriv = rtl_priv(hw);
1325 struct rtl_phy *rtlphy = &rtlpriv->phy;
1329 txpwr_level = rtlphy->cur_cck_txpwridx;
1330 txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
1332 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
1333 if (_rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
1335 txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
1337 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
1338 if (_rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
1339 txpwr_level) > txpwr_dbm)
1340 txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(
1341 hw, WIRELESS_MODE_N_24G, txpwr_level);
1342 *powerlevel = txpwr_dbm;
1345 static bool _rtl8822be_phy_get_chnl_index(u8 channel, u8 *chnl_index)
1347 u8 rtl_channel5g[CHANNEL_MAX_NUMBER_5G] = {
1348 36, 38, 40, 42, 44, 46, 48, /* Band 1 */
1349 52, 54, 56, 58, 60, 62, 64, /* Band 2 */
1350 100, 102, 104, 106, 108, 110, 112, /* Band 3 */
1351 116, 118, 120, 122, 124, 126, 128, /* Band 3 */
1352 132, 134, 136, 138, 140, 142, 144, /* Band 3 */
1353 149, 151, 153, 155, 157, 159, 161, /* Band 4 */
1354 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */
1358 if (channel <= 14) {
1360 *chnl_index = channel - 1;
1364 for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
1365 if (rtl_channel5g[i] == channel) {
1374 static char _rtl8822be_phy_get_world_wide_limit(char *limit_table)
1376 char min = limit_table[0];
1379 for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1380 if (limit_table[i] < min)
1381 min = limit_table[i];
1386 static char _rtl8822be_phy_get_txpower_limit(struct ieee80211_hw *hw, u8 band,
1387 enum ht_channel_width bandwidth,
1388 enum radio_path rf_path, u8 rate,
1391 struct rtl_priv *rtlpriv = rtl_priv(hw);
1392 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
1393 struct rtl_phy *rtlphy = &rtlpriv->phy;
1394 short regulation = -1, rate_section = -1, channel_index = -1;
1395 char power_limit = MAX_POWER_INDEX;
1397 if (rtlefuse->eeprom_regulatory == 2)
1398 return MAX_POWER_INDEX;
1400 regulation = TXPWR_LMT_WW;
1418 rate_section = OFDM;
1429 rate_section = HT_MCS0_MCS7;
1434 case DESC_RATEMCS10:
1435 case DESC_RATEMCS11:
1436 case DESC_RATEMCS12:
1437 case DESC_RATEMCS13:
1438 case DESC_RATEMCS14:
1439 case DESC_RATEMCS15:
1440 rate_section = HT_MCS8_MCS15;
1443 case DESC_RATEVHT1SS_MCS0:
1444 case DESC_RATEVHT1SS_MCS1:
1445 case DESC_RATEVHT1SS_MCS2:
1446 case DESC_RATEVHT1SS_MCS3:
1447 case DESC_RATEVHT1SS_MCS4:
1448 case DESC_RATEVHT1SS_MCS5:
1449 case DESC_RATEVHT1SS_MCS6:
1450 case DESC_RATEVHT1SS_MCS7:
1451 case DESC_RATEVHT1SS_MCS8:
1452 case DESC_RATEVHT1SS_MCS9:
1453 rate_section = VHT_1SSMCS0_1SSMCS9;
1456 case DESC_RATEVHT2SS_MCS0:
1457 case DESC_RATEVHT2SS_MCS1:
1458 case DESC_RATEVHT2SS_MCS2:
1459 case DESC_RATEVHT2SS_MCS3:
1460 case DESC_RATEVHT2SS_MCS4:
1461 case DESC_RATEVHT2SS_MCS5:
1462 case DESC_RATEVHT2SS_MCS6:
1463 case DESC_RATEVHT2SS_MCS7:
1464 case DESC_RATEVHT2SS_MCS8:
1465 case DESC_RATEVHT2SS_MCS9:
1466 rate_section = VHT_2SSMCS0_2SSMCS9;
1470 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Wrong rate 0x%x\n",
1475 if (band == BAND_ON_5G && rate_section == 0)
1476 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1477 "Wrong rate 0x%x: No CCK in 5G Band\n", rate);
1479 /* workaround for wrong index combination to obtain tx power limit,
1480 * OFDM only exists in BW 20M
1482 if (rate_section == 1)
1485 /* workaround for wrong index combination to obtain tx power limit,
1486 * CCK table will only be given in BW 20M
1488 if (rate_section == 0)
1491 /* workaround for wrong indxe combination to obtain tx power limit,
1492 * HT on 80M will reference to HT on 40M
1494 if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
1498 if (band == BAND_ON_2_4G)
1499 channel_index = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(
1500 hw, BAND_ON_2_4G, channel);
1501 else if (band == BAND_ON_5G)
1502 channel_index = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(
1503 hw, BAND_ON_5G, channel);
1504 else if (band == BAND_ON_BOTH)
1505 ; /* BAND_ON_BOTH don't care temporarily */
1507 if (band >= BANDMAX || regulation == -1 || bandwidth == -1 ||
1508 rate_section == -1 || channel_index == -1) {
1510 rtlpriv, COMP_POWER, DBG_LOUD,
1511 "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
1512 band, regulation, bandwidth, rf_path, rate_section,
1514 return MAX_POWER_INDEX;
1517 if (band == BAND_ON_2_4G) {
1518 char limits[10] = {0};
1521 for (i = 0; i < 4; ++i)
1522 limits[i] = rtlphy->txpwr_limit_2_4g[i][bandwidth]
1528 (regulation == TXPWR_LMT_WW) ?
1529 _rtl8822be_phy_get_world_wide_limit(limits) :
1530 rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1535 } else if (band == BAND_ON_5G) {
1536 char limits[10] = {0};
1539 for (i = 0; i < MAX_REGULATION_NUM; ++i)
1541 rtlphy->txpwr_limit_5g[i][bandwidth]
1543 [channel_index][rf_path];
1546 (regulation == TXPWR_LMT_WW) ?
1547 _rtl8822be_phy_get_world_wide_limit(limits) :
1548 rtlphy->txpwr_limit_5g[regulation]
1551 [channel_index][rf_path];
1553 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1554 "No power limit table of the specified band\n");
1561 _rtl8822be_phy_get_txpower_by_rate(struct ieee80211_hw *hw, u8 band, u8 path,
1562 u8 rate /* enum rtl_desc8822b_rate */)
1564 struct rtl_priv *rtlpriv = rtl_priv(hw);
1565 struct rtl_phy *rtlphy = &rtlpriv->phy;
1567 char tx_pwr_diff = 0;
1569 if (band != BAND_ON_2_4G && band != BAND_ON_5G)
1572 if (path > RF90_PATH_B)
1575 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1576 (rate >= DESC_RATEVHT2SS_MCS0 && rate <= DESC_RATEVHT2SS_MCS9))
1581 return (char)(rtlphy->tx_power_by_rate_offset[band][path][tx_num]
1586 u8 rtl8822be_get_txpower_index(struct ieee80211_hw *hw, u8 path, u8 rate,
1587 u8 bandwidth, u8 channel)
1589 struct rtl_priv *rtlpriv = rtl_priv(hw);
1590 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1591 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1592 u8 index = (channel - 1);
1594 bool in_24g = false;
1596 char powerdiff_byrate = 0;
1598 if ((rtlhal->current_bandtype == BAND_ON_2_4G &&
1599 (channel > 14 || channel < 1)) ||
1600 (rtlhal->current_bandtype == BAND_ON_5G && channel <= 14)) {
1602 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1603 "Illegal channel!!\n");
1606 /* 1. base tx power */
1607 in_24g = _rtl8822be_phy_get_chnl_index(channel, &index);
1609 if (RX_HAL_IS_CCK_RATE(rate))
1610 txpower = rtlefuse->txpwrlevel_cck[path][index];
1611 else if (rate >= DESC_RATE6M)
1612 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
1614 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1617 if (rate >= DESC_RATE6M && rate <= DESC_RATE54M &&
1618 !RX_HAL_IS_CCK_RATE(rate))
1619 txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
1621 if (bandwidth == HT_CHANNEL_WIDTH_20) {
1622 if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1623 (rate >= DESC_RATEVHT1SS_MCS0 &&
1624 rate <= DESC_RATEVHT2SS_MCS9))
1626 rtlefuse->txpwr_ht20diff[path][TX_1S];
1627 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1628 (rate >= DESC_RATEVHT2SS_MCS0 &&
1629 rate <= DESC_RATEVHT2SS_MCS9))
1631 rtlefuse->txpwr_ht20diff[path][TX_2S];
1632 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1633 if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1634 (rate >= DESC_RATEVHT1SS_MCS0 &&
1635 rate <= DESC_RATEVHT2SS_MCS9))
1637 rtlefuse->txpwr_ht40diff[path][TX_1S];
1638 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1639 (rate >= DESC_RATEVHT2SS_MCS0 &&
1640 rate <= DESC_RATEVHT2SS_MCS9))
1642 rtlefuse->txpwr_ht40diff[path][TX_2S];
1643 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
1644 if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1645 (rate >= DESC_RATEVHT1SS_MCS0 &&
1646 rate <= DESC_RATEVHT2SS_MCS9))
1648 rtlefuse->txpwr_ht40diff[path][TX_1S];
1649 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1650 (rate >= DESC_RATEVHT2SS_MCS0 &&
1651 rate <= DESC_RATEVHT2SS_MCS9))
1653 rtlefuse->txpwr_ht40diff[path][TX_2S];
1657 if (rate >= DESC_RATE6M)
1658 txpower = rtlefuse->txpwr_5g_bw40base[path][index];
1660 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
1663 if (rate >= DESC_RATE6M && rate <= DESC_RATE54M &&
1664 !RX_HAL_IS_CCK_RATE(rate))
1665 txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
1667 if (bandwidth == HT_CHANNEL_WIDTH_20) {
1668 if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1669 (rate >= DESC_RATEVHT1SS_MCS0 &&
1670 rate <= DESC_RATEVHT2SS_MCS9))
1671 txpower += rtlefuse->txpwr_5g_bw20diff[path]
1673 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1674 (rate >= DESC_RATEVHT2SS_MCS0 &&
1675 rate <= DESC_RATEVHT2SS_MCS9))
1676 txpower += rtlefuse->txpwr_5g_bw20diff[path]
1678 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1679 if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1680 (rate >= DESC_RATEVHT1SS_MCS0 &&
1681 rate <= DESC_RATEVHT2SS_MCS9))
1682 txpower += rtlefuse->txpwr_5g_bw40diff[path]
1684 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1685 (rate >= DESC_RATEVHT2SS_MCS0 &&
1686 rate <= DESC_RATEVHT2SS_MCS9))
1687 txpower += rtlefuse->txpwr_5g_bw40diff[path]
1689 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
1692 for (i = 0; i < sizeof(rtl_channel5g_80m) / sizeof(u8);
1694 if (rtl_channel5g_80m[i] == channel)
1697 txpower = rtlefuse->txpwr_5g_bw80base[path][index];
1699 if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1700 (rate >= DESC_RATEVHT1SS_MCS0 &&
1701 rate <= DESC_RATEVHT2SS_MCS9))
1702 txpower += rtlefuse->txpwr_5g_bw80diff[path]
1704 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1705 (rate >= DESC_RATEVHT2SS_MCS0 &&
1706 rate <= DESC_RATEVHT2SS_MCS9))
1707 txpower += rtlefuse->txpwr_5g_bw80diff[path]
1712 /* 2. tx power by rate */
1713 if (rtlefuse->eeprom_regulatory != 2)
1714 powerdiff_byrate = _rtl8822be_phy_get_txpower_by_rate(
1715 hw, (u8)(!in_24g), path, rate);
1717 /* 3. tx power limit */
1718 if (rtlefuse->eeprom_regulatory == 1)
1719 limit = _rtl8822be_phy_get_txpower_limit(
1720 hw, (u8)(!in_24g), bandwidth, path, rate,
1723 limit = MAX_POWER_INDEX;
1726 powerdiff_byrate = powerdiff_byrate > limit ? limit : powerdiff_byrate;
1728 txpower += powerdiff_byrate;
1730 if (txpower > MAX_POWER_INDEX)
1731 txpower = MAX_POWER_INDEX;
1736 static void _rtl8822be_phy_set_txpower_index(struct ieee80211_hw *hw,
1737 u8 power_index, u8 path, u8 rate)
1739 struct rtl_priv *rtlpriv = rtl_priv(hw);
1744 * For 8822B, phydm api use 4 bytes txagc value driver must
1745 * combine every four 1 byte to one 4 byte and send to phydm
1747 shift = rate & 0x03;
1748 index |= ((u32)power_index << (shift * 8));
1753 if (!rtlpriv->phydm.ops->phydm_write_txagc(rtlpriv, index, path,
1755 RT_TRACE(rtlpriv, COMP_TXAGC, DBG_LOUD,
1756 "%s(index:%d, rfpath:%d, rate:0x%02x) fail\n",
1757 __func__, index, path, rate);
1765 static void _rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
1767 u8 channel, u8 size)
1769 struct rtl_phy *rtlphy = &(rtl_priv(hw)->phy);
1773 for (i = 0; i < size; i++) {
1774 power_index = rtl8822be_get_txpower_index(
1775 hw, path, array[i], rtlphy->current_chan_bw, channel);
1776 _rtl8822be_phy_set_txpower_index(hw, power_index, path,
1781 void rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
1782 u8 channel, u8 path)
1784 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1787 * Below order is *VERY* important!
1788 * Because _rtl8822be_phy_set_txpower_index() do actually writing
1789 * every four power values.
1791 if (rtlhal->current_bandtype == BAND_ON_2_4G)
1792 _rtl8822be_phy_set_txpower_level_by_path(
1793 hw, cck_rates, path, channel, sizes_of_cck_retes);
1794 _rtl8822be_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
1795 sizes_of_ofdm_retes);
1796 _rtl8822be_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
1797 sizes_of_ht_retes_1t);
1798 _rtl8822be_phy_set_txpower_level_by_path(hw, ht_rates_2t, path, channel,
1799 sizes_of_ht_retes_2t);
1800 _rtl8822be_phy_set_txpower_level_by_path(hw, vht_rates_1t, path,
1801 channel, sizes_of_vht_retes);
1802 _rtl8822be_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
1803 channel, sizes_of_vht_retes);
1806 void rtl8822be_phy_set_tx_power_index_by_rs(struct ieee80211_hw *hw, u8 channel,
1807 u8 path, enum rate_section rs)
1812 } rs_ref[MAX_RATE_SECTION] = {
1813 {cck_rates, sizes_of_cck_retes},
1814 {ofdm_rates, sizes_of_ofdm_retes},
1815 {ht_rates_1t, sizes_of_ht_retes_1t},
1816 {ht_rates_2t, sizes_of_ht_retes_2t},
1817 {vht_rates_1t, sizes_of_vht_retes},
1818 {vht_rates_2t, sizes_of_vht_retes},
1821 if (rs >= MAX_RATE_SECTION)
1824 _rtl8822be_phy_set_txpower_level_by_path(hw, rs_ref[rs].array, path,
1825 channel, rs_ref[rs].size);
1828 void rtl8822be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1830 struct rtl_priv *rtlpriv = rtl_priv(hw);
1831 struct rtl_phy *rtlphy = &rtlpriv->phy;
1834 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
1835 rtl8822be_phy_set_txpower_level_by_path(hw, channel, path);
1838 static long _rtl8822be_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
1839 enum wireless_mode wirelessmode,
1844 switch (wirelessmode) {
1845 case WIRELESS_MODE_B:
1848 case WIRELESS_MODE_G:
1849 case WIRELESS_MODE_N_24G:
1856 return txpwridx / 2 + offset;
1859 void rtl8822be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1861 struct rtl_priv *rtlpriv = rtl_priv(hw);
1862 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1863 enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1865 if (!is_hal_stop(rtlhal)) {
1866 switch (operation) {
1867 case SCAN_OPT_BACKUP_BAND0:
1868 iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1869 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1873 case SCAN_OPT_BACKUP_BAND1:
1874 iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
1875 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1879 case SCAN_OPT_RESTORE:
1880 iotype = IO_CMD_RESUME_DM_BY_SCAN;
1881 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1885 pr_err("Unknown Scan Backup operation.\n");
1891 static u8 _rtl8822be_phy_get_pri_ch_id(struct rtl_priv *rtlpriv)
1893 struct rtl_phy *rtlphy = &rtlpriv->phy;
1894 struct rtl_mac *mac = rtl_mac(rtlpriv);
1897 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
1898 /* primary channel is at lower subband of 80MHz & 40MHz */
1899 if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER &&
1900 mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER) {
1901 pri_ch_idx = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
1902 /* primary channel is at
1903 * lower subband of 80MHz & upper subband of 40MHz
1905 } else if ((mac->cur_40_prime_sc ==
1906 HAL_PRIME_CHNL_OFFSET_UPPER) &&
1907 (mac->cur_80_prime_sc ==
1908 HAL_PRIME_CHNL_OFFSET_LOWER)) {
1909 pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ;
1910 /* primary channel is at
1911 * upper subband of 80MHz & lower subband of 40MHz
1913 } else if ((mac->cur_40_prime_sc ==
1914 HAL_PRIME_CHNL_OFFSET_LOWER) &&
1915 (mac->cur_80_prime_sc ==
1916 HAL_PRIME_CHNL_OFFSET_UPPER)) {
1917 pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ;
1918 /* primary channel is at
1919 * upper subband of 80MHz & upper subband of 40MHz
1921 } else if ((mac->cur_40_prime_sc ==
1922 HAL_PRIME_CHNL_OFFSET_UPPER) &&
1923 (mac->cur_80_prime_sc ==
1924 HAL_PRIME_CHNL_OFFSET_UPPER)) {
1925 pri_ch_idx = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
1927 if (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)
1928 pri_ch_idx = VHT_DATA_SC_40_LOWER_OF_80MHZ;
1929 else if (mac->cur_80_prime_sc ==
1930 HAL_PRIME_CHNL_OFFSET_UPPER)
1931 pri_ch_idx = VHT_DATA_SC_40_UPPER_OF_80MHZ;
1933 } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
1934 /* primary channel is at upper subband of 40MHz */
1935 if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER)
1936 pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ;
1937 /* primary channel is at lower subband of 40MHz */
1938 else if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)
1939 pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ;
1947 void rtl8822be_phy_set_bw_mode(struct ieee80211_hw *hw,
1948 enum nl80211_channel_type ch_type)
1950 struct rtl_priv *rtlpriv = rtl_priv(hw);
1951 struct rtl_phy *rtlphy = &rtlpriv->phy;
1952 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1953 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1954 u8 tmp_bw = rtlphy->current_chan_bw;
1956 if (rtlphy->set_bwmode_inprogress)
1958 rtlphy->set_bwmode_inprogress = true;
1959 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1960 /* get primary channel index */
1961 u8 pri_ch_idx = _rtl8822be_phy_get_pri_ch_id(rtlpriv);
1963 /* 3.1 set MAC register */
1964 rtlpriv->halmac.ops->halmac_set_bandwidth(
1965 rtlpriv, rtlphy->current_channel, pri_ch_idx,
1966 rtlphy->current_chan_bw);
1968 /* 3.2 set BB/RF registet */
1969 rtlpriv->phydm.ops->phydm_switch_bandwidth(
1970 rtlpriv, pri_ch_idx, rtlphy->current_chan_bw);
1972 if (!mac->act_scanning)
1973 rtlpriv->phydm.ops->phydm_iq_calibrate(rtlpriv);
1975 rtlphy->set_bwmode_inprogress = false;
1977 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1978 "FALSE driver sleep or unload\n");
1979 rtlphy->set_bwmode_inprogress = false;
1980 rtlphy->current_chan_bw = tmp_bw;
1984 u8 rtl8822be_phy_sw_chnl(struct ieee80211_hw *hw)
1986 struct rtl_priv *rtlpriv = rtl_priv(hw);
1987 struct rtl_phy *rtlphy = &rtlpriv->phy;
1988 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1989 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1990 u32 timeout = 1000, timecount = 0;
1991 u8 channel = rtlphy->current_channel;
1993 if (rtlphy->sw_chnl_inprogress)
1995 if (rtlphy->set_bwmode_inprogress)
1998 if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
1999 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
2000 "sw_chnl_inprogress false driver sleep or unload\n");
2003 while (rtlphy->lck_inprogress && timecount < timeout) {
2008 if (rtlphy->current_channel > 14)
2009 rtlhal->current_bandtype = BAND_ON_5G;
2010 else if (rtlphy->current_channel <= 14)
2011 rtlhal->current_bandtype = BAND_ON_2_4G;
2013 if (rtlpriv->cfg->ops->get_btc_status())
2014 rtlpriv->btcoexist.btc_ops->btc_switch_band_notify(
2015 rtlpriv, rtlhal->current_bandtype, mac->act_scanning);
2017 rtlpriv->btcoexist.btc_ops->btc_switch_band_notify_wifi_only(
2018 rtlpriv, rtlhal->current_bandtype, mac->act_scanning);
2020 rtlpriv->phydm.ops->phydm_switch_band(rtlpriv, rtlphy->current_channel);
2022 rtlphy->sw_chnl_inprogress = true;
2026 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
2027 "switch to channel%d, band type is %d\n",
2028 rtlphy->current_channel, rtlhal->current_bandtype);
2030 rtlpriv->phydm.ops->phydm_switch_channel(rtlpriv,
2031 rtlphy->current_channel);
2033 rtlpriv->phydm.ops->phydm_clear_txpowertracking_state(rtlpriv);
2035 rtl8822be_phy_set_txpower_level(hw, rtlphy->current_channel);
2037 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
2038 rtlphy->sw_chnl_inprogress = false;
2042 bool rtl8822be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2044 struct rtl_priv *rtlpriv = rtl_priv(hw);
2045 struct rtl_phy *rtlphy = &rtlpriv->phy;
2046 bool postprocessing = false;
2048 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2049 "-->IO Cmd(%#x), set_io_inprogress(%d)\n", iotype,
2050 rtlphy->set_io_inprogress);
2053 case IO_CMD_RESUME_DM_BY_SCAN:
2054 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2055 "[IO CMD] Resume DM after scan.\n");
2056 postprocessing = true;
2058 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2059 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
2060 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2061 "[IO CMD] Pause DM before scan.\n");
2062 postprocessing = true;
2065 pr_err("switch case not process\n");
2069 if (postprocessing && !rtlphy->set_io_inprogress) {
2070 rtlphy->set_io_inprogress = true;
2071 rtlphy->current_io_type = iotype;
2075 rtl8822be_phy_set_io(hw);
2076 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2080 static void rtl8822be_phy_set_io(struct ieee80211_hw *hw)
2082 struct rtl_priv *rtlpriv = rtl_priv(hw);
2083 struct rtl_phy *rtlphy = &rtlpriv->phy;
2085 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2086 "--->Cmd(%#x), set_io_inprogress(%d)\n",
2087 rtlphy->current_io_type, rtlphy->set_io_inprogress);
2088 switch (rtlphy->current_io_type) {
2089 case IO_CMD_RESUME_DM_BY_SCAN:
2091 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2093 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
2096 pr_err("switch case not process\n");
2099 rtlphy->set_io_inprogress = false;
2100 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "(%#x)\n",
2101 rtlphy->current_io_type);
2104 static void rtl8822be_phy_set_rf_on(struct ieee80211_hw *hw)
2106 struct rtl_priv *rtlpriv = rtl_priv(hw);
2108 rtl_write_byte(rtlpriv, REG_SPS0_CTRL_8822B, 0x2b);
2109 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE3);
2110 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE2);
2111 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE3);
2112 rtl_write_byte(rtlpriv, REG_TXPAUSE_8822B, 0x00);
2115 static bool _rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2116 enum rf_pwrstate rfpwr_state)
2118 struct rtl_priv *rtlpriv = rtl_priv(hw);
2119 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2120 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2121 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2122 bool bresult = true;
2124 struct rtl8192_tx_ring *ring = NULL;
2126 switch (rfpwr_state) {
2128 if (ppsc->rfpwr_state == ERFOFF &&
2129 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2130 bool rtstatus = false;
2131 u32 initialize_count = 0;
2135 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2136 "IPS Set eRf nic enable\n");
2137 rtstatus = rtl_ps_enable_nic(hw);
2138 } while ((!rtstatus) && (initialize_count < 10));
2139 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2141 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2142 "Set ERFON slept:%d ms\n",
2143 jiffies_to_msecs(jiffies -
2144 ppsc->last_sleep_jiffies));
2145 ppsc->last_awake_jiffies = jiffies;
2146 rtl8822be_phy_set_rf_on(hw);
2148 if (mac->link_state == MAC80211_LINKED)
2149 rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2151 rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2154 for (queue_id = 0, i = 0;
2155 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2156 ring = &pcipriv->dev.tx_ring[queue_id];
2157 if (queue_id == BEACON_QUEUE ||
2158 skb_queue_len(&ring->queue) == 0) {
2163 rtlpriv, COMP_ERR, DBG_WARNING,
2164 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2166 skb_queue_len(&ring->queue));
2171 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2173 rtlpriv, COMP_ERR, DBG_WARNING,
2174 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2175 MAX_DOZE_WAITING_TIMES_9x, queue_id,
2176 skb_queue_len(&ring->queue));
2181 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2182 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2183 "IPS Set eRf nic disable\n");
2184 rtl_ps_disable_nic(hw);
2185 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2187 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2188 rtlpriv->cfg->ops->led_control(hw,
2191 rtlpriv->cfg->ops->led_control(
2192 hw, LED_CTL_POWER_OFF);
2197 pr_err("switch case not process\n");
2202 ppsc->rfpwr_state = rfpwr_state;
2206 bool rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2207 enum rf_pwrstate rfpwr_state)
2209 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2211 bool bresult = false;
2213 if (rfpwr_state == ppsc->rfpwr_state)
2215 return _rtl8822be_phy_set_rf_power_state(hw, rfpwr_state);