0001
0002
0003
0004 #include <linux/export.h>
0005 #include "dm_common.h"
0006 #include "phy_common.h"
0007 #include "../pci.h"
0008 #include "../base.h"
0009 #include "../core.h"
0010
0011 #define BT_RSSI_STATE_NORMAL_POWER BIT(0)
0012 #define BT_RSSI_STATE_AMDPU_OFF BIT(1)
0013 #define BT_RSSI_STATE_SPECIAL_LOW BIT(2)
0014 #define BT_RSSI_STATE_BG_EDCA_LOW BIT(3)
0015 #define BT_RSSI_STATE_TXPOWER_LOW BIT(4)
0016 #define BT_MASK 0x00ffffff
0017
0018 #define RTLPRIV (struct rtl_priv *)
0019 #define GET_UNDECORATED_AVERAGE_RSSI(_priv) \
0020 ((RTLPRIV(_priv))->mac80211.opmode == \
0021 NL80211_IFTYPE_ADHOC) ? \
0022 ((RTLPRIV(_priv))->dm.entry_min_undec_sm_pwdb) : \
0023 ((RTLPRIV(_priv))->dm.undec_sm_pwdb)
0024
0025 static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
0026 0x7f8001fe,
0027 0x788001e2,
0028 0x71c001c7,
0029 0x6b8001ae,
0030 0x65400195,
0031 0x5fc0017f,
0032 0x5a400169,
0033 0x55400155,
0034 0x50800142,
0035 0x4c000130,
0036 0x47c0011f,
0037 0x43c0010f,
0038 0x40000100,
0039 0x3c8000f2,
0040 0x390000e4,
0041 0x35c000d7,
0042 0x32c000cb,
0043 0x300000c0,
0044 0x2d4000b5,
0045 0x2ac000ab,
0046 0x288000a2,
0047 0x26000098,
0048 0x24000090,
0049 0x22000088,
0050 0x20000080,
0051 0x1e400079,
0052 0x1c800072,
0053 0x1b00006c,
0054 0x19800066,
0055 0x18000060,
0056 0x16c0005b,
0057 0x15800056,
0058 0x14400051,
0059 0x1300004c,
0060 0x12000048,
0061 0x11000044,
0062 0x10000040,
0063 };
0064
0065 static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
0066 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
0067 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
0068 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
0069 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
0070 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
0071 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
0072 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
0073 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
0074 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
0075 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
0076 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
0077 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
0078 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
0079 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
0080 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
0081 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
0082 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
0083 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
0084 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
0085 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
0086 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
0087 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
0088 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},
0089 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},
0090 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},
0091 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},
0092 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},
0093 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
0094 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},
0095 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},
0096 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},
0097 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},
0098 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}
0099 };
0100
0101 static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
0102 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
0103 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
0104 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
0105 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},
0106 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
0107 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},
0108 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
0109 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
0110 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
0111 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
0112 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
0113 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
0114 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
0115 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
0116 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
0117 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
0118 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
0119 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
0120 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
0121 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
0122 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
0123 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
0124 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},
0125 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
0126 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
0127 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},
0128 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
0129 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
0130 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
0131 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
0132 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
0133 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
0134 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
0135 };
0136
0137 static u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a};
0138
0139 void dm_restorepowerindex(struct ieee80211_hw *hw)
0140 {
0141 struct rtl_priv *rtlpriv = rtl_priv(hw);
0142 u8 index;
0143
0144 for (index = 0; index < 6; index++)
0145 rtl_write_byte(rtlpriv, power_index_reg[index],
0146 rtlpriv->dm.powerindex_backup[index]);
0147 }
0148 EXPORT_SYMBOL_GPL(dm_restorepowerindex);
0149
0150 void dm_writepowerindex(struct ieee80211_hw *hw, u8 value)
0151 {
0152 struct rtl_priv *rtlpriv = rtl_priv(hw);
0153 u8 index;
0154
0155 for (index = 0; index < 6; index++)
0156 rtl_write_byte(rtlpriv, power_index_reg[index], value);
0157 }
0158 EXPORT_SYMBOL_GPL(dm_writepowerindex);
0159
0160 void dm_savepowerindex(struct ieee80211_hw *hw)
0161 {
0162 struct rtl_priv *rtlpriv = rtl_priv(hw);
0163 u8 index;
0164 u8 tmp;
0165
0166 for (index = 0; index < 6; index++) {
0167 tmp = rtl_read_byte(rtlpriv, power_index_reg[index]);
0168 rtlpriv->dm.powerindex_backup[index] = tmp;
0169 }
0170 }
0171 EXPORT_SYMBOL_GPL(dm_savepowerindex);
0172
0173 static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
0174 {
0175 struct rtl_priv *rtlpriv = rtl_priv(hw);
0176 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0177 long rssi_val_min = 0;
0178
0179 if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) &&
0180 (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) {
0181 if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0)
0182 rssi_val_min =
0183 (rtlpriv->dm.entry_min_undec_sm_pwdb >
0184 rtlpriv->dm.undec_sm_pwdb) ?
0185 rtlpriv->dm.undec_sm_pwdb :
0186 rtlpriv->dm.entry_min_undec_sm_pwdb;
0187 else
0188 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
0189 } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT ||
0190 dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) {
0191 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
0192 } else if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) {
0193 rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
0194 }
0195
0196 if (rssi_val_min > 100)
0197 rssi_val_min = 100;
0198 return (u8)rssi_val_min;
0199 }
0200
0201 static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
0202 {
0203 u32 ret_value;
0204 struct rtl_priv *rtlpriv = rtl_priv(hw);
0205 struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
0206
0207 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
0208 falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
0209
0210 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
0211 falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
0212 falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
0213
0214 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
0215 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
0216
0217 ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);
0218 falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff);
0219 falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16);
0220
0221 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
0222 falsealm_cnt->cnt_rate_illegal +
0223 falsealm_cnt->cnt_crc8_fail +
0224 falsealm_cnt->cnt_mcs_fail +
0225 falsealm_cnt->cnt_fast_fsync_fail +
0226 falsealm_cnt->cnt_sb_search_fail;
0227
0228 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
0229 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
0230 falsealm_cnt->cnt_cck_fail = ret_value;
0231
0232 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
0233 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
0234 falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail +
0235 falsealm_cnt->cnt_rate_illegal +
0236 falsealm_cnt->cnt_crc8_fail +
0237 falsealm_cnt->cnt_mcs_fail +
0238 falsealm_cnt->cnt_cck_fail);
0239
0240 rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
0241 rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
0242 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
0243 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
0244
0245 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0246 "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
0247 falsealm_cnt->cnt_parity_fail,
0248 falsealm_cnt->cnt_rate_illegal,
0249 falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
0250
0251 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0252 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
0253 falsealm_cnt->cnt_ofdm_fail,
0254 falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
0255 }
0256
0257 static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
0258 {
0259 struct rtl_priv *rtlpriv = rtl_priv(hw);
0260 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0261 u8 value_igi = dm_digtable->cur_igvalue;
0262
0263 if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
0264 value_igi--;
0265 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
0266 value_igi += 0;
0267 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2)
0268 value_igi++;
0269 else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2)
0270 value_igi += 2;
0271
0272 if (value_igi > DM_DIG_FA_UPPER)
0273 value_igi = DM_DIG_FA_UPPER;
0274 else if (value_igi < DM_DIG_FA_LOWER)
0275 value_igi = DM_DIG_FA_LOWER;
0276
0277 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
0278 value_igi = DM_DIG_FA_UPPER;
0279
0280 dm_digtable->cur_igvalue = value_igi;
0281 rtl92c_dm_write_dig(hw);
0282 }
0283
0284 static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
0285 {
0286 struct rtl_priv *rtlpriv = rtl_priv(hw);
0287 struct dig_t *digtable = &rtlpriv->dm_digtable;
0288 u32 isbt;
0289
0290
0291 if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
0292 digtable->large_fa_hit++;
0293 if (digtable->forbidden_igi < digtable->cur_igvalue) {
0294 digtable->forbidden_igi = digtable->cur_igvalue;
0295 digtable->large_fa_hit = 1;
0296 }
0297
0298 if (digtable->large_fa_hit >= 3) {
0299 if ((digtable->forbidden_igi + 1) >
0300 digtable->rx_gain_max)
0301 digtable->rx_gain_min = digtable->rx_gain_max;
0302 else
0303 digtable->rx_gain_min = (digtable->forbidden_igi + 1);
0304 digtable->recover_cnt = 3600;
0305 }
0306 } else {
0307
0308 if (digtable->recover_cnt != 0) {
0309 digtable->recover_cnt--;
0310 } else {
0311 if (digtable->large_fa_hit == 0) {
0312 if ((digtable->forbidden_igi-1) < DM_DIG_MIN) {
0313 digtable->forbidden_igi = DM_DIG_MIN;
0314 digtable->rx_gain_min = DM_DIG_MIN;
0315 } else {
0316 digtable->forbidden_igi--;
0317 digtable->rx_gain_min = digtable->forbidden_igi + 1;
0318 }
0319 } else if (digtable->large_fa_hit == 3) {
0320 digtable->large_fa_hit = 0;
0321 }
0322 }
0323 }
0324 if (rtlpriv->falsealm_cnt.cnt_all < 250) {
0325 isbt = rtl_read_byte(rtlpriv, 0x4fd) & 0x01;
0326
0327 if (!isbt) {
0328 if (rtlpriv->falsealm_cnt.cnt_all >
0329 digtable->fa_lowthresh) {
0330 if ((digtable->back_val - 2) <
0331 digtable->back_range_min)
0332 digtable->back_val = digtable->back_range_min;
0333 else
0334 digtable->back_val -= 2;
0335 } else if (rtlpriv->falsealm_cnt.cnt_all <
0336 digtable->fa_lowthresh) {
0337 if ((digtable->back_val + 2) >
0338 digtable->back_range_max)
0339 digtable->back_val = digtable->back_range_max;
0340 else
0341 digtable->back_val += 2;
0342 }
0343 } else {
0344 digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
0345 }
0346 } else {
0347
0348 if (rtlpriv->falsealm_cnt.cnt_all > 1000)
0349 digtable->cur_igvalue = digtable->pre_igvalue + 2;
0350 else if (rtlpriv->falsealm_cnt.cnt_all > 750)
0351 digtable->cur_igvalue = digtable->pre_igvalue + 1;
0352 else if (rtlpriv->falsealm_cnt.cnt_all < 500)
0353 digtable->cur_igvalue = digtable->pre_igvalue - 1;
0354 }
0355
0356
0357 if (digtable->cur_igvalue > digtable->rx_gain_max)
0358 digtable->cur_igvalue = digtable->rx_gain_max;
0359
0360 if (digtable->cur_igvalue < digtable->rx_gain_min)
0361 digtable->cur_igvalue = digtable->rx_gain_min;
0362
0363 rtl92c_dm_write_dig(hw);
0364 }
0365
0366 static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
0367 {
0368 static u8 initialized;
0369 struct rtl_priv *rtlpriv = rtl_priv(hw);
0370 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0371 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0372 long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb;
0373 bool multi_sta = false;
0374
0375 if (mac->opmode == NL80211_IFTYPE_ADHOC)
0376 multi_sta = true;
0377
0378 if (!multi_sta ||
0379 dm_digtable->cursta_cstate == DIG_STA_DISCONNECT) {
0380 initialized = false;
0381 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
0382 return;
0383 } else if (!initialized) {
0384 initialized = true;
0385 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
0386 dm_digtable->cur_igvalue = 0x20;
0387 rtl92c_dm_write_dig(hw);
0388 }
0389
0390 if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) {
0391 if ((rssi_strength < dm_digtable->rssi_lowthresh) &&
0392 (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) {
0393
0394 if (dm_digtable->dig_ext_port_stage ==
0395 DIG_EXT_PORT_STAGE_2) {
0396 dm_digtable->cur_igvalue = 0x20;
0397 rtl92c_dm_write_dig(hw);
0398 }
0399
0400 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1;
0401 } else if (rssi_strength > dm_digtable->rssi_highthresh) {
0402 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2;
0403 rtl92c_dm_ctrl_initgain_by_fa(hw);
0404 }
0405 } else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) {
0406 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
0407 dm_digtable->cur_igvalue = 0x20;
0408 rtl92c_dm_write_dig(hw);
0409 }
0410
0411 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0412 "curmultista_cstate = %x dig_ext_port_stage %x\n",
0413 dm_digtable->curmultista_cstate,
0414 dm_digtable->dig_ext_port_stage);
0415 }
0416
0417 static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
0418 {
0419 struct rtl_priv *rtlpriv = rtl_priv(hw);
0420 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0421
0422 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0423 "presta_cstate = %x, cursta_cstate = %x\n",
0424 dm_digtable->presta_cstate, dm_digtable->cursta_cstate);
0425 if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate ||
0426 dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT ||
0427 dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
0428 if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {
0429 dm_digtable->rssi_val_min =
0430 rtl92c_dm_initial_gain_min_pwdb(hw);
0431 if (dm_digtable->rssi_val_min > 100)
0432 dm_digtable->rssi_val_min = 100;
0433 rtl92c_dm_ctrl_initgain_by_rssi(hw);
0434 }
0435 } else {
0436 dm_digtable->rssi_val_min = 0;
0437 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
0438 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
0439 dm_digtable->cur_igvalue = 0x20;
0440 dm_digtable->pre_igvalue = 0;
0441 rtl92c_dm_write_dig(hw);
0442 }
0443 }
0444
0445 static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
0446 {
0447 struct rtl_priv *rtlpriv = rtl_priv(hw);
0448 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0449
0450 if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
0451 dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw);
0452 if (dm_digtable->rssi_val_min > 100)
0453 dm_digtable->rssi_val_min = 100;
0454
0455 if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
0456 if (dm_digtable->rssi_val_min <= 25)
0457 dm_digtable->cur_cck_pd_state =
0458 CCK_PD_STAGE_LOWRSSI;
0459 else
0460 dm_digtable->cur_cck_pd_state =
0461 CCK_PD_STAGE_HIGHRSSI;
0462 } else {
0463 if (dm_digtable->rssi_val_min <= 20)
0464 dm_digtable->cur_cck_pd_state =
0465 CCK_PD_STAGE_LOWRSSI;
0466 else
0467 dm_digtable->cur_cck_pd_state =
0468 CCK_PD_STAGE_HIGHRSSI;
0469 }
0470 } else {
0471 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
0472 }
0473
0474 if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) {
0475 if ((dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) ||
0476 (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_MAX))
0477 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83);
0478 else
0479 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
0480
0481 dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state;
0482 }
0483 }
0484
0485 static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
0486 {
0487 struct rtl_priv *rtlpriv = rtl_priv(hw);
0488 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0489 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0490
0491 if (mac->act_scanning)
0492 return;
0493
0494 if (mac->link_state >= MAC80211_LINKED)
0495 dm_digtable->cursta_cstate = DIG_STA_CONNECT;
0496 else
0497 dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
0498
0499 dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
0500
0501 rtl92c_dm_initial_gain_sta(hw);
0502 rtl92c_dm_initial_gain_multi_sta(hw);
0503 rtl92c_dm_cck_packet_detection_thresh(hw);
0504
0505 dm_digtable->presta_cstate = dm_digtable->cursta_cstate;
0506 }
0507
0508 static void rtl92c_dm_dig(struct ieee80211_hw *hw)
0509 {
0510 struct rtl_priv *rtlpriv = rtl_priv(hw);
0511
0512 if (!rtlpriv->dm.dm_initialgain_enable)
0513 return;
0514 if (!(rtlpriv->dm.dm_flag & DYNAMIC_FUNC_DIG))
0515 return;
0516
0517 rtl92c_dm_ctrl_initgain_by_twoport(hw);
0518 }
0519
0520 static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
0521 {
0522 struct rtl_priv *rtlpriv = rtl_priv(hw);
0523
0524 if (rtlpriv->rtlhal.interface == INTF_USB &&
0525 rtlpriv->rtlhal.board_type & 0x1) {
0526 dm_savepowerindex(hw);
0527 rtlpriv->dm.dynamic_txpower_enable = true;
0528 } else {
0529 rtlpriv->dm.dynamic_txpower_enable = false;
0530 }
0531 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
0532 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
0533 }
0534
0535 void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
0536 {
0537 struct rtl_priv *rtlpriv = rtl_priv(hw);
0538 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0539
0540 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
0541 "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n",
0542 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
0543 dm_digtable->back_val);
0544
0545 if (rtlpriv->rtlhal.interface == INTF_USB &&
0546 !dm_digtable->dig_enable_flag) {
0547 dm_digtable->pre_igvalue = 0x17;
0548 return;
0549 }
0550 dm_digtable->cur_igvalue -= 1;
0551 if (dm_digtable->cur_igvalue < DM_DIG_MIN)
0552 dm_digtable->cur_igvalue = DM_DIG_MIN;
0553
0554 if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) {
0555 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
0556 dm_digtable->cur_igvalue);
0557 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
0558 dm_digtable->cur_igvalue);
0559
0560 dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
0561 }
0562 rtl_dbg(rtlpriv, COMP_DIG, DBG_WARNING,
0563 "dig values 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
0564 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
0565 dm_digtable->rssi_val_min, dm_digtable->back_val,
0566 dm_digtable->rx_gain_max, dm_digtable->rx_gain_min,
0567 dm_digtable->large_fa_hit, dm_digtable->forbidden_igi);
0568 }
0569 EXPORT_SYMBOL(rtl92c_dm_write_dig);
0570
0571 static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw)
0572 {
0573 struct rtl_priv *rtlpriv = rtl_priv(hw);
0574 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0575 long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff;
0576
0577 if (mac->link_state != MAC80211_LINKED)
0578 return;
0579
0580 if (mac->opmode == NL80211_IFTYPE_ADHOC ||
0581 mac->opmode == NL80211_IFTYPE_AP) {
0582
0583 }
0584
0585 if (tmpentry_max_pwdb != 0)
0586 rtlpriv->dm.entry_max_undec_sm_pwdb = tmpentry_max_pwdb;
0587 else
0588 rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
0589
0590 if (tmpentry_min_pwdb != 0xff)
0591 rtlpriv->dm.entry_min_undec_sm_pwdb = tmpentry_min_pwdb;
0592 else
0593 rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603 }
0604
0605 void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw)
0606 {
0607 struct rtl_priv *rtlpriv = rtl_priv(hw);
0608
0609 rtlpriv->dm.current_turbo_edca = false;
0610 rtlpriv->dm.is_any_nonbepkts = false;
0611 rtlpriv->dm.is_cur_rdlstate = false;
0612 }
0613 EXPORT_SYMBOL(rtl92c_dm_init_edca_turbo);
0614
0615 static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)
0616 {
0617 struct rtl_priv *rtlpriv = rtl_priv(hw);
0618 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0619
0620 static u64 last_txok_cnt;
0621 static u64 last_rxok_cnt;
0622 static u32 last_bt_edca_ul;
0623 static u32 last_bt_edca_dl;
0624 u64 cur_txok_cnt = 0;
0625 u64 cur_rxok_cnt = 0;
0626 u32 edca_be_ul = 0x5ea42b;
0627 u32 edca_be_dl = 0x5ea42b;
0628 bool bt_change_edca = false;
0629
0630 if ((last_bt_edca_ul != rtlpriv->btcoexist.bt_edca_ul) ||
0631 (last_bt_edca_dl != rtlpriv->btcoexist.bt_edca_dl)) {
0632 rtlpriv->dm.current_turbo_edca = false;
0633 last_bt_edca_ul = rtlpriv->btcoexist.bt_edca_ul;
0634 last_bt_edca_dl = rtlpriv->btcoexist.bt_edca_dl;
0635 }
0636
0637 if (rtlpriv->btcoexist.bt_edca_ul != 0) {
0638 edca_be_ul = rtlpriv->btcoexist.bt_edca_ul;
0639 bt_change_edca = true;
0640 }
0641
0642 if (rtlpriv->btcoexist.bt_edca_dl != 0) {
0643 edca_be_ul = rtlpriv->btcoexist.bt_edca_dl;
0644 bt_change_edca = true;
0645 }
0646
0647 if (mac->link_state != MAC80211_LINKED) {
0648 rtlpriv->dm.current_turbo_edca = false;
0649 return;
0650 }
0651
0652 if ((!mac->ht_enable) && (!rtlpriv->btcoexist.bt_coexistence)) {
0653 if (!(edca_be_ul & 0xffff0000))
0654 edca_be_ul |= 0x005e0000;
0655
0656 if (!(edca_be_dl & 0xffff0000))
0657 edca_be_dl |= 0x005e0000;
0658 }
0659
0660 if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) &&
0661 (!rtlpriv->dm.disable_framebursting))) {
0662 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
0663 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
0664
0665 if (cur_rxok_cnt > 4 * cur_txok_cnt) {
0666 if (!rtlpriv->dm.is_cur_rdlstate ||
0667 !rtlpriv->dm.current_turbo_edca) {
0668 rtl_write_dword(rtlpriv,
0669 REG_EDCA_BE_PARAM,
0670 edca_be_dl);
0671 rtlpriv->dm.is_cur_rdlstate = true;
0672 }
0673 } else {
0674 if (rtlpriv->dm.is_cur_rdlstate ||
0675 !rtlpriv->dm.current_turbo_edca) {
0676 rtl_write_dword(rtlpriv,
0677 REG_EDCA_BE_PARAM,
0678 edca_be_ul);
0679 rtlpriv->dm.is_cur_rdlstate = false;
0680 }
0681 }
0682 rtlpriv->dm.current_turbo_edca = true;
0683 } else {
0684 if (rtlpriv->dm.current_turbo_edca) {
0685 u8 tmp = AC0_BE;
0686
0687 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
0688 &tmp);
0689 rtlpriv->dm.current_turbo_edca = false;
0690 }
0691 }
0692
0693 rtlpriv->dm.is_any_nonbepkts = false;
0694 last_txok_cnt = rtlpriv->stats.txbytesunicast;
0695 last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
0696 }
0697
0698 static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
0699 *hw)
0700 {
0701 struct rtl_priv *rtlpriv = rtl_priv(hw);
0702 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0703 struct rtl_phy *rtlphy = &(rtlpriv->phy);
0704 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
0705 u8 thermalvalue, delta, delta_lck, delta_iqk;
0706 long ele_a, ele_d, temp_cck, val_x, value32;
0707 long val_y, ele_c = 0;
0708 u8 ofdm_index[2], ofdm_index_old[2] = {0, 0}, cck_index_old = 0;
0709 s8 cck_index = 0;
0710 int i;
0711 bool is2t = IS_92C_SERIAL(rtlhal->version);
0712 s8 txpwr_level[3] = {0, 0, 0};
0713 u8 ofdm_min_index = 6, rf;
0714
0715 rtlpriv->dm.txpower_trackinginit = true;
0716 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0717 "%s\n", __func__);
0718
0719 thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
0720
0721 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0722 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
0723 thermalvalue, rtlpriv->dm.thermalvalue,
0724 rtlefuse->eeprom_thermalmeter);
0725
0726 rtl92c_phy_ap_calibrate(hw, (thermalvalue -
0727 rtlefuse->eeprom_thermalmeter));
0728 if (is2t)
0729 rf = 2;
0730 else
0731 rf = 1;
0732
0733 if (thermalvalue) {
0734 ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
0735 MASKDWORD) & MASKOFDM_D;
0736
0737 for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
0738 if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
0739 ofdm_index_old[0] = (u8) i;
0740
0741 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0742 "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n",
0743 ROFDM0_XATXIQIMBALANCE,
0744 ele_d, ofdm_index_old[0]);
0745 break;
0746 }
0747 }
0748
0749 if (is2t) {
0750 ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
0751 MASKDWORD) & MASKOFDM_D;
0752
0753 for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
0754 if (ele_d == (ofdmswing_table[i] &
0755 MASKOFDM_D)) {
0756 ofdm_index_old[1] = (u8) i;
0757 rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
0758 DBG_LOUD,
0759 "Initial pathB ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n",
0760 ROFDM0_XBTXIQIMBALANCE, ele_d,
0761 ofdm_index_old[1]);
0762 break;
0763 }
0764 }
0765 }
0766
0767 temp_cck =
0768 rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK;
0769
0770 for (i = 0; i < CCK_TABLE_LENGTH; i++) {
0771 if (rtlpriv->dm.cck_inch14) {
0772 if (memcmp((void *)&temp_cck,
0773 (void *)&cckswing_table_ch14[i][2],
0774 4) == 0) {
0775 cck_index_old = (u8) i;
0776
0777 rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
0778 DBG_LOUD,
0779 "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch 14 %d\n",
0780 RCCK0_TXFILTER2, temp_cck,
0781 cck_index_old,
0782 rtlpriv->dm.cck_inch14);
0783 break;
0784 }
0785 } else {
0786 if (memcmp((void *)&temp_cck,
0787 (void *)
0788 &cckswing_table_ch1ch13[i][2],
0789 4) == 0) {
0790 cck_index_old = (u8) i;
0791
0792 rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
0793 DBG_LOUD,
0794 "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch14 %d\n",
0795 RCCK0_TXFILTER2, temp_cck,
0796 cck_index_old,
0797 rtlpriv->dm.cck_inch14);
0798 break;
0799 }
0800 }
0801 }
0802
0803 if (!rtlpriv->dm.thermalvalue) {
0804 rtlpriv->dm.thermalvalue =
0805 rtlefuse->eeprom_thermalmeter;
0806 rtlpriv->dm.thermalvalue_lck = thermalvalue;
0807 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
0808 for (i = 0; i < rf; i++)
0809 rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
0810 rtlpriv->dm.cck_index = cck_index_old;
0811 }
0812
0813
0814 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
0815 (thermalvalue - rtlpriv->dm.thermalvalue) :
0816 (rtlpriv->dm.thermalvalue - thermalvalue);
0817
0818 delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
0819 (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
0820 (rtlpriv->dm.thermalvalue_lck - thermalvalue);
0821
0822 delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
0823 (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
0824 (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
0825
0826 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0827 "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",
0828 thermalvalue, rtlpriv->dm.thermalvalue,
0829 rtlefuse->eeprom_thermalmeter, delta, delta_lck,
0830 delta_iqk);
0831
0832 if (delta_lck > 1) {
0833 rtlpriv->dm.thermalvalue_lck = thermalvalue;
0834 rtl92c_phy_lc_calibrate(hw);
0835 }
0836
0837 if (delta > 0 && rtlpriv->dm.txpower_track_control) {
0838 if (thermalvalue > rtlpriv->dm.thermalvalue) {
0839 for (i = 0; i < rf; i++)
0840 rtlpriv->dm.ofdm_index[i] -= delta;
0841 rtlpriv->dm.cck_index -= delta;
0842 } else {
0843 for (i = 0; i < rf; i++)
0844 rtlpriv->dm.ofdm_index[i] += delta;
0845 rtlpriv->dm.cck_index += delta;
0846 }
0847
0848 if (is2t) {
0849 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0850 "temp OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n",
0851 rtlpriv->dm.ofdm_index[0],
0852 rtlpriv->dm.ofdm_index[1],
0853 rtlpriv->dm.cck_index);
0854 } else {
0855 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0856 "temp OFDM_A_index=0x%x, cck_index=0x%x\n",
0857 rtlpriv->dm.ofdm_index[0],
0858 rtlpriv->dm.cck_index);
0859 }
0860
0861 if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
0862 for (i = 0; i < rf; i++)
0863 ofdm_index[i] =
0864 rtlpriv->dm.ofdm_index[i]
0865 + 1;
0866 cck_index = rtlpriv->dm.cck_index + 1;
0867 } else {
0868 for (i = 0; i < rf; i++)
0869 ofdm_index[i] =
0870 rtlpriv->dm.ofdm_index[i];
0871 cck_index = rtlpriv->dm.cck_index;
0872 }
0873
0874 for (i = 0; i < rf; i++) {
0875 if (txpwr_level[i] >= 0 &&
0876 txpwr_level[i] <= 26) {
0877 if (thermalvalue >
0878 rtlefuse->eeprom_thermalmeter) {
0879 if (delta < 5)
0880 ofdm_index[i] -= 1;
0881
0882 else
0883 ofdm_index[i] -= 2;
0884 } else if (delta > 5 && thermalvalue <
0885 rtlefuse->
0886 eeprom_thermalmeter) {
0887 ofdm_index[i] += 1;
0888 }
0889 } else if (txpwr_level[i] >= 27 &&
0890 txpwr_level[i] <= 32
0891 && thermalvalue >
0892 rtlefuse->eeprom_thermalmeter) {
0893 if (delta < 5)
0894 ofdm_index[i] -= 1;
0895
0896 else
0897 ofdm_index[i] -= 2;
0898 } else if (txpwr_level[i] >= 32 &&
0899 txpwr_level[i] <= 38 &&
0900 thermalvalue >
0901 rtlefuse->eeprom_thermalmeter
0902 && delta > 5) {
0903 ofdm_index[i] -= 1;
0904 }
0905 }
0906
0907 if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) {
0908 if (thermalvalue >
0909 rtlefuse->eeprom_thermalmeter) {
0910 if (delta < 5)
0911 cck_index -= 1;
0912
0913 else
0914 cck_index -= 2;
0915 } else if (delta > 5 && thermalvalue <
0916 rtlefuse->eeprom_thermalmeter) {
0917 cck_index += 1;
0918 }
0919 } else if (txpwr_level[i] >= 27 &&
0920 txpwr_level[i] <= 32 &&
0921 thermalvalue >
0922 rtlefuse->eeprom_thermalmeter) {
0923 if (delta < 5)
0924 cck_index -= 1;
0925
0926 else
0927 cck_index -= 2;
0928 } else if (txpwr_level[i] >= 32 &&
0929 txpwr_level[i] <= 38 &&
0930 thermalvalue > rtlefuse->eeprom_thermalmeter
0931 && delta > 5) {
0932 cck_index -= 1;
0933 }
0934
0935 for (i = 0; i < rf; i++) {
0936 if (ofdm_index[i] > OFDM_TABLE_SIZE - 1)
0937 ofdm_index[i] = OFDM_TABLE_SIZE - 1;
0938
0939 else if (ofdm_index[i] < ofdm_min_index)
0940 ofdm_index[i] = ofdm_min_index;
0941 }
0942
0943 if (cck_index > CCK_TABLE_SIZE - 1)
0944 cck_index = CCK_TABLE_SIZE - 1;
0945 else if (cck_index < 0)
0946 cck_index = 0;
0947
0948 if (is2t) {
0949 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0950 "new OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n",
0951 ofdm_index[0], ofdm_index[1],
0952 cck_index);
0953 } else {
0954 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0955 "new OFDM_A_index=0x%x, cck_index=0x%x\n",
0956 ofdm_index[0], cck_index);
0957 }
0958 }
0959
0960 if (rtlpriv->dm.txpower_track_control && delta != 0) {
0961 ele_d =
0962 (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22;
0963 val_x = rtlphy->reg_e94;
0964 val_y = rtlphy->reg_e9c;
0965
0966 if (val_x != 0) {
0967 if ((val_x & 0x00000200) != 0)
0968 val_x = val_x | 0xFFFFFC00;
0969 ele_a = ((val_x * ele_d) >> 8) & 0x000003FF;
0970
0971 if ((val_y & 0x00000200) != 0)
0972 val_y = val_y | 0xFFFFFC00;
0973 ele_c = ((val_y * ele_d) >> 8) & 0x000003FF;
0974
0975 value32 = (ele_d << 22) |
0976 ((ele_c & 0x3F) << 16) | ele_a;
0977
0978 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
0979 MASKDWORD, value32);
0980
0981 value32 = (ele_c & 0x000003C0) >> 6;
0982 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
0983 value32);
0984
0985 value32 = ((val_x * ele_d) >> 7) & 0x01;
0986 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
0987 BIT(31), value32);
0988
0989 value32 = ((val_y * ele_d) >> 7) & 0x01;
0990 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
0991 BIT(29), value32);
0992 } else {
0993 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
0994 MASKDWORD,
0995 ofdmswing_table[ofdm_index[0]]);
0996
0997 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
0998 0x00);
0999 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1000 BIT(31) | BIT(29), 0x00);
1001 }
1002
1003 if (!rtlpriv->dm.cck_inch14) {
1004 rtl_write_byte(rtlpriv, 0xa22,
1005 cckswing_table_ch1ch13[cck_index]
1006 [0]);
1007 rtl_write_byte(rtlpriv, 0xa23,
1008 cckswing_table_ch1ch13[cck_index]
1009 [1]);
1010 rtl_write_byte(rtlpriv, 0xa24,
1011 cckswing_table_ch1ch13[cck_index]
1012 [2]);
1013 rtl_write_byte(rtlpriv, 0xa25,
1014 cckswing_table_ch1ch13[cck_index]
1015 [3]);
1016 rtl_write_byte(rtlpriv, 0xa26,
1017 cckswing_table_ch1ch13[cck_index]
1018 [4]);
1019 rtl_write_byte(rtlpriv, 0xa27,
1020 cckswing_table_ch1ch13[cck_index]
1021 [5]);
1022 rtl_write_byte(rtlpriv, 0xa28,
1023 cckswing_table_ch1ch13[cck_index]
1024 [6]);
1025 rtl_write_byte(rtlpriv, 0xa29,
1026 cckswing_table_ch1ch13[cck_index]
1027 [7]);
1028 } else {
1029 rtl_write_byte(rtlpriv, 0xa22,
1030 cckswing_table_ch14[cck_index]
1031 [0]);
1032 rtl_write_byte(rtlpriv, 0xa23,
1033 cckswing_table_ch14[cck_index]
1034 [1]);
1035 rtl_write_byte(rtlpriv, 0xa24,
1036 cckswing_table_ch14[cck_index]
1037 [2]);
1038 rtl_write_byte(rtlpriv, 0xa25,
1039 cckswing_table_ch14[cck_index]
1040 [3]);
1041 rtl_write_byte(rtlpriv, 0xa26,
1042 cckswing_table_ch14[cck_index]
1043 [4]);
1044 rtl_write_byte(rtlpriv, 0xa27,
1045 cckswing_table_ch14[cck_index]
1046 [5]);
1047 rtl_write_byte(rtlpriv, 0xa28,
1048 cckswing_table_ch14[cck_index]
1049 [6]);
1050 rtl_write_byte(rtlpriv, 0xa29,
1051 cckswing_table_ch14[cck_index]
1052 [7]);
1053 }
1054
1055 if (is2t) {
1056 ele_d = (ofdmswing_table[ofdm_index[1]] &
1057 0xFFC00000) >> 22;
1058
1059 val_x = rtlphy->reg_eb4;
1060 val_y = rtlphy->reg_ebc;
1061
1062 if (val_x != 0) {
1063 if ((val_x & 0x00000200) != 0)
1064 val_x = val_x | 0xFFFFFC00;
1065 ele_a = ((val_x * ele_d) >> 8) &
1066 0x000003FF;
1067
1068 if ((val_y & 0x00000200) != 0)
1069 val_y = val_y | 0xFFFFFC00;
1070 ele_c = ((val_y * ele_d) >> 8) &
1071 0x00003FF;
1072
1073 value32 = (ele_d << 22) |
1074 ((ele_c & 0x3F) << 16) | ele_a;
1075 rtl_set_bbreg(hw,
1076 ROFDM0_XBTXIQIMBALANCE,
1077 MASKDWORD, value32);
1078
1079 value32 = (ele_c & 0x000003C0) >> 6;
1080 rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
1081 MASKH4BITS, value32);
1082
1083 value32 = ((val_x * ele_d) >> 7) & 0x01;
1084 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1085 BIT(27), value32);
1086
1087 value32 = ((val_y * ele_d) >> 7) & 0x01;
1088 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1089 BIT(25), value32);
1090 } else {
1091 rtl_set_bbreg(hw,
1092 ROFDM0_XBTXIQIMBALANCE,
1093 MASKDWORD,
1094 ofdmswing_table[ofdm_index
1095 [1]]);
1096 rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
1097 MASKH4BITS, 0x00);
1098 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1099 BIT(27) | BIT(25), 0x00);
1100 }
1101
1102 }
1103 }
1104
1105 if (delta_iqk > 3) {
1106 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
1107 rtl92c_phy_iq_calibrate(hw, false);
1108 }
1109
1110 if (rtlpriv->dm.txpower_track_control)
1111 rtlpriv->dm.thermalvalue = thermalvalue;
1112 }
1113
1114 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n");
1115
1116 }
1117
1118 static void rtl92c_dm_initialize_txpower_tracking_thermalmeter(
1119 struct ieee80211_hw *hw)
1120 {
1121 struct rtl_priv *rtlpriv = rtl_priv(hw);
1122
1123 rtlpriv->dm.txpower_tracking = true;
1124 rtlpriv->dm.txpower_trackinginit = false;
1125
1126 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1127 "pMgntInfo->txpower_tracking = %d\n",
1128 rtlpriv->dm.txpower_tracking);
1129 }
1130
1131 static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
1132 {
1133 rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw);
1134 }
1135
1136 static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw)
1137 {
1138 rtl92c_dm_txpower_tracking_callback_thermalmeter(hw);
1139 }
1140
1141 static void rtl92c_dm_check_txpower_tracking_thermal_meter(
1142 struct ieee80211_hw *hw)
1143 {
1144 struct rtl_priv *rtlpriv = rtl_priv(hw);
1145
1146 if (!rtlpriv->dm.txpower_tracking)
1147 return;
1148
1149 if (!rtlpriv->dm.tm_trigger) {
1150 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK,
1151 0x60);
1152 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1153 "Trigger 92S Thermal Meter!!\n");
1154 rtlpriv->dm.tm_trigger = 1;
1155 return;
1156 } else {
1157 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1158 "Schedule TxPowerTracking direct call!!\n");
1159 rtl92c_dm_txpower_tracking_directcall(hw);
1160 rtlpriv->dm.tm_trigger = 0;
1161 }
1162 }
1163
1164 void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw)
1165 {
1166 rtl92c_dm_check_txpower_tracking_thermal_meter(hw);
1167 }
1168 EXPORT_SYMBOL(rtl92c_dm_check_txpower_tracking);
1169
1170 void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
1171 {
1172 struct rtl_priv *rtlpriv = rtl_priv(hw);
1173 struct rate_adaptive *p_ra = &(rtlpriv->ra);
1174
1175 p_ra->ratr_state = DM_RATR_STA_INIT;
1176 p_ra->pre_ratr_state = DM_RATR_STA_INIT;
1177
1178 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
1179 rtlpriv->dm.useramask = true;
1180 else
1181 rtlpriv->dm.useramask = false;
1182
1183 }
1184 EXPORT_SYMBOL(rtl92c_dm_init_rate_adaptive_mask);
1185
1186 static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1187 {
1188 struct rtl_priv *rtlpriv = rtl_priv(hw);
1189 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
1190
1191 dm_pstable->pre_ccastate = CCA_MAX;
1192 dm_pstable->cur_ccasate = CCA_MAX;
1193 dm_pstable->pre_rfstate = RF_MAX;
1194 dm_pstable->cur_rfstate = RF_MAX;
1195 dm_pstable->rssi_val_min = 0;
1196 }
1197
1198 void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
1199 {
1200 struct rtl_priv *rtlpriv = rtl_priv(hw);
1201 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
1202
1203 if (!rtlpriv->reg_init) {
1204 rtlpriv->reg_874 = (rtl_get_bbreg(hw,
1205 RFPGA0_XCD_RFINTERFACESW,
1206 MASKDWORD) & 0x1CC000) >> 14;
1207
1208 rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
1209 MASKDWORD) & BIT(3)) >> 3;
1210
1211 rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
1212 MASKDWORD) & 0xFF000000) >> 24;
1213
1214 rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) &
1215 0xF000) >> 12;
1216
1217 rtlpriv->reg_init = true;
1218 }
1219
1220 if (!bforce_in_normal) {
1221 if (dm_pstable->rssi_val_min != 0) {
1222 if (dm_pstable->pre_rfstate == RF_NORMAL) {
1223 if (dm_pstable->rssi_val_min >= 30)
1224 dm_pstable->cur_rfstate = RF_SAVE;
1225 else
1226 dm_pstable->cur_rfstate = RF_NORMAL;
1227 } else {
1228 if (dm_pstable->rssi_val_min <= 25)
1229 dm_pstable->cur_rfstate = RF_NORMAL;
1230 else
1231 dm_pstable->cur_rfstate = RF_SAVE;
1232 }
1233 } else {
1234 dm_pstable->cur_rfstate = RF_MAX;
1235 }
1236 } else {
1237 dm_pstable->cur_rfstate = RF_NORMAL;
1238 }
1239
1240 if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) {
1241 if (dm_pstable->cur_rfstate == RF_SAVE) {
1242 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1243 0x1C0000, 0x2);
1244 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0);
1245 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
1246 0xFF000000, 0x63);
1247 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1248 0xC000, 0x2);
1249 rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3);
1250 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
1251 rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
1252 } else {
1253 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1254 0x1CC000, rtlpriv->reg_874);
1255 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
1256 rtlpriv->reg_c70);
1257 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
1258 rtlpriv->reg_85c);
1259 rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74);
1260 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
1261 }
1262
1263 dm_pstable->pre_rfstate = dm_pstable->cur_rfstate;
1264 }
1265 }
1266 EXPORT_SYMBOL(rtl92c_dm_rf_saving);
1267
1268 static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1269 {
1270 struct rtl_priv *rtlpriv = rtl_priv(hw);
1271 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
1272 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1273 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1274
1275
1276 if (((mac->link_state == MAC80211_NOLINK)) &&
1277 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
1278 dm_pstable->rssi_val_min = 0;
1279 rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD, "Not connected to any\n");
1280 }
1281
1282 if (mac->link_state == MAC80211_LINKED) {
1283 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
1284 dm_pstable->rssi_val_min =
1285 rtlpriv->dm.entry_min_undec_sm_pwdb;
1286 rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD,
1287 "AP Client PWDB = 0x%lx\n",
1288 dm_pstable->rssi_val_min);
1289 } else {
1290 dm_pstable->rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
1291 rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD,
1292 "STA Default Port PWDB = 0x%lx\n",
1293 dm_pstable->rssi_val_min);
1294 }
1295 } else {
1296 dm_pstable->rssi_val_min =
1297 rtlpriv->dm.entry_min_undec_sm_pwdb;
1298
1299 rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD,
1300 "AP Ext Port PWDB = 0x%lx\n",
1301 dm_pstable->rssi_val_min);
1302 }
1303
1304
1305 if (IS_92C_SERIAL(rtlhal->version))
1306 ;
1307 else
1308 rtl92c_dm_rf_saving(hw, false);
1309 }
1310
1311 void rtl92c_dm_init(struct ieee80211_hw *hw)
1312 {
1313 struct rtl_priv *rtlpriv = rtl_priv(hw);
1314
1315 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1316 rtlpriv->dm.dm_flag = DYNAMIC_FUNC_DISABLE | DYNAMIC_FUNC_DIG;
1317 rtlpriv->dm.undec_sm_pwdb = -1;
1318 rtlpriv->dm.undec_sm_cck = -1;
1319 rtlpriv->dm.dm_initialgain_enable = true;
1320 rtl_dm_diginit(hw, 0x20);
1321
1322 rtlpriv->dm.dm_flag |= HAL_DM_HIPWR_DISABLE;
1323 rtl92c_dm_init_dynamic_txpower(hw);
1324
1325 rtl92c_dm_init_edca_turbo(hw);
1326 rtl92c_dm_init_rate_adaptive_mask(hw);
1327 rtlpriv->dm.dm_flag |= DYNAMIC_FUNC_SS;
1328 rtl92c_dm_initialize_txpower_tracking(hw);
1329 rtl92c_dm_init_dynamic_bb_powersaving(hw);
1330
1331 rtlpriv->dm.ofdm_pkt_cnt = 0;
1332 rtlpriv->dm.dm_rssi_sel = RSSI_DEFAULT;
1333 }
1334 EXPORT_SYMBOL(rtl92c_dm_init);
1335
1336 void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
1337 {
1338 struct rtl_priv *rtlpriv = rtl_priv(hw);
1339 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1340 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1341 long undec_sm_pwdb;
1342
1343 if (!rtlpriv->dm.dynamic_txpower_enable)
1344 return;
1345
1346 if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
1347 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
1348 return;
1349 }
1350
1351 if ((mac->link_state < MAC80211_LINKED) &&
1352 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
1353 rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,
1354 "Not connected to any\n");
1355
1356 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
1357
1358 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
1359 return;
1360 }
1361
1362 if (mac->link_state >= MAC80211_LINKED) {
1363 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
1364 undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
1365 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
1366 "AP Client PWDB = 0x%lx\n",
1367 undec_sm_pwdb);
1368 } else {
1369 undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
1370 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
1371 "STA Default Port PWDB = 0x%lx\n",
1372 undec_sm_pwdb);
1373 }
1374 } else {
1375 undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
1376
1377 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
1378 "AP Ext Port PWDB = 0x%lx\n",
1379 undec_sm_pwdb);
1380 }
1381
1382 if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
1383 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2;
1384 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
1385 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
1386 } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
1387 (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
1388
1389 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
1390 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
1391 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
1392 } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
1393 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
1394 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
1395 "TXHIGHPWRLEVEL_NORMAL\n");
1396 }
1397
1398 if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
1399 rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
1400 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
1401 rtlphy->current_channel);
1402 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
1403 if (rtlpriv->dm.dynamic_txhighpower_lvl ==
1404 TXHIGHPWRLEVEL_NORMAL)
1405 dm_restorepowerindex(hw);
1406 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
1407 TXHIGHPWRLEVEL_LEVEL1)
1408 dm_writepowerindex(hw, 0x14);
1409 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
1410 TXHIGHPWRLEVEL_LEVEL2)
1411 dm_writepowerindex(hw, 0x10);
1412 }
1413 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
1414 }
1415
1416 void rtl92c_dm_watchdog(struct ieee80211_hw *hw)
1417 {
1418 struct rtl_priv *rtlpriv = rtl_priv(hw);
1419 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1420 bool fw_current_inpsmode = false;
1421 bool fw_ps_awake = true;
1422
1423 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1424 (u8 *) (&fw_current_inpsmode));
1425 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1426 (u8 *) (&fw_ps_awake));
1427
1428 if (ppsc->p2p_ps_info.p2p_ps_mode)
1429 fw_ps_awake = false;
1430
1431 if ((ppsc->rfpwr_state == ERFON) && ((!fw_current_inpsmode) &&
1432 fw_ps_awake)
1433 && (!ppsc->rfchange_inprogress)) {
1434 rtl92c_dm_pwdb_monitor(hw);
1435 rtl92c_dm_dig(hw);
1436 rtl92c_dm_false_alarm_counter_statistics(hw);
1437 rtl92c_dm_dynamic_bb_powersaving(hw);
1438 rtl92c_dm_dynamic_txpower(hw);
1439 rtl92c_dm_check_txpower_tracking(hw);
1440
1441 rtl92c_dm_bt_coexist(hw);
1442 rtl92c_dm_check_edca_turbo(hw);
1443 }
1444 }
1445 EXPORT_SYMBOL(rtl92c_dm_watchdog);
1446
1447 u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw)
1448 {
1449 struct rtl_priv *rtlpriv = rtl_priv(hw);
1450 long undec_sm_pwdb;
1451 u8 curr_bt_rssi_state = 0x00;
1452
1453 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1454 undec_sm_pwdb = GET_UNDECORATED_AVERAGE_RSSI(rtlpriv);
1455 } else {
1456 if (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)
1457 undec_sm_pwdb = 100;
1458 else
1459 undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
1460 }
1461
1462
1463
1464 if (undec_sm_pwdb >= 67)
1465 curr_bt_rssi_state &= (~BT_RSSI_STATE_NORMAL_POWER);
1466 else if (undec_sm_pwdb < 62)
1467 curr_bt_rssi_state |= BT_RSSI_STATE_NORMAL_POWER;
1468
1469
1470 if (undec_sm_pwdb >= 40)
1471 curr_bt_rssi_state &= (~BT_RSSI_STATE_AMDPU_OFF);
1472 else if (undec_sm_pwdb <= 32)
1473 curr_bt_rssi_state |= BT_RSSI_STATE_AMDPU_OFF;
1474
1475
1476
1477 if (undec_sm_pwdb < 35)
1478 curr_bt_rssi_state |= BT_RSSI_STATE_SPECIAL_LOW;
1479 else
1480 curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW);
1481
1482
1483 if (undec_sm_pwdb < 15)
1484 curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW;
1485 else
1486 curr_bt_rssi_state &= (~BT_RSSI_STATE_BG_EDCA_LOW);
1487
1488 if (curr_bt_rssi_state != rtlpriv->btcoexist.bt_rssi_state) {
1489 rtlpriv->btcoexist.bt_rssi_state = curr_bt_rssi_state;
1490 return true;
1491 } else {
1492 return false;
1493 }
1494 }
1495 EXPORT_SYMBOL(rtl92c_bt_rssi_state_change);
1496
1497 static bool rtl92c_bt_state_change(struct ieee80211_hw *hw)
1498 {
1499 struct rtl_priv *rtlpriv = rtl_priv(hw);
1500
1501 u32 polling, ratio_tx, ratio_pri;
1502 u32 bt_tx, bt_pri;
1503 u8 bt_state;
1504 u8 cur_service_type;
1505
1506 if (rtlpriv->mac80211.link_state < MAC80211_LINKED)
1507 return false;
1508
1509 bt_state = rtl_read_byte(rtlpriv, 0x4fd);
1510 bt_tx = rtl_read_dword(rtlpriv, 0x488) & BT_MASK;
1511 bt_pri = rtl_read_dword(rtlpriv, 0x48c) & BT_MASK;
1512 polling = rtl_read_dword(rtlpriv, 0x490);
1513
1514 if (bt_tx == BT_MASK && bt_pri == BT_MASK &&
1515 polling == 0xffffffff && bt_state == 0xff)
1516 return false;
1517
1518 bt_state &= BIT(0);
1519 if (bt_state != rtlpriv->btcoexist.bt_cur_state) {
1520 rtlpriv->btcoexist.bt_cur_state = bt_state;
1521
1522 if (rtlpriv->btcoexist.reg_bt_sco == 3) {
1523 rtlpriv->btcoexist.bt_service = BT_IDLE;
1524
1525 bt_state = bt_state |
1526 ((rtlpriv->btcoexist.bt_ant_isolation == 1) ?
1527 0 : BIT(1)) | BIT(2);
1528 rtl_write_byte(rtlpriv, 0x4fd, bt_state);
1529 }
1530 return true;
1531 }
1532
1533 ratio_tx = bt_tx * 1000 / polling;
1534 ratio_pri = bt_pri * 1000 / polling;
1535 rtlpriv->btcoexist.ratio_tx = ratio_tx;
1536 rtlpriv->btcoexist.ratio_pri = ratio_pri;
1537
1538 if (bt_state && rtlpriv->btcoexist.reg_bt_sco == 3) {
1539
1540 if ((ratio_tx < 30) && (ratio_pri < 30))
1541 cur_service_type = BT_IDLE;
1542 else if ((ratio_pri > 110) && (ratio_pri < 250))
1543 cur_service_type = BT_SCO;
1544 else if ((ratio_tx >= 200) && (ratio_pri >= 200))
1545 cur_service_type = BT_BUSY;
1546 else if ((ratio_tx >= 350) && (ratio_tx < 500))
1547 cur_service_type = BT_OTHERBUSY;
1548 else if (ratio_tx >= 500)
1549 cur_service_type = BT_PAN;
1550 else
1551 cur_service_type = BT_OTHER_ACTION;
1552
1553 if (cur_service_type != rtlpriv->btcoexist.bt_service) {
1554 rtlpriv->btcoexist.bt_service = cur_service_type;
1555 bt_state = bt_state |
1556 ((rtlpriv->btcoexist.bt_ant_isolation == 1) ?
1557 0 : BIT(1)) |
1558 ((rtlpriv->btcoexist.bt_service != BT_IDLE) ?
1559 0 : BIT(2));
1560
1561
1562
1563 if (rtlpriv->btcoexist.bt_service != BT_IDLE) {
1564 rtl_write_word(rtlpriv, 0x504, 0x0ccc);
1565 rtl_write_byte(rtlpriv, 0x506, 0x54);
1566 rtl_write_byte(rtlpriv, 0x507, 0x54);
1567 } else {
1568 rtl_write_byte(rtlpriv, 0x506, 0x00);
1569 rtl_write_byte(rtlpriv, 0x507, 0x00);
1570 }
1571
1572 rtl_write_byte(rtlpriv, 0x4fd, bt_state);
1573 return true;
1574 }
1575 }
1576
1577 return false;
1578
1579 }
1580
1581 static bool rtl92c_bt_wifi_connect_change(struct ieee80211_hw *hw)
1582 {
1583 struct rtl_priv *rtlpriv = rtl_priv(hw);
1584 static bool media_connect;
1585
1586 if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1587 media_connect = false;
1588 } else {
1589 if (!media_connect) {
1590 media_connect = true;
1591 return true;
1592 }
1593 media_connect = true;
1594 }
1595
1596 return false;
1597 }
1598
1599 static void rtl92c_bt_set_normal(struct ieee80211_hw *hw)
1600 {
1601 struct rtl_priv *rtlpriv = rtl_priv(hw);
1602
1603 if (rtlpriv->btcoexist.bt_service == BT_OTHERBUSY) {
1604 rtlpriv->btcoexist.bt_edca_ul = 0x5ea72b;
1605 rtlpriv->btcoexist.bt_edca_dl = 0x5ea72b;
1606 } else if (rtlpriv->btcoexist.bt_service == BT_BUSY) {
1607 rtlpriv->btcoexist.bt_edca_ul = 0x5eb82f;
1608 rtlpriv->btcoexist.bt_edca_dl = 0x5eb82f;
1609 } else if (rtlpriv->btcoexist.bt_service == BT_SCO) {
1610 if (rtlpriv->btcoexist.ratio_tx > 160) {
1611 rtlpriv->btcoexist.bt_edca_ul = 0x5ea72f;
1612 rtlpriv->btcoexist.bt_edca_dl = 0x5ea72f;
1613 } else {
1614 rtlpriv->btcoexist.bt_edca_ul = 0x5ea32b;
1615 rtlpriv->btcoexist.bt_edca_dl = 0x5ea42b;
1616 }
1617 } else {
1618 rtlpriv->btcoexist.bt_edca_ul = 0;
1619 rtlpriv->btcoexist.bt_edca_dl = 0;
1620 }
1621
1622 if ((rtlpriv->btcoexist.bt_service != BT_IDLE) &&
1623 (rtlpriv->mac80211.mode == WIRELESS_MODE_G ||
1624 (rtlpriv->mac80211.mode == (WIRELESS_MODE_G | WIRELESS_MODE_B))) &&
1625 (rtlpriv->btcoexist.bt_rssi_state &
1626 BT_RSSI_STATE_BG_EDCA_LOW)) {
1627 rtlpriv->btcoexist.bt_edca_ul = 0x5eb82b;
1628 rtlpriv->btcoexist.bt_edca_dl = 0x5eb82b;
1629 }
1630 }
1631
1632 static void rtl92c_bt_ant_isolation(struct ieee80211_hw *hw, u8 tmp1byte)
1633 {
1634 struct rtl_priv *rtlpriv = rtl_priv(hw);
1635
1636
1637 if (rtlpriv->mac80211.vendor == PEER_CISCO &&
1638 rtlpriv->btcoexist.bt_service == BT_OTHER_ACTION) {
1639 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
1640 } else {
1641 if ((rtlpriv->btcoexist.bt_service == BT_BUSY) &&
1642 (rtlpriv->btcoexist.bt_rssi_state &
1643 BT_RSSI_STATE_NORMAL_POWER)) {
1644 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
1645 } else if ((rtlpriv->btcoexist.bt_service ==
1646 BT_OTHER_ACTION) && (rtlpriv->mac80211.mode <
1647 WIRELESS_MODE_N_24G) &&
1648 (rtlpriv->btcoexist.bt_rssi_state &
1649 BT_RSSI_STATE_SPECIAL_LOW)) {
1650 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
1651 } else {
1652 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, tmp1byte);
1653 }
1654 }
1655
1656 if (rtlpriv->btcoexist.bt_service == BT_PAN)
1657 rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x10100);
1658 else
1659 rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x0);
1660
1661 if (rtlpriv->btcoexist.bt_rssi_state &
1662 BT_RSSI_STATE_NORMAL_POWER) {
1663 rtl92c_bt_set_normal(hw);
1664 } else {
1665 rtlpriv->btcoexist.bt_edca_ul = 0;
1666 rtlpriv->btcoexist.bt_edca_dl = 0;
1667 }
1668
1669 if (rtlpriv->btcoexist.bt_service != BT_IDLE) {
1670 rtlpriv->cfg->ops->set_rfreg(hw,
1671 RF90_PATH_A,
1672 0x1e,
1673 0xf0, 0xf);
1674 } else {
1675 rtlpriv->cfg->ops->set_rfreg(hw,
1676 RF90_PATH_A, 0x1e, 0xf0,
1677 rtlpriv->btcoexist.bt_rfreg_origin_1e);
1678 }
1679
1680 if (!rtlpriv->dm.dynamic_txpower_enable) {
1681 if (rtlpriv->btcoexist.bt_service != BT_IDLE) {
1682 if (rtlpriv->btcoexist.bt_rssi_state &
1683 BT_RSSI_STATE_TXPOWER_LOW) {
1684 rtlpriv->dm.dynamic_txhighpower_lvl =
1685 TXHIGHPWRLEVEL_BT2;
1686 } else {
1687 rtlpriv->dm.dynamic_txhighpower_lvl =
1688 TXHIGHPWRLEVEL_BT1;
1689 }
1690 } else {
1691 rtlpriv->dm.dynamic_txhighpower_lvl =
1692 TXHIGHPWRLEVEL_NORMAL;
1693 }
1694 rtl92c_phy_set_txpower_level(hw,
1695 rtlpriv->phy.current_channel);
1696 }
1697 }
1698
1699 static void rtl92c_check_bt_change(struct ieee80211_hw *hw)
1700 {
1701 struct rtl_priv *rtlpriv = rtl_priv(hw);
1702 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1703 u8 tmp1byte = 0;
1704
1705 if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version) &&
1706 rtlpriv->btcoexist.bt_coexistence)
1707 tmp1byte |= BIT(5);
1708 if (rtlpriv->btcoexist.bt_cur_state) {
1709 if (rtlpriv->btcoexist.bt_ant_isolation)
1710 rtl92c_bt_ant_isolation(hw, tmp1byte);
1711 } else {
1712 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, tmp1byte);
1713 rtlpriv->cfg->ops->set_rfreg(hw, RF90_PATH_A, 0x1e, 0xf0,
1714 rtlpriv->btcoexist.bt_rfreg_origin_1e);
1715
1716 rtlpriv->btcoexist.bt_edca_ul = 0;
1717 rtlpriv->btcoexist.bt_edca_dl = 0;
1718 }
1719 }
1720
1721 void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw)
1722 {
1723 struct rtl_priv *rtlpriv = rtl_priv(hw);
1724 bool wifi_connect_change;
1725 bool bt_state_change;
1726 bool rssi_state_change;
1727
1728 if ((rtlpriv->btcoexist.bt_coexistence) &&
1729 (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4)) {
1730 wifi_connect_change = rtl92c_bt_wifi_connect_change(hw);
1731 bt_state_change = rtl92c_bt_state_change(hw);
1732 rssi_state_change = rtl92c_bt_rssi_state_change(hw);
1733
1734 if (wifi_connect_change || bt_state_change || rssi_state_change)
1735 rtl92c_check_bt_change(hw);
1736 }
1737 }
1738 EXPORT_SYMBOL(rtl92c_dm_bt_coexist);