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