linux/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2009-2012  Realtek Corporation.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of version 2 of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 *
  14 * You should have received a copy of the GNU General Public License along with
  15 * this program; if not, write to the Free Software Foundation, Inc.,
  16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17 *
  18 * The full GNU General Public License is included in this distribution in the
  19 * file called LICENSE.
  20 *
  21 * Contact Information:
  22 * wlanfae <wlanfae@realtek.com>
  23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  24 * Hsinchu 300, Taiwan.
  25 *
  26 * Larry Finger <Larry.Finger@lwfinger.net>
  27 *
  28 *****************************************************************************/
  29
  30#include "../wifi.h"
  31#include "../rtl8192ce/reg.h"
  32#include "../rtl8192ce/def.h"
  33#include "dm_common.h"
  34#include "fw_common.h"
  35#include "phy_common.h"
  36#include <linux/export.h>
  37
  38u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
  39{
  40        struct rtl_priv *rtlpriv = rtl_priv(hw);
  41        u32 returnvalue, originalvalue, bitshift;
  42
  43        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
  44                 regaddr, bitmask);
  45        originalvalue = rtl_read_dword(rtlpriv, regaddr);
  46        bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
  47        returnvalue = (originalvalue & bitmask) >> bitshift;
  48
  49        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  50                 "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
  51                 bitmask, regaddr, originalvalue);
  52
  53        return returnvalue;
  54}
  55EXPORT_SYMBOL(rtl92c_phy_query_bb_reg);
  56
  57void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
  58                           u32 regaddr, u32 bitmask, u32 data)
  59{
  60        struct rtl_priv *rtlpriv = rtl_priv(hw);
  61        u32 originalvalue, bitshift;
  62
  63        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  64                 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
  65                 regaddr, bitmask, data);
  66
  67        if (bitmask != MASKDWORD) {
  68                originalvalue = rtl_read_dword(rtlpriv, regaddr);
  69                bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
  70                data = ((originalvalue & (~bitmask)) | (data << bitshift));
  71        }
  72
  73        rtl_write_dword(rtlpriv, regaddr, data);
  74
  75        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  76                 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
  77                 regaddr, bitmask, data);
  78}
  79EXPORT_SYMBOL(rtl92c_phy_set_bb_reg);
  80
  81u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
  82                                  enum radio_path rfpath, u32 offset)
  83{
  84        RT_ASSERT(false, "deprecated!\n");
  85        return 0;
  86}
  87EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_read);
  88
  89void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
  90                                    enum radio_path rfpath, u32 offset,
  91                                    u32 data)
  92{
  93        RT_ASSERT(false, "deprecated!\n");
  94}
  95EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write);
  96
  97u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
  98                               enum radio_path rfpath, u32 offset)
  99{
 100        struct rtl_priv *rtlpriv = rtl_priv(hw);
 101        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 102        struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 103        u32 newoffset;
 104        u32 tmplong, tmplong2;
 105        u8 rfpi_enable = 0;
 106        u32 retvalue;
 107
 108        offset &= 0x3f;
 109        newoffset = offset;
 110        if (RT_CANNOT_IO(hw)) {
 111                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
 112                return 0xFFFFFFFF;
 113        }
 114        tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
 115        if (rfpath == RF90_PATH_A)
 116                tmplong2 = tmplong;
 117        else
 118                tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
 119        tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
 120            (newoffset << 23) | BLSSIREADEDGE;
 121        rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
 122                      tmplong & (~BLSSIREADEDGE));
 123        mdelay(1);
 124        rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
 125        mdelay(1);
 126        rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
 127                      tmplong | BLSSIREADEDGE);
 128        mdelay(1);
 129        if (rfpath == RF90_PATH_A)
 130                rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
 131                                                 BIT(8));
 132        else if (rfpath == RF90_PATH_B)
 133                rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
 134                                                 BIT(8));
 135        if (rfpi_enable)
 136                retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
 137                                         BLSSIREADBACKDATA);
 138        else
 139                retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
 140                                         BLSSIREADBACKDATA);
 141        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n",
 142                                               rfpath, pphyreg->rf_rb,
 143                                               retvalue);
 144        return retvalue;
 145}
 146EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read);
 147
 148void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
 149                                 enum radio_path rfpath, u32 offset,
 150                                 u32 data)
 151{
 152        u32 data_and_addr;
 153        u32 newoffset;
 154        struct rtl_priv *rtlpriv = rtl_priv(hw);
 155        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 156        struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 157
 158        if (RT_CANNOT_IO(hw)) {
 159                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
 160                return;
 161        }
 162        offset &= 0x3f;
 163        newoffset = offset;
 164        data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
 165        rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
 166        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
 167                                               rfpath, pphyreg->rf3wire_offset,
 168                                               data_and_addr);
 169}
 170EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write);
 171
 172u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask)
 173{
 174        u32 i;
 175
 176        for (i = 0; i <= 31; i++) {
 177                if (((bitmask >> i) & 0x1) == 1)
 178                        break;
 179        }
 180        return i;
 181}
 182EXPORT_SYMBOL(_rtl92c_phy_calculate_bit_shift);
 183
 184static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw)
 185{
 186        rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
 187        rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);
 188        rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);
 189        rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);
 190        rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);
 191        rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);
 192        rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);
 193        rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);
 194        rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
 195        rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
 196}
 197
 198bool rtl92c_phy_rf_config(struct ieee80211_hw *hw)
 199{
 200        struct rtl_priv *rtlpriv = rtl_priv(hw);
 201
 202        return rtlpriv->cfg->ops->phy_rf6052_config(hw);
 203}
 204EXPORT_SYMBOL(rtl92c_phy_rf_config);
 205
 206bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
 207{
 208        struct rtl_priv *rtlpriv = rtl_priv(hw);
 209        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 210        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 211        bool rtstatus;
 212
 213        rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw,
 214                                                 BASEBAND_CONFIG_PHY_REG);
 215        if (!rtstatus) {
 216                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
 217                return false;
 218        }
 219        if (rtlphy->rf_type == RF_1T2R) {
 220                _rtl92c_phy_bb_config_1t(hw);
 221                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
 222        }
 223        if (rtlefuse->autoload_failflag == false) {
 224                rtlphy->pwrgroup_cnt = 0;
 225                rtstatus = rtlpriv->cfg->ops->config_bb_with_pgheaderfile(hw,
 226                                                   BASEBAND_CONFIG_PHY_REG);
 227        }
 228        if (!rtstatus) {
 229                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
 230                return false;
 231        }
 232        rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw,
 233                                                 BASEBAND_CONFIG_AGC_TAB);
 234        if (!rtstatus) {
 235                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
 236                return false;
 237        }
 238        rtlphy->cck_high_power =
 239                (bool)(rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, 0x200));
 240
 241        return true;
 242}
 243
 244EXPORT_SYMBOL(_rtl92c_phy_bb8192c_config_parafile);
 245
 246void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
 247                                            u32 regaddr, u32 bitmask,
 248                                            u32 data)
 249{
 250        struct rtl_priv *rtlpriv = rtl_priv(hw);
 251        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 252
 253        if (regaddr == RTXAGC_A_RATE18_06) {
 254                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
 255                    data;
 256                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 257                         "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
 258                          rtlphy->pwrgroup_cnt,
 259                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 260                                                            pwrgroup_cnt][0]);
 261        }
 262        if (regaddr == RTXAGC_A_RATE54_24) {
 263                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
 264                    data;
 265                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 266                         "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
 267                          rtlphy->pwrgroup_cnt,
 268                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 269                                                            pwrgroup_cnt][1]);
 270        }
 271        if (regaddr == RTXAGC_A_CCK1_MCS32) {
 272                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
 273                    data;
 274                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 275                         "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
 276                          rtlphy->pwrgroup_cnt,
 277                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 278                                                            pwrgroup_cnt][6]);
 279        }
 280        if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
 281                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] =
 282                    data;
 283                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 284                         "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
 285                          rtlphy->pwrgroup_cnt,
 286                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 287                                                            pwrgroup_cnt][7]);
 288        }
 289        if (regaddr == RTXAGC_A_MCS03_MCS00) {
 290                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
 291                    data;
 292                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 293                         "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
 294                          rtlphy->pwrgroup_cnt,
 295                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 296                                                            pwrgroup_cnt][2]);
 297        }
 298        if (regaddr == RTXAGC_A_MCS07_MCS04) {
 299                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
 300                    data;
 301                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 302                         "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
 303                          rtlphy->pwrgroup_cnt,
 304                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 305                                                            pwrgroup_cnt][3]);
 306        }
 307        if (regaddr == RTXAGC_A_MCS11_MCS08) {
 308                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
 309                    data;
 310                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 311                         "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
 312                          rtlphy->pwrgroup_cnt,
 313                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 314                                                            pwrgroup_cnt][4]);
 315        }
 316        if (regaddr == RTXAGC_A_MCS15_MCS12) {
 317                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
 318                    data;
 319                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 320                         "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
 321                          rtlphy->pwrgroup_cnt,
 322                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 323                                                            pwrgroup_cnt][5]);
 324        }
 325        if (regaddr == RTXAGC_B_RATE18_06) {
 326                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] =
 327                    data;
 328                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 329                         "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
 330                          rtlphy->pwrgroup_cnt,
 331                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 332                                                            pwrgroup_cnt][8]);
 333        }
 334        if (regaddr == RTXAGC_B_RATE54_24) {
 335                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] =
 336                    data;
 337                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 338                         "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
 339                          rtlphy->pwrgroup_cnt,
 340                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 341                                                            pwrgroup_cnt][9]);
 342        }
 343        if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
 344                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] =
 345                    data;
 346                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 347                         "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
 348                          rtlphy->pwrgroup_cnt,
 349                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 350                                                            pwrgroup_cnt][14]);
 351        }
 352        if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
 353                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] =
 354                    data;
 355                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 356                         "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
 357                          rtlphy->pwrgroup_cnt,
 358                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 359                                                            pwrgroup_cnt][15]);
 360        }
 361        if (regaddr == RTXAGC_B_MCS03_MCS00) {
 362                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] =
 363                    data;
 364                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 365                         "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
 366                          rtlphy->pwrgroup_cnt,
 367                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 368                                                            pwrgroup_cnt][10]);
 369        }
 370        if (regaddr == RTXAGC_B_MCS07_MCS04) {
 371                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] =
 372                    data;
 373                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 374                         "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
 375                          rtlphy->pwrgroup_cnt,
 376                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 377                                                            pwrgroup_cnt][11]);
 378        }
 379        if (regaddr == RTXAGC_B_MCS11_MCS08) {
 380                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] =
 381                    data;
 382                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 383                         "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
 384                          rtlphy->pwrgroup_cnt,
 385                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 386                                                            pwrgroup_cnt][12]);
 387        }
 388        if (regaddr == RTXAGC_B_MCS15_MCS12) {
 389                rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] =
 390                    data;
 391                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 392                         "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
 393                          rtlphy->pwrgroup_cnt,
 394                          rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 395                                                            pwrgroup_cnt][13]);
 396
 397                rtlphy->pwrgroup_cnt++;
 398        }
 399}
 400EXPORT_SYMBOL(_rtl92c_store_pwrIndex_diffrate_offset);
 401
 402void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
 403{
 404        struct rtl_priv *rtlpriv = rtl_priv(hw);
 405        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 406
 407        rtlphy->default_initialgain[0] =
 408            (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
 409        rtlphy->default_initialgain[1] =
 410            (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
 411        rtlphy->default_initialgain[2] =
 412            (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
 413        rtlphy->default_initialgain[3] =
 414            (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
 415
 416        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 417                 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
 418                  rtlphy->default_initialgain[0],
 419                  rtlphy->default_initialgain[1],
 420                  rtlphy->default_initialgain[2],
 421                  rtlphy->default_initialgain[3]);
 422
 423        rtlphy->framesync = (u8)rtl_get_bbreg(hw,
 424                                               ROFDM0_RXDETECTOR3, MASKBYTE0);
 425        rtlphy->framesync_c34 = rtl_get_bbreg(hw,
 426                                              ROFDM0_RXDETECTOR2, MASKDWORD);
 427
 428        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 429                 "Default framesync (0x%x) = 0x%x\n",
 430                  ROFDM0_RXDETECTOR3, rtlphy->framesync);
 431}
 432
 433void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
 434{
 435        struct rtl_priv *rtlpriv = rtl_priv(hw);
 436        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 437
 438        rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
 439        rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
 440        rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
 441        rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
 442
 443        rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
 444        rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
 445        rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
 446        rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
 447
 448        rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
 449        rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
 450
 451        rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
 452        rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
 453
 454        rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
 455            RFPGA0_XA_LSSIPARAMETER;
 456        rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
 457            RFPGA0_XB_LSSIPARAMETER;
 458
 459        rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER;
 460        rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER;
 461        rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER;
 462        rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER;
 463
 464        rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
 465        rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
 466        rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
 467        rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
 468
 469        rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
 470        rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
 471
 472        rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
 473        rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
 474
 475        rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
 476        rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
 477        rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
 478        rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
 479
 480        rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
 481        rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
 482        rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
 483        rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
 484
 485        rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
 486        rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
 487        rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
 488        rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
 489
 490        rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE;
 491        rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE;
 492        rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE;
 493        rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE;
 494
 495        rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
 496        rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
 497        rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
 498        rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
 499
 500        rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE;
 501        rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE;
 502        rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE;
 503        rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE;
 504
 505        rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
 506        rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
 507        rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
 508        rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
 509
 510        rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
 511        rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
 512        rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK;
 513        rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK;
 514
 515        rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
 516        rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
 517
 518}
 519EXPORT_SYMBOL(_rtl92c_phy_init_bb_rf_register_definition);
 520
 521void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
 522{
 523        struct rtl_priv *rtlpriv = rtl_priv(hw);
 524        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 525        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 526        u8 txpwr_level;
 527        long txpwr_dbm;
 528
 529        txpwr_level = rtlphy->cur_cck_txpwridx;
 530        txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
 531                                                 txpwr_level);
 532        txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
 533            rtlefuse->legacy_ht_txpowerdiff;
 534        if (_rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
 535                                         txpwr_level) > txpwr_dbm)
 536                txpwr_dbm =
 537                    _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
 538                                                 txpwr_level);
 539        txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
 540        if (_rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
 541                                         txpwr_level) > txpwr_dbm)
 542                txpwr_dbm =
 543                    _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
 544                                                 txpwr_level);
 545        *powerlevel = txpwr_dbm;
 546}
 547
 548static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
 549                                      u8 *cckpowerlevel, u8 *ofdmpowerlevel)
 550{
 551        struct rtl_priv *rtlpriv = rtl_priv(hw);
 552        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 553        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 554        u8 index = (channel - 1);
 555
 556        cckpowerlevel[RF90_PATH_A] =
 557            rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
 558        cckpowerlevel[RF90_PATH_B] =
 559            rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
 560        if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {
 561                ofdmpowerlevel[RF90_PATH_A] =
 562                    rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
 563                ofdmpowerlevel[RF90_PATH_B] =
 564                    rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
 565        } else if (get_rf_type(rtlphy) == RF_2T2R) {
 566                ofdmpowerlevel[RF90_PATH_A] =
 567                    rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
 568                ofdmpowerlevel[RF90_PATH_B] =
 569                    rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
 570        }
 571}
 572
 573static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw,
 574                                         u8 channel, u8 *cckpowerlevel,
 575                                         u8 *ofdmpowerlevel)
 576{
 577        struct rtl_priv *rtlpriv = rtl_priv(hw);
 578        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 579
 580        rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
 581        rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
 582}
 583
 584void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
 585{
 586        struct rtl_priv *rtlpriv = rtl_priv(hw);
 587        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 588        u8 cckpowerlevel[2], ofdmpowerlevel[2];
 589
 590        if (!rtlefuse->txpwr_fromeprom)
 591                return;
 592        _rtl92c_get_txpower_index(hw, channel,
 593                                  &cckpowerlevel[0], &ofdmpowerlevel[0]);
 594        _rtl92c_ccxpower_index_check(hw, channel, &cckpowerlevel[0],
 595                                     &ofdmpowerlevel[0]);
 596        rtlpriv->cfg->ops->phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
 597        rtlpriv->cfg->ops->phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0],
 598                                                       channel);
 599}
 600EXPORT_SYMBOL(rtl92c_phy_set_txpower_level);
 601
 602bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
 603{
 604        struct rtl_priv *rtlpriv = rtl_priv(hw);
 605        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 606        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 607        u8 idx;
 608        u8 rf_path;
 609        u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_idx(hw, WIRELESS_MODE_B,
 610                                                      power_indbm);
 611        u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_idx(hw, WIRELESS_MODE_N_24G,
 612                                                       power_indbm);
 613        if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)
 614                ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;
 615        else
 616                ofdmtxpwridx = 0;
 617        RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE,
 618                 "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
 619                  power_indbm, ccktxpwridx, ofdmtxpwridx);
 620        for (idx = 0; idx < 14; idx++) {
 621                for (rf_path = 0; rf_path < 2; rf_path++) {
 622                        rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
 623                        rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =
 624                            ofdmtxpwridx;
 625                        rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =
 626                            ofdmtxpwridx;
 627                }
 628        }
 629        rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
 630        return true;
 631}
 632EXPORT_SYMBOL(rtl92c_phy_update_txpower_dbm);
 633
 634u8 _rtl92c_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw,
 635                                enum wireless_mode wirelessmode,
 636                                long power_indbm)
 637{
 638        u8 txpwridx;
 639        long offset;
 640
 641        switch (wirelessmode) {
 642        case WIRELESS_MODE_B:
 643                offset = -7;
 644                break;
 645        case WIRELESS_MODE_G:
 646        case WIRELESS_MODE_N_24G:
 647                offset = -8;
 648                break;
 649        default:
 650                offset = -8;
 651                break;
 652        }
 653
 654        if ((power_indbm - offset) > 0)
 655                txpwridx = (u8)((power_indbm - offset) * 2);
 656        else
 657                txpwridx = 0;
 658
 659        if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)
 660                txpwridx = MAX_TXPWR_IDX_NMODE_92S;
 661
 662        return txpwridx;
 663}
 664EXPORT_SYMBOL(_rtl92c_phy_dbm_to_txpwr_idx);
 665
 666long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
 667                                  enum wireless_mode wirelessmode,
 668                                  u8 txpwridx)
 669{
 670        long offset;
 671        long pwrout_dbm;
 672
 673        switch (wirelessmode) {
 674        case WIRELESS_MODE_B:
 675                offset = -7;
 676                break;
 677        case WIRELESS_MODE_G:
 678        case WIRELESS_MODE_N_24G:
 679                offset = -8;
 680                break;
 681        default:
 682                offset = -8;
 683                break;
 684        }
 685        pwrout_dbm = txpwridx / 2 + offset;
 686        return pwrout_dbm;
 687}
 688EXPORT_SYMBOL(_rtl92c_phy_txpwr_idx_to_dbm);
 689
 690void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
 691                            enum nl80211_channel_type ch_type)
 692{
 693        struct rtl_priv *rtlpriv = rtl_priv(hw);
 694        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 695        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 696        u8 tmp_bw = rtlphy->current_chan_bw;
 697
 698        if (rtlphy->set_bwmode_inprogress)
 699                return;
 700        rtlphy->set_bwmode_inprogress = true;
 701        if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
 702                rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw);
 703        } else {
 704                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 705                         "false driver sleep or unload\n");
 706                rtlphy->set_bwmode_inprogress = false;
 707                rtlphy->current_chan_bw = tmp_bw;
 708        }
 709}
 710EXPORT_SYMBOL(rtl92c_phy_set_bw_mode);
 711
 712void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw)
 713{
 714        struct rtl_priv *rtlpriv = rtl_priv(hw);
 715        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 716        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 717        u32 delay;
 718
 719        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
 720                 "switch to channel%d\n", rtlphy->current_channel);
 721        if (is_hal_stop(rtlhal))
 722                return;
 723        do {
 724                if (!rtlphy->sw_chnl_inprogress)
 725                        break;
 726                if (!_rtl92c_phy_sw_chnl_step_by_step
 727                    (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
 728                     &rtlphy->sw_chnl_step, &delay)) {
 729                        if (delay > 0)
 730                                mdelay(delay);
 731                        else
 732                                continue;
 733                } else {
 734                        rtlphy->sw_chnl_inprogress = false;
 735                }
 736                break;
 737        } while (true);
 738        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
 739}
 740EXPORT_SYMBOL(rtl92c_phy_sw_chnl_callback);
 741
 742u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw)
 743{
 744        struct rtl_priv *rtlpriv = rtl_priv(hw);
 745        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 746        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 747
 748        if (rtlphy->sw_chnl_inprogress)
 749                return 0;
 750        if (rtlphy->set_bwmode_inprogress)
 751                return 0;
 752        RT_ASSERT((rtlphy->current_channel <= 14),
 753                  "WIRELESS_MODE_G but channel>14");
 754        rtlphy->sw_chnl_inprogress = true;
 755        rtlphy->sw_chnl_stage = 0;
 756        rtlphy->sw_chnl_step = 0;
 757        if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
 758                rtl92c_phy_sw_chnl_callback(hw);
 759                RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
 760                         "sw_chnl_inprogress false schdule workitem\n");
 761                rtlphy->sw_chnl_inprogress = false;
 762        } else {
 763                RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
 764                         "sw_chnl_inprogress false driver sleep or unload\n");
 765                rtlphy->sw_chnl_inprogress = false;
 766        }
 767        return 1;
 768}
 769EXPORT_SYMBOL(rtl92c_phy_sw_chnl);
 770
 771static void _rtl92c_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel)
 772{
 773        struct rtl_priv *rtlpriv = rtl_priv(hw);
 774        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 775        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 776        if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) {
 777                if (channel == 6 &&
 778                    rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
 779                        rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1,
 780                                      MASKDWORD, 0x00255);
 781                } else {
 782                        u32 backuprf0x1A =
 783                          (u32)rtl_get_rfreg(hw, RF90_PATH_A, RF_RX_G1,
 784                                             RFREG_OFFSET_MASK);
 785                        rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
 786                                      backuprf0x1A);
 787                }
 788        }
 789}
 790
 791static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
 792                                             u32 cmdtableidx, u32 cmdtablesz,
 793                                             enum swchnlcmd_id cmdid,
 794                                             u32 para1, u32 para2, u32 msdelay)
 795{
 796        struct swchnlcmd *pcmd;
 797
 798        if (cmdtable == NULL) {
 799                RT_ASSERT(false, "cmdtable cannot be NULL.\n");
 800                return false;
 801        }
 802
 803        if (cmdtableidx >= cmdtablesz)
 804                return false;
 805
 806        pcmd = cmdtable + cmdtableidx;
 807        pcmd->cmdid = cmdid;
 808        pcmd->para1 = para1;
 809        pcmd->para2 = para2;
 810        pcmd->msdelay = msdelay;
 811        return true;
 812}
 813
 814bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
 815                                      u8 channel, u8 *stage, u8 *step,
 816                                      u32 *delay)
 817{
 818        struct rtl_priv *rtlpriv = rtl_priv(hw);
 819        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 820        struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
 821        u32 precommoncmdcnt;
 822        struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
 823        u32 postcommoncmdcnt;
 824        struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
 825        u32 rfdependcmdcnt;
 826        struct swchnlcmd *currentcmd = NULL;
 827        u8 rfpath;
 828        u8 num_total_rfpath = rtlphy->num_total_rfpath;
 829
 830        precommoncmdcnt = 0;
 831        _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
 832                                         MAX_PRECMD_CNT,
 833                                         CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
 834        _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
 835                                         MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
 836
 837        postcommoncmdcnt = 0;
 838
 839        _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
 840                                         MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
 841
 842        rfdependcmdcnt = 0;
 843
 844        RT_ASSERT((channel >= 1 && channel <= 14),
 845                  "illegal channel for Zebra: %d\n", channel);
 846
 847        _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
 848                                         MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
 849                                         RF_CHNLBW, channel, 10);
 850
 851        _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
 852                                         MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0,
 853                                         0);
 854
 855        do {
 856                switch (*stage) {
 857                case 0:
 858                        currentcmd = &precommoncmd[*step];
 859                        break;
 860                case 1:
 861                        currentcmd = &rfdependcmd[*step];
 862                        break;
 863                case 2:
 864                        currentcmd = &postcommoncmd[*step];
 865                        break;
 866                default:
 867                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 868                                 "Invalid 'stage' = %d, Check it!\n", *stage);
 869                        return true;
 870                }
 871
 872                if (currentcmd->cmdid == CMDID_END) {
 873                        if ((*stage) == 2) {
 874                                return true;
 875                        } else {
 876                                (*stage)++;
 877                                (*step) = 0;
 878                                continue;
 879                        }
 880                }
 881
 882                switch (currentcmd->cmdid) {
 883                case CMDID_SET_TXPOWEROWER_LEVEL:
 884                        rtl92c_phy_set_txpower_level(hw, channel);
 885                        break;
 886                case CMDID_WRITEPORT_ULONG:
 887                        rtl_write_dword(rtlpriv, currentcmd->para1,
 888                                        currentcmd->para2);
 889                        break;
 890                case CMDID_WRITEPORT_USHORT:
 891                        rtl_write_word(rtlpriv, currentcmd->para1,
 892                                       (u16) currentcmd->para2);
 893                        break;
 894                case CMDID_WRITEPORT_UCHAR:
 895                        rtl_write_byte(rtlpriv, currentcmd->para1,
 896                                       (u8)currentcmd->para2);
 897                        break;
 898                case CMDID_RF_WRITEREG:
 899                        for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
 900                                rtlphy->rfreg_chnlval[rfpath] =
 901                                    ((rtlphy->rfreg_chnlval[rfpath] &
 902                                      0xfffffc00) | currentcmd->para2);
 903
 904                                rtl_set_rfreg(hw, (enum radio_path)rfpath,
 905                                              currentcmd->para1,
 906                                              RFREG_OFFSET_MASK,
 907                                              rtlphy->rfreg_chnlval[rfpath]);
 908                        }
 909                        _rtl92c_phy_sw_rf_seting(hw, channel);
 910                        break;
 911                default:
 912                        RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
 913                                 "switch case not process\n");
 914                        break;
 915                }
 916
 917                break;
 918        } while (true);
 919
 920        (*delay) = currentcmd->msdelay;
 921        (*step)++;
 922        return false;
 923}
 924
 925bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath)
 926{
 927        return true;
 928}
 929EXPORT_SYMBOL(rtl8192_phy_check_is_legal_rfpath);
 930
 931static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
 932{
 933        u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
 934        u8 result = 0x00;
 935
 936        rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
 937        rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
 938        rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
 939        rtl_set_bbreg(hw, 0xe3c, MASKDWORD,
 940                      config_pathb ? 0x28160202 : 0x28160502);
 941
 942        if (config_pathb) {
 943                rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
 944                rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
 945                rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
 946                rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);
 947        }
 948
 949        rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);
 950        rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
 951        rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
 952
 953        mdelay(IQK_DELAY_TIME);
 954
 955        reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
 956        reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
 957        reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
 958        reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
 959
 960        if (!(reg_eac & BIT(28)) &&
 961            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
 962            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
 963                result |= 0x01;
 964        else
 965                return result;
 966
 967        if (!(reg_eac & BIT(27)) &&
 968            (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
 969            (((reg_eac & 0x03FF0000) >> 16) != 0x36))
 970                result |= 0x02;
 971        return result;
 972}
 973
 974static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw)
 975{
 976        u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
 977        u8 result = 0x00;
 978
 979        rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
 980        rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
 981        mdelay(IQK_DELAY_TIME);
 982        reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
 983        reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
 984        reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
 985        reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
 986        reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
 987
 988        if (!(reg_eac & BIT(31)) &&
 989            (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
 990            (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
 991                result |= 0x01;
 992        else
 993                return result;
 994        if (!(reg_eac & BIT(30)) &&
 995            (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
 996            (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
 997                result |= 0x02;
 998        return result;
 999}
1000
1001static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
1002                                               bool b_iqk_ok, long result[][8],
1003                                               u8 final_candidate, bool btxonly)
1004{
1005        u32 oldval_0, x, tx0_a, reg;
1006        long y, tx0_c;
1007
1008        if (final_candidate == 0xFF) {
1009                return;
1010        } else if (b_iqk_ok) {
1011                oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1012                                          MASKDWORD) >> 22) & 0x3FF;
1013                x = result[final_candidate][0];
1014                if ((x & 0x00000200) != 0)
1015                        x = x | 0xFFFFFC00;
1016                tx0_a = (x * oldval_0) >> 8;
1017                rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
1018                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
1019                              ((x * oldval_0 >> 7) & 0x1));
1020                y = result[final_candidate][1];
1021                if ((y & 0x00000200) != 0)
1022                        y = y | 0xFFFFFC00;
1023                tx0_c = (y * oldval_0) >> 8;
1024                rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
1025                              ((tx0_c & 0x3C0) >> 6));
1026                rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
1027                              (tx0_c & 0x3F));
1028                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
1029                              ((y * oldval_0 >> 7) & 0x1));
1030                if (btxonly)
1031                        return;
1032                reg = result[final_candidate][2];
1033                rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
1034                reg = result[final_candidate][3] & 0x3F;
1035                rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
1036                reg = (result[final_candidate][3] >> 6) & 0xF;
1037                rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
1038        }
1039}
1040
1041static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1042                                               bool b_iqk_ok, long result[][8],
1043                                               u8 final_candidate, bool btxonly)
1044{
1045        u32 oldval_1, x, tx1_a, reg;
1046        long y, tx1_c;
1047
1048        if (final_candidate == 0xFF) {
1049                return;
1050        } else if (b_iqk_ok) {
1051                oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1052                                          MASKDWORD) >> 22) & 0x3FF;
1053                x = result[final_candidate][4];
1054                if ((x & 0x00000200) != 0)
1055                        x = x | 0xFFFFFC00;
1056                tx1_a = (x * oldval_1) >> 8;
1057                rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
1058                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
1059                              ((x * oldval_1 >> 7) & 0x1));
1060                y = result[final_candidate][5];
1061                if ((y & 0x00000200) != 0)
1062                        y = y | 0xFFFFFC00;
1063                tx1_c = (y * oldval_1) >> 8;
1064                rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
1065                              ((tx1_c & 0x3C0) >> 6));
1066                rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
1067                              (tx1_c & 0x3F));
1068                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
1069                              ((y * oldval_1 >> 7) & 0x1));
1070                if (btxonly)
1071                        return;
1072                reg = result[final_candidate][6];
1073                rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1074                reg = result[final_candidate][7] & 0x3F;
1075                rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1076                reg = (result[final_candidate][7] >> 6) & 0xF;
1077                rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg);
1078        }
1079}
1080
1081static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw,
1082                                            u32 *addareg, u32 *addabackup,
1083                                            u32 registernum)
1084{
1085        u32 i;
1086
1087        for (i = 0; i < registernum; i++)
1088                addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
1089}
1090
1091static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw,
1092                                           u32 *macreg, u32 *macbackup)
1093{
1094        struct rtl_priv *rtlpriv = rtl_priv(hw);
1095        u32 i;
1096
1097        for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1098                macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
1099        macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
1100}
1101
1102static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw,
1103                                              u32 *addareg, u32 *addabackup,
1104                                              u32 regiesternum)
1105{
1106        u32 i;
1107
1108        for (i = 0; i < regiesternum; i++)
1109                rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
1110}
1111
1112static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw,
1113                                             u32 *macreg, u32 *macbackup)
1114{
1115        struct rtl_priv *rtlpriv = rtl_priv(hw);
1116        u32 i;
1117
1118        for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1119                rtl_write_byte(rtlpriv, macreg[i], (u8)macbackup[i]);
1120        rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
1121}
1122
1123static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw,
1124                                     u32 *addareg, bool is_patha_on, bool is2t)
1125{
1126        u32 pathOn;
1127        u32 i;
1128
1129        pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
1130        if (false == is2t) {
1131                pathOn = 0x0bdb25a0;
1132                rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
1133        } else {
1134                rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn);
1135        }
1136
1137        for (i = 1; i < IQK_ADDA_REG_NUM; i++)
1138                rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn);
1139}
1140
1141static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw,
1142                                                u32 *macreg, u32 *macbackup)
1143{
1144        struct rtl_priv *rtlpriv = rtl_priv(hw);
1145        u32 i = 0;
1146
1147        rtl_write_byte(rtlpriv, macreg[i], 0x3F);
1148
1149        for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
1150                rtl_write_byte(rtlpriv, macreg[i],
1151                               (u8)(macbackup[i] & (~BIT(3))));
1152        rtl_write_byte(rtlpriv, macreg[i], (u8)(macbackup[i] & (~BIT(5))));
1153}
1154
1155static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw)
1156{
1157        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
1158        rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1159        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1160}
1161
1162static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
1163{
1164        u32 mode;
1165
1166        mode = pi_mode ? 0x01000100 : 0x01000000;
1167        rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
1168        rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
1169}
1170
1171static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw,
1172                                           long result[][8], u8 c1, u8 c2)
1173{
1174        u32 i, j, diff, simularity_bitmap, bound;
1175        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1176
1177        u8 final_candidate[2] = { 0xFF, 0xFF };
1178        bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
1179
1180        if (is2t)
1181                bound = 8;
1182        else
1183                bound = 4;
1184
1185        simularity_bitmap = 0;
1186
1187        for (i = 0; i < bound; i++) {
1188                diff = (result[c1][i] > result[c2][i]) ?
1189                    (result[c1][i] - result[c2][i]) :
1190                    (result[c2][i] - result[c1][i]);
1191
1192                if (diff > MAX_TOLERANCE) {
1193                        if ((i == 2 || i == 6) && !simularity_bitmap) {
1194                                if (result[c1][i] + result[c1][i + 1] == 0)
1195                                        final_candidate[(i / 4)] = c2;
1196                                else if (result[c2][i] + result[c2][i + 1] == 0)
1197                                        final_candidate[(i / 4)] = c1;
1198                                else
1199                                        simularity_bitmap = simularity_bitmap |
1200                                            (1 << i);
1201                        } else
1202                                simularity_bitmap =
1203                                    simularity_bitmap | (1 << i);
1204                }
1205        }
1206
1207        if (simularity_bitmap == 0) {
1208                for (i = 0; i < (bound / 4); i++) {
1209                        if (final_candidate[i] != 0xFF) {
1210                                for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1211                                        result[3][j] =
1212                                            result[final_candidate[i]][j];
1213                                bresult = false;
1214                        }
1215                }
1216                return bresult;
1217        } else if (!(simularity_bitmap & 0x0F)) {
1218                for (i = 0; i < 4; i++)
1219                        result[3][i] = result[c1][i];
1220                return false;
1221        } else if (!(simularity_bitmap & 0xF0) && is2t) {
1222                for (i = 4; i < 8; i++)
1223                        result[3][i] = result[c1][i];
1224                return false;
1225        } else {
1226                return false;
1227        }
1228}
1229
1230static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1231                                     long result[][8], u8 t, bool is2t)
1232{
1233        struct rtl_priv *rtlpriv = rtl_priv(hw);
1234        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1235        u32 i;
1236        u8 patha_ok, pathb_ok;
1237        u32 adda_reg[IQK_ADDA_REG_NUM] = {
1238                0x85c, 0xe6c, 0xe70, 0xe74,
1239                0xe78, 0xe7c, 0xe80, 0xe84,
1240                0xe88, 0xe8c, 0xed0, 0xed4,
1241                0xed8, 0xedc, 0xee0, 0xeec
1242        };
1243        u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1244                0x522, 0x550, 0x551, 0x040
1245        };
1246        const u32 retrycount = 2;
1247        u32 bbvalue;
1248
1249        if (t == 0) {
1250                bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD);
1251
1252                _rtl92c_phy_save_adda_registers(hw, adda_reg,
1253                                                rtlphy->adda_backup, 16);
1254                _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg,
1255                                               rtlphy->iqk_mac_backup);
1256        }
1257        _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t);
1258        if (t == 0) {
1259                rtlphy->rfpi_enable =
1260                   (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
1261                                     BIT(8));
1262        }
1263
1264        if (!rtlphy->rfpi_enable)
1265                _rtl92c_phy_pi_mode_switch(hw, true);
1266        if (t == 0) {
1267                rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
1268                rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
1269                rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
1270        }
1271        rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1272        rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1273        rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1274        if (is2t) {
1275                rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1276                rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1277        }
1278        _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg,
1279                                            rtlphy->iqk_mac_backup);
1280        rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
1281        if (is2t)
1282                rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);
1283        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1284        rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1285        rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
1286        for (i = 0; i < retrycount; i++) {
1287                patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t);
1288                if (patha_ok == 0x03) {
1289                        result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1290                                        0x3FF0000) >> 16;
1291                        result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1292                                        0x3FF0000) >> 16;
1293                        result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1294                                        0x3FF0000) >> 16;
1295                        result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1296                                        0x3FF0000) >> 16;
1297                        break;
1298                } else if (i == (retrycount - 1) && patha_ok == 0x01)
1299
1300                        result[t][0] = (rtl_get_bbreg(hw, 0xe94,
1301                                                      MASKDWORD) & 0x3FF0000) >>
1302                            16;
1303                result[t][1] =
1304                    (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
1305
1306        }
1307
1308        if (is2t) {
1309                _rtl92c_phy_path_a_standby(hw);
1310                _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t);
1311                for (i = 0; i < retrycount; i++) {
1312                        pathb_ok = _rtl92c_phy_path_b_iqk(hw);
1313                        if (pathb_ok == 0x03) {
1314                                result[t][4] = (rtl_get_bbreg(hw,
1315                                                              0xeb4,
1316                                                              MASKDWORD) &
1317                                                0x3FF0000) >> 16;
1318                                result[t][5] =
1319                                    (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1320                                     0x3FF0000) >> 16;
1321                                result[t][6] =
1322                                    (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1323                                     0x3FF0000) >> 16;
1324                                result[t][7] =
1325                                    (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1326                                     0x3FF0000) >> 16;
1327                                break;
1328                        } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1329                                result[t][4] = (rtl_get_bbreg(hw,
1330                                                              0xeb4,
1331                                                              MASKDWORD) &
1332                                                0x3FF0000) >> 16;
1333                        }
1334                        result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1335                                        0x3FF0000) >> 16;
1336                }
1337        }
1338        rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
1339        rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
1340        rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
1341        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1342        rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1343        if (is2t)
1344                rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1345        if (t != 0) {
1346                if (!rtlphy->rfpi_enable)
1347                        _rtl92c_phy_pi_mode_switch(hw, false);
1348                _rtl92c_phy_reload_adda_registers(hw, adda_reg,
1349                                                  rtlphy->adda_backup, 16);
1350                _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg,
1351                                                 rtlphy->iqk_mac_backup);
1352        }
1353}
1354
1355static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,
1356                                     char delta, bool is2t)
1357{
1358}
1359
1360static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1361                                          bool bmain, bool is2t)
1362{
1363        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1364
1365        if (is_hal_stop(rtlhal)) {
1366                rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);
1367                rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1368        }
1369        if (is2t) {
1370                if (bmain)
1371                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1372                                      BIT(5) | BIT(6), 0x1);
1373                else
1374                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1375                                      BIT(5) | BIT(6), 0x2);
1376        } else {
1377                if (bmain)
1378                        rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);
1379                else
1380                        rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
1381        }
1382}
1383
1384#undef IQK_ADDA_REG_NUM
1385#undef IQK_DELAY_TIME
1386
1387void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
1388{
1389        struct rtl_priv *rtlpriv = rtl_priv(hw);
1390        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1391        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1392
1393        long result[4][8];
1394        u8 i, final_candidate;
1395        bool b_patha_ok, b_pathb_ok;
1396        long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
1397            reg_ecc, reg_tmp = 0;
1398        bool is12simular, is13simular, is23simular;
1399        u32 iqk_bb_reg[10] = {
1400                ROFDM0_XARXIQIMBALANCE,
1401                ROFDM0_XBRXIQIMBALANCE,
1402                ROFDM0_ECCATHRESHOLD,
1403                ROFDM0_AGCRSSITABLE,
1404                ROFDM0_XATXIQIMBALANCE,
1405                ROFDM0_XBTXIQIMBALANCE,
1406                ROFDM0_XCTXIQIMBALANCE,
1407                ROFDM0_XCTXAFE,
1408                ROFDM0_XDTXAFE,
1409                ROFDM0_RXIQEXTANTA
1410        };
1411
1412        if (b_recovery) {
1413                _rtl92c_phy_reload_adda_registers(hw,
1414                                                  iqk_bb_reg,
1415                                                  rtlphy->iqk_bb_backup, 10);
1416                return;
1417        }
1418        for (i = 0; i < 8; i++) {
1419                result[0][i] = 0;
1420                result[1][i] = 0;
1421                result[2][i] = 0;
1422                result[3][i] = 0;
1423        }
1424        final_candidate = 0xff;
1425        b_patha_ok = false;
1426        b_pathb_ok = false;
1427        is12simular = false;
1428        is23simular = false;
1429        is13simular = false;
1430        for (i = 0; i < 3; i++) {
1431                if (IS_92C_SERIAL(rtlhal->version))
1432                        _rtl92c_phy_iq_calibrate(hw, result, i, true);
1433                else
1434                        _rtl92c_phy_iq_calibrate(hw, result, i, false);
1435                if (i == 1) {
1436                        is12simular = _rtl92c_phy_simularity_compare(hw,
1437                                                                     result, 0,
1438                                                                     1);
1439                        if (is12simular) {
1440                                final_candidate = 0;
1441                                break;
1442                        }
1443                }
1444                if (i == 2) {
1445                        is13simular = _rtl92c_phy_simularity_compare(hw,
1446                                                                     result, 0,
1447                                                                     2);
1448                        if (is13simular) {
1449                                final_candidate = 0;
1450                                break;
1451                        }
1452                        is23simular = _rtl92c_phy_simularity_compare(hw,
1453                                                                     result, 1,
1454                                                                     2);
1455                        if (is23simular)
1456                                final_candidate = 1;
1457                        else {
1458                                for (i = 0; i < 8; i++)
1459                                        reg_tmp += result[3][i];
1460
1461                                if (reg_tmp != 0)
1462                                        final_candidate = 3;
1463                                else
1464                                        final_candidate = 0xFF;
1465                        }
1466                }
1467        }
1468        for (i = 0; i < 4; i++) {
1469                reg_e94 = result[i][0];
1470                reg_e9c = result[i][1];
1471                reg_ea4 = result[i][2];
1472                reg_eac = result[i][3];
1473                reg_eb4 = result[i][4];
1474                reg_ebc = result[i][5];
1475                reg_ec4 = result[i][6];
1476                reg_ecc = result[i][7];
1477        }
1478        if (final_candidate != 0xff) {
1479                rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
1480                rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
1481                reg_ea4 = result[final_candidate][2];
1482                reg_eac = result[final_candidate][3];
1483                rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
1484                rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
1485                reg_ec4 = result[final_candidate][6];
1486                reg_ecc = result[final_candidate][7];
1487                b_patha_ok = true;
1488                b_pathb_ok = true;
1489        } else {
1490                rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
1491                rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
1492        }
1493        if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1494                _rtl92c_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
1495                                                   final_candidate,
1496                                                   (reg_ea4 == 0));
1497        if (IS_92C_SERIAL(rtlhal->version)) {
1498                if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */
1499                        _rtl92c_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok,
1500                                                           result,
1501                                                           final_candidate,
1502                                                           (reg_ec4 == 0));
1503        }
1504        _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg,
1505                                        rtlphy->iqk_bb_backup, 10);
1506}
1507EXPORT_SYMBOL(rtl92c_phy_iq_calibrate);
1508
1509void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw)
1510{
1511        struct rtl_priv *rtlpriv = rtl_priv(hw);
1512        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1513
1514        if (IS_92C_SERIAL(rtlhal->version))
1515                rtlpriv->cfg->ops->phy_lc_calibrate(hw, true);
1516        else
1517                rtlpriv->cfg->ops->phy_lc_calibrate(hw, false);
1518}
1519EXPORT_SYMBOL(rtl92c_phy_lc_calibrate);
1520
1521void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
1522{
1523        struct rtl_priv *rtlpriv = rtl_priv(hw);
1524        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1525        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1526
1527        if (rtlphy->apk_done)
1528                return;
1529        if (IS_92C_SERIAL(rtlhal->version))
1530                _rtl92c_phy_ap_calibrate(hw, delta, true);
1531        else
1532                _rtl92c_phy_ap_calibrate(hw, delta, false);
1533}
1534EXPORT_SYMBOL(rtl92c_phy_ap_calibrate);
1535
1536void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1537{
1538        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1539
1540        if (IS_92C_SERIAL(rtlhal->version))
1541                _rtl92c_phy_set_rfpath_switch(hw, bmain, true);
1542        else
1543                _rtl92c_phy_set_rfpath_switch(hw, bmain, false);
1544}
1545EXPORT_SYMBOL(rtl92c_phy_set_rfpath_switch);
1546
1547bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1548{
1549        struct rtl_priv *rtlpriv = rtl_priv(hw);
1550        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1551        bool postprocessing = false;
1552
1553        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1554                 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1555                  iotype, rtlphy->set_io_inprogress);
1556        do {
1557                switch (iotype) {
1558                case IO_CMD_RESUME_DM_BY_SCAN:
1559                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1560                                 "[IO CMD] Resume DM after scan.\n");
1561                        postprocessing = true;
1562                        break;
1563                case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
1564                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1565                                 "[IO CMD] Pause DM before scan.\n");
1566                        postprocessing = true;
1567                        break;
1568                default:
1569                        RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1570                                 "switch case not process\n");
1571                        break;
1572                }
1573        } while (false);
1574        if (postprocessing && !rtlphy->set_io_inprogress) {
1575                rtlphy->set_io_inprogress = true;
1576                rtlphy->current_io_type = iotype;
1577        } else {
1578                return false;
1579        }
1580        rtl92c_phy_set_io(hw);
1581        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
1582        return true;
1583}
1584EXPORT_SYMBOL(rtl92c_phy_set_io_cmd);
1585
1586void rtl92c_phy_set_io(struct ieee80211_hw *hw)
1587{
1588        struct rtl_priv *rtlpriv = rtl_priv(hw);
1589        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1590        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
1591
1592        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1593                 "--->Cmd(%#x), set_io_inprogress(%d)\n",
1594                  rtlphy->current_io_type, rtlphy->set_io_inprogress);
1595        switch (rtlphy->current_io_type) {
1596        case IO_CMD_RESUME_DM_BY_SCAN:
1597                dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
1598                rtl92c_dm_write_dig(hw);
1599                rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
1600                break;
1601        case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
1602                rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
1603                dm_digtable->cur_igvalue = 0x17;
1604                rtl92c_dm_write_dig(hw);
1605                break;
1606        default:
1607                RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1608                         "switch case not process\n");
1609                break;
1610        }
1611        rtlphy->set_io_inprogress = false;
1612        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1613                 "(%#x)\n", rtlphy->current_io_type);
1614}
1615EXPORT_SYMBOL(rtl92c_phy_set_io);
1616
1617void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw)
1618{
1619        struct rtl_priv *rtlpriv = rtl_priv(hw);
1620
1621        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
1622        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1623        rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1624        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1625        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1626        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1627}
1628EXPORT_SYMBOL(rtl92ce_phy_set_rf_on);
1629
1630void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw)
1631{
1632        u32 u4b_tmp;
1633        u8 delay = 5;
1634        struct rtl_priv *rtlpriv = rtl_priv(hw);
1635
1636        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1637        rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1638        rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1639        u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1640        while (u4b_tmp != 0 && delay > 0) {
1641                rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
1642                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1643                rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1644                u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1645                delay--;
1646        }
1647        if (delay == 0) {
1648                rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1649                rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1650                rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1651                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1652                RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1653                         "Switch RF timeout !!!.\n");
1654                return;
1655        }
1656        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1657        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
1658}
1659EXPORT_SYMBOL(_rtl92c_phy_set_rf_sleep);
1660