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 #define UNDEC_SM_PWDB entry_min_undec_sm_pwdb
0014
0015 static const u32 ofdmswing_table[OFDM_TABLE_SIZE_92D] = {
0016 0x7f8001fe,
0017 0x788001e2,
0018 0x71c001c7,
0019 0x6b8001ae,
0020 0x65400195,
0021 0x5fc0017f,
0022 0x5a400169,
0023 0x55400155,
0024 0x50800142,
0025 0x4c000130,
0026 0x47c0011f,
0027 0x43c0010f,
0028 0x40000100,
0029 0x3c8000f2,
0030 0x390000e4,
0031 0x35c000d7,
0032 0x32c000cb,
0033 0x300000c0,
0034 0x2d4000b5,
0035 0x2ac000ab,
0036 0x288000a2,
0037 0x26000098,
0038 0x24000090,
0039 0x22000088,
0040 0x20000080,
0041 0x1e400079,
0042 0x1c800072,
0043 0x1b00006c,
0044 0x19800066,
0045 0x18000060,
0046 0x16c0005b,
0047 0x15800056,
0048 0x14400051,
0049 0x1300004c,
0050 0x12000048,
0051 0x11000044,
0052 0x10000040,
0053 0x0f00003c,
0054 0x0e400039,
0055 0x0d800036,
0056 0x0cc00033,
0057 0x0c000030,
0058 0x0b40002d,
0059 };
0060
0061 static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
0062 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
0063 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
0064 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
0065 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
0066 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
0067 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
0068 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
0069 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
0070 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
0071 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
0072 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
0073 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
0074 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
0075 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
0076 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
0077 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
0078 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
0079 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
0080 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
0081 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
0082 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
0083 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
0084 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},
0085 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},
0086 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},
0087 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},
0088 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},
0089 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
0090 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},
0091 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},
0092 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},
0093 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},
0094 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}
0095 };
0096
0097 static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
0098 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
0099 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
0100 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
0101 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},
0102 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
0103 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},
0104 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
0105 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
0106 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
0107 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
0108 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
0109 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
0110 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
0111 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
0112 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
0113 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
0114 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
0115 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
0116 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
0117 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
0118 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
0119 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
0120 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},
0121 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
0122 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
0123 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},
0124 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
0125 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
0126 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
0127 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
0128 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
0129 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
0130 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
0131 };
0132
0133 static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
0134 {
0135 u32 ret_value;
0136 struct rtl_priv *rtlpriv = rtl_priv(hw);
0137 struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
0138 unsigned long flag = 0;
0139
0140
0141 rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1);
0142 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1);
0143
0144 ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);
0145 falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff);
0146 falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16);
0147 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
0148 falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
0149 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
0150 falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
0151 falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
0152 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
0153 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
0154 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
0155 falsealm_cnt->cnt_rate_illegal +
0156 falsealm_cnt->cnt_crc8_fail +
0157 falsealm_cnt->cnt_mcs_fail +
0158 falsealm_cnt->cnt_fast_fsync_fail +
0159 falsealm_cnt->cnt_sb_search_fail;
0160
0161 if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) {
0162
0163 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
0164 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
0165 falsealm_cnt->cnt_cck_fail = ret_value;
0166 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
0167 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
0168 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
0169 } else {
0170 falsealm_cnt->cnt_cck_fail = 0;
0171 }
0172
0173
0174 falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail +
0175 falsealm_cnt->cnt_sb_search_fail +
0176 falsealm_cnt->cnt_parity_fail +
0177 falsealm_cnt->cnt_rate_illegal +
0178 falsealm_cnt->cnt_crc8_fail +
0179 falsealm_cnt->cnt_mcs_fail +
0180 falsealm_cnt->cnt_cck_fail;
0181
0182 rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
0183
0184 rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
0185
0186 rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 0);
0187
0188 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 0);
0189 if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) {
0190
0191 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
0192 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
0193
0194 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
0195 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
0196 }
0197 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
0198 "Cnt_Fast_Fsync_fail = %x, Cnt_SB_Search_fail = %x\n",
0199 falsealm_cnt->cnt_fast_fsync_fail,
0200 falsealm_cnt->cnt_sb_search_fail);
0201 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
0202 "Cnt_Parity_Fail = %x, Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, Cnt_Mcs_fail = %x\n",
0203 falsealm_cnt->cnt_parity_fail,
0204 falsealm_cnt->cnt_rate_illegal,
0205 falsealm_cnt->cnt_crc8_fail,
0206 falsealm_cnt->cnt_mcs_fail);
0207 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
0208 "Cnt_Ofdm_fail = %x, Cnt_Cck_fail = %x, Cnt_all = %x\n",
0209 falsealm_cnt->cnt_ofdm_fail,
0210 falsealm_cnt->cnt_cck_fail,
0211 falsealm_cnt->cnt_all);
0212 }
0213
0214 static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw)
0215 {
0216 struct rtl_priv *rtlpriv = rtl_priv(hw);
0217 struct dig_t *de_digtable = &rtlpriv->dm_digtable;
0218 struct rtl_mac *mac = rtl_mac(rtlpriv);
0219
0220
0221 if ((mac->link_state < MAC80211_LINKED) &&
0222 (rtlpriv->dm.UNDEC_SM_PWDB == 0)) {
0223 de_digtable->min_undec_pwdb_for_dm = 0;
0224 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
0225 "Not connected to any\n");
0226 }
0227 if (mac->link_state >= MAC80211_LINKED) {
0228 if (mac->opmode == NL80211_IFTYPE_AP ||
0229 mac->opmode == NL80211_IFTYPE_ADHOC) {
0230 de_digtable->min_undec_pwdb_for_dm =
0231 rtlpriv->dm.UNDEC_SM_PWDB;
0232 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
0233 "AP Client PWDB = 0x%lx\n",
0234 rtlpriv->dm.UNDEC_SM_PWDB);
0235 } else {
0236 de_digtable->min_undec_pwdb_for_dm =
0237 rtlpriv->dm.undec_sm_pwdb;
0238 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
0239 "STA Default Port PWDB = 0x%x\n",
0240 de_digtable->min_undec_pwdb_for_dm);
0241 }
0242 } else {
0243 de_digtable->min_undec_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB;
0244 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
0245 "AP Ext Port or disconnect PWDB = 0x%x\n",
0246 de_digtable->min_undec_pwdb_for_dm);
0247 }
0248
0249 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n",
0250 de_digtable->min_undec_pwdb_for_dm);
0251 }
0252
0253 static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
0254 {
0255 struct rtl_priv *rtlpriv = rtl_priv(hw);
0256 struct dig_t *de_digtable = &rtlpriv->dm_digtable;
0257 unsigned long flag = 0;
0258
0259 if (de_digtable->cursta_cstate == DIG_STA_CONNECT) {
0260 if (de_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
0261 if (de_digtable->min_undec_pwdb_for_dm <= 25)
0262 de_digtable->cur_cck_pd_state =
0263 CCK_PD_STAGE_LOWRSSI;
0264 else
0265 de_digtable->cur_cck_pd_state =
0266 CCK_PD_STAGE_HIGHRSSI;
0267 } else {
0268 if (de_digtable->min_undec_pwdb_for_dm <= 20)
0269 de_digtable->cur_cck_pd_state =
0270 CCK_PD_STAGE_LOWRSSI;
0271 else
0272 de_digtable->cur_cck_pd_state =
0273 CCK_PD_STAGE_HIGHRSSI;
0274 }
0275 } else {
0276 de_digtable->cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI;
0277 }
0278 if (de_digtable->pre_cck_pd_state != de_digtable->cur_cck_pd_state) {
0279 if (de_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
0280 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
0281 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83);
0282 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
0283 } else {
0284 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
0285 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
0286 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
0287 }
0288 de_digtable->pre_cck_pd_state = de_digtable->cur_cck_pd_state;
0289 }
0290 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "CurSTAConnectState=%s\n",
0291 de_digtable->cursta_cstate == DIG_STA_CONNECT ?
0292 "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT");
0293 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "CCKPDStage=%s\n",
0294 de_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ?
0295 "Low RSSI " : "High RSSI ");
0296 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "is92d single phy =%x\n",
0297 IS_92D_SINGLEPHY(rtlpriv->rtlhal.version));
0298
0299 }
0300
0301 void rtl92d_dm_write_dig(struct ieee80211_hw *hw)
0302 {
0303 struct rtl_priv *rtlpriv = rtl_priv(hw);
0304 struct dig_t *de_digtable = &rtlpriv->dm_digtable;
0305
0306 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
0307 "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n",
0308 de_digtable->cur_igvalue, de_digtable->pre_igvalue,
0309 de_digtable->back_val);
0310 if (de_digtable->dig_enable_flag == false) {
0311 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "DIG is disabled\n");
0312 de_digtable->pre_igvalue = 0x17;
0313 return;
0314 }
0315 if (de_digtable->pre_igvalue != de_digtable->cur_igvalue) {
0316 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
0317 de_digtable->cur_igvalue);
0318 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
0319 de_digtable->cur_igvalue);
0320 de_digtable->pre_igvalue = de_digtable->cur_igvalue;
0321 }
0322 }
0323
0324 static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv)
0325 {
0326 struct dig_t *de_digtable = &rtlpriv->dm_digtable;
0327
0328 if ((rtlpriv->mac80211.link_state >= MAC80211_LINKED) &&
0329 (rtlpriv->mac80211.vendor == PEER_CISCO)) {
0330 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "IOT_PEER = CISCO\n");
0331 if (de_digtable->last_min_undec_pwdb_for_dm >= 50
0332 && de_digtable->min_undec_pwdb_for_dm < 50) {
0333 rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00);
0334 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
0335 "Early Mode Off\n");
0336 } else if (de_digtable->last_min_undec_pwdb_for_dm <= 55 &&
0337 de_digtable->min_undec_pwdb_for_dm > 55) {
0338 rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f);
0339 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
0340 "Early Mode On\n");
0341 }
0342 } else if (!(rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL) & 0xf)) {
0343 rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f);
0344 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Early Mode On\n");
0345 }
0346 }
0347
0348 static void rtl92d_dm_dig(struct ieee80211_hw *hw)
0349 {
0350 struct rtl_priv *rtlpriv = rtl_priv(hw);
0351 struct dig_t *de_digtable = &rtlpriv->dm_digtable;
0352 u8 value_igi = de_digtable->cur_igvalue;
0353 struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
0354
0355 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "==>\n");
0356 if (rtlpriv->rtlhal.earlymode_enable) {
0357 rtl92d_early_mode_enabled(rtlpriv);
0358 de_digtable->last_min_undec_pwdb_for_dm =
0359 de_digtable->min_undec_pwdb_for_dm;
0360 }
0361 if (!rtlpriv->dm.dm_initialgain_enable)
0362 return;
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372 if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
0373 return;
0374 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "progress\n");
0375
0376 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
0377 de_digtable->cursta_cstate = DIG_STA_CONNECT;
0378 else
0379 de_digtable->cursta_cstate = DIG_STA_DISCONNECT;
0380
0381
0382 if (falsealm_cnt->cnt_all < DM_DIG_FA_TH0)
0383 value_igi--;
0384 else if (falsealm_cnt->cnt_all < DM_DIG_FA_TH1)
0385 value_igi += 0;
0386 else if (falsealm_cnt->cnt_all < DM_DIG_FA_TH2)
0387 value_igi++;
0388 else if (falsealm_cnt->cnt_all >= DM_DIG_FA_TH2)
0389 value_igi += 2;
0390 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
0391 "dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n",
0392 de_digtable->large_fa_hit, de_digtable->forbidden_igi);
0393 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
0394 "dm_DIG() Before: Recover_cnt=%d, rx_gain_min=%x\n",
0395 de_digtable->recover_cnt, de_digtable->rx_gain_min);
0396
0397
0398 if (falsealm_cnt->cnt_all > 10000) {
0399 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
0400 "dm_DIG(): Abnormally false alarm case\n");
0401
0402 de_digtable->large_fa_hit++;
0403 if (de_digtable->forbidden_igi < de_digtable->cur_igvalue) {
0404 de_digtable->forbidden_igi = de_digtable->cur_igvalue;
0405 de_digtable->large_fa_hit = 1;
0406 }
0407 if (de_digtable->large_fa_hit >= 3) {
0408 if ((de_digtable->forbidden_igi + 1) > DM_DIG_MAX)
0409 de_digtable->rx_gain_min = DM_DIG_MAX;
0410 else
0411 de_digtable->rx_gain_min =
0412 (de_digtable->forbidden_igi + 1);
0413 de_digtable->recover_cnt = 3600;
0414 }
0415 } else {
0416
0417 if (de_digtable->recover_cnt != 0) {
0418 de_digtable->recover_cnt--;
0419 } else {
0420 if (de_digtable->large_fa_hit == 0) {
0421 if ((de_digtable->forbidden_igi - 1) <
0422 DM_DIG_FA_LOWER) {
0423 de_digtable->forbidden_igi =
0424 DM_DIG_FA_LOWER;
0425 de_digtable->rx_gain_min =
0426 DM_DIG_FA_LOWER;
0427
0428 } else {
0429 de_digtable->forbidden_igi--;
0430 de_digtable->rx_gain_min =
0431 (de_digtable->forbidden_igi + 1);
0432 }
0433 } else if (de_digtable->large_fa_hit == 3) {
0434 de_digtable->large_fa_hit = 0;
0435 }
0436 }
0437 }
0438 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
0439 "dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n",
0440 de_digtable->large_fa_hit, de_digtable->forbidden_igi);
0441 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
0442 "dm_DIG() After: recover_cnt=%d, rx_gain_min=%x\n",
0443 de_digtable->recover_cnt, de_digtable->rx_gain_min);
0444
0445 if (value_igi > DM_DIG_MAX)
0446 value_igi = DM_DIG_MAX;
0447 else if (value_igi < de_digtable->rx_gain_min)
0448 value_igi = de_digtable->rx_gain_min;
0449 de_digtable->cur_igvalue = value_igi;
0450 rtl92d_dm_write_dig(hw);
0451 if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G)
0452 rtl92d_dm_cck_packet_detection_thresh(hw);
0453 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "<<==\n");
0454 }
0455
0456 static void rtl92d_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
0457 {
0458 struct rtl_priv *rtlpriv = rtl_priv(hw);
0459
0460 rtlpriv->dm.dynamic_txpower_enable = true;
0461 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
0462 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
0463 }
0464
0465 static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw)
0466 {
0467 struct rtl_priv *rtlpriv = rtl_priv(hw);
0468 struct rtl_phy *rtlphy = &(rtlpriv->phy);
0469 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
0470 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0471 long undec_sm_pwdb;
0472
0473 if ((!rtlpriv->dm.dynamic_txpower_enable)
0474 || rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
0475 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
0476 return;
0477 }
0478 if ((mac->link_state < MAC80211_LINKED) &&
0479 (rtlpriv->dm.UNDEC_SM_PWDB == 0)) {
0480 rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,
0481 "Not connected to any\n");
0482 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
0483 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
0484 return;
0485 }
0486 if (mac->link_state >= MAC80211_LINKED) {
0487 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
0488 undec_sm_pwdb =
0489 rtlpriv->dm.UNDEC_SM_PWDB;
0490 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0491 "IBSS Client PWDB = 0x%lx\n",
0492 undec_sm_pwdb);
0493 } else {
0494 undec_sm_pwdb =
0495 rtlpriv->dm.undec_sm_pwdb;
0496 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0497 "STA Default Port PWDB = 0x%lx\n",
0498 undec_sm_pwdb);
0499 }
0500 } else {
0501 undec_sm_pwdb =
0502 rtlpriv->dm.UNDEC_SM_PWDB;
0503
0504 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0505 "AP Ext Port PWDB = 0x%lx\n",
0506 undec_sm_pwdb);
0507 }
0508 if (rtlhal->current_bandtype == BAND_ON_5G) {
0509 if (undec_sm_pwdb >= 0x33) {
0510 rtlpriv->dm.dynamic_txhighpower_lvl =
0511 TXHIGHPWRLEVEL_LEVEL2;
0512 rtl_dbg(rtlpriv, COMP_HIPWR, DBG_LOUD,
0513 "5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n");
0514 } else if ((undec_sm_pwdb < 0x33)
0515 && (undec_sm_pwdb >= 0x2b)) {
0516 rtlpriv->dm.dynamic_txhighpower_lvl =
0517 TXHIGHPWRLEVEL_LEVEL1;
0518 rtl_dbg(rtlpriv, COMP_HIPWR, DBG_LOUD,
0519 "5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n");
0520 } else if (undec_sm_pwdb < 0x2b) {
0521 rtlpriv->dm.dynamic_txhighpower_lvl =
0522 TXHIGHPWRLEVEL_NORMAL;
0523 rtl_dbg(rtlpriv, COMP_HIPWR, DBG_LOUD,
0524 "5G:TxHighPwrLevel_Normal\n");
0525 }
0526 } else {
0527 if (undec_sm_pwdb >=
0528 TX_POWER_NEAR_FIELD_THRESH_LVL2) {
0529 rtlpriv->dm.dynamic_txhighpower_lvl =
0530 TXHIGHPWRLEVEL_LEVEL2;
0531 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0532 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
0533 } else
0534 if ((undec_sm_pwdb <
0535 (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3))
0536 && (undec_sm_pwdb >=
0537 TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
0538
0539 rtlpriv->dm.dynamic_txhighpower_lvl =
0540 TXHIGHPWRLEVEL_LEVEL1;
0541 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0542 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
0543 } else if (undec_sm_pwdb <
0544 (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
0545 rtlpriv->dm.dynamic_txhighpower_lvl =
0546 TXHIGHPWRLEVEL_NORMAL;
0547 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0548 "TXHIGHPWRLEVEL_NORMAL\n");
0549 }
0550 }
0551 if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
0552 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0553 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
0554 rtlphy->current_channel);
0555 rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel);
0556 }
0557 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
0558 }
0559
0560 static void rtl92d_dm_pwdb_monitor(struct ieee80211_hw *hw)
0561 {
0562 struct rtl_priv *rtlpriv = rtl_priv(hw);
0563
0564
0565 if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
0566 return;
0567
0568 if (rtlpriv->dm.useramask) {
0569 u32 temp = rtlpriv->dm.undec_sm_pwdb;
0570
0571 temp <<= 16;
0572 temp |= 0x100;
0573
0574
0575 rtl92d_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, (u8 *) (&temp));
0576 } else {
0577 rtl_write_byte(rtlpriv, 0x4fe,
0578 (u8) rtlpriv->dm.undec_sm_pwdb);
0579 }
0580 }
0581
0582 void rtl92d_dm_init_edca_turbo(struct ieee80211_hw *hw)
0583 {
0584 struct rtl_priv *rtlpriv = rtl_priv(hw);
0585
0586 rtlpriv->dm.current_turbo_edca = false;
0587 rtlpriv->dm.is_any_nonbepkts = false;
0588 rtlpriv->dm.is_cur_rdlstate = false;
0589 }
0590
0591 static void rtl92d_dm_check_edca_turbo(struct ieee80211_hw *hw)
0592 {
0593 struct rtl_priv *rtlpriv = rtl_priv(hw);
0594 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0595 static u64 last_txok_cnt;
0596 static u64 last_rxok_cnt;
0597 u64 cur_txok_cnt;
0598 u64 cur_rxok_cnt;
0599 u32 edca_be_ul = 0x5ea42b;
0600 u32 edca_be_dl = 0x5ea42b;
0601
0602 if (mac->link_state != MAC80211_LINKED) {
0603 rtlpriv->dm.current_turbo_edca = false;
0604 goto exit;
0605 }
0606
0607
0608
0609 if ((!rtlpriv->dm.disable_framebursting) &&
0610 (rtlpriv->sec.pairwise_enc_algorithm == WEP40_ENCRYPTION ||
0611 rtlpriv->sec.pairwise_enc_algorithm == WEP104_ENCRYPTION ||
0612 rtlpriv->sec.pairwise_enc_algorithm == TKIP_ENCRYPTION)) {
0613
0614 if (!(edca_be_ul & 0xffff0000))
0615 edca_be_ul |= 0x005e0000;
0616
0617 if (!(edca_be_dl & 0xffff0000))
0618 edca_be_dl |= 0x005e0000;
0619 }
0620
0621 if ((!rtlpriv->dm.is_any_nonbepkts) &&
0622 (!rtlpriv->dm.disable_framebursting)) {
0623 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
0624 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
0625 if (cur_rxok_cnt > 4 * cur_txok_cnt) {
0626 if (!rtlpriv->dm.is_cur_rdlstate ||
0627 !rtlpriv->dm.current_turbo_edca) {
0628 rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM,
0629 edca_be_dl);
0630 rtlpriv->dm.is_cur_rdlstate = true;
0631 }
0632 } else {
0633 if (rtlpriv->dm.is_cur_rdlstate ||
0634 !rtlpriv->dm.current_turbo_edca) {
0635 rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM,
0636 edca_be_ul);
0637 rtlpriv->dm.is_cur_rdlstate = false;
0638 }
0639 }
0640 rtlpriv->dm.current_turbo_edca = true;
0641 } else {
0642 if (rtlpriv->dm.current_turbo_edca) {
0643 u8 tmp = AC0_BE;
0644 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
0645 &tmp);
0646 rtlpriv->dm.current_turbo_edca = false;
0647 }
0648 }
0649
0650 exit:
0651 rtlpriv->dm.is_any_nonbepkts = false;
0652 last_txok_cnt = rtlpriv->stats.txbytesunicast;
0653 last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
0654 }
0655
0656 static void rtl92d_dm_rxgain_tracking_thermalmeter(struct ieee80211_hw *hw)
0657 {
0658 struct rtl_priv *rtlpriv = rtl_priv(hw);
0659 u8 index_mapping[RX_INDEX_MAPPING_NUM] = {
0660 0x0f, 0x0f, 0x0d, 0x0c, 0x0b,
0661 0x0a, 0x09, 0x08, 0x07, 0x06,
0662 0x05, 0x04, 0x04, 0x03, 0x02
0663 };
0664 int i;
0665 u32 u4tmp;
0666
0667 u4tmp = (index_mapping[(rtlpriv->efuse.eeprom_thermalmeter -
0668 rtlpriv->dm.thermalvalue_rxgain)]) << 12;
0669 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0670 "===> Rx Gain %x\n", u4tmp);
0671 for (i = RF90_PATH_A; i < rtlpriv->phy.num_total_rfpath; i++)
0672 rtl_set_rfreg(hw, i, 0x3C, RFREG_OFFSET_MASK,
0673 (rtlpriv->phy.reg_rf3c[i] & (~(0xF000))) | u4tmp);
0674 }
0675
0676 static void rtl92d_bandtype_2_4G(struct ieee80211_hw *hw, long *temp_cckg,
0677 u8 *cck_index_old)
0678 {
0679 struct rtl_priv *rtlpriv = rtl_priv(hw);
0680 int i;
0681 unsigned long flag = 0;
0682 long temp_cck;
0683 const u8 *cckswing;
0684
0685
0686 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
0687 temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2,
0688 MASKDWORD) & MASKCCK;
0689 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
0690 for (i = 0; i < CCK_TABLE_LENGTH; i++) {
0691 if (rtlpriv->dm.cck_inch14)
0692 cckswing = &cckswing_table_ch14[i][2];
0693 else
0694 cckswing = &cckswing_table_ch1ch13[i][2];
0695
0696 if (temp_cck == le32_to_cpu(*((__le32 *)cckswing))) {
0697 *cck_index_old = (u8)i;
0698 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0699 "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n",
0700 RCCK0_TXFILTER2, temp_cck,
0701 *cck_index_old,
0702 rtlpriv->dm.cck_inch14);
0703 break;
0704 }
0705 }
0706 *temp_cckg = temp_cck;
0707 }
0708
0709 static void rtl92d_bandtype_5G(struct rtl_hal *rtlhal, u8 *ofdm_index,
0710 bool *internal_pa, u8 thermalvalue, u8 delta,
0711 u8 rf, struct rtl_efuse *rtlefuse,
0712 struct rtl_priv *rtlpriv, struct rtl_phy *rtlphy,
0713 const u8 index_mapping[5][INDEX_MAPPING_NUM],
0714 const u8 index_mapping_pa[8][INDEX_MAPPING_NUM])
0715 {
0716 int i;
0717 u8 index;
0718 u8 offset = 0;
0719
0720 for (i = 0; i < rf; i++) {
0721 if (rtlhal->macphymode == DUALMAC_DUALPHY &&
0722 rtlhal->interfaceindex == 1)
0723 *internal_pa = rtlefuse->internal_pa_5g[1];
0724 else
0725 *internal_pa = rtlefuse->internal_pa_5g[i];
0726 if (*internal_pa) {
0727 if (rtlhal->interfaceindex == 1 || i == rf)
0728 offset = 4;
0729 else
0730 offset = 0;
0731 if (rtlphy->current_channel >= 100 &&
0732 rtlphy->current_channel <= 165)
0733 offset += 2;
0734 } else {
0735 if (rtlhal->interfaceindex == 1 || i == rf)
0736 offset = 2;
0737 else
0738 offset = 0;
0739 }
0740 if (thermalvalue > rtlefuse->eeprom_thermalmeter)
0741 offset++;
0742 if (*internal_pa) {
0743 if (delta > INDEX_MAPPING_NUM - 1)
0744 index = index_mapping_pa[offset]
0745 [INDEX_MAPPING_NUM - 1];
0746 else
0747 index =
0748 index_mapping_pa[offset][delta];
0749 } else {
0750 if (delta > INDEX_MAPPING_NUM - 1)
0751 index =
0752 index_mapping[offset][INDEX_MAPPING_NUM - 1];
0753 else
0754 index = index_mapping[offset][delta];
0755 }
0756 if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
0757 if (*internal_pa && thermalvalue > 0x12) {
0758 ofdm_index[i] = rtlpriv->dm.ofdm_index[i] -
0759 ((delta / 2) * 3 + (delta % 2));
0760 } else {
0761 ofdm_index[i] -= index;
0762 }
0763 } else {
0764 ofdm_index[i] += index;
0765 }
0766 }
0767 }
0768
0769 static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
0770 struct ieee80211_hw *hw)
0771 {
0772 struct rtl_priv *rtlpriv = rtl_priv(hw);
0773 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0774 struct rtl_phy *rtlphy = &(rtlpriv->phy);
0775 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
0776 u8 thermalvalue, delta, delta_lck, delta_iqk, delta_rxgain;
0777 u8 offset, thermalvalue_avg_count = 0;
0778 u32 thermalvalue_avg = 0;
0779 bool internal_pa = false;
0780 long ele_a = 0, ele_d, temp_cck, val_x, value32;
0781 long val_y, ele_c = 0;
0782 u8 ofdm_index[2];
0783 s8 cck_index = 0;
0784 u8 ofdm_index_old[2] = {0, 0};
0785 s8 cck_index_old = 0;
0786 u8 index;
0787 int i;
0788 bool is2t = IS_92D_SINGLEPHY(rtlhal->version);
0789 u8 ofdm_min_index = 6, ofdm_min_index_internal_pa = 3, rf;
0790 u8 indexforchannel =
0791 rtl92d_get_rightchnlplace_for_iqk(rtlphy->current_channel);
0792 static const u8 index_mapping[5][INDEX_MAPPING_NUM] = {
0793
0794 {0, 1, 3, 6, 8, 9, 11, 13, 14, 16, 17, 18, 18},
0795
0796 {0, 2, 4, 5, 7, 10, 12, 14, 16, 18, 18, 18, 18},
0797
0798 {0, 2, 3, 6, 8, 9, 11, 13, 14, 16, 17, 18, 18},
0799
0800 {0, 2, 4, 5, 7, 10, 13, 16, 16, 18, 18, 18, 18},
0801
0802 {0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 10},
0803 };
0804 static const u8 index_mapping_internal_pa[8][INDEX_MAPPING_NUM] = {
0805
0806 {0, 1, 2, 4, 6, 7, 9, 11, 12, 14, 15, 16, 16},
0807
0808 {0, 2, 4, 5, 7, 10, 12, 14, 16, 18, 18, 18, 18},
0809
0810 {0, 1, 2, 3, 5, 6, 8, 10, 11, 13, 14, 15, 15},
0811
0812 {0, 2, 4, 5, 7, 10, 12, 14, 16, 18, 18, 18, 18},
0813
0814 {0, 1, 2, 4, 6, 7, 9, 11, 12, 14, 15, 16, 16},
0815
0816 {0, 2, 4, 5, 7, 10, 13, 16, 16, 18, 18, 18, 18},
0817
0818 {0, 1, 2, 3, 5, 6, 8, 9, 10, 12, 13, 14, 14},
0819
0820 {0, 2, 4, 5, 7, 10, 13, 16, 16, 18, 18, 18, 18},
0821 };
0822
0823 rtlpriv->dm.txpower_trackinginit = true;
0824 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "\n");
0825 thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0xf800);
0826 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0827 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
0828 thermalvalue,
0829 rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter);
0830 rtl92d_phy_ap_calibrate(hw, (thermalvalue -
0831 rtlefuse->eeprom_thermalmeter));
0832
0833 if (!thermalvalue)
0834 goto exit;
0835
0836 if (is2t)
0837 rf = 2;
0838 else
0839 rf = 1;
0840
0841 if (rtlpriv->dm.thermalvalue && !rtlhal->reloadtxpowerindex)
0842 goto old_index_done;
0843
0844 ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD) & MASKOFDM_D;
0845 for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
0846 if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
0847 ofdm_index_old[0] = (u8)i;
0848
0849 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0850 "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n",
0851 ROFDM0_XATXIQIMBALANCE,
0852 ele_d, ofdm_index_old[0]);
0853 break;
0854 }
0855 }
0856 if (is2t) {
0857 ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
0858 MASKDWORD) & MASKOFDM_D;
0859 for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
0860 if (ele_d ==
0861 (ofdmswing_table[i] & MASKOFDM_D)) {
0862 ofdm_index_old[1] = (u8)i;
0863 rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
0864 DBG_LOUD,
0865 "Initial pathB ele_d reg 0x%x = 0x%lx, ofdm_index = 0x%x\n",
0866 ROFDM0_XBTXIQIMBALANCE, ele_d,
0867 ofdm_index_old[1]);
0868 break;
0869 }
0870 }
0871 }
0872 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
0873 rtl92d_bandtype_2_4G(hw, &temp_cck, &cck_index_old);
0874 } else {
0875 temp_cck = 0x090e1317;
0876 cck_index_old = 12;
0877 }
0878
0879 if (!rtlpriv->dm.thermalvalue) {
0880 rtlpriv->dm.thermalvalue = rtlefuse->eeprom_thermalmeter;
0881 rtlpriv->dm.thermalvalue_lck = thermalvalue;
0882 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
0883 rtlpriv->dm.thermalvalue_rxgain = rtlefuse->eeprom_thermalmeter;
0884 for (i = 0; i < rf; i++)
0885 rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
0886 rtlpriv->dm.cck_index = cck_index_old;
0887 }
0888 if (rtlhal->reloadtxpowerindex) {
0889 for (i = 0; i < rf; i++)
0890 rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
0891 rtlpriv->dm.cck_index = cck_index_old;
0892 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0893 "reload ofdm index for band switch\n");
0894 }
0895 old_index_done:
0896 for (i = 0; i < rf; i++)
0897 ofdm_index[i] = rtlpriv->dm.ofdm_index[i];
0898
0899 rtlpriv->dm.thermalvalue_avg
0900 [rtlpriv->dm.thermalvalue_avg_index] = thermalvalue;
0901 rtlpriv->dm.thermalvalue_avg_index++;
0902 if (rtlpriv->dm.thermalvalue_avg_index == AVG_THERMAL_NUM)
0903 rtlpriv->dm.thermalvalue_avg_index = 0;
0904 for (i = 0; i < AVG_THERMAL_NUM; i++) {
0905 if (rtlpriv->dm.thermalvalue_avg[i]) {
0906 thermalvalue_avg += rtlpriv->dm.thermalvalue_avg[i];
0907 thermalvalue_avg_count++;
0908 }
0909 }
0910 if (thermalvalue_avg_count)
0911 thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count);
0912 if (rtlhal->reloadtxpowerindex) {
0913 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
0914 (thermalvalue - rtlefuse->eeprom_thermalmeter) :
0915 (rtlefuse->eeprom_thermalmeter - thermalvalue);
0916 rtlhal->reloadtxpowerindex = false;
0917 rtlpriv->dm.done_txpower = false;
0918 } else if (rtlpriv->dm.done_txpower) {
0919 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
0920 (thermalvalue - rtlpriv->dm.thermalvalue) :
0921 (rtlpriv->dm.thermalvalue - thermalvalue);
0922 } else {
0923 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
0924 (thermalvalue - rtlefuse->eeprom_thermalmeter) :
0925 (rtlefuse->eeprom_thermalmeter - thermalvalue);
0926 }
0927 delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
0928 (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
0929 (rtlpriv->dm.thermalvalue_lck - thermalvalue);
0930 delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
0931 (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
0932 (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
0933 delta_rxgain =
0934 (thermalvalue > rtlpriv->dm.thermalvalue_rxgain) ?
0935 (thermalvalue - rtlpriv->dm.thermalvalue_rxgain) :
0936 (rtlpriv->dm.thermalvalue_rxgain - thermalvalue);
0937 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0938 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n",
0939 thermalvalue, rtlpriv->dm.thermalvalue,
0940 rtlefuse->eeprom_thermalmeter, delta, delta_lck,
0941 delta_iqk);
0942 if (delta_lck > rtlefuse->delta_lck && rtlefuse->delta_lck != 0) {
0943 rtlpriv->dm.thermalvalue_lck = thermalvalue;
0944 rtl92d_phy_lc_calibrate(hw);
0945 }
0946
0947 if (delta == 0 || !rtlpriv->dm.txpower_track_control)
0948 goto check_delta;
0949
0950 rtlpriv->dm.done_txpower = true;
0951 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
0952 (thermalvalue - rtlefuse->eeprom_thermalmeter) :
0953 (rtlefuse->eeprom_thermalmeter - thermalvalue);
0954 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
0955 offset = 4;
0956 if (delta > INDEX_MAPPING_NUM - 1)
0957 index = index_mapping[offset][INDEX_MAPPING_NUM - 1];
0958 else
0959 index = index_mapping[offset][delta];
0960 if (thermalvalue > rtlpriv->dm.thermalvalue) {
0961 for (i = 0; i < rf; i++)
0962 ofdm_index[i] -= delta;
0963 cck_index -= delta;
0964 } else {
0965 for (i = 0; i < rf; i++)
0966 ofdm_index[i] += index;
0967 cck_index += index;
0968 }
0969 } else if (rtlhal->current_bandtype == BAND_ON_5G) {
0970 rtl92d_bandtype_5G(rtlhal, ofdm_index,
0971 &internal_pa, thermalvalue,
0972 delta, rf, rtlefuse, rtlpriv,
0973 rtlphy, index_mapping,
0974 index_mapping_internal_pa);
0975 }
0976 if (is2t) {
0977 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0978 "temp OFDM_A_index=0x%x, OFDM_B_index = 0x%x,cck_index=0x%x\n",
0979 rtlpriv->dm.ofdm_index[0],
0980 rtlpriv->dm.ofdm_index[1],
0981 rtlpriv->dm.cck_index);
0982 } else {
0983 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0984 "temp OFDM_A_index=0x%x,cck_index = 0x%x\n",
0985 rtlpriv->dm.ofdm_index[0],
0986 rtlpriv->dm.cck_index);
0987 }
0988 for (i = 0; i < rf; i++) {
0989 if (ofdm_index[i] > OFDM_TABLE_SIZE_92D - 1) {
0990 ofdm_index[i] = OFDM_TABLE_SIZE_92D - 1;
0991 } else if (internal_pa ||
0992 rtlhal->current_bandtype == BAND_ON_2_4G) {
0993 if (ofdm_index[i] < ofdm_min_index_internal_pa)
0994 ofdm_index[i] = ofdm_min_index_internal_pa;
0995 } else if (ofdm_index[i] < ofdm_min_index) {
0996 ofdm_index[i] = ofdm_min_index;
0997 }
0998 }
0999 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
1000 if (cck_index > CCK_TABLE_SIZE - 1) {
1001 cck_index = CCK_TABLE_SIZE - 1;
1002 } else if (cck_index < 0) {
1003 cck_index = 0;
1004 }
1005 }
1006 if (is2t) {
1007 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1008 "new OFDM_A_index=0x%x, OFDM_B_index = 0x%x, cck_index=0x%x\n",
1009 ofdm_index[0], ofdm_index[1],
1010 cck_index);
1011 } else {
1012 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1013 "new OFDM_A_index=0x%x,cck_index = 0x%x\n",
1014 ofdm_index[0], cck_index);
1015 }
1016 ele_d = (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22;
1017 val_x = rtlphy->iqk_matrix[indexforchannel].value[0][0];
1018 val_y = rtlphy->iqk_matrix[indexforchannel].value[0][1];
1019 if (val_x != 0) {
1020 if ((val_x & 0x00000200) != 0)
1021 val_x = val_x | 0xFFFFFC00;
1022 ele_a = ((val_x * ele_d) >> 8) & 0x000003FF;
1023
1024
1025 if ((val_y & 0x00000200) != 0)
1026 val_y = val_y | 0xFFFFFC00;
1027 ele_c = ((val_y * ele_d) >> 8) & 0x000003FF;
1028
1029
1030
1031
1032 value32 = (ele_d << 22) | ((ele_c & 0x3F) << 16) | ele_a;
1033 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1034 MASKDWORD, value32);
1035
1036 value32 = (ele_c & 0x000003C0) >> 6;
1037 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
1038 value32);
1039
1040 value32 = ((val_x * ele_d) >> 7) & 0x01;
1041 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
1042 value32);
1043
1044 } else {
1045 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1046 MASKDWORD,
1047 ofdmswing_table[(u8)ofdm_index[0]]);
1048 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
1049 0x00);
1050 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1051 BIT(24), 0x00);
1052 }
1053
1054 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1055 "TxPwrTracking for interface %d path A: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = 0x%lx\n",
1056 rtlhal->interfaceindex,
1057 val_x, val_y, ele_a, ele_c, ele_d,
1058 val_x, val_y);
1059
1060 if (cck_index >= CCK_TABLE_SIZE)
1061 cck_index = CCK_TABLE_SIZE - 1;
1062 if (cck_index < 0)
1063 cck_index = 0;
1064 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
1065
1066 if (!rtlpriv->dm.cck_inch14) {
1067 rtl_write_byte(rtlpriv, 0xa22,
1068 cckswing_table_ch1ch13[cck_index][0]);
1069 rtl_write_byte(rtlpriv, 0xa23,
1070 cckswing_table_ch1ch13[cck_index][1]);
1071 rtl_write_byte(rtlpriv, 0xa24,
1072 cckswing_table_ch1ch13[cck_index][2]);
1073 rtl_write_byte(rtlpriv, 0xa25,
1074 cckswing_table_ch1ch13[cck_index][3]);
1075 rtl_write_byte(rtlpriv, 0xa26,
1076 cckswing_table_ch1ch13[cck_index][4]);
1077 rtl_write_byte(rtlpriv, 0xa27,
1078 cckswing_table_ch1ch13[cck_index][5]);
1079 rtl_write_byte(rtlpriv, 0xa28,
1080 cckswing_table_ch1ch13[cck_index][6]);
1081 rtl_write_byte(rtlpriv, 0xa29,
1082 cckswing_table_ch1ch13[cck_index][7]);
1083 } else {
1084 rtl_write_byte(rtlpriv, 0xa22,
1085 cckswing_table_ch14[cck_index][0]);
1086 rtl_write_byte(rtlpriv, 0xa23,
1087 cckswing_table_ch14[cck_index][1]);
1088 rtl_write_byte(rtlpriv, 0xa24,
1089 cckswing_table_ch14[cck_index][2]);
1090 rtl_write_byte(rtlpriv, 0xa25,
1091 cckswing_table_ch14[cck_index][3]);
1092 rtl_write_byte(rtlpriv, 0xa26,
1093 cckswing_table_ch14[cck_index][4]);
1094 rtl_write_byte(rtlpriv, 0xa27,
1095 cckswing_table_ch14[cck_index][5]);
1096 rtl_write_byte(rtlpriv, 0xa28,
1097 cckswing_table_ch14[cck_index][6]);
1098 rtl_write_byte(rtlpriv, 0xa29,
1099 cckswing_table_ch14[cck_index][7]);
1100 }
1101 }
1102 if (is2t) {
1103 ele_d = (ofdmswing_table[ofdm_index[1]] & 0xFFC00000) >> 22;
1104 val_x = rtlphy->iqk_matrix[indexforchannel].value[0][4];
1105 val_y = rtlphy->iqk_matrix[indexforchannel].value[0][5];
1106 if (val_x != 0) {
1107 if ((val_x & 0x00000200) != 0)
1108
1109 val_x = val_x | 0xFFFFFC00;
1110 ele_a = ((val_x * ele_d) >> 8) & 0x000003FF;
1111
1112 if ((val_y & 0x00000200) != 0)
1113 val_y = val_y | 0xFFFFFC00;
1114 ele_c = ((val_y * ele_d) >> 8) & 0x00003FF;
1115
1116
1117
1118 value32 = (ele_d << 22) | ((ele_c & 0x3F) << 16) | ele_a;
1119 rtl_set_bbreg(hw,
1120 ROFDM0_XBTXIQIMBALANCE,
1121 MASKDWORD, value32);
1122 value32 = (ele_c & 0x000003C0) >> 6;
1123 rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
1124 MASKH4BITS, value32);
1125 value32 = ((val_x * ele_d) >> 7) & 0x01;
1126 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1127 BIT(28), value32);
1128 } else {
1129 rtl_set_bbreg(hw,
1130 ROFDM0_XBTXIQIMBALANCE,
1131 MASKDWORD,
1132 ofdmswing_table[ofdm_index[1]]);
1133 rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
1134 MASKH4BITS, 0x00);
1135 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1136 BIT(28), 0x00);
1137 }
1138 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1139 "TxPwrTracking path B: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xeb4 = 0x%lx 0xebc = 0x%lx\n",
1140 val_x, val_y, ele_a, ele_c,
1141 ele_d, val_x, val_y);
1142 }
1143 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1144 "TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n",
1145 rtl_get_bbreg(hw, 0xc80, MASKDWORD),
1146 rtl_get_bbreg(hw, 0xc94, MASKDWORD),
1147 rtl_get_rfreg(hw, RF90_PATH_A, 0x24,
1148 RFREG_OFFSET_MASK));
1149
1150 check_delta:
1151 if (delta_iqk > rtlefuse->delta_iqk && rtlefuse->delta_iqk != 0) {
1152 rtl92d_phy_reset_iqk_result(hw);
1153 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
1154 rtl92d_phy_iq_calibrate(hw);
1155 }
1156 if (delta_rxgain > 0 && rtlhal->current_bandtype == BAND_ON_5G &&
1157 thermalvalue <= rtlefuse->eeprom_thermalmeter) {
1158 rtlpriv->dm.thermalvalue_rxgain = thermalvalue;
1159 rtl92d_dm_rxgain_tracking_thermalmeter(hw);
1160 }
1161 if (rtlpriv->dm.txpower_track_control)
1162 rtlpriv->dm.thermalvalue = thermalvalue;
1163
1164 exit:
1165 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n");
1166 }
1167
1168 static void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
1169 {
1170 struct rtl_priv *rtlpriv = rtl_priv(hw);
1171
1172 rtlpriv->dm.txpower_tracking = true;
1173 rtlpriv->dm.txpower_trackinginit = false;
1174 rtlpriv->dm.txpower_track_control = true;
1175 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1176 "pMgntInfo->txpower_tracking = %d\n",
1177 rtlpriv->dm.txpower_tracking);
1178 }
1179
1180 void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw)
1181 {
1182 struct rtl_priv *rtlpriv = rtl_priv(hw);
1183
1184 if (!rtlpriv->dm.txpower_tracking)
1185 return;
1186
1187 if (!rtlpriv->dm.tm_trigger) {
1188 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) |
1189 BIT(16), 0x03);
1190 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1191 "Trigger 92S Thermal Meter!!\n");
1192 rtlpriv->dm.tm_trigger = 1;
1193 return;
1194 } else {
1195 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1196 "Schedule TxPowerTracking direct call!!\n");
1197 rtl92d_dm_txpower_tracking_callback_thermalmeter(hw);
1198 rtlpriv->dm.tm_trigger = 0;
1199 }
1200 }
1201
1202 void rtl92d_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
1203 {
1204 struct rtl_priv *rtlpriv = rtl_priv(hw);
1205 struct rate_adaptive *ra = &(rtlpriv->ra);
1206
1207 ra->ratr_state = DM_RATR_STA_INIT;
1208 ra->pre_ratr_state = DM_RATR_STA_INIT;
1209 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
1210 rtlpriv->dm.useramask = true;
1211 else
1212 rtlpriv->dm.useramask = false;
1213 }
1214
1215 void rtl92d_dm_init(struct ieee80211_hw *hw)
1216 {
1217 struct rtl_priv *rtlpriv = rtl_priv(hw);
1218
1219 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1220 rtl_dm_diginit(hw, 0x20);
1221 rtlpriv->dm_digtable.rx_gain_max = DM_DIG_FA_UPPER;
1222 rtlpriv->dm_digtable.rx_gain_min = DM_DIG_FA_LOWER;
1223 rtl92d_dm_init_dynamic_txpower(hw);
1224 rtl92d_dm_init_edca_turbo(hw);
1225 rtl92d_dm_init_rate_adaptive_mask(hw);
1226 rtl92d_dm_initialize_txpower_tracking(hw);
1227 }
1228
1229 void rtl92d_dm_watchdog(struct ieee80211_hw *hw)
1230 {
1231 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1232 bool fw_current_inpsmode = false;
1233 bool fwps_awake = true;
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243 if ((ppsc->rfpwr_state == ERFON) && ((!fw_current_inpsmode) &&
1244 fwps_awake) && (!ppsc->rfchange_inprogress)) {
1245 rtl92d_dm_pwdb_monitor(hw);
1246 rtl92d_dm_false_alarm_counter_statistics(hw);
1247 rtl92d_dm_find_minimum_rssi(hw);
1248 rtl92d_dm_dig(hw);
1249
1250 rtl92d_dm_dynamic_txpower(hw);
1251
1252
1253
1254 rtl92d_dm_check_edca_turbo(hw);
1255 }
1256 }