linux/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2009-2012  Realtek Corporation.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of version 2 of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 *
  14 * You should have received a copy of the GNU General Public License along with
  15 * this program; if not, write to the Free Software Foundation, Inc.,
  16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17 *
  18 * The full GNU General Public License is included in this distribution in the
  19 * file called LICENSE.
  20 *
  21 * Contact Information:
  22 * wlanfae <wlanfae@realtek.com>
  23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  24 * Hsinchu 300, Taiwan.
  25 *
  26 * Larry Finger <Larry.Finger@lwfinger.net>
  27 *
  28 ****************************************************************************
  29 */
  30
  31#include "../wifi.h"
  32#include "../base.h"
  33#include "../pci.h"
  34#include "reg.h"
  35#include "def.h"
  36#include "phy.h"
  37#include "dm.h"
  38#include "../rtl8723com/dm_common.h"
  39#include "fw.h"
  40#include "hal_btc.h"
  41
  42static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
  43        0x7f8001fe,
  44        0x788001e2,
  45        0x71c001c7,
  46        0x6b8001ae,
  47        0x65400195,
  48        0x5fc0017f,
  49        0x5a400169,
  50        0x55400155,
  51        0x50800142,
  52        0x4c000130,
  53        0x47c0011f,
  54        0x43c0010f,
  55        0x40000100,
  56        0x3c8000f2,
  57        0x390000e4,
  58        0x35c000d7,
  59        0x32c000cb,
  60        0x300000c0,
  61        0x2d4000b5,
  62        0x2ac000ab,
  63        0x288000a2,
  64        0x26000098,
  65        0x24000090,
  66        0x22000088,
  67        0x20000080,
  68        0x1e400079,
  69        0x1c800072,
  70        0x1b00006c,
  71        0x19800066,
  72        0x18000060,
  73        0x16c0005b,
  74        0x15800056,
  75        0x14400051,
  76        0x1300004c,
  77        0x12000048,
  78        0x11000044,
  79        0x10000040,
  80};
  81
  82static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
  83        {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
  84        {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
  85        {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
  86        {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
  87        {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
  88        {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
  89        {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
  90        {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
  91        {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
  92        {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
  93        {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
  94        {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
  95        {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
  96        {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
  97        {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
  98        {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
  99        {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
 100        {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
 101        {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
 102        {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
 103        {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
 104        {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
 105        {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},
 106        {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},
 107        {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},
 108        {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},
 109        {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},
 110        {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
 111        {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},
 112        {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},
 113        {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},
 114        {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},
 115        {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}
 116};
 117
 118static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
 119        {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
 120        {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
 121        {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
 122        {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},
 123        {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
 124        {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},
 125        {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
 126        {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
 127        {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
 128        {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
 129        {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
 130        {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
 131        {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
 132        {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
 133        {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
 134        {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
 135        {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
 136        {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
 137        {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
 138        {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
 139        {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
 140        {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
 141        {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},
 142        {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
 143        {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
 144        {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},
 145        {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
 146        {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
 147        {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
 148        {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
 149        {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
 150        {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
 151        {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
 152};
 153
 154static void rtl8723ae_dm_diginit(struct ieee80211_hw *hw)
 155{
 156        struct rtl_priv *rtlpriv = rtl_priv(hw);
 157        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 158
 159        dm_digtable->dig_enable_flag = true;
 160        dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
 161        dm_digtable->cur_igvalue = 0x20;
 162        dm_digtable->pre_igvalue = 0x0;
 163        dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
 164        dm_digtable->presta_cstate = DIG_STA_DISCONNECT;
 165        dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
 166        dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
 167        dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
 168        dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
 169        dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
 170        dm_digtable->rx_gain_max = DM_DIG_MAX;
 171        dm_digtable->rx_gain_min = DM_DIG_MIN;
 172        dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
 173        dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
 174        dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
 175        dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX;
 176        dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
 177}
 178
 179static u8 rtl_init_gain_min_pwdb(struct ieee80211_hw *hw)
 180{
 181        struct rtl_priv *rtlpriv = rtl_priv(hw);
 182        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 183        long rssi_val_min = 0;
 184
 185        if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) &&
 186            (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) {
 187                if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0)
 188                        rssi_val_min =
 189                            (rtlpriv->dm.entry_min_undec_sm_pwdb >
 190                             rtlpriv->dm.undec_sm_pwdb) ?
 191                            rtlpriv->dm.undec_sm_pwdb :
 192                            rtlpriv->dm.entry_min_undec_sm_pwdb;
 193                else
 194                        rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
 195        } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT ||
 196                   dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) {
 197                rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
 198        } else if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) {
 199                rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
 200        }
 201
 202        return (u8) rssi_val_min;
 203}
 204
 205static void rtl8723ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
 206{
 207        u32 ret_value;
 208        struct rtl_priv *rtlpriv = rtl_priv(hw);
 209        struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
 210
 211        ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
 212        falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
 213
 214        ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
 215        falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
 216        falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
 217
 218        ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
 219        falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
 220        falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
 221            falsealm_cnt->cnt_rate_illegal +
 222            falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail;
 223
 224        rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
 225        ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
 226        falsealm_cnt->cnt_cck_fail = ret_value;
 227
 228        ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
 229        falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
 230        falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail +
 231                                 falsealm_cnt->cnt_rate_illegal +
 232                                 falsealm_cnt->cnt_crc8_fail +
 233                                 falsealm_cnt->cnt_mcs_fail +
 234                                 falsealm_cnt->cnt_cck_fail);
 235
 236        rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
 237        rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
 238        rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
 239        rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
 240
 241        RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
 242                 "cnt_parity_fail = %d, cnt_rate_illegal = %d, "
 243                 "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
 244                 falsealm_cnt->cnt_parity_fail,
 245                 falsealm_cnt->cnt_rate_illegal,
 246                 falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
 247
 248        RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
 249                 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
 250                 falsealm_cnt->cnt_ofdm_fail,
 251                 falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
 252}
 253
 254static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
 255{
 256        struct rtl_priv *rtlpriv = rtl_priv(hw);
 257        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 258        u8 value_igi = dm_digtable->cur_igvalue;
 259
 260        if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
 261                value_igi--;
 262        else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
 263                value_igi += 0;
 264        else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2)
 265                value_igi++;
 266        else
 267                value_igi += 2;
 268
 269        value_igi = clamp(value_igi, (u8)DM_DIG_FA_LOWER, (u8)DM_DIG_FA_UPPER);
 270        if (rtlpriv->falsealm_cnt.cnt_all > 10000)
 271                value_igi = 0x32;
 272
 273        dm_digtable->cur_igvalue = value_igi;
 274        rtl8723ae_dm_write_dig(hw);
 275}
 276
 277static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
 278{
 279        struct rtl_priv *rtlpriv = rtl_priv(hw);
 280        struct dig_t *dgtbl = &rtlpriv->dm_digtable;
 281
 282        if (rtlpriv->falsealm_cnt.cnt_all > dgtbl->fa_highthresh) {
 283                if ((dgtbl->back_val - 2) < dgtbl->back_range_min)
 284                        dgtbl->back_val = dgtbl->back_range_min;
 285                else
 286                        dgtbl->back_val -= 2;
 287        } else if (rtlpriv->falsealm_cnt.cnt_all < dgtbl->fa_lowthresh) {
 288                if ((dgtbl->back_val + 2) > dgtbl->back_range_max)
 289                        dgtbl->back_val = dgtbl->back_range_max;
 290                else
 291                        dgtbl->back_val += 2;
 292        }
 293
 294        if ((dgtbl->rssi_val_min + 10 - dgtbl->back_val) >
 295            dgtbl->rx_gain_max)
 296                dgtbl->cur_igvalue = dgtbl->rx_gain_max;
 297        else if ((dgtbl->rssi_val_min + 10 -
 298                  dgtbl->back_val) < dgtbl->rx_gain_min)
 299                dgtbl->cur_igvalue = dgtbl->rx_gain_min;
 300        else
 301                dgtbl->cur_igvalue = dgtbl->rssi_val_min + 10 - dgtbl->back_val;
 302
 303        RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
 304                 "rssi_val_min = %x back_val %x\n",
 305                 dgtbl->rssi_val_min, dgtbl->back_val);
 306
 307        rtl8723ae_dm_write_dig(hw);
 308}
 309
 310static void rtl8723ae_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
 311{
 312        struct rtl_priv *rtlpriv = rtl_priv(hw);
 313        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 314        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 315        long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb;
 316        bool multi_sta = false;
 317
 318        if (mac->opmode == NL80211_IFTYPE_ADHOC)
 319                multi_sta = true;
 320
 321        if ((!multi_sta) ||
 322            (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT)) {
 323                rtlpriv->initialized = false;
 324                dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
 325                return;
 326        } else if (!rtlpriv->initialized) {
 327                rtlpriv->initialized = true;
 328                dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
 329                dm_digtable->cur_igvalue = 0x20;
 330                rtl8723ae_dm_write_dig(hw);
 331        }
 332
 333        if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) {
 334                if ((rssi_strength < dm_digtable->rssi_lowthresh) &&
 335                    (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) {
 336
 337                        if (dm_digtable->dig_ext_port_stage ==
 338                            DIG_EXT_PORT_STAGE_2) {
 339                                dm_digtable->cur_igvalue = 0x20;
 340                                rtl8723ae_dm_write_dig(hw);
 341                        }
 342
 343                        dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1;
 344                } else if (rssi_strength > dm_digtable->rssi_highthresh) {
 345                        dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2;
 346                        rtl92c_dm_ctrl_initgain_by_fa(hw);
 347                }
 348        } else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) {
 349                dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
 350                dm_digtable->cur_igvalue = 0x20;
 351                rtl8723ae_dm_write_dig(hw);
 352        }
 353
 354        RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
 355                 "curmultista_cstate = %x dig_ext_port_stage %x\n",
 356                 dm_digtable->curmultista_cstate,
 357                 dm_digtable->dig_ext_port_stage);
 358}
 359
 360static void rtl8723ae_dm_initial_gain_sta(struct ieee80211_hw *hw)
 361{
 362        struct rtl_priv *rtlpriv = rtl_priv(hw);
 363        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 364
 365        RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
 366                 "presta_cstate = %x, cursta_cstate = %x\n",
 367                 dm_digtable->presta_cstate,
 368                 dm_digtable->cursta_cstate);
 369
 370        if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate ||
 371            dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT ||
 372            dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
 373
 374                if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {
 375                        dm_digtable->rssi_val_min = rtl_init_gain_min_pwdb(hw);
 376                        rtl92c_dm_ctrl_initgain_by_rssi(hw);
 377                }
 378        } else {
 379                dm_digtable->rssi_val_min = 0;
 380                dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
 381                dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
 382                dm_digtable->cur_igvalue = 0x20;
 383                dm_digtable->pre_igvalue = 0;
 384                rtl8723ae_dm_write_dig(hw);
 385        }
 386}
 387static void rtl8723ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
 388{
 389        struct rtl_priv *rtlpriv = rtl_priv(hw);
 390        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 391
 392        if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
 393                dm_digtable->rssi_val_min = rtl_init_gain_min_pwdb(hw);
 394
 395                if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) {
 396                        if (dm_digtable->rssi_val_min <= 25)
 397                                dm_digtable->cur_cck_pd_state =
 398                                    CCK_PD_STAGE_LowRssi;
 399                        else
 400                                dm_digtable->cur_cck_pd_state =
 401                                    CCK_PD_STAGE_HighRssi;
 402                } else {
 403                        if (dm_digtable->rssi_val_min <= 20)
 404                                dm_digtable->cur_cck_pd_state =
 405                                    CCK_PD_STAGE_LowRssi;
 406                        else
 407                                dm_digtable->cur_cck_pd_state =
 408                                    CCK_PD_STAGE_HighRssi;
 409                }
 410        } else {
 411                dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
 412        }
 413
 414        if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) {
 415                if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) {
 416                        if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800)
 417                                dm_digtable->cur_cck_fa_state =
 418                                    CCK_FA_STAGE_High;
 419                        else
 420                                dm_digtable->cur_cck_fa_state =
 421                                                         CCK_FA_STAGE_Low;
 422
 423                        if (dm_digtable->pre_cck_fa_state !=
 424                            dm_digtable->cur_cck_fa_state) {
 425                                if (dm_digtable->cur_cck_fa_state ==
 426                                    CCK_FA_STAGE_Low)
 427                                        rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
 428                                                      0x83);
 429                                else
 430                                        rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
 431                                                      0xcd);
 432
 433                                dm_digtable->pre_cck_fa_state =
 434                                    dm_digtable->cur_cck_fa_state;
 435                        }
 436
 437                        rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40);
 438
 439                } else {
 440                        rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
 441                        rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47);
 442
 443                }
 444                dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state;
 445        }
 446
 447        RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
 448                 "CCKPDStage=%x\n", dm_digtable->cur_cck_pd_state);
 449
 450}
 451
 452static void rtl8723ae_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
 453{
 454        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 455        struct rtl_priv *rtlpriv = rtl_priv(hw);
 456        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 457
 458        if (mac->act_scanning == true)
 459                return;
 460
 461        if (mac->link_state >= MAC80211_LINKED)
 462                dm_digtable->cursta_cstate = DIG_STA_CONNECT;
 463        else
 464                dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
 465
 466        rtl8723ae_dm_initial_gain_sta(hw);
 467        rtl8723ae_dm_initial_gain_multi_sta(hw);
 468        rtl8723ae_dm_cck_packet_detection_thresh(hw);
 469
 470        dm_digtable->presta_cstate = dm_digtable->cursta_cstate;
 471
 472}
 473
 474static void rtl8723ae_dm_dig(struct ieee80211_hw *hw)
 475{
 476        struct rtl_priv *rtlpriv = rtl_priv(hw);
 477        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 478
 479        if (rtlpriv->dm.dm_initialgain_enable == false)
 480                return;
 481        if (dm_digtable->dig_enable_flag == false)
 482                return;
 483
 484        rtl8723ae_dm_ctrl_initgain_by_twoport(hw);
 485}
 486
 487static void rtl8723ae_dm_dynamic_txpower(struct ieee80211_hw *hw)
 488{
 489        struct rtl_priv *rtlpriv = rtl_priv(hw);
 490        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 491        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 492        long undec_sm_pwdb;
 493
 494        if (!rtlpriv->dm.dynamic_txpower_enable)
 495                return;
 496
 497        if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
 498                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 499                return;
 500        }
 501
 502        if ((mac->link_state < MAC80211_LINKED) &&
 503            (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
 504                RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
 505                         "Not connected\n");
 506
 507                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 508
 509                rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
 510                return;
 511        }
 512
 513        if (mac->link_state >= MAC80211_LINKED) {
 514                if (mac->opmode == NL80211_IFTYPE_ADHOC) {
 515                        undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
 516                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 517                                 "AP Client PWDB = 0x%lx\n",
 518                                 undec_sm_pwdb);
 519                } else {
 520                        undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
 521                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 522                                 "STA Default Port PWDB = 0x%lx\n",
 523                                 undec_sm_pwdb);
 524                }
 525        } else {
 526                undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
 527
 528                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 529                         "AP Ext Port PWDB = 0x%lx\n",
 530                          undec_sm_pwdb);
 531        }
 532
 533        if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
 534                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
 535                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 536                         "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
 537        } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
 538                   (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
 539                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
 540                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 541                         "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
 542        } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
 543                rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 544                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 545                         "TXHIGHPWRLEVEL_NORMAL\n");
 546        }
 547
 548        if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
 549                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 550                         "PHY_SetTxPowerLevel8192S() Channel = %d\n",
 551                          rtlphy->current_channel);
 552                rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel);
 553        }
 554
 555        rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
 556}
 557
 558void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw)
 559{
 560        struct rtl_priv *rtlpriv = rtl_priv(hw);
 561        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 562
 563        RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
 564                 "cur_igvalue = 0x%x, "
 565                 "pre_igvalue = 0x%x, back_val = %d\n",
 566                 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
 567                 dm_digtable->back_val);
 568
 569        if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) {
 570                rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
 571                              dm_digtable->cur_igvalue);
 572                rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
 573                              dm_digtable->cur_igvalue);
 574
 575                dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
 576        }
 577}
 578
 579static void rtl8723ae_dm_check_edca_turbo(struct ieee80211_hw *hw)
 580{
 581        struct rtl_priv *rtlpriv = rtl_priv(hw);
 582        struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
 583        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 584
 585        u64 cur_txok_cnt = 0;
 586        u64 cur_rxok_cnt = 0;
 587        u32 edca_be_ul = 0x5ea42b;
 588        u32 edca_be_dl = 0x5ea42b;
 589        bool bt_change_edca = false;
 590
 591        if ((mac->last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) ||
 592            (mac->last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) {
 593                rtlpriv->dm.current_turbo_edca = false;
 594                mac->last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
 595                mac->last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl;
 596        }
 597
 598        if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) {
 599                edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
 600                bt_change_edca = true;
 601        }
 602
 603        if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) {
 604                edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl;
 605                bt_change_edca = true;
 606        }
 607
 608        if (mac->link_state != MAC80211_LINKED) {
 609                rtlpriv->dm.current_turbo_edca = false;
 610                return;
 611        }
 612
 613        if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) {
 614                if (!(edca_be_ul & 0xffff0000))
 615                        edca_be_ul |= 0x005e0000;
 616
 617                if (!(edca_be_dl & 0xffff0000))
 618                        edca_be_dl |= 0x005e0000;
 619        }
 620
 621        if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) &&
 622             (!rtlpriv->dm.disable_framebursting))) {
 623
 624                cur_txok_cnt = rtlpriv->stats.txbytesunicast -
 625                               mac->last_txok_cnt;
 626                cur_rxok_cnt = rtlpriv->stats.rxbytesunicast -
 627                               mac->last_rxok_cnt;
 628
 629                if (cur_rxok_cnt > 4 * cur_txok_cnt) {
 630                        if (!rtlpriv->dm.is_cur_rdlstate ||
 631                            !rtlpriv->dm.current_turbo_edca) {
 632                                rtl_write_dword(rtlpriv,
 633                                                REG_EDCA_BE_PARAM,
 634                                                edca_be_dl);
 635                                rtlpriv->dm.is_cur_rdlstate = true;
 636                        }
 637                } else {
 638                        if (rtlpriv->dm.is_cur_rdlstate ||
 639                            !rtlpriv->dm.current_turbo_edca) {
 640                                rtl_write_dword(rtlpriv,
 641                                                REG_EDCA_BE_PARAM,
 642                                                edca_be_ul);
 643                                rtlpriv->dm.is_cur_rdlstate = false;
 644                        }
 645                }
 646                rtlpriv->dm.current_turbo_edca = true;
 647        } else {
 648                if (rtlpriv->dm.current_turbo_edca) {
 649                        u8 tmp = AC0_BE;
 650                        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
 651                                                      &tmp);
 652                        rtlpriv->dm.current_turbo_edca = false;
 653                }
 654        }
 655
 656        rtlpriv->dm.is_any_nonbepkts = false;
 657        mac->last_txok_cnt = rtlpriv->stats.txbytesunicast;
 658        mac->last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
 659}
 660
 661static void rtl8723ae_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
 662{
 663        struct rtl_priv *rtlpriv = rtl_priv(hw);
 664
 665        rtlpriv->dm.txpower_tracking = true;
 666        rtlpriv->dm.txpower_trackinginit = false;
 667
 668        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
 669                 "pMgntInfo->txpower_tracking = %d\n",
 670                 rtlpriv->dm.txpower_tracking);
 671}
 672
 673void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
 674{
 675        struct rtl_priv *rtlpriv = rtl_priv(hw);
 676        struct rate_adaptive *p_ra = &(rtlpriv->ra);
 677
 678        p_ra->ratr_state = DM_RATR_STA_INIT;
 679        p_ra->pre_ratr_state = DM_RATR_STA_INIT;
 680
 681        if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
 682                rtlpriv->dm.useramask = true;
 683        else
 684                rtlpriv->dm.useramask = false;
 685}
 686
 687static void rtl8723ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
 688{
 689        struct rtl_priv *rtlpriv = rtl_priv(hw);
 690        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 691        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 692        struct rate_adaptive *p_ra = &(rtlpriv->ra);
 693        u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
 694        struct ieee80211_sta *sta = NULL;
 695
 696        if (is_hal_stop(rtlhal)) {
 697                RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
 698                         " driver is going to unload\n");
 699                return;
 700        }
 701
 702        if (!rtlpriv->dm.useramask) {
 703                RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
 704                         " driver does not control rate adaptive mask\n");
 705                return;
 706        }
 707
 708        if (mac->link_state == MAC80211_LINKED &&
 709            mac->opmode == NL80211_IFTYPE_STATION) {
 710                switch (p_ra->pre_ratr_state) {
 711                case DM_RATR_STA_HIGH:
 712                        high_rssithresh_for_ra = 50;
 713                        low_rssithresh_for_ra = 20;
 714                        break;
 715                case DM_RATR_STA_MIDDLE:
 716                        high_rssithresh_for_ra = 55;
 717                        low_rssithresh_for_ra = 20;
 718                        break;
 719                case DM_RATR_STA_LOW:
 720                        high_rssithresh_for_ra = 50;
 721                        low_rssithresh_for_ra = 25;
 722                        break;
 723                default:
 724                        high_rssithresh_for_ra = 50;
 725                        low_rssithresh_for_ra = 20;
 726                        break;
 727                }
 728
 729                if (rtlpriv->dm.undec_sm_pwdb > high_rssithresh_for_ra)
 730                        p_ra->ratr_state = DM_RATR_STA_HIGH;
 731                else if (rtlpriv->dm.undec_sm_pwdb > low_rssithresh_for_ra)
 732                        p_ra->ratr_state = DM_RATR_STA_MIDDLE;
 733                else
 734                        p_ra->ratr_state = DM_RATR_STA_LOW;
 735
 736                if (p_ra->pre_ratr_state != p_ra->ratr_state) {
 737                        RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
 738                                 "RSSI = %ld\n",
 739                                 rtlpriv->dm.undec_sm_pwdb);
 740                        RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
 741                                 "RSSI_LEVEL = %d\n", p_ra->ratr_state);
 742                        RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
 743                                 "PreState = %d, CurState = %d\n",
 744                                 p_ra->pre_ratr_state, p_ra->ratr_state);
 745
 746                        rcu_read_lock();
 747                        sta = rtl_find_sta(hw, mac->bssid);
 748                        if (sta)
 749                                rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
 750                                                           p_ra->ratr_state);
 751                        rcu_read_unlock();
 752
 753                        p_ra->pre_ratr_state = p_ra->ratr_state;
 754                }
 755        }
 756}
 757
 758void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 force_in_normal)
 759{
 760        struct rtl_priv *rtlpriv = rtl_priv(hw);
 761        struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
 762
 763        if (!rtlpriv->reg_init) {
 764                rtlpriv->reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
 765                                    MASKDWORD) & 0x1CC000) >> 14;
 766
 767                rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
 768                                    MASKDWORD) & BIT(3)) >> 3;
 769
 770                rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
 771                                    MASKDWORD) & 0xFF000000) >> 24;
 772
 773                rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) &
 774                                   0xF000) >> 12;
 775
 776                rtlpriv->reg_init = true;
 777        }
 778
 779        if (!force_in_normal) {
 780                if (dm_pstable->rssi_val_min != 0) {
 781                        if (dm_pstable->pre_rfstate == RF_NORMAL) {
 782                                if (dm_pstable->rssi_val_min >= 30)
 783                                        dm_pstable->cur_rfstate = RF_SAVE;
 784                                else
 785                                        dm_pstable->cur_rfstate = RF_NORMAL;
 786                        } else {
 787                                if (dm_pstable->rssi_val_min <= 25)
 788                                        dm_pstable->cur_rfstate = RF_NORMAL;
 789                                else
 790                                        dm_pstable->cur_rfstate = RF_SAVE;
 791                        }
 792                } else {
 793                        dm_pstable->cur_rfstate = RF_MAX;
 794                }
 795        } else {
 796                dm_pstable->cur_rfstate = RF_NORMAL;
 797        }
 798
 799        if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) {
 800                if (dm_pstable->cur_rfstate == RF_SAVE) {
 801
 802                        rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
 803                                      BIT(5), 0x1);
 804                        rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
 805                                      0x1C0000, 0x2);
 806                        rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0);
 807                        rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
 808                                      0xFF000000, 0x63);
 809                        rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
 810                                      0xC000, 0x2);
 811                        rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3);
 812                        rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
 813                        rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
 814                } else {
 815                        rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
 816                                      0x1CC000, rtlpriv->reg_874);
 817                        rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
 818                                      rtlpriv->reg_c70);
 819                        rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
 820                                      rtlpriv->reg_85c);
 821                        rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74);
 822                        rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
 823                        rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
 824                                      BIT(5), 0x0);
 825                }
 826
 827                dm_pstable->pre_rfstate = dm_pstable->cur_rfstate;
 828        }
 829}
 830
 831static void rtl8723ae_dm_dynamic_bpowersaving(struct ieee80211_hw *hw)
 832{
 833        struct rtl_priv *rtlpriv = rtl_priv(hw);
 834        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 835        struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
 836
 837        if (((mac->link_state == MAC80211_NOLINK)) &&
 838            (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
 839                dm_pstable->rssi_val_min = 0;
 840                RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
 841                         "Not connected to any\n");
 842        }
 843
 844        if (mac->link_state == MAC80211_LINKED) {
 845                if (mac->opmode == NL80211_IFTYPE_ADHOC) {
 846                        dm_pstable->rssi_val_min =
 847                            rtlpriv->dm.entry_min_undec_sm_pwdb;
 848                        RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
 849                                 "AP Client PWDB = 0x%lx\n",
 850                                 dm_pstable->rssi_val_min);
 851                } else {
 852                        dm_pstable->rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
 853                        RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
 854                                 "STA Default Port PWDB = 0x%lx\n",
 855                                 dm_pstable->rssi_val_min);
 856                }
 857        } else {
 858                dm_pstable->rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
 859
 860                RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
 861                         "AP Ext Port PWDB = 0x%lx\n",
 862                         dm_pstable->rssi_val_min);
 863        }
 864
 865        rtl8723ae_dm_rf_saving(hw, false);
 866}
 867
 868void rtl8723ae_dm_init(struct ieee80211_hw *hw)
 869{
 870        struct rtl_priv *rtlpriv = rtl_priv(hw);
 871
 872        rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
 873        rtl8723ae_dm_diginit(hw);
 874        rtl8723_dm_init_dynamic_txpower(hw);
 875        rtl8723_dm_init_edca_turbo(hw);
 876        rtl8723ae_dm_init_rate_adaptive_mask(hw);
 877        rtl8723ae_dm_initialize_txpower_tracking(hw);
 878        rtl8723_dm_init_dynamic_bb_powersaving(hw);
 879}
 880
 881void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw)
 882{
 883        struct rtl_priv *rtlpriv = rtl_priv(hw);
 884        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 885        struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
 886        bool fw_current_inpsmode = false;
 887        bool fw_ps_awake = true;
 888        rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
 889                                      (u8 *) (&fw_current_inpsmode));
 890        rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
 891                                      (u8 *) (&fw_ps_awake));
 892
 893        if (ppsc->p2p_ps_info.p2p_ps_mode)
 894                fw_ps_awake = false;
 895
 896        if ((ppsc->rfpwr_state == ERFON) &&
 897            ((!fw_current_inpsmode) && fw_ps_awake) &&
 898            (!ppsc->rfchange_inprogress)) {
 899                rtl8723ae_dm_dig(hw);
 900                rtl8723ae_dm_false_alarm_counter_statistics(hw);
 901                rtl8723ae_dm_dynamic_bpowersaving(hw);
 902                rtl8723ae_dm_dynamic_txpower(hw);
 903                rtl8723ae_dm_refresh_rate_adaptive_mask(hw);
 904                rtl8723ae_dm_bt_coexist(hw);
 905                rtl8723ae_dm_check_edca_turbo(hw);
 906        }
 907        if (rtlpcipriv->bt_coexist.init_set)
 908                rtl_write_byte(rtlpriv, 0x76e, 0xc);
 909}
 910
 911static void rtl8723ae_dm_init_bt_coexist(struct ieee80211_hw *hw)
 912{
 913        struct rtl_priv *rtlpriv = rtl_priv(hw);
 914        struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
 915
 916        rtlpcipriv->bt_coexist.bt_rfreg_origin_1e
 917                = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK1, 0xfffff);
 918        rtlpcipriv->bt_coexist.bt_rfreg_origin_1f
 919                = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK2, 0xf0);
 920
 921        rtlpcipriv->bt_coexist.cstate = 0;
 922        rtlpcipriv->bt_coexist.previous_state = 0;
 923        rtlpcipriv->bt_coexist.cstate_h = 0;
 924        rtlpcipriv->bt_coexist.previous_state_h = 0;
 925        rtlpcipriv->bt_coexist.lps_counter = 0;
 926
 927        /*  Enable counter statistics */
 928        rtl_write_byte(rtlpriv, 0x76e, 0x4);
 929        rtl_write_byte(rtlpriv, 0x778, 0x3);
 930        rtl_write_byte(rtlpriv, 0x40, 0x20);
 931
 932        rtlpcipriv->bt_coexist.init_set = true;
 933}
 934
 935void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw)
 936{
 937        struct rtl_priv *rtlpriv = rtl_priv(hw);
 938        struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
 939        u8 tmp_byte = 0;
 940        if (!rtlpcipriv->bt_coexist.bt_coexistence) {
 941                RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
 942                         "[DM]{BT], BT not exist!!\n");
 943                return;
 944        }
 945
 946        if (!rtlpcipriv->bt_coexist.init_set) {
 947                RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
 948                         "[DM][BT], rtl8723ae_dm_bt_coexist()\n");
 949
 950                rtl8723ae_dm_init_bt_coexist(hw);
 951        }
 952
 953        tmp_byte = rtl_read_byte(rtlpriv, 0x40);
 954        RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
 955                 "[DM][BT], 0x40 is 0x%x", tmp_byte);
 956        RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
 957                 "[DM][BT], bt_dm_coexist start");
 958        rtl8723ae_dm_bt_coexist_8723(hw);
 959}
 960