linux/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2009-2014  Realtek Corporation.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of version 2 of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 *
  14 * The full GNU General Public License is included in this distribution in the
  15 * file called LICENSE.
  16 *
  17 * Contact Information:
  18 * wlanfae <wlanfae@realtek.com>
  19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  20 * Hsinchu 300, Taiwan.
  21 *
  22 * Larry Finger <Larry.Finger@lwfinger.net>
  23 *
  24 *****************************************************************************/
  25
  26#include "../wifi.h"
  27#include "../efuse.h"
  28#include "../base.h"
  29#include "../regd.h"
  30#include "../cam.h"
  31#include "../ps.h"
  32#include "../pci.h"
  33#include "reg.h"
  34#include "def.h"
  35#include "phy.h"
  36#include "../rtl8723com/phy_common.h"
  37#include "dm.h"
  38#include "../rtl8723com/dm_common.h"
  39#include "fw.h"
  40#include "../rtl8723com/fw_common.h"
  41#include "led.h"
  42#include "hw.h"
  43#include "../pwrseqcmd.h"
  44#include "pwrseq.h"
  45#include "../btcoexist/rtl_btc.h"
  46
  47#define LLT_CONFIG      5
  48
  49static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw)
  50{
  51        struct rtl_priv *rtlpriv = rtl_priv(hw);
  52        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
  53        struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
  54        unsigned long flags;
  55
  56        spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
  57        while (skb_queue_len(&ring->queue)) {
  58                struct rtl_tx_desc *entry = &ring->desc[ring->idx];
  59                struct sk_buff *skb = __skb_dequeue(&ring->queue);
  60
  61                pci_unmap_single(rtlpci->pdev,
  62                                 rtlpriv->cfg->ops->get_desc(
  63                                 (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
  64                                 skb->len, PCI_DMA_TODEVICE);
  65                kfree_skb(skb);
  66                ring->idx = (ring->idx + 1) % ring->entries;
  67        }
  68        spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
  69}
  70
  71static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
  72                                        u8 set_bits, u8 clear_bits)
  73{
  74        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
  75        struct rtl_priv *rtlpriv = rtl_priv(hw);
  76
  77        rtlpci->reg_bcn_ctrl_val |= set_bits;
  78        rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
  79
  80        rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val);
  81}
  82
  83static void _rtl8723be_stop_tx_beacon(struct ieee80211_hw *hw)
  84{
  85        struct rtl_priv *rtlpriv = rtl_priv(hw);
  86        u8 tmp1byte;
  87
  88        tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
  89        rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
  90        rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
  91        tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
  92        tmp1byte &= ~(BIT(0));
  93        rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
  94}
  95
  96static void _rtl8723be_resume_tx_beacon(struct ieee80211_hw *hw)
  97{
  98        struct rtl_priv *rtlpriv = rtl_priv(hw);
  99        u8 tmp1byte;
 100
 101        tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
 102        rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
 103        rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
 104        tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
 105        tmp1byte |= BIT(1);
 106        rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
 107}
 108
 109static void _rtl8723be_enable_bcn_sub_func(struct ieee80211_hw *hw)
 110{
 111        _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(1));
 112}
 113
 114static void _rtl8723be_disable_bcn_sub_func(struct ieee80211_hw *hw)
 115{
 116        _rtl8723be_set_bcn_ctrl_reg(hw, BIT(1), 0);
 117}
 118
 119static void _rtl8723be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val,
 120                                       bool b_need_turn_off_ckk)
 121{
 122        struct rtl_priv *rtlpriv = rtl_priv(hw);
 123        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 124        bool b_support_remote_wake_up;
 125        u32 count = 0, isr_regaddr, content;
 126        bool b_schedule_timer = b_need_turn_off_ckk;
 127        rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
 128                                      (u8 *)(&b_support_remote_wake_up));
 129
 130        if (!rtlhal->fw_ready)
 131                return;
 132        if (!rtlpriv->psc.fw_current_inpsmode)
 133                return;
 134
 135        while (1) {
 136                spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
 137                if (rtlhal->fw_clk_change_in_progress) {
 138                        while (rtlhal->fw_clk_change_in_progress) {
 139                                spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
 140                                count++;
 141                                udelay(100);
 142                                if (count > 1000)
 143                                        return;
 144                                spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
 145                        }
 146                        spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
 147                } else {
 148                        rtlhal->fw_clk_change_in_progress = false;
 149                        spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
 150                        break;
 151                }
 152        }
 153
 154        if (IS_IN_LOW_POWER_STATE(rtlhal->fw_ps_state)) {
 155                rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
 156                                              (u8 *)(&rpwm_val));
 157                if (FW_PS_IS_ACK(rpwm_val)) {
 158                        isr_regaddr = REG_HISR;
 159                        content = rtl_read_dword(rtlpriv, isr_regaddr);
 160                        while (!(content & IMR_CPWM) && (count < 500)) {
 161                                udelay(50);
 162                                count++;
 163                                content = rtl_read_dword(rtlpriv, isr_regaddr);
 164                        }
 165
 166                        if (content & IMR_CPWM) {
 167                                rtl_write_word(rtlpriv, isr_regaddr, 0x0100);
 168                                rtlhal->fw_ps_state = FW_PS_STATE_RF_ON;
 169                                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 170                                         "Receive CPWM INT!!! Set pHalData->FwPSState = %X\n",
 171                                         rtlhal->fw_ps_state);
 172                        }
 173                }
 174
 175                spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
 176                rtlhal->fw_clk_change_in_progress = false;
 177                spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
 178                if (b_schedule_timer)
 179                        mod_timer(&rtlpriv->works.fw_clockoff_timer,
 180                                  jiffies + MSECS(10));
 181        } else  {
 182                spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
 183                rtlhal->fw_clk_change_in_progress = false;
 184                spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
 185        }
 186}
 187
 188static void _rtl8723be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val)
 189{
 190        struct rtl_priv *rtlpriv = rtl_priv(hw);
 191        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 192        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 193        struct rtl8192_tx_ring *ring;
 194        enum rf_pwrstate rtstate;
 195        bool b_schedule_timer = false;
 196        u8 queue;
 197
 198        if (!rtlhal->fw_ready)
 199                return;
 200        if (!rtlpriv->psc.fw_current_inpsmode)
 201                return;
 202        if (!rtlhal->allow_sw_to_change_hwclc)
 203                return;
 204        rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate));
 205        if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF)
 206                return;
 207
 208        for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) {
 209                ring = &rtlpci->tx_ring[queue];
 210                if (skb_queue_len(&ring->queue)) {
 211                        b_schedule_timer = true;
 212                        break;
 213                }
 214        }
 215
 216        if (b_schedule_timer) {
 217                mod_timer(&rtlpriv->works.fw_clockoff_timer,
 218                          jiffies + MSECS(10));
 219                return;
 220        }
 221
 222        if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR) {
 223                spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
 224                if (!rtlhal->fw_clk_change_in_progress) {
 225                        rtlhal->fw_clk_change_in_progress = true;
 226                        spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
 227                        rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
 228                        rtl_write_word(rtlpriv, REG_HISR, 0x0100);
 229                        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
 230                                                      (u8 *)(&rpwm_val));
 231                        spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
 232                        rtlhal->fw_clk_change_in_progress = false;
 233                        spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
 234                } else {
 235                        spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
 236                        mod_timer(&rtlpriv->works.fw_clockoff_timer,
 237                                  jiffies + MSECS(10));
 238                }
 239        }
 240
 241}
 242
 243static void _rtl8723be_set_fw_ps_rf_on(struct ieee80211_hw *hw)
 244{
 245        u8 rpwm_val = 0;
 246        rpwm_val |= (FW_PS_STATE_RF_OFF | FW_PS_ACK);
 247        _rtl8723be_set_fw_clock_on(hw, rpwm_val, true);
 248}
 249
 250static void _rtl8723be_fwlps_leave(struct ieee80211_hw *hw)
 251{
 252        struct rtl_priv *rtlpriv = rtl_priv(hw);
 253        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 254        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 255        bool fw_current_inps = false;
 256        u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE;
 257
 258        if (ppsc->low_power_enable) {
 259                rpwm_val = (FW_PS_STATE_ALL_ON | FW_PS_ACK);/* RF on */
 260                _rtl8723be_set_fw_clock_on(hw, rpwm_val, false);
 261                rtlhal->allow_sw_to_change_hwclc = false;
 262                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
 263                                              (u8 *)(&fw_pwrmode));
 264                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
 265                                              (u8 *)(&fw_current_inps));
 266        } else {
 267                rpwm_val = FW_PS_STATE_ALL_ON;  /* RF on */
 268                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
 269                                              (u8 *)(&rpwm_val));
 270                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
 271                                              (u8 *)(&fw_pwrmode));
 272                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
 273                                              (u8 *)(&fw_current_inps));
 274        }
 275
 276}
 277
 278static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw)
 279{
 280        struct rtl_priv *rtlpriv = rtl_priv(hw);
 281        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 282        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 283        bool fw_current_inps = true;
 284        u8 rpwm_val;
 285
 286        if (ppsc->low_power_enable) {
 287                rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR;  /* RF off */
 288                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
 289                                              (u8 *)(&fw_current_inps));
 290                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
 291                                              (u8 *)(&ppsc->fwctrl_psmode));
 292                rtlhal->allow_sw_to_change_hwclc = true;
 293                _rtl8723be_set_fw_clock_off(hw, rpwm_val);
 294        } else {
 295                rpwm_val = FW_PS_STATE_RF_OFF;  /* RF off */
 296                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
 297                                              (u8 *)(&fw_current_inps));
 298                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
 299                                              (u8 *)(&ppsc->fwctrl_psmode));
 300                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
 301                                              (u8 *)(&rpwm_val));
 302        }
 303
 304}
 305
 306void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 307{
 308        struct rtl_priv *rtlpriv = rtl_priv(hw);
 309        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 310        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 311
 312        switch (variable) {
 313        case HW_VAR_RCR:
 314                *((u32 *)(val)) = rtlpci->receive_config;
 315                break;
 316        case HW_VAR_RF_STATE:
 317                *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
 318                break;
 319        case HW_VAR_FWLPS_RF_ON:{
 320                enum rf_pwrstate rfState;
 321                u32 val_rcr;
 322
 323                rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
 324                                              (u8 *)(&rfState));
 325                if (rfState == ERFOFF) {
 326                        *((bool *)(val)) = true;
 327                } else {
 328                        val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
 329                        val_rcr &= 0x00070000;
 330                        if (val_rcr)
 331                                *((bool *)(val)) = false;
 332                        else
 333                                *((bool *)(val)) = true;
 334                }
 335                }
 336                break;
 337        case HW_VAR_FW_PSMODE_STATUS:
 338                *((bool *)(val)) = ppsc->fw_current_inpsmode;
 339                break;
 340        case HW_VAR_CORRECT_TSF:{
 341                u64 tsf;
 342                u32 *ptsf_low = (u32 *)&tsf;
 343                u32 *ptsf_high = ((u32 *)&tsf) + 1;
 344
 345                *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
 346                *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
 347
 348                *((u64 *)(val)) = tsf;
 349                }
 350                break;
 351        case HAL_DEF_WOWLAN:
 352                break;
 353        default:
 354                RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
 355                         "switch case %#x not processed\n", variable);
 356                break;
 357        }
 358}
 359
 360static void _rtl8723be_download_rsvd_page(struct ieee80211_hw *hw)
 361{
 362        struct rtl_priv *rtlpriv = rtl_priv(hw);
 363        u8 tmp_regcr, tmp_reg422, bcnvalid_reg;
 364        u8 count = 0, dlbcn_count = 0;
 365        bool b_recover = false;
 366
 367        tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
 368        rtl_write_byte(rtlpriv, REG_CR + 1,
 369                       (tmp_regcr | BIT(0)));
 370
 371        _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
 372        _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
 373
 374        tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
 375        rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422 & (~BIT(6)));
 376        if (tmp_reg422 & BIT(6))
 377                b_recover = true;
 378
 379        do {
 380                bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2);
 381                rtl_write_byte(rtlpriv, REG_TDECTRL + 2,
 382                               (bcnvalid_reg | BIT(0)));
 383                _rtl8723be_return_beacon_queue_skb(hw);
 384
 385                rtl8723be_set_fw_rsvdpagepkt(hw, 0);
 386                bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2);
 387                count = 0;
 388                while (!(bcnvalid_reg & BIT(0)) && count < 20) {
 389                        count++;
 390                        udelay(10);
 391                        bcnvalid_reg = rtl_read_byte(rtlpriv,
 392                                                     REG_TDECTRL + 2);
 393                }
 394                dlbcn_count++;
 395        } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5);
 396
 397        if (bcnvalid_reg & BIT(0))
 398                rtl_write_byte(rtlpriv, REG_TDECTRL + 2, BIT(0));
 399
 400        _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
 401        _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
 402
 403        if (b_recover)
 404                rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422);
 405
 406        tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
 407        rtl_write_byte(rtlpriv, REG_CR + 1, (tmp_regcr & ~(BIT(0))));
 408}
 409
 410void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 411{
 412        struct rtl_priv *rtlpriv = rtl_priv(hw);
 413        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 414        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 415        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 416        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 417        u8 idx;
 418
 419        switch (variable) {
 420        case HW_VAR_ETHER_ADDR:
 421                for (idx = 0; idx < ETH_ALEN; idx++)
 422                        rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]);
 423                break;
 424        case HW_VAR_BASIC_RATE:{
 425                u16 b_rate_cfg = ((u16 *)val)[0];
 426                u8 rate_index = 0;
 427                b_rate_cfg = b_rate_cfg & 0x15f;
 428                b_rate_cfg |= 0x01;
 429                rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff);
 430                rtl_write_byte(rtlpriv, REG_RRSR + 1, (b_rate_cfg >> 8) & 0xff);
 431                while (b_rate_cfg > 0x1) {
 432                        b_rate_cfg = (b_rate_cfg >> 1);
 433                        rate_index++;
 434                }
 435                rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, rate_index);
 436                }
 437                break;
 438        case HW_VAR_BSSID:
 439                for (idx = 0; idx < ETH_ALEN; idx++)
 440                        rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]);
 441
 442                break;
 443        case HW_VAR_SIFS:
 444                rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
 445                rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
 446
 447                rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
 448                rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
 449
 450                if (!mac->ht_enable)
 451                        rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e);
 452                else
 453                        rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
 454                                       *((u16 *)val));
 455                break;
 456        case HW_VAR_SLOT_TIME:{
 457                u8 e_aci;
 458
 459                RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
 460                         "HW_VAR_SLOT_TIME %x\n", val[0]);
 461
 462                rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
 463
 464                for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
 465                        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
 466                                                      (u8 *)(&e_aci));
 467                }
 468                }
 469                break;
 470        case HW_VAR_ACK_PREAMBLE:{
 471                u8 reg_tmp;
 472                u8 short_preamble = (bool)(*(u8 *)val);
 473                reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2);
 474                if (short_preamble) {
 475                        reg_tmp |= 0x02;
 476                        rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
 477                } else {
 478                        reg_tmp &= 0xFD;
 479                        rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
 480                }
 481                }
 482                break;
 483        case HW_VAR_WPA_CONFIG:
 484                rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
 485                break;
 486        case HW_VAR_AMPDU_MIN_SPACE:{
 487                u8 min_spacing_to_set;
 488                u8 sec_min_space;
 489
 490                min_spacing_to_set = *((u8 *)val);
 491                if (min_spacing_to_set <= 7) {
 492                        sec_min_space = 0;
 493
 494                        if (min_spacing_to_set < sec_min_space)
 495                                min_spacing_to_set = sec_min_space;
 496
 497                        mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) |
 498                                              min_spacing_to_set);
 499
 500                        *val = min_spacing_to_set;
 501
 502                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
 503                                 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
 504                                  mac->min_space_cfg);
 505
 506                        rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
 507                                       mac->min_space_cfg);
 508                }
 509                }
 510                break;
 511        case HW_VAR_SHORTGI_DENSITY:{
 512                u8 density_to_set;
 513
 514                density_to_set = *((u8 *)val);
 515                mac->min_space_cfg |= (density_to_set << 3);
 516
 517                RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
 518                         "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
 519                          mac->min_space_cfg);
 520
 521                rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
 522                               mac->min_space_cfg);
 523                }
 524                break;
 525        case HW_VAR_AMPDU_FACTOR:{
 526                u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
 527                u8 factor_toset;
 528                u8 *p_regtoset = NULL;
 529                u8 index = 0;
 530
 531                p_regtoset = regtoset_normal;
 532
 533                factor_toset = *((u8 *)val);
 534                if (factor_toset <= 3) {
 535                        factor_toset = (1 << (factor_toset + 2));
 536                        if (factor_toset > 0xf)
 537                                factor_toset = 0xf;
 538
 539                        for (index = 0; index < 4; index++) {
 540                                if ((p_regtoset[index] & 0xf0) >
 541                                    (factor_toset << 4))
 542                                        p_regtoset[index] =
 543                                                (p_regtoset[index] & 0x0f) |
 544                                                (factor_toset << 4);
 545
 546                                if ((p_regtoset[index] & 0x0f) > factor_toset)
 547                                        p_regtoset[index] =
 548                                                (p_regtoset[index] & 0xf0) |
 549                                                (factor_toset);
 550
 551                                rtl_write_byte(rtlpriv,
 552                                               (REG_AGGLEN_LMT + index),
 553                                               p_regtoset[index]);
 554
 555                        }
 556
 557                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
 558                                 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
 559                                  factor_toset);
 560                }
 561                }
 562                break;
 563        case HW_VAR_AC_PARAM:{
 564                u8 e_aci = *((u8 *)val);
 565                rtl8723_dm_init_edca_turbo(hw);
 566
 567                if (rtlpci->acm_method != EACMWAY2_SW)
 568                        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
 569                                                      (u8 *)(&e_aci));
 570                }
 571                break;
 572        case HW_VAR_ACM_CTRL:{
 573                u8 e_aci = *((u8 *)val);
 574                union aci_aifsn *p_aci_aifsn =
 575                                (union aci_aifsn *)(&(mac->ac[0].aifs));
 576                u8 acm = p_aci_aifsn->f.acm;
 577                u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
 578
 579                acm_ctrl =
 580                    acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
 581
 582                if (acm) {
 583                        switch (e_aci) {
 584                        case AC0_BE:
 585                                acm_ctrl |= ACMHW_BEQEN;
 586                                break;
 587                        case AC2_VI:
 588                                acm_ctrl |= ACMHW_VIQEN;
 589                                break;
 590                        case AC3_VO:
 591                                acm_ctrl |= ACMHW_VOQEN;
 592                                break;
 593                        default:
 594                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 595                                         "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
 596                                         acm);
 597                                break;
 598                        }
 599                } else {
 600                        switch (e_aci) {
 601                        case AC0_BE:
 602                                acm_ctrl &= (~ACMHW_BEQEN);
 603                                break;
 604                        case AC2_VI:
 605                                acm_ctrl &= (~ACMHW_VIQEN);
 606                                break;
 607                        case AC3_VO:
 608                                acm_ctrl &= (~ACMHW_VOQEN);
 609                                break;
 610                        default:
 611                                RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
 612                                         "switch case %#x not processed\n",
 613                                         e_aci);
 614                                break;
 615                        }
 616                }
 617
 618                RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
 619                         "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
 620                         acm_ctrl);
 621                rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
 622                }
 623                break;
 624        case HW_VAR_RCR:
 625                rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]);
 626                rtlpci->receive_config = ((u32 *)(val))[0];
 627                break;
 628        case HW_VAR_RETRY_LIMIT:{
 629                u8 retry_limit = ((u8 *)(val))[0];
 630
 631                rtl_write_word(rtlpriv, REG_RL,
 632                               retry_limit << RETRY_LIMIT_SHORT_SHIFT |
 633                               retry_limit << RETRY_LIMIT_LONG_SHIFT);
 634                }
 635                break;
 636        case HW_VAR_DUAL_TSF_RST:
 637                rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
 638                break;
 639        case HW_VAR_EFUSE_BYTES:
 640                rtlefuse->efuse_usedbytes = *((u16 *)val);
 641                break;
 642        case HW_VAR_EFUSE_USAGE:
 643                rtlefuse->efuse_usedpercentage = *((u8 *)val);
 644                break;
 645        case HW_VAR_IO_CMD:
 646                rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val));
 647                break;
 648        case HW_VAR_SET_RPWM:{
 649                u8 rpwm_val;
 650
 651                rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
 652                udelay(1);
 653
 654                if (rpwm_val & BIT(7)) {
 655                        rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val));
 656                } else {
 657                        rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
 658                                       ((*(u8 *)val) | BIT(7)));
 659                }
 660                }
 661                break;
 662        case HW_VAR_H2C_FW_PWRMODE:
 663                rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
 664                break;
 665        case HW_VAR_FW_PSMODE_STATUS:
 666                ppsc->fw_current_inpsmode = *((bool *)val);
 667                break;
 668        case HW_VAR_RESUME_CLK_ON:
 669                _rtl8723be_set_fw_ps_rf_on(hw);
 670                break;
 671        case HW_VAR_FW_LPS_ACTION:{
 672                bool b_enter_fwlps = *((bool *)val);
 673
 674                if (b_enter_fwlps)
 675                        _rtl8723be_fwlps_enter(hw);
 676                else
 677                        _rtl8723be_fwlps_leave(hw);
 678                }
 679                break;
 680        case HW_VAR_H2C_FW_JOINBSSRPT:{
 681                u8 mstatus = (*(u8 *)val);
 682
 683                if (mstatus == RT_MEDIA_CONNECT) {
 684                        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
 685                        _rtl8723be_download_rsvd_page(hw);
 686                }
 687                rtl8723be_set_fw_media_status_rpt_cmd(hw, mstatus);
 688                }
 689                break;
 690        case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
 691                rtl8723be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
 692                break;
 693        case HW_VAR_AID:{
 694                u16 u2btmp;
 695                u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
 696                u2btmp &= 0xC000;
 697                rtl_write_word(rtlpriv, REG_BCN_PSR_RPT,
 698                               (u2btmp | mac->assoc_id));
 699                }
 700                break;
 701        case HW_VAR_CORRECT_TSF:{
 702                u8 btype_ibss = ((u8 *)(val))[0];
 703
 704                if (btype_ibss)
 705                        _rtl8723be_stop_tx_beacon(hw);
 706
 707                _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
 708
 709                rtl_write_dword(rtlpriv, REG_TSFTR,
 710                                (u32) (mac->tsf & 0xffffffff));
 711                rtl_write_dword(rtlpriv, REG_TSFTR + 4,
 712                                (u32) ((mac->tsf >> 32) & 0xffffffff));
 713
 714                _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
 715
 716                if (btype_ibss)
 717                        _rtl8723be_resume_tx_beacon(hw);
 718                }
 719                break;
 720        case HW_VAR_KEEP_ALIVE:{
 721                u8 array[2];
 722                array[0] = 0xff;
 723                array[1] = *((u8 *)val);
 724                rtl8723be_fill_h2c_cmd(hw, H2C_8723B_KEEP_ALIVE_CTRL, 2, array);
 725                }
 726                break;
 727        default:
 728                RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
 729                         "switch case %#x not processed\n", variable);
 730                break;
 731        }
 732}
 733
 734static bool _rtl8723be_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
 735{
 736        struct rtl_priv *rtlpriv = rtl_priv(hw);
 737        bool status = true;
 738        long count = 0;
 739        u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
 740                    _LLT_OP(_LLT_WRITE_ACCESS);
 741
 742        rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
 743
 744        do {
 745                value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
 746                if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
 747                        break;
 748
 749                if (count > POLLING_LLT_THRESHOLD) {
 750                        pr_err("Failed to polling write LLT done at address %d!\n",
 751                               address);
 752                        status = false;
 753                        break;
 754                }
 755        } while (++count);
 756
 757        return status;
 758}
 759
 760static bool _rtl8723be_llt_table_init(struct ieee80211_hw *hw)
 761{
 762        struct rtl_priv *rtlpriv = rtl_priv(hw);
 763        unsigned short i;
 764        u8 txpktbuf_bndy;
 765        u8 maxPage;
 766        bool status;
 767
 768        maxPage = 255;
 769        txpktbuf_bndy = 245;
 770
 771        rtl_write_dword(rtlpriv, REG_TRXFF_BNDY,
 772                        (0x27FF0000 | txpktbuf_bndy));
 773        rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
 774
 775        rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
 776        rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
 777
 778        rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
 779        rtl_write_byte(rtlpriv, REG_PBP, 0x31);
 780        rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
 781
 782        for (i = 0; i < (txpktbuf_bndy - 1); i++) {
 783                status = _rtl8723be_llt_write(hw, i, i + 1);
 784                if (!status)
 785                        return status;
 786        }
 787
 788        status = _rtl8723be_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
 789
 790        if (!status)
 791                return status;
 792
 793        for (i = txpktbuf_bndy; i < maxPage; i++) {
 794                status = _rtl8723be_llt_write(hw, i, (i + 1));
 795                if (!status)
 796                        return status;
 797        }
 798
 799        status = _rtl8723be_llt_write(hw, maxPage, txpktbuf_bndy);
 800        if (!status)
 801                return status;
 802
 803        rtl_write_dword(rtlpriv, REG_RQPN, 0x80e40808);
 804        rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00);
 805
 806        return true;
 807}
 808
 809static void _rtl8723be_gen_refresh_led_state(struct ieee80211_hw *hw)
 810{
 811        struct rtl_priv *rtlpriv = rtl_priv(hw);
 812        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 813        struct rtl_led *pled0 = &rtlpriv->ledctl.sw_led0;
 814
 815        if (rtlpriv->rtlhal.up_first_time)
 816                return;
 817
 818        if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
 819                rtl8723be_sw_led_on(hw, pled0);
 820        else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
 821                rtl8723be_sw_led_on(hw, pled0);
 822        else
 823                rtl8723be_sw_led_off(hw, pled0);
 824}
 825
 826static bool _rtl8723be_init_mac(struct ieee80211_hw *hw)
 827{
 828        struct rtl_priv *rtlpriv = rtl_priv(hw);
 829        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 830        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 831        unsigned char bytetmp;
 832        unsigned short wordtmp;
 833
 834        rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
 835
 836        /*Auto Power Down to CHIP-off State*/
 837        bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7));
 838        rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
 839
 840        /* HW Power on sequence */
 841        if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK,
 842                                      PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,
 843                                      RTL8723_NIC_ENABLE_FLOW)) {
 844                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 845                         "init MAC Fail as power on failure\n");
 846                return false;
 847        }
 848
 849        bytetmp = rtl_read_byte(rtlpriv, REG_MULTI_FUNC_CTRL);
 850        rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, bytetmp | BIT(3));
 851
 852        bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4);
 853        rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp);
 854
 855        bytetmp = rtl_read_byte(rtlpriv, REG_CR);
 856        bytetmp = 0xff;
 857        rtl_write_byte(rtlpriv, REG_CR, bytetmp);
 858        mdelay(2);
 859
 860        bytetmp = rtl_read_byte(rtlpriv, REG_HWSEQ_CTRL);
 861        bytetmp |= 0x7f;
 862        rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp);
 863        mdelay(2);
 864
 865        bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CFG + 3);
 866        if (bytetmp & BIT(0)) {
 867                bytetmp = rtl_read_byte(rtlpriv, 0x7c);
 868                rtl_write_byte(rtlpriv, 0x7c, bytetmp | BIT(6));
 869        }
 870
 871        bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR);
 872        rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp | BIT(3));
 873        bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1);
 874        rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp & (~BIT(4)));
 875
 876        rtl_write_word(rtlpriv, REG_CR, 0x2ff);
 877
 878        if (!rtlhal->mac_func_enable) {
 879                if (_rtl8723be_llt_table_init(hw) == false)
 880                        return false;
 881        }
 882
 883        rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
 884        rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff);
 885
 886        /* Enable FW Beamformer Interrupt */
 887        bytetmp = rtl_read_byte(rtlpriv, REG_FWIMR + 3);
 888        rtl_write_byte(rtlpriv, REG_FWIMR + 3, bytetmp | BIT(6));
 889
 890        wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
 891        wordtmp &= 0xf;
 892        wordtmp |= 0xF5B1;
 893        rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
 894
 895        rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
 896        rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
 897        rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF);
 898        rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
 899
 900        rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
 901                        ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
 902                        DMA_BIT_MASK(32));
 903        rtl_write_dword(rtlpriv, REG_MGQ_DESA,
 904                        (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
 905                        DMA_BIT_MASK(32));
 906        rtl_write_dword(rtlpriv, REG_VOQ_DESA,
 907                        (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
 908        rtl_write_dword(rtlpriv, REG_VIQ_DESA,
 909                        (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
 910        rtl_write_dword(rtlpriv, REG_BEQ_DESA,
 911                        (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
 912        rtl_write_dword(rtlpriv, REG_BKQ_DESA,
 913                        (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
 914        rtl_write_dword(rtlpriv, REG_HQ_DESA,
 915                        (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
 916                        DMA_BIT_MASK(32));
 917        rtl_write_dword(rtlpriv, REG_RX_DESA,
 918                        (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
 919                        DMA_BIT_MASK(32));
 920
 921        bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3);
 922        rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0x77);
 923
 924        rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
 925
 926        rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
 927
 928        rtl_write_byte(rtlpriv, REG_SECONDARY_CCA_CTRL, 0x3);
 929
 930        /* <20130114, Kordan> The following setting is
 931         * only for DPDT and Fixed board type.
 932         * TODO:  A better solution is configure it
 933         * according EFUSE during the run-time.
 934         */
 935        rtl_set_bbreg(hw, 0x64, BIT(20), 0x0);/* 0x66[4]=0 */
 936        rtl_set_bbreg(hw, 0x64, BIT(24), 0x0);/* 0x66[8]=0 */
 937        rtl_set_bbreg(hw, 0x40, BIT(4), 0x0)/* 0x40[4]=0 */;
 938        rtl_set_bbreg(hw, 0x40, BIT(3), 0x1)/* 0x40[3]=1 */;
 939        rtl_set_bbreg(hw, 0x4C, BIT(24) | BIT(23), 0x2)/* 0x4C[24:23]=10 */;
 940        rtl_set_bbreg(hw, 0x944, BIT(1) | BIT(0), 0x3)/* 0x944[1:0]=11 */;
 941        rtl_set_bbreg(hw, 0x930, MASKBYTE0, 0x77)/* 0x930[7:0]=77 */;
 942        rtl_set_bbreg(hw, 0x38, BIT(11), 0x1)/* 0x38[11]=1 */;
 943
 944        bytetmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
 945        rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, bytetmp & (~BIT(2)));
 946
 947        _rtl8723be_gen_refresh_led_state(hw);
 948        return true;
 949}
 950
 951static void _rtl8723be_hw_configure(struct ieee80211_hw *hw)
 952{
 953        struct rtl_priv *rtlpriv = rtl_priv(hw);
 954        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 955        u32 reg_rrsr;
 956
 957        reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
 958        /* Init value for RRSR. */
 959        rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr);
 960
 961        /* ARFB table 9 for 11ac 5G 2SS */
 962        rtl_write_dword(rtlpriv, REG_ARFR0 + 4, 0xfffff000);
 963
 964        /* ARFB table 10 for 11ac 5G 1SS */
 965        rtl_write_dword(rtlpriv, REG_ARFR1 + 4, 0x003ff000);
 966
 967        /* CF-End setting. */
 968        rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F00);
 969
 970        /* 0x456 = 0x70, sugguested by Zhilin */
 971        rtl_write_byte(rtlpriv, REG_AMPDU_MAX_TIME, 0x70);
 972
 973        /* Set retry limit */
 974        rtl_write_word(rtlpriv, REG_RL, 0x0707);
 975
 976        /* Set Data / Response auto rate fallack retry count */
 977        rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
 978        rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
 979        rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
 980        rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
 981
 982        rtlpci->reg_bcn_ctrl_val = 0x1d;
 983        rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val);
 984
 985        /* TBTT prohibit hold time. Suggested by designer TimChen. */
 986        rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); /* 8 ms */
 987
 988        rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040);
 989
 990        /*For Rx TP. Suggested by SD1 Richard. Added by tynli. 2010.04.12.*/
 991        rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666);
 992
 993        rtl_write_byte(rtlpriv, REG_HT_SINGLE_AMPDU, 0x80);
 994
 995        rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20);
 996
 997        rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x1F);
 998}
 999
