linux/drivers/staging/rtlwifi/phydm/phydm_adaptivity.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2007 - 2016  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 * The full GNU General Public License is included in this distribution in the
  15 * file called LICENSE.
  16 *
  17 * Contact Information:
  18 * wlanfae <wlanfae@realtek.com>
  19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  20 * Hsinchu 300, Taiwan.
  21 *
  22 * Larry Finger <Larry.Finger@lwfinger.net>
  23 *
  24 *****************************************************************************/
  25
  26/* ************************************************************
  27 * include files
  28 * *************************************************************/
  29#include "mp_precomp.h"
  30#include "phydm_precomp.h"
  31
  32void phydm_check_adaptivity(void *dm_void)
  33{
  34        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
  35        struct adaptivity_statistics *adaptivity =
  36                (struct adaptivity_statistics *)phydm_get_structure(
  37                        dm, PHYDM_ADAPTIVITY);
  38
  39        if (dm->support_ability & ODM_BB_ADAPTIVITY) {
  40                if (adaptivity->dynamic_link_adaptivity ||
  41                    adaptivity->acs_for_adaptivity) {
  42                        if (dm->is_linked && !adaptivity->is_check) {
  43                                phydm_nhm_counter_statistics(dm);
  44                                phydm_check_environment(dm);
  45                        } else if (!dm->is_linked) {
  46                                adaptivity->is_check = false;
  47                        }
  48                } else {
  49                        dm->adaptivity_enable = true;
  50
  51                        if (dm->support_ic_type & (ODM_IC_11AC_GAIN_IDX_EDCCA |
  52                                                   ODM_IC_11N_GAIN_IDX_EDCCA))
  53                                dm->adaptivity_flag = false;
  54                        else
  55                                dm->adaptivity_flag = true;
  56                }
  57        } else {
  58                dm->adaptivity_enable = false;
  59                dm->adaptivity_flag = false;
  60        }
  61}
  62
  63void phydm_nhm_counter_statistics_init(void *dm_void)
  64{
  65        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
  66
  67        if (dm->support_ic_type & ODM_IC_11N_SERIES) {
  68                /*PHY parameters initialize for n series*/
  69
  70                /*0x894[31:16]=0x0xC350
  71                 *Time duration for NHM unit: us, 0xc350=200ms
  72                 */
  73                odm_write_2byte(dm, ODM_REG_CCX_PERIOD_11N + 2, 0xC350);
  74                /*0x890[31:16]=0xffff           th_9, th_10*/
  75                odm_write_2byte(dm, ODM_REG_NHM_TH9_TH10_11N + 2, 0xffff);
  76                /*0x898=0xffffff52              th_3, th_2, th_1, th_0*/
  77                odm_write_4byte(dm, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff50);
  78                /*0x89c=0xffffffff              th_7, th_6, th_5, th_4*/
  79                odm_write_4byte(dm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffffff);
  80                /*0xe28[7:0]=0xff               th_8*/
  81                odm_set_bb_reg(dm, ODM_REG_FPGA0_IQK_11N, MASKBYTE0, 0xff);
  82                /*0x890[10:8]=1         ignoreCCA ignore PHYTXON enable CCX*/
  83                odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N,
  84                               BIT(10) | BIT(9) | BIT(8), 0x1);
  85                /*0xc0c[7]=1                    max power among all RX ants*/
  86                odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTC_11N, BIT(7), 0x1);
  87        } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
  88                /*PHY parameters initialize for ac series*/
  89
  90                odm_write_2byte(dm, ODM_REG_CCX_PERIOD_11AC + 2, 0xC350);
  91                /*0x994[31:16]=0xffff           th_9, th_10*/
  92                odm_write_2byte(dm, ODM_REG_NHM_TH9_TH10_11AC + 2, 0xffff);
  93                /*0x998=0xffffff52              th_3, th_2, th_1, th_0*/
  94                odm_write_4byte(dm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0xffffff50);
  95                /*0x99c=0xffffffff              th_7, th_6, th_5, th_4*/
  96                odm_write_4byte(dm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffffff);
  97                /*0x9a0[7:0]=0xff               th_8*/
  98                odm_set_bb_reg(dm, ODM_REG_NHM_TH8_11AC, MASKBYTE0, 0xff);
  99                /*0x994[10:8]=1         ignoreCCA ignore PHYTXON enable CCX*/
 100                odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC,
 101                               BIT(8) | BIT(9) | BIT(10), 0x1);
 102                /*0x9e8[7]=1                    max power among all RX ants*/
 103                odm_set_bb_reg(dm, ODM_REG_NHM_9E8_11AC, BIT(0), 0x1);
 104        }
 105}
 106
 107void phydm_nhm_counter_statistics(void *dm_void)
 108{
 109        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 110
 111        if (!(dm->support_ability & ODM_BB_NHM_CNT))
 112                return;
 113
 114        /*Get NHM report*/
 115        phydm_get_nhm_counter_statistics(dm);
 116
 117        /*Reset NHM counter*/
 118        phydm_nhm_counter_statistics_reset(dm);
 119}
 120
 121void phydm_get_nhm_counter_statistics(void *dm_void)
 122{
 123        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 124        u32 value32 = 0;
 125
 126        if (dm->support_ic_type & ODM_IC_11AC_SERIES)
 127                value32 = odm_get_bb_reg(dm, ODM_REG_NHM_CNT_11AC, MASKDWORD);
 128        else if (dm->support_ic_type & ODM_IC_11N_SERIES)
 129                value32 = odm_get_bb_reg(dm, ODM_REG_NHM_CNT_11N, MASKDWORD);
 130
 131        dm->nhm_cnt_0 = (u8)(value32 & MASKBYTE0);
 132        dm->nhm_cnt_1 = (u8)((value32 & MASKBYTE1) >> 8);
 133}
 134
 135void phydm_nhm_counter_statistics_reset(void *dm_void)
 136{
 137        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 138
 139        if (dm->support_ic_type & ODM_IC_11N_SERIES) {
 140                odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 0);
 141                odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11N, BIT(1), 1);
 142        } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
 143                odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 0);
 144                odm_set_bb_reg(dm, ODM_REG_NHM_TH9_TH10_11AC, BIT(1), 1);
 145        }
 146}
 147
 148void phydm_set_edcca_threshold(void *dm_void, s8 H2L, s8 L2H)
 149{
 150        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 151
 152        if (dm->support_ic_type & ODM_IC_11N_SERIES)
 153                odm_set_bb_reg(dm, REG_OFDM_0_ECCA_THRESHOLD,
 154                               MASKBYTE2 | MASKBYTE0,
 155                               (u32)((u8)L2H | (u8)H2L << 16));
 156        else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
 157                odm_set_bb_reg(dm, REG_FPGA0_XB_LSSI_READ_BACK, MASKLWORD,
 158                               (u16)((u8)L2H | (u8)H2L << 8));
 159}
 160
 161static void phydm_set_lna(void *dm_void, enum phydm_set_lna type)
 162{
 163        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 164
 165        if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8192E)) {
 166                if (type == phydm_disable_lna) {
 167                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
 168                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
 169                                       0x18000); /*select Rx mode*/
 170                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
 171                                       0x0000f);
 172                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
 173                                       0x37f82); /*disable LNA*/
 174                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
 175                        if (dm->rf_type > ODM_1T1R) {
 176                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
 177                                               0x1);
 178                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x30, 0xfffff,
 179                                               0x18000);
 180                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x31, 0xfffff,
 181                                               0x0000f);
 182                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x32, 0xfffff,
 183                                               0x37f82);
 184                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
 185                                               0x0);
 186                        }
 187                } else if (type == phydm_enable_lna) {
 188                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
 189                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
 190                                       0x18000); /*select Rx mode*/
 191                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
 192                                       0x0000f);
 193                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
 194                                       0x77f82); /*back to normal*/
 195                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
 196                        if (dm->rf_type > ODM_1T1R) {
 197                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
 198                                               0x1);
 199                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x30, 0xfffff,
 200                                               0x18000);
 201                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x31, 0xfffff,
 202                                               0x0000f);
 203                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x32, 0xfffff,
 204                                               0x77f82);
 205                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
 206                                               0x0);
 207                        }
 208                }
 209        } else if (dm->support_ic_type & ODM_RTL8723B) {
 210                if (type == phydm_disable_lna) {
 211                        /*S0*/
 212                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
 213                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
 214                                       0x18000); /*select Rx mode*/
 215                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
 216                                       0x0001f);
 217                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
 218                                       0xe6137); /*disable LNA*/
 219                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
 220                        /*S1*/
 221                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xed, 0x00020, 0x1);
 222                        odm_set_rf_reg(
 223                                dm, ODM_RF_PATH_A, 0x43, 0xfffff,
 224                                0x3008d); /*select Rx mode and disable LNA*/
 225                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xed, 0x00020, 0x0);
 226                } else if (type == phydm_enable_lna) {
 227                        /*S0*/
 228                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
 229                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
 230                                       0x18000); /*select Rx mode*/
 231                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
 232                                       0x0001f);
 233                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
 234                                       0xe6177); /*disable LNA*/
 235                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
 236                        /*S1*/
 237                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xed, 0x00020, 0x1);
 238                        odm_set_rf_reg(
 239                                dm, ODM_RF_PATH_A, 0x43, 0xfffff,
 240                                0x300bd); /*select Rx mode and disable LNA*/
 241                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xed, 0x00020, 0x0);
 242                }
 243
 244        } else if (dm->support_ic_type & ODM_RTL8812) {
 245                if (type == phydm_disable_lna) {
 246                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
 247                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
 248                                       0x18000); /*select Rx mode*/
 249                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
 250                                       0x3f7ff);
 251                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
 252                                       0xc22bf); /*disable LNA*/
 253                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
 254                        if (dm->rf_type > ODM_1T1R) {
 255                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
 256                                               0x1);
 257                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x30, 0xfffff,
 258                                               0x18000); /*select Rx mode*/
 259                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x31, 0xfffff,
 260                                               0x3f7ff);
 261                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x32, 0xfffff,
 262                                               0xc22bf); /*disable LNA*/
 263                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
 264                                               0x0);
 265                        }
 266                } else if (type == phydm_enable_lna) {
 267                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
 268                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
 269                                       0x18000); /*select Rx mode*/
 270                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
 271                                       0x3f7ff);
 272                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
 273                                       0xc26bf); /*disable LNA*/
 274                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
 275                        if (dm->rf_type > ODM_1T1R) {
 276                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
 277                                               0x1);
 278                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x30, 0xfffff,
 279                                               0x18000); /*select Rx mode*/
 280                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x31, 0xfffff,
 281                                               0x3f7ff);
 282                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x32, 0xfffff,
 283                                               0xc26bf); /*disable LNA*/
 284                                odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, 0x80000,
 285                                               0x0);
 286                        }
 287                }
 288        } else if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
 289                if (type == phydm_disable_lna) {
 290                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
 291                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
 292                                       0x18000); /*select Rx mode*/
 293                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
 294                                       0x0002f);
 295                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
 296                                       0xfb09b); /*disable LNA*/
 297                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
 298                } else if (type == phydm_enable_lna) {
 299                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);
 300                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x30, 0xfffff,
 301                                       0x18000); /*select Rx mode*/
 302                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x31, 0xfffff,
 303                                       0x0002f);
 304                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x32, 0xfffff,
 305                                       0xfb0bb); /*disable LNA*/
 306                        odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);
 307                }
 308        }
 309}
 310
 311void phydm_set_trx_mux(void *dm_void, enum phydm_trx_mux_type tx_mode,
 312                       enum phydm_trx_mux_type rx_mode)
 313{
 314        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 315
 316        if (dm->support_ic_type & ODM_IC_11N_SERIES) {
 317                /*set TXmod to standby mode to remove outside noise affect*/
 318                odm_set_bb_reg(dm, ODM_REG_CCK_RPT_FORMAT_11N,
 319                               BIT(3) | BIT(2) | BIT(1), tx_mode);
 320                /*set RXmod to standby mode to remove outside noise affect*/
 321                odm_set_bb_reg(dm, ODM_REG_CCK_RPT_FORMAT_11N,
 322                               BIT(22) | BIT(21) | BIT(20), rx_mode);
 323                if (dm->rf_type > ODM_1T1R) {
 324                        /*set TXmod to standby mode to rm outside noise affect*/
 325                        odm_set_bb_reg(dm, ODM_REG_CCK_RPT_FORMAT_11N_B,
 326                                       BIT(3) | BIT(2) | BIT(1), tx_mode);
 327                        /*set RXmod to standby mode to rm outside noise affect*/
 328                        odm_set_bb_reg(dm, ODM_REG_CCK_RPT_FORMAT_11N_B,
 329                                       BIT(22) | BIT(21) | BIT(20), rx_mode);
 330                }
 331        } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
 332                /*set TXmod to standby mode to remove outside noise affect*/
 333                odm_set_bb_reg(dm, ODM_REG_TRMUX_11AC,
 334                               BIT(11) | BIT(10) | BIT(9) | BIT(8), tx_mode);
 335                /*set RXmod to standby mode to remove outside noise affect*/
 336                odm_set_bb_reg(dm, ODM_REG_TRMUX_11AC,
 337                               BIT(7) | BIT(6) | BIT(5) | BIT(4), rx_mode);
 338                if (dm->rf_type > ODM_1T1R) {
 339                        /*set TXmod to standby mode to rm outside noise affect*/
 340                        odm_set_bb_reg(dm, ODM_REG_TRMUX_11AC_B,
 341                                       BIT(11) | BIT(10) | BIT(9) | BIT(8),
 342                                       tx_mode);
 343                        /*set RXmod to standby mode to rm outside noise affect*/
 344                        odm_set_bb_reg(dm, ODM_REG_TRMUX_11AC_B,
 345                                       BIT(7) | BIT(6) | BIT(5) | BIT(4),
 346                                       rx_mode);
 347                }
 348        }
 349}
 350
 351void phydm_mac_edcca_state(void *dm_void, enum phydm_mac_edcca_type state)
 352{
 353        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 354
 355        if (state == phydm_ignore_edcca) {
 356                /*ignore EDCCA  reg520[15]=1*/
 357                odm_set_mac_reg(dm, REG_TX_PTCL_CTRL, BIT(15), 1);
 358        } else { /*don't set MAC ignore EDCCA signal*/
 359                /*don't ignore EDCCA     reg520[15]=0*/
 360                odm_set_mac_reg(dm, REG_TX_PTCL_CTRL, BIT(15), 0);
 361        }
 362        ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY, "EDCCA enable state = %d\n",
 363                     state);
 364}
 365
 366bool phydm_cal_nhm_cnt(void *dm_void)
 367{
 368        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 369        u16 base = 0;
 370
 371        base = dm->nhm_cnt_0 + dm->nhm_cnt_1;
 372
 373        if (base != 0) {
 374                dm->nhm_cnt_0 = ((dm->nhm_cnt_0) << 8) / base;
 375                dm->nhm_cnt_1 = ((dm->nhm_cnt_1) << 8) / base;
 376        }
 377        if ((dm->nhm_cnt_0 - dm->nhm_cnt_1) >= 100)
 378                return true; /*clean environment*/
 379        else
 380                return false; /*noisy environment*/
 381}
 382
 383void phydm_check_environment(void *dm_void)
 384{
 385        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 386        struct adaptivity_statistics *adaptivity =
 387                (struct adaptivity_statistics *)phydm_get_structure(
 388                        dm, PHYDM_ADAPTIVITY);
 389        bool is_clean_environment = false;
 390
 391        if (adaptivity->is_first_link) {
 392                if (dm->support_ic_type &
 393                    (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA))
 394                        dm->adaptivity_flag = false;
 395                else
 396                        dm->adaptivity_flag = true;
 397
 398                adaptivity->is_first_link = false;
 399                return;
 400        }
 401
 402        if (adaptivity->nhm_wait < 3) { /*Start enter NHM after 4 nhm_wait*/
 403                adaptivity->nhm_wait++;
 404                phydm_nhm_counter_statistics(dm);
 405                return;
 406        }
 407
 408        phydm_nhm_counter_statistics(dm);
 409        is_clean_environment = phydm_cal_nhm_cnt(dm);
 410
 411        if (is_clean_environment) {
 412                dm->th_l2h_ini =
 413                        adaptivity->th_l2h_ini_backup; /*adaptivity mode*/
 414                dm->th_edcca_hl_diff = adaptivity->th_edcca_hl_diff_backup;
 415
 416                dm->adaptivity_enable = true;
 417
 418                if (dm->support_ic_type &
 419                    (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA))
 420                        dm->adaptivity_flag = false;
 421                else
 422                        dm->adaptivity_flag = true;
 423        } else {
 424                if (!adaptivity->acs_for_adaptivity) {
 425                        dm->th_l2h_ini = dm->th_l2h_ini_mode2; /*mode2*/
 426                        dm->th_edcca_hl_diff = dm->th_edcca_hl_diff_mode2;
 427
 428                        dm->adaptivity_flag = false;
 429                        dm->adaptivity_enable = false;
 430                }
 431        }
 432
 433        adaptivity->nhm_wait = 0;
 434        adaptivity->is_first_link = true;
 435        adaptivity->is_check = true;
 436}
 437
 438void phydm_search_pwdb_lower_bound(void *dm_void)
 439{
 440        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 441        struct adaptivity_statistics *adaptivity =
 442                (struct adaptivity_statistics *)phydm_get_structure(
 443                        dm, PHYDM_ADAPTIVITY);
 444        u32 value32 = 0, reg_value32 = 0;
 445        u8 cnt, try_count = 0;
 446        u8 tx_edcca1 = 0, tx_edcca0 = 0;
 447        bool is_adjust = true;
 448        s8 th_l2h_dmc, th_h2l_dmc, igi_target = 0x32;
 449        s8 diff;
 450        u8 IGI = adaptivity->igi_base + 30 + (u8)dm->th_l2h_ini -
 451                 (u8)dm->th_edcca_hl_diff;
 452
 453        if (dm->support_ic_type & (ODM_RTL8723B | ODM_RTL8188E | ODM_RTL8192E |
 454                                   ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) {
 455                phydm_set_lna(dm, phydm_disable_lna);
 456        } else {
 457                phydm_set_trx_mux(dm, phydm_standby_mode, phydm_standby_mode);
 458                odm_pause_dig(dm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_0, 0x7e);
 459        }
 460
 461        diff = igi_target - (s8)IGI;
 462        th_l2h_dmc = dm->th_l2h_ini + diff;
 463        if (th_l2h_dmc > 10)
 464                th_l2h_dmc = 10;
 465        th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
 466
 467        phydm_set_edcca_threshold(dm, th_h2l_dmc, th_l2h_dmc);
 468        ODM_delay_ms(30);
 469
 470        while (is_adjust) {
 471                if (dm->support_ic_type & ODM_IC_11N_SERIES) {
 472                        odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x0);
 473                        reg_value32 =
 474                                odm_get_bb_reg(dm, ODM_REG_RPT_11N, MASKDWORD);
 475                } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
 476                        odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD,
 477                                       0x0);
 478                        reg_value32 =
 479                                odm_get_bb_reg(dm, ODM_REG_RPT_11AC, MASKDWORD);
 480                }
 481                while (reg_value32 & BIT(3) && try_count < 3) {
 482                        ODM_delay_ms(3);
 483                        try_count = try_count + 1;
 484                        if (dm->support_ic_type & ODM_IC_11N_SERIES)
 485                                reg_value32 = odm_get_bb_reg(
 486                                        dm, ODM_REG_RPT_11N, MASKDWORD);
 487                        else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
 488                                reg_value32 = odm_get_bb_reg(
 489                                        dm, ODM_REG_RPT_11AC, MASKDWORD);
 490                }
 491                try_count = 0;
 492
 493                for (cnt = 0; cnt < 20; cnt++) {
 494                        if (dm->support_ic_type & ODM_IC_11N_SERIES) {
 495                                odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N,
 496                                               MASKDWORD, 0x208);
 497                                value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11N,
 498                                                         MASKDWORD);
 499                        } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
 500                                odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC,
 501                                               MASKDWORD, 0x209);
 502                                value32 = odm_get_bb_reg(dm, ODM_REG_RPT_11AC,
 503                                                         MASKDWORD);
 504                        }
 505                        if (value32 & BIT(30) &&
 506                            (dm->support_ic_type &
 507                             (ODM_RTL8723B | ODM_RTL8188E)))
 508                                tx_edcca1 = tx_edcca1 + 1;
 509                        else if (value32 & BIT(29))
 510                                tx_edcca1 = tx_edcca1 + 1;
 511                        else
 512                                tx_edcca0 = tx_edcca0 + 1;
 513                }
 514
 515                if (tx_edcca1 > 1) {
 516                        IGI = IGI - 1;
 517                        th_l2h_dmc = th_l2h_dmc + 1;
 518                        if (th_l2h_dmc > 10)
 519                                th_l2h_dmc = 10;
 520                        th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
 521
 522                        phydm_set_edcca_threshold(dm, th_h2l_dmc, th_l2h_dmc);
 523                        if (th_l2h_dmc == 10) {
 524                                is_adjust = false;
 525                                adaptivity->h2l_lb = th_h2l_dmc;
 526                                adaptivity->l2h_lb = th_l2h_dmc;
 527                                dm->adaptivity_igi_upper = IGI;
 528                        }
 529
 530                        tx_edcca1 = 0;
 531                        tx_edcca0 = 0;
 532
 533                } else {
 534                        is_adjust = false;
 535                        adaptivity->h2l_lb = th_h2l_dmc;
 536                        adaptivity->l2h_lb = th_l2h_dmc;
 537                        dm->adaptivity_igi_upper = IGI;
 538                        tx_edcca1 = 0;
 539                        tx_edcca0 = 0;
 540                }
 541        }
 542
 543        dm->adaptivity_igi_upper = dm->adaptivity_igi_upper - dm->dc_backoff;
 544        adaptivity->h2l_lb = adaptivity->h2l_lb + dm->dc_backoff;
 545        adaptivity->l2h_lb = adaptivity->l2h_lb + dm->dc_backoff;
 546
 547        if (dm->support_ic_type & (ODM_RTL8723B | ODM_RTL8188E | ODM_RTL8192E |
 548                                   ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) {
 549                phydm_set_lna(dm, phydm_enable_lna);
 550        } else {
 551                phydm_set_trx_mux(dm, phydm_tx_mode, phydm_rx_mode);
 552                odm_pause_dig(dm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_0, NONE);
 553        }
 554
 555        phydm_set_edcca_threshold(dm, 0x7f, 0x7f); /*resume to no link state*/
 556}
 557
 558static bool phydm_re_search_condition(void *dm_void)
 559{
 560        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 561        u8 adaptivity_igi_upper;
 562        u8 count = 0;
 563
 564        adaptivity_igi_upper = dm->adaptivity_igi_upper + dm->dc_backoff;
 565
 566        if (adaptivity_igi_upper <= 0x26 && count < 3) {
 567                count = count + 1;
 568                return true;
 569        }
 570
 571        return false;
 572}
 573
 574void phydm_adaptivity_info_init(void *dm_void, enum phydm_adapinfo cmn_info,
 575                                u32 value)
 576{
 577        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 578        struct adaptivity_statistics *adaptivity =
 579                (struct adaptivity_statistics *)phydm_get_structure(
 580                        dm, PHYDM_ADAPTIVITY);
 581
 582        switch (cmn_info) {
 583        case PHYDM_ADAPINFO_CARRIER_SENSE_ENABLE:
 584                dm->carrier_sense_enable = (bool)value;
 585                break;
 586
 587        case PHYDM_ADAPINFO_DCBACKOFF:
 588                dm->dc_backoff = (u8)value;
 589                break;
 590
 591        case PHYDM_ADAPINFO_DYNAMICLINKADAPTIVITY:
 592                adaptivity->dynamic_link_adaptivity = (bool)value;
 593                break;
 594
 595        case PHYDM_ADAPINFO_TH_L2H_INI:
 596                dm->th_l2h_ini = (s8)value;
 597                break;
 598
 599        case PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF:
 600                dm->th_edcca_hl_diff = (s8)value;
 601                break;
 602
 603        case PHYDM_ADAPINFO_AP_NUM_TH:
 604                adaptivity->ap_num_th = (u8)value;
 605                break;
 606
 607        default:
 608                break;
 609        }
 610}
 611
 612void phydm_adaptivity_init(void *dm_void)
 613{
 614        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 615        struct adaptivity_statistics *adaptivity =
 616                (struct adaptivity_statistics *)phydm_get_structure(
 617                        dm, PHYDM_ADAPTIVITY);
 618        s8 igi_target = 0x32;
 619
 620        if (!dm->carrier_sense_enable) {
 621                if (dm->th_l2h_ini == 0)
 622                        dm->th_l2h_ini = 0xf5;
 623        } else {
 624                dm->th_l2h_ini = 0xa;
 625        }
 626
 627        if (dm->th_edcca_hl_diff == 0)
 628                dm->th_edcca_hl_diff = 7;
 629        if (dm->wifi_test || dm->mp_mode) {
 630                /*even no adaptivity, we still enable EDCCA, AP use mib ctrl*/
 631                dm->edcca_enable = false;
 632        } else {
 633                dm->edcca_enable = true;
 634        }
 635
 636        dm->adaptivity_igi_upper = 0;
 637        dm->adaptivity_enable =
 638                false; /*use this flag to decide enable or disable*/
 639
 640        dm->th_l2h_ini_mode2 = 20;
 641        dm->th_edcca_hl_diff_mode2 = 8;
 642        adaptivity->th_l2h_ini_backup = dm->th_l2h_ini;
 643        adaptivity->th_edcca_hl_diff_backup = dm->th_edcca_hl_diff;
 644
 645        adaptivity->igi_base = 0x32;
 646        adaptivity->igi_target = 0x1c;
 647        adaptivity->h2l_lb = 0;
 648        adaptivity->l2h_lb = 0;
 649        adaptivity->nhm_wait = 0;
 650        adaptivity->is_check = false;
 651        adaptivity->is_first_link = true;
 652        adaptivity->adajust_igi_level = 0;
 653        adaptivity->is_stop_edcca = false;
 654        adaptivity->backup_h2l = 0;
 655        adaptivity->backup_l2h = 0;
 656
 657        phydm_mac_edcca_state(dm, phydm_dont_ignore_edcca);
 658
 659        /*Search pwdB lower bound*/
 660        if (dm->support_ic_type & ODM_IC_11N_SERIES)
 661                odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x208);
 662        else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
 663                odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11AC, MASKDWORD, 0x209);
 664
 665        if (dm->support_ic_type & ODM_IC_11N_GAIN_IDX_EDCCA) {
 666                if (dm->support_ic_type & ODM_RTL8197F) {
 667                        /*set to page B1*/
 668                        odm_set_bb_reg(dm, ODM_REG_PAGE_B1_97F, BIT(30), 0x1);
 669                        /*0:rx_dfir, 1: dcnf_out, 2 :rx_iq, 3: rx_nbi_nf_out*/
 670                        odm_set_bb_reg(dm, ODM_REG_EDCCA_DCNF_97F,
 671                                       BIT(27) | BIT(26), 0x1);
 672                        odm_set_bb_reg(dm, ODM_REG_PAGE_B1_97F, BIT(30), 0x0);
 673                } else {
 674                        /*0:rx_dfir, 1: dcnf_out, 2 :rx_iq, 3: rx_nbi_nf_out*/
 675                        odm_set_bb_reg(dm, ODM_REG_EDCCA_DCNF_11N,
 676                                       BIT(21) | BIT(20), 0x1);
 677                }
 678        }
 679        /*8814a no need to find pwdB lower bound, maybe*/
 680        if (dm->support_ic_type & ODM_IC_11AC_GAIN_IDX_EDCCA) {
 681                /*0:rx_dfir, 1: dcnf_out, 2 :rx_iq, 3: rx_nbi_nf_out*/
 682                odm_set_bb_reg(dm, ODM_REG_ACBB_EDCCA_ENHANCE,
 683                               BIT(29) | BIT(28), 0x1);
 684        }
 685
 686        if (!(dm->support_ic_type &
 687              (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA))) {
 688                phydm_search_pwdb_lower_bound(dm);
 689                if (phydm_re_search_condition(dm))
 690                        phydm_search_pwdb_lower_bound(dm);
 691        }
 692
 693        /*we need to consider PwdB upper bound for 8814 later IC*/
 694        adaptivity->adajust_igi_level =
 695                (u8)((dm->th_l2h_ini + igi_target) - pwdb_upper_bound +
 696                     dfir_loss); /*IGI = L2H - PwdB - dfir_loss*/
 697
 698        ODM_RT_TRACE(
 699                dm, PHYDM_COMP_ADAPTIVITY,
 700                "th_l2h_ini = 0x%x, th_edcca_hl_diff = 0x%x, adaptivity->adajust_igi_level = 0x%x\n",
 701                dm->th_l2h_ini, dm->th_edcca_hl_diff,
 702                adaptivity->adajust_igi_level);
 703
 704        /*Check this later on Windows*/
 705        /*phydm_set_edcca_threshold_api(dm, dig_tab->cur_ig_value);*/
 706}
 707
 708void phydm_adaptivity(void *dm_void)
 709{
 710        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 711        struct dig_thres *dig_tab = &dm->dm_dig_table;
 712        u8 IGI = dig_tab->cur_ig_value;
 713        s8 th_l2h_dmc, th_h2l_dmc;
 714        s8 diff = 0, igi_target;
 715        struct adaptivity_statistics *adaptivity =
 716                (struct adaptivity_statistics *)phydm_get_structure(
 717                        dm, PHYDM_ADAPTIVITY);
 718
 719        if (!dm->edcca_enable || adaptivity->is_stop_edcca) {
 720                ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY, "Disable EDCCA!!!\n");
 721                return;
 722        }
 723
 724        if (!(dm->support_ability & ODM_BB_ADAPTIVITY)) {
 725                ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY,
 726                             "adaptivity disable, enable EDCCA mode!!!\n");
 727                dm->th_l2h_ini = dm->th_l2h_ini_mode2;
 728                dm->th_edcca_hl_diff = dm->th_edcca_hl_diff_mode2;
 729        }
 730
 731        ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY, "%s() =====>\n", __func__);
 732        ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY,
 733                     "igi_base=0x%x, th_l2h_ini = %d, th_edcca_hl_diff = %d\n",
 734                     adaptivity->igi_base, dm->th_l2h_ini,
 735                     dm->th_edcca_hl_diff);
 736        if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
 737                /*fix AC series when enable EDCCA hang issue*/
 738                odm_set_bb_reg(dm, 0x800, BIT(10), 1); /*ADC_mask disable*/
 739                odm_set_bb_reg(dm, 0x800, BIT(10), 0); /*ADC_mask enable*/
 740        }
 741        if (*dm->band_width == ODM_BW20M) /*CHANNEL_WIDTH_20*/
 742                igi_target = adaptivity->igi_base;
 743        else if (*dm->band_width == ODM_BW40M)
 744                igi_target = adaptivity->igi_base + 2;
 745        else if (*dm->band_width == ODM_BW80M)
 746                igi_target = adaptivity->igi_base + 2;
 747        else
 748                igi_target = adaptivity->igi_base;
 749        adaptivity->igi_target = (u8)igi_target;
 750
 751        ODM_RT_TRACE(
 752                dm, PHYDM_COMP_ADAPTIVITY,
 753                "band_width=%s, igi_target=0x%x, dynamic_link_adaptivity = %d, acs_for_adaptivity = %d\n",
 754                (*dm->band_width == ODM_BW80M) ?
 755                        "80M" :
 756                        ((*dm->band_width == ODM_BW40M) ? "40M" : "20M"),
 757                igi_target, adaptivity->dynamic_link_adaptivity,
 758                adaptivity->acs_for_adaptivity);
 759        ODM_RT_TRACE(
 760                dm, PHYDM_COMP_ADAPTIVITY,
 761                "rssi_min = %d, adaptivity->adajust_igi_level= 0x%x, adaptivity_flag = %d, adaptivity_enable = %d\n",
 762                dm->rssi_min, adaptivity->adajust_igi_level,
 763                dm->adaptivity_flag, dm->adaptivity_enable);
 764
 765        if (adaptivity->dynamic_link_adaptivity && (!dm->is_linked) &&
 766            !dm->adaptivity_enable) {
 767                phydm_set_edcca_threshold(dm, 0x7f, 0x7f);
 768                ODM_RT_TRACE(
 769                        dm, PHYDM_COMP_ADAPTIVITY,
 770                        "In DynamicLink mode(noisy) and No link, Turn off EDCCA!!\n");
 771                return;
 772        }
 773
 774        if (dm->support_ic_type &
 775            (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) {
 776                if ((adaptivity->adajust_igi_level > IGI) &&
 777                    dm->adaptivity_enable)
 778                        diff = adaptivity->adajust_igi_level - IGI;
 779
 780                th_l2h_dmc = dm->th_l2h_ini - diff + igi_target;
 781                th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
 782        } else {
 783                diff = igi_target - (s8)IGI;
 784                th_l2h_dmc = dm->th_l2h_ini + diff;
 785                if (th_l2h_dmc > 10 && dm->adaptivity_enable)
 786                        th_l2h_dmc = 10;
 787
 788                th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
 789
 790                /*replace lower bound to prevent EDCCA always equal 1*/
 791                if (th_h2l_dmc < adaptivity->h2l_lb)
 792                        th_h2l_dmc = adaptivity->h2l_lb;
 793                if (th_l2h_dmc < adaptivity->l2h_lb)
 794                        th_l2h_dmc = adaptivity->l2h_lb;
 795        }
 796        ODM_RT_TRACE(dm, PHYDM_COMP_ADAPTIVITY,
 797                     "IGI=0x%x, th_l2h_dmc = %d, th_h2l_dmc = %d\n", IGI,
 798                     th_l2h_dmc, th_h2l_dmc);
 799        ODM_RT_TRACE(
 800                dm, PHYDM_COMP_ADAPTIVITY,
 801                "adaptivity_igi_upper=0x%x, h2l_lb = 0x%x, l2h_lb = 0x%x\n",
 802                dm->adaptivity_igi_upper, adaptivity->h2l_lb,
 803                adaptivity->l2h_lb);
 804
 805        phydm_set_edcca_threshold(dm, th_h2l_dmc, th_l2h_dmc);
 806
 807        if (dm->adaptivity_enable)
 808                odm_set_mac_reg(dm, REG_RD_CTRL, BIT(11), 1);
 809}
 810
 811/*This is for solving USB can't Tx problem due to USB3.0 interference in 2.4G*/
 812void phydm_pause_edcca(void *dm_void, bool is_pasue_edcca)
 813{
 814        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 815        struct adaptivity_statistics *adaptivity =
 816                (struct adaptivity_statistics *)phydm_get_structure(
 817                        dm, PHYDM_ADAPTIVITY);
 818        struct dig_thres *dig_tab = &dm->dm_dig_table;
 819        u8 IGI = dig_tab->cur_ig_value;
 820        s8 diff = 0;
 821
 822        if (is_pasue_edcca) {
 823                adaptivity->is_stop_edcca = true;
 824
 825                if (dm->support_ic_type &
 826                    (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) {
 827                        if (adaptivity->adajust_igi_level > IGI)
 828                                diff = adaptivity->adajust_igi_level - IGI;
 829
 830                        adaptivity->backup_l2h =
 831                                dm->th_l2h_ini - diff + adaptivity->igi_target;
 832                        adaptivity->backup_h2l =
 833                                adaptivity->backup_l2h - dm->th_edcca_hl_diff;
 834                } else {
 835                        diff = adaptivity->igi_target - (s8)IGI;
 836                        adaptivity->backup_l2h = dm->th_l2h_ini + diff;
 837                        if (adaptivity->backup_l2h > 10)
 838                                adaptivity->backup_l2h = 10;
 839
 840                        adaptivity->backup_h2l =
 841                                adaptivity->backup_l2h - dm->th_edcca_hl_diff;
 842
 843                        /*replace lower bound to prevent EDCCA always equal 1*/
 844                        if (adaptivity->backup_h2l < adaptivity->h2l_lb)
 845                                adaptivity->backup_h2l = adaptivity->h2l_lb;
 846                        if (adaptivity->backup_l2h < adaptivity->l2h_lb)
 847                                adaptivity->backup_l2h = adaptivity->l2h_lb;
 848                }
 849                ODM_RT_TRACE(
 850                        dm, PHYDM_COMP_ADAPTIVITY,
 851                        "pauseEDCCA : L2Hbak = 0x%x, H2Lbak = 0x%x, IGI = 0x%x\n",
 852                        adaptivity->backup_l2h, adaptivity->backup_h2l, IGI);
 853
 854                /*Disable EDCCA*/
 855                phydm_pause_edcca_work_item_callback(dm);
 856
 857        } else {
 858                adaptivity->is_stop_edcca = false;
 859                ODM_RT_TRACE(
 860                        dm, PHYDM_COMP_ADAPTIVITY,
 861                        "resumeEDCCA : L2Hbak = 0x%x, H2Lbak = 0x%x, IGI = 0x%x\n",
 862                        adaptivity->backup_l2h, adaptivity->backup_h2l, IGI);
 863                /*Resume EDCCA*/
 864                phydm_resume_edcca_work_item_callback(dm);
 865        }
 866}
 867
 868void phydm_pause_edcca_work_item_callback(void *dm_void)
 869{
 870        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 871
 872        if (dm->support_ic_type & ODM_IC_11N_SERIES)
 873                odm_set_bb_reg(dm, REG_OFDM_0_ECCA_THRESHOLD,
 874                               MASKBYTE2 | MASKBYTE0, (u32)(0x7f | 0x7f << 16));
 875        else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
 876                odm_set_bb_reg(dm, REG_FPGA0_XB_LSSI_READ_BACK, MASKLWORD,
 877                               (u16)(0x7f | 0x7f << 8));
 878}
 879
 880void phydm_resume_edcca_work_item_callback(void *dm_void)
 881{
 882        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 883        struct adaptivity_statistics *adaptivity =
 884                (struct adaptivity_statistics *)phydm_get_structure(
 885                        dm, PHYDM_ADAPTIVITY);
 886
 887        if (dm->support_ic_type & ODM_IC_11N_SERIES)
 888                odm_set_bb_reg(dm, REG_OFDM_0_ECCA_THRESHOLD,
 889                               MASKBYTE2 | MASKBYTE0,
 890                               (u32)((u8)adaptivity->backup_l2h |
 891                                     (u8)adaptivity->backup_h2l << 16));
 892        else if (dm->support_ic_type & ODM_IC_11AC_SERIES)
 893                odm_set_bb_reg(dm, REG_FPGA0_XB_LSSI_READ_BACK, MASKLWORD,
 894                               (u16)((u8)adaptivity->backup_l2h |
 895                                     (u8)adaptivity->backup_h2l << 8));
 896}
 897
 898void phydm_set_edcca_threshold_api(void *dm_void, u8 IGI)
 899{
 900        struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
 901        struct adaptivity_statistics *adaptivity =
 902                (struct adaptivity_statistics *)phydm_get_structure(
 903                        dm, PHYDM_ADAPTIVITY);
 904        s8 th_l2h_dmc, th_h2l_dmc;
 905        s8 diff = 0, igi_target = 0x32;
 906
 907        if (dm->support_ability & ODM_BB_ADAPTIVITY) {
 908                if (dm->support_ic_type &
 909                    (ODM_IC_11AC_GAIN_IDX_EDCCA | ODM_IC_11N_GAIN_IDX_EDCCA)) {
 910                        if (adaptivity->adajust_igi_level > IGI)
 911                                diff = adaptivity->adajust_igi_level - IGI;
 912
 913                        th_l2h_dmc = dm->th_l2h_ini - diff + igi_target;
 914                        th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
 915                } else {
 916                        diff = igi_target - (s8)IGI;
 917                        th_l2h_dmc = dm->th_l2h_ini + diff;
 918                        if (th_l2h_dmc > 10)
 919                                th_l2h_dmc = 10;
 920
 921                        th_h2l_dmc = th_l2h_dmc - dm->th_edcca_hl_diff;
 922
 923                        /*replace lower bound to prevent EDCCA always equal 1*/
 924                        if (th_h2l_dmc < adaptivity->h2l_lb)
 925                                th_h2l_dmc = adaptivity->h2l_lb;
 926                        if (th_l2h_dmc < adaptivity->l2h_lb)
 927                                th_l2h_dmc = adaptivity->l2h_lb;
 928                }
 929                ODM_RT_TRACE(
 930                        dm, PHYDM_COMP_ADAPTIVITY,
 931                        "API :IGI=0x%x, th_l2h_dmc = %d, th_h2l_dmc = %d\n",
 932                        IGI, th_l2h_dmc, th_h2l_dmc);
 933                ODM_RT_TRACE(
 934                        dm, PHYDM_COMP_ADAPTIVITY,
 935                        "API :adaptivity_igi_upper=0x%x, h2l_lb = 0x%x, l2h_lb = 0x%x\n",
 936                        dm->adaptivity_igi_upper, adaptivity->h2l_lb,
 937                        adaptivity->l2h_lb);
 938
 939                phydm_set_edcca_threshold(dm, th_h2l_dmc, th_l2h_dmc);
 940        }
 941}
 942