0001
0002
0003
0004 #include "../wifi.h"
0005 #include "../base.h"
0006 #include "../pci.h"
0007 #include "../core.h"
0008 #include "reg.h"
0009 #include "def.h"
0010 #include "phy.h"
0011 #include "dm.h"
0012 #include "fw.h"
0013 #include "trx.h"
0014
0015 static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
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 cck_tbl_ch1_13[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 cck_tbl_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 #define CAL_SWING_OFF(_off, _dir, _size, _del) \
0134 do { \
0135 for (_off = 0; _off < _size; _off++) { \
0136 if (_del < thermal_threshold[_dir][_off]) { \
0137 if (_off != 0) \
0138 _off--; \
0139 break; \
0140 } \
0141 } \
0142 if (_off >= _size) \
0143 _off = _size - 1; \
0144 } while (0)
0145
0146 static void rtl88e_set_iqk_matrix(struct ieee80211_hw *hw,
0147 u8 ofdm_index, u8 rfpath,
0148 long iqk_result_x, long iqk_result_y)
0149 {
0150 long ele_a = 0, ele_d, ele_c = 0, value32;
0151
0152 ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000)>>22;
0153
0154 if (iqk_result_x != 0) {
0155 if ((iqk_result_x & 0x00000200) != 0)
0156 iqk_result_x = iqk_result_x | 0xFFFFFC00;
0157 ele_a = ((iqk_result_x * ele_d)>>8)&0x000003FF;
0158
0159 if ((iqk_result_y & 0x00000200) != 0)
0160 iqk_result_y = iqk_result_y | 0xFFFFFC00;
0161 ele_c = ((iqk_result_y * ele_d)>>8)&0x000003FF;
0162
0163 switch (rfpath) {
0164 case RF90_PATH_A:
0165 value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a;
0166 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
0167 MASKDWORD, value32);
0168 value32 = (ele_c & 0x000003C0) >> 6;
0169 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
0170 value32);
0171 value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
0172 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
0173 value32);
0174 break;
0175 case RF90_PATH_B:
0176 value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a;
0177 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, MASKDWORD,
0178 value32);
0179 value32 = (ele_c & 0x000003C0) >> 6;
0180 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, MASKH4BITS, value32);
0181 value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
0182 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28),
0183 value32);
0184 break;
0185 default:
0186 break;
0187 }
0188 } else {
0189 switch (rfpath) {
0190 case RF90_PATH_A:
0191 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
0192 MASKDWORD, ofdmswing_table[ofdm_index]);
0193 rtl_set_bbreg(hw, ROFDM0_XCTXAFE,
0194 MASKH4BITS, 0x00);
0195 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
0196 BIT(24), 0x00);
0197 break;
0198 case RF90_PATH_B:
0199 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
0200 MASKDWORD, ofdmswing_table[ofdm_index]);
0201 rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
0202 MASKH4BITS, 0x00);
0203 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
0204 BIT(28), 0x00);
0205 break;
0206 default:
0207 break;
0208 }
0209 }
0210 }
0211
0212 void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw *hw,
0213 u8 type, u8 *pdirection, u32 *poutwrite_val)
0214 {
0215 struct rtl_priv *rtlpriv = rtl_priv(hw);
0216 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
0217 u8 pwr_val = 0;
0218 u8 cck_base = rtldm->swing_idx_cck_base;
0219 u8 cck_val = rtldm->swing_idx_cck;
0220 u8 ofdm_base = rtldm->swing_idx_ofdm_base[0];
0221 u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A];
0222
0223 if (type == 0) {
0224 if (ofdm_val <= ofdm_base) {
0225 *pdirection = 1;
0226 pwr_val = ofdm_base - ofdm_val;
0227 } else {
0228 *pdirection = 2;
0229 pwr_val = ofdm_base - ofdm_val;
0230 }
0231 } else if (type == 1) {
0232 if (cck_val <= cck_base) {
0233 *pdirection = 1;
0234 pwr_val = cck_base - cck_val;
0235 } else {
0236 *pdirection = 2;
0237 pwr_val = cck_val - cck_base;
0238 }
0239 }
0240
0241 if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
0242 pwr_val = TXPWRTRACK_MAX_IDX;
0243
0244 *poutwrite_val = pwr_val | (pwr_val << 8) | (pwr_val << 16) |
0245 (pwr_val << 24);
0246 }
0247
0248 static void dm_tx_pwr_track_set_pwr(struct ieee80211_hw *hw,
0249 enum pwr_track_control_method method,
0250 u8 rfpath, u8 channel_mapped_index)
0251 {
0252 struct rtl_priv *rtlpriv = rtl_priv(hw);
0253 struct rtl_phy *rtlphy = &rtlpriv->phy;
0254 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
0255
0256 if (method == TXAGC) {
0257 if (rtldm->swing_flag_ofdm ||
0258 rtldm->swing_flag_cck) {
0259 rtl88e_phy_set_txpower_level(hw,
0260 rtlphy->current_channel);
0261 rtldm->swing_flag_ofdm = false;
0262 rtldm->swing_flag_cck = false;
0263 }
0264 } else if (method == BBSWING) {
0265 if (!rtldm->cck_inch14) {
0266 rtl_write_byte(rtlpriv, 0xa22,
0267 cck_tbl_ch1_13[rtldm->swing_idx_cck][0]);
0268 rtl_write_byte(rtlpriv, 0xa23,
0269 cck_tbl_ch1_13[rtldm->swing_idx_cck][1]);
0270 rtl_write_byte(rtlpriv, 0xa24,
0271 cck_tbl_ch1_13[rtldm->swing_idx_cck][2]);
0272 rtl_write_byte(rtlpriv, 0xa25,
0273 cck_tbl_ch1_13[rtldm->swing_idx_cck][3]);
0274 rtl_write_byte(rtlpriv, 0xa26,
0275 cck_tbl_ch1_13[rtldm->swing_idx_cck][4]);
0276 rtl_write_byte(rtlpriv, 0xa27,
0277 cck_tbl_ch1_13[rtldm->swing_idx_cck][5]);
0278 rtl_write_byte(rtlpriv, 0xa28,
0279 cck_tbl_ch1_13[rtldm->swing_idx_cck][6]);
0280 rtl_write_byte(rtlpriv, 0xa29,
0281 cck_tbl_ch1_13[rtldm->swing_idx_cck][7]);
0282 } else {
0283 rtl_write_byte(rtlpriv, 0xa22,
0284 cck_tbl_ch14[rtldm->swing_idx_cck][0]);
0285 rtl_write_byte(rtlpriv, 0xa23,
0286 cck_tbl_ch14[rtldm->swing_idx_cck][1]);
0287 rtl_write_byte(rtlpriv, 0xa24,
0288 cck_tbl_ch14[rtldm->swing_idx_cck][2]);
0289 rtl_write_byte(rtlpriv, 0xa25,
0290 cck_tbl_ch14[rtldm->swing_idx_cck][3]);
0291 rtl_write_byte(rtlpriv, 0xa26,
0292 cck_tbl_ch14[rtldm->swing_idx_cck][4]);
0293 rtl_write_byte(rtlpriv, 0xa27,
0294 cck_tbl_ch14[rtldm->swing_idx_cck][5]);
0295 rtl_write_byte(rtlpriv, 0xa28,
0296 cck_tbl_ch14[rtldm->swing_idx_cck][6]);
0297 rtl_write_byte(rtlpriv, 0xa29,
0298 cck_tbl_ch14[rtldm->swing_idx_cck][7]);
0299 }
0300
0301 if (rfpath == RF90_PATH_A) {
0302 rtl88e_set_iqk_matrix(hw, rtldm->swing_idx_ofdm[rfpath],
0303 rfpath, rtlphy->iqk_matrix
0304 [channel_mapped_index].
0305 value[0][0],
0306 rtlphy->iqk_matrix
0307 [channel_mapped_index].
0308 value[0][1]);
0309 } else if (rfpath == RF90_PATH_B) {
0310 rtl88e_set_iqk_matrix(hw, rtldm->swing_idx_ofdm[rfpath],
0311 rfpath, rtlphy->iqk_matrix
0312 [channel_mapped_index].
0313 value[0][4],
0314 rtlphy->iqk_matrix
0315 [channel_mapped_index].
0316 value[0][5]);
0317 }
0318 } else {
0319 return;
0320 }
0321 }
0322
0323 static u8 rtl88e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
0324 {
0325 struct rtl_priv *rtlpriv = rtl_priv(hw);
0326 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
0327 long rssi_val_min = 0;
0328
0329 if ((dm_dig->curmultista_cstate == DIG_MULTISTA_CONNECT) &&
0330 (dm_dig->cur_sta_cstate == DIG_STA_CONNECT)) {
0331 if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0)
0332 rssi_val_min =
0333 (rtlpriv->dm.entry_min_undec_sm_pwdb >
0334 rtlpriv->dm.undec_sm_pwdb) ?
0335 rtlpriv->dm.undec_sm_pwdb :
0336 rtlpriv->dm.entry_min_undec_sm_pwdb;
0337 else
0338 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
0339 } else if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT ||
0340 dm_dig->cur_sta_cstate == DIG_STA_BEFORE_CONNECT) {
0341 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
0342 } else if (dm_dig->curmultista_cstate ==
0343 DIG_MULTISTA_CONNECT) {
0344 rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
0345 }
0346
0347 return (u8)rssi_val_min;
0348 }
0349
0350 static void rtl88e_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
0351 {
0352 u32 ret_value;
0353 struct rtl_priv *rtlpriv = rtl_priv(hw);
0354 struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
0355
0356 rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1);
0357 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1);
0358
0359 ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);
0360 falsealm_cnt->cnt_fast_fsync_fail = (ret_value&0xffff);
0361 falsealm_cnt->cnt_sb_search_fail = ((ret_value&0xffff0000)>>16);
0362
0363 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
0364 falsealm_cnt->cnt_ofdm_cca = (ret_value&0xffff);
0365 falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
0366
0367 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
0368 falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
0369 falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
0370
0371 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
0372 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
0373 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
0374 falsealm_cnt->cnt_rate_illegal +
0375 falsealm_cnt->cnt_crc8_fail +
0376 falsealm_cnt->cnt_mcs_fail +
0377 falsealm_cnt->cnt_fast_fsync_fail +
0378 falsealm_cnt->cnt_sb_search_fail;
0379
0380 ret_value = rtl_get_bbreg(hw, REG_SC_CNT, MASKDWORD);
0381 falsealm_cnt->cnt_bw_lsc = (ret_value & 0xffff);
0382 falsealm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16);
0383
0384 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(12), 1);
0385 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
0386
0387 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
0388 falsealm_cnt->cnt_cck_fail = ret_value;
0389
0390 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
0391 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
0392
0393 ret_value = rtl_get_bbreg(hw, RCCK0_CCA_CNT, MASKDWORD);
0394 falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |
0395 ((ret_value&0xFF00)>>8);
0396
0397 falsealm_cnt->cnt_all = (falsealm_cnt->cnt_fast_fsync_fail +
0398 falsealm_cnt->cnt_sb_search_fail +
0399 falsealm_cnt->cnt_parity_fail +
0400 falsealm_cnt->cnt_rate_illegal +
0401 falsealm_cnt->cnt_crc8_fail +
0402 falsealm_cnt->cnt_mcs_fail +
0403 falsealm_cnt->cnt_cck_fail);
0404 falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +
0405 falsealm_cnt->cnt_cck_cca;
0406
0407 rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 1);
0408 rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 0);
0409 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 1);
0410 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 0);
0411 rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 0);
0412 rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 0);
0413 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 0);
0414 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 2);
0415 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 0);
0416 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 2);
0417
0418 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0419 "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
0420 falsealm_cnt->cnt_parity_fail,
0421 falsealm_cnt->cnt_rate_illegal,
0422 falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
0423
0424 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0425 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
0426 falsealm_cnt->cnt_ofdm_fail,
0427 falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
0428 }
0429
0430 static void rtl88e_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
0431 {
0432 struct rtl_priv *rtlpriv = rtl_priv(hw);
0433 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
0434 u8 cur_cck_cca_thresh;
0435
0436 if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT) {
0437 dm_dig->rssi_val_min = rtl88e_dm_initial_gain_min_pwdb(hw);
0438 if (dm_dig->rssi_val_min > 25) {
0439 cur_cck_cca_thresh = 0xcd;
0440 } else if ((dm_dig->rssi_val_min <= 25) &&
0441 (dm_dig->rssi_val_min > 10)) {
0442 cur_cck_cca_thresh = 0x83;
0443 } else {
0444 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
0445 cur_cck_cca_thresh = 0x83;
0446 else
0447 cur_cck_cca_thresh = 0x40;
0448 }
0449
0450 } else {
0451 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
0452 cur_cck_cca_thresh = 0x83;
0453 else
0454 cur_cck_cca_thresh = 0x40;
0455 }
0456
0457 if (dm_dig->cur_cck_cca_thres != cur_cck_cca_thresh)
0458 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh);
0459
0460 dm_dig->cur_cck_cca_thres = cur_cck_cca_thresh;
0461 dm_dig->pre_cck_cca_thres = dm_dig->cur_cck_cca_thres;
0462 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0463 "CCK cca thresh hold =%x\n", dm_dig->cur_cck_cca_thres);
0464 }
0465
0466 static void rtl88e_dm_dig(struct ieee80211_hw *hw)
0467 {
0468 struct rtl_priv *rtlpriv = rtl_priv(hw);
0469 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0470 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
0471 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
0472 u8 dig_dynamic_min, dig_maxofmin;
0473 bool bfirstconnect;
0474 u8 dm_dig_max, dm_dig_min;
0475 u8 current_igi = dm_dig->cur_igvalue;
0476
0477 if (!rtlpriv->dm.dm_initialgain_enable)
0478 return;
0479 if (!dm_dig->dig_enable_flag)
0480 return;
0481 if (mac->act_scanning)
0482 return;
0483
0484 if (mac->link_state >= MAC80211_LINKED)
0485 dm_dig->cur_sta_cstate = DIG_STA_CONNECT;
0486 else
0487 dm_dig->cur_sta_cstate = DIG_STA_DISCONNECT;
0488 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
0489 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
0490 dm_dig->cur_sta_cstate = DIG_STA_DISCONNECT;
0491
0492 dm_dig_max = DM_DIG_MAX;
0493 dm_dig_min = DM_DIG_MIN;
0494 dig_maxofmin = DM_DIG_MAX_AP;
0495 dig_dynamic_min = dm_dig->dig_min_0;
0496 bfirstconnect = ((mac->link_state >= MAC80211_LINKED) ? true : false) &&
0497 !dm_dig->media_connect_0;
0498
0499 dm_dig->rssi_val_min =
0500 rtl88e_dm_initial_gain_min_pwdb(hw);
0501
0502 if (mac->link_state >= MAC80211_LINKED) {
0503 if ((dm_dig->rssi_val_min + 20) > dm_dig_max)
0504 dm_dig->rx_gain_max = dm_dig_max;
0505 else if ((dm_dig->rssi_val_min + 20) < dm_dig_min)
0506 dm_dig->rx_gain_max = dm_dig_min;
0507 else
0508 dm_dig->rx_gain_max = dm_dig->rssi_val_min + 20;
0509
0510 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
0511 dig_dynamic_min = dm_dig->antdiv_rssi_max;
0512 } else {
0513 if (dm_dig->rssi_val_min < dm_dig_min)
0514 dig_dynamic_min = dm_dig_min;
0515 else if (dm_dig->rssi_val_min < dig_maxofmin)
0516 dig_dynamic_min = dig_maxofmin;
0517 else
0518 dig_dynamic_min = dm_dig->rssi_val_min;
0519 }
0520 } else {
0521 dm_dig->rx_gain_max = dm_dig_max;
0522 dig_dynamic_min = dm_dig_min;
0523 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");
0524 }
0525
0526 if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
0527 dm_dig->large_fa_hit++;
0528 if (dm_dig->forbidden_igi < current_igi) {
0529 dm_dig->forbidden_igi = current_igi;
0530 dm_dig->large_fa_hit = 1;
0531 }
0532
0533 if (dm_dig->large_fa_hit >= 3) {
0534 if ((dm_dig->forbidden_igi + 1) >
0535 dm_dig->rx_gain_max)
0536 dm_dig->rx_gain_min =
0537 dm_dig->rx_gain_max;
0538 else
0539 dm_dig->rx_gain_min =
0540 dm_dig->forbidden_igi + 1;
0541 dm_dig->recover_cnt = 3600;
0542 }
0543 } else {
0544 if (dm_dig->recover_cnt != 0) {
0545 dm_dig->recover_cnt--;
0546 } else {
0547 if (dm_dig->large_fa_hit == 0) {
0548 if ((dm_dig->forbidden_igi - 1) <
0549 dig_dynamic_min) {
0550 dm_dig->forbidden_igi = dig_dynamic_min;
0551 dm_dig->rx_gain_min = dig_dynamic_min;
0552 } else {
0553 dm_dig->forbidden_igi--;
0554 dm_dig->rx_gain_min =
0555 dm_dig->forbidden_igi + 1;
0556 }
0557 } else if (dm_dig->large_fa_hit == 3) {
0558 dm_dig->large_fa_hit = 0;
0559 }
0560 }
0561 }
0562
0563 if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT) {
0564 if (bfirstconnect) {
0565 current_igi = dm_dig->rssi_val_min;
0566 } else {
0567 if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
0568 current_igi += 2;
0569 else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
0570 current_igi++;
0571 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
0572 current_igi--;
0573 }
0574 } else {
0575 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
0576 current_igi += 2;
0577 else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
0578 current_igi++;
0579 else if (rtlpriv->falsealm_cnt.cnt_all < 500)
0580 current_igi--;
0581 }
0582
0583 if (current_igi > DM_DIG_FA_UPPER)
0584 current_igi = DM_DIG_FA_UPPER;
0585 else if (current_igi < DM_DIG_FA_LOWER)
0586 current_igi = DM_DIG_FA_LOWER;
0587
0588 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
0589 current_igi = DM_DIG_FA_UPPER;
0590
0591 dm_dig->cur_igvalue = current_igi;
0592 rtl88e_dm_write_dig(hw);
0593 dm_dig->media_connect_0 =
0594 ((mac->link_state >= MAC80211_LINKED) ? true : false);
0595 dm_dig->dig_min_0 = dig_dynamic_min;
0596
0597 rtl88e_dm_cck_packet_detection_thresh(hw);
0598 }
0599
0600 static void rtl88e_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
0601 {
0602 struct rtl_priv *rtlpriv = rtl_priv(hw);
0603
0604 rtlpriv->dm.dynamic_txpower_enable = false;
0605
0606 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
0607 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
0608 }
0609
0610 static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
0611 {
0612 struct rtl_priv *rtlpriv = rtl_priv(hw);
0613 struct rtl_phy *rtlphy = &rtlpriv->phy;
0614 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0615 long undec_sm_pwdb;
0616
0617 if (!rtlpriv->dm.dynamic_txpower_enable)
0618 return;
0619
0620 if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
0621 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
0622 return;
0623 }
0624
0625 if ((mac->link_state < MAC80211_LINKED) &&
0626 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
0627 rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,
0628 "Not connected to any\n");
0629
0630 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
0631
0632 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
0633 return;
0634 }
0635
0636 if (mac->link_state >= MAC80211_LINKED) {
0637 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
0638 undec_sm_pwdb =
0639 rtlpriv->dm.entry_min_undec_sm_pwdb;
0640 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0641 "AP Client PWDB = 0x%lx\n",
0642 undec_sm_pwdb);
0643 } else {
0644 undec_sm_pwdb =
0645 rtlpriv->dm.undec_sm_pwdb;
0646 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0647 "STA Default Port PWDB = 0x%lx\n",
0648 undec_sm_pwdb);
0649 }
0650 } else {
0651 undec_sm_pwdb =
0652 rtlpriv->dm.entry_min_undec_sm_pwdb;
0653
0654 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0655 "AP Ext Port PWDB = 0x%lx\n",
0656 undec_sm_pwdb);
0657 }
0658
0659 if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
0660 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
0661 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0662 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x0)\n");
0663 } else if ((undec_sm_pwdb <
0664 (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
0665 (undec_sm_pwdb >=
0666 TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
0667 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
0668 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0669 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x10)\n");
0670 } else if (undec_sm_pwdb <
0671 (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
0672 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
0673 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0674 "TXHIGHPWRLEVEL_NORMAL\n");
0675 }
0676
0677 if ((rtlpriv->dm.dynamic_txhighpower_lvl !=
0678 rtlpriv->dm.last_dtp_lvl)) {
0679 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
0680 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
0681 rtlphy->current_channel);
0682 rtl88e_phy_set_txpower_level(hw, rtlphy->current_channel);
0683 }
0684
0685 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
0686 }
0687
0688 void rtl88e_dm_write_dig(struct ieee80211_hw *hw)
0689 {
0690 struct rtl_priv *rtlpriv = rtl_priv(hw);
0691 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
0692
0693 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
0694 "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n",
0695 dm_dig->cur_igvalue, dm_dig->pre_igvalue,
0696 dm_dig->back_val);
0697
0698 if (dm_dig->cur_igvalue > 0x3f)
0699 dm_dig->cur_igvalue = 0x3f;
0700 if (dm_dig->pre_igvalue != dm_dig->cur_igvalue) {
0701 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
0702 dm_dig->cur_igvalue);
0703
0704 dm_dig->pre_igvalue = dm_dig->cur_igvalue;
0705 }
0706 }
0707
0708 static void rtl88e_dm_pwdb_monitor(struct ieee80211_hw *hw)
0709 {
0710 struct rtl_priv *rtlpriv = rtl_priv(hw);
0711 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0712 struct rtl_sta_info *drv_priv;
0713 static u64 last_record_txok_cnt;
0714 static u64 last_record_rxok_cnt;
0715 long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
0716
0717 if (rtlhal->oem_id == RT_CID_819X_HP) {
0718 u64 cur_txok_cnt = 0;
0719 u64 cur_rxok_cnt = 0;
0720 cur_txok_cnt = rtlpriv->stats.txbytesunicast -
0721 last_record_txok_cnt;
0722 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast -
0723 last_record_rxok_cnt;
0724 last_record_txok_cnt = cur_txok_cnt;
0725 last_record_rxok_cnt = cur_rxok_cnt;
0726
0727 if (cur_rxok_cnt > (cur_txok_cnt * 6))
0728 rtl_write_dword(rtlpriv, REG_ARFR0, 0x8f015);
0729 else
0730 rtl_write_dword(rtlpriv, REG_ARFR0, 0xff015);
0731 }
0732
0733
0734 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
0735 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
0736 if (drv_priv->rssi_stat.undec_sm_pwdb <
0737 tmp_entry_min_pwdb)
0738 tmp_entry_min_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
0739 if (drv_priv->rssi_stat.undec_sm_pwdb >
0740 tmp_entry_max_pwdb)
0741 tmp_entry_max_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
0742 }
0743 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
0744
0745
0746 if (tmp_entry_max_pwdb != 0) {
0747 rtlpriv->dm.entry_max_undec_sm_pwdb = tmp_entry_max_pwdb;
0748 RTPRINT(rtlpriv, FDM, DM_PWDB, "EntryMaxPWDB = 0x%lx(%ld)\n",
0749 tmp_entry_max_pwdb, tmp_entry_max_pwdb);
0750 } else {
0751 rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
0752 }
0753
0754 if (tmp_entry_min_pwdb != 0xff) {
0755 rtlpriv->dm.entry_min_undec_sm_pwdb = tmp_entry_min_pwdb;
0756 RTPRINT(rtlpriv, FDM, DM_PWDB, "EntryMinPWDB = 0x%lx(%ld)\n",
0757 tmp_entry_min_pwdb, tmp_entry_min_pwdb);
0758 } else {
0759 rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
0760 }
0761
0762 if (!rtlpriv->dm.useramask)
0763 rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb);
0764 }
0765
0766 void rtl88e_dm_init_edca_turbo(struct ieee80211_hw *hw)
0767 {
0768 struct rtl_priv *rtlpriv = rtl_priv(hw);
0769
0770 rtlpriv->dm.current_turbo_edca = false;
0771 rtlpriv->dm.is_any_nonbepkts = false;
0772 rtlpriv->dm.is_cur_rdlstate = false;
0773 }
0774
0775 static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw)
0776 {
0777 struct rtl_priv *rtlpriv = rtl_priv(hw);
0778 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0779 static u64 last_txok_cnt;
0780 static u64 last_rxok_cnt;
0781 static u32 last_bt_edca_ul;
0782 static u32 last_bt_edca_dl;
0783 u64 cur_txok_cnt = 0;
0784 u64 cur_rxok_cnt = 0;
0785 u32 edca_be_ul = 0x5ea42b;
0786 u32 edca_be_dl = 0x5ea42b;
0787 bool bt_change_edca = false;
0788
0789 if ((last_bt_edca_ul != rtlpriv->btcoexist.bt_edca_ul) ||
0790 (last_bt_edca_dl != rtlpriv->btcoexist.bt_edca_dl)) {
0791 rtlpriv->dm.current_turbo_edca = false;
0792 last_bt_edca_ul = rtlpriv->btcoexist.bt_edca_ul;
0793 last_bt_edca_dl = rtlpriv->btcoexist.bt_edca_dl;
0794 }
0795
0796 if (rtlpriv->btcoexist.bt_edca_ul != 0) {
0797 edca_be_ul = rtlpriv->btcoexist.bt_edca_ul;
0798 bt_change_edca = true;
0799 }
0800
0801 if (rtlpriv->btcoexist.bt_edca_dl != 0) {
0802 edca_be_ul = rtlpriv->btcoexist.bt_edca_dl;
0803 bt_change_edca = true;
0804 }
0805
0806 if (mac->link_state != MAC80211_LINKED) {
0807 rtlpriv->dm.current_turbo_edca = false;
0808 return;
0809 }
0810 if ((bt_change_edca) ||
0811 ((!rtlpriv->dm.is_any_nonbepkts) &&
0812 (!rtlpriv->dm.disable_framebursting))) {
0813
0814 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
0815 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
0816
0817 if (cur_rxok_cnt > 4 * cur_txok_cnt) {
0818 if (!rtlpriv->dm.is_cur_rdlstate ||
0819 !rtlpriv->dm.current_turbo_edca) {
0820 rtl_write_dword(rtlpriv,
0821 REG_EDCA_BE_PARAM,
0822 edca_be_dl);
0823 rtlpriv->dm.is_cur_rdlstate = true;
0824 }
0825 } else {
0826 if (rtlpriv->dm.is_cur_rdlstate ||
0827 !rtlpriv->dm.current_turbo_edca) {
0828 rtl_write_dword(rtlpriv,
0829 REG_EDCA_BE_PARAM,
0830 edca_be_ul);
0831 rtlpriv->dm.is_cur_rdlstate = false;
0832 }
0833 }
0834 rtlpriv->dm.current_turbo_edca = true;
0835 } else {
0836 if (rtlpriv->dm.current_turbo_edca) {
0837 u8 tmp = AC0_BE;
0838
0839 rtlpriv->cfg->ops->set_hw_reg(hw,
0840 HW_VAR_AC_PARAM,
0841 &tmp);
0842 rtlpriv->dm.current_turbo_edca = false;
0843 }
0844 }
0845
0846 rtlpriv->dm.is_any_nonbepkts = false;
0847 last_txok_cnt = rtlpriv->stats.txbytesunicast;
0848 last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
0849 }
0850
0851 static void dm_txpower_track_cb_therm(struct ieee80211_hw *hw)
0852 {
0853 struct rtl_priv *rtlpriv = rtl_priv(hw);
0854 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
0855 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
0856 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0857 u8 thermalvalue = 0, delta, delta_lck, delta_iqk, offset;
0858 u8 thermalvalue_avg_count = 0;
0859 u32 thermalvalue_avg = 0;
0860 long ele_d, temp_cck;
0861 s8 ofdm_index[2], cck_index = 0,
0862 ofdm_index_old[2] = {0, 0}, cck_index_old = 0;
0863 int i = 0;
0864
0865
0866 u8 ofdm_min_index = 6, rf = 1;
0867
0868 enum _power_dec_inc {power_dec, power_inc};
0869
0870
0871
0872
0873 static const s8 delta_swing_table_idx[2][15] = {
0874 {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},
0875 {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10}
0876 };
0877 static const u8 thermal_threshold[2][15] = {
0878 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},
0879 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25}
0880 };
0881
0882
0883 rtlpriv->dm.txpower_trackinginit = true;
0884 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0885 "%s\n", __func__);
0886
0887 thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER,
0888 0xfc00);
0889 if (!thermalvalue)
0890 return;
0891 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0892 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
0893 thermalvalue, rtlpriv->dm.thermalvalue,
0894 rtlefuse->eeprom_thermalmeter);
0895
0896
0897 ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD) &
0898 MASKOFDM_D;
0899 for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
0900 if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
0901 ofdm_index_old[0] = (u8)i;
0902 rtldm->swing_idx_ofdm_base[RF90_PATH_A] = (u8)i;
0903 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0904 "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index = 0x%x\n",
0905 ROFDM0_XATXIQIMBALANCE,
0906 ele_d, ofdm_index_old[0]);
0907 break;
0908 }
0909 }
0910
0911
0912 temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK;
0913 for (i = 0; i < CCK_TABLE_LENGTH; i++) {
0914 if (rtlpriv->dm.cck_inch14) {
0915 if (memcmp(&temp_cck, &cck_tbl_ch14[i][2], 4) == 0) {
0916 cck_index_old = (u8)i;
0917 rtldm->swing_idx_cck_base = (u8)i;
0918 rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
0919 DBG_LOUD,
0920 "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch 14 %d\n",
0921 RCCK0_TXFILTER2, temp_cck,
0922 cck_index_old,
0923 rtlpriv->dm.cck_inch14);
0924 break;
0925 }
0926 } else {
0927 if (memcmp(&temp_cck, &cck_tbl_ch1_13[i][2], 4) == 0) {
0928 cck_index_old = (u8)i;
0929 rtldm->swing_idx_cck_base = (u8)i;
0930 rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
0931 DBG_LOUD,
0932 "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n",
0933 RCCK0_TXFILTER2, temp_cck,
0934 cck_index_old,
0935 rtlpriv->dm.cck_inch14);
0936 break;
0937 }
0938 }
0939 }
0940
0941
0942 if (!rtldm->thermalvalue) {
0943 rtlpriv->dm.thermalvalue = rtlefuse->eeprom_thermalmeter;
0944 rtlpriv->dm.thermalvalue_lck = thermalvalue;
0945 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
0946 for (i = 0; i < rf; i++)
0947 rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
0948 rtlpriv->dm.cck_index = cck_index_old;
0949 }
0950
0951
0952 rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue;
0953 rtldm->thermalvalue_avg_index++;
0954 if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_88E)
0955 rtldm->thermalvalue_avg_index = 0;
0956
0957 for (i = 0; i < AVG_THERMAL_NUM_88E; i++) {
0958 if (rtldm->thermalvalue_avg[i]) {
0959 thermalvalue_avg += rtldm->thermalvalue_avg[i];
0960 thermalvalue_avg_count++;
0961 }
0962 }
0963
0964 if (thermalvalue_avg_count)
0965 thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count);
0966
0967
0968 if (rtlhal->reloadtxpowerindex) {
0969 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
0970 (thermalvalue - rtlefuse->eeprom_thermalmeter) :
0971 (rtlefuse->eeprom_thermalmeter - thermalvalue);
0972 rtlhal->reloadtxpowerindex = false;
0973 rtlpriv->dm.done_txpower = false;
0974 } else if (rtlpriv->dm.done_txpower) {
0975 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
0976 (thermalvalue - rtlpriv->dm.thermalvalue) :
0977 (rtlpriv->dm.thermalvalue - thermalvalue);
0978 } else {
0979 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
0980 (thermalvalue - rtlefuse->eeprom_thermalmeter) :
0981 (rtlefuse->eeprom_thermalmeter - thermalvalue);
0982 }
0983 delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
0984 (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
0985 (rtlpriv->dm.thermalvalue_lck - thermalvalue);
0986 delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
0987 (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
0988 (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
0989
0990 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0991 "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",
0992 thermalvalue, rtlpriv->dm.thermalvalue,
0993 rtlefuse->eeprom_thermalmeter, delta, delta_lck,
0994 delta_iqk);
0995
0996 if (delta_lck >= 8) {
0997 rtlpriv->dm.thermalvalue_lck = thermalvalue;
0998 rtl88e_phy_lc_calibrate(hw);
0999 }
1000
1001
1002
1003
1004 if (delta > 0 && rtlpriv->dm.txpower_track_control) {
1005 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
1006 (thermalvalue - rtlefuse->eeprom_thermalmeter) :
1007 (rtlefuse->eeprom_thermalmeter - thermalvalue);
1008
1009
1010
1011
1012 if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
1013 CAL_SWING_OFF(offset, power_inc, INDEX_MAPPING_NUM,
1014 delta);
1015 for (i = 0; i < rf; i++)
1016 ofdm_index[i] =
1017 rtldm->ofdm_index[i] +
1018 delta_swing_table_idx[power_inc][offset];
1019 cck_index = rtldm->cck_index +
1020 delta_swing_table_idx[power_inc][offset];
1021 } else {
1022 CAL_SWING_OFF(offset, power_dec, INDEX_MAPPING_NUM,
1023 delta);
1024 for (i = 0; i < rf; i++)
1025 ofdm_index[i] =
1026 rtldm->ofdm_index[i] +
1027 delta_swing_table_idx[power_dec][offset];
1028 cck_index = rtldm->cck_index +
1029 delta_swing_table_idx[power_dec][offset];
1030 }
1031
1032
1033 for (i = 0; i < rf; i++) {
1034 if (ofdm_index[i] > OFDM_TABLE_SIZE-1)
1035 ofdm_index[i] = OFDM_TABLE_SIZE-1;
1036 else if (rtldm->ofdm_index[i] < ofdm_min_index)
1037 ofdm_index[i] = ofdm_min_index;
1038 }
1039
1040 if (cck_index > CCK_TABLE_SIZE-1)
1041 cck_index = CCK_TABLE_SIZE-1;
1042 else if (cck_index < 0)
1043 cck_index = 0;
1044
1045
1046 if (rtlpriv->dm.txpower_track_control) {
1047 rtldm->done_txpower = true;
1048 rtldm->swing_idx_ofdm[RF90_PATH_A] =
1049 (u8)ofdm_index[RF90_PATH_A];
1050 rtldm->swing_idx_cck = cck_index;
1051 if (rtldm->swing_idx_ofdm_cur !=
1052 rtldm->swing_idx_ofdm[0]) {
1053 rtldm->swing_idx_ofdm_cur =
1054 rtldm->swing_idx_ofdm[0];
1055 rtldm->swing_flag_ofdm = true;
1056 }
1057
1058 if (rtldm->swing_idx_cck_cur != rtldm->swing_idx_cck) {
1059 rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck;
1060 rtldm->swing_flag_cck = true;
1061 }
1062
1063 dm_tx_pwr_track_set_pwr(hw, TXAGC, 0, 0);
1064 }
1065 }
1066
1067 if (delta_iqk >= 8) {
1068 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
1069 rtl88e_phy_iq_calibrate(hw, false);
1070 }
1071
1072 if (rtldm->txpower_track_control)
1073 rtldm->thermalvalue = thermalvalue;
1074 rtldm->txpowercount = 0;
1075 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n");
1076 }
1077
1078 static void rtl88e_dm_init_txpower_tracking(struct ieee80211_hw *hw)
1079 {
1080 struct rtl_priv *rtlpriv = rtl_priv(hw);
1081
1082 rtlpriv->dm.txpower_tracking = true;
1083 rtlpriv->dm.txpower_trackinginit = false;
1084 rtlpriv->dm.txpowercount = 0;
1085 rtlpriv->dm.txpower_track_control = true;
1086
1087 rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A] = 12;
1088 rtlpriv->dm.swing_idx_ofdm_cur = 12;
1089 rtlpriv->dm.swing_flag_ofdm = false;
1090 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1091 "rtlpriv->dm.txpower_tracking = %d\n",
1092 rtlpriv->dm.txpower_tracking);
1093 }
1094
1095 void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw *hw)
1096 {
1097 struct rtl_priv *rtlpriv = rtl_priv(hw);
1098
1099 if (!rtlpriv->dm.txpower_tracking)
1100 return;
1101
1102 if (!rtlpriv->dm.tm_trigger) {
1103 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17)|BIT(16),
1104 0x03);
1105 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1106 "Trigger 88E Thermal Meter!!\n");
1107 rtlpriv->dm.tm_trigger = 1;
1108 return;
1109 } else {
1110 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1111 "Schedule TxPowerTracking !!\n");
1112 dm_txpower_track_cb_therm(hw);
1113 rtlpriv->dm.tm_trigger = 0;
1114 }
1115 }
1116
1117 void rtl88e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
1118 {
1119 struct rtl_priv *rtlpriv = rtl_priv(hw);
1120 struct rate_adaptive *p_ra = &rtlpriv->ra;
1121
1122 p_ra->ratr_state = DM_RATR_STA_INIT;
1123 p_ra->pre_ratr_state = DM_RATR_STA_INIT;
1124
1125 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
1126 rtlpriv->dm.useramask = true;
1127 else
1128 rtlpriv->dm.useramask = false;
1129 }
1130
1131 static void rtl88e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
1132 {
1133 struct rtl_priv *rtlpriv = rtl_priv(hw);
1134 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1135 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1136 struct rate_adaptive *p_ra = &rtlpriv->ra;
1137 u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
1138 struct ieee80211_sta *sta = NULL;
1139
1140 if (is_hal_stop(rtlhal)) {
1141 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
1142 "driver is going to unload\n");
1143 return;
1144 }
1145
1146 if (!rtlpriv->dm.useramask) {
1147 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
1148 "driver does not control rate adaptive mask\n");
1149 return;
1150 }
1151
1152 if (mac->link_state == MAC80211_LINKED &&
1153 mac->opmode == NL80211_IFTYPE_STATION) {
1154 switch (p_ra->pre_ratr_state) {
1155 case DM_RATR_STA_HIGH:
1156 high_rssithresh_for_ra = 50;
1157 low_rssithresh_for_ra = 20;
1158 break;
1159 case DM_RATR_STA_MIDDLE:
1160 high_rssithresh_for_ra = 55;
1161 low_rssithresh_for_ra = 20;
1162 break;
1163 case DM_RATR_STA_LOW:
1164 high_rssithresh_for_ra = 50;
1165 low_rssithresh_for_ra = 25;
1166 break;
1167 default:
1168 high_rssithresh_for_ra = 50;
1169 low_rssithresh_for_ra = 20;
1170 break;
1171 }
1172
1173 if (rtlpriv->dm.undec_sm_pwdb >
1174 (long)high_rssithresh_for_ra)
1175 p_ra->ratr_state = DM_RATR_STA_HIGH;
1176 else if (rtlpriv->dm.undec_sm_pwdb >
1177 (long)low_rssithresh_for_ra)
1178 p_ra->ratr_state = DM_RATR_STA_MIDDLE;
1179 else
1180 p_ra->ratr_state = DM_RATR_STA_LOW;
1181
1182 if (p_ra->pre_ratr_state != p_ra->ratr_state) {
1183 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
1184 "RSSI = %ld\n",
1185 rtlpriv->dm.undec_sm_pwdb);
1186 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
1187 "RSSI_LEVEL = %d\n", p_ra->ratr_state);
1188 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
1189 "PreState = %d, CurState = %d\n",
1190 p_ra->pre_ratr_state, p_ra->ratr_state);
1191
1192 rcu_read_lock();
1193 sta = rtl_find_sta(hw, mac->bssid);
1194 if (sta)
1195 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
1196 p_ra->ratr_state,
1197 true);
1198 rcu_read_unlock();
1199
1200 p_ra->pre_ratr_state = p_ra->ratr_state;
1201 }
1202 }
1203 }
1204
1205 static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1206 {
1207 struct rtl_priv *rtlpriv = rtl_priv(hw);
1208 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
1209
1210 dm_pstable->pre_ccastate = CCA_MAX;
1211 dm_pstable->cur_ccasate = CCA_MAX;
1212 dm_pstable->pre_rfstate = RF_MAX;
1213 dm_pstable->cur_rfstate = RF_MAX;
1214 dm_pstable->rssi_val_min = 0;
1215 }
1216
1217 static void rtl88e_dm_update_rx_idle_ant(struct ieee80211_hw *hw,
1218 u8 ant)
1219 {
1220 struct rtl_priv *rtlpriv = rtl_priv(hw);
1221 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1222 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1223 struct fast_ant_training *pfat_table = &rtldm->fat_table;
1224 u32 default_ant, optional_ant;
1225
1226 if (pfat_table->rx_idle_ant != ant) {
1227 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1228 "need to update rx idle ant\n");
1229 if (ant == MAIN_ANT) {
1230 default_ant =
1231 (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1232 MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
1233 optional_ant =
1234 (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1235 AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
1236 } else {
1237 default_ant =
1238 (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1239 AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
1240 optional_ant =
1241 (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1242 MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
1243 }
1244
1245 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
1246 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1247 BIT(5) | BIT(4) | BIT(3), default_ant);
1248 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1249 BIT(8) | BIT(7) | BIT(6), optional_ant);
1250 rtl_set_bbreg(hw, DM_REG_ANTSEL_CTRL_11N,
1251 BIT(14) | BIT(13) | BIT(12),
1252 default_ant);
1253 rtl_set_bbreg(hw, DM_REG_RESP_TX_11N,
1254 BIT(6) | BIT(7), default_ant);
1255 } else if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) {
1256 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1257 BIT(5) | BIT(4) | BIT(3), default_ant);
1258 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1259 BIT(8) | BIT(7) | BIT(6), optional_ant);
1260 }
1261 }
1262 pfat_table->rx_idle_ant = ant;
1263 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "RxIdleAnt %s\n",
1264 (ant == MAIN_ANT) ? ("MAIN_ANT") : ("AUX_ANT"));
1265 }
1266
1267 static void rtl88e_dm_update_tx_ant(struct ieee80211_hw *hw,
1268 u8 ant, u32 mac_id)
1269 {
1270 struct rtl_priv *rtlpriv = rtl_priv(hw);
1271 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1272 struct fast_ant_training *pfat_table = &rtldm->fat_table;
1273 u8 target_ant;
1274
1275 if (ant == MAIN_ANT)
1276 target_ant = MAIN_ANT_CG_TRX;
1277 else
1278 target_ant = AUX_ANT_CG_TRX;
1279
1280 pfat_table->antsel_a[mac_id] = target_ant & BIT(0);
1281 pfat_table->antsel_b[mac_id] = (target_ant & BIT(1)) >> 1;
1282 pfat_table->antsel_c[mac_id] = (target_ant & BIT(2)) >> 2;
1283 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "txfrominfo target ant %s\n",
1284 (ant == MAIN_ANT) ? ("MAIN_ANT") : ("AUX_ANT"));
1285 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "antsel_tr_mux = 3'b%d%d%d\n",
1286 pfat_table->antsel_c[mac_id],
1287 pfat_table->antsel_b[mac_id],
1288 pfat_table->antsel_a[mac_id]);
1289 }
1290
1291 static void rtl88e_dm_rx_hw_antena_div_init(struct ieee80211_hw *hw)
1292 {
1293 u32 value32;
1294
1295
1296 value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1297 rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N,
1298 MASKDWORD, value32 | (BIT(23) | BIT(25)));
1299
1300 rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1301 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1302 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 1);
1303 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1304
1305 rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1306
1307 rtl_set_bbreg(hw, DM_REG_BB_PWR_SAV4_11N, BIT(7), 1);
1308 rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1);
1309 rtl88e_dm_update_rx_idle_ant(hw, MAIN_ANT);
1310 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKLWORD, 0x0201);
1311 }
1312
1313 static void rtl88e_dm_trx_hw_antenna_div_init(struct ieee80211_hw *hw)
1314 {
1315 u32 value32;
1316
1317
1318 value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1319 rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD,
1320 value32 | (BIT(23) | BIT(25)));
1321
1322 rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1323 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1324 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 0);
1325 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1326
1327 rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1328
1329 rtl_set_bbreg(hw, DM_REG_BB_PWR_SAV4_11N, BIT(7), 1);
1330 rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1);
1331
1332 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 0);
1333 rtl88e_dm_update_rx_idle_ant(hw, MAIN_ANT);
1334 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKLWORD, 0x0201);
1335 }
1336
1337 static void rtl88e_dm_fast_training_init(struct ieee80211_hw *hw)
1338 {
1339 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1340 struct fast_ant_training *pfat_table = &rtldm->fat_table;
1341 u32 ant_combination = 2;
1342 u32 value32, i;
1343
1344 for (i = 0; i < 6; i++) {
1345 pfat_table->bssid[i] = 0;
1346 pfat_table->ant_sum[i] = 0;
1347 pfat_table->ant_cnt[i] = 0;
1348 pfat_table->ant_ave[i] = 0;
1349 }
1350 pfat_table->train_idx = 0;
1351 pfat_table->fat_state = FAT_NORMAL_STATE;
1352
1353
1354 value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1355 rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N,
1356 MASKDWORD, value32 | (BIT(23) | BIT(25)));
1357 value32 = rtl_get_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N, MASKDWORD);
1358 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,
1359 MASKDWORD, value32 | (BIT(16) | BIT(17)));
1360 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,
1361 MASKLWORD, 0);
1362 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA1_11N,
1363 MASKDWORD, 0);
1364
1365
1366 rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1367 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1368 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 0);
1369 rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1370
1371
1372 rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1373
1374 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE0, 1);
1375 rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE1, 2);
1376
1377
1378 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 1);
1379 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1380 BIT(5) | BIT(4) | BIT(3), 0);
1381 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1382 BIT(8) | BIT(7) | BIT(6), 1);
1383 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1384 BIT(2) | BIT(1) | BIT(0), (ant_combination - 1));
1385
1386 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1387 }
1388
1389 static void rtl88e_dm_antenna_div_init(struct ieee80211_hw *hw)
1390 {
1391 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1392
1393 if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1394 rtl88e_dm_rx_hw_antena_div_init(hw);
1395 else if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1396 rtl88e_dm_trx_hw_antenna_div_init(hw);
1397 else if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)
1398 rtl88e_dm_fast_training_init(hw);
1399
1400 }
1401
1402 void rtl88e_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,
1403 u8 *pdesc, u32 mac_id)
1404 {
1405 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1406 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1407 struct fast_ant_training *pfat_table = &rtldm->fat_table;
1408 __le32 *pdesc32 = (__le32 *)pdesc;
1409
1410 if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||
1411 (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)) {
1412 set_tx_desc_antsel_a(pdesc32, pfat_table->antsel_a[mac_id]);
1413 set_tx_desc_antsel_b(pdesc32, pfat_table->antsel_b[mac_id]);
1414 set_tx_desc_antsel_c(pdesc32, pfat_table->antsel_c[mac_id]);
1415 }
1416 }
1417
1418 void rtl88e_dm_ant_sel_statistics(struct ieee80211_hw *hw,
1419 u8 antsel_tr_mux, u32 mac_id,
1420 u32 rx_pwdb_all)
1421 {
1422 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1423 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1424 struct fast_ant_training *pfat_table = &rtldm->fat_table;
1425
1426 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
1427 if (antsel_tr_mux == MAIN_ANT_CG_TRX) {
1428 pfat_table->main_ant_sum[mac_id] += rx_pwdb_all;
1429 pfat_table->main_ant_cnt[mac_id]++;
1430 } else {
1431 pfat_table->aux_ant_sum[mac_id] += rx_pwdb_all;
1432 pfat_table->aux_ant_cnt[mac_id]++;
1433 }
1434 } else if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) {
1435 if (antsel_tr_mux == MAIN_ANT_CGCS_RX) {
1436 pfat_table->main_ant_sum[mac_id] += rx_pwdb_all;
1437 pfat_table->main_ant_cnt[mac_id]++;
1438 } else {
1439 pfat_table->aux_ant_sum[mac_id] += rx_pwdb_all;
1440 pfat_table->aux_ant_cnt[mac_id]++;
1441 }
1442 }
1443 }
1444
1445 static void rtl88e_dm_hw_ant_div(struct ieee80211_hw *hw)
1446 {
1447 struct rtl_priv *rtlpriv = rtl_priv(hw);
1448 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1449 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1450 struct rtl_sta_info *drv_priv;
1451 struct fast_ant_training *pfat_table = &rtldm->fat_table;
1452 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
1453 u32 i, min_rssi = 0xff, ant_div_max_rssi = 0;
1454 u32 max_rssi = 0, local_min_rssi, local_max_rssi;
1455 u32 main_rssi, aux_rssi;
1456 u8 rx_idle_ant = 0, target_ant = 7;
1457
1458
1459 i = 0;
1460 main_rssi = (pfat_table->main_ant_cnt[i] != 0) ?
1461 (pfat_table->main_ant_sum[i] / pfat_table->main_ant_cnt[i]) : 0;
1462 aux_rssi = (pfat_table->aux_ant_cnt[i] != 0) ?
1463 (pfat_table->aux_ant_sum[i] / pfat_table->aux_ant_cnt[i]) : 0;
1464 target_ant = (main_rssi == aux_rssi) ?
1465 pfat_table->rx_idle_ant : ((main_rssi >= aux_rssi) ?
1466 MAIN_ANT : AUX_ANT);
1467 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1468 "main_ant_sum %d main_ant_cnt %d\n",
1469 pfat_table->main_ant_sum[i],
1470 pfat_table->main_ant_cnt[i]);
1471 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1472 "aux_ant_sum %d aux_ant_cnt %d\n",
1473 pfat_table->aux_ant_sum[i], pfat_table->aux_ant_cnt[i]);
1474 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "main_rssi %d aux_rssi%d\n",
1475 main_rssi, aux_rssi);
1476 local_max_rssi = (main_rssi > aux_rssi) ? main_rssi : aux_rssi;
1477 if ((local_max_rssi > ant_div_max_rssi) && (local_max_rssi < 40))
1478 ant_div_max_rssi = local_max_rssi;
1479 if (local_max_rssi > max_rssi)
1480 max_rssi = local_max_rssi;
1481
1482 if ((pfat_table->rx_idle_ant == MAIN_ANT) && (main_rssi == 0))
1483 main_rssi = aux_rssi;
1484 else if ((pfat_table->rx_idle_ant == AUX_ANT) && (aux_rssi == 0))
1485 aux_rssi = main_rssi;
1486
1487 local_min_rssi = (main_rssi > aux_rssi) ? aux_rssi : main_rssi;
1488 if (local_min_rssi < min_rssi) {
1489 min_rssi = local_min_rssi;
1490 rx_idle_ant = target_ant;
1491 }
1492 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1493 rtl88e_dm_update_tx_ant(hw, target_ant, i);
1494
1495 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
1496 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) {
1497 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1498 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
1499 i++;
1500 main_rssi = (pfat_table->main_ant_cnt[i] != 0) ?
1501 (pfat_table->main_ant_sum[i] /
1502 pfat_table->main_ant_cnt[i]) : 0;
1503 aux_rssi = (pfat_table->aux_ant_cnt[i] != 0) ?
1504 (pfat_table->aux_ant_sum[i] /
1505 pfat_table->aux_ant_cnt[i]) : 0;
1506 target_ant = (main_rssi == aux_rssi) ?
1507 pfat_table->rx_idle_ant : ((main_rssi >=
1508 aux_rssi) ? MAIN_ANT : AUX_ANT);
1509
1510 local_max_rssi = (main_rssi > aux_rssi) ?
1511 main_rssi : aux_rssi;
1512 if ((local_max_rssi > ant_div_max_rssi) &&
1513 (local_max_rssi < 40))
1514 ant_div_max_rssi = local_max_rssi;
1515 if (local_max_rssi > max_rssi)
1516 max_rssi = local_max_rssi;
1517
1518 if ((pfat_table->rx_idle_ant == MAIN_ANT) &&
1519 (main_rssi == 0))
1520 main_rssi = aux_rssi;
1521 else if ((pfat_table->rx_idle_ant == AUX_ANT) &&
1522 (aux_rssi == 0))
1523 aux_rssi = main_rssi;
1524
1525 local_min_rssi = (main_rssi > aux_rssi) ?
1526 aux_rssi : main_rssi;
1527 if (local_min_rssi < min_rssi) {
1528 min_rssi = local_min_rssi;
1529 rx_idle_ant = target_ant;
1530 }
1531 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1532 rtl88e_dm_update_tx_ant(hw, target_ant, i);
1533 }
1534 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1535 }
1536
1537 for (i = 0; i < ASSOCIATE_ENTRY_NUM; i++) {
1538 pfat_table->main_ant_sum[i] = 0;
1539 pfat_table->aux_ant_sum[i] = 0;
1540 pfat_table->main_ant_cnt[i] = 0;
1541 pfat_table->aux_ant_cnt[i] = 0;
1542 }
1543
1544 rtl88e_dm_update_rx_idle_ant(hw, rx_idle_ant);
1545
1546 dm_dig->antdiv_rssi_max = ant_div_max_rssi;
1547 dm_dig->rssi_max = max_rssi;
1548 }
1549
1550 static void rtl88e_set_next_mac_address_target(struct ieee80211_hw *hw)
1551 {
1552 struct rtl_priv *rtlpriv = rtl_priv(hw);
1553 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1554 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1555 struct rtl_sta_info *drv_priv;
1556 struct fast_ant_training *pfat_table = &rtldm->fat_table;
1557 u32 value32, i, j = 0;
1558
1559 if (mac->link_state >= MAC80211_LINKED) {
1560 for (i = 0; i < ASSOCIATE_ENTRY_NUM; i++) {
1561 if ((pfat_table->train_idx + 1) == ASSOCIATE_ENTRY_NUM)
1562 pfat_table->train_idx = 0;
1563 else
1564 pfat_table->train_idx++;
1565
1566 if (pfat_table->train_idx == 0) {
1567 value32 = (mac->mac_addr[5] << 8) |
1568 mac->mac_addr[4];
1569 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,
1570 MASKLWORD, value32);
1571
1572 value32 = (mac->mac_addr[3] << 24) |
1573 (mac->mac_addr[2] << 16) |
1574 (mac->mac_addr[1] << 8) |
1575 mac->mac_addr[0];
1576 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA1_11N,
1577 MASKDWORD, value32);
1578 break;
1579 }
1580
1581 if (rtlpriv->mac80211.opmode !=
1582 NL80211_IFTYPE_STATION) {
1583 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1584 list_for_each_entry(drv_priv,
1585 &rtlpriv->entry_list, list) {
1586 j++;
1587 if (j != pfat_table->train_idx)
1588 continue;
1589
1590 value32 = (drv_priv->mac_addr[5] << 8) |
1591 drv_priv->mac_addr[4];
1592 rtl_set_bbreg(hw,
1593 DM_REG_ANT_TRAIN_PARA2_11N,
1594 MASKLWORD, value32);
1595
1596 value32 = (drv_priv->mac_addr[3] << 24) |
1597 (drv_priv->mac_addr[2] << 16) |
1598 (drv_priv->mac_addr[1] << 8) |
1599 drv_priv->mac_addr[0];
1600 rtl_set_bbreg(hw,
1601 DM_REG_ANT_TRAIN_PARA1_11N,
1602 MASKDWORD, value32);
1603 break;
1604 }
1605 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1606
1607 if (j == pfat_table->train_idx)
1608 break;
1609 }
1610 }
1611 }
1612 }
1613
1614 static void rtl88e_dm_fast_ant_training(struct ieee80211_hw *hw)
1615 {
1616 struct rtl_priv *rtlpriv = rtl_priv(hw);
1617 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1618 struct fast_ant_training *pfat_table = &rtldm->fat_table;
1619 u32 i, max_rssi = 0;
1620 u8 target_ant = 2;
1621 bool bpkt_filter_match = false;
1622
1623 if (pfat_table->fat_state == FAT_TRAINING_STATE) {
1624 for (i = 0; i < 7; i++) {
1625 if (pfat_table->ant_cnt[i] == 0) {
1626 pfat_table->ant_ave[i] = 0;
1627 } else {
1628 pfat_table->ant_ave[i] =
1629 pfat_table->ant_sum[i] /
1630 pfat_table->ant_cnt[i];
1631 bpkt_filter_match = true;
1632 }
1633
1634 if (pfat_table->ant_ave[i] > max_rssi) {
1635 max_rssi = pfat_table->ant_ave[i];
1636 target_ant = (u8) i;
1637 }
1638 }
1639
1640 if (!bpkt_filter_match) {
1641 rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N,
1642 BIT(16), 0);
1643 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1644 } else {
1645 rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N,
1646 BIT(16), 0);
1647 rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(8) |
1648 BIT(7) | BIT(6), target_ant);
1649 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,
1650 BIT(21), 1);
1651
1652 pfat_table->antsel_a[pfat_table->train_idx] =
1653 target_ant & BIT(0);
1654 pfat_table->antsel_b[pfat_table->train_idx] =
1655 (target_ant & BIT(1)) >> 1;
1656 pfat_table->antsel_c[pfat_table->train_idx] =
1657 (target_ant & BIT(2)) >> 2;
1658
1659 if (target_ant == 0)
1660 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1661 }
1662
1663 for (i = 0; i < 7; i++) {
1664 pfat_table->ant_sum[i] = 0;
1665 pfat_table->ant_cnt[i] = 0;
1666 }
1667
1668 pfat_table->fat_state = FAT_NORMAL_STATE;
1669 return;
1670 }
1671
1672 if (pfat_table->fat_state == FAT_NORMAL_STATE) {
1673 rtl88e_set_next_mac_address_target(hw);
1674
1675 pfat_table->fat_state = FAT_TRAINING_STATE;
1676 rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N, BIT(16), 1);
1677 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1678
1679 mod_timer(&rtlpriv->works.fast_antenna_training_timer,
1680 jiffies + MSECS(RTL_WATCH_DOG_TIME));
1681 }
1682 }
1683
1684 void rtl88e_dm_fast_antenna_training_callback(struct timer_list *t)
1685 {
1686 struct rtl_priv *rtlpriv =
1687 from_timer(rtlpriv, t, works.fast_antenna_training_timer);
1688 struct ieee80211_hw *hw = rtlpriv->hw;
1689
1690 rtl88e_dm_fast_ant_training(hw);
1691 }
1692
1693 static void rtl88e_dm_antenna_diversity(struct ieee80211_hw *hw)
1694 {
1695 struct rtl_priv *rtlpriv = rtl_priv(hw);
1696 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1697 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1698 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1699 struct fast_ant_training *pfat_table = &rtldm->fat_table;
1700
1701 if (mac->link_state < MAC80211_LINKED) {
1702 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No Link\n");
1703 if (pfat_table->becomelinked) {
1704 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
1705 "need to turn off HW AntDiv\n");
1706 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1707 rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA1_11N,
1708 BIT(15), 0);
1709 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1710 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,
1711 BIT(21), 0);
1712 pfat_table->becomelinked =
1713 (mac->link_state == MAC80211_LINKED) ?
1714 true : false;
1715 }
1716 return;
1717 } else {
1718 if (!pfat_table->becomelinked) {
1719 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
1720 "Need to turn on HW AntDiv\n");
1721 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1722 rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA1_11N,
1723 BIT(15), 1);
1724 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1725 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,
1726 BIT(21), 1);
1727 pfat_table->becomelinked =
1728 (mac->link_state >= MAC80211_LINKED) ?
1729 true : false;
1730 }
1731 }
1732
1733 if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||
1734 (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV))
1735 rtl88e_dm_hw_ant_div(hw);
1736 else if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)
1737 rtl88e_dm_fast_ant_training(hw);
1738 }
1739
1740 void rtl88e_dm_init(struct ieee80211_hw *hw)
1741 {
1742 struct rtl_priv *rtlpriv = rtl_priv(hw);
1743 u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
1744
1745 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1746 rtl_dm_diginit(hw, cur_igvalue);
1747 rtl88e_dm_init_dynamic_txpower(hw);
1748 rtl88e_dm_init_edca_turbo(hw);
1749 rtl88e_dm_init_rate_adaptive_mask(hw);
1750 rtl88e_dm_init_txpower_tracking(hw);
1751 rtl92c_dm_init_dynamic_bb_powersaving(hw);
1752 rtl88e_dm_antenna_div_init(hw);
1753 }
1754
1755 void rtl88e_dm_watchdog(struct ieee80211_hw *hw)
1756 {
1757 struct rtl_priv *rtlpriv = rtl_priv(hw);
1758 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1759 bool fw_current_inpsmode = false;
1760 bool fw_ps_awake = true;
1761
1762 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1763 (u8 *)(&fw_current_inpsmode));
1764 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1765 (u8 *)(&fw_ps_awake));
1766 if (ppsc->p2p_ps_info.p2p_ps_mode)
1767 fw_ps_awake = false;
1768
1769 spin_lock(&rtlpriv->locks.rf_ps_lock);
1770 if ((ppsc->rfpwr_state == ERFON) &&
1771 ((!fw_current_inpsmode) && fw_ps_awake) &&
1772 (!ppsc->rfchange_inprogress)) {
1773 rtl88e_dm_pwdb_monitor(hw);
1774 rtl88e_dm_dig(hw);
1775 rtl88e_dm_false_alarm_counter_statistics(hw);
1776 rtl92c_dm_dynamic_txpower(hw);
1777 rtl88e_dm_check_txpower_tracking(hw);
1778 rtl88e_dm_refresh_rate_adaptive_mask(hw);
1779 rtl88e_dm_check_edca_turbo(hw);
1780 rtl88e_dm_antenna_diversity(hw);
1781 }
1782 spin_unlock(&rtlpriv->locks.rf_ps_lock);
1783 }