1000static u8 _rtl8723be_dbi_read(struct rtl_priv *rtlpriv, u16 addr)
1001{
1002        u16 read_addr = addr & 0xfffc;
1003        u8 ret = 0, tmp = 0, count = 0;
1004
1005        rtl_write_word(rtlpriv, REG_DBI_ADDR, read_addr);
1006        rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x2);
1007        tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1008        count = 0;
1009        while (tmp && count < 20) {
1010                udelay(10);
1011                tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1012                count++;
1013        }
1014        if (0 == tmp) {
1015                read_addr = REG_DBI_RDATA + addr % 4;
1016                ret = rtl_read_byte(rtlpriv, read_addr);
1017        }
1018
1019        return ret;
1020}
1021
1022static void _rtl8723be_dbi_write(struct rtl_priv *rtlpriv, u16 addr, u8 data)
1023{
1024        u8 tmp = 0, count = 0;
1025        u16 write_addr = 0, remainder = addr % 4;
1026
1027        /* Write DBI 1Byte Data */
1028        write_addr = REG_DBI_WDATA + remainder;
1029        rtl_write_byte(rtlpriv, write_addr, data);
1030
1031        /* Write DBI 2Byte Address & Write Enable */
1032        write_addr = (addr & 0xfffc) | (BIT(0) << (remainder + 12));
1033        rtl_write_word(rtlpriv, REG_DBI_ADDR, write_addr);
1034
1035        /* Write DBI Write Flag */
1036        rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x1);
1037
1038        tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1039        count = 0;
1040        while (tmp && count < 20) {
1041                udelay(10);
1042                tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1043                count++;
1044        }
1045}
1046
1047static u16 _rtl8723be_mdio_read(struct rtl_priv *rtlpriv, u8 addr)
1048{
1049        u16 ret = 0;
1050        u8 tmp = 0, count = 0;
1051
1052        rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(6));
1053        tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
1054        count = 0;
1055        while (tmp && count < 20) {
1056                udelay(10);
1057                tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
1058                count++;
1059        }
1060
1061        if (0 == tmp)
1062                ret = rtl_read_word(rtlpriv, REG_MDIO_RDATA);
1063
1064        return ret;
1065}
1066
1067static void _rtl8723be_mdio_write(struct rtl_priv *rtlpriv, u8 addr, u16 data)
1068{
1069        u8 tmp = 0, count = 0;
1070
1071        rtl_write_word(rtlpriv, REG_MDIO_WDATA, data);
1072        rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(5));
1073        tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
1074        count = 0;
1075        while (tmp && count < 20) {
1076                udelay(10);
1077                tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
1078                count++;
1079        }
1080}
1081
1082static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw)
1083{
1084        struct rtl_priv *rtlpriv = rtl_priv(hw);
1085        u8 tmp8 = 0;
1086        u16 tmp16 = 0;
1087
1088        /* <Roger_Notes> Overwrite following ePHY parameter for
1089         * some platform compatibility issue,
1090         * especially when CLKReq is enabled, 2012.11.09.
1091         */
1092        tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x01);
1093        if (tmp16 != 0x0663)
1094                _rtl8723be_mdio_write(rtlpriv, 0x01, 0x0663);
1095
1096        tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x04);
1097        if (tmp16 != 0x7544)
1098                _rtl8723be_mdio_write(rtlpriv, 0x04, 0x7544);
1099
1100        tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x06);
1101        if (tmp16 != 0xB880)
1102                _rtl8723be_mdio_write(rtlpriv, 0x06, 0xB880);
1103
1104        tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x07);
1105        if (tmp16 != 0x4000)
1106                _rtl8723be_mdio_write(rtlpriv, 0x07, 0x4000);
1107
1108        tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x08);
1109        if (tmp16 != 0x9003)
1110                _rtl8723be_mdio_write(rtlpriv, 0x08, 0x9003);
1111
1112        tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x09);
1113        if (tmp16 != 0x0D03)
1114                _rtl8723be_mdio_write(rtlpriv, 0x09, 0x0D03);
1115
1116        tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0A);
1117        if (tmp16 != 0x4037)
1118                _rtl8723be_mdio_write(rtlpriv, 0x0A, 0x4037);
1119
1120        tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0B);
1121        if (tmp16 != 0x0070)
1122                _rtl8723be_mdio_write(rtlpriv, 0x0B, 0x0070);
1123
1124        /* Configuration Space offset 0x70f BIT7 is used to control L0S */
1125        tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x70f);
1126        _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7));
1127
1128        /* Configuration Space offset 0x719 Bit3 is for L1
1129         * BIT4 is for clock request
1130         */
1131        tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x719);
1132        _rtl8723be_dbi_write(rtlpriv, 0x719, tmp8 | BIT(3) | BIT(4));
1133}
1134
1135void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw)
1136{
1137        struct rtl_priv *rtlpriv = rtl_priv(hw);
1138        u8 sec_reg_value;
1139
1140        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1141                 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
1142                  rtlpriv->sec.pairwise_enc_algorithm,
1143                  rtlpriv->sec.group_enc_algorithm);
1144
1145        if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
1146                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1147                         "not open hw encryption\n");
1148                return;
1149        }
1150
1151        sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE;
1152
1153        if (rtlpriv->sec.use_defaultkey) {
1154                sec_reg_value |= SCR_TXUSEDK;
1155                sec_reg_value |= SCR_RXUSEDK;
1156        }
1157
1158        sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
1159
1160        rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
1161
1162        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1163                 "The SECR-value %x\n", sec_reg_value);
1164
1165        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
1166}
1167
1168static void _rtl8723be_poweroff_adapter(struct ieee80211_hw *hw)
1169{
1170        struct rtl_priv *rtlpriv = rtl_priv(hw);
1171        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1172        u8 u1b_tmp;
1173
1174        rtlhal->mac_func_enable = false;
1175        /* Combo (PCIe + USB) Card and PCIe-MF Card */
1176        /* 1. Run LPS WL RFOFF flow */
1177        rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1178                                 PWR_INTF_PCI_MSK, RTL8723_NIC_LPS_ENTER_FLOW);
1179
1180        /* 2. 0x1F[7:0] = 0 */
1181        /* turn off RF */
1182        /* rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); */
1183        if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) &&
1184            rtlhal->fw_ready) {
1185                rtl8723be_firmware_selfreset(hw);
1186        }
1187
1188        /* Reset MCU. Suggested by Filen. */
1189        u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1190        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
1191
1192        /* g.   MCUFWDL 0x80[1:0]=0      */
1193        /* reset MCU ready status */
1194        rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1195
1196        /* HW card disable configuration. */
1197        rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1198                                 PWR_INTF_PCI_MSK, RTL8723_NIC_DISABLE_FLOW);
1199
1200        /* Reset MCU IO Wrapper */
1201        u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1202        rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
1203        u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1204        rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1b_tmp | BIT(0));
1205
1206        /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */
1207        /* lock ISO/CLK/Power control register */
1208        rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
1209}
1210
1211static bool _rtl8723be_check_pcie_dma_hang(struct rtl_priv *rtlpriv)
1212{
1213        u8 tmp;
1214
1215        /* write reg 0x350 Bit[26]=1. Enable debug port. */
1216        tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3);
1217        if (!(tmp & BIT(2))) {
1218                rtl_write_byte(rtlpriv, REG_DBI_CTRL + 3, (tmp | BIT(2)));
1219                mdelay(100); /* Suggested by DD Justin_tsai. */
1220        }
1221
1222        /* read reg 0x350 Bit[25] if 1 : RX hang
1223         * read reg 0x350 Bit[24] if 1 : TX hang
1224         */
1225        tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3);
1226        if ((tmp & BIT(0)) || (tmp & BIT(1))) {
1227                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1228                         "CheckPcieDMAHang8723BE(): true!!\n");
1229                return true;
1230        }
1231        return false;
1232}
1233
1234static void _rtl8723be_reset_pcie_interface_dma(struct rtl_priv *rtlpriv,
1235                                                bool mac_power_on)
1236{
1237        u8 tmp;
1238        bool release_mac_rx_pause;
1239        u8 backup_pcie_dma_pause;
1240
1241        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1242                 "ResetPcieInterfaceDMA8723BE()\n");
1243
1244        /* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03"
1245         * released by SD1 Alan.
1246         * 2013.05.07, by tynli.
1247         */
1248
1249        /* 1. disable register write lock
1250         *      write 0x1C bit[1:0] = 2'h0
1251         *      write 0xCC bit[2] = 1'b1
1252         */
1253        tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL);
1254        tmp &= ~(BIT(1) | BIT(0));
1255        rtl_write_byte(rtlpriv, REG_RSV_CTRL, tmp);
1256        tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1257        tmp |= BIT(2);
1258        rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1259
1260        /* 2. Check and pause TRX DMA
1261         *      write 0x284 bit[18] = 1'b1
1262         *      write 0x301 = 0xFF
1263         */
1264        tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1265        if (tmp & BIT(2)) {
1266                /* Already pause before the function for another purpose. */
1267                release_mac_rx_pause = false;
1268        } else {
1269                rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp | BIT(2)));
1270                release_mac_rx_pause = true;
1271        }
1272
1273        backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 1);
1274        if (backup_pcie_dma_pause != 0xFF)
1275                rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFF);
1276
1277        if (mac_power_on) {
1278                /* 3. reset TRX function
1279                 *      write 0x100 = 0x00
1280                 */
1281                rtl_write_byte(rtlpriv, REG_CR, 0);
1282        }
1283
1284        /* 4. Reset PCIe DMA
1285         *      write 0x003 bit[0] = 0
1286         */
1287        tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1288        tmp &= ~(BIT(0));
1289        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1290
1291        /* 5. Enable PCIe DMA
1292         *      write 0x003 bit[0] = 1
1293         */
1294        tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1295        tmp |= BIT(0);
1296        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1297
1298        if (mac_power_on) {
1299                /* 6. enable TRX function
1300                 *      write 0x100 = 0xFF
1301                 */
1302                rtl_write_byte(rtlpriv, REG_CR, 0xFF);
1303
1304                /* We should init LLT & RQPN and
1305                 * prepare Tx/Rx descrptor address later
1306                 * because MAC function is reset.
1307                 */
1308        }
1309
1310        /* 7. Restore PCIe autoload down bit
1311         *      write 0xF8 bit[17] = 1'b1
1312         */
1313        tmp = rtl_read_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2);
1314        tmp |= BIT(1);
1315        rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2, tmp);
1316
1317        /* In MAC power on state, BB and RF maybe in ON state,
1318         * if we release TRx DMA here
1319         * it will cause packets to be started to Tx/Rx,
1320         * so we release Tx/Rx DMA later.
1321         */
1322        if (!mac_power_on) {
1323                /* 8. release TRX DMA
1324                 *      write 0x284 bit[18] = 1'b0
1325                 *      write 0x301 = 0x00
1326                 */
1327                if (release_mac_rx_pause) {
1328                        tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1329                        rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL,
1330                                       (tmp & (~BIT(2))));
1331                }
1332                rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1,
1333                               backup_pcie_dma_pause);
1334        }
1335
1336        /* 9. lock system register
1337         *      write 0xCC bit[2] = 1'b0
1338         */
1339        tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1340        tmp &= ~(BIT(2));
1341        rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1342}
1343
1344int rtl8723be_hw_init(struct ieee80211_hw *hw)
1345{
1346        struct rtl_priv *rtlpriv = rtl_priv(hw);
1347        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1348        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1349        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1350        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1351        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1352        bool rtstatus = true;
1353        int err;
1354        u8 tmp_u1b;
1355        unsigned long flags;
1356
1357        /* reenable interrupts to not interfere with other devices */
1358        local_save_flags(flags);
1359        local_irq_enable();
1360
1361        rtlhal->fw_ready = false;
1362        rtlpriv->rtlhal.being_init_adapter = true;
1363        rtlpriv->intf_ops->disable_aspm(hw);
1364
1365        tmp_u1b = rtl_read_byte(rtlpriv, REG_CR);
1366        if (tmp_u1b != 0 && tmp_u1b != 0xea) {
1367                rtlhal->mac_func_enable = true;
1368        } else {
1369                rtlhal->mac_func_enable = false;
1370                rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON;
1371        }
1372
1373        if (_rtl8723be_check_pcie_dma_hang(rtlpriv)) {
1374                _rtl8723be_reset_pcie_interface_dma(rtlpriv,
1375                                                    rtlhal->mac_func_enable);
1376                rtlhal->mac_func_enable = false;
1377        }
1378        if (rtlhal->mac_func_enable) {
1379                _rtl8723be_poweroff_adapter(hw);
1380                rtlhal->mac_func_enable = false;
1381        }
1382        rtstatus = _rtl8723be_init_mac(hw);
1383        if (!rtstatus) {
1384                pr_err("Init MAC failed\n");
1385                err = 1;
1386                goto exit;
1387        }
1388
1389        tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CFG);
1390        rtl_write_byte(rtlpriv, REG_SYS_CFG, tmp_u1b & 0x7F);
1391
1392        err = rtl8723_download_fw(hw, true, FW_8723B_POLLING_TIMEOUT_COUNT);
1393        if (err) {
1394                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1395                         "Failed to download FW. Init HW without FW now..\n");
1396                err = 1;
1397                goto exit;
1398        }
1399        rtlhal->fw_ready = true;
1400
1401        rtlhal->last_hmeboxnum = 0;
1402        rtl8723be_phy_mac_config(hw);
1403        /* because last function modify RCR, so we update
1404         * rcr var here, or TP will unstable for receive_config
1405         * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx
1406         * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
1407         */
1408        rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
1409        rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
1410        rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
1411
1412        rtl8723be_phy_bb_config(hw);
1413        rtl8723be_phy_rf_config(hw);
1414
1415        rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
1416                                                 RF_CHNLBW, RFREG_OFFSET_MASK);
1417        rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
1418                                                 RF_CHNLBW, RFREG_OFFSET_MASK);
1419        rtlphy->rfreg_chnlval[0] &= 0xFFF03FF;
1420        rtlphy->rfreg_chnlval[0] |= (BIT(10) | BIT(11));
1421
1422        _rtl8723be_hw_configure(hw);
1423        rtlhal->mac_func_enable = true;
1424        rtl_cam_reset_all_entry(hw);
1425        rtl8723be_enable_hw_security_config(hw);
1426
1427        ppsc->rfpwr_state = ERFON;
1428
1429        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
1430        _rtl8723be_enable_aspm_back_door(hw);
1431        rtlpriv->intf_ops->enable_aspm(hw);
1432
1433        rtl8723be_bt_hw_init(hw);
1434
1435        if (ppsc->rfpwr_state == ERFON) {
1436                rtl8723be_phy_set_rfpath_switch(hw, 1);
1437                /* when use 1ant NIC, iqk will disturb BT music
1438                 * root cause is not clear now, is something
1439                 * related with 'mdelay' and Reg[0x948]
1440                 */
1441                if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2 ||
1442                    !rtlpriv->cfg->ops->get_btc_status()) {
1443                        rtl8723be_phy_iq_calibrate(hw,
1444                                                   (rtlphy->iqk_initialized ?
1445                                                    true : false));
1446                        rtlphy->iqk_initialized = true;
1447                }
1448                rtl8723be_dm_check_txpower_tracking(hw);
1449                rtl8723be_phy_lc_calibrate(hw);
1450        }
1451        rtl_write_byte(rtlpriv, REG_NAV_UPPER, ((30000 + 127) / 128));
1452
1453        /* Release Rx DMA. */
1454        tmp_u1b = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1455        if (tmp_u1b & BIT(2)) {
1456                /* Release Rx DMA if needed */
1457                tmp_u1b &= (~BIT(2));
1458                rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, tmp_u1b);
1459        }
1460        /* Release Tx/Rx PCIE DMA. */
1461        rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0);
1462
1463        rtl8723be_dm_init(hw);
1464exit:
1465        local_irq_restore(flags);
1466        rtlpriv->rtlhal.being_init_adapter = false;
1467        return err;
1468}
1469
1470static enum version_8723e _rtl8723be_read_chip_version(struct ieee80211_hw *hw)
1471{
1472        struct rtl_priv *rtlpriv = rtl_priv(hw);
1473        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1474        enum version_8723e version = VERSION_UNKNOWN;
1475        u32 value32;
1476
1477        value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1);
1478        if ((value32 & (CHIP_8723B)) != CHIP_8723B)
1479                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "unknown chip version\n");
1480        else
1481                version = (enum version_8723e)CHIP_8723B;
1482
1483        rtlphy->rf_type = RF_1T1R;
1484
1485        /* treat rtl8723be chip as  MP version in default */
1486        version = (enum version_8723e)(version | NORMAL_CHIP);
1487
1488        value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
1489        /* cut version */
1490        version |= (enum version_8723e)(value32 & CHIP_VER_RTL_MASK);
1491        /* Manufacture */
1492        if (((value32 & EXT_VENDOR_ID) >> 18) == 0x01)
1493                version = (enum version_8723e)(version | CHIP_VENDOR_SMIC);
1494
1495        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1496                 "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
1497                  "RF_2T2R" : "RF_1T1R");
1498
1499        return version;
1500}
1501
1502static int _rtl8723be_set_media_status(struct ieee80211_hw *hw,
1503                                       enum nl80211_iftype type)
1504{
1505        struct rtl_priv *rtlpriv = rtl_priv(hw);
1506        u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc;
1507        enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
1508        u8 mode = MSR_NOLINK;
1509
1510        switch (type) {
1511        case NL80211_IFTYPE_UNSPECIFIED:
1512                mode = MSR_NOLINK;
1513                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1514                         "Set Network type to NO LINK!\n");
1515                break;
1516        case NL80211_IFTYPE_ADHOC:
1517        case NL80211_IFTYPE_MESH_POINT:
1518                mode = MSR_ADHOC;
1519                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1520                         "Set Network type to Ad Hoc!\n");
1521                break;
1522        case NL80211_IFTYPE_STATION:
1523                mode = MSR_INFRA;
1524                ledaction = LED_CTL_LINK;
1525                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1526                         "Set Network type to STA!\n");
1527                break;
1528        case NL80211_IFTYPE_AP:
1529                mode = MSR_AP;
1530                ledaction = LED_CTL_LINK;
1531                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1532                         "Set Network type to AP!\n");
1533                break;
1534        default:
1535                pr_err("Network type %d not support!\n", type);
1536                return 1;
1537        }
1538
1539        /* MSR_INFRA == Link in infrastructure network;
1540         * MSR_ADHOC == Link in ad hoc network;
1541         * Therefore, check link state is necessary.
1542         *
1543         * MSR_AP == AP mode; link state is not cared here.
1544         */
1545        if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1546                mode = MSR_NOLINK;
1547                ledaction = LED_CTL_NO_LINK;
1548        }
1549
1550        if (mode == MSR_NOLINK || mode == MSR_INFRA) {
1551                _rtl8723be_stop_tx_beacon(hw);
1552                _rtl8723be_enable_bcn_sub_func(hw);
1553        } else if (mode == MSR_ADHOC || mode == MSR_AP) {
1554                _rtl8723be_resume_tx_beacon(hw);
1555                _rtl8723be_disable_bcn_sub_func(hw);
1556        } else {
1557                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1558                         "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n",
1559                         mode);
1560        }
1561
1562        rtl_write_byte(rtlpriv, MSR, bt_msr | mode);
1563        rtlpriv->cfg->ops->led_control(hw, ledaction);
1564        if (mode == MSR_AP)
1565                rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1566        else
1567                rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1568        return 0;
1569}
1570
1571void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1572{
1573        struct rtl_priv *rtlpriv = rtl_priv(hw);
1574        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1575        u32 reg_rcr = rtlpci->receive_config;
1576
1577        if (rtlpriv->psc.rfpwr_state != ERFON)
1578                return;
1579
1580        if (check_bssid) {
1581                reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1582                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1583                                              (u8 *)(&reg_rcr));
1584                _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
1585        } else if (!check_bssid) {
1586                reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1587                _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
1588                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1589                                              (u8 *)(&reg_rcr));
1590        }
1591
1592}
1593
1594int rtl8723be_set_network_type(struct ieee80211_hw *hw,
1595                               enum nl80211_iftype type)
1596{
1597        struct rtl_priv *rtlpriv = rtl_priv(hw);
1598
1599        if (_rtl8723be_set_media_status(hw, type))
1600                return -EOPNOTSUPP;
1601
1602        if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1603                if (type != NL80211_IFTYPE_AP)
1604                        rtl8723be_set_check_bssid(hw, true);
1605        } else {
1606                rtl8723be_set_check_bssid(hw, false);
1607        }
1608
1609        return 0;
1610}
1611
1612/* don't set REG_EDCA_BE_PARAM here
1613 * because mac80211 will send pkt when scan
1614 */
1615void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci)
1616{
1617        struct rtl_priv *rtlpriv = rtl_priv(hw);
1618
1619        rtl8723_dm_init_edca_turbo(hw);
1620        switch (aci) {
1621        case AC1_BK:
1622                rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
1623                break;
1624        case AC0_BE:
1625                break;
1626        case AC2_VI:
1627                rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
1628                break;
1629        case AC3_VO:
1630                rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
1631                break;
1632        default:
1633                WARN_ONCE(true, "rtl8723be: invalid aci: %d !\n", aci);
1634                break;
1635        }
1636}
1637
1638void rtl8723be_enable_interrupt(struct ieee80211_hw *hw)
1639{
1640        struct rtl_priv *rtlpriv = rtl_priv(hw);
1641        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1642
1643        rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
1644        rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
1645        rtlpci->irq_enabled = true;
1646
1647        /*enable system interrupt*/
1648        rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF);
1649}
1650
1651void rtl8723be_disable_interrupt(struct ieee80211_hw *hw)
1652{
1653        struct rtl_priv *rtlpriv = rtl_priv(hw);
1654        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1655
1656        rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED);
1657        rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED);
1658        rtlpci->irq_enabled = false;
1659        /*synchronize_irq(rtlpci->pdev->irq);*/
1660}
1661
1662void rtl8723be_card_disable(struct ieee80211_hw *hw)
1663{
1664        struct rtl_priv *rtlpriv = rtl_priv(hw);
1665        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1666        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1667        enum nl80211_iftype opmode;
1668
1669        mac->link_state = MAC80211_NOLINK;
1670        opmode = NL80211_IFTYPE_UNSPECIFIED;
1671        _rtl8723be_set_media_status(hw, opmode);
1672        if (rtlpriv->rtlhal.driver_is_goingto_unload ||
1673            ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1674                rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1675        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1676        _rtl8723be_poweroff_adapter(hw);
1677
1678        /* after power off we should do iqk again */
1679        if (!rtlpriv->cfg->ops->get_btc_status())
1680                rtlpriv->phy.iqk_initialized = false;
1681}
1682
1683void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw,
1684                                    u32 *p_inta, u32 *p_intb)
1685{
1686        struct rtl_priv *rtlpriv = rtl_priv(hw);
1687        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1688
1689        *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
1690        rtl_write_dword(rtlpriv, ISR, *p_inta);
1691
1692        *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) &
1693                                        rtlpci->irq_mask[1];
1694        rtl_write_dword(rtlpriv, REG_HISRE, *p_intb);
1695}
1696
1697void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw)
1698{
1699        struct rtl_priv *rtlpriv = rtl_priv(hw);
1700        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1701        u16 bcn_interval, atim_window;
1702
1703        bcn_interval = mac->beacon_interval;
1704        atim_window = 2;        /*FIX MERGE */
1705        rtl8723be_disable_interrupt(hw);
1706        rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1707        rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1708        rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
1709        rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
1710        rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
1711        rtl_write_byte(rtlpriv, 0x606, 0x30);
1712        rtl8723be_enable_interrupt(hw);
1713}
1714
1715void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw)
1716{
1717        struct rtl_priv *rtlpriv = rtl_priv(hw);
1718        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1719        u16 bcn_interval = mac->beacon_interval;
1720
1721        RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
1722                 "beacon_interval:%d\n", bcn_interval);
1723        rtl8723be_disable_interrupt(hw);
1724        rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1725        rtl8723be_enable_interrupt(hw);
1726}
1727
1728void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw,
1729                                   u32 add_msr, u32 rm_msr)
1730{
1731        struct rtl_priv *rtlpriv = rtl_priv(hw);
1732        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1733
1734        RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
1735                 "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr);
1736
1737        if (add_msr)
1738                rtlpci->irq_mask[0] |= add_msr;
1739        if (rm_msr)
1740                rtlpci->irq_mask[0] &= (~rm_msr);
1741        rtl8723be_disable_interrupt(hw);
1742        rtl8723be_enable_interrupt(hw);
1743}
1744
1745static u8 _rtl8723be_get_chnl_group(u8 chnl)
1746{
1747        u8 group;
1748
1749        if (chnl < 3)
1750                group = 0;
1751        else if (chnl < 9)
1752                group = 1;
1753        else
1754                group = 2;
1755        return group;
1756}
1757
1758static void _rtl8723be_read_power_value_fromprom(struct ieee80211_hw *hw,
1759                                        struct txpower_info_2g *pw2g,
1760                                        struct txpower_info_5g *pw5g,
1761                                        bool autoload_fail, u8 *hwinfo)
1762{
1763        struct rtl_priv *rtlpriv = rtl_priv(hw);
1764        u32 path, addr = EEPROM_TX_PWR_INX, group, cnt = 0;
1765
1766        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1767                 "hal_ReadPowerValueFromPROM8723BE(): PROMContent[0x%x]=0x%x\n",
1768                 (addr + 1), hwinfo[addr + 1]);
1769        if (0xFF == hwinfo[addr + 1])  /*YJ,add,120316*/
1770                autoload_fail = true;
1771
1772        if (autoload_fail) {
1773                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1774                         "auto load fail : Use Default value!\n");
1775                for (path = 0; path < MAX_RF_PATH; path++) {
1776                        /* 2.4G default value */
1777                        for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) {
1778                                pw2g->index_cck_base[path][group] = 0x2D;
1779                                pw2g->index_bw40_base[path][group] = 0x2D;
1780                        }
1781                        for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1782                                if (cnt == 0) {
1783                                        pw2g->bw20_diff[path][0] = 0x02;
1784                                        pw2g->ofdm_diff[path][0] = 0x04;
1785                                } else {
1786                                        pw2g->bw20_diff[path][cnt] = 0xFE;
1787                                        pw2g->bw40_diff[path][cnt] = 0xFE;
1788                                        pw2g->cck_diff[path][cnt] = 0xFE;
1789                                        pw2g->ofdm_diff[path][cnt] = 0xFE;
1790                                }
1791                        }
1792                }
1793                return;
1794        }
1795
1796        for (path = 0; path < MAX_RF_PATH; path++) {
1797                /*2.4G default value*/
1798                for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1799                        pw2g->index_cck_base[path][group] = hwinfo[addr++];
1800                        if (pw2g->index_cck_base[path][group] == 0xFF)
1801                                pw2g->index_cck_base[path][group] = 0x2D;
1802
1803                }
1804                for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
1805                        pw2g->index_bw40_base[path][group] = hwinfo[addr++];
1806                        if (pw2g->index_bw40_base[path][group] == 0xFF)
1807                                pw2g->index_bw40_base[path][group] = 0x2D;
1808                }
1809                for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1810                        if (cnt == 0) {
1811                                pw2g->bw40_diff[path][cnt] = 0;
1812                                if (hwinfo[addr] == 0xFF) {
1813                                        pw2g->bw20_diff[path][cnt] = 0x02;
1814                                } else {
1815                                        pw2g->bw20_diff[path][cnt] =
1816                                                (hwinfo[addr] & 0xf0) >> 4;
1817                                        /*bit sign number to 8 bit sign number*/
1818                                        if (pw2g->bw20_diff[path][cnt] & BIT(3))
1819                                                pw2g->bw20_diff[path][cnt] |=
1820                                                                          0xF0;
1821                                }
1822
1823                                if (hwinfo[addr] == 0xFF) {
1824                                        pw2g->ofdm_diff[path][cnt] = 0x04;
1825                                } else {
1826                                        pw2g->ofdm_diff[path][cnt] =
1827                                                        (hwinfo[addr] & 0x0f);
1828                                        /*bit sign number to 8 bit sign number*/
1829                                        if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1830                                                pw2g->ofdm_diff[path][cnt] |=
1831                                                                          0xF0;
1832                                }
1833                                pw2g->cck_diff[path][cnt] = 0;
1834                                addr++;
1835                        } else {
1836                                if (hwinfo[addr] == 0xFF) {
1837                                        pw2g->bw40_diff[path][cnt] = 0xFE;
1838                                } else {
1839                                        pw2g->bw40_diff[path][cnt] =
1840                                                (hwinfo[addr] & 0xf0) >> 4;
1841                                        if (pw2g->bw40_diff[path][cnt] & BIT(3))
1842                                                pw2g->bw40_diff[path][cnt] |=
1843                                                                          0xF0;
1844                                }
1845
1846                                if (hwinfo[addr] == 0xFF) {
1847                                        pw2g->bw20_diff[path][cnt] = 0xFE;
1848                                } else {
1849                                        pw2g->bw20_diff[path][cnt] =
1850                                                        (hwinfo[addr] & 0x0f);
1851                                        if (pw2g->bw20_diff[path][cnt] & BIT(3))
1852                                                pw2g->bw20_diff[path][cnt] |=
1853                                                                          0xF0;
1854                                }
1855                                addr++;
1856
1857                                if (hwinfo[addr] == 0xFF) {
1858                                        pw2g->ofdm_diff[path][cnt] = 0xFE;
1859                                } else {
1860                                        pw2g->ofdm_diff[path][cnt] =
1861                                                (hwinfo[addr] & 0xf0) >> 4;
1862                                        if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1863                                                pw2g->ofdm_diff[path][cnt] |=
1864                                                                          0xF0;
1865                                }
1866
1867                                if (hwinfo[addr] == 0xFF)
1868                                        pw2g->cck_diff[path][cnt] = 0xFE;
1869                                else {
1870                                        pw2g->cck_diff[path][cnt] =
1871                                                        (hwinfo[addr] & 0x0f);
1872                                        if (pw2g->cck_diff[path][cnt] & BIT(3))
1873                                                pw2g->cck_diff[path][cnt] |=
1874                                                                         0xF0;
1875                                }
1876                                addr++;
1877                        }
1878                }
1879
1880                /*5G default value*/
1881                for (group = 0; group < MAX_CHNL_GROUP_5G; group++) {
1882                        pw5g->index_bw40_base[path][group] = hwinfo[addr++];
1883                        if (pw5g->index_bw40_base[path][group] == 0xFF)
1884                                pw5g->index_bw40_base[path][group] = 0xFE;
1885                }
1886
1887                for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1888                        if (cnt == 0) {
1889                                pw5g->bw40_diff[path][cnt] = 0;
1890
1891                                if (hwinfo[addr] == 0xFF) {
1892                                        pw5g->bw20_diff[path][cnt] = 0;
1893                                } else {
1894                                        pw5g->bw20_diff[path][0] =
1895                                                (hwinfo[addr] & 0xf0) >> 4;
1896                                        if (pw5g->bw20_diff[path][cnt] & BIT(3))
1897                                                pw5g->bw20_diff[path][cnt] |=
1898                                                                          0xF0;
1899                                }
1900
1901                                if (hwinfo[addr] == 0xFF)
1902                                        pw5g->ofdm_diff[path][cnt] = 0x04;
1903                                else {
1904                                        pw5g->ofdm_diff[path][0] =
1905                                                        (hwinfo[addr] & 0x0f);
1906                                        if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1907                                                pw5g->ofdm_diff[path][cnt] |=
1908                                                                          0xF0;
1909                                }
1910                                addr++;
1911                        } else {
1912                                if (hwinfo[addr] == 0xFF) {
1913                                        pw5g->bw40_diff[path][cnt] = 0xFE;
1914                                } else {
1915                                        pw5g->bw40_diff[path][cnt] =
1916                                                (hwinfo[addr] & 0xf0) >> 4;
1917                                        if (pw5g->bw40_diff[path][cnt] & BIT(3))
1918                                                pw5g->bw40_diff[path][cnt] |= 0xF0;
1919                                }
1920
1921                                if (hwinfo[addr] == 0xFF) {
1922                                        pw5g->bw20_diff[path][cnt] = 0xFE;
1923                                } else {
1924                                        pw5g->bw20_diff[path][cnt] =
1925                                                        (hwinfo[addr] & 0x0f);
1926                                        if (pw5g->bw20_diff[path][cnt] & BIT(3))
1927                                                pw5g->bw20_diff[path][cnt] |= 0xF0;
1928                                }
1929                                addr++;
1930                        }
1931                }
1932
1933                if (hwinfo[addr] == 0xFF) {
1934                        pw5g->ofdm_diff[path][1] = 0xFE;
1935                        pw5g->ofdm_diff[path][2] = 0xFE;
1936                } else {
1937                        pw5g->ofdm_diff[path][1] = (hwinfo[addr] & 0xf0) >> 4;
1938                        pw5g->ofdm_diff[path][2] = (hwinfo[addr] & 0x0f);
1939                }
1940                addr++;
1941
1942                if (hwinfo[addr] == 0xFF)
1943                        pw5g->ofdm_diff[path][3] = 0xFE;
1944                else
1945                        pw5g->ofdm_diff[path][3] = (hwinfo[addr] & 0x0f);
1946                addr++;
1947
1948                for (cnt = 1; cnt < MAX_TX_COUNT; cnt++) {
1949                        if (pw5g->ofdm_diff[path][cnt] == 0xFF)
1950                                pw5g->ofdm_diff[path][cnt] = 0xFE;
1951                        else if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1952                                pw5g->ofdm_diff[path][cnt] |= 0xF0;
1953                }
1954        }
1955}
1956
1957static void _rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1958                                                   bool autoload_fail,
1959                                                   u8 *hwinfo)
1960{
1961        struct rtl_priv *rtlpriv = rtl_priv(hw);
1962        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1963        struct txpower_info_2g pw2g;
1964        struct txpower_info_5g pw5g;
1965        u8 rf_path, index;
1966        u8 i;
1967
1968        _rtl8723be_read_power_value_fromprom(hw, &pw2g, &pw5g, autoload_fail,
1969                                             hwinfo);
1970
1971        for (rf_path = 0; rf_path < 2; rf_path++) {
1972                for (i = 0; i < 14; i++) {
1973                        index = _rtl8723be_get_chnl_group(i+1);
1974
1975                        rtlefuse->txpwrlevel_cck[rf_path][i] =
1976                                        pw2g.index_cck_base[rf_path][index];
1977                        rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1978                                        pw2g.index_bw40_base[rf_path][index];
1979                }
1980                for (i = 0; i < MAX_TX_COUNT; i++) {
1981                        rtlefuse->txpwr_ht20diff[rf_path][i] =
1982                                                pw2g.bw20_diff[rf_path][i];
1983                        rtlefuse->txpwr_ht40diff[rf_path][i] =
1984                                                pw2g.bw40_diff[rf_path][i];
1985                        rtlefuse->txpwr_legacyhtdiff[rf_path][i] =
1986                                                pw2g.ofdm_diff[rf_path][i];
1987                }
1988
1989                for (i = 0; i < 14; i++) {
1990                        RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1991                                "RF(%d)-Ch(%d) [CCK / HT40_1S ] = [0x%x / 0x%x ]\n",
1992                                rf_path, i,
1993                                rtlefuse->txpwrlevel_cck[rf_path][i],
1994                                rtlefuse->txpwrlevel_ht40_1s[rf_path][i]);
1995                }
1996        }
1997
1998        if (!autoload_fail)
1999                rtlefuse->eeprom_thermalmeter =
2000                                        hwinfo[EEPROM_THERMAL_METER_88E];
2001        else
2002                rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
2003
2004        if (rtlefuse->eeprom_thermalmeter == 0xff || autoload_fail) {
2005                rtlefuse->apk_thermalmeterignore = true;
2006                rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
2007        }
2008
2009        rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
2010        RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
2011                "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
2012
2013        if (!autoload_fail) {
2014                rtlefuse->eeprom_regulatory =
2015                        hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x07;/*bit0~2*/
2016                if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
2017                        rtlefuse->eeprom_regulatory = 0;
2018        } else {
2019                rtlefuse->eeprom_regulatory = 0;
2020        }
2021        RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
2022                "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
2023}
2024
2025static u8 _rtl8723be_read_package_type(struct ieee80211_hw *hw)
2026{
2027        u8 package_type;
2028        u8 value;
2029
2030        efuse_power_switch(hw, false, true);
2031        if (!efuse_one_byte_read(hw, 0x1FB, &value))
2032                value = 0;
2033        efuse_power_switch(hw, false, false);
2034
2035        switch (value & 0x7) {
2036        case 0x4:
2037                package_type = PACKAGE_TFBGA79;
2038                break;
2039        case 0x5:
2040                package_type = PACKAGE_TFBGA90;
2041                break;
2042        case 0x6:
2043                package_type = PACKAGE_QFN68;
2044                break;
2045        case 0x7:
2046                package_type = PACKAGE_TFBGA80;
2047                break;
2048        default:
2049                package_type = PACKAGE_DEFAULT;
2050                break;
2051        }
2052
2053        return package_type;
2054}
2055
2056static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
2057                                         bool pseudo_test)
2058{
2059        struct rtl_priv *rtlpriv = rtl_priv(hw);
2060        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2061        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2062        int params[] = {RTL8723BE_EEPROM_ID, EEPROM_VID, EEPROM_DID,
2063                        EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
2064                        EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
2065                        COUNTRY_CODE_WORLD_WIDE_13};
2066        u8 *hwinfo;
2067        int i;
2068        bool is_toshiba_smid1 = false;
2069        bool is_toshiba_smid2 = false;
2070        bool is_samsung_smid = false;
2071        bool is_lenovo_smid = false;
2072        u16 toshiba_smid1[] = {
2073                0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180,
2074                0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180,
2075                0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185,
2076                0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185
2077        };
2078        u16 toshiba_smid2[] = {
2079                0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181,
2080                0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185
2081        };
2082        u16 samsung_smid[] = {
2083                0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192,
2084                0x8193, 0x9191, 0x9192, 0x9193
2085        };
2086        u16 lenovo_smid[] = {
2087                0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200
2088        };
2089
2090        if (pseudo_test) {
2091                /* needs to be added */
2092                return;
2093        }
2094
2095        hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL);
2096        if (!hwinfo)
2097                return;
2098
2099        if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params))
2100                goto exit;
2101
2102        /*parse xtal*/
2103        rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8723BE];
2104        if (rtlefuse->crystalcap == 0xFF)
2105                rtlefuse->crystalcap = 0x20;
2106
2107        _rtl8723be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag,
2108                                               hwinfo);
2109
2110        rtl8723be_read_bt_coexist_info_from_hwpg(hw,
2111                                                 rtlefuse->autoload_failflag,
2112                                                 hwinfo);
2113
2114        if (rtlpriv->btcoexist.btc_info.btcoexist == 1)
2115                rtlefuse->board_type |= BIT(2); /* ODM_BOARD_BT */
2116
2117        rtlhal->board_type = rtlefuse->board_type;
2118        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2119                 "board_type = 0x%x\n", rtlefuse->board_type);
2120
2121        rtlhal->package_type = _rtl8723be_read_package_type(hw);
2122
2123        /* set channel plan from efuse */
2124        rtlefuse->channel_plan = rtlefuse->eeprom_channelplan;
2125
2126        if (rtlhal->oem_id == RT_CID_DEFAULT) {
2127                /* Does this one have a Toshiba SMID from group 1? */
2128                for (i = 0; i < sizeof(toshiba_smid1) / sizeof(u16); i++) {
2129                        if (rtlefuse->eeprom_smid == toshiba_smid1[i]) {
2130                                is_toshiba_smid1 = true;
2131                                break;
2132                        }
2133                }
2134                /* Does this one have a Toshiba SMID from group 2? */
2135                for (i = 0; i < sizeof(toshiba_smid2) / sizeof(u16); i++) {
2136                        if (rtlefuse->eeprom_smid == toshiba_smid2[i]) {
2137                                is_toshiba_smid2 = true;
2138                                break;
2139                        }
2140                }
2141                /* Does this one have a Samsung SMID? */
2142                for (i = 0; i < sizeof(samsung_smid) / sizeof(u16); i++) {
2143                        if (rtlefuse->eeprom_smid == samsung_smid[i]) {
2144                                is_samsung_smid = true;
2145                                break;
2146                        }
2147                }
2148                /* Does this one have a Lenovo SMID? */
2149                for (i = 0; i < sizeof(lenovo_smid) / sizeof(u16); i++) {
2150                        if (rtlefuse->eeprom_smid == lenovo_smid[i]) {
2151                                is_lenovo_smid = true;
2152                                break;
2153                        }
2154                }
2155                switch (rtlefuse->eeprom_oemid) {
2156                case EEPROM_CID_DEFAULT:
2157                        if (rtlefuse->eeprom_did == 0x8176) {
2158                                if (rtlefuse->eeprom_svid == 0x10EC &&
2159                                    is_toshiba_smid1) {
2160                                        rtlhal->oem_id = RT_CID_TOSHIBA;
2161                                } else if (rtlefuse->eeprom_svid == 0x1025) {
2162                                        rtlhal->oem_id = RT_CID_819X_ACER;
2163                                } else if (rtlefuse->eeprom_svid == 0x10EC &&
2164                                           is_samsung_smid) {
2165                                        rtlhal->oem_id = RT_CID_819X_SAMSUNG;
2166                                } else if (rtlefuse->eeprom_svid == 0x10EC &&
2167                                           is_lenovo_smid) {
2168                                        rtlhal->oem_id = RT_CID_819X_LENOVO;
2169                                } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2170                                            rtlefuse->eeprom_smid == 0x8197) ||
2171                                           (rtlefuse->eeprom_svid == 0x10EC &&
2172                                            rtlefuse->eeprom_smid == 0x9196)) {
2173                                        rtlhal->oem_id = RT_CID_819X_CLEVO;
2174                                } else if ((rtlefuse->eeprom_svid == 0x1028 &&
2175                                            rtlefuse->eeprom_smid == 0x8194) ||
2176                                           (rtlefuse->eeprom_svid == 0x1028 &&
2177                                            rtlefuse->eeprom_smid == 0x8198) ||
2178                                           (rtlefuse->eeprom_svid == 0x1028 &&
2179                                            rtlefuse->eeprom_smid == 0x9197) ||
2180                                           (rtlefuse->eeprom_svid == 0x1028 &&
2181                                            rtlefuse->eeprom_smid == 0x9198)) {
2182                                        rtlhal->oem_id = RT_CID_819X_DELL;
2183                                } else if ((rtlefuse->eeprom_svid == 0x103C &&
2184                                            rtlefuse->eeprom_smid == 0x1629)) {
2185                                        rtlhal->oem_id = RT_CID_819X_HP;
2186                                } else if ((rtlefuse->eeprom_svid == 0x1A32 &&
2187                                           rtlefuse->eeprom_smid == 0x2315)) {
2188                                        rtlhal->oem_id = RT_CID_819X_QMI;
2189                                } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2190                                           rtlefuse->eeprom_smid == 0x8203)) {
2191                                        rtlhal->oem_id = RT_CID_819X_PRONETS;
2192                                } else if ((rtlefuse->eeprom_svid == 0x1043 &&
2193                                           rtlefuse->eeprom_smid == 0x84B5)) {
2194                                        rtlhal->oem_id = RT_CID_819X_EDIMAX_ASUS;
2195                                } else {
2196                                        rtlhal->oem_id = RT_CID_DEFAULT;
2197                                }
2198                        } else if (rtlefuse->eeprom_did == 0x8178) {
2199                                if (rtlefuse->eeprom_svid == 0x10EC &&
2200                                    is_toshiba_smid2)
2201                                        rtlhal->oem_id = RT_CID_TOSHIBA;
2202                                else if (rtlefuse->eeprom_svid == 0x1025)
2203                                        rtlhal->oem_id = RT_CID_819X_ACER;
2204                                else if ((rtlefuse->eeprom_svid == 0x10EC &&
2205                                          rtlefuse->eeprom_smid == 0x8186))
2206                                        rtlhal->oem_id = RT_CID_819X_PRONETS;
2207                                else if ((rtlefuse->eeprom_svid == 0x1043 &&
2208                                          rtlefuse->eeprom_smid == 0x84B6))
2209                                        rtlhal->oem_id =
2210                                                        RT_CID_819X_EDIMAX_ASUS;
2211                                else
2212                                        rtlhal->oem_id = RT_CID_DEFAULT;
2213                        } else {
2214                                        rtlhal->oem_id = RT_CID_DEFAULT;
2215                        }
2216                        break;
2217                case EEPROM_CID_TOSHIBA:
2218                        rtlhal->oem_id = RT_CID_TOSHIBA;
2219                        break;
2220                case EEPROM_CID_CCX:
2221                        rtlhal->oem_id = RT_CID_CCX;
2222                        break;
2223                case EEPROM_CID_QMI:
2224                        rtlhal->oem_id = RT_CID_819X_QMI;
2225                        break;
2226                case EEPROM_CID_WHQL:
2227                        break;
2228                default:
2229                        rtlhal->oem_id = RT_CID_DEFAULT;
2230                        break;
2231                }
2232        }
2233exit:
2234        kfree(hwinfo);
2235}
2236
2237static void _rtl8723be_hal_customized_behavior(struct ieee80211_hw *hw)
2238{
2239        struct rtl_priv *rtlpriv = rtl_priv(hw);
2240        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2241
2242        rtlpriv->ledctl.led_opendrain = true;
2243        switch (rtlhal->oem_id) {
2244        case RT_CID_819X_HP:
2245                rtlpriv->ledctl.led_opendrain = true;
2246                break;
2247        case RT_CID_819X_LENOVO:
2248        case RT_CID_DEFAULT:
2249        case RT_CID_TOSHIBA:
2250        case RT_CID_CCX:
2251        case RT_CID_819X_ACER:
2252        case RT_CID_WHQL:
2253        default:
2254                break;
2255        }
2256        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2257                 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
2258}
2259
2260void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw)
2261{
2262        struct rtl_priv *rtlpriv = rtl_priv(hw);
2263        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2264        struct rtl_phy *rtlphy = &(rtlpriv->phy);
2265        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2266        u8 tmp_u1b;
2267
2268        rtlhal->version = _rtl8723be_read_chip_version(hw);
2269        if (get_rf_type(rtlphy) == RF_1T1R)
2270                rtlpriv->dm.rfpath_rxenable[0] = true;
2271        else
2272                rtlpriv->dm.rfpath_rxenable[0] =
2273                    rtlpriv->dm.rfpath_rxenable[1] = true;
2274        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
2275                 rtlhal->version);
2276        tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
2277        if (tmp_u1b & BIT(4)) {
2278                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
2279                rtlefuse->epromtype = EEPROM_93C46;
2280        } else {
2281                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
2282                rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
2283        }
2284        if (tmp_u1b & BIT(5)) {
2285                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
2286                rtlefuse->autoload_failflag = false;
2287                _rtl8723be_read_adapter_info(hw, false);
2288        } else {
2289                pr_err("Autoload ERR!!\n");
2290        }
2291        _rtl8723be_hal_customized_behavior(hw);
2292}
2293
2294static u8 _rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw *hw,
2295                                          u8 rate_index)
2296{
2297        u8 ret = 0;
2298        switch (rate_index) {
2299        case RATR_INX_WIRELESS_NGB:
2300                ret = 1;
2301                break;
2302        case RATR_INX_WIRELESS_N:
2303        case RATR_INX_WIRELESS_NG:
2304                ret = 5;
2305                break;
2306        case RATR_INX_WIRELESS_NB:
2307                ret = 3;
2308                break;
2309        case RATR_INX_WIRELESS_GB:
2310                ret = 6;
2311                break;
2312        case RATR_INX_WIRELESS_G:
2313                ret = 7;
2314                break;
2315        case RATR_INX_WIRELESS_B:
2316                ret = 8;
2317                break;
2318        default:
2319                ret = 0;
2320                break;
2321        }
2322        return ret;
2323}
2324
2325static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw,
2326                                           struct ieee80211_sta *sta,
2327                                           u8 rssi_level)
2328{
2329        struct rtl_priv *rtlpriv = rtl_priv(hw);
2330        struct rtl_phy *rtlphy = &(rtlpriv->phy);
2331        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2332        struct rtl_sta_info *sta_entry = NULL;
2333        u32 ratr_bitmap;
2334        u8 ratr_index;
2335        u8 curtxbw_40mhz = (sta->ht_cap.cap &
2336                              IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
2337        u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
2338                                1 : 0;
2339        u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
2340                                1 : 0;
2341        enum wireless_mode wirelessmode = 0;
2342        bool shortgi = false;
2343        u8 rate_mask[7];
2344        u8 macid = 0;
2345
2346        sta_entry = (struct rtl_sta_info *)sta->drv_priv;
2347        wirelessmode = sta_entry->wireless_mode;
2348        if (mac->opmode == NL80211_IFTYPE_STATION ||
2349            mac->opmode == NL80211_IFTYPE_MESH_POINT)
2350                curtxbw_40mhz = mac->bw_40;
2351        else if (mac->opmode == NL80211_IFTYPE_AP ||
2352                 mac->opmode == NL80211_IFTYPE_ADHOC)
2353                macid = sta->aid + 1;
2354
2355        ratr_bitmap = sta->supp_rates[0];
2356
2357        if (mac->opmode == NL80211_IFTYPE_ADHOC)
2358                ratr_bitmap = 0xfff;
2359
2360        ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2361                        sta->ht_cap.mcs.rx_mask[0] << 12);
2362        switch (wirelessmode) {
2363        case WIRELESS_MODE_B:
2364                ratr_index = RATR_INX_WIRELESS_B;
2365                if (ratr_bitmap & 0x0000000c)
2366                        ratr_bitmap &= 0x0000000d;
2367                else
2368                        ratr_bitmap &= 0x0000000f;
2369                break;
2370        case WIRELESS_MODE_G:
2371                ratr_index = RATR_INX_WIRELESS_GB;
2372
2373                if (rssi_level == 1)
2374                        ratr_bitmap &= 0x00000f00;
2375                else if (rssi_level == 2)
2376                        ratr_bitmap &= 0x00000ff0;
2377                else
2378                        ratr_bitmap &= 0x00000ff5;
2379                break;
2380        case WIRELESS_MODE_N_24G:
2381        case WIRELESS_MODE_N_5G:
2382                ratr_index = RATR_INX_WIRELESS_NGB;
2383                if (rtlphy->rf_type == RF_1T1R) {
2384                        if (curtxbw_40mhz) {
2385                                if (rssi_level == 1)
2386                                        ratr_bitmap &= 0x000f0000;
2387                                else if (rssi_level == 2)
2388                                        ratr_bitmap &= 0x000ff000;
2389                                else
2390                                        ratr_bitmap &= 0x000ff015;
2391                        } else {
2392                                if (rssi_level == 1)
2393                                        ratr_bitmap &= 0x000f0000;
2394                                else if (rssi_level == 2)
2395                                        ratr_bitmap &= 0x000ff000;
2396                                else
2397                                        ratr_bitmap &= 0x000ff005;
2398                        }
2399                } else {
2400                        if (curtxbw_40mhz) {
2401                                if (rssi_level == 1)
2402                                        ratr_bitmap &= 0x0f8f0000;
2403                                else if (rssi_level == 2)
2404                                        ratr_bitmap &= 0x0f8ff000;
2405                                else
2406                                        ratr_bitmap &= 0x0f8ff015;
2407                        } else {
2408                                if (rssi_level == 1)
2409                                        ratr_bitmap &= 0x0f8f0000;
2410                                else if (rssi_level == 2)
2411                                        ratr_bitmap &= 0x0f8ff000;
2412                                else
2413                                        ratr_bitmap &= 0x0f8ff005;
2414                        }
2415                }
2416                if ((curtxbw_40mhz && curshortgi_40mhz) ||
2417                    (!curtxbw_40mhz && curshortgi_20mhz)) {
2418                        if (macid == 0)
2419                                shortgi = true;
2420                        else if (macid == 1)
2421                                shortgi = false;
2422                }
2423                break;
2424        default:
2425                ratr_index = RATR_INX_WIRELESS_NGB;
2426
2427                if (rtlphy->rf_type == RF_1T2R)
2428                        ratr_bitmap &= 0x000ff0ff;
2429                else
2430                        ratr_bitmap &= 0x0f0ff0ff;
2431                break;
2432        }
2433
2434        sta_entry->ratr_index = ratr_index;
2435
2436        RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2437                 "ratr_bitmap :%x\n", ratr_bitmap);
2438        *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
2439                                       (ratr_index << 28);
2440        rate_mask[0] = macid;
2441        rate_mask[1] = _rtl8723be_mrate_idx_to_arfr_id(hw, ratr_index) |
2442                                                      (shortgi ? 0x80 : 0x00);
2443        rate_mask[2] = curtxbw_40mhz;
2444
2445        rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
2446        rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8);
2447        rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
2448        rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
2449
2450        RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2451                 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n",
2452                 ratr_index, ratr_bitmap,
2453                 rate_mask[0], rate_mask[1],
2454                 rate_mask[2], rate_mask[3],
2455                 rate_mask[4], rate_mask[5],
2456                 rate_mask[6]);
2457        rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RA_MASK, 7, rate_mask);
2458        _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
2459}
2460
2461void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw,
2462                                   struct ieee80211_sta *sta,
2463                                   u8 rssi_level)
2464{
2465        struct rtl_priv *rtlpriv = rtl_priv(hw);
2466        if (rtlpriv->dm.useramask)
2467                rtl8723be_update_hal_rate_mask(hw, sta, rssi_level);
2468}
2469
2470void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw)
2471{
2472        struct rtl_priv *rtlpriv = rtl_priv(hw);
2473        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2474        u16 sifs_timer;
2475
2476        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
2477        if (!mac->ht_enable)
2478                sifs_timer = 0x0a0a;
2479        else
2480                sifs_timer = 0x0e0e;
2481        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2482}
2483
2484bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2485{
2486        struct rtl_priv *rtlpriv = rtl_priv(hw);
2487        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2488        struct rtl_phy *rtlphy = &(rtlpriv->phy);
2489        enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
2490        u8 u1tmp;
2491        bool b_actuallyset = false;
2492
2493        if (rtlpriv->rtlhal.being_init_adapter)
2494                return false;
2495
2496        if (ppsc->swrf_processing)
2497                return false;
2498
2499        spin_lock(&rtlpriv->locks.rf_ps_lock);
2500        if (ppsc->rfchange_inprogress) {
2501                spin_unlock(&rtlpriv->locks.rf_ps_lock);
2502                return false;
2503        } else {
2504                ppsc->rfchange_inprogress = true;
2505                spin_unlock(&rtlpriv->locks.rf_ps_lock);
2506        }
2507
2508        cur_rfstate = ppsc->rfpwr_state;
2509
2510        rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2511                       rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1)));
2512
2513        u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
2514
2515        if (rtlphy->polarity_ctl)
2516                e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
2517        else
2518                e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
2519
2520        if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) {
2521                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2522                         "GPIOChangeRF  - HW Radio ON, RF ON\n");
2523
2524                e_rfpowerstate_toset = ERFON;
2525                ppsc->hwradiooff = false;
2526                b_actuallyset = true;
2527        } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) {
2528                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2529                         "GPIOChangeRF  - HW Radio OFF, RF OFF\n");
2530
2531                e_rfpowerstate_toset = ERFOFF;
2532                ppsc->hwradiooff = true;
2533                b_actuallyset = true;
2534        }
2535
2536        if (b_actuallyset) {
2537                spin_lock(&rtlpriv->locks.rf_ps_lock);
2538                ppsc->rfchange_inprogress = false;
2539                spin_unlock(&rtlpriv->locks.rf_ps_lock);
2540        } else {
2541                if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2542                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2543
2544                spin_lock(&rtlpriv->locks.rf_ps_lock);
2545                ppsc->rfchange_inprogress = false;
2546                spin_unlock(&rtlpriv->locks.rf_ps_lock);
2547        }
2548
2549        *valid = 1;
2550        return !ppsc->hwradiooff;
2551
2552}
2553
2554void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index,
2555                       u8 *p_macaddr, bool is_group, u8 enc_algo,
2556                       bool is_wepkey, bool clear_all)
2557{
2558        struct rtl_priv *rtlpriv = rtl_priv(hw);
2559        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2560        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2561        u8 *macaddr = p_macaddr;
2562        u32 entry_id = 0;
2563        bool is_pairwise = false;
2564
2565        static u8 cam_const_addr[4][6] = {
2566                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2567                {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2568                {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2569                {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2570        };
2571        static u8 cam_const_broad[] = {
2572                0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2573        };
2574
2575        if (clear_all) {
2576                u8 idx = 0;
2577                u8 cam_offset = 0;
2578                u8 clear_number = 5;
2579
2580                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2581
2582                for (idx = 0; idx < clear_number; idx++) {
2583                        rtl_cam_mark_invalid(hw, cam_offset + idx);
2584                        rtl_cam_empty_entry(hw, cam_offset + idx);
2585
2586                        if (idx < 5) {
2587                                memset(rtlpriv->sec.key_buf[idx], 0,
2588                                       MAX_KEY_LEN);
2589                                rtlpriv->sec.key_len[idx] = 0;
2590                        }
2591                }
2592
2593        } else {
2594                switch (enc_algo) {
2595                case WEP40_ENCRYPTION:
2596                        enc_algo = CAM_WEP40;
2597                        break;
2598                case WEP104_ENCRYPTION:
2599                        enc_algo = CAM_WEP104;
2600                        break;
2601                case TKIP_ENCRYPTION:
2602                        enc_algo = CAM_TKIP;
2603                        break;
2604                case AESCCMP_ENCRYPTION:
2605                        enc_algo = CAM_AES;
2606                        break;
2607                default:
2608                        RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2609                                 "switch case %#x not processed\n", enc_algo);
2610                        enc_algo = CAM_TKIP;
2611                        break;
2612                }
2613
2614                if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2615                        macaddr = cam_const_addr[key_index];
2616                        entry_id = key_index;
2617                } else {
2618                        if (is_group) {
2619                                macaddr = cam_const_broad;
2620                                entry_id = key_index;
2621                        } else {
2622                                if (mac->opmode == NL80211_IFTYPE_AP) {
2623                                        entry_id = rtl_cam_get_free_entry(hw,
2624                                                                p_macaddr);
2625                                        if (entry_id >=  TOTAL_CAM_ENTRY) {
2626                                                pr_err("Can not find free hw security cam entry\n");
2627                                                return;
2628                                        }
2629                                } else {
2630                                        entry_id = CAM_PAIRWISE_KEY_POSITION;
2631                                }
2632
2633                                key_index = PAIRWISE_KEYIDX;
2634                                is_pairwise = true;
2635                        }
2636                }
2637
2638                if (rtlpriv->sec.key_len[key_index] == 0) {
2639                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2640                                 "delete one entry, entry_id is %d\n",
2641                                  entry_id);
2642                        if (mac->opmode == NL80211_IFTYPE_AP)
2643                                rtl_cam_del_entry(hw, p_macaddr);
2644                        rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2645                } else {
2646                        RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2647                                 "add one entry\n");
2648                        if (is_pairwise) {
2649                                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2650                                         "set Pairwise key\n");
2651
2652                                rtl_cam_add_one_entry(hw, macaddr, key_index,
2653                                               entry_id, enc_algo,
2654                                               CAM_CONFIG_NO_USEDK,
2655                                               rtlpriv->sec.key_buf[key_index]);
2656                        } else {
2657                                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2658                                         "set group key\n");
2659
2660                                if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2661                                        rtl_cam_add_one_entry(hw,
2662                                                rtlefuse->dev_addr,
2663                                                PAIRWISE_KEYIDX,
2664                                                CAM_PAIRWISE_KEY_POSITION,
2665                                                enc_algo,
2666                                                CAM_CONFIG_NO_USEDK,
2667                                                rtlpriv->sec.key_buf
2668                                                [entry_id]);
2669                                }
2670
2671                                rtl_cam_add_one_entry(hw, macaddr, key_index,
2672                                                entry_id, enc_algo,
2673                                                CAM_CONFIG_NO_USEDK,
2674                                                rtlpriv->sec.key_buf[entry_id]);
2675                        }
2676                }
2677        }
2678}
2679
2680void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2681                                              bool auto_load_fail, u8 *hwinfo)
2682{
2683        struct rtl_priv *rtlpriv = rtl_priv(hw);
2684        struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
2685        u8 value;
2686        u32 tmpu_32;
2687
2688        if (!auto_load_fail) {
2689                tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
2690                if (tmpu_32 & BIT(18))
2691                        rtlpriv->btcoexist.btc_info.btcoexist = 1;
2692                else
2693                        rtlpriv->btcoexist.btc_info.btcoexist = 0;
2694                value = hwinfo[EEPROM_RF_BT_SETTING_8723B];
2695                rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2696                rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
2697                rtlpriv->btcoexist.btc_info.single_ant_path =
2698                         (value & 0x40);        /*0xc3[6]*/
2699        } else {
2700                rtlpriv->btcoexist.btc_info.btcoexist = 0;
2701                rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2702                rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
2703                rtlpriv->btcoexist.btc_info.single_ant_path = 0;
2704        }
2705
2706        /* override ant_num / ant_path */
2707        if (mod_params->ant_sel) {
2708                rtlpriv->btcoexist.btc_info.ant_num =
2709                        (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
2710
2711                rtlpriv->btcoexist.btc_info.single_ant_path =
2712                        (mod_params->ant_sel == 1 ? 0 : 1);
2713        }
2714}
2715
2716void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
2717{
2718        struct rtl_priv *rtlpriv = rtl_priv(hw);
2719
2720        /* 0:Low, 1:High, 2:From Efuse. */
2721        rtlpriv->btcoexist.reg_bt_iso = 2;
2722        /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2723        rtlpriv->btcoexist.reg_bt_sco = 3;
2724        /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2725        rtlpriv->btcoexist.reg_bt_sco = 0;
2726}
2727
2728void rtl8723be_bt_hw_init(struct ieee80211_hw *hw)
2729{
2730        struct rtl_priv *rtlpriv = rtl_priv(hw);
2731
2732        if (rtlpriv->cfg->ops->get_btc_status())
2733                rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
2734
2735}
2736
2737void rtl8723be_suspend(struct ieee80211_hw *hw)
2738{
2739}
2740
2741void rtl8723be_resume(struct ieee80211_hw *hw)
2742{
2743}
2744