Back to home page

OSCL-LXR

 
 

    


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