Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright(c) 2009-2012  Realtek Corporation.*/
0003 
0004 #include "../wifi.h"
0005 #include "../base.h"
0006 #include "../pci.h"
0007 #include "../core.h"
0008 #include "reg.h"
0009 #include "def.h"
0010 #include "phy.h"
0011 #include "dm.h"
0012 #include "../rtl8723com/dm_common.h"
0013 #include "fw.h"
0014 #include "hal_btc.h"
0015 
0016 static u8 rtl8723e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
0017 {
0018     struct rtl_priv *rtlpriv = rtl_priv(hw);
0019     struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0020     struct rtl_mac *mac = rtl_mac(rtlpriv);
0021     long rssi_val_min = 0;
0022 
0023     if (mac->link_state == MAC80211_LINKED &&
0024         mac->opmode == NL80211_IFTYPE_STATION &&
0025         rtlpriv->link_info.bcn_rx_inperiod == 0)
0026         return 0;
0027 
0028     if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) &&
0029         (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) {
0030         if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0)
0031             rssi_val_min =
0032                 (rtlpriv->dm.entry_min_undec_sm_pwdb >
0033                  rtlpriv->dm.undec_sm_pwdb) ?
0034                 rtlpriv->dm.undec_sm_pwdb :
0035                 rtlpriv->dm.entry_min_undec_sm_pwdb;
0036         else
0037             rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
0038     } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT ||
0039            dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) {
0040         rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
0041     } else if (dm_digtable->curmultista_cstate ==
0042         DIG_MULTISTA_CONNECT) {
0043         rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
0044     }
0045 
0046     return (u8) rssi_val_min;
0047 }
0048 
0049 static void rtl8723e_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
0050 {
0051     u32 ret_value;
0052     struct rtl_priv *rtlpriv = rtl_priv(hw);
0053     struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
0054 
0055     ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
0056     falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
0057 
0058     ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
0059     falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
0060     falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
0061 
0062     ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
0063     falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
0064     falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
0065         falsealm_cnt->cnt_rate_illegal +
0066         falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail;
0067 
0068     rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
0069     ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
0070     falsealm_cnt->cnt_cck_fail = ret_value;
0071 
0072     ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
0073     falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
0074     falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail +
0075                  falsealm_cnt->cnt_rate_illegal +
0076                  falsealm_cnt->cnt_crc8_fail +
0077                  falsealm_cnt->cnt_mcs_fail +
0078                  falsealm_cnt->cnt_cck_fail);
0079 
0080     rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
0081     rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
0082     rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
0083     rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
0084 
0085     rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0086         "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
0087         falsealm_cnt->cnt_parity_fail,
0088         falsealm_cnt->cnt_rate_illegal,
0089         falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
0090 
0091     rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0092         "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
0093         falsealm_cnt->cnt_ofdm_fail,
0094         falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
0095 }
0096 
0097 static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
0098 {
0099     struct rtl_priv *rtlpriv = rtl_priv(hw);
0100     struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0101     u8 value_igi = dm_digtable->cur_igvalue;
0102 
0103     if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
0104         value_igi--;
0105     else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
0106         value_igi += 0;
0107     else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2)
0108         value_igi++;
0109     else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2)
0110         value_igi += 2;
0111     if (value_igi > DM_DIG_FA_UPPER)
0112         value_igi = DM_DIG_FA_UPPER;
0113     else if (value_igi < DM_DIG_FA_LOWER)
0114         value_igi = DM_DIG_FA_LOWER;
0115     if (rtlpriv->falsealm_cnt.cnt_all > 10000)
0116         value_igi = 0x32;
0117 
0118     dm_digtable->cur_igvalue = value_igi;
0119     rtl8723e_dm_write_dig(hw);
0120 }
0121 
0122 static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
0123 {
0124     struct rtl_priv *rtlpriv = rtl_priv(hw);
0125     struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0126 
0127     if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable->fa_highthresh) {
0128         if ((dm_digtable->back_val - 2) <
0129             dm_digtable->back_range_min)
0130             dm_digtable->back_val =
0131                 dm_digtable->back_range_min;
0132         else
0133             dm_digtable->back_val -= 2;
0134     } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable->fa_lowthresh) {
0135         if ((dm_digtable->back_val + 2) >
0136             dm_digtable->back_range_max)
0137             dm_digtable->back_val =
0138                 dm_digtable->back_range_max;
0139         else
0140             dm_digtable->back_val += 2;
0141     }
0142 
0143     if ((dm_digtable->rssi_val_min + 10 - dm_digtable->back_val) >
0144         dm_digtable->rx_gain_max)
0145         dm_digtable->cur_igvalue = dm_digtable->rx_gain_max;
0146     else if ((dm_digtable->rssi_val_min + 10 -
0147           dm_digtable->back_val) < dm_digtable->rx_gain_min)
0148         dm_digtable->cur_igvalue = dm_digtable->rx_gain_min;
0149     else
0150         dm_digtable->cur_igvalue = dm_digtable->rssi_val_min + 10 -
0151             dm_digtable->back_val;
0152 
0153     rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0154         "rssi_val_min = %x back_val %x\n",
0155         dm_digtable->rssi_val_min, dm_digtable->back_val);
0156 
0157     rtl8723e_dm_write_dig(hw);
0158 }
0159 
0160 static void rtl8723e_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
0161 {
0162     static u8 binitialized;
0163     struct rtl_priv *rtlpriv = rtl_priv(hw);
0164     struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0165     struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0166     long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb;
0167     bool multi_sta = false;
0168 
0169     if (mac->opmode == NL80211_IFTYPE_ADHOC)
0170         multi_sta = true;
0171 
0172     if (!multi_sta || (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT)) {
0173         binitialized = false;
0174         dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
0175         return;
0176     } else if (!binitialized) {
0177         binitialized = true;
0178         dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
0179         dm_digtable->cur_igvalue = 0x20;
0180         rtl8723e_dm_write_dig(hw);
0181     }
0182 
0183     if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) {
0184         if ((rssi_strength < dm_digtable->rssi_lowthresh) &&
0185             (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) {
0186 
0187             if (dm_digtable->dig_ext_port_stage ==
0188                 DIG_EXT_PORT_STAGE_2) {
0189                 dm_digtable->cur_igvalue = 0x20;
0190                 rtl8723e_dm_write_dig(hw);
0191             }
0192 
0193             dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1;
0194         } else if (rssi_strength > dm_digtable->rssi_highthresh) {
0195             dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2;
0196             rtl92c_dm_ctrl_initgain_by_fa(hw);
0197         }
0198     } else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) {
0199         dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
0200         dm_digtable->cur_igvalue = 0x20;
0201         rtl8723e_dm_write_dig(hw);
0202     }
0203 
0204     rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0205         "curmultista_cstate = %x dig_ext_port_stage %x\n",
0206         dm_digtable->curmultista_cstate,
0207         dm_digtable->dig_ext_port_stage);
0208 }
0209 
0210 static void rtl8723e_dm_initial_gain_sta(struct ieee80211_hw *hw)
0211 {
0212     struct rtl_priv *rtlpriv = rtl_priv(hw);
0213     struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0214 
0215     rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0216         "presta_cstate = %x, cursta_cstate = %x\n",
0217         dm_digtable->presta_cstate,
0218         dm_digtable->cursta_cstate);
0219 
0220     if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate ||
0221         dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT ||
0222         dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
0223         if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {
0224             dm_digtable->rssi_val_min =
0225                 rtl8723e_dm_initial_gain_min_pwdb(hw);
0226             rtl92c_dm_ctrl_initgain_by_rssi(hw);
0227         }
0228     } else {
0229         dm_digtable->rssi_val_min = 0;
0230         dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
0231         dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
0232         dm_digtable->cur_igvalue = 0x20;
0233         dm_digtable->pre_igvalue = 0;
0234         rtl8723e_dm_write_dig(hw);
0235     }
0236 }
0237 
0238 static void rtl8723e_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
0239 {
0240     struct rtl_priv *rtlpriv = rtl_priv(hw);
0241     struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0242 
0243     if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
0244         dm_digtable->rssi_val_min = rtl8723e_dm_initial_gain_min_pwdb(hw);
0245 
0246         if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
0247             if (dm_digtable->rssi_val_min <= 25)
0248                 dm_digtable->cur_cck_pd_state =
0249                     CCK_PD_STAGE_LOWRSSI;
0250             else
0251                 dm_digtable->cur_cck_pd_state =
0252                     CCK_PD_STAGE_HIGHRSSI;
0253         } else {
0254             if (dm_digtable->rssi_val_min <= 20)
0255                 dm_digtable->cur_cck_pd_state =
0256                     CCK_PD_STAGE_LOWRSSI;
0257             else
0258                 dm_digtable->cur_cck_pd_state =
0259                     CCK_PD_STAGE_HIGHRSSI;
0260         }
0261     } else {
0262         dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
0263     }
0264 
0265     if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) {
0266         if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
0267             if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800)
0268                 dm_digtable->cur_cck_fa_state =
0269                     CCK_FA_STAGE_HIGH;
0270             else
0271                 dm_digtable->cur_cck_fa_state =
0272                     CCK_FA_STAGE_LOW;
0273             if (dm_digtable->pre_cck_fa_state !=
0274                 dm_digtable->cur_cck_fa_state) {
0275                 if (dm_digtable->cur_cck_fa_state ==
0276                     CCK_FA_STAGE_LOW)
0277                     rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
0278                               0x83);
0279                 else
0280                     rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
0281                               0xcd);
0282 
0283                 dm_digtable->pre_cck_fa_state =
0284                     dm_digtable->cur_cck_fa_state;
0285             }
0286 
0287             rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40);
0288 
0289         } else {
0290             rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
0291             rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47);
0292             dm_digtable->pre_cck_fa_state = 0;
0293             dm_digtable->cur_cck_fa_state = 0;
0294 
0295         }
0296         dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state;
0297     }
0298 
0299     rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0300         "CCKPDStage=%x\n", dm_digtable->cur_cck_pd_state);
0301 
0302 }
0303 
0304 static void rtl8723e_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
0305 {
0306     struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0307     struct rtl_priv *rtlpriv = rtl_priv(hw);
0308     struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0309 
0310     if (mac->act_scanning)
0311         return;
0312 
0313     if (mac->link_state >= MAC80211_LINKED)
0314         dm_digtable->cursta_cstate = DIG_STA_CONNECT;
0315     else
0316         dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
0317 
0318     rtl8723e_dm_initial_gain_sta(hw);
0319     rtl8723e_dm_initial_gain_multi_sta(hw);
0320     rtl8723e_dm_cck_packet_detection_thresh(hw);
0321 
0322     dm_digtable->presta_cstate = dm_digtable->cursta_cstate;
0323 
0324 }
0325 
0326 static void rtl8723e_dm_dig(struct ieee80211_hw *hw)
0327 {
0328     struct rtl_priv *rtlpriv = rtl_priv(hw);
0329     struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0330 
0331     if (!rtlpriv->dm.dm_initialgain_enable)
0332         return;
0333     if (!dm_digtable->dig_enable_flag)
0334         return;
0335 
0336     rtl8723e_dm_ctrl_initgain_by_twoport(hw);
0337 
0338 }
0339 
0340 static void rtl8723e_dm_dynamic_txpower(struct ieee80211_hw *hw)
0341 {
0342     struct rtl_priv *rtlpriv = rtl_priv(hw);
0343     struct rtl_phy *rtlphy = &(rtlpriv->phy);
0344     struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0345     long undec_sm_pwdb;
0346 
0347     if (!rtlpriv->dm.dynamic_txpower_enable)
0348         return;
0349 
0350     if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
0351         rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
0352         return;
0353     }
0354 
0355     if ((mac->link_state < MAC80211_LINKED) &&
0356         (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
0357         rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,
0358             "Not connected to any\n");
0359 
0360         rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
0361 
0362         rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
0363         return;
0364     }
0365 
0366     if (mac->link_state >= MAC80211_LINKED) {
0367         if (mac->opmode == NL80211_IFTYPE_ADHOC) {
0368             undec_sm_pwdb =
0369                 rtlpriv->dm.entry_min_undec_sm_pwdb;
0370             rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0371                 "AP Client PWDB = 0x%lx\n",
0372                 undec_sm_pwdb);
0373         } else {
0374             undec_sm_pwdb =
0375                 rtlpriv->dm.undec_sm_pwdb;
0376             rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0377                 "STA Default Port PWDB = 0x%lx\n",
0378                 undec_sm_pwdb);
0379         }
0380     } else {
0381         undec_sm_pwdb =
0382             rtlpriv->dm.entry_min_undec_sm_pwdb;
0383 
0384         rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0385             "AP Ext Port PWDB = 0x%lx\n",
0386             undec_sm_pwdb);
0387     }
0388 
0389     if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
0390         rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
0391         rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0392             "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
0393     } else if ((undec_sm_pwdb <
0394             (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
0395            (undec_sm_pwdb >=
0396             TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
0397         rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
0398         rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0399             "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
0400     } else if (undec_sm_pwdb <
0401            (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
0402         rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
0403         rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0404             "TXHIGHPWRLEVEL_NORMAL\n");
0405     }
0406 
0407     if (rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl) {
0408         rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0409             "PHY_SetTxPowerLevel8192S() Channel = %d\n",
0410             rtlphy->current_channel);
0411         rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel);
0412     }
0413 
0414     rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
0415 }
0416 
0417 void rtl8723e_dm_write_dig(struct ieee80211_hw *hw)
0418 {
0419     struct rtl_priv *rtlpriv = rtl_priv(hw);
0420     struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0421 
0422     rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
0423         "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n",
0424         dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
0425         dm_digtable->back_val);
0426 
0427     if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) {
0428         rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
0429                   dm_digtable->cur_igvalue);
0430         rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
0431                   dm_digtable->cur_igvalue);
0432 
0433         dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
0434     }
0435 }
0436 
0437 static void rtl8723e_dm_pwdb_monitor(struct ieee80211_hw *hw)
0438 {
0439 }
0440 
0441 static void rtl8723e_dm_check_edca_turbo(struct ieee80211_hw *hw)
0442 {
0443     struct rtl_priv *rtlpriv = rtl_priv(hw);
0444     struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0445 
0446     static u64 last_txok_cnt;
0447     static u64 last_rxok_cnt;
0448     static u32 last_bt_edca_ul;
0449     static u32 last_bt_edca_dl;
0450     u64 cur_txok_cnt = 0;
0451     u64 cur_rxok_cnt = 0;
0452     u32 edca_be_ul = 0x5ea42b;
0453     u32 edca_be_dl = 0x5ea42b;
0454     bool bt_change_edca = false;
0455 
0456     if ((last_bt_edca_ul != rtlpriv->btcoexist.bt_edca_ul) ||
0457         (last_bt_edca_dl != rtlpriv->btcoexist.bt_edca_dl)) {
0458         rtlpriv->dm.current_turbo_edca = false;
0459         last_bt_edca_ul = rtlpriv->btcoexist.bt_edca_ul;
0460         last_bt_edca_dl = rtlpriv->btcoexist.bt_edca_dl;
0461     }
0462 
0463     if (rtlpriv->btcoexist.bt_edca_ul != 0) {
0464         edca_be_ul = rtlpriv->btcoexist.bt_edca_ul;
0465         bt_change_edca = true;
0466     }
0467 
0468     if (rtlpriv->btcoexist.bt_edca_dl != 0) {
0469         edca_be_ul = rtlpriv->btcoexist.bt_edca_dl;
0470         bt_change_edca = true;
0471     }
0472 
0473     if (mac->link_state != MAC80211_LINKED) {
0474         rtlpriv->dm.current_turbo_edca = false;
0475         return;
0476     }
0477     if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) &&
0478          (!rtlpriv->dm.disable_framebursting))) {
0479 
0480         cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
0481         cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
0482 
0483         if (cur_rxok_cnt > 4 * cur_txok_cnt) {
0484             if (!rtlpriv->dm.is_cur_rdlstate ||
0485                 !rtlpriv->dm.current_turbo_edca) {
0486                 rtl_write_dword(rtlpriv,
0487                         REG_EDCA_BE_PARAM,
0488                         edca_be_dl);
0489                 rtlpriv->dm.is_cur_rdlstate = true;
0490             }
0491         } else {
0492             if (rtlpriv->dm.is_cur_rdlstate ||
0493                 !rtlpriv->dm.current_turbo_edca) {
0494                 rtl_write_dword(rtlpriv,
0495                         REG_EDCA_BE_PARAM,
0496                         edca_be_ul);
0497                 rtlpriv->dm.is_cur_rdlstate = false;
0498             }
0499         }
0500         rtlpriv->dm.current_turbo_edca = true;
0501     } else {
0502         if (rtlpriv->dm.current_turbo_edca) {
0503             u8 tmp = AC0_BE;
0504             rtlpriv->cfg->ops->set_hw_reg(hw,
0505                               HW_VAR_AC_PARAM,
0506                               (u8 *)(&tmp));
0507             rtlpriv->dm.current_turbo_edca = false;
0508         }
0509     }
0510 
0511     rtlpriv->dm.is_any_nonbepkts = false;
0512     last_txok_cnt = rtlpriv->stats.txbytesunicast;
0513     last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
0514 }
0515 
0516 static void rtl8723e_dm_initialize_txpower_tracking_thermalmeter(
0517                 struct ieee80211_hw *hw)
0518 {
0519     struct rtl_priv *rtlpriv = rtl_priv(hw);
0520 
0521     rtlpriv->dm.txpower_tracking = true;
0522     rtlpriv->dm.txpower_trackinginit = false;
0523 
0524     rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0525         "pMgntInfo->txpower_tracking = %d\n",
0526         rtlpriv->dm.txpower_tracking);
0527 }
0528 
0529 static void rtl8723e_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
0530 {
0531     rtl8723e_dm_initialize_txpower_tracking_thermalmeter(hw);
0532 }
0533 
0534 void rtl8723e_dm_check_txpower_tracking(struct ieee80211_hw *hw)
0535 {
0536     return;
0537 }
0538 
0539 void rtl8723e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
0540 {
0541     struct rtl_priv *rtlpriv = rtl_priv(hw);
0542     struct rate_adaptive *p_ra = &rtlpriv->ra;
0543 
0544     p_ra->ratr_state = DM_RATR_STA_INIT;
0545     p_ra->pre_ratr_state = DM_RATR_STA_INIT;
0546 
0547     if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
0548         rtlpriv->dm.useramask = true;
0549     else
0550         rtlpriv->dm.useramask = false;
0551 
0552 }
0553 
0554 static void rtl8723e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
0555 {
0556     struct rtl_priv *rtlpriv = rtl_priv(hw);
0557     struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0558     struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0559     struct rate_adaptive *p_ra = &rtlpriv->ra;
0560     u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
0561     struct ieee80211_sta *sta = NULL;
0562 
0563     if (is_hal_stop(rtlhal)) {
0564         rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
0565             " driver is going to unload\n");
0566         return;
0567     }
0568 
0569     if (!rtlpriv->dm.useramask) {
0570         rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
0571             " driver does not control rate adaptive mask\n");
0572         return;
0573     }
0574 
0575     if (mac->link_state == MAC80211_LINKED &&
0576         mac->opmode == NL80211_IFTYPE_STATION) {
0577         switch (p_ra->pre_ratr_state) {
0578         case DM_RATR_STA_HIGH:
0579             high_rssithresh_for_ra = 50;
0580             low_rssithresh_for_ra = 20;
0581             break;
0582         case DM_RATR_STA_MIDDLE:
0583             high_rssithresh_for_ra = 55;
0584             low_rssithresh_for_ra = 20;
0585             break;
0586         case DM_RATR_STA_LOW:
0587             high_rssithresh_for_ra = 60;
0588             low_rssithresh_for_ra = 25;
0589             break;
0590         default:
0591             high_rssithresh_for_ra = 50;
0592             low_rssithresh_for_ra = 20;
0593             break;
0594         }
0595 
0596         if (rtlpriv->link_info.bcn_rx_inperiod == 0)
0597             switch (p_ra->pre_ratr_state) {
0598             case DM_RATR_STA_HIGH:
0599             default:
0600                 p_ra->ratr_state = DM_RATR_STA_MIDDLE;
0601                 break;
0602             case DM_RATR_STA_MIDDLE:
0603             case DM_RATR_STA_LOW:
0604                 p_ra->ratr_state = DM_RATR_STA_LOW;
0605                 break;
0606             }
0607         else if (rtlpriv->dm.undec_sm_pwdb > high_rssithresh_for_ra)
0608             p_ra->ratr_state = DM_RATR_STA_HIGH;
0609         else if (rtlpriv->dm.undec_sm_pwdb > low_rssithresh_for_ra)
0610             p_ra->ratr_state = DM_RATR_STA_MIDDLE;
0611         else
0612             p_ra->ratr_state = DM_RATR_STA_LOW;
0613 
0614         if (p_ra->pre_ratr_state != p_ra->ratr_state) {
0615             rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
0616                 "RSSI = %ld\n",
0617                 rtlpriv->dm.undec_sm_pwdb);
0618             rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
0619                 "RSSI_LEVEL = %d\n", p_ra->ratr_state);
0620             rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
0621                 "PreState = %d, CurState = %d\n",
0622                 p_ra->pre_ratr_state, p_ra->ratr_state);
0623 
0624             rcu_read_lock();
0625             sta = rtl_find_sta(hw, mac->bssid);
0626             if (sta)
0627                 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
0628                                p_ra->ratr_state,
0629                                       true);
0630             rcu_read_unlock();
0631 
0632             p_ra->pre_ratr_state = p_ra->ratr_state;
0633         }
0634     }
0635 }
0636 
0637 void rtl8723e_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
0638 {
0639     struct rtl_priv *rtlpriv = rtl_priv(hw);
0640     struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
0641     static u8 initialize;
0642     static u32 reg_874, reg_c70, reg_85c, reg_a74;
0643 
0644     if (initialize == 0) {
0645         reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
0646                      MASKDWORD) & 0x1CC000) >> 14;
0647 
0648         reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
0649                      MASKDWORD) & BIT(3)) >> 3;
0650 
0651         reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
0652                      MASKDWORD) & 0xFF000000) >> 24;
0653 
0654         reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12;
0655 
0656         initialize = 1;
0657     }
0658 
0659     if (!bforce_in_normal) {
0660         if (dm_pstable->rssi_val_min != 0) {
0661             if (dm_pstable->pre_rfstate == RF_NORMAL) {
0662                 if (dm_pstable->rssi_val_min >= 30)
0663                     dm_pstable->cur_rfstate = RF_SAVE;
0664                 else
0665                     dm_pstable->cur_rfstate = RF_NORMAL;
0666             } else {
0667                 if (dm_pstable->rssi_val_min <= 25)
0668                     dm_pstable->cur_rfstate = RF_NORMAL;
0669                 else
0670                     dm_pstable->cur_rfstate = RF_SAVE;
0671             }
0672         } else {
0673             dm_pstable->cur_rfstate = RF_MAX;
0674         }
0675     } else {
0676         dm_pstable->cur_rfstate = RF_NORMAL;
0677     }
0678 
0679     if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) {
0680         if (dm_pstable->cur_rfstate == RF_SAVE) {
0681             rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
0682                       BIT(5), 0x1);
0683             rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
0684                       0x1C0000, 0x2);
0685             rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0);
0686             rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
0687                       0xFF000000, 0x63);
0688             rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
0689                       0xC000, 0x2);
0690             rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3);
0691             rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
0692             rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
0693         } else {
0694             rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
0695                       0x1CC000, reg_874);
0696             rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
0697                       reg_c70);
0698             rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
0699                       reg_85c);
0700             rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74);
0701             rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
0702             rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
0703                       BIT(5), 0x0);
0704         }
0705 
0706         dm_pstable->pre_rfstate = dm_pstable->cur_rfstate;
0707     }
0708 }
0709 
0710 static void rtl8723e_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
0711 {
0712     struct rtl_priv *rtlpriv = rtl_priv(hw);
0713     struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0714     struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
0715 
0716     if (((mac->link_state == MAC80211_NOLINK)) &&
0717         (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
0718         dm_pstable->rssi_val_min = 0;
0719         rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD,
0720             "Not connected to any\n");
0721     }
0722 
0723     if (mac->link_state == MAC80211_LINKED) {
0724         if (mac->opmode == NL80211_IFTYPE_ADHOC) {
0725             dm_pstable->rssi_val_min =
0726                 rtlpriv->dm.entry_min_undec_sm_pwdb;
0727             rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD,
0728                 "AP Client PWDB = 0x%lx\n",
0729                 dm_pstable->rssi_val_min);
0730         } else {
0731             dm_pstable->rssi_val_min =
0732                 rtlpriv->dm.undec_sm_pwdb;
0733             rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD,
0734                 "STA Default Port PWDB = 0x%lx\n",
0735                 dm_pstable->rssi_val_min);
0736         }
0737     } else {
0738         dm_pstable->rssi_val_min =
0739             rtlpriv->dm.entry_min_undec_sm_pwdb;
0740 
0741         rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD,
0742             "AP Ext Port PWDB = 0x%lx\n",
0743             dm_pstable->rssi_val_min);
0744     }
0745 
0746     rtl8723e_dm_rf_saving(hw, false);
0747 }
0748 
0749 void rtl8723e_dm_init(struct ieee80211_hw *hw)
0750 {
0751     struct rtl_priv *rtlpriv = rtl_priv(hw);
0752 
0753     rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
0754     rtl_dm_diginit(hw, 0x20);
0755     rtl8723_dm_init_dynamic_txpower(hw);
0756     rtl8723_dm_init_edca_turbo(hw);
0757     rtl8723e_dm_init_rate_adaptive_mask(hw);
0758     rtl8723e_dm_initialize_txpower_tracking(hw);
0759     rtl8723_dm_init_dynamic_bb_powersaving(hw);
0760 }
0761 
0762 void rtl8723e_dm_watchdog(struct ieee80211_hw *hw)
0763 {
0764     struct rtl_priv *rtlpriv = rtl_priv(hw);
0765     struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
0766     bool fw_current_inpsmode = false;
0767     bool fw_ps_awake = true;
0768     rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
0769                       (u8 *)(&fw_current_inpsmode));
0770     rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
0771                       (u8 *)(&fw_ps_awake));
0772 
0773     if (ppsc->p2p_ps_info.p2p_ps_mode)
0774         fw_ps_awake = false;
0775 
0776     spin_lock(&rtlpriv->locks.rf_ps_lock);
0777     if ((ppsc->rfpwr_state == ERFON) &&
0778         ((!fw_current_inpsmode) && fw_ps_awake) &&
0779         (!ppsc->rfchange_inprogress)) {
0780         rtl8723e_dm_pwdb_monitor(hw);
0781         rtl8723e_dm_dig(hw);
0782         rtl8723e_dm_false_alarm_counter_statistics(hw);
0783         rtl8723e_dm_dynamic_bb_powersaving(hw);
0784         rtl8723e_dm_dynamic_txpower(hw);
0785         rtl8723e_dm_check_txpower_tracking(hw);
0786         rtl8723e_dm_refresh_rate_adaptive_mask(hw);
0787         rtl8723e_dm_bt_coexist(hw);
0788         rtl8723e_dm_check_edca_turbo(hw);
0789     }
0790     spin_unlock(&rtlpriv->locks.rf_ps_lock);
0791     if (rtlpriv->btcoexist.init_set)
0792         rtl_write_byte(rtlpriv, 0x76e, 0xc);
0793 }
0794 
0795 static void rtl8723e_dm_init_bt_coexist(struct ieee80211_hw *hw)
0796 {
0797     struct rtl_priv *rtlpriv = rtl_priv(hw);
0798 
0799     rtlpriv->btcoexist.bt_rfreg_origin_1e
0800         = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK1, 0xfffff);
0801     rtlpriv->btcoexist.bt_rfreg_origin_1f
0802         = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK2, 0xf0);
0803 
0804     rtlpriv->btcoexist.cstate = 0;
0805     rtlpriv->btcoexist.previous_state = 0;
0806     rtlpriv->btcoexist.cstate_h = 0;
0807     rtlpriv->btcoexist.previous_state_h = 0;
0808     rtlpriv->btcoexist.lps_counter = 0;
0809 
0810     /*  Enable counter statistics */
0811     rtl_write_byte(rtlpriv, 0x76e, 0x4);
0812     rtl_write_byte(rtlpriv, 0x778, 0x3);
0813     rtl_write_byte(rtlpriv, 0x40, 0x20);
0814 
0815     rtlpriv->btcoexist.init_set = true;
0816 }
0817 
0818 void rtl8723e_dm_bt_coexist(struct ieee80211_hw *hw)
0819 {
0820     struct rtl_priv *rtlpriv = rtl_priv(hw);
0821     u8 tmp_byte = 0;
0822     if (!rtlpriv->btcoexist.bt_coexistence) {
0823         rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
0824             "[DM]{BT], BT not exist!!\n");
0825         return;
0826     }
0827 
0828     if (!rtlpriv->btcoexist.init_set) {
0829         rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
0830             "[DM][BT], %s\n", __func__);
0831         rtl8723e_dm_init_bt_coexist(hw);
0832     }
0833 
0834     tmp_byte = rtl_read_byte(rtlpriv, 0x40);
0835     rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
0836         "[DM][BT], 0x40 is 0x%x\n", tmp_byte);
0837     rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
0838         "[DM][BT], bt_dm_coexist start\n");
0839     rtl8723e_dm_bt_coexist_8723(hw);
0840 }