0001
0002
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,
0015 0x5ea44f,
0016 0x5ea44f,
0017 0xa630,
0018 0xa44f,
0019 0xa630,
0020 0xa630,
0021 0xa42b,
0022 };
0023
0024 static const u32 edca_setting_dl_gmode[PEER_MAX] = {
0025 0x4322,
0026 0xa44f,
0027 0x5ea44f,
0028 0xa42b,
0029 0x5e4322,
0030 0x4322,
0031 0xa430,
0032 0x5ea44f,
0033 };
0034
0035 static const u32 edca_setting_ul[PEER_MAX] = {
0036 0x5e4322,
0037 0xa44f,
0038 0x5ea44f,
0039 0x5ea322,
0040 0x5ea422,
0041 0x5ea322,
0042 0x3ea44f,
0043 0x5ea44f,
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
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 {
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
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 *)(¤t_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
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
0318 enable_mrc = true;
0319 } else if (rssi_b < 5) {
0320
0321 enable_mrc = false;
0322
0323 } else if (rssi_a > 15 && (rssi_a >= rssi_b)) {
0324 if ((rssi_a - rssi_b) > 15)
0325
0326 enable_mrc = false;
0327 else if ((rssi_a - rssi_b) < 10)
0328
0329 enable_mrc = true;
0330 else
0331 enable_mrc = current_mrc;
0332 } else {
0333
0334 enable_mrc = true;
0335 }
0336 }
0337
0338
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
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
0470 } else {
0471
0472 return;
0473 }
0474
0475
0476 } else {
0477
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
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
0495 rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_DISABLE);
0496
0497 initial_gain = (u8)digtable->cur_igvalue;
0498
0499
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
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
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
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
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
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
0646 digtable->dig_dbgmode = DM_DBG_OFF;
0647 digtable->dig_slgorithm_switch = 0;
0648
0649
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
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