root/drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _rtl92s_dm_check_edca_turbo
  2. _rtl92s_dm_txpowertracking_callback_thermalmeter
  3. _rtl92s_dm_check_txpowertracking_thermalmeter
  4. _rtl92s_dm_refresh_rateadaptive_mask
  5. _rtl92s_dm_switch_baseband_mrc
  6. rtl92s_dm_init_edca_turbo
  7. _rtl92s_dm_init_rate_adaptive_mask
  8. _rtl92s_dm_init_txpowertracking_thermalmeter
  9. _rtl92s_dm_false_alarm_counter_statistics
  10. rtl92s_backoff_enable_flag
  11. _rtl92s_dm_initial_gain_sta_beforeconnect
  12. _rtl92s_dm_ctrl_initgain_bytwoport
  13. _rtl92s_dm_ctrl_initgain_byrssi
  14. _rtl92s_dm_dynamic_txpower
  15. _rtl92s_dm_init_dig
  16. _rtl92s_dm_init_dynamic_txpower
  17. rtl92s_dm_init
  18. rtl92s_dm_watchdog

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright(c) 2009-2012  Realtek Corporation.*/
   3 
   4 #include "../wifi.h"
   5 #include "../base.h"
   6 #include "../core.h"
   7 #include "reg.h"
   8 #include "def.h"
   9 #include "phy.h"
  10 #include "dm.h"
  11 #include "fw.h"
  12 
  13 static const u32 edca_setting_dl[PEER_MAX] = {
  14         0xa44f,         /* 0 UNKNOWN */
  15         0x5ea44f,       /* 1 REALTEK_90 */
  16         0x5ea44f,       /* 2 REALTEK_92SE */
  17         0xa630,         /* 3 BROAD      */
  18         0xa44f,         /* 4 RAL */
  19         0xa630,         /* 5 ATH */
  20         0xa630,         /* 6 CISCO */
  21         0xa42b,         /* 7 MARV */
  22 };
  23 
  24 static const u32 edca_setting_dl_gmode[PEER_MAX] = {
  25         0x4322,         /* 0 UNKNOWN */
  26         0xa44f,         /* 1 REALTEK_90 */
  27         0x5ea44f,       /* 2 REALTEK_92SE */
  28         0xa42b,         /* 3 BROAD */
  29         0x5e4322,       /* 4 RAL */
  30         0x4322,         /* 5 ATH */
  31         0xa430,         /* 6 CISCO */
  32         0x5ea44f,       /* 7 MARV */
  33 };
  34 
  35 static const u32 edca_setting_ul[PEER_MAX] = {
  36         0x5e4322,       /* 0 UNKNOWN */
  37         0xa44f,         /* 1 REALTEK_90 */
  38         0x5ea44f,       /* 2 REALTEK_92SE */
  39         0x5ea322,       /* 3 BROAD */
  40         0x5ea422,       /* 4 RAL */
  41         0x5ea322,       /* 5 ATH */
  42         0x3ea44f,       /* 6 CISCO */
  43         0x5ea44f,       /* 7 MARV */
  44 };
  45 
  46 static void _rtl92s_dm_check_edca_turbo(struct ieee80211_hw *hw)
  47 {
  48         struct rtl_priv *rtlpriv = rtl_priv(hw);
  49         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  50 
  51         static u64 last_txok_cnt;
  52         static u64 last_rxok_cnt;
  53         u64 cur_txok_cnt = 0;
  54         u64 cur_rxok_cnt = 0;
  55 
  56         u32 edca_be_ul = edca_setting_ul[mac->vendor];
  57         u32 edca_be_dl = edca_setting_dl[mac->vendor];
  58         u32 edca_gmode = edca_setting_dl_gmode[mac->vendor];
  59 
  60         if (mac->link_state != MAC80211_LINKED) {
  61                 rtlpriv->dm.current_turbo_edca = false;
  62                 goto dm_checkedcaturbo_exit;
  63         }
  64 
  65         if ((!rtlpriv->dm.is_any_nonbepkts) &&
  66             (!rtlpriv->dm.disable_framebursting)) {
  67                 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
  68                 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
  69 
  70                 if (rtlpriv->phy.rf_type == RF_1T2R) {
  71                         if (cur_txok_cnt > 4 * cur_rxok_cnt) {
  72                                 /* Uplink TP is present. */
  73                                 if (rtlpriv->dm.is_cur_rdlstate ||
  74                                         !rtlpriv->dm.current_turbo_edca) {
  75                                         rtl_write_dword(rtlpriv, EDCAPARA_BE,
  76                                                         edca_be_ul);
  77                                         rtlpriv->dm.is_cur_rdlstate = false;
  78                                 }
  79                         } else {/* Balance TP is present. */
  80                                 if (!rtlpriv->dm.is_cur_rdlstate ||
  81                                         !rtlpriv->dm.current_turbo_edca) {
  82                                         if (mac->mode == WIRELESS_MODE_G ||
  83                                             mac->mode == WIRELESS_MODE_B)
  84                                                 rtl_write_dword(rtlpriv,
  85                                                                 EDCAPARA_BE,
  86                                                                 edca_gmode);
  87                                         else
  88                                                 rtl_write_dword(rtlpriv,
  89                                                                 EDCAPARA_BE,
  90                                                                 edca_be_dl);
  91                                         rtlpriv->dm.is_cur_rdlstate = true;
  92                                 }
  93                         }
  94                         rtlpriv->dm.current_turbo_edca = true;
  95                 } else {
  96                         if (cur_rxok_cnt > 4 * cur_txok_cnt) {
  97                                 if (!rtlpriv->dm.is_cur_rdlstate ||
  98                                         !rtlpriv->dm.current_turbo_edca) {
  99                                         if (mac->mode == WIRELESS_MODE_G ||
 100                                             mac->mode == WIRELESS_MODE_B)
 101                                                 rtl_write_dword(rtlpriv,
 102                                                                 EDCAPARA_BE,
 103                                                                 edca_gmode);
 104                                         else
 105                                                 rtl_write_dword(rtlpriv,
 106                                                                 EDCAPARA_BE,
 107                                                                 edca_be_dl);
 108                                         rtlpriv->dm.is_cur_rdlstate = true;
 109                                 }
 110                         } else {
 111                                 if (rtlpriv->dm.is_cur_rdlstate ||
 112                                         !rtlpriv->dm.current_turbo_edca) {
 113                                         rtl_write_dword(rtlpriv, EDCAPARA_BE,
 114                                                         edca_be_ul);
 115                                         rtlpriv->dm.is_cur_rdlstate = false;
 116                                 }
 117                         }
 118                         rtlpriv->dm.current_turbo_edca = true;
 119                 }
 120         } else {
 121                 if (rtlpriv->dm.current_turbo_edca) {
 122                         u8 tmp = AC0_BE;
 123                         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
 124                                                       &tmp);
 125                         rtlpriv->dm.current_turbo_edca = false;
 126                 }
 127         }
 128 
 129 dm_checkedcaturbo_exit:
 130         rtlpriv->dm.is_any_nonbepkts = false;
 131         last_txok_cnt = rtlpriv->stats.txbytesunicast;
 132         last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
 133 }
 134 
 135 static void _rtl92s_dm_txpowertracking_callback_thermalmeter(
 136                                         struct ieee80211_hw *hw)
 137 {
 138         struct rtl_priv *rtlpriv = rtl_priv(hw);
 139         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 140         u8 thermalvalue = 0;
 141         u32 fw_cmd = 0;
 142 
 143         rtlpriv->dm.txpower_trackinginit = true;
 144 
 145         thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
 146 
 147         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
 148                  "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermal meter 0x%x\n",
 149                  thermalvalue,
 150                  rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter);
 151 
 152         if (thermalvalue) {
 153                 rtlpriv->dm.thermalvalue = thermalvalue;
 154                 if (hal_get_firmwareversion(rtlpriv) >= 0x35) {
 155                         rtl92s_phy_set_fw_cmd(hw, FW_CMD_TXPWR_TRACK_THERMAL);
 156                 } else {
 157                         fw_cmd = (FW_TXPWR_TRACK_THERMAL |
 158                                  (rtlpriv->efuse.thermalmeter[0] << 8) |
 159                                  (thermalvalue << 16));
 160 
 161                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
 162                                  "Write to FW Thermal Val = 0x%x\n", fw_cmd);
 163 
 164                         rtl_write_dword(rtlpriv, WFM5, fw_cmd);
 165                         rtl92s_phy_chk_fwcmd_iodone(hw);
 166                 }
 167         }
 168 
 169         rtlpriv->dm.txpowercount = 0;
 170 }
 171 
 172 static void _rtl92s_dm_check_txpowertracking_thermalmeter(
 173                                         struct ieee80211_hw *hw)
 174 {
 175         struct rtl_priv *rtlpriv = rtl_priv(hw);
 176         struct rtl_phy *rtlphy = &(rtlpriv->phy);
 177         u8 tx_power_checkcnt = 5;
 178 
 179         /* 2T2R TP issue */
 180         if (rtlphy->rf_type == RF_2T2R)
 181                 return;
 182 
 183         if (!rtlpriv->dm.txpower_tracking)
 184                 return;
 185 
 186         if (rtlpriv->dm.txpowercount <= tx_power_checkcnt) {
 187                 rtlpriv->dm.txpowercount++;
 188                 return;
 189         }
 190 
 191         if (!rtlpriv->dm.tm_trigger) {
 192                 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER,
 193                               RFREG_OFFSET_MASK, 0x60);
 194                 rtlpriv->dm.tm_trigger = 1;
 195         } else {
 196                 _rtl92s_dm_txpowertracking_callback_thermalmeter(hw);
 197                 rtlpriv->dm.tm_trigger = 0;
 198         }
 199 }
 200 
 201 static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
 202 {
 203         struct rtl_priv *rtlpriv = rtl_priv(hw);
 204         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 205         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 206         struct rate_adaptive *ra = &(rtlpriv->ra);
 207         struct ieee80211_sta *sta = NULL;
 208         u32 low_rssi_thresh = 0;
 209         u32 middle_rssi_thresh = 0;
 210         u32 high_rssi_thresh = 0;
 211 
 212         if (is_hal_stop(rtlhal))
 213                 return;
 214 
 215         if (!rtlpriv->dm.useramask)
 216                 return;
 217 
 218         if (hal_get_firmwareversion(rtlpriv) >= 61 &&
 219             !rtlpriv->dm.inform_fw_driverctrldm) {
 220                 rtl92s_phy_set_fw_cmd(hw, FW_CMD_CTRL_DM_BY_DRIVER);
 221                 rtlpriv->dm.inform_fw_driverctrldm = true;
 222         }
 223 
 224         if ((mac->link_state == MAC80211_LINKED) &&
 225             (mac->opmode == NL80211_IFTYPE_STATION)) {
 226                 switch (ra->pre_ratr_state) {
 227                 case DM_RATR_STA_HIGH:
 228                         high_rssi_thresh = 40;
 229                         middle_rssi_thresh = 30;
 230                         low_rssi_thresh = 20;
 231                         break;
 232                 case DM_RATR_STA_MIDDLE:
 233                         high_rssi_thresh = 44;
 234                         middle_rssi_thresh = 30;
 235                         low_rssi_thresh = 20;
 236                         break;
 237                 case DM_RATR_STA_LOW:
 238                         high_rssi_thresh = 44;
 239                         middle_rssi_thresh = 34;
 240                         low_rssi_thresh = 20;
 241                         break;
 242                 case DM_RATR_STA_ULTRALOW:
 243                         high_rssi_thresh = 44;
 244                         middle_rssi_thresh = 34;
 245                         low_rssi_thresh = 24;
 246                         break;
 247                 default:
 248                         high_rssi_thresh = 44;
 249                         middle_rssi_thresh = 34;
 250                         low_rssi_thresh = 24;
 251                         break;
 252                 }
 253 
 254                 if (rtlpriv->dm.undec_sm_pwdb > (long)high_rssi_thresh) {
 255                         ra->ratr_state = DM_RATR_STA_HIGH;
 256                 } else if (rtlpriv->dm.undec_sm_pwdb >
 257                            (long)middle_rssi_thresh) {
 258                         ra->ratr_state = DM_RATR_STA_LOW;
 259                 } else if (rtlpriv->dm.undec_sm_pwdb >
 260                            (long)low_rssi_thresh) {
 261                         ra->ratr_state = DM_RATR_STA_LOW;
 262                 } else {
 263                         ra->ratr_state = DM_RATR_STA_ULTRALOW;
 264                 }
 265 
 266                 if (ra->pre_ratr_state != ra->ratr_state) {
 267                         RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
 268                                  "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
 269                                  rtlpriv->dm.undec_sm_pwdb, ra->ratr_state,
 270                                  ra->pre_ratr_state, ra->ratr_state);
 271 
 272                         rcu_read_lock();
 273                         sta = rtl_find_sta(hw, mac->bssid);
 274                         if (sta)
 275                                 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
 276                                                            ra->ratr_state,
 277                                                            true);
 278                         rcu_read_unlock();
 279 
 280                         ra->pre_ratr_state = ra->ratr_state;
 281                 }
 282         }
 283 }
 284 
 285 static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw)
 286 {
 287         struct rtl_priv *rtlpriv = rtl_priv(hw);
 288         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 289         struct rtl_phy *rtlphy = &(rtlpriv->phy);
 290         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 291         bool current_mrc;
 292         bool enable_mrc = true;
 293         long tmpentry_maxpwdb = 0;
 294         u8 rssi_a = 0;
 295         u8 rssi_b = 0;
 296 
 297         if (is_hal_stop(rtlhal))
 298                 return;
 299 
 300         if ((rtlphy->rf_type == RF_1T1R) || (rtlphy->rf_type == RF_2T2R))
 301                 return;
 302 
 303         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MRC, (u8 *)(&current_mrc));
 304 
 305         if (mac->link_state >= MAC80211_LINKED) {
 306                 if (rtlpriv->dm.undec_sm_pwdb > tmpentry_maxpwdb) {
 307                         rssi_a = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_A];
 308                         rssi_b = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_B];
 309                 }
 310         }
 311 
 312         /* MRC settings would NOT affect TP on Wireless B mode. */
 313         if (mac->mode != WIRELESS_MODE_B) {
 314                 if ((rssi_a == 0) && (rssi_b == 0)) {
 315                         enable_mrc = true;
 316                 } else if (rssi_b > 30) {
 317                         /* Turn on B-Path */
 318                         enable_mrc = true;
 319                 } else if (rssi_b < 5) {
 320                         /* Turn off B-path  */
 321                         enable_mrc = false;
 322                 /* Take care of RSSI differentiation. */
 323                 } else if (rssi_a > 15 && (rssi_a >= rssi_b)) {
 324                         if ((rssi_a - rssi_b) > 15)
 325                                 /* Turn off B-path  */
 326                                 enable_mrc = false;
 327                         else if ((rssi_a - rssi_b) < 10)
 328                                 /* Turn on B-Path */
 329                                 enable_mrc = true;
 330                         else
 331                                 enable_mrc = current_mrc;
 332                 } else {
 333                         /* Turn on B-Path */
 334                         enable_mrc = true;
 335                 }
 336         }
 337 
 338         /* Update MRC settings if needed. */
 339         if (enable_mrc != current_mrc)
 340                 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC,
 341                                               (u8 *)&enable_mrc);
 342 
 343 }
 344 
 345 void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw)
 346 {
 347         struct rtl_priv *rtlpriv = rtl_priv(hw);
 348 
 349         rtlpriv->dm.current_turbo_edca = false;
 350         rtlpriv->dm.is_any_nonbepkts = false;
 351         rtlpriv->dm.is_cur_rdlstate = false;
 352 }
 353 
 354 static void _rtl92s_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
 355 {
 356         struct rtl_priv *rtlpriv = rtl_priv(hw);
 357         struct rate_adaptive *ra = &(rtlpriv->ra);
 358 
 359         ra->ratr_state = DM_RATR_STA_MAX;
 360         ra->pre_ratr_state = DM_RATR_STA_MAX;
 361 
 362         if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER &&
 363             hal_get_firmwareversion(rtlpriv) >= 60)
 364                 rtlpriv->dm.useramask = true;
 365         else
 366                 rtlpriv->dm.useramask = false;
 367 
 368         rtlpriv->dm.useramask = false;
 369         rtlpriv->dm.inform_fw_driverctrldm = false;
 370 }
 371 
 372 static void _rtl92s_dm_init_txpowertracking_thermalmeter(
 373                                 struct ieee80211_hw *hw)
 374 {
 375         struct rtl_priv *rtlpriv = rtl_priv(hw);
 376 
 377         rtlpriv->dm.txpower_tracking = true;
 378         rtlpriv->dm.txpowercount = 0;
 379         rtlpriv->dm.txpower_trackinginit = false;
 380 }
 381 
 382 static void _rtl92s_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
 383 {
 384         struct rtl_priv *rtlpriv = rtl_priv(hw);
 385         struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
 386         u32 ret_value;
 387 
 388         ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
 389         falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
 390 
 391         ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
 392         falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
 393         falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
 394         ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
 395         falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
 396 
 397         falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
 398                 falsealm_cnt->cnt_rate_illegal + falsealm_cnt->cnt_crc8_fail +
 399                 falsealm_cnt->cnt_mcs_fail;
 400 
 401         /* read CCK false alarm */
 402         ret_value = rtl_get_bbreg(hw, 0xc64, MASKDWORD);
 403         falsealm_cnt->cnt_cck_fail = (ret_value & 0xffff);
 404         falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail +
 405                 falsealm_cnt->cnt_cck_fail;
 406 }
 407 
 408 static void rtl92s_backoff_enable_flag(struct ieee80211_hw *hw)
 409 {
 410         struct rtl_priv *rtlpriv = rtl_priv(hw);
 411         struct dig_t *digtable = &rtlpriv->dm_digtable;
 412         struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
 413 
 414         if (falsealm_cnt->cnt_all > digtable->fa_highthresh) {
 415                 if ((digtable->back_val - 6) <
 416                         digtable->backoffval_range_min)
 417                         digtable->back_val = digtable->backoffval_range_min;
 418                 else
 419                         digtable->back_val -= 6;
 420         } else if (falsealm_cnt->cnt_all < digtable->fa_lowthresh) {
 421                 if ((digtable->back_val + 6) >
 422                         digtable->backoffval_range_max)
 423                         digtable->back_val =
 424                                  digtable->backoffval_range_max;
 425                 else
 426                         digtable->back_val += 6;
 427         }
 428 }
 429 
 430 static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
 431 {
 432         struct rtl_priv *rtlpriv = rtl_priv(hw);
 433         struct dig_t *digtable = &rtlpriv->dm_digtable;
 434         struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
 435         static u8 initialized, force_write;
 436         u8 initial_gain = 0;
 437 
 438         if ((digtable->pre_sta_cstate == digtable->cur_sta_cstate) ||
 439             (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT)) {
 440                 if (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT) {
 441                         if (rtlpriv->psc.rfpwr_state != ERFON)
 442                                 return;
 443 
 444                         if (digtable->backoff_enable_flag)
 445                                 rtl92s_backoff_enable_flag(hw);
 446                         else
 447                                 digtable->back_val = DM_DIG_BACKOFF_MAX;
 448 
 449                         if ((digtable->rssi_val + 10 - digtable->back_val) >
 450                                 digtable->rx_gain_max)
 451                                 digtable->cur_igvalue =
 452                                                 digtable->rx_gain_max;
 453                         else if ((digtable->rssi_val + 10 - digtable->back_val)
 454                                  < digtable->rx_gain_min)
 455                                 digtable->cur_igvalue =
 456                                                 digtable->rx_gain_min;
 457                         else
 458                                 digtable->cur_igvalue = digtable->rssi_val + 10
 459                                         - digtable->back_val;
 460 
 461                         if (falsealm_cnt->cnt_all > 10000)
 462                                 digtable->cur_igvalue =
 463                                          (digtable->cur_igvalue > 0x33) ?
 464                                          digtable->cur_igvalue : 0x33;
 465 
 466                         if (falsealm_cnt->cnt_all > 16000)
 467                                 digtable->cur_igvalue =
 468                                                  digtable->rx_gain_max;
 469                 /* connected -> connected or disconnected -> disconnected  */
 470                 } else {
 471                         /* Firmware control DIG, do nothing in driver dm */
 472                         return;
 473                 }
 474                 /* disconnected -> connected or connected ->
 475                  * disconnected or beforeconnect->(dis)connected */
 476         } else {
 477                 /* Enable FW DIG */
 478                 digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
 479                 rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE);
 480 
 481                 digtable->back_val = DM_DIG_BACKOFF_MAX;
 482                 digtable->cur_igvalue = rtlpriv->phy.default_initialgain[0];
 483                 digtable->pre_igvalue = 0;
 484                 return;
 485         }
 486 
 487         /* Forced writing to prevent from fw-dig overwriting. */
 488         if (digtable->pre_igvalue != rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1,
 489                                                   MASKBYTE0))
 490                 force_write = 1;
 491 
 492         if ((digtable->pre_igvalue != digtable->cur_igvalue) ||
 493             !initialized || force_write) {
 494                 /* Disable FW DIG */
 495                 rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_DISABLE);
 496 
 497                 initial_gain = (u8)digtable->cur_igvalue;
 498 
 499                 /* Set initial gain. */
 500                 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, initial_gain);
 501                 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, initial_gain);
 502                 digtable->pre_igvalue = digtable->cur_igvalue;
 503                 initialized = 1;
 504                 force_write = 0;
 505         }
 506 }
 507 
 508 static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw)
 509 {
 510         struct rtl_priv *rtlpriv = rtl_priv(hw);
 511         struct dig_t *dig = &rtlpriv->dm_digtable;
 512 
 513         if (rtlpriv->mac80211.act_scanning)
 514                 return;
 515 
 516         /* Decide the current status and if modify initial gain or not */
 517         if (rtlpriv->mac80211.link_state >= MAC80211_LINKED ||
 518             rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
 519                 dig->cur_sta_cstate = DIG_STA_CONNECT;
 520         else
 521                 dig->cur_sta_cstate = DIG_STA_DISCONNECT;
 522 
 523         dig->rssi_val = rtlpriv->dm.undec_sm_pwdb;
 524 
 525         /* Change dig mode to rssi */
 526         if (dig->cur_sta_cstate != DIG_STA_DISCONNECT) {
 527                 if (dig->dig_twoport_algorithm ==
 528                     DIG_TWO_PORT_ALGO_FALSE_ALARM) {
 529                         dig->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
 530                         rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_MODE_SS);
 531                 }
 532         }
 533 
 534         _rtl92s_dm_false_alarm_counter_statistics(hw);
 535         _rtl92s_dm_initial_gain_sta_beforeconnect(hw);
 536 
 537         dig->pre_sta_cstate = dig->cur_sta_cstate;
 538 }
 539 
 540 static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw)
 541 {
 542         struct rtl_priv *rtlpriv = rtl_priv(hw);
 543         struct rtl_phy *rtlphy = &(rtlpriv->phy);
 544         struct dig_t *digtable = &rtlpriv->dm_digtable;
 545 
 546         /* 2T2R TP issue */
 547         if (rtlphy->rf_type == RF_2T2R)
 548                 return;
 549 
 550         if (!rtlpriv->dm.dm_initialgain_enable)
 551                 return;
 552 
 553         if (digtable->dig_enable_flag == false)
 554                 return;
 555 
 556         _rtl92s_dm_ctrl_initgain_bytwoport(hw);
 557 }
 558 
 559 static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw)
 560 {
 561         struct rtl_priv *rtlpriv = rtl_priv(hw);
 562         struct rtl_phy *rtlphy = &(rtlpriv->phy);
 563         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 564         long undec_sm_pwdb;
 565         long txpwr_threshold_lv1, txpwr_threshold_lv2;
 566 
 567         /* 2T2R TP issue */
 568         if (rtlphy->rf_type == RF_2T2R)
 569                 return;
 570 
 571         if (!rtlpriv->dm.dynamic_txpower_enable ||
 572             rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
 573                 rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
 574                 return;
 575         }
 576 
 577         if ((mac->link_state < MAC80211_LINKED) &&
 578             (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
 579                 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
 580                          "Not connected to any\n");
 581 
 582                 rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
 583 
 584                 rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
 585                 return;
 586         }
 587 
 588         if (mac->link_state >= MAC80211_LINKED) {
 589                 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
 590                         undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
 591                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 592                                  "AP Client PWDB = 0x%lx\n",
 593                                  undec_sm_pwdb);
 594                 } else {
 595                         undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
 596                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 597                                  "STA Default Port PWDB = 0x%lx\n",
 598                                  undec_sm_pwdb);
 599                 }
 600         } else {
 601                 undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
 602 
 603                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 604                          "AP Ext Port PWDB = 0x%lx\n",
 605                          undec_sm_pwdb);
 606         }
 607 
 608         txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2;
 609         txpwr_threshold_lv1 = TX_POWER_NEAR_FIELD_THRESH_LVL1;
 610 
 611         if (rtl_get_bbreg(hw, 0xc90, MASKBYTE0) == 1)
 612                 rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
 613         else if (undec_sm_pwdb >= txpwr_threshold_lv2)
 614                 rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL2;
 615         else if ((undec_sm_pwdb < (txpwr_threshold_lv2 - 3)) &&
 616                 (undec_sm_pwdb >= txpwr_threshold_lv1))
 617                 rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL1;
 618         else if (undec_sm_pwdb < (txpwr_threshold_lv1 - 3))
 619                 rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
 620 
 621         if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl))
 622                 rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
 623 
 624         rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
 625 }
 626 
 627 static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw)
 628 {
 629         struct rtl_priv *rtlpriv = rtl_priv(hw);
 630         struct dig_t *digtable = &rtlpriv->dm_digtable;
 631 
 632         /* Disable DIG scheme now.*/
 633         digtable->dig_enable_flag = true;
 634         digtable->backoff_enable_flag = true;
 635 
 636         if ((rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) &&
 637             (hal_get_firmwareversion(rtlpriv) >= 0x3c))
 638                 digtable->dig_algorithm = DIG_ALGO_BY_TOW_PORT;
 639         else
 640                 digtable->dig_algorithm =
 641                          DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM;
 642 
 643         digtable->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
 644         digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
 645         /* off=by real rssi value, on=by digtable->rssi_val for new dig */
 646         digtable->dig_dbgmode = DM_DBG_OFF;
 647         digtable->dig_slgorithm_switch = 0;
 648 
 649         /* 2007/10/04 MH Define init gain threshol. */
 650         digtable->dig_state = DM_STA_DIG_MAX;
 651         digtable->dig_highpwrstate = DM_STA_DIG_MAX;
 652 
 653         digtable->cur_sta_cstate = DIG_STA_DISCONNECT;
 654         digtable->pre_sta_cstate = DIG_STA_DISCONNECT;
 655         digtable->cur_ap_cstate = DIG_AP_DISCONNECT;
 656         digtable->pre_ap_cstate = DIG_AP_DISCONNECT;
 657 
 658         digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
 659         digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
 660 
 661         digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
 662         digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
 663 
 664         digtable->rssi_highpower_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
 665         digtable->rssi_highpower_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
 666 
 667         /* for dig debug rssi value */
 668         digtable->rssi_val = 50;
 669         digtable->back_val = DM_DIG_BACKOFF_MAX;
 670         digtable->rx_gain_max = DM_DIG_MAX;
 671 
 672         digtable->rx_gain_min = DM_DIG_MIN;
 673 
 674         digtable->backoffval_range_max = DM_DIG_BACKOFF_MAX;
 675         digtable->backoffval_range_min = DM_DIG_BACKOFF_MIN;
 676 }
 677 
 678 static void _rtl92s_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
 679 {
 680         struct rtl_priv *rtlpriv = rtl_priv(hw);
 681 
 682         if ((hal_get_firmwareversion(rtlpriv) >= 60) &&
 683             (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER))
 684                 rtlpriv->dm.dynamic_txpower_enable = true;
 685         else
 686                 rtlpriv->dm.dynamic_txpower_enable = false;
 687 
 688         rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
 689         rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
 690 }
 691 
 692 void rtl92s_dm_init(struct ieee80211_hw *hw)
 693 {
 694         struct rtl_priv *rtlpriv = rtl_priv(hw);
 695 
 696         rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
 697         rtlpriv->dm.undec_sm_pwdb = -1;
 698 
 699         _rtl92s_dm_init_dynamic_txpower(hw);
 700         rtl92s_dm_init_edca_turbo(hw);
 701         _rtl92s_dm_init_rate_adaptive_mask(hw);
 702         _rtl92s_dm_init_txpowertracking_thermalmeter(hw);
 703         _rtl92s_dm_init_dig(hw);
 704 
 705         rtl_write_dword(rtlpriv, WFM5, FW_CCA_CHK_ENABLE);
 706 }
 707 
 708 void rtl92s_dm_watchdog(struct ieee80211_hw *hw)
 709 {
 710         _rtl92s_dm_check_edca_turbo(hw);
 711         _rtl92s_dm_check_txpowertracking_thermalmeter(hw);
 712         _rtl92s_dm_ctrl_initgain_byrssi(hw);
 713         _rtl92s_dm_dynamic_txpower(hw);
 714         _rtl92s_dm_refresh_rateadaptive_mask(hw);
 715         _rtl92s_dm_switch_baseband_mrc(hw);
 716 }
 717 

/* [<][>][^][v][top][bottom][index][help] */