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 "../core.h"
0007 #include "reg.h"
0008 #include "def.h"
0009 #include "phy.h"
0010 #include "dm.h"
0011 #include "fw.h"
0012 
0013 static const u32 edca_setting_dl[PEER_MAX] = {
0014     0xa44f,     /* 0 UNKNOWN */
0015     0x5ea44f,   /* 1 REALTEK_90 */
0016     0x5ea44f,   /* 2 REALTEK_92SE */
0017     0xa630,     /* 3 BROAD  */
0018     0xa44f,     /* 4 RAL */
0019     0xa630,     /* 5 ATH */
0020     0xa630,     /* 6 CISCO */
0021     0xa42b,     /* 7 MARV */
0022 };
0023 
0024 static const u32 edca_setting_dl_gmode[PEER_MAX] = {
0025     0x4322,     /* 0 UNKNOWN */
0026     0xa44f,     /* 1 REALTEK_90 */
0027     0x5ea44f,   /* 2 REALTEK_92SE */
0028     0xa42b,     /* 3 BROAD */
0029     0x5e4322,   /* 4 RAL */
0030     0x4322,     /* 5 ATH */
0031     0xa430,     /* 6 CISCO */
0032     0x5ea44f,   /* 7 MARV */
0033 };
0034 
0035 static const u32 edca_setting_ul[PEER_MAX] = {
0036     0x5e4322,   /* 0 UNKNOWN */
0037     0xa44f,     /* 1 REALTEK_90 */
0038     0x5ea44f,   /* 2 REALTEK_92SE */
0039     0x5ea322,   /* 3 BROAD */
0040     0x5ea422,   /* 4 RAL */
0041     0x5ea322,   /* 5 ATH */
0042     0x3ea44f,   /* 6 CISCO */
0043     0x5ea44f,   /* 7 MARV */
0044 };
0045 
0046 static void _rtl92s_dm_check_edca_turbo(struct ieee80211_hw *hw)
0047 {
0048     struct rtl_priv *rtlpriv = rtl_priv(hw);
0049     struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0050 
0051     static u64 last_txok_cnt;
0052     static u64 last_rxok_cnt;
0053     u64 cur_txok_cnt = 0;
0054     u64 cur_rxok_cnt = 0;
0055 
0056     u32 edca_be_ul = edca_setting_ul[mac->vendor];
0057     u32 edca_be_dl = edca_setting_dl[mac->vendor];
0058     u32 edca_gmode = edca_setting_dl_gmode[mac->vendor];
0059 
0060     if (mac->link_state != MAC80211_LINKED) {
0061         rtlpriv->dm.current_turbo_edca = false;
0062         goto dm_checkedcaturbo_exit;
0063     }
0064 
0065     if ((!rtlpriv->dm.is_any_nonbepkts) &&
0066         (!rtlpriv->dm.disable_framebursting)) {
0067         cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
0068         cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
0069 
0070         if (rtlpriv->phy.rf_type == RF_1T2R) {
0071             if (cur_txok_cnt > 4 * cur_rxok_cnt) {
0072                 /* Uplink TP is present. */
0073                 if (rtlpriv->dm.is_cur_rdlstate ||
0074                     !rtlpriv->dm.current_turbo_edca) {
0075                     rtl_write_dword(rtlpriv, EDCAPARA_BE,
0076                             edca_be_ul);
0077                     rtlpriv->dm.is_cur_rdlstate = false;
0078                 }
0079             } else {/* Balance TP is present. */
0080                 if (!rtlpriv->dm.is_cur_rdlstate ||
0081                     !rtlpriv->dm.current_turbo_edca) {
0082                     if (mac->mode == WIRELESS_MODE_G ||
0083                         mac->mode == WIRELESS_MODE_B)
0084                         rtl_write_dword(rtlpriv,
0085                                 EDCAPARA_BE,
0086                                 edca_gmode);
0087                     else
0088                         rtl_write_dword(rtlpriv,
0089                                 EDCAPARA_BE,
0090                                 edca_be_dl);
0091                     rtlpriv->dm.is_cur_rdlstate = true;
0092                 }
0093             }
0094             rtlpriv->dm.current_turbo_edca = true;
0095         } else {
0096             if (cur_rxok_cnt > 4 * cur_txok_cnt) {
0097                 if (!rtlpriv->dm.is_cur_rdlstate ||
0098                     !rtlpriv->dm.current_turbo_edca) {
0099                     if (mac->mode == WIRELESS_MODE_G ||
0100                         mac->mode == WIRELESS_MODE_B)
0101                         rtl_write_dword(rtlpriv,
0102                                 EDCAPARA_BE,
0103                                 edca_gmode);
0104                     else
0105                         rtl_write_dword(rtlpriv,
0106                                 EDCAPARA_BE,
0107                                 edca_be_dl);
0108                     rtlpriv->dm.is_cur_rdlstate = true;
0109                 }
0110             } else {
0111                 if (rtlpriv->dm.is_cur_rdlstate ||
0112                     !rtlpriv->dm.current_turbo_edca) {
0113                     rtl_write_dword(rtlpriv, EDCAPARA_BE,
0114                             edca_be_ul);
0115                     rtlpriv->dm.is_cur_rdlstate = false;
0116                 }
0117             }
0118             rtlpriv->dm.current_turbo_edca = true;
0119         }
0120     } else {
0121         if (rtlpriv->dm.current_turbo_edca) {
0122             u8 tmp = AC0_BE;
0123             rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
0124                               &tmp);
0125             rtlpriv->dm.current_turbo_edca = false;
0126         }
0127     }
0128 
0129 dm_checkedcaturbo_exit:
0130     rtlpriv->dm.is_any_nonbepkts = false;
0131     last_txok_cnt = rtlpriv->stats.txbytesunicast;
0132     last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
0133 }
0134 
0135 static void _rtl92s_dm_txpowertracking_callback_thermalmeter(
0136                     struct ieee80211_hw *hw)
0137 {
0138     struct rtl_priv *rtlpriv = rtl_priv(hw);
0139     struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
0140     u8 thermalvalue = 0;
0141     u32 fw_cmd = 0;
0142 
0143     rtlpriv->dm.txpower_trackinginit = true;
0144 
0145     thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
0146 
0147     rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0148         "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermal meter 0x%x\n",
0149         thermalvalue,
0150         rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter);
0151 
0152     if (thermalvalue) {
0153         rtlpriv->dm.thermalvalue = thermalvalue;
0154         if (hal_get_firmwareversion(rtlpriv) >= 0x35) {
0155             rtl92s_phy_set_fw_cmd(hw, FW_CMD_TXPWR_TRACK_THERMAL);
0156         } else {
0157             fw_cmd = (FW_TXPWR_TRACK_THERMAL |
0158                  (rtlpriv->efuse.thermalmeter[0] << 8) |
0159                  (thermalvalue << 16));
0160 
0161             rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0162                 "Write to FW Thermal Val = 0x%x\n", fw_cmd);
0163 
0164             rtl_write_dword(rtlpriv, WFM5, fw_cmd);
0165             rtl92s_phy_chk_fwcmd_iodone(hw);
0166         }
0167     }
0168 
0169     rtlpriv->dm.txpowercount = 0;
0170 }
0171 
0172 static void _rtl92s_dm_check_txpowertracking_thermalmeter(
0173                     struct ieee80211_hw *hw)
0174 {
0175     struct rtl_priv *rtlpriv = rtl_priv(hw);
0176     struct rtl_phy *rtlphy = &(rtlpriv->phy);
0177     u8 tx_power_checkcnt = 5;
0178 
0179     /* 2T2R TP issue */
0180     if (rtlphy->rf_type == RF_2T2R)
0181         return;
0182 
0183     if (!rtlpriv->dm.txpower_tracking)
0184         return;
0185 
0186     if (rtlpriv->dm.txpowercount <= tx_power_checkcnt) {
0187         rtlpriv->dm.txpowercount++;
0188         return;
0189     }
0190 
0191     if (!rtlpriv->dm.tm_trigger) {
0192         rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER,
0193                   RFREG_OFFSET_MASK, 0x60);
0194         rtlpriv->dm.tm_trigger = 1;
0195     } else {
0196         _rtl92s_dm_txpowertracking_callback_thermalmeter(hw);
0197         rtlpriv->dm.tm_trigger = 0;
0198     }
0199 }
0200 
0201 static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
0202 {
0203     struct rtl_priv *rtlpriv = rtl_priv(hw);
0204     struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0205     struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0206     struct rate_adaptive *ra = &(rtlpriv->ra);
0207     struct ieee80211_sta *sta = NULL;
0208     u32 low_rssi_thresh = 0;
0209     u32 middle_rssi_thresh = 0;
0210     u32 high_rssi_thresh = 0;
0211 
0212     if (is_hal_stop(rtlhal))
0213         return;
0214 
0215     if (!rtlpriv->dm.useramask)
0216         return;
0217 
0218     if (hal_get_firmwareversion(rtlpriv) >= 61 &&
0219         !rtlpriv->dm.inform_fw_driverctrldm) {
0220         rtl92s_phy_set_fw_cmd(hw, FW_CMD_CTRL_DM_BY_DRIVER);
0221         rtlpriv->dm.inform_fw_driverctrldm = true;
0222     }
0223 
0224     if ((mac->link_state == MAC80211_LINKED) &&
0225         (mac->opmode == NL80211_IFTYPE_STATION)) {
0226         switch (ra->pre_ratr_state) {
0227         case DM_RATR_STA_HIGH:
0228             high_rssi_thresh = 40;
0229             middle_rssi_thresh = 30;
0230             low_rssi_thresh = 20;
0231             break;
0232         case DM_RATR_STA_MIDDLE:
0233             high_rssi_thresh = 44;
0234             middle_rssi_thresh = 30;
0235             low_rssi_thresh = 20;
0236             break;
0237         case DM_RATR_STA_LOW:
0238             high_rssi_thresh = 44;
0239             middle_rssi_thresh = 34;
0240             low_rssi_thresh = 20;
0241             break;
0242         case DM_RATR_STA_ULTRALOW:
0243             high_rssi_thresh = 44;
0244             middle_rssi_thresh = 34;
0245             low_rssi_thresh = 24;
0246             break;
0247         default:
0248             high_rssi_thresh = 44;
0249             middle_rssi_thresh = 34;
0250             low_rssi_thresh = 24;
0251             break;
0252         }
0253 
0254         if (rtlpriv->dm.undec_sm_pwdb > (long)high_rssi_thresh) {
0255             ra->ratr_state = DM_RATR_STA_HIGH;
0256         } else if (rtlpriv->dm.undec_sm_pwdb >
0257                (long)middle_rssi_thresh) {
0258             ra->ratr_state = DM_RATR_STA_LOW;
0259         } else if (rtlpriv->dm.undec_sm_pwdb >
0260                (long)low_rssi_thresh) {
0261             ra->ratr_state = DM_RATR_STA_LOW;
0262         } else {
0263             ra->ratr_state = DM_RATR_STA_ULTRALOW;
0264         }
0265 
0266         if (ra->pre_ratr_state != ra->ratr_state) {
0267             rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
0268                 "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
0269                 rtlpriv->dm.undec_sm_pwdb, ra->ratr_state,
0270                 ra->pre_ratr_state, ra->ratr_state);
0271 
0272             rcu_read_lock();
0273             sta = rtl_find_sta(hw, mac->bssid);
0274             if (sta)
0275                 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
0276                                ra->ratr_state,
0277                                true);
0278             rcu_read_unlock();
0279 
0280             ra->pre_ratr_state = ra->ratr_state;
0281         }
0282     }
0283 }
0284 
0285 static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw)
0286 {
0287     struct rtl_priv *rtlpriv = rtl_priv(hw);
0288     struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0289     struct rtl_phy *rtlphy = &(rtlpriv->phy);
0290     struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0291     bool current_mrc;
0292     bool enable_mrc = true;
0293     long tmpentry_maxpwdb = 0;
0294     u8 rssi_a = 0;
0295     u8 rssi_b = 0;
0296 
0297     if (is_hal_stop(rtlhal))
0298         return;
0299 
0300     if ((rtlphy->rf_type == RF_1T1R) || (rtlphy->rf_type == RF_2T2R))
0301         return;
0302 
0303     rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MRC, (u8 *)(&current_mrc));
0304 
0305     if (mac->link_state >= MAC80211_LINKED) {
0306         if (rtlpriv->dm.undec_sm_pwdb > tmpentry_maxpwdb) {
0307             rssi_a = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_A];
0308             rssi_b = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_B];
0309         }
0310     }
0311 
0312     /* MRC settings would NOT affect TP on Wireless B mode. */
0313     if (mac->mode != WIRELESS_MODE_B) {
0314         if ((rssi_a == 0) && (rssi_b == 0)) {
0315             enable_mrc = true;
0316         } else if (rssi_b > 30) {
0317             /* Turn on B-Path */
0318             enable_mrc = true;
0319         } else if (rssi_b < 5) {
0320             /* Turn off B-path  */
0321             enable_mrc = false;
0322         /* Take care of RSSI differentiation. */
0323         } else if (rssi_a > 15 && (rssi_a >= rssi_b)) {
0324             if ((rssi_a - rssi_b) > 15)
0325                 /* Turn off B-path  */
0326                 enable_mrc = false;
0327             else if ((rssi_a - rssi_b) < 10)
0328                 /* Turn on B-Path */
0329                 enable_mrc = true;
0330             else
0331                 enable_mrc = current_mrc;
0332         } else {
0333             /* Turn on B-Path */
0334             enable_mrc = true;
0335         }
0336     }
0337 
0338     /* Update MRC settings if needed. */
0339     if (enable_mrc != current_mrc)
0340         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC,
0341                           (u8 *)&enable_mrc);
0342 
0343 }
0344 
0345 void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw)
0346 {
0347     struct rtl_priv *rtlpriv = rtl_priv(hw);
0348 
0349     rtlpriv->dm.current_turbo_edca = false;
0350     rtlpriv->dm.is_any_nonbepkts = false;
0351     rtlpriv->dm.is_cur_rdlstate = false;
0352 }
0353 
0354 static void _rtl92s_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
0355 {
0356     struct rtl_priv *rtlpriv = rtl_priv(hw);
0357     struct rate_adaptive *ra = &(rtlpriv->ra);
0358 
0359     ra->ratr_state = DM_RATR_STA_MAX;
0360     ra->pre_ratr_state = DM_RATR_STA_MAX;
0361 
0362     if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER &&
0363         hal_get_firmwareversion(rtlpriv) >= 60)
0364         rtlpriv->dm.useramask = true;
0365     else
0366         rtlpriv->dm.useramask = false;
0367 
0368     rtlpriv->dm.useramask = false;
0369     rtlpriv->dm.inform_fw_driverctrldm = false;
0370 }
0371 
0372 static void _rtl92s_dm_init_txpowertracking_thermalmeter(
0373                 struct ieee80211_hw *hw)
0374 {
0375     struct rtl_priv *rtlpriv = rtl_priv(hw);
0376 
0377     rtlpriv->dm.txpower_tracking = true;
0378     rtlpriv->dm.txpowercount = 0;
0379     rtlpriv->dm.txpower_trackinginit = false;
0380 }
0381 
0382 static void _rtl92s_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
0383 {
0384     struct rtl_priv *rtlpriv = rtl_priv(hw);
0385     struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
0386     u32 ret_value;
0387 
0388     ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
0389     falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
0390 
0391     ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
0392     falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
0393     falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
0394     ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
0395     falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
0396 
0397     falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
0398         falsealm_cnt->cnt_rate_illegal + falsealm_cnt->cnt_crc8_fail +
0399         falsealm_cnt->cnt_mcs_fail;
0400 
0401     /* read CCK false alarm */
0402     ret_value = rtl_get_bbreg(hw, 0xc64, MASKDWORD);
0403     falsealm_cnt->cnt_cck_fail = (ret_value & 0xffff);
0404     falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail +
0405         falsealm_cnt->cnt_cck_fail;
0406 }
0407 
0408 static void rtl92s_backoff_enable_flag(struct ieee80211_hw *hw)
0409 {
0410     struct rtl_priv *rtlpriv = rtl_priv(hw);
0411     struct dig_t *digtable = &rtlpriv->dm_digtable;
0412     struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
0413 
0414     if (falsealm_cnt->cnt_all > digtable->fa_highthresh) {
0415         if ((digtable->back_val - 6) <
0416             digtable->backoffval_range_min)
0417             digtable->back_val = digtable->backoffval_range_min;
0418         else
0419             digtable->back_val -= 6;
0420     } else if (falsealm_cnt->cnt_all < digtable->fa_lowthresh) {
0421         if ((digtable->back_val + 6) >
0422             digtable->backoffval_range_max)
0423             digtable->back_val =
0424                  digtable->backoffval_range_max;
0425         else
0426             digtable->back_val += 6;
0427     }
0428 }
0429 
0430 static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
0431 {
0432     struct rtl_priv *rtlpriv = rtl_priv(hw);
0433     struct dig_t *digtable = &rtlpriv->dm_digtable;
0434     struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
0435     static u8 initialized, force_write;
0436     u8 initial_gain = 0;
0437 
0438     if ((digtable->pre_sta_cstate == digtable->cur_sta_cstate) ||
0439         (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT)) {
0440         if (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT) {
0441             if (rtlpriv->psc.rfpwr_state != ERFON)
0442                 return;
0443 
0444             if (digtable->backoff_enable_flag)
0445                 rtl92s_backoff_enable_flag(hw);
0446             else
0447                 digtable->back_val = DM_DIG_BACKOFF_MAX;
0448 
0449             if ((digtable->rssi_val + 10 - digtable->back_val) >
0450                 digtable->rx_gain_max)
0451                 digtable->cur_igvalue =
0452                         digtable->rx_gain_max;
0453             else if ((digtable->rssi_val + 10 - digtable->back_val)
0454                  < digtable->rx_gain_min)
0455                 digtable->cur_igvalue =
0456                         digtable->rx_gain_min;
0457             else
0458                 digtable->cur_igvalue = digtable->rssi_val + 10
0459                     - digtable->back_val;
0460 
0461             if (falsealm_cnt->cnt_all > 10000)
0462                 digtable->cur_igvalue =
0463                      (digtable->cur_igvalue > 0x33) ?
0464                      digtable->cur_igvalue : 0x33;
0465 
0466             if (falsealm_cnt->cnt_all > 16000)
0467                 digtable->cur_igvalue =
0468                          digtable->rx_gain_max;
0469         /* connected -> connected or disconnected -> disconnected  */
0470         } else {
0471             /* Firmware control DIG, do nothing in driver dm */
0472             return;
0473         }
0474         /* disconnected -> connected or connected ->
0475          * disconnected or beforeconnect->(dis)connected */
0476     } else {
0477         /* Enable FW DIG */
0478         digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
0479         rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE);
0480 
0481         digtable->back_val = DM_DIG_BACKOFF_MAX;
0482         digtable->cur_igvalue = rtlpriv->phy.default_initialgain[0];
0483         digtable->pre_igvalue = 0;
0484         return;
0485     }
0486 
0487     /* Forced writing to prevent from fw-dig overwriting. */
0488     if (digtable->pre_igvalue != rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1,
0489                           MASKBYTE0))
0490         force_write = 1;
0491 
0492     if ((digtable->pre_igvalue != digtable->cur_igvalue) ||
0493         !initialized || force_write) {
0494         /* Disable FW DIG */
0495         rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_DISABLE);
0496 
0497         initial_gain = (u8)digtable->cur_igvalue;
0498 
0499         /* Set initial gain. */
0500         rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, initial_gain);
0501         rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, initial_gain);
0502         digtable->pre_igvalue = digtable->cur_igvalue;
0503         initialized = 1;
0504         force_write = 0;
0505     }
0506 }
0507 
0508 static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw)
0509 {
0510     struct rtl_priv *rtlpriv = rtl_priv(hw);
0511     struct dig_t *dig = &rtlpriv->dm_digtable;
0512 
0513     if (rtlpriv->mac80211.act_scanning)
0514         return;
0515 
0516     /* Decide the current status and if modify initial gain or not */
0517     if (rtlpriv->mac80211.link_state >= MAC80211_LINKED ||
0518         rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
0519         dig->cur_sta_cstate = DIG_STA_CONNECT;
0520     else
0521         dig->cur_sta_cstate = DIG_STA_DISCONNECT;
0522 
0523     dig->rssi_val = rtlpriv->dm.undec_sm_pwdb;
0524 
0525     /* Change dig mode to rssi */
0526     if (dig->cur_sta_cstate != DIG_STA_DISCONNECT) {
0527         if (dig->dig_twoport_algorithm ==
0528             DIG_TWO_PORT_ALGO_FALSE_ALARM) {
0529             dig->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
0530             rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_MODE_SS);
0531         }
0532     }
0533 
0534     _rtl92s_dm_false_alarm_counter_statistics(hw);
0535     _rtl92s_dm_initial_gain_sta_beforeconnect(hw);
0536 
0537     dig->pre_sta_cstate = dig->cur_sta_cstate;
0538 }
0539 
0540 static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw)
0541 {
0542     struct rtl_priv *rtlpriv = rtl_priv(hw);
0543     struct rtl_phy *rtlphy = &(rtlpriv->phy);
0544     struct dig_t *digtable = &rtlpriv->dm_digtable;
0545 
0546     /* 2T2R TP issue */
0547     if (rtlphy->rf_type == RF_2T2R)
0548         return;
0549 
0550     if (!rtlpriv->dm.dm_initialgain_enable)
0551         return;
0552 
0553     if (digtable->dig_enable_flag == false)
0554         return;
0555 
0556     _rtl92s_dm_ctrl_initgain_bytwoport(hw);
0557 }
0558 
0559 static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw)
0560 {
0561     struct rtl_priv *rtlpriv = rtl_priv(hw);
0562     struct rtl_phy *rtlphy = &(rtlpriv->phy);
0563     struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0564     long undec_sm_pwdb;
0565     long txpwr_threshold_lv1, txpwr_threshold_lv2;
0566 
0567     /* 2T2R TP issue */
0568     if (rtlphy->rf_type == RF_2T2R)
0569         return;
0570 
0571     if (!rtlpriv->dm.dynamic_txpower_enable ||
0572         rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
0573         rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
0574         return;
0575     }
0576 
0577     if ((mac->link_state < MAC80211_LINKED) &&
0578         (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
0579         rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,
0580             "Not connected to any\n");
0581 
0582         rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
0583 
0584         rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
0585         return;
0586     }
0587 
0588     if (mac->link_state >= MAC80211_LINKED) {
0589         if (mac->opmode == NL80211_IFTYPE_ADHOC) {
0590             undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
0591             rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0592                 "AP Client PWDB = 0x%lx\n",
0593                 undec_sm_pwdb);
0594         } else {
0595             undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
0596             rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0597                 "STA Default Port PWDB = 0x%lx\n",
0598                 undec_sm_pwdb);
0599         }
0600     } else {
0601         undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
0602 
0603         rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0604             "AP Ext Port PWDB = 0x%lx\n",
0605             undec_sm_pwdb);
0606     }
0607 
0608     txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2;
0609     txpwr_threshold_lv1 = TX_POWER_NEAR_FIELD_THRESH_LVL1;
0610 
0611     if (rtl_get_bbreg(hw, 0xc90, MASKBYTE0) == 1)
0612         rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
0613     else if (undec_sm_pwdb >= txpwr_threshold_lv2)
0614         rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL2;
0615     else if ((undec_sm_pwdb < (txpwr_threshold_lv2 - 3)) &&
0616         (undec_sm_pwdb >= txpwr_threshold_lv1))
0617         rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL1;
0618     else if (undec_sm_pwdb < (txpwr_threshold_lv1 - 3))
0619         rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
0620 
0621     if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl))
0622         rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
0623 
0624     rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
0625 }
0626 
0627 static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw)
0628 {
0629     struct rtl_priv *rtlpriv = rtl_priv(hw);
0630     struct dig_t *digtable = &rtlpriv->dm_digtable;
0631 
0632     /* Disable DIG scheme now.*/
0633     digtable->dig_enable_flag = true;
0634     digtable->backoff_enable_flag = true;
0635 
0636     if ((rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) &&
0637         (hal_get_firmwareversion(rtlpriv) >= 0x3c))
0638         digtable->dig_algorithm = DIG_ALGO_BY_TOW_PORT;
0639     else
0640         digtable->dig_algorithm =
0641              DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM;
0642 
0643     digtable->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
0644     digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
0645     /* off=by real rssi value, on=by digtable->rssi_val for new dig */
0646     digtable->dig_dbgmode = DM_DBG_OFF;
0647     digtable->dig_slgorithm_switch = 0;
0648 
0649     /* 2007/10/04 MH Define init gain threshol. */
0650     digtable->dig_state = DM_STA_DIG_MAX;
0651     digtable->dig_highpwrstate = DM_STA_DIG_MAX;
0652 
0653     digtable->cur_sta_cstate = DIG_STA_DISCONNECT;
0654     digtable->pre_sta_cstate = DIG_STA_DISCONNECT;
0655     digtable->cur_ap_cstate = DIG_AP_DISCONNECT;
0656     digtable->pre_ap_cstate = DIG_AP_DISCONNECT;
0657 
0658     digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
0659     digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
0660 
0661     digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
0662     digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
0663 
0664     digtable->rssi_highpower_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
0665     digtable->rssi_highpower_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
0666 
0667     /* for dig debug rssi value */
0668     digtable->rssi_val = 50;
0669     digtable->back_val = DM_DIG_BACKOFF_MAX;
0670     digtable->rx_gain_max = DM_DIG_MAX;
0671 
0672     digtable->rx_gain_min = DM_DIG_MIN;
0673 
0674     digtable->backoffval_range_max = DM_DIG_BACKOFF_MAX;
0675     digtable->backoffval_range_min = DM_DIG_BACKOFF_MIN;
0676 }
0677 
0678 static void _rtl92s_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
0679 {
0680     struct rtl_priv *rtlpriv = rtl_priv(hw);
0681 
0682     if ((hal_get_firmwareversion(rtlpriv) >= 60) &&
0683         (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER))
0684         rtlpriv->dm.dynamic_txpower_enable = true;
0685     else
0686         rtlpriv->dm.dynamic_txpower_enable = false;
0687 
0688     rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
0689     rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
0690 }
0691 
0692 void rtl92s_dm_init(struct ieee80211_hw *hw)
0693 {
0694     struct rtl_priv *rtlpriv = rtl_priv(hw);
0695 
0696     rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
0697     rtlpriv->dm.undec_sm_pwdb = -1;
0698 
0699     _rtl92s_dm_init_dynamic_txpower(hw);
0700     rtl92s_dm_init_edca_turbo(hw);
0701     _rtl92s_dm_init_rate_adaptive_mask(hw);
0702     _rtl92s_dm_init_txpowertracking_thermalmeter(hw);
0703     _rtl92s_dm_init_dig(hw);
0704 
0705     rtl_write_dword(rtlpriv, WFM5, FW_CCA_CHK_ENABLE);
0706 }
0707 
0708 void rtl92s_dm_watchdog(struct ieee80211_hw *hw)
0709 {
0710     _rtl92s_dm_check_edca_turbo(hw);
0711     _rtl92s_dm_check_txpowertracking_thermalmeter(hw);
0712     _rtl92s_dm_ctrl_initgain_byrssi(hw);
0713     _rtl92s_dm_dynamic_txpower(hw);
0714     _rtl92s_dm_refresh_rateadaptive_mask(hw);
0715     _rtl92s_dm_switch_baseband_mrc(hw);
0716 }
0717