linux/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2009-2013  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#include "../wifi.h"
  31#include "../pci.h"
  32#include "../ps.h"
  33#include "reg.h"
  34#include "def.h"
  35#include "phy.h"
  36#include "rf.h"
  37#include "dm.h"
  38#include "table.h"
  39
  40static void set_baseband_phy_config(struct ieee80211_hw *hw);
  41static void set_baseband_agc_config(struct ieee80211_hw *hw);
  42static void store_pwrindex_offset(struct ieee80211_hw *hw,
  43                                  u32 regaddr, u32 bitmask,
  44                                  u32 data);
  45static bool check_cond(struct ieee80211_hw *hw, const u32  condition);
  46
  47static u32 rf_serial_read(struct ieee80211_hw *hw,
  48                          enum radio_path rfpath, u32 offset)
  49{
  50        struct rtl_priv *rtlpriv = rtl_priv(hw);
  51        struct rtl_phy *rtlphy = &(rtlpriv->phy);
  52        struct bb_reg_def *phreg = &rtlphy->phyreg_def[rfpath];
  53        u32 newoffset;
  54        u32 tmplong, tmplong2;
  55        u8 rfpi_enable = 0;
  56        u32 ret;
  57        int jj = RF90_PATH_A;
  58        int kk = RF90_PATH_B;
  59
  60        offset &= 0xff;
  61        newoffset = offset;
  62        if (RT_CANNOT_IO(hw)) {
  63                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
  64                return 0xFFFFFFFF;
  65        }
  66        tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
  67        if (rfpath == jj)
  68                tmplong2 = tmplong;
  69        else
  70                tmplong2 = rtl_get_bbreg(hw, phreg->rfhssi_para2, MASKDWORD);
  71        tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
  72            (newoffset << 23) | BLSSIREADEDGE;
  73        rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
  74                      tmplong & (~BLSSIREADEDGE));
  75        mdelay(1);
  76        rtl_set_bbreg(hw, phreg->rfhssi_para2, MASKDWORD, tmplong2);
  77        mdelay(2);
  78        if (rfpath == jj)
  79                rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
  80                                                 BIT(8));
  81        else if (rfpath == kk)
  82                rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
  83                                                 BIT(8));
  84        if (rfpi_enable)
  85                ret = rtl_get_bbreg(hw, phreg->rf_rbpi, BLSSIREADBACKDATA);
  86        else
  87                ret = rtl_get_bbreg(hw, phreg->rf_rb, BLSSIREADBACKDATA);
  88        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]= 0x%x\n",
  89                 rfpath, phreg->rf_rb, ret);
  90        return ret;
  91}
  92
  93static void rf_serial_write(struct ieee80211_hw *hw,
  94                            enum radio_path rfpath, u32 offset,
  95                            u32 data)
  96{
  97        u32 data_and_addr;
  98        u32 newoffset;
  99        struct rtl_priv *rtlpriv = rtl_priv(hw);
 100        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 101        struct bb_reg_def *phreg = &rtlphy->phyreg_def[rfpath];
 102
 103        if (RT_CANNOT_IO(hw)) {
 104                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
 105                return;
 106        }
 107        offset &= 0xff;
 108        newoffset = offset;
 109        data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
 110        rtl_set_bbreg(hw, phreg->rf3wire_offset, MASKDWORD, data_and_addr);
 111        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]= 0x%x\n",
 112                 rfpath, phreg->rf3wire_offset, data_and_addr);
 113}
 114
 115static u32 cal_bit_shift(u32 bitmask)
 116{
 117        u32 i;
 118
 119        for (i = 0; i <= 31; i++) {
 120                if (((bitmask >> i) & 0x1) == 1)
 121                        break;
 122        }
 123        return i;
 124}
 125
 126static bool config_bb_with_header(struct ieee80211_hw *hw,
 127                                  u8 configtype)
 128{
 129        if (configtype == BASEBAND_CONFIG_PHY_REG)
 130                set_baseband_phy_config(hw);
 131        else if (configtype == BASEBAND_CONFIG_AGC_TAB)
 132                set_baseband_agc_config(hw);
 133        return true;
 134}
 135
 136static bool config_bb_with_pgheader(struct ieee80211_hw *hw,
 137                                    u8 configtype)
 138{
 139        struct rtl_priv *rtlpriv = rtl_priv(hw);
 140        int i;
 141        u32 *table_pg;
 142        u16 tbl_page_len;
 143        u32 v1 = 0, v2 = 0;
 144
 145        tbl_page_len = RTL8188EEPHY_REG_ARRAY_PGLEN;
 146        table_pg = RTL8188EEPHY_REG_ARRAY_PG;
 147
 148        if (configtype == BASEBAND_CONFIG_PHY_REG) {
 149                for (i = 0; i < tbl_page_len; i = i + 3) {
 150                        v1 = table_pg[i];
 151                        v2 = table_pg[i + 1];
 152
 153                        if (v1 < 0xcdcdcdcd) {
 154                                if (table_pg[i] == 0xfe)
 155                                        mdelay(50);
 156                                else if (table_pg[i] == 0xfd)
 157                                        mdelay(5);
 158                                else if (table_pg[i] == 0xfc)
 159                                        mdelay(1);
 160                                else if (table_pg[i] == 0xfb)
 161                                        udelay(50);
 162                                else if (table_pg[i] == 0xfa)
 163                                        udelay(5);
 164                                else if (table_pg[i] == 0xf9)
 165                                        udelay(1);
 166
 167                                store_pwrindex_offset(hw, table_pg[i],
 168                                                      table_pg[i + 1],
 169                                                      table_pg[i + 2]);
 170                                continue;
 171                        } else {
 172                                if (!check_cond(hw, table_pg[i])) {
 173                                        /*don't need the hw_body*/
 174                                        i += 2; /* skip the pair of expression*/
 175                                        v1 = table_pg[i];
 176                                        v2 = table_pg[i + 1];
 177                                        while (v2 != 0xDEAD) {
 178                                                i += 3;
 179                                                v1 = table_pg[i];
 180                                                v2 = table_pg[i + 1];
 181                                        }
 182                                }
 183                        }
 184                }
 185        } else {
 186                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 187                         "configtype != BaseBand_Config_PHY_REG\n");
 188        }
 189        return true;
 190}
 191
 192static bool config_parafile(struct ieee80211_hw *hw)
 193{
 194        struct rtl_priv *rtlpriv = rtl_priv(hw);
 195        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 196        struct rtl_efuse *fuse = rtl_efuse(rtl_priv(hw));
 197        bool rtstatus;
 198
 199        rtstatus = config_bb_with_header(hw, BASEBAND_CONFIG_PHY_REG);
 200        if (rtstatus != true) {
 201                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
 202                return false;
 203        }
 204
 205        if (fuse->autoload_failflag == false) {
 206                rtlphy->pwrgroup_cnt = 0;
 207                rtstatus = config_bb_with_pgheader(hw, BASEBAND_CONFIG_PHY_REG);
 208        }
 209        if (rtstatus != true) {
 210                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
 211                return false;
 212        }
 213        rtstatus = config_bb_with_header(hw, BASEBAND_CONFIG_AGC_TAB);
 214        if (rtstatus != true) {
 215                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
 216                return false;
 217        }
 218        rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
 219                                 RFPGA0_XA_HSSIPARAMETER2, 0x200));
 220
 221        return true;
 222}
 223
 224static void rtl88e_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
 225{
 226        struct rtl_priv *rtlpriv = rtl_priv(hw);
 227        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 228        int jj = RF90_PATH_A;
 229        int kk = RF90_PATH_B;
 230
 231        rtlphy->phyreg_def[jj].rfintfs = RFPGA0_XAB_RFINTERFACESW;
 232        rtlphy->phyreg_def[kk].rfintfs = RFPGA0_XAB_RFINTERFACESW;
 233        rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
 234        rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
 235
 236        rtlphy->phyreg_def[jj].rfintfi = RFPGA0_XAB_RFINTERFACERB;
 237        rtlphy->phyreg_def[kk].rfintfi = RFPGA0_XAB_RFINTERFACERB;
 238        rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
 239        rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
 240
 241        rtlphy->phyreg_def[jj].rfintfo = RFPGA0_XA_RFINTERFACEOE;
 242        rtlphy->phyreg_def[kk].rfintfo = RFPGA0_XB_RFINTERFACEOE;
 243
 244        rtlphy->phyreg_def[jj].rfintfe = RFPGA0_XA_RFINTERFACEOE;
 245        rtlphy->phyreg_def[kk].rfintfe = RFPGA0_XB_RFINTERFACEOE;
 246
 247        rtlphy->phyreg_def[jj].rf3wire_offset = RFPGA0_XA_LSSIPARAMETER;
 248        rtlphy->phyreg_def[kk].rf3wire_offset = RFPGA0_XB_LSSIPARAMETER;
 249
 250        rtlphy->phyreg_def[jj].rflssi_select = rFPGA0_XAB_RFPARAMETER;
 251        rtlphy->phyreg_def[kk].rflssi_select = rFPGA0_XAB_RFPARAMETER;
 252        rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER;
 253        rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER;
 254
 255        rtlphy->phyreg_def[jj].rftxgain_stage = RFPGA0_TXGAINSTAGE;
 256        rtlphy->phyreg_def[kk].rftxgain_stage = RFPGA0_TXGAINSTAGE;
 257        rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
 258        rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
 259
 260        rtlphy->phyreg_def[jj].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
 261        rtlphy->phyreg_def[kk].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
 262
 263        rtlphy->phyreg_def[jj].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
 264        rtlphy->phyreg_def[kk].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
 265
 266        rtlphy->phyreg_def[jj].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
 267        rtlphy->phyreg_def[kk].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
 268        rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
 269        rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
 270
 271        rtlphy->phyreg_def[jj].rfagc_control1 = ROFDM0_XAAGCCORE1;
 272        rtlphy->phyreg_def[kk].rfagc_control1 = ROFDM0_XBAGCCORE1;
 273        rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
 274        rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
 275
 276        rtlphy->phyreg_def[jj].rfagc_control2 = ROFDM0_XAAGCCORE2;
 277        rtlphy->phyreg_def[kk].rfagc_control2 = ROFDM0_XBAGCCORE2;
 278        rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
 279        rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
 280
 281        rtlphy->phyreg_def[jj].rfrxiq_imbal = ROFDM0_XARXIQIMBAL;
 282        rtlphy->phyreg_def[kk].rfrxiq_imbal = ROFDM0_XBRXIQIMBAL;
 283        rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBAL;
 284        rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBAL;
 285
 286        rtlphy->phyreg_def[jj].rfrx_afe = ROFDM0_XARXAFE;
 287        rtlphy->phyreg_def[kk].rfrx_afe = ROFDM0_XBRXAFE;
 288        rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
 289        rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
 290
 291        rtlphy->phyreg_def[jj].rftxiq_imbal = ROFDM0_XATXIQIMBAL;
 292        rtlphy->phyreg_def[kk].rftxiq_imbal = ROFDM0_XBTXIQIMBAL;
 293        rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBAL;
 294        rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBAL;
 295
 296        rtlphy->phyreg_def[jj].rftx_afe = ROFDM0_XATXAFE;
 297        rtlphy->phyreg_def[kk].rftx_afe = ROFDM0_XBTXAFE;
 298
 299        rtlphy->phyreg_def[jj].rf_rb = RFPGA0_XA_LSSIREADBACK;
 300        rtlphy->phyreg_def[kk].rf_rb = RFPGA0_XB_LSSIREADBACK;
 301
 302        rtlphy->phyreg_def[jj].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
 303        rtlphy->phyreg_def[kk].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
 304}
 305
 306static bool rtl88e_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
 307                                            u32 cmdtableidx, u32 cmdtablesz,
 308                                            enum swchnlcmd_id cmdid,
 309                                            u32 para1, u32 para2, u32 msdelay)
 310{
 311        struct swchnlcmd *pcmd;
 312
 313        if (cmdtable == NULL) {
 314                RT_ASSERT(false, "cmdtable cannot be NULL.\n");
 315                return false;
 316        }
 317
 318        if (cmdtableidx >= cmdtablesz)
 319                return false;
 320
 321        pcmd = cmdtable + cmdtableidx;
 322        pcmd->cmdid = cmdid;
 323        pcmd->para1 = para1;
 324        pcmd->para2 = para2;
 325        pcmd->msdelay = msdelay;
 326        return true;
 327}
 328
 329static bool chnl_step_by_step(struct ieee80211_hw *hw,
 330                              u8 channel, u8 *stage, u8 *step,
 331                              u32 *delay)
 332{
 333        struct rtl_priv *rtlpriv = rtl_priv(hw);
 334        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 335        struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
 336        u32 precommoncmdcnt;
 337        struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
 338        u32 postcommoncmdcnt;
 339        struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
 340        u32 rfdependcmdcnt;
 341        struct swchnlcmd *currentcmd = NULL;
 342        u8 rfpath;
 343        u8 num_total_rfpath = rtlphy->num_total_rfpath;
 344
 345        precommoncmdcnt = 0;
 346        rtl88e_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
 347                                        MAX_PRECMD_CNT,
 348                                        CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
 349        rtl88e_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
 350                                        MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
 351
 352        postcommoncmdcnt = 0;
 353
 354        rtl88e_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
 355                                        MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
 356
 357        rfdependcmdcnt = 0;
 358
 359        RT_ASSERT((channel >= 1 && channel <= 14),
 360                  "illegal channel for Zebra: %d\n", channel);
 361
 362        rtl88e_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
 363                                        MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
 364                                        RF_CHNLBW, channel, 10);
 365
 366        rtl88e_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
 367                                        MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0,
 368                                         0);
 369
 370        do {
 371                switch (*stage) {
 372                case 0:
 373                        currentcmd = &precommoncmd[*step];
 374                        break;
 375                case 1:
 376                        currentcmd = &rfdependcmd[*step];
 377                        break;
 378                case 2:
 379                        currentcmd = &postcommoncmd[*step];
 380                        break;
 381                }
 382
 383                if (currentcmd->cmdid == CMDID_END) {
 384                        if ((*stage) == 2) {
 385                                return true;
 386                        } else {
 387                                (*stage)++;
 388                                (*step) = 0;
 389                                continue;
 390                        }
 391                }
 392
 393                switch (currentcmd->cmdid) {
 394                case CMDID_SET_TXPOWEROWER_LEVEL:
 395                        rtl88e_phy_set_txpower_level(hw, channel);
 396                        break;
 397                case CMDID_WRITEPORT_ULONG:
 398                        rtl_write_dword(rtlpriv, currentcmd->para1,
 399                                        currentcmd->para2);
 400                        break;
 401                case CMDID_WRITEPORT_USHORT:
 402                        rtl_write_word(rtlpriv, currentcmd->para1,
 403                                       (u16) currentcmd->para2);
 404                        break;
 405                case CMDID_WRITEPORT_UCHAR:
 406                        rtl_write_byte(rtlpriv, currentcmd->para1,
 407                                       (u8) currentcmd->para2);
 408                        break;
 409                case CMDID_RF_WRITEREG:
 410                        for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
 411                                rtlphy->rfreg_chnlval[rfpath] =
 412                                    ((rtlphy->rfreg_chnlval[rfpath] &
 413                                      0xfffffc00) | currentcmd->para2);
 414
 415                                rtl_set_rfreg(hw, (enum radio_path)rfpath,
 416                                              currentcmd->para1,
 417                                              RFREG_OFFSET_MASK,
 418                                              rtlphy->rfreg_chnlval[rfpath]);
 419                        }
 420                        break;
 421                default:
 422                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 423                                 "switch case not processed\n");
 424                        break;
 425                }
 426
 427                break;
 428        } while (true);
 429
 430        (*delay) = currentcmd->msdelay;
 431        (*step)++;
 432        return false;
 433}
 434
 435static long rtl88e_pwr_idx_dbm(struct ieee80211_hw *hw,
 436                               enum wireless_mode wirelessmode,
 437                               u8 txpwridx)
 438{
 439        long offset;
 440        long pwrout_dbm;
 441
 442        switch (wirelessmode) {
 443        case WIRELESS_MODE_B:
 444                offset = -7;
 445                break;
 446        case WIRELESS_MODE_G:
 447        case WIRELESS_MODE_N_24G:
 448                offset = -8;
 449                break;
 450        default:
 451                offset = -8;
 452                break;
 453        }
 454        pwrout_dbm = txpwridx / 2 + offset;
 455        return pwrout_dbm;
 456}
 457
 458static void rtl88e_phy_set_io(struct ieee80211_hw *hw)
 459{
 460        struct rtl_priv *rtlpriv = rtl_priv(hw);
 461        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 462        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
 463
 464        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
 465                 "--->Cmd(%#x), set_io_inprogress(%d)\n",
 466                 rtlphy->current_io_type, rtlphy->set_io_inprogress);
 467        switch (rtlphy->current_io_type) {
 468        case IO_CMD_RESUME_DM_BY_SCAN:
 469                dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
 470                /*rtl92c_dm_write_dig(hw);*/
 471                rtl88e_phy_set_txpower_level(hw, rtlphy->current_channel);
 472                rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
 473                break;
 474        case IO_CMD_PAUSE_DM_BY_SCAN:
 475                rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
 476                dm_digtable->cur_igvalue = 0x17;
 477                rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
 478                break;
 479        default:
 480                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 481                         "switch case not processed\n");
 482                break;
 483        }
 484        rtlphy->set_io_inprogress = false;
 485        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
 486                 "(%#x)\n", rtlphy->current_io_type);
 487}
 488
 489u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
 490{
 491        struct rtl_priv *rtlpriv = rtl_priv(hw);
 492        u32 returnvalue, originalvalue, bitshift;
 493
 494        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 495                 "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask);
 496        originalvalue = rtl_read_dword(rtlpriv, regaddr);
 497        bitshift = cal_bit_shift(bitmask);
 498        returnvalue = (originalvalue & bitmask) >> bitshift;
 499
 500        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 501                 "BBR MASK = 0x%x Addr[0x%x]= 0x%x\n", bitmask,
 502                 regaddr, originalvalue);
 503
 504        return returnvalue;
 505}
 506
 507void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw,
 508                           u32 regaddr, u32 bitmask, u32 data)
 509{
 510        struct rtl_priv *rtlpriv = rtl_priv(hw);
 511        u32 originalvalue, bitshift;
 512
 513        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 514                 "regaddr(%#x), bitmask(%#x),data(%#x)\n",
 515                 regaddr, bitmask, data);
 516
 517        if (bitmask != MASKDWORD) {
 518                originalvalue = rtl_read_dword(rtlpriv, regaddr);
 519                bitshift = cal_bit_shift(bitmask);
 520                data = ((originalvalue & (~bitmask)) | (data << bitshift));
 521        }
 522
 523        rtl_write_dword(rtlpriv, regaddr, data);
 524
 525        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 526                 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
 527                 regaddr, bitmask, data);
 528}
 529
 530u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw,
 531                            enum radio_path rfpath, u32 regaddr, u32 bitmask)
 532{
 533        struct rtl_priv *rtlpriv = rtl_priv(hw);
 534        u32 original_value, readback_value, bitshift;
 535        unsigned long flags;
 536
 537        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 538                 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
 539                 regaddr, rfpath, bitmask);
 540
 541        spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
 542
 543
 544        original_value = rf_serial_read(hw, rfpath, regaddr);
 545        bitshift = cal_bit_shift(bitmask);
 546        readback_value = (original_value & bitmask) >> bitshift;
 547
 548        spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
 549
 550        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 551                 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
 552                  regaddr, rfpath, bitmask, original_value);
 553
 554        return readback_value;
 555}
 556
 557void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw,
 558                           enum radio_path rfpath,
 559                           u32 regaddr, u32 bitmask, u32 data)
 560{
 561        struct rtl_priv *rtlpriv = rtl_priv(hw);
 562        u32 original_value, bitshift;
 563        unsigned long flags;
 564
 565        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 566                 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 567                  regaddr, bitmask, data, rfpath);
 568
 569        spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
 570
 571        if (bitmask != RFREG_OFFSET_MASK) {
 572                        original_value = rf_serial_read(hw, rfpath, regaddr);
 573                        bitshift = cal_bit_shift(bitmask);
 574                        data = ((original_value & (~bitmask)) |
 575                                (data << bitshift));
 576                }
 577
 578        rf_serial_write(hw, rfpath, regaddr, data);
 579
 580
 581        spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
 582
 583        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 584                 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 585                 regaddr, bitmask, data, rfpath);
 586}
 587
 588static bool config_mac_with_header(struct ieee80211_hw *hw)
 589{
 590        struct rtl_priv *rtlpriv = rtl_priv(hw);
 591        u32 i;
 592        u32 arraylength;
 593        u32 *ptrarray;
 594
 595        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl8188EMACPHY_Array\n");
 596        arraylength = RTL8188EEMAC_1T_ARRAYLEN;
 597        ptrarray = RTL8188EEMAC_1T_ARRAY;
 598        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 599                 "Img:RTL8188EEMAC_1T_ARRAY LEN %d\n", arraylength);
 600        for (i = 0; i < arraylength; i = i + 2)
 601                rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
 602        return true;
 603}
 604
 605bool rtl88e_phy_mac_config(struct ieee80211_hw *hw)
 606{
 607        struct rtl_priv *rtlpriv = rtl_priv(hw);
 608        bool rtstatus = config_mac_with_header(hw);
 609
 610        rtl_write_byte(rtlpriv, 0x04CA, 0x0B);
 611        return rtstatus;
 612}
 613
 614bool rtl88e_phy_bb_config(struct ieee80211_hw *hw)
 615{
 616        bool rtstatus = true;
 617        struct rtl_priv *rtlpriv = rtl_priv(hw);
 618        u16 regval;
 619        u8 reg_hwparafile = 1;
 620        u32 tmp;
 621        rtl88e_phy_init_bb_rf_register_definition(hw);
 622        regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
 623        rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
 624                       regval | BIT(13) | BIT(0) | BIT(1));
 625
 626        rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
 627        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
 628                       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
 629                       FEN_BB_GLB_RSTN | FEN_BBRSTB);
 630        tmp = rtl_read_dword(rtlpriv, 0x4c);
 631        rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
 632        if (reg_hwparafile == 1)
 633                rtstatus = config_parafile(hw);
 634        return rtstatus;
 635}
 636
 637bool rtl88e_phy_rf_config(struct ieee80211_hw *hw)
 638{
 639        return rtl88e_phy_rf6052_config(hw);
 640}
 641
 642static bool check_cond(struct ieee80211_hw *hw,
 643                                    const u32  condition)
 644{
 645        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 646        struct rtl_efuse *fuse = rtl_efuse(rtl_priv(hw));
 647        u32 _board = fuse->board_type; /*need efuse define*/
 648        u32 _interface = rtlhal->interface;
 649        u32 _platform = 0x08;/*SupportPlatform */
 650        u32 cond = condition;
 651
 652        if (condition == 0xCDCDCDCD)
 653                return true;
 654
 655        cond = condition & 0xFF;
 656        if ((_board & cond) == 0 && cond != 0x1F)
 657                return false;
 658
 659        cond = condition & 0xFF00;
 660        cond = cond >> 8;
 661        if ((_interface & cond) == 0 && cond != 0x07)
 662                return false;
 663
 664        cond = condition & 0xFF0000;
 665        cond = cond >> 16;
 666        if ((_platform & cond) == 0 && cond != 0x0F)
 667                return false;
 668        return true;
 669}
 670
 671static void _rtl8188e_config_rf_reg(struct ieee80211_hw *hw,
 672                                    u32 addr, u32 data, enum radio_path rfpath,
 673                                    u32 regaddr)
 674{
 675        if (addr == 0xffe) {
 676                mdelay(50);
 677        } else if (addr == 0xfd) {
 678                mdelay(5);
 679        } else if (addr == 0xfc) {
 680                mdelay(1);
 681        } else if (addr == 0xfb) {
 682                udelay(50);
 683        } else if (addr == 0xfa) {
 684                udelay(5);
 685        } else if (addr == 0xf9) {
 686                udelay(1);
 687        } else {
 688                rtl_set_rfreg(hw, rfpath, regaddr,
 689                              RFREG_OFFSET_MASK,
 690                              data);
 691                udelay(1);
 692        }
 693}
 694
 695static void rtl88_config_s(struct ieee80211_hw *hw,
 696        u32 addr, u32 data)
 697{
 698        u32 content = 0x1000; /*RF Content: radio_a_txt*/
 699        u32 maskforphyset = (u32)(content & 0xE000);
 700
 701        _rtl8188e_config_rf_reg(hw, addr, data, RF90_PATH_A,
 702                                addr | maskforphyset);
 703}
 704
 705static void _rtl8188e_config_bb_reg(struct ieee80211_hw *hw,
 706                                    u32 addr, u32 data)
 707{
 708        if (addr == 0xfe) {
 709                mdelay(50);
 710        } else if (addr == 0xfd) {
 711                mdelay(5);
 712        } else if (addr == 0xfc) {
 713                mdelay(1);
 714        } else if (addr == 0xfb) {
 715                udelay(50);
 716        } else if (addr == 0xfa) {
 717                udelay(5);
 718        } else if (addr == 0xf9) {
 719                udelay(1);
 720        } else {
 721                rtl_set_bbreg(hw, addr, MASKDWORD, data);
 722                udelay(1);
 723        }
 724}
 725
 726
 727#define NEXT_PAIR(v1, v2, i)                            \
 728        do {                                            \
 729                i += 2; v1 = array_table[i];            \
 730                v2 = array_table[i + 1];                \
 731        } while (0)
 732
 733static void set_baseband_agc_config(struct ieee80211_hw *hw)
 734{
 735        int i;
 736        u32 *array_table;
 737        u16 arraylen;
 738        struct rtl_priv *rtlpriv = rtl_priv(hw);
 739        u32 v1 = 0, v2 = 0;
 740
 741        arraylen = RTL8188EEAGCTAB_1TARRAYLEN;
 742        array_table = RTL8188EEAGCTAB_1TARRAY;
 743
 744        for (i = 0; i < arraylen; i += 2) {
 745                v1 = array_table[i];
 746                v2 = array_table[i + 1];
 747                if (v1 < 0xCDCDCDCD) {
 748                        rtl_set_bbreg(hw, array_table[i], MASKDWORD,
 749                                      array_table[i + 1]);
 750                        udelay(1);
 751                        continue;
 752                } else {/*This line is the start line of branch.*/
 753                        if (!check_cond(hw, array_table[i])) {
 754                                /*Discard the following (offset, data) pairs*/
 755                                NEXT_PAIR(v1, v2, i);
 756                                while (v2 != 0xDEAD && v2 != 0xCDEF &&
 757                                       v2 != 0xCDCD && i < arraylen - 2) {
 758                                        NEXT_PAIR(v1, v2, i);
 759                                }
 760                                i -= 2; /* compensate for loop's += 2*/
 761                        } else {
 762                                /* Configure matched pairs and skip to end */
 763                                NEXT_PAIR(v1, v2, i);
 764                                while (v2 != 0xDEAD && v2 != 0xCDEF &&
 765                                       v2 != 0xCDCD && i < arraylen - 2) {
 766                                        rtl_set_bbreg(hw, array_table[i],
 767                                                      MASKDWORD,
 768                                                      array_table[i + 1]);
 769                                        udelay(1);
 770                                        NEXT_PAIR(v1, v2, i);
 771                                }
 772
 773                                while (v2 != 0xDEAD && i < arraylen - 2)
 774                                        NEXT_PAIR(v1, v2, i);
 775                        }
 776                }
 777                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 778                         "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
 779                         array_table[i],
 780                         array_table[i + 1]);
 781        }
 782}
 783
 784static void set_baseband_phy_config(struct ieee80211_hw *hw)
 785{
 786        int i;
 787        u32 *array_table;
 788        u16 arraylen;
 789        u32 v1 = 0, v2 = 0;
 790
 791        arraylen = RTL8188EEPHY_REG_1TARRAYLEN;
 792        array_table = RTL8188EEPHY_REG_1TARRAY;
 793
 794        for (i = 0; i < arraylen; i += 2) {
 795                v1 = array_table[i];
 796                v2 = array_table[i + 1];
 797                if (v1 < 0xcdcdcdcd) {
 798                        _rtl8188e_config_bb_reg(hw, v1, v2);
 799                } else {/*This line is the start line of branch.*/
 800                        if (!check_cond(hw, array_table[i])) {
 801                                /*Discard the following (offset, data) pairs*/
 802                                NEXT_PAIR(v1, v2, i);
 803                                while (v2 != 0xDEAD &&
 804                                       v2 != 0xCDEF &&
 805                                       v2 != 0xCDCD && i < arraylen - 2)
 806                                        NEXT_PAIR(v1, v2, i);
 807                                i -= 2; /* prevent from for-loop += 2*/
 808                        } else {
 809                                /* Configure matched pairs and skip to end */
 810                                NEXT_PAIR(v1, v2, i);
 811                                while (v2 != 0xDEAD &&
 812                                       v2 != 0xCDEF &&
 813                                       v2 != 0xCDCD && i < arraylen - 2) {
 814                                        _rtl8188e_config_bb_reg(hw, v1, v2);
 815                                        NEXT_PAIR(v1, v2, i);
 816                                }
 817
 818                                while (v2 != 0xDEAD && i < arraylen - 2)
 819                                        NEXT_PAIR(v1, v2, i);
 820                        }
 821                }
 822        }
 823}
 824
 825static void store_pwrindex_offset(struct ieee80211_hw *hw,
 826                                  u32 regaddr, u32 bitmask,
 827                                  u32 data)
 828{
 829        struct rtl_priv *rtlpriv = rtl_priv(hw);
 830        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 831
 832        if (regaddr == RTXAGC_A_RATE18_06) {
 833                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0] = data;
 834                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 835                         "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
 836                         rtlphy->pwrgroup_cnt,
 837                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0]);
 838        }
 839        if (regaddr == RTXAGC_A_RATE54_24) {
 840                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1] = data;
 841                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 842                         "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
 843                         rtlphy->pwrgroup_cnt,
 844                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1]);
 845        }
 846        if (regaddr == RTXAGC_A_CCK1_MCS32) {
 847                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6] = data;
 848                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 849                         "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
 850                         rtlphy->pwrgroup_cnt,
 851                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6]);
 852        }
 853        if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
 854                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7] = data;
 855                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 856                         "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
 857                         rtlphy->pwrgroup_cnt,
 858                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7]);
 859        }
 860        if (regaddr == RTXAGC_A_MCS03_MCS00) {
 861                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2] = data;
 862                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 863                         "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
 864                         rtlphy->pwrgroup_cnt,
 865                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2]);
 866        }
 867        if (regaddr == RTXAGC_A_MCS07_MCS04) {
 868                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3] = data;
 869                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 870                         "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
 871                         rtlphy->pwrgroup_cnt,
 872                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3]);
 873        }
 874        if (regaddr == RTXAGC_A_MCS11_MCS08) {
 875                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4] = data;
 876                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 877                         "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
 878                         rtlphy->pwrgroup_cnt,
 879                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4]);
 880        }
 881        if (regaddr == RTXAGC_A_MCS15_MCS12) {
 882                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5] = data;
 883                if (get_rf_type(rtlphy) == RF_1T1R)
 884                        rtlphy->pwrgroup_cnt++;
 885                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 886                         "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
 887                         rtlphy->pwrgroup_cnt,
 888                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5]);
 889        }
 890        if (regaddr == RTXAGC_B_RATE18_06) {
 891                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8] = data;
 892                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 893                         "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
 894                         rtlphy->pwrgroup_cnt,
 895                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8]);
 896        }
 897        if (regaddr == RTXAGC_B_RATE54_24) {
 898                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9] = data;
 899                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 900                         "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
 901                         rtlphy->pwrgroup_cnt,
 902                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9]);
 903        }
 904        if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
 905                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14] = data;
 906                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 907                         "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
 908                         rtlphy->pwrgroup_cnt,
 909                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14]);
 910        }
 911        if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
 912                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15] = data;
 913                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 914                         "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
 915                         rtlphy->pwrgroup_cnt,
 916                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15]);
 917        }
 918        if (regaddr == RTXAGC_B_MCS03_MCS00) {
 919                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10] = data;
 920                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 921                         "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
 922                         rtlphy->pwrgroup_cnt,
 923                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10]);
 924        }
 925        if (regaddr == RTXAGC_B_MCS07_MCS04) {
 926                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11] = data;
 927                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 928                         "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
 929                         rtlphy->pwrgroup_cnt,
 930                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11]);
 931        }
 932        if (regaddr == RTXAGC_B_MCS11_MCS08) {
 933                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12] = data;
 934                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 935                         "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
 936                         rtlphy->pwrgroup_cnt,
 937                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12]);
 938        }
 939        if (regaddr == RTXAGC_B_MCS15_MCS12) {
 940                rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13] = data;
 941                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 942                         "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
 943                         rtlphy->pwrgroup_cnt,
 944                         rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13]);
 945                if (get_rf_type(rtlphy) != RF_1T1R)
 946                        rtlphy->pwrgroup_cnt++;
 947        }
 948}
 949
 950#define READ_NEXT_RF_PAIR(v1, v2, i)            \
 951        do {                                    \
 952                i += 2; v1 = a_table[i];        \
 953                v2 = a_table[i + 1];            \
 954        } while (0)
 955
 956bool rtl88e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 957                                          enum radio_path rfpath)
 958{
 959        int i;
 960        u32 *a_table;
 961        u16 a_len;
 962        struct rtl_priv *rtlpriv = rtl_priv(hw);
 963        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 964        u32 v1 = 0, v2 = 0;
 965
 966        a_len = RTL8188EE_RADIOA_1TARRAYLEN;
 967        a_table = RTL8188EE_RADIOA_1TARRAY;
 968        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 969                 "Radio_A:RTL8188EE_RADIOA_1TARRAY %d\n", a_len);
 970        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
 971        switch (rfpath) {
 972        case RF90_PATH_A:
 973                for (i = 0; i < a_len; i = i + 2) {
 974                        v1 = a_table[i];
 975                        v2 = a_table[i + 1];
 976                        if (v1 < 0xcdcdcdcd) {
 977                                rtl88_config_s(hw, v1, v2);
 978                        } else {/*This line is the start line of branch.*/
 979                                if (!check_cond(hw, a_table[i])) {
 980                                        /* Discard the following (offset, data)
 981                                         * pairs
 982                                         */
 983                                        READ_NEXT_RF_PAIR(v1, v2, i);
 984                                        while (v2 != 0xDEAD && v2 != 0xCDEF &&
 985                                               v2 != 0xCDCD && i < a_len - 2)
 986                                                READ_NEXT_RF_PAIR(v1, v2, i);
 987                                        i -= 2; /* prevent from for-loop += 2*/
 988                                } else {
 989                                        /* Configure matched pairs and skip to
 990                                         * end of if-else.
 991                                         */
 992                                        READ_NEXT_RF_PAIR(v1, v2, i);
 993                                        while (v2 != 0xDEAD && v2 != 0xCDEF &&
 994                                               v2 != 0xCDCD && i < a_len - 2) {
 995                                                rtl88_config_s(hw, v1, v2);
 996                                                READ_NEXT_RF_PAIR(v1, v2, i);
 997                                        }
 998
 999                                        while (v2 != 0xDEAD && i < a_len - 2)
1000                                                READ_NEXT_RF_PAIR(v1, v2, i);
1001                                }
1002                        }
1003                }
1004
1005                if (rtlhal->oem_id == RT_CID_819x_HP)
1006                        rtl88_config_s(hw, 0x52, 0x7E4BD);
1007
1008                break;
1009
1010        case RF90_PATH_B:
1011        case RF90_PATH_C:
1012        case RF90_PATH_D:
1013        default:
1014                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1015                         "switch case not processed\n");
1016                break;
1017        }
1018        return true;
1019}
1020
1021void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
1022{
1023        struct rtl_priv *rtlpriv = rtl_priv(hw);
1024        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1025
1026        rtlphy->default_initialgain[0] = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1,
1027                                                       MASKBYTE0);
1028        rtlphy->default_initialgain[1] = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1,
1029                                                       MASKBYTE0);
1030        rtlphy->default_initialgain[2] = rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1,
1031                                                       MASKBYTE0);
1032        rtlphy->default_initialgain[3] = rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1,
1033                                                       MASKBYTE0);
1034
1035        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1036                 "Default initial gain (c50 = 0x%x, c58 = 0x%x, c60 = 0x%x, c68 = 0x%x\n",
1037                  rtlphy->default_initialgain[0],
1038                  rtlphy->default_initialgain[1],
1039                  rtlphy->default_initialgain[2],
1040                  rtlphy->default_initialgain[3]);
1041
1042        rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
1043                                          MASKBYTE0);
1044        rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
1045                                              MASKDWORD);
1046
1047        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1048                 "Default framesync (0x%x) = 0x%x\n",
1049                 ROFDM0_RXDETECTOR3, rtlphy->framesync);
1050}
1051
1052void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
1053{
1054        struct rtl_priv *rtlpriv = rtl_priv(hw);
1055        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1056        u8 level;
1057        long dbm;
1058
1059        level = rtlphy->cur_cck_txpwridx;
1060        dbm = rtl88e_pwr_idx_dbm(hw, WIRELESS_MODE_B, level);
1061        level = rtlphy->cur_ofdm24g_txpwridx;
1062        if (rtl88e_pwr_idx_dbm(hw, WIRELESS_MODE_G, level) > dbm)
1063                dbm = rtl88e_pwr_idx_dbm(hw, WIRELESS_MODE_G, level);
1064        level = rtlphy->cur_ofdm24g_txpwridx;
1065        if (rtl88e_pwr_idx_dbm(hw, WIRELESS_MODE_N_24G, level) > dbm)
1066                dbm = rtl88e_pwr_idx_dbm(hw, WIRELESS_MODE_N_24G, level);
1067        *powerlevel = dbm;
1068}
1069
1070static void _rtl88e_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
1071                                      u8 *cckpower, u8 *ofdm, u8 *bw20_pwr,
1072                                      u8 *bw40_pwr)
1073{
1074        struct rtl_efuse *fuse = rtl_efuse(rtl_priv(hw));
1075        u8 i = (channel - 1);
1076        u8 rf_path = 0;
1077        int jj = RF90_PATH_A;
1078        int kk = RF90_PATH_B;
1079
1080        for (rf_path = 0; rf_path < 2; rf_path++) {
1081                if (rf_path == jj) {
1082                        cckpower[jj] = fuse->txpwrlevel_cck[jj][i];
1083                        if (fuse->txpwr_ht20diff[jj][i] > 0x0f) /*-8~7 */
1084                                bw20_pwr[jj] = fuse->txpwrlevel_ht40_1s[jj][i] -
1085                                        (~(fuse->txpwr_ht20diff[jj][i]) + 1);
1086                        else
1087                                bw20_pwr[jj] = fuse->txpwrlevel_ht40_1s[jj][i] +
1088                                         fuse->txpwr_ht20diff[jj][i];
1089                        if (fuse->txpwr_legacyhtdiff[jj][i] > 0xf)
1090                                ofdm[jj] = fuse->txpwrlevel_ht40_1s[jj][i] -
1091                                        (~(fuse->txpwr_legacyhtdiff[jj][i])+1);
1092                        else
1093                                ofdm[jj] = fuse->txpwrlevel_ht40_1s[jj][i] +
1094                                           fuse->txpwr_legacyhtdiff[jj][i];
1095                        bw40_pwr[jj] = fuse->txpwrlevel_ht40_1s[jj][i];
1096
1097                } else if (rf_path == kk) {
1098                        cckpower[kk] = fuse->txpwrlevel_cck[kk][i];
1099                        bw20_pwr[kk] = fuse->txpwrlevel_ht40_1s[kk][i] +
1100                                       fuse->txpwr_ht20diff[kk][i];
1101                        ofdm[kk] = fuse->txpwrlevel_ht40_1s[kk][i] +
1102                                        fuse->txpwr_legacyhtdiff[kk][i];
1103                        bw40_pwr[kk] = fuse->txpwrlevel_ht40_1s[kk][i];
1104                }
1105        }
1106}
1107
1108static void _rtl88e_ccxpower_index_check(struct ieee80211_hw *hw,
1109                                         u8 channel, u8 *cckpower,
1110                                         u8 *ofdm, u8 *bw20_pwr,
1111                                         u8 *bw40_pwr)
1112{
1113        struct rtl_priv *rtlpriv = rtl_priv(hw);
1114        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1115
1116        rtlphy->cur_cck_txpwridx = cckpower[0];
1117        rtlphy->cur_ofdm24g_txpwridx = ofdm[0];
1118        rtlphy->cur_bw20_txpwridx = bw20_pwr[0];
1119        rtlphy->cur_bw40_txpwridx = bw40_pwr[0];
1120}
1121
1122void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1123{
1124        struct rtl_efuse *fuse = rtl_efuse(rtl_priv(hw));
1125        u8 cckpower[MAX_TX_COUNT]  = {0}, ofdm[MAX_TX_COUNT] = {0};
1126        u8 bw20_pwr[MAX_TX_COUNT] = {0}, bw40_pwr[MAX_TX_COUNT] = {0};
1127
1128        if (fuse->txpwr_fromeprom == false)
1129                return;
1130        _rtl88e_get_txpower_index(hw, channel, &cckpower[0], &ofdm[0],
1131                                  &bw20_pwr[0], &bw40_pwr[0]);
1132        _rtl88e_ccxpower_index_check(hw, channel, &cckpower[0], &ofdm[0],
1133                                     &bw20_pwr[0], &bw40_pwr[0]);
1134        rtl88e_phy_rf6052_set_cck_txpower(hw, &cckpower[0]);
1135        rtl88e_phy_rf6052_set_ofdm_txpower(hw, &ofdm[0], &bw20_pwr[0],
1136                                           &bw40_pwr[0], channel);
1137}
1138
1139void rtl88e_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1140{
1141        struct rtl_priv *rtlpriv = rtl_priv(hw);
1142        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1143        enum io_type iotype;
1144
1145        if (!is_hal_stop(rtlhal)) {
1146                switch (operation) {
1147                case SCAN_OPT_BACKUP:
1148                        iotype = IO_CMD_PAUSE_DM_BY_SCAN;
1149                        rtlpriv->cfg->ops->set_hw_reg(hw,
1150                                                      HW_VAR_IO_CMD,
1151                                                      (u8 *)&iotype);
1152                        break;
1153                case SCAN_OPT_RESTORE:
1154                        iotype = IO_CMD_RESUME_DM_BY_SCAN;
1155                        rtlpriv->cfg->ops->set_hw_reg(hw,
1156                                                      HW_VAR_IO_CMD,
1157                                                      (u8 *)&iotype);
1158                        break;
1159                default:
1160                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1161                                 "Unknown Scan Backup operation.\n");
1162                        break;
1163                }
1164        }
1165}
1166
1167void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1168{
1169        struct rtl_priv *rtlpriv = rtl_priv(hw);
1170        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1171        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1172        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1173        u8 reg_bw_opmode;
1174        u8 reg_prsr_rsc;
1175
1176        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1177                 "Switch to %s bandwidth\n",
1178                 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1179                 "20MHz" : "40MHz");
1180
1181        if (is_hal_stop(rtlhal)) {
1182                rtlphy->set_bwmode_inprogress = false;
1183                return;
1184        }
1185
1186        reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1187        reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1188
1189        switch (rtlphy->current_chan_bw) {
1190        case HT_CHANNEL_WIDTH_20:
1191                reg_bw_opmode |= BW_OPMODE_20MHZ;
1192                rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1193                break;
1194        case HT_CHANNEL_WIDTH_20_40:
1195                reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1196                rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1197                reg_prsr_rsc =
1198                    (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
1199                rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1200                break;
1201        default:
1202                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1203                         "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1204                break;
1205        }
1206
1207        switch (rtlphy->current_chan_bw) {
1208        case HT_CHANNEL_WIDTH_20:
1209                rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1210                rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1211        /*      rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/
1212                break;
1213        case HT_CHANNEL_WIDTH_20_40:
1214                rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1215                rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1216
1217                rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1218                              (mac->cur_40_prime_sc >> 1));
1219                rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1220                /*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/
1221
1222                rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1223                              (mac->cur_40_prime_sc ==
1224                               HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1225                break;
1226        default:
1227                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1228                         "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1229                break;
1230        }
1231        rtl88e_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1232        rtlphy->set_bwmode_inprogress = false;
1233        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1234}
1235
1236void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw,
1237                            enum nl80211_channel_type ch_type)
1238{
1239        struct rtl_priv *rtlpriv = rtl_priv(hw);
1240        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1241        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1242        u8 tmp_bw = rtlphy->current_chan_bw;
1243
1244        if (rtlphy->set_bwmode_inprogress)
1245                return;
1246        rtlphy->set_bwmode_inprogress = true;
1247        if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1248                rtl88e_phy_set_bw_mode_callback(hw);
1249        } else {
1250                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1251                         "FALSE driver sleep or unload\n");
1252                rtlphy->set_bwmode_inprogress = false;
1253                rtlphy->current_chan_bw = tmp_bw;
1254        }
1255}
1256
1257void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1258{
1259        struct rtl_priv *rtlpriv = rtl_priv(hw);
1260        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1261        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1262        u32 delay;
1263
1264        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1265                 "switch to channel%d\n", rtlphy->current_channel);
1266        if (is_hal_stop(rtlhal))
1267                return;
1268        do {
1269                if (!rtlphy->sw_chnl_inprogress)
1270                        break;
1271                if (!chnl_step_by_step(hw, rtlphy->current_channel,
1272                                       &rtlphy->sw_chnl_stage,
1273                                       &rtlphy->sw_chnl_step, &delay)) {
1274                        if (delay > 0)
1275                                mdelay(delay);
1276                        else
1277                                continue;
1278                } else {
1279                        rtlphy->sw_chnl_inprogress = false;
1280                }
1281                break;
1282        } while (true);
1283        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1284}
1285
1286u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw)
1287{
1288        struct rtl_priv *rtlpriv = rtl_priv(hw);
1289        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1290        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1291
1292        if (rtlphy->sw_chnl_inprogress)
1293                return 0;
1294        if (rtlphy->set_bwmode_inprogress)
1295                return 0;
1296        RT_ASSERT((rtlphy->current_channel <= 14),
1297                  "WIRELESS_MODE_G but channel>14");
1298        rtlphy->sw_chnl_inprogress = true;
1299        rtlphy->sw_chnl_stage = 0;
1300        rtlphy->sw_chnl_step = 0;
1301        if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1302                rtl88e_phy_sw_chnl_callback(hw);
1303                RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1304                         "sw_chnl_inprogress false schdule workitem current channel %d\n",
1305                         rtlphy->current_channel);
1306                rtlphy->sw_chnl_inprogress = false;
1307        } else {
1308                RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1309                         "sw_chnl_inprogress false driver sleep or unload\n");
1310                rtlphy->sw_chnl_inprogress = false;
1311        }
1312        return 1;
1313}
1314
1315static u8 _rtl88e_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1316{
1317        u32 reg_eac, reg_e94, reg_e9c;
1318        u8 result = 0x00;
1319
1320        rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1c);
1321        rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x30008c1c);
1322        rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x8214032a);
1323        rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160000);
1324
1325        rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);
1326        rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1327        rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1328
1329        mdelay(IQK_DELAY_TIME);
1330
1331        reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1332        reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1333        reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1334
1335        if (!(reg_eac & BIT(28)) &&
1336            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1337            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1338                result |= 0x01;
1339        return result;
1340}
1341
1342static u8 _rtl88e_phy_path_b_iqk(struct ieee80211_hw *hw)
1343{
1344        u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
1345        u8 result = 0x00;
1346
1347        rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
1348        rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
1349        mdelay(IQK_DELAY_TIME);
1350        reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1351        reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
1352        reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
1353        reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
1354        reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
1355
1356        if (!(reg_eac & BIT(31)) &&
1357            (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
1358            (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
1359                result |= 0x01;
1360        else
1361                return result;
1362        if (!(reg_eac & BIT(30)) &&
1363            (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
1364            (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
1365                result |= 0x02;
1366        return result;
1367}
1368
1369static u8 _rtl88e_phy_path_a_rx_iqk(struct ieee80211_hw *hw, bool config_pathb)
1370{
1371        u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32temp;
1372        u8 result = 0x00;
1373        int jj = RF90_PATH_A;
1374
1375        /*Get TXIMR Setting*/
1376        /*Modify RX IQK mode table*/
1377        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1378        rtl_set_rfreg(hw, jj, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1379        rtl_set_rfreg(hw, jj, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1380        rtl_set_rfreg(hw, jj, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
1381        rtl_set_rfreg(hw, jj, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b);
1382        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1383
1384        /*IQK Setting*/
1385        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1386        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x81004800);
1387
1388        /*path a IQK setting*/
1389        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x10008c1c);
1390        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x30008c1c);
1391        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160804);
1392        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000);
1393
1394        /*LO calibration Setting*/
1395        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1396        /*one shot, path A LOK & iqk*/
1397        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1398        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1399
1400        mdelay(IQK_DELAY_TIME);
1401
1402        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1403        reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1404        reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1405
1406
1407        if (!(reg_eac & BIT(28)) &&
1408            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1409            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1410                result |= 0x01;
1411        else
1412                return result;
1413
1414        u32temp = 0x80007C00 | (reg_e94&0x3FF0000)  |
1415                  ((reg_e9c&0x3FF0000) >> 16);
1416        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp);
1417        /*RX IQK*/
1418        /*Modify RX IQK mode table*/
1419        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1420        rtl_set_rfreg(hw, jj, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1421        rtl_set_rfreg(hw, jj, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1422        rtl_set_rfreg(hw, jj, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
1423        rtl_set_rfreg(hw, jj, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa);
1424        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1425
1426        /*IQK Setting*/
1427        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1428
1429        /*path a IQK setting*/
1430        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x30008c1c);
1431        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x10008c1c);
1432        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c05);
1433        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160c05);
1434
1435        /*LO calibration Setting*/
1436        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1437        /*one shot, path A LOK & iqk*/
1438        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1439        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1440
1441        mdelay(IQK_DELAY_TIME);
1442
1443        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1444        reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1445        reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1446        reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1447
1448        if (!(reg_eac & BIT(27)) &&
1449            (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1450            (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1451                result |= 0x02;
1452        return result;
1453}
1454
1455static void fill_iqk(struct ieee80211_hw *hw, bool iqk_ok, long result[][8],
1456                     u8 final, bool btxonly)
1457{
1458        u32 oldval_0, x, tx0_a, reg;
1459        long y, tx0_c;
1460
1461        if (final == 0xFF) {
1462                return;
1463        } else if (iqk_ok) {
1464                oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBAL,
1465                                          MASKDWORD) >> 22) & 0x3FF;
1466                x = result[final][0];
1467                if ((x & 0x00000200) != 0)
1468                        x = x | 0xFFFFFC00;
1469                tx0_a = (x * oldval_0) >> 8;
1470                rtl_set_bbreg(hw, ROFDM0_XATXIQIMBAL, 0x3FF, tx0_a);
1471                rtl_set_bbreg(hw, ROFDM0_ECCATHRES, BIT(31),
1472                              ((x * oldval_0 >> 7) & 0x1));
1473                y = result[final][1];
1474                if ((y & 0x00000200) != 0)
1475                        y |= 0xFFFFFC00;
1476                tx0_c = (y * oldval_0) >> 8;
1477                rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
1478                              ((tx0_c & 0x3C0) >> 6));
1479                rtl_set_bbreg(hw, ROFDM0_XATXIQIMBAL, 0x003F0000,
1480                              (tx0_c & 0x3F));
1481                rtl_set_bbreg(hw, ROFDM0_ECCATHRES, BIT(29),
1482                              ((y * oldval_0 >> 7) & 0x1));
1483                if (btxonly)
1484                        return;
1485                reg = result[final][2];
1486                rtl_set_bbreg(hw, ROFDM0_XARXIQIMBAL, 0x3FF, reg);
1487                reg = result[final][3] & 0x3F;
1488                rtl_set_bbreg(hw, ROFDM0_XARXIQIMBAL, 0xFC00, reg);
1489                reg = (result[final][3] >> 6) & 0xF;
1490                rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
1491        }
1492}
1493
1494static void save_adda_reg(struct ieee80211_hw *hw,
1495                          const u32 *addareg, u32 *backup,
1496                          u32 registernum)
1497{
1498        u32 i;
1499
1500        for (i = 0; i < registernum; i++)
1501                backup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
1502}
1503
1504static void save_mac_reg(struct ieee80211_hw *hw, const u32 *macreg,
1505                         u32 *macbackup)
1506{
1507        struct rtl_priv *rtlpriv = rtl_priv(hw);
1508        u32 i;
1509
1510        for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1511                macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
1512        macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
1513}
1514
1515static void reload_adda(struct ieee80211_hw *hw, const u32 *addareg,
1516                        u32 *backup, u32 reg_num)
1517{
1518        u32 i;
1519
1520        for (i = 0; i < reg_num; i++)
1521                rtl_set_bbreg(hw, addareg[i], MASKDWORD, backup[i]);
1522}
1523
1524static void reload_mac(struct ieee80211_hw *hw, const u32 *macreg,
1525                       u32 *macbackup)
1526{
1527        struct rtl_priv *rtlpriv = rtl_priv(hw);
1528        u32 i;
1529
1530        for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1531                rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
1532        rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
1533}
1534
1535static void _rtl88e_phy_path_adda_on(struct ieee80211_hw *hw,
1536                                     const u32 *addareg, bool is_patha_on,
1537                                     bool is2t)
1538{
1539        u32 pathon;
1540        u32 i;
1541
1542        pathon = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
1543        if (false == is2t) {
1544                pathon = 0x0bdb25a0;
1545                rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
1546        } else {
1547                rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon);
1548        }
1549
1550        for (i = 1; i < IQK_ADDA_REG_NUM; i++)
1551                rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon);
1552}
1553
1554static void _rtl88e_phy_mac_setting_calibration(struct ieee80211_hw *hw,
1555                                                const u32 *macreg,
1556                                                u32 *macbackup)
1557{
1558        struct rtl_priv *rtlpriv = rtl_priv(hw);
1559        u32 i = 0;
1560
1561        rtl_write_byte(rtlpriv, macreg[i], 0x3F);
1562
1563        for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
1564                rtl_write_byte(rtlpriv, macreg[i],
1565                               (u8) (macbackup[i] & (~BIT(3))));
1566        rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
1567}
1568
1569static void _rtl88e_phy_path_a_standby(struct ieee80211_hw *hw)
1570{
1571        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
1572        rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1573        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1574}
1575
1576static void _rtl88e_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
1577{
1578        u32 mode;
1579
1580        mode = pi_mode ? 0x01000100 : 0x01000000;
1581        rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
1582        rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
1583}
1584
1585static bool sim_comp(struct ieee80211_hw *hw, long result[][8], u8 c1, u8 c2)
1586{
1587        u32 i, j, diff, bitmap, bound;
1588        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1589
1590        u8 final[2] = {0xFF, 0xFF};
1591        bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
1592
1593        if (is2t)
1594                bound = 8;
1595        else
1596                bound = 4;
1597
1598        bitmap = 0;
1599
1600        for (i = 0; i < bound; i++) {
1601                diff = (result[c1][i] > result[c2][i]) ?
1602                       (result[c1][i] - result[c2][i]) :
1603                       (result[c2][i] - result[c1][i]);
1604
1605                if (diff > MAX_TOLERANCE) {
1606                        if ((i == 2 || i == 6) && !bitmap) {
1607                                if (result[c1][i] + result[c1][i + 1] == 0)
1608                                        final[(i / 4)] = c2;
1609                                else if (result[c2][i] + result[c2][i + 1] == 0)
1610                                        final[(i / 4)] = c1;
1611                                else
1612                                        bitmap = bitmap | (1 << i);
1613                        } else {
1614                                bitmap = bitmap | (1 << i);
1615                        }
1616                }
1617        }
1618
1619        if (bitmap == 0) {
1620                for (i = 0; i < (bound / 4); i++) {
1621                        if (final[i] != 0xFF) {
1622                                for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1623                                        result[3][j] = result[final[i]][j];
1624                                bresult = false;
1625                        }
1626                }
1627                return bresult;
1628        } else if (!(bitmap & 0x0F)) {
1629                for (i = 0; i < 4; i++)
1630                        result[3][i] = result[c1][i];
1631                return false;
1632        } else if (!(bitmap & 0xF0) && is2t) {
1633                for (i = 4; i < 8; i++)
1634                        result[3][i] = result[c1][i];
1635                return false;
1636        } else {
1637                return false;
1638        }
1639}
1640
1641static void _rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw,
1642                                     long result[][8], u8 t, bool is2t)
1643{
1644        struct rtl_priv *rtlpriv = rtl_priv(hw);
1645        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1646        u32 i;
1647        u8 patha_ok, pathb_ok;
1648        const u32 adda_reg[IQK_ADDA_REG_NUM] = {
1649                0x85c, 0xe6c, 0xe70, 0xe74,
1650                0xe78, 0xe7c, 0xe80, 0xe84,
1651                0xe88, 0xe8c, 0xed0, 0xed4,
1652                0xed8, 0xedc, 0xee0, 0xeec
1653        };
1654        const u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1655                0x522, 0x550, 0x551, 0x040
1656        };
1657        const u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
1658                ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR, RFPGA0_XCD_RFINTERFACESW,
1659                0xb68, 0xb6c, 0x870, 0x860, 0x864, 0x800
1660        };
1661        const u32 retrycount = 2;
1662
1663        if (t == 0) {
1664                save_adda_reg(hw, adda_reg, rtlphy->adda_backup, 16);
1665                save_mac_reg(hw, iqk_mac_reg, rtlphy->iqk_mac_backup);
1666                save_adda_reg(hw, iqk_bb_reg, rtlphy->iqk_bb_backup,
1667                              IQK_BB_REG_NUM);
1668        }
1669        _rtl88e_phy_path_adda_on(hw, adda_reg, true, is2t);
1670        if (t == 0) {
1671                rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1672                                           RFPGA0_XA_HSSIPARAMETER1, BIT(8));
1673        }
1674
1675        if (!rtlphy->rfpi_enable)
1676                _rtl88e_phy_pi_mode_switch(hw, true);
1677        /*BB Setting*/
1678        rtl_set_bbreg(hw, 0x800, BIT(24), 0x00);
1679        rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1680        rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1681        rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1682
1683        rtl_set_bbreg(hw, 0x870, BIT(10), 0x01);
1684        rtl_set_bbreg(hw, 0x870, BIT(26), 0x01);
1685        rtl_set_bbreg(hw, 0x860, BIT(10), 0x00);
1686        rtl_set_bbreg(hw, 0x864, BIT(10), 0x00);
1687
1688        if (is2t) {
1689                rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1690                rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1691        }
1692        _rtl88e_phy_mac_setting_calibration(hw, iqk_mac_reg,
1693                                            rtlphy->iqk_mac_backup);
1694        rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000);
1695        if (is2t)
1696                rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x0f600000);
1697
1698        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1699        rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1700        rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x81004800);
1701        for (i = 0; i < retrycount; i++) {
1702                patha_ok = _rtl88e_phy_path_a_iqk(hw, is2t);
1703                if (patha_ok == 0x01) {
1704                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1705                                 "Path A Tx IQK Success!!\n");
1706                        result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1707                                        0x3FF0000) >> 16;
1708                        result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1709                                        0x3FF0000) >> 16;
1710                        break;
1711                }
1712        }
1713
1714        for (i = 0; i < retrycount; i++) {
1715                patha_ok = _rtl88e_phy_path_a_rx_iqk(hw, is2t);
1716                if (patha_ok == 0x03) {
1717                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1718                                 "Path A Rx IQK Success!!\n");
1719                        result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1720                                        0x3FF0000) >> 16;
1721                        result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1722                                        0x3FF0000) >> 16;
1723                        break;
1724                } else {
1725                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1726                                 "Path a RX iqk fail!!!\n");
1727                }
1728        }
1729
1730        if (0 == patha_ok) {
1731                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1732                         "Path A IQK Success!!\n");
1733        }
1734        if (is2t) {
1735                _rtl88e_phy_path_a_standby(hw);
1736                _rtl88e_phy_path_adda_on(hw, adda_reg, false, is2t);
1737                for (i = 0; i < retrycount; i++) {
1738                        pathb_ok = _rtl88e_phy_path_b_iqk(hw);
1739                        if (pathb_ok == 0x03) {
1740                                result[t][4] = (rtl_get_bbreg(hw,
1741                                                0xeb4, MASKDWORD) &
1742                                                0x3FF0000) >> 16;
1743                                result[t][5] =
1744                                    (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1745                                                   0x3FF0000) >> 16;
1746                                result[t][6] =
1747                                    (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1748                                                   0x3FF0000) >> 16;
1749                                result[t][7] =
1750                                    (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1751                                                   0x3FF0000) >> 16;
1752                                break;
1753                        } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1754                                result[t][4] = (rtl_get_bbreg(hw,
1755                                                0xeb4, MASKDWORD) &
1756                                                0x3FF0000) >> 16;
1757                        }
1758                        result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1759                                        0x3FF0000) >> 16;
1760                }
1761        }
1762
1763        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1764
1765        if (t != 0) {
1766                if (!rtlphy->rfpi_enable)
1767                        _rtl88e_phy_pi_mode_switch(hw, false);
1768                reload_adda(hw, adda_reg, rtlphy->adda_backup, 16);
1769                reload_mac(hw, iqk_mac_reg, rtlphy->iqk_mac_backup);
1770                reload_adda(hw, iqk_bb_reg, rtlphy->iqk_bb_backup,
1771                            IQK_BB_REG_NUM);
1772
1773                rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1774                if (is2t)
1775                        rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1776                rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
1777                rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
1778        }
1779        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "88ee IQK Finish!!\n");
1780}
1781
1782static void _rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1783{
1784        u8 tmpreg;
1785        u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1786        struct rtl_priv *rtlpriv = rtl_priv(hw);
1787        int jj = RF90_PATH_A;
1788        int kk = RF90_PATH_B;
1789
1790        tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1791
1792        if ((tmpreg & 0x70) != 0)
1793                rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1794        else
1795                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1796
1797        if ((tmpreg & 0x70) != 0) {
1798                rf_a_mode = rtl_get_rfreg(hw, jj, 0x00, MASK12BITS);
1799
1800                if (is2t)
1801                        rf_b_mode = rtl_get_rfreg(hw, kk, 0x00,
1802                                                  MASK12BITS);
1803
1804                rtl_set_rfreg(hw, jj, 0x00, MASK12BITS,
1805                              (rf_a_mode & 0x8FFFF) | 0x10000);
1806
1807                if (is2t)
1808                        rtl_set_rfreg(hw, kk, 0x00, MASK12BITS,
1809                                      (rf_b_mode & 0x8FFFF) | 0x10000);
1810        }
1811        lc_cal = rtl_get_rfreg(hw, jj, 0x18, MASK12BITS);
1812
1813        rtl_set_rfreg(hw, jj, 0x18, MASK12BITS, lc_cal | 0x08000);
1814
1815        mdelay(100);
1816
1817        if ((tmpreg & 0x70) != 0) {
1818                rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1819                rtl_set_rfreg(hw, jj, 0x00, MASK12BITS, rf_a_mode);
1820
1821                if (is2t)
1822                        rtl_set_rfreg(hw, kk, 0x00, MASK12BITS,
1823                                      rf_b_mode);
1824        } else {
1825                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1826        }
1827        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1828}
1829
1830static void rfpath_switch(struct ieee80211_hw *hw,
1831                          bool bmain, bool is2t)
1832{
1833        struct rtl_priv *rtlpriv = rtl_priv(hw);
1834        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1835        struct rtl_efuse *fuse = rtl_efuse(rtl_priv(hw));
1836        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1837
1838        if (is_hal_stop(rtlhal)) {
1839                u8 u1btmp;
1840                u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0);
1841                rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7));
1842                rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1843        }
1844        if (is2t) {
1845                if (bmain)
1846                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1847                                      BIT(5) | BIT(6), 0x1);
1848                else
1849                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1850                                      BIT(5) | BIT(6), 0x2);
1851        } else {
1852                rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0);
1853                rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201);
1854
1855                /* We use the RF definition of MAIN and AUX, left antenna and
1856                 * right antenna repectively.
1857                 * Default output at AUX.
1858                 */
1859                if (bmain) {
1860                        rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(14) |
1861                                      BIT(13) | BIT(12), 0);
1862                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(5) |
1863                                      BIT(4) | BIT(3), 0);
1864                        if (fuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1865                                rtl_set_bbreg(hw, RCONFIG_RAM64X16, BIT(31), 0);
1866                } else {
1867                        rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(14) |
1868                                      BIT(13) | BIT(12), 1);
1869                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(5) |
1870                                      BIT(4) | BIT(3), 1);
1871                        if (fuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1872                                rtl_set_bbreg(hw, RCONFIG_RAM64X16, BIT(31), 1);
1873                }
1874        }
1875}
1876
1877#undef IQK_ADDA_REG_NUM
1878#undef IQK_DELAY_TIME
1879
1880void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1881{
1882        struct rtl_priv *rtlpriv = rtl_priv(hw);
1883        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1884        long result[4][8];
1885        u8 i, final;
1886        bool patha_ok;
1887        long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_tmp = 0;
1888        bool is12simular, is13simular, is23simular;
1889        u32 iqk_bb_reg[9] = {
1890                ROFDM0_XARXIQIMBAL,
1891                ROFDM0_XBRXIQIMBAL,
1892                ROFDM0_ECCATHRES,
1893                ROFDM0_AGCRSSITABLE,
1894                ROFDM0_XATXIQIMBAL,
1895                ROFDM0_XBTXIQIMBAL,
1896                ROFDM0_XCTXAFE,
1897                ROFDM0_XDTXAFE,
1898                ROFDM0_RXIQEXTANTA
1899        };
1900
1901        if (recovery) {
1902                reload_adda(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 9);
1903                return;
1904        }
1905
1906        memset(result, 0, 32 * sizeof(long));
1907        final = 0xff;
1908        patha_ok = false;
1909        is12simular = false;
1910        is23simular = false;
1911        is13simular = false;
1912        for (i = 0; i < 3; i++) {
1913                if (get_rf_type(rtlphy) == RF_2T2R)
1914                        _rtl88e_phy_iq_calibrate(hw, result, i, true);
1915                else
1916                        _rtl88e_phy_iq_calibrate(hw, result, i, false);
1917                if (i == 1) {
1918                        is12simular = sim_comp(hw, result, 0, 1);
1919                        if (is12simular) {
1920                                final = 0;
1921                                break;
1922                        }
1923                }
1924                if (i == 2) {
1925                        is13simular = sim_comp(hw, result, 0, 2);
1926                        if (is13simular) {
1927                                final = 0;
1928                                break;
1929                        }
1930                        is23simular = sim_comp(hw, result, 1, 2);
1931                        if (is23simular) {
1932                                final = 1;
1933                        } else {
1934                                for (i = 0; i < 8; i++)
1935                                        reg_tmp += result[3][i];
1936
1937                                if (reg_tmp != 0)
1938                                        final = 3;
1939                                else
1940                                        final = 0xFF;
1941                        }
1942                }
1943        }
1944        for (i = 0; i < 4; i++) {
1945                reg_e94 = result[i][0];
1946                reg_e9c = result[i][1];
1947                reg_ea4 = result[i][2];
1948                reg_eb4 = result[i][4];
1949                reg_ebc = result[i][5];
1950        }
1951        if (final != 0xff) {
1952                reg_e94 = result[final][0];
1953                rtlphy->reg_e94 = reg_e94;
1954                reg_e9c = result[final][1];
1955                rtlphy->reg_e9c = reg_e9c;
1956                reg_ea4 = result[final][2];
1957                reg_eb4 = result[final][4];
1958                rtlphy->reg_eb4 = reg_eb4;
1959                reg_ebc = result[final][5];
1960                rtlphy->reg_ebc = reg_ebc;
1961                patha_ok = true;
1962        } else {
1963                rtlphy->reg_e94 = 0x100;
1964                rtlphy->reg_eb4 = 0x100;
1965                rtlphy->reg_ebc = 0x0;
1966                rtlphy->reg_e9c = 0x0;
1967        }
1968        if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1969                fill_iqk(hw, patha_ok, result, final, (reg_ea4 == 0));
1970        if (final != 0xFF) {
1971                for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
1972                        rtlphy->iqk_matrix[0].value[0][i] = result[final][i];
1973                rtlphy->iqk_matrix[0].iqk_done = true;
1974        }
1975        save_adda_reg(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 9);
1976}
1977
1978void rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw)
1979{
1980        struct rtl_priv *rtlpriv = rtl_priv(hw);
1981        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1982        struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
1983        bool start_conttx = false, singletone = false;
1984        u32 timeout = 2000, timecount = 0;
1985
1986        if (start_conttx || singletone)
1987                return;
1988
1989        while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
1990                udelay(50);
1991                timecount += 50;
1992        }
1993
1994        rtlphy->lck_inprogress = true;
1995        RTPRINT(rtlpriv, FINIT, INIT_IQK,
1996                "LCK:Start!!! currentband %x delay %d ms\n",
1997                 rtlhal->current_bandtype, timecount);
1998
1999        _rtl88e_phy_lc_calibrate(hw, false);
2000
2001        rtlphy->lck_inprogress = false;
2002}
2003
2004void rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2005{
2006        rfpath_switch(hw, bmain, false);
2007}
2008
2009bool rtl88e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2010{
2011        struct rtl_priv *rtlpriv = rtl_priv(hw);
2012        struct rtl_phy *rtlphy = &(rtlpriv->phy);
2013        bool postprocessing = false;
2014
2015        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2016                 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2017                 iotype, rtlphy->set_io_inprogress);
2018        do {
2019                switch (iotype) {
2020                case IO_CMD_RESUME_DM_BY_SCAN:
2021                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2022                                 "[IO CMD] Resume DM after scan.\n");
2023                        postprocessing = true;
2024                        break;
2025                case IO_CMD_PAUSE_DM_BY_SCAN:
2026                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2027                                 "[IO CMD] Pause DM before scan.\n");
2028                        postprocessing = true;
2029                        break;
2030                default:
2031                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2032                                 "switch case not processed\n");
2033                        break;
2034                }
2035        } while (false);
2036        if (postprocessing && !rtlphy->set_io_inprogress) {
2037                rtlphy->set_io_inprogress = true;
2038                rtlphy->current_io_type = iotype;
2039        } else {
2040                return false;
2041        }
2042        rtl88e_phy_set_io(hw);
2043        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2044        return true;
2045}
2046
2047static void rtl88ee_phy_set_rf_on(struct ieee80211_hw *hw)
2048{
2049        struct rtl_priv *rtlpriv = rtl_priv(hw);
2050
2051        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2052        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2053        /*rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);*/
2054        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2055        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2056        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2057}
2058
2059static void _rtl88ee_phy_set_rf_sleep(struct ieee80211_hw *hw)
2060{
2061        struct rtl_priv *rtlpriv = rtl_priv(hw);
2062        int jj = RF90_PATH_A;
2063
2064        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2065        rtl_set_rfreg(hw, jj, 0x00, RFREG_OFFSET_MASK, 0x00);
2066        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2067        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2068}
2069
2070static bool _rtl88ee_phy_set_rf_power_state(struct ieee80211_hw *hw,
2071                                            enum rf_pwrstate rfpwr_state)
2072{
2073        struct rtl_priv *rtlpriv = rtl_priv(hw);
2074        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2075        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2076        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2077        struct rtl8192_tx_ring *ring = NULL;
2078        bool bresult = true;
2079        u8 i, queue_id;
2080
2081        switch (rfpwr_state) {
2082        case ERFON:{
2083                if ((ppsc->rfpwr_state == ERFOFF) &&
2084                    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2085                        bool rtstatus;
2086                        u32 init = 0;
2087                        do {
2088                                init++;
2089                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2090                                         "IPS Set eRf nic enable\n");
2091                                rtstatus = rtl_ps_enable_nic(hw);
2092                        } while ((rtstatus != true) && (init < 10));
2093                        RT_CLEAR_PS_LEVEL(ppsc,
2094                                          RT_RF_OFF_LEVL_HALT_NIC);
2095                } else {
2096                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2097                                 "Set ERFON sleeped:%d ms\n",
2098                                 jiffies_to_msecs(jiffies - ppsc->
2099                                                  last_sleep_jiffies));
2100                        ppsc->last_awake_jiffies = jiffies;
2101                        rtl88ee_phy_set_rf_on(hw);
2102                }
2103                if (mac->link_state == MAC80211_LINKED)
2104                        rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2105                else
2106                        rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2107                break; }
2108        case ERFOFF:{
2109                for (queue_id = 0, i = 0;
2110                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2111                        ring = &pcipriv->dev.tx_ring[queue_id];
2112                        if (skb_queue_len(&ring->queue) == 0) {
2113                                queue_id++;
2114                                continue;
2115                        } else {
2116                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2117                                         "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2118                                         (i + 1), queue_id,
2119                                         skb_queue_len(&ring->queue));
2120
2121                                udelay(10);
2122                                i++;
2123                        }
2124                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2125                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2126                                         "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2127                                          MAX_DOZE_WAITING_TIMES_9x,
2128                                          queue_id,
2129                                          skb_queue_len(&ring->queue));
2130                                break;
2131                        }
2132                }
2133                if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2134                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2135                                 "IPS Set eRf nic disable\n");
2136                        rtl_ps_disable_nic(hw);
2137                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2138                } else {
2139                        if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2140                                rtlpriv->cfg->ops->led_control(hw,
2141                                                LED_CTL_NO_LINK);
2142                        } else {
2143                                rtlpriv->cfg->ops->led_control(hw,
2144                                                LED_CTL_POWER_OFF);
2145                        }
2146                }
2147                break; }
2148        case ERFSLEEP:{
2149                if (ppsc->rfpwr_state == ERFOFF)
2150                        break;
2151                for (queue_id = 0, i = 0;
2152                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2153                        ring = &pcipriv->dev.tx_ring[queue_id];
2154                        if (skb_queue_len(&ring->queue) == 0) {
2155                                queue_id++;
2156                                continue;
2157                        } else {
2158                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2159                                         "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2160                                         (i + 1), queue_id,
2161                                         skb_queue_len(&ring->queue));
2162
2163                                udelay(10);
2164                                i++;
2165                        }
2166                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2167                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2168                                         "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2169                                         MAX_DOZE_WAITING_TIMES_9x,
2170                                         queue_id,
2171                                         skb_queue_len(&ring->queue));
2172                                break;
2173                        }
2174                }
2175                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2176                         "Set ERFSLEEP awaked:%d ms\n",
2177                         jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
2178                ppsc->last_sleep_jiffies = jiffies;
2179                _rtl88ee_phy_set_rf_sleep(hw);
2180                break; }
2181        default:
2182                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2183                         "switch case not processed\n");
2184                bresult = false;
2185                break;
2186        }
2187        if (bresult)
2188                ppsc->rfpwr_state = rfpwr_state;
2189        return bresult;
2190}
2191
2192bool rtl88e_phy_set_rf_power_state(struct ieee80211_hw *hw,
2193                                   enum rf_pwrstate rfpwr_state)
2194{
2195        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2196        bool bresult;
2197
2198        if (rfpwr_state == ppsc->rfpwr_state)
2199                return false;
2200        bresult = _rtl88ee_phy_set_rf_power_state(hw, rfpwr_state);
2201        return bresult;
2202}
2203