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

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

DEFINITIONS

This source file includes following definitions.
  1. rtl88e_set_iqk_matrix
  2. rtl88e_dm_txpower_track_adjust
  3. dm_tx_pwr_track_set_pwr
  4. rtl88e_dm_initial_gain_min_pwdb
  5. rtl88e_dm_false_alarm_counter_statistics
  6. rtl88e_dm_cck_packet_detection_thresh
  7. rtl88e_dm_dig
  8. rtl88e_dm_init_dynamic_txpower
  9. rtl92c_dm_dynamic_txpower
  10. rtl88e_dm_write_dig
  11. rtl88e_dm_pwdb_monitor
  12. rtl88e_dm_init_edca_turbo
  13. rtl88e_dm_check_edca_turbo
  14. dm_txpower_track_cb_therm
  15. rtl88e_dm_init_txpower_tracking
  16. rtl88e_dm_check_txpower_tracking
  17. rtl88e_dm_init_rate_adaptive_mask
  18. rtl88e_dm_refresh_rate_adaptive_mask
  19. rtl92c_dm_init_dynamic_bb_powersaving
  20. rtl88e_dm_update_rx_idle_ant
  21. rtl88e_dm_update_tx_ant
  22. rtl88e_dm_rx_hw_antena_div_init
  23. rtl88e_dm_trx_hw_antenna_div_init
  24. rtl88e_dm_fast_training_init
  25. rtl88e_dm_antenna_div_init
  26. rtl88e_dm_set_tx_ant_by_tx_info
  27. rtl88e_dm_ant_sel_statistics
  28. rtl88e_dm_hw_ant_div
  29. rtl88e_set_next_mac_address_target
  30. rtl88e_dm_fast_ant_training
  31. rtl88e_dm_fast_antenna_training_callback
  32. rtl88e_dm_antenna_diversity
  33. rtl88e_dm_init
  34. rtl88e_dm_watchdog

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright(c) 2009-2013  Realtek Corporation.*/
   3 
   4 #include "../wifi.h"
   5 #include "../base.h"
   6 #include "../pci.h"
   7 #include "../core.h"
   8 #include "reg.h"
   9 #include "def.h"
  10 #include "phy.h"
  11 #include "dm.h"
  12 #include "fw.h"
  13 #include "trx.h"
  14 
  15 static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
  16         0x7f8001fe,             /* 0, +6.0dB */
  17         0x788001e2,             /* 1, +5.5dB */
  18         0x71c001c7,             /* 2, +5.0dB */
  19         0x6b8001ae,             /* 3, +4.5dB */
  20         0x65400195,             /* 4, +4.0dB */
  21         0x5fc0017f,             /* 5, +3.5dB */
  22         0x5a400169,             /* 6, +3.0dB */
  23         0x55400155,             /* 7, +2.5dB */
  24         0x50800142,             /* 8, +2.0dB */
  25         0x4c000130,             /* 9, +1.5dB */
  26         0x47c0011f,             /* 10, +1.0dB */
  27         0x43c0010f,             /* 11, +0.5dB */
  28         0x40000100,             /* 12, +0dB */
  29         0x3c8000f2,             /* 13, -0.5dB */
  30         0x390000e4,             /* 14, -1.0dB */
  31         0x35c000d7,             /* 15, -1.5dB */
  32         0x32c000cb,             /* 16, -2.0dB */
  33         0x300000c0,             /* 17, -2.5dB */
  34         0x2d4000b5,             /* 18, -3.0dB */
  35         0x2ac000ab,             /* 19, -3.5dB */
  36         0x288000a2,             /* 20, -4.0dB */
  37         0x26000098,             /* 21, -4.5dB */
  38         0x24000090,             /* 22, -5.0dB */
  39         0x22000088,             /* 23, -5.5dB */
  40         0x20000080,             /* 24, -6.0dB */
  41         0x1e400079,             /* 25, -6.5dB */
  42         0x1c800072,             /* 26, -7.0dB */
  43         0x1b00006c,             /* 27. -7.5dB */
  44         0x19800066,             /* 28, -8.0dB */
  45         0x18000060,             /* 29, -8.5dB */
  46         0x16c0005b,             /* 30, -9.0dB */
  47         0x15800056,             /* 31, -9.5dB */
  48         0x14400051,             /* 32, -10.0dB */
  49         0x1300004c,             /* 33, -10.5dB */
  50         0x12000048,             /* 34, -11.0dB */
  51         0x11000044,             /* 35, -11.5dB */
  52         0x10000040,             /* 36, -12.0dB */
  53         0x0f00003c,             /* 37, -12.5dB */
  54         0x0e400039,             /* 38, -13.0dB */
  55         0x0d800036,             /* 39, -13.5dB */
  56         0x0cc00033,             /* 40, -14.0dB */
  57         0x0c000030,             /* 41, -14.5dB */
  58         0x0b40002d,             /* 42, -15.0dB */
  59 };
  60 
  61 static const u8 cck_tbl_ch1_13[CCK_TABLE_SIZE][8] = {
  62         {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},       /* 0, +0dB */
  63         {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},       /* 1, -0.5dB */
  64         {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},       /* 2, -1.0dB */
  65         {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},       /* 3, -1.5dB */
  66         {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},       /* 4, -2.0dB */
  67         {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},       /* 5, -2.5dB */
  68         {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},       /* 6, -3.0dB */
  69         {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},       /* 7, -3.5dB */
  70         {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},       /* 8, -4.0dB */
  71         {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},       /* 9, -4.5dB */
  72         {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},       /* 10, -5.0dB */
  73         {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},       /* 11, -5.5dB */
  74         {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},       /* 12, -6.0dB */
  75         {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},       /* 13, -6.5dB */
  76         {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},       /* 14, -7.0dB */
  77         {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},       /* 15, -7.5dB */
  78         {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},       /* 16, -8.0dB */
  79         {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},       /* 17, -8.5dB */
  80         {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},       /* 18, -9.0dB */
  81         {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},       /* 19, -9.5dB */
  82         {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},       /* 20, -10.0dB*/
  83         {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},       /* 21, -10.5dB*/
  84         {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},       /* 22, -11.0dB*/
  85         {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},       /* 23, -11.5dB*/
  86         {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},       /* 24, -12.0dB*/
  87         {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},       /* 25, -12.5dB*/
  88         {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},       /* 26, -13.0dB*/
  89         {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},       /* 27, -13.5dB*/
  90         {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},       /* 28, -14.0dB*/
  91         {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},       /* 29, -14.5dB*/
  92         {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},       /* 30, -15.0dB*/
  93         {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},       /* 31, -15.5dB*/
  94         {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}        /* 32, -16.0dB*/
  95 };
  96 
  97 static const u8 cck_tbl_ch14[CCK_TABLE_SIZE][8] = {
  98         {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},       /* 0, +0dB */
  99         {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},       /* 1, -0.5dB */
 100         {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},       /* 2, -1.0dB */
 101         {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},       /* 3, -1.5dB */
 102         {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},       /* 4, -2.0dB */
 103         {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},       /* 5, -2.5dB */
 104         {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},       /* 6, -3.0dB */
 105         {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},       /* 7, -3.5dB */
 106         {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},       /* 8, -4.0dB */
 107         {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},       /* 9, -4.5dB */
 108         {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},       /* 10, -5.0dB */
 109         {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},       /* 11, -5.5dB */
 110         {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},       /* 12, -6.0dB */
 111         {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},       /* 13, -6.5dB */
 112         {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},       /* 14, -7.0dB */
 113         {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},       /* 15, -7.5dB */
 114         {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},       /* 16, -8.0dB */
 115         {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},       /* 17, -8.5dB */
 116         {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},       /* 18, -9.0dB */
 117         {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},       /* 19, -9.5dB */
 118         {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},       /* 20, -10.0dB*/
 119         {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},       /* 21, -10.5dB*/
 120         {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},       /* 22, -11.0dB*/
 121         {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},       /* 23, -11.5dB*/
 122         {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},       /* 24, -12.0dB*/
 123         {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},       /* 25, -12.5dB*/
 124         {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},       /* 26, -13.0dB*/
 125         {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},       /* 27, -13.5dB*/
 126         {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},       /* 28, -14.0dB*/
 127         {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},       /* 29, -14.5dB*/
 128         {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},       /* 30, -15.0dB*/
 129         {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},       /* 31, -15.5dB*/
 130         {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}        /* 32, -16.0dB*/
 131 };
 132 
 133 #define CAL_SWING_OFF(_off, _dir, _size, _del)                          \
 134         do {                                                            \
 135                 for (_off = 0; _off < _size; _off++) {                  \
 136                         if (_del < thermal_threshold[_dir][_off]) {     \
 137                                 if (_off != 0)                          \
 138                                         _off--;                         \
 139                                 break;                                  \
 140                         }                                               \
 141                 }                                                       \
 142                 if (_off >= _size)                                      \
 143                         _off = _size - 1;                               \
 144         } while (0)
 145 
 146 static void rtl88e_set_iqk_matrix(struct ieee80211_hw *hw,
 147                                   u8 ofdm_index, u8 rfpath,
 148                                   long iqk_result_x, long iqk_result_y)
 149 {
 150         long ele_a = 0, ele_d, ele_c = 0, value32;
 151 
 152         ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000)>>22;
 153 
 154         if (iqk_result_x != 0) {
 155                 if ((iqk_result_x & 0x00000200) != 0)
 156                         iqk_result_x = iqk_result_x | 0xFFFFFC00;
 157                 ele_a = ((iqk_result_x * ele_d)>>8)&0x000003FF;
 158 
 159                 if ((iqk_result_y & 0x00000200) != 0)
 160                         iqk_result_y = iqk_result_y | 0xFFFFFC00;
 161                 ele_c = ((iqk_result_y * ele_d)>>8)&0x000003FF;
 162 
 163                 switch (rfpath) {
 164                 case RF90_PATH_A:
 165                         value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a;
 166                         rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
 167                                       MASKDWORD, value32);
 168                         value32 = (ele_c & 0x000003C0) >> 6;
 169                         rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
 170                                       value32);
 171                         value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
 172                         rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
 173                                       value32);
 174                         break;
 175                 case RF90_PATH_B:
 176                         value32 = (ele_d << 22)|((ele_c & 0x3F)<<16) | ele_a;
 177                         rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, MASKDWORD,
 178                                       value32);
 179                         value32 = (ele_c & 0x000003C0) >> 6;
 180                         rtl_set_bbreg(hw, ROFDM0_XDTXAFE, MASKH4BITS, value32);
 181                         value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
 182                         rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28),
 183                                       value32);
 184                         break;
 185                 default:
 186                         break;
 187                 }
 188         } else {
 189                 switch (rfpath) {
 190                 case RF90_PATH_A:
 191                         rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
 192                                       MASKDWORD, ofdmswing_table[ofdm_index]);
 193                         rtl_set_bbreg(hw, ROFDM0_XCTXAFE,
 194                                       MASKH4BITS, 0x00);
 195                         rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
 196                                       BIT(24), 0x00);
 197                         break;
 198                 case RF90_PATH_B:
 199                         rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
 200                                       MASKDWORD, ofdmswing_table[ofdm_index]);
 201                         rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
 202                                       MASKH4BITS, 0x00);
 203                         rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
 204                                       BIT(28), 0x00);
 205                         break;
 206                 default:
 207                         break;
 208                 }
 209         }
 210 }
 211 
 212 void rtl88e_dm_txpower_track_adjust(struct ieee80211_hw *hw,
 213         u8 type, u8 *pdirection, u32 *poutwrite_val)
 214 {
 215         struct rtl_priv *rtlpriv = rtl_priv(hw);
 216         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
 217         u8 pwr_val = 0;
 218         u8 cck_base = rtldm->swing_idx_cck_base;
 219         u8 cck_val = rtldm->swing_idx_cck;
 220         u8 ofdm_base = rtldm->swing_idx_ofdm_base[0];
 221         u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A];
 222 
 223         if (type == 0) {
 224                 if (ofdm_val <= ofdm_base) {
 225                         *pdirection = 1;
 226                         pwr_val = ofdm_base - ofdm_val;
 227                 } else {
 228                         *pdirection = 2;
 229                         pwr_val = ofdm_base - ofdm_val;
 230                 }
 231         } else if (type == 1) {
 232                 if (cck_val <= cck_base) {
 233                         *pdirection = 1;
 234                         pwr_val = cck_base - cck_val;
 235                 } else {
 236                         *pdirection = 2;
 237                         pwr_val = cck_val - cck_base;
 238                 }
 239         }
 240 
 241         if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
 242                 pwr_val = TXPWRTRACK_MAX_IDX;
 243 
 244         *poutwrite_val = pwr_val | (pwr_val << 8) | (pwr_val << 16) |
 245                          (pwr_val << 24);
 246 }
 247 
 248 static void dm_tx_pwr_track_set_pwr(struct ieee80211_hw *hw,
 249                                     enum pwr_track_control_method method,
 250                                     u8 rfpath, u8 channel_mapped_index)
 251 {
 252         struct rtl_priv *rtlpriv = rtl_priv(hw);
 253         struct rtl_phy *rtlphy = &rtlpriv->phy;
 254         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
 255 
 256         if (method == TXAGC) {
 257                 if (rtldm->swing_flag_ofdm ||
 258                     rtldm->swing_flag_cck) {
 259                         rtl88e_phy_set_txpower_level(hw,
 260                                                      rtlphy->current_channel);
 261                         rtldm->swing_flag_ofdm = false;
 262                         rtldm->swing_flag_cck = false;
 263                 }
 264         } else if (method == BBSWING) {
 265                 if (!rtldm->cck_inch14) {
 266                         rtl_write_byte(rtlpriv, 0xa22,
 267                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][0]);
 268                         rtl_write_byte(rtlpriv, 0xa23,
 269                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][1]);
 270                         rtl_write_byte(rtlpriv, 0xa24,
 271                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][2]);
 272                         rtl_write_byte(rtlpriv, 0xa25,
 273                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][3]);
 274                         rtl_write_byte(rtlpriv, 0xa26,
 275                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][4]);
 276                         rtl_write_byte(rtlpriv, 0xa27,
 277                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][5]);
 278                         rtl_write_byte(rtlpriv, 0xa28,
 279                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][6]);
 280                         rtl_write_byte(rtlpriv, 0xa29,
 281                                        cck_tbl_ch1_13[rtldm->swing_idx_cck][7]);
 282                 } else {
 283                         rtl_write_byte(rtlpriv, 0xa22,
 284                                        cck_tbl_ch14[rtldm->swing_idx_cck][0]);
 285                         rtl_write_byte(rtlpriv, 0xa23,
 286                                        cck_tbl_ch14[rtldm->swing_idx_cck][1]);
 287                         rtl_write_byte(rtlpriv, 0xa24,
 288                                        cck_tbl_ch14[rtldm->swing_idx_cck][2]);
 289                         rtl_write_byte(rtlpriv, 0xa25,
 290                                        cck_tbl_ch14[rtldm->swing_idx_cck][3]);
 291                         rtl_write_byte(rtlpriv, 0xa26,
 292                                        cck_tbl_ch14[rtldm->swing_idx_cck][4]);
 293                         rtl_write_byte(rtlpriv, 0xa27,
 294                                        cck_tbl_ch14[rtldm->swing_idx_cck][5]);
 295                         rtl_write_byte(rtlpriv, 0xa28,
 296                                        cck_tbl_ch14[rtldm->swing_idx_cck][6]);
 297                         rtl_write_byte(rtlpriv, 0xa29,
 298                                        cck_tbl_ch14[rtldm->swing_idx_cck][7]);
 299                 }
 300 
 301                 if (rfpath == RF90_PATH_A) {
 302                         rtl88e_set_iqk_matrix(hw, rtldm->swing_idx_ofdm[rfpath],
 303                                               rfpath, rtlphy->iqk_matrix
 304                                               [channel_mapped_index].
 305                                               value[0][0],
 306                                               rtlphy->iqk_matrix
 307                                               [channel_mapped_index].
 308                                               value[0][1]);
 309                 } else if (rfpath == RF90_PATH_B) {
 310                         rtl88e_set_iqk_matrix(hw, rtldm->swing_idx_ofdm[rfpath],
 311                                               rfpath, rtlphy->iqk_matrix
 312                                               [channel_mapped_index].
 313                                               value[0][4],
 314                                               rtlphy->iqk_matrix
 315                                               [channel_mapped_index].
 316                                               value[0][5]);
 317                 }
 318         } else {
 319                 return;
 320         }
 321 }
 322 
 323 static u8 rtl88e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
 324 {
 325         struct rtl_priv *rtlpriv = rtl_priv(hw);
 326         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
 327         long rssi_val_min = 0;
 328 
 329         if ((dm_dig->curmultista_cstate == DIG_MULTISTA_CONNECT) &&
 330             (dm_dig->cur_sta_cstate == DIG_STA_CONNECT)) {
 331                 if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0)
 332                         rssi_val_min =
 333                             (rtlpriv->dm.entry_min_undec_sm_pwdb >
 334                              rtlpriv->dm.undec_sm_pwdb) ?
 335                             rtlpriv->dm.undec_sm_pwdb :
 336                             rtlpriv->dm.entry_min_undec_sm_pwdb;
 337                 else
 338                         rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
 339         } else if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT ||
 340                    dm_dig->cur_sta_cstate == DIG_STA_BEFORE_CONNECT) {
 341                 rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
 342         } else if (dm_dig->curmultista_cstate ==
 343                 DIG_MULTISTA_CONNECT) {
 344                 rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
 345         }
 346 
 347         return (u8)rssi_val_min;
 348 }
 349 
 350 static void rtl88e_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
 351 {
 352         u32 ret_value;
 353         struct rtl_priv *rtlpriv = rtl_priv(hw);
 354         struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
 355 
 356         rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1);
 357         rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1);
 358 
 359         ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);
 360         falsealm_cnt->cnt_fast_fsync_fail = (ret_value&0xffff);
 361         falsealm_cnt->cnt_sb_search_fail = ((ret_value&0xffff0000)>>16);
 362 
 363         ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
 364         falsealm_cnt->cnt_ofdm_cca = (ret_value&0xffff);
 365         falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
 366 
 367         ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
 368         falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
 369         falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
 370 
 371         ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
 372         falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
 373         falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
 374                 falsealm_cnt->cnt_rate_illegal +
 375                 falsealm_cnt->cnt_crc8_fail +
 376                 falsealm_cnt->cnt_mcs_fail +
 377                 falsealm_cnt->cnt_fast_fsync_fail +
 378                 falsealm_cnt->cnt_sb_search_fail;
 379 
 380         ret_value = rtl_get_bbreg(hw, REG_SC_CNT, MASKDWORD);
 381         falsealm_cnt->cnt_bw_lsc = (ret_value & 0xffff);
 382         falsealm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16);
 383 
 384         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(12), 1);
 385         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
 386 
 387         ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
 388         falsealm_cnt->cnt_cck_fail = ret_value;
 389 
 390         ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
 391         falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
 392 
 393         ret_value = rtl_get_bbreg(hw, RCCK0_CCA_CNT, MASKDWORD);
 394         falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |
 395                 ((ret_value&0xFF00)>>8);
 396 
 397         falsealm_cnt->cnt_all = (falsealm_cnt->cnt_fast_fsync_fail +
 398                                 falsealm_cnt->cnt_sb_search_fail +
 399                                 falsealm_cnt->cnt_parity_fail +
 400                                 falsealm_cnt->cnt_rate_illegal +
 401                                 falsealm_cnt->cnt_crc8_fail +
 402                                 falsealm_cnt->cnt_mcs_fail +
 403                                 falsealm_cnt->cnt_cck_fail);
 404         falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +
 405                 falsealm_cnt->cnt_cck_cca;
 406 
 407         rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 1);
 408         rtl_set_bbreg(hw, ROFDM0_TRSWISOLATION, BIT(31), 0);
 409         rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 1);
 410         rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(27), 0);
 411         rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 0);
 412         rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 0);
 413         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 0);
 414         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(13)|BIT(12), 2);
 415         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 0);
 416         rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(15)|BIT(14), 2);
 417 
 418         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
 419                  "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
 420                  falsealm_cnt->cnt_parity_fail,
 421                  falsealm_cnt->cnt_rate_illegal,
 422                  falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
 423 
 424         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
 425                  "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
 426                  falsealm_cnt->cnt_ofdm_fail,
 427                  falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
 428 }
 429 
 430 static void rtl88e_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
 431 {
 432         struct rtl_priv *rtlpriv = rtl_priv(hw);
 433         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
 434         u8 cur_cck_cca_thresh;
 435 
 436         if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT) {
 437                 dm_dig->rssi_val_min = rtl88e_dm_initial_gain_min_pwdb(hw);
 438                 if (dm_dig->rssi_val_min > 25) {
 439                         cur_cck_cca_thresh = 0xcd;
 440                 } else if ((dm_dig->rssi_val_min <= 25) &&
 441                            (dm_dig->rssi_val_min > 10)) {
 442                         cur_cck_cca_thresh = 0x83;
 443                 } else {
 444                         if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
 445                                 cur_cck_cca_thresh = 0x83;
 446                         else
 447                                 cur_cck_cca_thresh = 0x40;
 448                 }
 449 
 450         } else {
 451                 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
 452                         cur_cck_cca_thresh = 0x83;
 453                 else
 454                         cur_cck_cca_thresh = 0x40;
 455         }
 456 
 457         if (dm_dig->cur_cck_cca_thres != cur_cck_cca_thresh)
 458                 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh);
 459 
 460         dm_dig->cur_cck_cca_thres = cur_cck_cca_thresh;
 461         dm_dig->pre_cck_cca_thres = dm_dig->cur_cck_cca_thres;
 462         RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
 463                  "CCK cca thresh hold =%x\n", dm_dig->cur_cck_cca_thres);
 464 }
 465 
 466 static void rtl88e_dm_dig(struct ieee80211_hw *hw)
 467 {
 468         struct rtl_priv *rtlpriv = rtl_priv(hw);
 469         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 470         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 471         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
 472         u8 dig_dynamic_min, dig_maxofmin;
 473         bool bfirstconnect;
 474         u8 dm_dig_max, dm_dig_min;
 475         u8 current_igi = dm_dig->cur_igvalue;
 476 
 477         if (rtlpriv->dm.dm_initialgain_enable == false)
 478                 return;
 479         if (dm_dig->dig_enable_flag == false)
 480                 return;
 481         if (mac->act_scanning == true)
 482                 return;
 483 
 484         if (mac->link_state >= MAC80211_LINKED)
 485                 dm_dig->cur_sta_cstate = DIG_STA_CONNECT;
 486         else
 487                 dm_dig->cur_sta_cstate = DIG_STA_DISCONNECT;
 488         if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
 489             rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
 490                 dm_dig->cur_sta_cstate = DIG_STA_DISCONNECT;
 491 
 492         dm_dig_max = DM_DIG_MAX;
 493         dm_dig_min = DM_DIG_MIN;
 494         dig_maxofmin = DM_DIG_MAX_AP;
 495         dig_dynamic_min = dm_dig->dig_min_0;
 496         bfirstconnect = ((mac->link_state >= MAC80211_LINKED) ? true : false) &&
 497                          !dm_dig->media_connect_0;
 498 
 499         dm_dig->rssi_val_min =
 500                 rtl88e_dm_initial_gain_min_pwdb(hw);
 501 
 502         if (mac->link_state >= MAC80211_LINKED) {
 503                 if ((dm_dig->rssi_val_min + 20) > dm_dig_max)
 504                         dm_dig->rx_gain_max = dm_dig_max;
 505                 else if ((dm_dig->rssi_val_min + 20) < dm_dig_min)
 506                         dm_dig->rx_gain_max = dm_dig_min;
 507                 else
 508                         dm_dig->rx_gain_max = dm_dig->rssi_val_min + 20;
 509 
 510                 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
 511                         dig_dynamic_min  = dm_dig->antdiv_rssi_max;
 512                 } else {
 513                         if (dm_dig->rssi_val_min < dm_dig_min)
 514                                 dig_dynamic_min = dm_dig_min;
 515                         else if (dm_dig->rssi_val_min < dig_maxofmin)
 516                                 dig_dynamic_min = dig_maxofmin;
 517                         else
 518                                 dig_dynamic_min = dm_dig->rssi_val_min;
 519                 }
 520         } else {
 521                 dm_dig->rx_gain_max = dm_dig_max;
 522                 dig_dynamic_min = dm_dig_min;
 523                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");
 524         }
 525 
 526         if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
 527                 dm_dig->large_fa_hit++;
 528                 if (dm_dig->forbidden_igi < current_igi) {
 529                         dm_dig->forbidden_igi = current_igi;
 530                         dm_dig->large_fa_hit = 1;
 531                 }
 532 
 533                 if (dm_dig->large_fa_hit >= 3) {
 534                         if ((dm_dig->forbidden_igi + 1) >
 535                                 dm_dig->rx_gain_max)
 536                                 dm_dig->rx_gain_min =
 537                                         dm_dig->rx_gain_max;
 538                         else
 539                                 dm_dig->rx_gain_min =
 540                                         dm_dig->forbidden_igi + 1;
 541                         dm_dig->recover_cnt = 3600;
 542                 }
 543         } else {
 544                 if (dm_dig->recover_cnt != 0) {
 545                         dm_dig->recover_cnt--;
 546                 } else {
 547                         if (dm_dig->large_fa_hit == 0) {
 548                                 if ((dm_dig->forbidden_igi - 1) <
 549                                     dig_dynamic_min) {
 550                                         dm_dig->forbidden_igi = dig_dynamic_min;
 551                                         dm_dig->rx_gain_min = dig_dynamic_min;
 552                                 } else {
 553                                         dm_dig->forbidden_igi--;
 554                                         dm_dig->rx_gain_min =
 555                                                 dm_dig->forbidden_igi + 1;
 556                                 }
 557                         } else if (dm_dig->large_fa_hit == 3) {
 558                                 dm_dig->large_fa_hit = 0;
 559                         }
 560                 }
 561         }
 562 
 563         if (dm_dig->cur_sta_cstate == DIG_STA_CONNECT) {
 564                 if (bfirstconnect) {
 565                         current_igi = dm_dig->rssi_val_min;
 566                 } else {
 567                         if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
 568                                 current_igi += 2;
 569                         else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
 570                                 current_igi++;
 571                         else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
 572                                 current_igi--;
 573                 }
 574         } else {
 575                 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
 576                         current_igi += 2;
 577                 else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
 578                         current_igi++;
 579                 else if (rtlpriv->falsealm_cnt.cnt_all < 500)
 580                         current_igi--;
 581         }
 582 
 583         if (current_igi > DM_DIG_FA_UPPER)
 584                 current_igi = DM_DIG_FA_UPPER;
 585         else if (current_igi < DM_DIG_FA_LOWER)
 586                 current_igi = DM_DIG_FA_LOWER;
 587 
 588         if (rtlpriv->falsealm_cnt.cnt_all > 10000)
 589                 current_igi = DM_DIG_FA_UPPER;
 590 
 591         dm_dig->cur_igvalue = current_igi;
 592         rtl88e_dm_write_dig(hw);
 593         dm_dig->media_connect_0 =
 594                 ((mac->link_state >= MAC80211_LINKED) ? true : false);
 595         dm_dig->dig_min_0 = dig_dynamic_min;
 596 
 597         rtl88e_dm_cck_packet_detection_thresh(hw);
 598 }
 599 
 600 static void rtl88e_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
 601 {
 602         struct rtl_priv *rtlpriv = rtl_priv(hw);
 603 
 604         rtlpriv->dm.dynamic_txpower_enable = false;
 605 
 606         rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
 607         rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 608 }
 609 
 610 static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
 611 {
 612         struct rtl_priv *rtlpriv = rtl_priv(hw);
 613         struct rtl_phy *rtlphy = &rtlpriv->phy;
 614         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 615         long undec_sm_pwdb;
 616 
 617         if (!rtlpriv->dm.dynamic_txpower_enable)
 618                 return;
 619 
 620         if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
 621                 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 622                 return;
 623         }
 624 
 625         if ((mac->link_state < MAC80211_LINKED) &&
 626             (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
 627                 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
 628                          "Not connected to any\n");
 629 
 630                 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 631 
 632                 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
 633                 return;
 634         }
 635 
 636         if (mac->link_state >= MAC80211_LINKED) {
 637                 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
 638                         undec_sm_pwdb =
 639                             rtlpriv->dm.entry_min_undec_sm_pwdb;
 640                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 641                                  "AP Client PWDB = 0x%lx\n",
 642                                   undec_sm_pwdb);
 643                 } else {
 644                         undec_sm_pwdb =
 645                             rtlpriv->dm.undec_sm_pwdb;
 646                         RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 647                                  "STA Default Port PWDB = 0x%lx\n",
 648                                   undec_sm_pwdb);
 649                 }
 650         } else {
 651                 undec_sm_pwdb =
 652                     rtlpriv->dm.entry_min_undec_sm_pwdb;
 653 
 654                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 655                          "AP Ext Port PWDB = 0x%lx\n",
 656                           undec_sm_pwdb);
 657         }
 658 
 659         if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
 660                 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
 661                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 662                          "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x0)\n");
 663         } else if ((undec_sm_pwdb <
 664                     (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
 665                    (undec_sm_pwdb >=
 666                     TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
 667                 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
 668                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 669                          "TXHIGHPWRLEVEL_LEVEL1 (TxPwr = 0x10)\n");
 670         } else if (undec_sm_pwdb <
 671                    (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
 672                 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 673                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 674                          "TXHIGHPWRLEVEL_NORMAL\n");
 675         }
 676 
 677         if ((rtlpriv->dm.dynamic_txhighpower_lvl !=
 678                 rtlpriv->dm.last_dtp_lvl)) {
 679                 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 680                          "PHY_SetTxPowerLevel8192S() Channel = %d\n",
 681                           rtlphy->current_channel);
 682                 rtl88e_phy_set_txpower_level(hw, rtlphy->current_channel);
 683         }
 684 
 685         rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
 686 }
 687 
 688 void rtl88e_dm_write_dig(struct ieee80211_hw *hw)
 689 {
 690         struct rtl_priv *rtlpriv = rtl_priv(hw);
 691         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
 692 
 693         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 694                  "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n",
 695                  dm_dig->cur_igvalue, dm_dig->pre_igvalue,
 696                  dm_dig->back_val);
 697 
 698         if (dm_dig->cur_igvalue > 0x3f)
 699                 dm_dig->cur_igvalue = 0x3f;
 700         if (dm_dig->pre_igvalue != dm_dig->cur_igvalue) {
 701                 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
 702                               dm_dig->cur_igvalue);
 703 
 704                 dm_dig->pre_igvalue = dm_dig->cur_igvalue;
 705         }
 706 }
 707 
 708 static void rtl88e_dm_pwdb_monitor(struct ieee80211_hw *hw)
 709 {
 710         struct rtl_priv *rtlpriv = rtl_priv(hw);
 711         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 712         struct rtl_sta_info *drv_priv;
 713         static u64 last_record_txok_cnt;
 714         static u64 last_record_rxok_cnt;
 715         long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
 716 
 717         if (rtlhal->oem_id == RT_CID_819X_HP) {
 718                 u64 cur_txok_cnt = 0;
 719                 u64 cur_rxok_cnt = 0;
 720                 cur_txok_cnt = rtlpriv->stats.txbytesunicast -
 721                         last_record_txok_cnt;
 722                 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast -
 723                         last_record_rxok_cnt;
 724                 last_record_txok_cnt = cur_txok_cnt;
 725                 last_record_rxok_cnt = cur_rxok_cnt;
 726 
 727                 if (cur_rxok_cnt > (cur_txok_cnt * 6))
 728                         rtl_write_dword(rtlpriv, REG_ARFR0, 0x8f015);
 729                 else
 730                         rtl_write_dword(rtlpriv, REG_ARFR0, 0xff015);
 731         }
 732 
 733         /* AP & ADHOC & MESH */
 734         spin_lock_bh(&rtlpriv->locks.entry_list_lock);
 735         list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
 736                 if (drv_priv->rssi_stat.undec_sm_pwdb <
 737                         tmp_entry_min_pwdb)
 738                         tmp_entry_min_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
 739                 if (drv_priv->rssi_stat.undec_sm_pwdb >
 740                         tmp_entry_max_pwdb)
 741                         tmp_entry_max_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
 742         }
 743         spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
 744 
 745         /* If associated entry is found */
 746         if (tmp_entry_max_pwdb != 0) {
 747                 rtlpriv->dm.entry_max_undec_sm_pwdb = tmp_entry_max_pwdb;
 748                 RTPRINT(rtlpriv, FDM, DM_PWDB, "EntryMaxPWDB = 0x%lx(%ld)\n",
 749                         tmp_entry_max_pwdb, tmp_entry_max_pwdb);
 750         } else {
 751                 rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
 752         }
 753         /* If associated entry is found */
 754         if (tmp_entry_min_pwdb != 0xff) {
 755                 rtlpriv->dm.entry_min_undec_sm_pwdb = tmp_entry_min_pwdb;
 756                 RTPRINT(rtlpriv, FDM, DM_PWDB, "EntryMinPWDB = 0x%lx(%ld)\n",
 757                                         tmp_entry_min_pwdb, tmp_entry_min_pwdb);
 758         } else {
 759                 rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
 760         }
 761         /* Indicate Rx signal strength to FW. */
 762         if (rtlpriv->dm.useramask) {
 763                 u8 h2c_parameter[3] = { 0 };
 764 
 765                 h2c_parameter[2] = (u8)(rtlpriv->dm.undec_sm_pwdb & 0xFF);
 766                 h2c_parameter[0] = 0x20;
 767         } else {
 768                 rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb);
 769         }
 770 }
 771 
 772 void rtl88e_dm_init_edca_turbo(struct ieee80211_hw *hw)
 773 {
 774         struct rtl_priv *rtlpriv = rtl_priv(hw);
 775 
 776         rtlpriv->dm.current_turbo_edca = false;
 777         rtlpriv->dm.is_any_nonbepkts = false;
 778         rtlpriv->dm.is_cur_rdlstate = false;
 779 }
 780 
 781 static void rtl88e_dm_check_edca_turbo(struct ieee80211_hw *hw)
 782 {
 783         struct rtl_priv *rtlpriv = rtl_priv(hw);
 784         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 785         static u64 last_txok_cnt;
 786         static u64 last_rxok_cnt;
 787         static u32 last_bt_edca_ul;
 788         static u32 last_bt_edca_dl;
 789         u64 cur_txok_cnt = 0;
 790         u64 cur_rxok_cnt = 0;
 791         u32 edca_be_ul = 0x5ea42b;
 792         u32 edca_be_dl = 0x5ea42b;
 793         bool bt_change_edca = false;
 794 
 795         if ((last_bt_edca_ul != rtlpriv->btcoexist.bt_edca_ul) ||
 796             (last_bt_edca_dl != rtlpriv->btcoexist.bt_edca_dl)) {
 797                 rtlpriv->dm.current_turbo_edca = false;
 798                 last_bt_edca_ul = rtlpriv->btcoexist.bt_edca_ul;
 799                 last_bt_edca_dl = rtlpriv->btcoexist.bt_edca_dl;
 800         }
 801 
 802         if (rtlpriv->btcoexist.bt_edca_ul != 0) {
 803                 edca_be_ul = rtlpriv->btcoexist.bt_edca_ul;
 804                 bt_change_edca = true;
 805         }
 806 
 807         if (rtlpriv->btcoexist.bt_edca_dl != 0) {
 808                 edca_be_ul = rtlpriv->btcoexist.bt_edca_dl;
 809                 bt_change_edca = true;
 810         }
 811 
 812         if (mac->link_state != MAC80211_LINKED) {
 813                 rtlpriv->dm.current_turbo_edca = false;
 814                 return;
 815         }
 816         if ((bt_change_edca) ||
 817             ((!rtlpriv->dm.is_any_nonbepkts) &&
 818              (!rtlpriv->dm.disable_framebursting))) {
 819 
 820                 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
 821                 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
 822 
 823                 if (cur_rxok_cnt > 4 * cur_txok_cnt) {
 824                         if (!rtlpriv->dm.is_cur_rdlstate ||
 825                             !rtlpriv->dm.current_turbo_edca) {
 826                                 rtl_write_dword(rtlpriv,
 827                                                 REG_EDCA_BE_PARAM,
 828                                                 edca_be_dl);
 829                                 rtlpriv->dm.is_cur_rdlstate = true;
 830                         }
 831                 } else {
 832                         if (rtlpriv->dm.is_cur_rdlstate ||
 833                             !rtlpriv->dm.current_turbo_edca) {
 834                                 rtl_write_dword(rtlpriv,
 835                                                 REG_EDCA_BE_PARAM,
 836                                                 edca_be_ul);
 837                                 rtlpriv->dm.is_cur_rdlstate = false;
 838                         }
 839                 }
 840                 rtlpriv->dm.current_turbo_edca = true;
 841         } else {
 842                 if (rtlpriv->dm.current_turbo_edca) {
 843                         u8 tmp = AC0_BE;
 844 
 845                         rtlpriv->cfg->ops->set_hw_reg(hw,
 846                                                       HW_VAR_AC_PARAM,
 847                                                       &tmp);
 848                         rtlpriv->dm.current_turbo_edca = false;
 849                 }
 850         }
 851 
 852         rtlpriv->dm.is_any_nonbepkts = false;
 853         last_txok_cnt = rtlpriv->stats.txbytesunicast;
 854         last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
 855 }
 856 
 857 static void dm_txpower_track_cb_therm(struct ieee80211_hw *hw)
 858 {
 859         struct rtl_priv *rtlpriv = rtl_priv(hw);
 860         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 861         struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
 862         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 863         u8 thermalvalue = 0, delta, delta_lck, delta_iqk, offset;
 864         u8 thermalvalue_avg_count = 0;
 865         u32 thermalvalue_avg = 0;
 866         long  ele_d, temp_cck;
 867         s8 ofdm_index[2], cck_index = 0,
 868                 ofdm_index_old[2] = {0, 0}, cck_index_old = 0;
 869         int i = 0;
 870         /*bool is2t = false;*/
 871 
 872         u8 ofdm_min_index = 6, rf = 1;
 873         /*u8 index_for_channel;*/
 874         enum _power_dec_inc {power_dec, power_inc};
 875 
 876         /*0.1 the following TWO tables decide the
 877          *final index of OFDM/CCK swing table
 878          */
 879         s8 delta_swing_table_idx[2][15]  = {
 880                 {0, 0, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11},
 881                 {0, 0, -1, -2, -3, -4, -4, -4, -4, -5, -7, -8, -9, -9, -10}
 882         };
 883         u8 thermal_threshold[2][15] = {
 884                 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 27},
 885                 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 25, 25, 25}
 886         };
 887 
 888         /*Initilization (7 steps in total) */
 889         rtlpriv->dm.txpower_trackinginit = true;
 890         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
 891                  "dm_txpower_track_cb_therm\n");
 892 
 893         thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER,
 894                                          0xfc00);
 895         if (!thermalvalue)
 896                 return;
 897         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
 898                  "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
 899                  thermalvalue, rtlpriv->dm.thermalvalue,
 900                  rtlefuse->eeprom_thermalmeter);
 901 
 902         /*1. Query OFDM Default Setting: Path A*/
 903         ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD) &
 904                               MASKOFDM_D;
 905         for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
 906                 if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
 907                         ofdm_index_old[0] = (u8)i;
 908                         rtldm->swing_idx_ofdm_base[RF90_PATH_A] = (u8)i;
 909                         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
 910                                  "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index = 0x%x\n",
 911                                  ROFDM0_XATXIQIMBALANCE,
 912                                  ele_d, ofdm_index_old[0]);
 913                         break;
 914                 }
 915         }
 916 
 917         /*2.Query CCK default setting From 0xa24*/
 918         temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK;
 919         for (i = 0; i < CCK_TABLE_LENGTH; i++) {
 920                 if (rtlpriv->dm.cck_inch14) {
 921                         if (memcmp(&temp_cck, &cck_tbl_ch14[i][2], 4) == 0) {
 922                                 cck_index_old = (u8)i;
 923                                 rtldm->swing_idx_cck_base = (u8)i;
 924                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
 925                                          DBG_LOUD,
 926                                          "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch 14 %d\n",
 927                                          RCCK0_TXFILTER2, temp_cck,
 928                                          cck_index_old,
 929                                          rtlpriv->dm.cck_inch14);
 930                                 break;
 931                         }
 932                 } else {
 933                         if (memcmp(&temp_cck, &cck_tbl_ch1_13[i][2], 4) == 0) {
 934                                 cck_index_old = (u8)i;
 935                                 rtldm->swing_idx_cck_base = (u8)i;
 936                                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
 937                                          DBG_LOUD,
 938                                          "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n",
 939                                          RCCK0_TXFILTER2, temp_cck,
 940                                          cck_index_old,
 941                                          rtlpriv->dm.cck_inch14);
 942                                 break;
 943                         }
 944                 }
 945         }
 946 
 947         /*3 Initialize ThermalValues of RFCalibrateInfo*/
 948         if (!rtldm->thermalvalue) {
 949                 rtlpriv->dm.thermalvalue = rtlefuse->eeprom_thermalmeter;
 950                 rtlpriv->dm.thermalvalue_lck = thermalvalue;
 951                 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
 952                 for (i = 0; i < rf; i++)
 953                         rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
 954                 rtlpriv->dm.cck_index = cck_index_old;
 955         }
 956 
 957         /*4 Calculate average thermal meter*/
 958         rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue;
 959         rtldm->thermalvalue_avg_index++;
 960         if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_88E)
 961                 rtldm->thermalvalue_avg_index = 0;
 962 
 963         for (i = 0; i < AVG_THERMAL_NUM_88E; i++) {
 964                 if (rtldm->thermalvalue_avg[i]) {
 965                         thermalvalue_avg += rtldm->thermalvalue_avg[i];
 966                         thermalvalue_avg_count++;
 967                 }
 968         }
 969 
 970         if (thermalvalue_avg_count)
 971                 thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count);
 972 
 973         /* 5 Calculate delta, delta_LCK, delta_IQK.*/
 974         if (rtlhal->reloadtxpowerindex) {
 975                 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
 976                     (thermalvalue - rtlefuse->eeprom_thermalmeter) :
 977                     (rtlefuse->eeprom_thermalmeter - thermalvalue);
 978                 rtlhal->reloadtxpowerindex = false;
 979                 rtlpriv->dm.done_txpower = false;
 980         } else if (rtlpriv->dm.done_txpower) {
 981                 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
 982                     (thermalvalue - rtlpriv->dm.thermalvalue) :
 983                     (rtlpriv->dm.thermalvalue - thermalvalue);
 984         } else {
 985                 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
 986                     (thermalvalue - rtlefuse->eeprom_thermalmeter) :
 987                     (rtlefuse->eeprom_thermalmeter - thermalvalue);
 988         }
 989         delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
 990             (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
 991             (rtlpriv->dm.thermalvalue_lck - thermalvalue);
 992         delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
 993             (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
 994             (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
 995 
 996         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
 997                  "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",
 998                  thermalvalue, rtlpriv->dm.thermalvalue,
 999                  rtlefuse->eeprom_thermalmeter, delta, delta_lck,
1000                  delta_iqk);
1001         /* 6 If necessary, do LCK.*/
1002         if (delta_lck >= 8) {
1003                 rtlpriv->dm.thermalvalue_lck = thermalvalue;
1004                 rtl88e_phy_lc_calibrate(hw);
1005         }
1006 
1007         /* 7 If necessary, move the index of
1008          * swing table to adjust Tx power.
1009          */
1010         if (delta > 0 && rtlpriv->dm.txpower_track_control) {
1011                 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
1012                     (thermalvalue - rtlefuse->eeprom_thermalmeter) :
1013                     (rtlefuse->eeprom_thermalmeter - thermalvalue);
1014 
1015                 /* 7.1 Get the final CCK_index and OFDM_index for each
1016                  * swing table.
1017                  */
1018                 if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
1019                         CAL_SWING_OFF(offset, power_inc, INDEX_MAPPING_NUM,
1020                                       delta);
1021                         for (i = 0; i < rf; i++)
1022                                 ofdm_index[i] =
1023                                   rtldm->ofdm_index[i] +
1024                                   delta_swing_table_idx[power_inc][offset];
1025                         cck_index = rtldm->cck_index +
1026                                 delta_swing_table_idx[power_inc][offset];
1027                 } else {
1028                         CAL_SWING_OFF(offset, power_dec, INDEX_MAPPING_NUM,
1029                                       delta);
1030                         for (i = 0; i < rf; i++)
1031                                 ofdm_index[i] =
1032                                   rtldm->ofdm_index[i] +
1033                                   delta_swing_table_idx[power_dec][offset];
1034                         cck_index = rtldm->cck_index +
1035                                 delta_swing_table_idx[power_dec][offset];
1036                 }
1037 
1038                 /* 7.2 Handle boundary conditions of index.*/
1039                 for (i = 0; i < rf; i++) {
1040                         if (ofdm_index[i] > OFDM_TABLE_SIZE-1)
1041                                 ofdm_index[i] = OFDM_TABLE_SIZE-1;
1042                         else if (rtldm->ofdm_index[i] < ofdm_min_index)
1043                                 ofdm_index[i] = ofdm_min_index;
1044                 }
1045 
1046                 if (cck_index > CCK_TABLE_SIZE-1)
1047                         cck_index = CCK_TABLE_SIZE-1;
1048                 else if (cck_index < 0)
1049                         cck_index = 0;
1050 
1051                 /*7.3Configure the Swing Table to adjust Tx Power.*/
1052                 if (rtlpriv->dm.txpower_track_control) {
1053                         rtldm->done_txpower = true;
1054                         rtldm->swing_idx_ofdm[RF90_PATH_A] =
1055                                 (u8)ofdm_index[RF90_PATH_A];
1056                         rtldm->swing_idx_cck = cck_index;
1057                         if (rtldm->swing_idx_ofdm_cur !=
1058                             rtldm->swing_idx_ofdm[0]) {
1059                                 rtldm->swing_idx_ofdm_cur =
1060                                          rtldm->swing_idx_ofdm[0];
1061                                 rtldm->swing_flag_ofdm = true;
1062                         }
1063 
1064                         if (rtldm->swing_idx_cck_cur != rtldm->swing_idx_cck) {
1065                                 rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck;
1066                                 rtldm->swing_flag_cck = true;
1067                         }
1068 
1069                         dm_tx_pwr_track_set_pwr(hw, TXAGC, 0, 0);
1070                 }
1071         }
1072 
1073         if (delta_iqk >= 8) {
1074                 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
1075                 rtl88e_phy_iq_calibrate(hw, false);
1076         }
1077 
1078         if (rtldm->txpower_track_control)
1079                 rtldm->thermalvalue = thermalvalue;
1080         rtldm->txpowercount = 0;
1081         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n");
1082 }
1083 
1084 static void rtl88e_dm_init_txpower_tracking(struct ieee80211_hw *hw)
1085 {
1086         struct rtl_priv *rtlpriv = rtl_priv(hw);
1087 
1088         rtlpriv->dm.txpower_tracking = true;
1089         rtlpriv->dm.txpower_trackinginit = false;
1090         rtlpriv->dm.txpowercount = 0;
1091         rtlpriv->dm.txpower_track_control = true;
1092 
1093         rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A] = 12;
1094         rtlpriv->dm.swing_idx_ofdm_cur = 12;
1095         rtlpriv->dm.swing_flag_ofdm = false;
1096         RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1097                  "rtlpriv->dm.txpower_tracking = %d\n",
1098                  rtlpriv->dm.txpower_tracking);
1099 }
1100 
1101 void rtl88e_dm_check_txpower_tracking(struct ieee80211_hw *hw)
1102 {
1103         struct rtl_priv *rtlpriv = rtl_priv(hw);
1104 
1105         if (!rtlpriv->dm.txpower_tracking)
1106                 return;
1107 
1108         if (!rtlpriv->dm.tm_trigger) {
1109                 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17)|BIT(16),
1110                               0x03);
1111                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1112                          "Trigger 88E Thermal Meter!!\n");
1113                 rtlpriv->dm.tm_trigger = 1;
1114                 return;
1115         } else {
1116                 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1117                          "Schedule TxPowerTracking !!\n");
1118                 dm_txpower_track_cb_therm(hw);
1119                 rtlpriv->dm.tm_trigger = 0;
1120         }
1121 }
1122 
1123 void rtl88e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
1124 {
1125         struct rtl_priv *rtlpriv = rtl_priv(hw);
1126         struct rate_adaptive *p_ra = &rtlpriv->ra;
1127 
1128         p_ra->ratr_state = DM_RATR_STA_INIT;
1129         p_ra->pre_ratr_state = DM_RATR_STA_INIT;
1130 
1131         if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
1132                 rtlpriv->dm.useramask = true;
1133         else
1134                 rtlpriv->dm.useramask = false;
1135 }
1136 
1137 static void rtl88e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
1138 {
1139         struct rtl_priv *rtlpriv = rtl_priv(hw);
1140         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1141         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1142         struct rate_adaptive *p_ra = &rtlpriv->ra;
1143         u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
1144         struct ieee80211_sta *sta = NULL;
1145 
1146         if (is_hal_stop(rtlhal)) {
1147                 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1148                          "driver is going to unload\n");
1149                 return;
1150         }
1151 
1152         if (!rtlpriv->dm.useramask) {
1153                 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1154                          "driver does not control rate adaptive mask\n");
1155                 return;
1156         }
1157 
1158         if (mac->link_state == MAC80211_LINKED &&
1159             mac->opmode == NL80211_IFTYPE_STATION) {
1160                 switch (p_ra->pre_ratr_state) {
1161                 case DM_RATR_STA_HIGH:
1162                         high_rssithresh_for_ra = 50;
1163                         low_rssithresh_for_ra = 20;
1164                         break;
1165                 case DM_RATR_STA_MIDDLE:
1166                         high_rssithresh_for_ra = 55;
1167                         low_rssithresh_for_ra = 20;
1168                         break;
1169                 case DM_RATR_STA_LOW:
1170                         high_rssithresh_for_ra = 50;
1171                         low_rssithresh_for_ra = 25;
1172                         break;
1173                 default:
1174                         high_rssithresh_for_ra = 50;
1175                         low_rssithresh_for_ra = 20;
1176                         break;
1177                 }
1178 
1179                 if (rtlpriv->dm.undec_sm_pwdb >
1180                     (long)high_rssithresh_for_ra)
1181                         p_ra->ratr_state = DM_RATR_STA_HIGH;
1182                 else if (rtlpriv->dm.undec_sm_pwdb >
1183                          (long)low_rssithresh_for_ra)
1184                         p_ra->ratr_state = DM_RATR_STA_MIDDLE;
1185                 else
1186                         p_ra->ratr_state = DM_RATR_STA_LOW;
1187 
1188                 if (p_ra->pre_ratr_state != p_ra->ratr_state) {
1189                         RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1190                                  "RSSI = %ld\n",
1191                                   rtlpriv->dm.undec_sm_pwdb);
1192                         RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1193                                  "RSSI_LEVEL = %d\n", p_ra->ratr_state);
1194                         RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1195                                  "PreState = %d, CurState = %d\n",
1196                                   p_ra->pre_ratr_state, p_ra->ratr_state);
1197 
1198                         rcu_read_lock();
1199                         sta = rtl_find_sta(hw, mac->bssid);
1200                         if (sta)
1201                                 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
1202                                                         p_ra->ratr_state,
1203                                                                    true);
1204                         rcu_read_unlock();
1205 
1206                         p_ra->pre_ratr_state = p_ra->ratr_state;
1207                 }
1208         }
1209 }
1210 
1211 static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1212 {
1213         struct rtl_priv *rtlpriv = rtl_priv(hw);
1214         struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
1215 
1216         dm_pstable->pre_ccastate = CCA_MAX;
1217         dm_pstable->cur_ccasate = CCA_MAX;
1218         dm_pstable->pre_rfstate = RF_MAX;
1219         dm_pstable->cur_rfstate = RF_MAX;
1220         dm_pstable->rssi_val_min = 0;
1221 }
1222 
1223 static void rtl88e_dm_update_rx_idle_ant(struct ieee80211_hw *hw,
1224                                          u8 ant)
1225 {
1226         struct rtl_priv *rtlpriv = rtl_priv(hw);
1227         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1228         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1229         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1230         u32 default_ant, optional_ant;
1231 
1232         if (pfat_table->rx_idle_ant != ant) {
1233                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1234                          "need to update rx idle ant\n");
1235                 if (ant == MAIN_ANT) {
1236                         default_ant =
1237                           (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1238                           MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
1239                         optional_ant =
1240                           (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1241                           AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
1242                 } else {
1243                         default_ant =
1244                            (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1245                            AUX_ANT_CG_TRX : AUX_ANT_CGCS_RX;
1246                         optional_ant =
1247                            (pfat_table->rx_idle_ant == CG_TRX_HW_ANTDIV) ?
1248                            MAIN_ANT_CG_TRX : MAIN_ANT_CGCS_RX;
1249                 }
1250 
1251                 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
1252                         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1253                                       BIT(5) | BIT(4) | BIT(3), default_ant);
1254                         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1255                                       BIT(8) | BIT(7) | BIT(6), optional_ant);
1256                         rtl_set_bbreg(hw, DM_REG_ANTSEL_CTRL_11N,
1257                                       BIT(14) | BIT(13) | BIT(12),
1258                                       default_ant);
1259                         rtl_set_bbreg(hw, DM_REG_RESP_TX_11N,
1260                                       BIT(6) | BIT(7), default_ant);
1261                 } else if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) {
1262                         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1263                                       BIT(5) | BIT(4) | BIT(3), default_ant);
1264                         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1265                                       BIT(8) | BIT(7) | BIT(6), optional_ant);
1266                 }
1267         }
1268         pfat_table->rx_idle_ant = ant;
1269         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "RxIdleAnt %s\n",
1270                  (ant == MAIN_ANT) ? ("MAIN_ANT") : ("AUX_ANT"));
1271 }
1272 
1273 static void rtl88e_dm_update_tx_ant(struct ieee80211_hw *hw,
1274                                     u8 ant, u32 mac_id)
1275 {
1276         struct rtl_priv *rtlpriv = rtl_priv(hw);
1277         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1278         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1279         u8 target_ant;
1280 
1281         if (ant == MAIN_ANT)
1282                 target_ant = MAIN_ANT_CG_TRX;
1283         else
1284                 target_ant = AUX_ANT_CG_TRX;
1285 
1286         pfat_table->antsel_a[mac_id] = target_ant & BIT(0);
1287         pfat_table->antsel_b[mac_id] = (target_ant & BIT(1)) >> 1;
1288         pfat_table->antsel_c[mac_id] = (target_ant & BIT(2)) >> 2;
1289         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "txfrominfo target ant %s\n",
1290                 (ant == MAIN_ANT) ? ("MAIN_ANT") : ("AUX_ANT"));
1291         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "antsel_tr_mux = 3'b%d%d%d\n",
1292                 pfat_table->antsel_c[mac_id],
1293                 pfat_table->antsel_b[mac_id],
1294                 pfat_table->antsel_a[mac_id]);
1295 }
1296 
1297 static void rtl88e_dm_rx_hw_antena_div_init(struct ieee80211_hw *hw)
1298 {
1299         u32  value32;
1300 
1301         /*MAC Setting*/
1302         value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1303         rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N,
1304                       MASKDWORD, value32 | (BIT(23) | BIT(25)));
1305         /*Pin Setting*/
1306         rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1307         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1308         rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 1);
1309         rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1310         /*OFDM Setting*/
1311         rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1312         /*CCK Setting*/
1313         rtl_set_bbreg(hw, DM_REG_BB_PWR_SAV4_11N, BIT(7), 1);
1314         rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1);
1315         rtl88e_dm_update_rx_idle_ant(hw, MAIN_ANT);
1316         rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKLWORD, 0x0201);
1317 }
1318 
1319 static void rtl88e_dm_trx_hw_antenna_div_init(struct ieee80211_hw *hw)
1320 {
1321         u32  value32;
1322 
1323         /*MAC Setting*/
1324         value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1325         rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD,
1326                       value32 | (BIT(23) | BIT(25)));
1327         /*Pin Setting*/
1328         rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1329         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1330         rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 0);
1331         rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1332         /*OFDM Setting*/
1333         rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1334         /*CCK Setting*/
1335         rtl_set_bbreg(hw, DM_REG_BB_PWR_SAV4_11N, BIT(7), 1);
1336         rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1);
1337         /*TX Setting*/
1338         rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 0);
1339         rtl88e_dm_update_rx_idle_ant(hw, MAIN_ANT);
1340         rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKLWORD, 0x0201);
1341 }
1342 
1343 static void rtl88e_dm_fast_training_init(struct ieee80211_hw *hw)
1344 {
1345         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1346         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1347         u32 ant_combination = 2;
1348         u32 value32, i;
1349 
1350         for (i = 0; i < 6; i++) {
1351                 pfat_table->bssid[i] = 0;
1352                 pfat_table->ant_sum[i] = 0;
1353                 pfat_table->ant_cnt[i] = 0;
1354                 pfat_table->ant_ave[i] = 0;
1355         }
1356         pfat_table->train_idx = 0;
1357         pfat_table->fat_state = FAT_NORMAL_STATE;
1358 
1359         /*MAC Setting*/
1360         value32 = rtl_get_bbreg(hw, DM_REG_ANTSEL_PIN_11N, MASKDWORD);
1361         rtl_set_bbreg(hw, DM_REG_ANTSEL_PIN_11N,
1362                       MASKDWORD, value32 | (BIT(23) | BIT(25)));
1363         value32 = rtl_get_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N, MASKDWORD);
1364         rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,
1365                       MASKDWORD, value32 | (BIT(16) | BIT(17)));
1366         rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,
1367                       MASKLWORD, 0);
1368         rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA1_11N,
1369                       MASKDWORD, 0);
1370 
1371         /*Pin Setting*/
1372         rtl_set_bbreg(hw, DM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);
1373         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(10), 0);
1374         rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(22), 0);
1375         rtl_set_bbreg(hw, DM_REG_LNA_SWITCH_11N, BIT(31), 1);
1376 
1377         /*OFDM Setting*/
1378         rtl_set_bbreg(hw, DM_REG_ANTDIV_PARA1_11N, MASKDWORD, 0x000000a0);
1379         /*antenna mapping table*/
1380         rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE0, 1);
1381         rtl_set_bbreg(hw, DM_REG_ANT_MAPPING1_11N, MASKBYTE1, 2);
1382 
1383         /*TX Setting*/
1384         rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N, BIT(21), 1);
1385         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1386                       BIT(5) | BIT(4) | BIT(3), 0);
1387         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1388                       BIT(8) | BIT(7) | BIT(6), 1);
1389         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N,
1390                       BIT(2) | BIT(1) | BIT(0), (ant_combination - 1));
1391 
1392         rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1393 }
1394 
1395 static void rtl88e_dm_antenna_div_init(struct ieee80211_hw *hw)
1396 {
1397         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1398 
1399         if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1400                 rtl88e_dm_rx_hw_antena_div_init(hw);
1401         else if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1402                 rtl88e_dm_trx_hw_antenna_div_init(hw);
1403         else if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)
1404                 rtl88e_dm_fast_training_init(hw);
1405 
1406 }
1407 
1408 void rtl88e_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,
1409                                      u8 *pdesc, u32 mac_id)
1410 {
1411         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1412         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1413         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1414         __le32 *pdesc32 = (__le32 *)pdesc;
1415 
1416         if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||
1417             (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)) {
1418                 set_tx_desc_antsel_a(pdesc32, pfat_table->antsel_a[mac_id]);
1419                 set_tx_desc_antsel_b(pdesc32, pfat_table->antsel_b[mac_id]);
1420                 set_tx_desc_antsel_c(pdesc32, pfat_table->antsel_c[mac_id]);
1421         }
1422 }
1423 
1424 void rtl88e_dm_ant_sel_statistics(struct ieee80211_hw *hw,
1425                                   u8 antsel_tr_mux, u32 mac_id,
1426                                   u32 rx_pwdb_all)
1427 {
1428         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1429         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1430         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1431 
1432         if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) {
1433                 if (antsel_tr_mux == MAIN_ANT_CG_TRX) {
1434                         pfat_table->main_ant_sum[mac_id] += rx_pwdb_all;
1435                         pfat_table->main_ant_cnt[mac_id]++;
1436                 } else {
1437                         pfat_table->aux_ant_sum[mac_id] += rx_pwdb_all;
1438                         pfat_table->aux_ant_cnt[mac_id]++;
1439                 }
1440         } else if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) {
1441                 if (antsel_tr_mux == MAIN_ANT_CGCS_RX) {
1442                         pfat_table->main_ant_sum[mac_id] += rx_pwdb_all;
1443                         pfat_table->main_ant_cnt[mac_id]++;
1444                 } else {
1445                         pfat_table->aux_ant_sum[mac_id] += rx_pwdb_all;
1446                         pfat_table->aux_ant_cnt[mac_id]++;
1447                 }
1448         }
1449 }
1450 
1451 static void rtl88e_dm_hw_ant_div(struct ieee80211_hw *hw)
1452 {
1453         struct rtl_priv *rtlpriv = rtl_priv(hw);
1454         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1455         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1456         struct rtl_sta_info *drv_priv;
1457         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1458         struct dig_t *dm_dig = &rtlpriv->dm_digtable;
1459         u32 i, min_rssi = 0xff, ant_div_max_rssi = 0;
1460         u32 max_rssi = 0, local_min_rssi, local_max_rssi;
1461         u32 main_rssi, aux_rssi;
1462         u8 rx_idle_ant = 0, target_ant = 7;
1463 
1464         /*for sta its self*/
1465         i = 0;
1466         main_rssi = (pfat_table->main_ant_cnt[i] != 0) ?
1467                 (pfat_table->main_ant_sum[i] / pfat_table->main_ant_cnt[i]) : 0;
1468         aux_rssi = (pfat_table->aux_ant_cnt[i] != 0) ?
1469                 (pfat_table->aux_ant_sum[i] / pfat_table->aux_ant_cnt[i]) : 0;
1470         target_ant = (main_rssi == aux_rssi) ?
1471                 pfat_table->rx_idle_ant : ((main_rssi >= aux_rssi) ?
1472                 MAIN_ANT : AUX_ANT);
1473         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1474                 "main_ant_sum %d main_ant_cnt %d\n",
1475                 pfat_table->main_ant_sum[i],
1476                 pfat_table->main_ant_cnt[i]);
1477         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1478                  "aux_ant_sum %d aux_ant_cnt %d\n",
1479                  pfat_table->aux_ant_sum[i], pfat_table->aux_ant_cnt[i]);
1480         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "main_rssi %d aux_rssi%d\n",
1481                  main_rssi, aux_rssi);
1482         local_max_rssi = (main_rssi > aux_rssi) ? main_rssi : aux_rssi;
1483         if ((local_max_rssi > ant_div_max_rssi) && (local_max_rssi < 40))
1484                 ant_div_max_rssi = local_max_rssi;
1485         if (local_max_rssi > max_rssi)
1486                 max_rssi = local_max_rssi;
1487 
1488         if ((pfat_table->rx_idle_ant == MAIN_ANT) && (main_rssi == 0))
1489                 main_rssi = aux_rssi;
1490         else if ((pfat_table->rx_idle_ant == AUX_ANT) && (aux_rssi == 0))
1491                 aux_rssi = main_rssi;
1492 
1493         local_min_rssi = (main_rssi > aux_rssi) ? aux_rssi : main_rssi;
1494         if (local_min_rssi < min_rssi) {
1495                 min_rssi = local_min_rssi;
1496                 rx_idle_ant = target_ant;
1497         }
1498         if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1499                 rtl88e_dm_update_tx_ant(hw, target_ant, i);
1500 
1501         if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
1502             rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) {
1503                 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1504                 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
1505                         i++;
1506                         main_rssi = (pfat_table->main_ant_cnt[i] != 0) ?
1507                                 (pfat_table->main_ant_sum[i] /
1508                                 pfat_table->main_ant_cnt[i]) : 0;
1509                         aux_rssi = (pfat_table->aux_ant_cnt[i] != 0) ?
1510                                 (pfat_table->aux_ant_sum[i] /
1511                                 pfat_table->aux_ant_cnt[i]) : 0;
1512                         target_ant = (main_rssi == aux_rssi) ?
1513                                 pfat_table->rx_idle_ant : ((main_rssi >=
1514                                 aux_rssi) ? MAIN_ANT : AUX_ANT);
1515 
1516                         local_max_rssi = (main_rssi > aux_rssi) ?
1517                                          main_rssi : aux_rssi;
1518                         if ((local_max_rssi > ant_div_max_rssi) &&
1519                             (local_max_rssi < 40))
1520                                 ant_div_max_rssi = local_max_rssi;
1521                         if (local_max_rssi > max_rssi)
1522                                 max_rssi = local_max_rssi;
1523 
1524                         if ((pfat_table->rx_idle_ant == MAIN_ANT) &&
1525                             (main_rssi == 0))
1526                                 main_rssi = aux_rssi;
1527                         else if ((pfat_table->rx_idle_ant == AUX_ANT) &&
1528                                  (aux_rssi == 0))
1529                                 aux_rssi = main_rssi;
1530 
1531                         local_min_rssi = (main_rssi > aux_rssi) ?
1532                                 aux_rssi : main_rssi;
1533                         if (local_min_rssi < min_rssi) {
1534                                 min_rssi = local_min_rssi;
1535                                 rx_idle_ant = target_ant;
1536                         }
1537                         if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1538                                 rtl88e_dm_update_tx_ant(hw, target_ant, i);
1539                 }
1540                 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1541         }
1542 
1543         for (i = 0; i < ASSOCIATE_ENTRY_NUM; i++) {
1544                 pfat_table->main_ant_sum[i] = 0;
1545                 pfat_table->aux_ant_sum[i] = 0;
1546                 pfat_table->main_ant_cnt[i] = 0;
1547                 pfat_table->aux_ant_cnt[i] = 0;
1548         }
1549 
1550         rtl88e_dm_update_rx_idle_ant(hw, rx_idle_ant);
1551 
1552         dm_dig->antdiv_rssi_max = ant_div_max_rssi;
1553         dm_dig->rssi_max = max_rssi;
1554 }
1555 
1556 static void rtl88e_set_next_mac_address_target(struct ieee80211_hw *hw)
1557 {
1558         struct rtl_priv *rtlpriv = rtl_priv(hw);
1559         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1560         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1561         struct rtl_sta_info *drv_priv;
1562         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1563         u32 value32, i, j = 0;
1564 
1565         if (mac->link_state >= MAC80211_LINKED) {
1566                 for (i = 0; i < ASSOCIATE_ENTRY_NUM; i++) {
1567                         if ((pfat_table->train_idx + 1) == ASSOCIATE_ENTRY_NUM)
1568                                 pfat_table->train_idx = 0;
1569                         else
1570                                 pfat_table->train_idx++;
1571 
1572                         if (pfat_table->train_idx == 0) {
1573                                 value32 = (mac->mac_addr[5] << 8) |
1574                                           mac->mac_addr[4];
1575                                 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA2_11N,
1576                                               MASKLWORD, value32);
1577 
1578                                 value32 = (mac->mac_addr[3] << 24) |
1579                                           (mac->mac_addr[2] << 16) |
1580                                           (mac->mac_addr[1] << 8) |
1581                                           mac->mac_addr[0];
1582                                 rtl_set_bbreg(hw, DM_REG_ANT_TRAIN_PARA1_11N,
1583                                               MASKDWORD, value32);
1584                                 break;
1585                         }
1586 
1587                         if (rtlpriv->mac80211.opmode !=
1588                             NL80211_IFTYPE_STATION) {
1589                                 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1590                                 list_for_each_entry(drv_priv,
1591                                                     &rtlpriv->entry_list, list) {
1592                                         j++;
1593                                         if (j != pfat_table->train_idx)
1594                                                 continue;
1595 
1596                                         value32 = (drv_priv->mac_addr[5] << 8) |
1597                                                   drv_priv->mac_addr[4];
1598                                         rtl_set_bbreg(hw,
1599                                                       DM_REG_ANT_TRAIN_PARA2_11N,
1600                                                       MASKLWORD, value32);
1601 
1602                                         value32 = (drv_priv->mac_addr[3] << 24) |
1603                                                   (drv_priv->mac_addr[2] << 16) |
1604                                                   (drv_priv->mac_addr[1] << 8) |
1605                                                   drv_priv->mac_addr[0];
1606                                         rtl_set_bbreg(hw,
1607                                                       DM_REG_ANT_TRAIN_PARA1_11N,
1608                                                       MASKDWORD, value32);
1609                                         break;
1610                                 }
1611                                 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1612                                 /*find entry, break*/
1613                                 if (j == pfat_table->train_idx)
1614                                         break;
1615                         }
1616                 }
1617         }
1618 }
1619 
1620 static void rtl88e_dm_fast_ant_training(struct ieee80211_hw *hw)
1621 {
1622         struct rtl_priv *rtlpriv = rtl_priv(hw);
1623         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1624         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1625         u32 i, max_rssi = 0;
1626         u8 target_ant = 2;
1627         bool bpkt_filter_match = false;
1628 
1629         if (pfat_table->fat_state == FAT_TRAINING_STATE) {
1630                 for (i = 0; i < 7; i++) {
1631                         if (pfat_table->ant_cnt[i] == 0) {
1632                                 pfat_table->ant_ave[i] = 0;
1633                         } else {
1634                                 pfat_table->ant_ave[i] =
1635                                         pfat_table->ant_sum[i] /
1636                                         pfat_table->ant_cnt[i];
1637                                 bpkt_filter_match = true;
1638                         }
1639 
1640                         if (pfat_table->ant_ave[i] > max_rssi) {
1641                                 max_rssi = pfat_table->ant_ave[i];
1642                                 target_ant = (u8) i;
1643                         }
1644                 }
1645 
1646                 if (bpkt_filter_match == false) {
1647                         rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N,
1648                                       BIT(16), 0);
1649                         rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1650                 } else {
1651                         rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N,
1652                                       BIT(16), 0);
1653                         rtl_set_bbreg(hw, DM_REG_RX_ANT_CTRL_11N, BIT(8) |
1654                                       BIT(7) | BIT(6), target_ant);
1655                         rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,
1656                                       BIT(21), 1);
1657 
1658                         pfat_table->antsel_a[pfat_table->train_idx] =
1659                                 target_ant & BIT(0);
1660                         pfat_table->antsel_b[pfat_table->train_idx] =
1661                                 (target_ant & BIT(1)) >> 1;
1662                         pfat_table->antsel_c[pfat_table->train_idx] =
1663                                 (target_ant & BIT(2)) >> 2;
1664 
1665                         if (target_ant == 0)
1666                                 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1667                 }
1668 
1669                 for (i = 0; i < 7; i++) {
1670                         pfat_table->ant_sum[i] = 0;
1671                         pfat_table->ant_cnt[i] = 0;
1672                 }
1673 
1674                 pfat_table->fat_state = FAT_NORMAL_STATE;
1675                 return;
1676         }
1677 
1678         if (pfat_table->fat_state == FAT_NORMAL_STATE) {
1679                 rtl88e_set_next_mac_address_target(hw);
1680 
1681                 pfat_table->fat_state = FAT_TRAINING_STATE;
1682                 rtl_set_bbreg(hw, DM_REG_TXAGC_A_1_MCS32_11N, BIT(16), 1);
1683                 rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1684 
1685                 mod_timer(&rtlpriv->works.fast_antenna_training_timer,
1686                           jiffies + MSECS(RTL_WATCH_DOG_TIME));
1687         }
1688 }
1689 
1690 void rtl88e_dm_fast_antenna_training_callback(struct timer_list *t)
1691 {
1692         struct rtl_priv *rtlpriv =
1693                 from_timer(rtlpriv, t, works.fast_antenna_training_timer);
1694         struct ieee80211_hw *hw = rtlpriv->hw;
1695 
1696         rtl88e_dm_fast_ant_training(hw);
1697 }
1698 
1699 static void rtl88e_dm_antenna_diversity(struct ieee80211_hw *hw)
1700 {
1701         struct rtl_priv *rtlpriv = rtl_priv(hw);
1702         struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1703         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1704         struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1705         struct fast_ant_training *pfat_table = &rtldm->fat_table;
1706 
1707         if (mac->link_state < MAC80211_LINKED) {
1708                 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "No Link\n");
1709                 if (pfat_table->becomelinked) {
1710                         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
1711                                  "need to turn off HW AntDiv\n");
1712                         rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 0);
1713                         rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA1_11N,
1714                                       BIT(15), 0);
1715                         if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1716                                 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,
1717                                               BIT(21), 0);
1718                         pfat_table->becomelinked =
1719                                 (mac->link_state == MAC80211_LINKED) ?
1720                                 true : false;
1721                 }
1722                 return;
1723         } else {
1724                 if (!pfat_table->becomelinked) {
1725                         RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
1726                                  "Need to turn on HW AntDiv\n");
1727                         rtl_set_bbreg(hw, DM_REG_IGI_A_11N, BIT(7), 1);
1728                         rtl_set_bbreg(hw, DM_REG_CCK_ANTDIV_PARA1_11N,
1729                                       BIT(15), 1);
1730                         if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
1731                                 rtl_set_bbreg(hw, DM_REG_TX_ANT_CTRL_11N,
1732                                               BIT(21), 1);
1733                         pfat_table->becomelinked =
1734                                 (mac->link_state >= MAC80211_LINKED) ?
1735                                 true : false;
1736                 }
1737         }
1738 
1739         if ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) ||
1740             (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV))
1741                 rtl88e_dm_hw_ant_div(hw);
1742         else if (rtlefuse->antenna_div_type == CG_TRX_SMART_ANTDIV)
1743                 rtl88e_dm_fast_ant_training(hw);
1744 }
1745 
1746 void rtl88e_dm_init(struct ieee80211_hw *hw)
1747 {
1748         struct rtl_priv *rtlpriv = rtl_priv(hw);
1749         u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
1750 
1751         rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1752         rtl_dm_diginit(hw, cur_igvalue);
1753         rtl88e_dm_init_dynamic_txpower(hw);
1754         rtl88e_dm_init_edca_turbo(hw);
1755         rtl88e_dm_init_rate_adaptive_mask(hw);
1756         rtl88e_dm_init_txpower_tracking(hw);
1757         rtl92c_dm_init_dynamic_bb_powersaving(hw);
1758         rtl88e_dm_antenna_div_init(hw);
1759 }
1760 
1761 void rtl88e_dm_watchdog(struct ieee80211_hw *hw)
1762 {
1763         struct rtl_priv *rtlpriv = rtl_priv(hw);
1764         struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1765         bool fw_current_inpsmode = false;
1766         bool fw_ps_awake = true;
1767 
1768         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1769                                       (u8 *)(&fw_current_inpsmode));
1770         rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1771                                       (u8 *)(&fw_ps_awake));
1772         if (ppsc->p2p_ps_info.p2p_ps_mode)
1773                 fw_ps_awake = false;
1774 
1775         spin_lock(&rtlpriv->locks.rf_ps_lock);
1776         if ((ppsc->rfpwr_state == ERFON) &&
1777             ((!fw_current_inpsmode) && fw_ps_awake) &&
1778             (!ppsc->rfchange_inprogress)) {
1779                 rtl88e_dm_pwdb_monitor(hw);
1780                 rtl88e_dm_dig(hw);
1781                 rtl88e_dm_false_alarm_counter_statistics(hw);
1782                 rtl92c_dm_dynamic_txpower(hw);
1783                 rtl88e_dm_check_txpower_tracking(hw);
1784                 rtl88e_dm_refresh_rate_adaptive_mask(hw);
1785                 rtl88e_dm_check_edca_turbo(hw);
1786                 rtl88e_dm_antenna_diversity(hw);
1787         }
1788         spin_unlock(&rtlpriv->locks.rf_ps_lock);
1789 }

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