Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorJohn W. Linville <linville@tuxdriver.com>
Thu, 30 Jun 2011 17:34:06 +0000 (13:34 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 30 Jun 2011 17:34:06 +0000 (13:34 -0400)
84 files changed:
drivers/bcma/main.c
drivers/net/wireless/ath/ath9k/ar9003_mac.c
drivers/net/wireless/ath/ath9k/ar9003_paprd.c
drivers/net/wireless/ath/ath9k/ar9003_phy.h
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/carl9170/rx.c
drivers/net/wireless/b43/Makefile
drivers/net/wireless/b43/phy_ht.c
drivers/net/wireless/b43/phy_ht.h
drivers/net/wireless/b43/radio_2059.c
drivers/net/wireless/b43/radio_2059.h
drivers/net/wireless/b43/tables_phy_ht.c [new file with mode: 0644]
drivers/net/wireless/b43/tables_phy_ht.h [new file with mode: 0644]
drivers/net/wireless/iwlegacy/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-2000.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn-sta.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-hcmd.c
drivers/net/wireless/iwlwifi/iwl-pci.c
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/libertas_tf/main.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwifiex/sta_cmd.c
drivers/net/wireless/mwifiex/sta_cmdresp.c
drivers/net/wireless/rt2x00/rt2x00queue.h
drivers/net/wireless/rtlwifi/Kconfig
drivers/net/wireless/rtlwifi/Makefile
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/pci.h
drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
drivers/net/wireless/rtlwifi/rtl8192de/Makefile [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/def.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/dm.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/dm.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/fw.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/fw.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/hw.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/hw.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/led.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/led.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/phy.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/phy.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/reg.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/rf.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/rf.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/sw.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/sw.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/table.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/table.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/trx.c [new file with mode: 0644]
drivers/net/wireless/rtlwifi/rtl8192de/trx.h [new file with mode: 0644]
drivers/net/wireless/rtlwifi/wifi.h
drivers/net/wireless/wl12xx/cmd.c
drivers/ssb/main.c
drivers/ssb/scan.c
include/linux/ieee80211.h
include/net/cfg80211.h
include/net/mac80211.h
net/bluetooth/Kconfig
net/mac80211/agg-rx.c
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/util.c
net/mac80211/wme.c
net/mac80211/wme.h
net/mac80211/work.c
net/mac80211/wpa.c
net/wireless/nl80211.c

index ba15105..08a14a3 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "bcma_private.h"
 #include <linux/bcma/bcma.h>
+#include <linux/slab.h>
 
 MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
 MODULE_LICENSE("GPL");
index 04e6be0..575e185 100644 (file)
@@ -229,6 +229,7 @@ static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
 static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
                                 struct ath_tx_status *ts)
 {
+       struct ar9003_txc *txc = (struct ar9003_txc *) ds;
        struct ar9003_txs *ads;
        u32 status;
 
@@ -238,7 +239,11 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
        if ((status & AR_TxDone) == 0)
                return -EINPROGRESS;
 
-       ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
+       ts->qid = MS(ads->ds_info, AR_TxQcuNum);
+       if (!txc || (MS(txc->info, AR_TxQcuNum) == ts->qid))
+               ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
+       else
+               return -ENOENT;
 
        if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
            (MS(ads->ds_info, AR_TxRxDesc) != 1)) {
@@ -254,7 +259,6 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
        ts->ts_seqnum = MS(status, AR_SeqNum);
        ts->tid = MS(status, AR_TxTid);
 
-       ts->qid = MS(ads->ds_info, AR_TxQcuNum);
        ts->desc_id = MS(ads->status1, AR_TxDescId);
        ts->ts_tstamp = ads->status4;
        ts->ts_status = 0;
index 8f6d11d..de19723 100644 (file)
@@ -236,7 +236,7 @@ static void ar9003_paprd_get_gain_table(struct ath_hw *ah)
        memset(entry, 0, sizeof(ah->paprd_gain_table_entries));
        memset(index, 0, sizeof(ah->paprd_gain_table_index));
 
-       for (i = 0; i < 32; i++) {
+       for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) {
                entry[i] = REG_READ(ah, reg);
                index[i] = (entry[i] >> 24) & 0xff;
                reg += 4;
@@ -246,13 +246,13 @@ static void ar9003_paprd_get_gain_table(struct ath_hw *ah)
 static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain,
                                            int target_power)
 {
-       int olpc_gain_delta = 0;
+       int olpc_gain_delta = 0, cl_gain_mod;
        int alpha_therm, alpha_volt;
        int therm_cal_value, volt_cal_value;
        int therm_value, volt_value;
        int thermal_gain_corr, voltage_gain_corr;
        int desired_scale, desired_gain = 0;
-       u32 reg;
+       u32 reg_olpc  = 0, reg_cl_gain  = 0;
 
        REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
                    AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
@@ -271,15 +271,29 @@ static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain,
        volt_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4,
                                    AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE);
 
-       if (chain == 0)
-               reg = AR_PHY_TPC_11_B0;
-       else if (chain == 1)
-               reg = AR_PHY_TPC_11_B1;
-       else
-               reg = AR_PHY_TPC_11_B2;
+       switch (chain) {
+       case 0:
+               reg_olpc = AR_PHY_TPC_11_B0;
+               reg_cl_gain = AR_PHY_CL_TAB_0;
+               break;
+       case 1:
+               reg_olpc = AR_PHY_TPC_11_B1;
+               reg_cl_gain = AR_PHY_CL_TAB_1;
+               break;
+       case 2:
+               reg_olpc = AR_PHY_TPC_11_B2;
+               reg_cl_gain = AR_PHY_CL_TAB_2;
+               break;
+       default:
+               ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+               "Invalid chainmask: %d\n", chain);
+               break;
+       }
 
-       olpc_gain_delta = REG_READ_FIELD(ah, reg,
+       olpc_gain_delta = REG_READ_FIELD(ah, reg_olpc,
                                         AR_PHY_TPC_11_OLPC_GAIN_DELTA);
+       cl_gain_mod = REG_READ_FIELD(ah, reg_cl_gain,
+                                        AR_PHY_CL_TAB_CL_GAIN_MOD);
 
        if (olpc_gain_delta >= 128)
                olpc_gain_delta = olpc_gain_delta - 256;
@@ -289,7 +303,7 @@ static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain,
        voltage_gain_corr = (alpha_volt * (volt_value - volt_cal_value) +
                             (128 / 2)) / 128;
        desired_gain = target_power - olpc_gain_delta - thermal_gain_corr -
-           voltage_gain_corr + desired_scale;
+           voltage_gain_corr + desired_scale + cl_gain_mod;
 
        return desired_gain;
 }
@@ -727,7 +741,7 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
        desired_gain = ar9003_get_desired_gain(ah, chain, train_power);
 
        gain_index = 0;
-       for (i = 0; i < 32; i++) {
+       for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) {
                if (ah->paprd_gain_table_index[i] >= desired_gain)
                        break;
                gain_index++;
index 9eb3aa2..6de3f0b 100644 (file)
 #define AR_PHY_POWERTX_RATE8_POWERTXHT40_5     0x3F00
 #define AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S   8
 
+#define AR_PHY_CL_TAB_CL_GAIN_MOD              0x1f
+#define AR_PHY_CL_TAB_CL_GAIN_MOD_S            0
+
 void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
 
 #endif  /* AR9003_PHY_H */
index 359576f..46393f9 100644 (file)
@@ -101,6 +101,11 @@ enum buffer_type {
 
 #define ATH_TXSTATUS_RING_SIZE 64
 
+#define        DS2PHYS(_dd, _ds)                                               \
+       ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
+#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
+#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
+
 struct ath_descdma {
        void *dd_desc;
        dma_addr_t dd_desc_paddr;
index 4c790b5..0d13ff7 100644 (file)
@@ -361,6 +361,7 @@ void ath_beacon_tasklet(unsigned long data)
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath_buf *bf = NULL;
        struct ieee80211_vif *vif;
+       struct ath_tx_status ts;
        int slot;
        u32 bfaddr, bc = 0;
 
@@ -385,7 +386,9 @@ void ath_beacon_tasklet(unsigned long data)
                        ath_dbg(common, ATH_DBG_BSTUCK,
                                "beacon is officially stuck\n");
                        sc->sc_flags |= SC_OP_TSF_RESET;
+                       spin_lock(&sc->sc_pcu_lock);
                        ath_reset(sc, true);
+                       spin_unlock(&sc->sc_pcu_lock);
                }
 
                return;
@@ -465,6 +468,11 @@ void ath_beacon_tasklet(unsigned long data)
                ath9k_hw_txstart(ah, sc->beacon.beaconq);
 
                sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
+               if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
+                       spin_lock_bh(&sc->sc_pcu_lock);
+                       ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts);
+                       spin_unlock_bh(&sc->sc_pcu_lock);
+               }
        }
 }
 
index 260f1f3..8028fe9 100644 (file)
@@ -49,6 +49,8 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
          .driver_info = AR9280_USB },  /* Netgear WNDA3200 */
        { USB_DEVICE(0x083A, 0xA704),
          .driver_info = AR9280_USB },  /* SMC Networks */
+       { USB_DEVICE(0x0411, 0x017f),
+         .driver_info = AR9280_USB },  /* Sony UWA-BR100 */
 
        { USB_DEVICE(0x0cf3, 0x20ff),
          .driver_info = STORAGE_DEVICE },
index 616e30b..b855fe1 100644 (file)
@@ -299,10 +299,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
                      struct list_head *head, const char *name,
                      int nbuf, int ndesc, bool is_tx)
 {
-#define        DS2PHYS(_dd, _ds)                                               \
-       ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
-#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
-#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        u8 *ds;
        struct ath_buf *bf;
@@ -397,9 +393,6 @@ fail2:
 fail:
        memset(dd, 0, sizeof(*dd));
        return error;
-#undef ATH_DESC_4KB_BOUND_CHECK
-#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
-#undef DS2PHYS
 }
 
 void ath9k_init_crypto(struct ath_softc *sc)
index 5ae303b..9098aaa 100644 (file)
@@ -617,8 +617,11 @@ void ath_hw_check(struct work_struct *work)
        ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, "
                "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
        if (busy >= 99) {
-               if (++sc->hw_busy_count >= 3)
+               if (++sc->hw_busy_count >= 3) {
+                       spin_lock_bh(&sc->sc_pcu_lock);
                        ath_reset(sc, true);
+                       spin_unlock_bh(&sc->sc_pcu_lock);
+               }
        } else if (busy >= 0)
                sc->hw_busy_count = 0;
 
@@ -637,7 +640,9 @@ static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
                        /* Rx is hung for more than 500ms. Reset it */
                        ath_dbg(common, ATH_DBG_RESET,
                                "Possible RX hang, resetting");
+                       spin_lock_bh(&sc->sc_pcu_lock);
                        ath_reset(sc, true);
+                       spin_unlock_bh(&sc->sc_pcu_lock);
                        count = 0;
                }
        } else
@@ -674,7 +679,9 @@ void ath9k_tasklet(unsigned long data)
 
        if ((status & ATH9K_INT_FATAL) ||
            (status & ATH9K_INT_BB_WATCHDOG)) {
+               spin_lock(&sc->sc_pcu_lock);
                ath_reset(sc, true);
+               spin_unlock(&sc->sc_pcu_lock);
                return;
        }
 
@@ -980,7 +987,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
        del_timer_sync(&common->ani.timer);
 
        ath9k_ps_wakeup(sc);
-       spin_lock_bh(&sc->sc_pcu_lock);
 
        ieee80211_stop_queues(hw);
 
@@ -1023,7 +1029,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
        }
 
        ieee80211_wake_queues(hw);
-       spin_unlock_bh(&sc->sc_pcu_lock);
 
        /* Start ANI */
        if (!common->disable_ani)
@@ -2326,9 +2331,9 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
        ath9k_ps_wakeup(sc);
        spin_lock_bh(&sc->sc_pcu_lock);
        drain_txq = ath_drain_all_txq(sc, false);
-       spin_unlock_bh(&sc->sc_pcu_lock);
        if (!drain_txq)
                ath_reset(sc, false);
+       spin_unlock_bh(&sc->sc_pcu_lock);
        ath9k_ps_restore(sc);
        ieee80211_wake_queues(hw);
 
index 7e79bba..52dadfc 100644 (file)
@@ -566,11 +566,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 
        rcu_read_unlock();
 
-       if (needreset) {
-               spin_unlock_bh(&sc->sc_pcu_lock);
+       if (needreset)
                ath_reset(sc, false);
-               spin_lock_bh(&sc->sc_pcu_lock);
-       }
 }
 
 static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
@@ -2170,7 +2167,9 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
        if (needreset) {
                ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
                        "tx hung, resetting the chip\n");
+               spin_lock_bh(&sc->sc_pcu_lock);
                ath_reset(sc, true);
+               spin_unlock_bh(&sc->sc_pcu_lock);
        }
 
        ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
index ec21ea9..dc99030 100644 (file)
@@ -472,7 +472,7 @@ static struct sk_buff *carl9170_rx_copy_data(u8 *buf, int len)
                u8 *qc = ieee80211_get_qos_ctl(hdr);
                reserved += NET_IP_ALIGN;
 
-               if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
+               if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT)
                        reserved += NET_IP_ALIGN;
        }
 
index 900dc9c..1b25604 100644 (file)
@@ -11,6 +11,7 @@ b43-$(CONFIG_B43_PHY_N)               += phy_n.o
 b43-$(CONFIG_B43_PHY_LP)       += phy_lp.o
 b43-$(CONFIG_B43_PHY_LP)       += tables_lpphy.o
 b43-$(CONFIG_B43_PHY_HT)       += phy_ht.o
+b43-$(CONFIG_B43_PHY_HT)       += tables_phy_ht.o
 b43-$(CONFIG_B43_PHY_HT)       += radio_2059.o
 b43-y                          += sysfs.o
 b43-y                          += xmit.o
index 72f01ce..30b19c6 100644 (file)
 
 #include "b43.h"
 #include "phy_ht.h"
+#include "tables_phy_ht.h"
 #include "radio_2059.h"
 #include "main.h"
 
+/**************************************************
+ * Radio 2059.
+ **************************************************/
+
 static void b43_radio_2059_channel_setup(struct b43_wldev *dev,
                        const struct b43_phy_ht_channeltab_e_radio2059 *e)
 {
@@ -56,7 +61,7 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev,
        b43_radio_write(dev, 0x98, e->radio_syn98);
 
        for (i = 0; i < 2; i++) {
-               routing = i ? 0x800 : 0x400;
+               routing = i ? R2059_RXRX1 : R2059_TXRX0;
                b43_radio_write(dev, routing | 0x4a, e->radio_rxtx4a);
                b43_radio_write(dev, routing | 0x58, e->radio_rxtx58);
                b43_radio_write(dev, routing | 0x5a, e->radio_rxtx5a);
@@ -78,11 +83,120 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev,
        udelay(300);
 }
 
+static void b43_radio_2059_init(struct b43_wldev *dev)
+{
+       const u16 routing[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1 };
+       const u16 radio_values[3][2] = {
+               { 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 },
+       };
+       u16 i, j;
+
+       b43_radio_write(dev, R2059_ALL | 0x51, 0x0070);
+       b43_radio_write(dev, R2059_ALL | 0x5a, 0x0003);
+
+       for (i = 0; i < ARRAY_SIZE(routing); i++)
+               b43_radio_set(dev, routing[i] | 0x146, 0x3);
+
+       b43_radio_set(dev, 0x2e, 0x0078);
+       b43_radio_set(dev, 0xc0, 0x0080);
+       msleep(2);
+       b43_radio_mask(dev, 0x2e, ~0x0078);
+       b43_radio_mask(dev, 0xc0, ~0x0080);
+
+       if (1) { /* FIXME */
+               b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x1);
+               udelay(10);
+               b43_radio_set(dev, R2059_RXRX1 | 0x0BF, 0x1);
+               b43_radio_maskset(dev, R2059_RXRX1 | 0x19B, 0x3, 0x2);
+
+               b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x2);
+               udelay(100);
+               b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x2);
+
+               for (i = 0; i < 10000; i++) {
+                       if (b43_radio_read(dev, R2059_RXRX1 | 0x145) & 1) {
+                               i = 0;
+                               break;
+                       }
+                       udelay(100);
+               }
+               if (i)
+                       b43err(dev->wl, "radio 0x945 timeout\n");
+
+               b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x1);
+               b43_radio_set(dev, 0xa, 0x60);
+
+               for (i = 0; i < 3; i++) {
+                       b43_radio_write(dev, 0x17F, radio_values[i][0]);
+                       b43_radio_write(dev, 0x13D, 0x6E);
+                       b43_radio_write(dev, 0x13E, radio_values[i][1]);
+                       b43_radio_write(dev, 0x13C, 0x55);
+
+                       for (j = 0; j < 10000; j++) {
+                               if (b43_radio_read(dev, 0x140) & 2) {
+                                       j = 0;
+                                       break;
+                               }
+                               udelay(500);
+                       }
+                       if (j)
+                               b43err(dev->wl, "radio 0x140 timeout\n");
+
+                       b43_radio_write(dev, 0x13C, 0x15);
+               }
+
+               b43_radio_mask(dev, 0x17F, ~0x1);
+       }
+
+       b43_radio_mask(dev, 0x11, 0x0008);
+}
+
+/**************************************************
+ * Channel switching ops.
+ **************************************************/
+
 static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
                                const struct b43_phy_ht_channeltab_e_phy *e,
                                struct ieee80211_channel *new_channel)
 {
-       /* TODO */
+       bool old_band_5ghz;
+       u8 i;
+
+       old_band_5ghz = b43_phy_read(dev, B43_PHY_HT_BANDCTL) & 0; /* FIXME */
+       if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
+               /* TODO */
+       } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
+               /* TODO */
+       }
+
+       b43_phy_write(dev, B43_PHY_HT_BW1, e->bw1);
+       b43_phy_write(dev, B43_PHY_HT_BW2, e->bw2);
+       b43_phy_write(dev, B43_PHY_HT_BW3, e->bw3);
+       b43_phy_write(dev, B43_PHY_HT_BW4, e->bw4);
+       b43_phy_write(dev, B43_PHY_HT_BW5, e->bw5);
+       b43_phy_write(dev, B43_PHY_HT_BW6, e->bw6);
+
+       /* TODO: some ops on PHY regs 0x0B0 and 0xC0A */
+
+       /* TODO: separated function? */
+       for (i = 0; i < 3; i++) {
+               u16 mask;
+               u32 tmp = b43_httab_read(dev, B43_HTTAB32(26, 0xE8));
+
+               if (0) /* FIXME */
+                       mask = 0x2 << (i * 4);
+               else
+                       mask = 0;
+               b43_phy_mask(dev, B43_PHY_EXTG(0x108), mask);
+
+               b43_httab_write(dev, B43_HTTAB16(7, 0x110 + i), tmp >> 16);
+               b43_httab_write(dev, B43_HTTAB8(13, 0x63 + (i * 4)),
+                               tmp & 0xFF);
+               b43_httab_write(dev, B43_HTTAB8(13, 0x73 + (i * 4)),
+                               tmp & 0xFF);
+       }
+
+       b43_phy_write(dev, 0x017e, 0x3830);
 }
 
 static int b43_phy_ht_set_channel(struct b43_wldev *dev,
@@ -139,6 +253,13 @@ static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev)
        memset(phy_ht, 0, sizeof(*phy_ht));
 }
 
+static int b43_phy_ht_op_init(struct b43_wldev *dev)
+{
+       b43_phy_ht_tables_init(dev);
+
+       return 0;
+}
+
 static void b43_phy_ht_op_free(struct b43_wldev *dev)
 {
        struct b43_phy *phy = &dev->phy;
@@ -162,6 +283,11 @@ static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev,
                b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x1);
                b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, ~0);
                b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, ~0, 0x2);
+
+               if (dev->phy.radio_ver == 0x2059)
+                       b43_radio_2059_init(dev);
+               else
+                       B43_WARN_ON(1);
        }
 }
 
@@ -255,9 +381,7 @@ const struct b43_phy_operations b43_phyops_ht = {
        .allocate               = b43_phy_ht_op_allocate,
        .free                   = b43_phy_ht_op_free,
        .prepare_structs        = b43_phy_ht_op_prepare_structs,
-       /*
        .init                   = b43_phy_ht_op_init,
-       */
        .phy_read               = b43_phy_ht_op_read,
        .phy_write              = b43_phy_ht_op_write,
        .phy_maskset            = b43_phy_ht_op_maskset,
index afa448d..7ad7aff 100644 (file)
@@ -4,9 +4,16 @@
 #include "phy_common.h"
 
 
+#define B43_PHY_HT_BANDCTL                     0x009 /* Band control */
 #define B43_PHY_HT_TABLE_ADDR                  0x072 /* Table address */
 #define B43_PHY_HT_TABLE_DATALO                        0x073 /* Table data low */
 #define B43_PHY_HT_TABLE_DATAHI                        0x074 /* Table data high */
+#define B43_PHY_HT_BW1                         0x1CE
+#define B43_PHY_HT_BW2                         0x1CF
+#define B43_PHY_HT_BW3                         0x1D0
+#define B43_PHY_HT_BW4                         0x1D1
+#define B43_PHY_HT_BW5                         0x1D2
+#define B43_PHY_HT_BW6                         0x1D3
 
 #define B43_PHY_HT_RF_CTL1                     B43_PHY_EXTG(0x010)
 
 
 /* Values for PHY registers used on channel switching */
 struct b43_phy_ht_channeltab_e_phy {
-       /* TODO */
+       u16 bw1;
+       u16 bw2;
+       u16 bw3;
+       u16 bw4;
+       u16 bw5;
+       u16 bw6;
 };
 
 
index 55d7da7..23dea4b 100644 (file)
 #include "b43.h"
 #include "radio_2059.h"
 
+#define RADIOREGS(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
+                 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
+                 r20, r21, r22, r23, r24, r25, r26, r27, r28) \
+       .radio_syn16                    = r00,  \
+       .radio_syn17                    = r01,  \
+       .radio_syn22                    = r02,  \
+       .radio_syn25                    = r03,  \
+       .radio_syn27                    = r04,  \
+       .radio_syn28                    = r05,  \
+       .radio_syn29                    = r06,  \
+       .radio_syn2c                    = r07,  \
+       .radio_syn2d                    = r08,  \
+       .radio_syn37                    = r09,  \
+       .radio_syn41                    = r10,  \
+       .radio_syn43                    = r11,  \
+       .radio_syn47                    = r12,  \
+       .radio_syn4a                    = r13,  \
+       .radio_syn58                    = r14,  \
+       .radio_syn5a                    = r15,  \
+       .radio_syn6a                    = r16,  \
+       .radio_syn6d                    = r17,  \
+       .radio_syn6e                    = r18,  \
+       .radio_syn92                    = r19,  \
+       .radio_syn98                    = r20,  \
+       .radio_rxtx4a                   = r21,  \
+       .radio_rxtx58                   = r22,  \
+       .radio_rxtx5a                   = r23,  \
+       .radio_rxtx6a                   = r24,  \
+       .radio_rxtx6d                   = r25,  \
+       .radio_rxtx6e                   = r26,  \
+       .radio_rxtx92                   = r27,  \
+       .radio_rxtx98                   = r28
+
+#define PHYREGS(r0, r1, r2, r3, r4, r5)        \
+       .phy_regs.bw1   = r0,   \
+       .phy_regs.bw2   = r1,   \
+       .phy_regs.bw3   = r2,   \
+       .phy_regs.bw4   = r3,   \
+       .phy_regs.bw5   = r4,   \
+       .phy_regs.bw6   = r5
+
+static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radio2059[] = {
+  {    .freq                   = 2412,
+       RADIOREGS(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
+                 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00),
+       PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
+  },
+  {    .freq                   = 2417,
+       RADIOREGS(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
+                 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00),
+       PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
+  },
+  {    .freq                   = 2422,
+       RADIOREGS(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
+                 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00),
+       PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
+  },
+  {    .freq                   = 2427,
+       RADIOREGS(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
+                 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00),
+       PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
+  },
+  {    .freq                   = 2432,
+       RADIOREGS(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
+                 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00),
+       PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
+  },
+  {    .freq                   = 2437,
+       RADIOREGS(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
+                 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00),
+       PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
+  },
+  {    .freq                   = 2442,
+       RADIOREGS(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
+                 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00),
+       PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
+  },
+  {    .freq                   = 2447,
+       RADIOREGS(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
+                 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00),
+       PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
+  },
+  {    .freq                   = 2452,
+       RADIOREGS(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
+                 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00),
+       PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
+  },
+  {    .freq                   = 2457,
+       RADIOREGS(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
+                 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00),
+       PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
+  },
+  {    .freq                   = 2462,
+       RADIOREGS(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
+                 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00),
+       PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
+  },
+  {    .freq                   = 2467,
+       RADIOREGS(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3,
+                 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00),
+       PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
+  },
+  {    .freq                   = 2472,
+       RADIOREGS(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8,
+                 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x61, 0x03,
+                 0x00, 0x00, 0x00, 0xf0, 0x00),
+       PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
+  },
+};
+
 const struct b43_phy_ht_channeltab_e_radio2059
 *b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq)
 {
index c2874b1..e4d69e5 100644 (file)
@@ -5,6 +5,11 @@
 
 #include "phy_ht.h"
 
+#define R2059_SYN                      0x000
+#define R2059_TXRX0                    0x400
+#define R2059_RXRX1                    0x800
+#define R2059_ALL                      0xC00
+
 /* Values for various registers uploaded on channel switching */
 struct b43_phy_ht_channeltab_e_radio2059 {
        /* The channel frequency in MHz */
diff --git a/drivers/net/wireless/b43/tables_phy_ht.c b/drivers/net/wireless/b43/tables_phy_ht.c
new file mode 100644 (file)
index 0000000..6039386
--- /dev/null
@@ -0,0 +1,750 @@
+/*
+
+  Broadcom B43 wireless driver
+  IEEE 802.11n HT-PHY data tables
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; see the file COPYING.  If not, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "tables_phy_ht.h"
+#include "phy_common.h"
+#include "phy_ht.h"
+
+static const u16 b43_httab_0x12[] = {
+       0x0000, 0x0008, 0x000a, 0x0010, 0x0012, 0x0019,
+       0x001a, 0x001c, 0x0080, 0x0088, 0x008a, 0x0090,
+       0x0092, 0x0099, 0x009a, 0x009c, 0x0100, 0x0108,
+       0x010a, 0x0110, 0x0112, 0x0119, 0x011a, 0x011c,
+       0x0180, 0x0188, 0x018a, 0x0190, 0x0192, 0x0199,
+       0x019a, 0x019c, 0x0000, 0x0098, 0x00a0, 0x00a8,
+       0x009a, 0x00a2, 0x00aa, 0x0120, 0x0128, 0x0128,
+       0x0130, 0x0138, 0x0138, 0x0140, 0x0122, 0x012a,
+       0x012a, 0x0132, 0x013a, 0x013a, 0x0142, 0x01a8,
+       0x01b0, 0x01b8, 0x01b0, 0x01b8, 0x01c0, 0x01c8,
+       0x01c0, 0x01c8, 0x01d0, 0x01d0, 0x01d8, 0x01aa,
+       0x01b2, 0x01ba, 0x01b2, 0x01ba, 0x01c2, 0x01ca,
+       0x01c2, 0x01ca, 0x01d2, 0x01d2, 0x01da, 0x0001,
+       0x0002, 0x0004, 0x0009, 0x000c, 0x0011, 0x0014,
+       0x0018, 0x0020, 0x0021, 0x0022, 0x0024, 0x0081,
+       0x0082, 0x0084, 0x0089, 0x008c, 0x0091, 0x0094,
+       0x0098, 0x00a0, 0x00a1, 0x00a2, 0x00a4, 0x0007,
+       0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007,
+       0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007,
+       0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007,
+       0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007,
+       0x0007, 0x0007,
+};
+
+static const u16 b43_httab_0x27[] = {
+       0x0009, 0x000e, 0x0011, 0x0014, 0x0017, 0x001a,
+       0x001d, 0x0020, 0x0009, 0x000e, 0x0011, 0x0014,
+       0x0017, 0x001a, 0x001d, 0x0020, 0x0009, 0x000e,
+       0x0011, 0x0014, 0x0017, 0x001a, 0x001d, 0x0020,
+       0x0009, 0x000e, 0x0011, 0x0014, 0x0017, 0x001a,
+       0x001d, 0x0020,
+};
+
+static const u16 b43_httab_0x26[] = {
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000,
+};
+
+static const u32 b43_httab_0x25[] = {
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u32 b43_httab_0x2f[] = {
+       0x00035700, 0x0002cc9a, 0x00026666, 0x0001581f,
+       0x0001581f, 0x0001581f, 0x0001581f, 0x0001581f,
+       0x0001581f, 0x0001581f, 0x0001581f, 0x00035700,
+       0x0002cc9a, 0x00026666, 0x0001581f, 0x0001581f,
+       0x0001581f, 0x0001581f, 0x0001581f, 0x0001581f,
+       0x0001581f, 0x0001581f,
+};
+
+static const u16 b43_httab_0x1a[] = {
+       0x0055, 0x0054, 0x0054, 0x0053, 0x0052, 0x0052,
+       0x0051, 0x0051, 0x0050, 0x004f, 0x004f, 0x004e,
+       0x004e, 0x004d, 0x004c, 0x004c, 0x004b, 0x004a,
+       0x0049, 0x0049, 0x0048, 0x0047, 0x0046, 0x0046,
+       0x0045, 0x0044, 0x0043, 0x0042, 0x0041, 0x0040,
+       0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003a,
+       0x0039, 0x0038, 0x0037, 0x0036, 0x0035, 0x0033,
+       0x0032, 0x0031, 0x002f, 0x002e, 0x002c, 0x002b,
+       0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f,
+       0x001d, 0x001a, 0x0018, 0x0015, 0x0012, 0x000e,
+       0x000b, 0x0007, 0x0002, 0x00fd,
+};
+
+static const u16 b43_httab_0x1b[] = {
+       0x0055, 0x0054, 0x0054, 0x0053, 0x0052, 0x0052,
+       0x0051, 0x0051, 0x0050, 0x004f, 0x004f, 0x004e,
+       0x004e, 0x004d, 0x004c, 0x004c, 0x004b, 0x004a,
+       0x0049, 0x0049, 0x0048, 0x0047, 0x0046, 0x0046,
+       0x0045, 0x0044, 0x0043, 0x0042, 0x0041, 0x0040,
+       0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003a,
+       0x0039, 0x0038, 0x0037, 0x0036, 0x0035, 0x0033,
+       0x0032, 0x0031, 0x002f, 0x002e, 0x002c, 0x002b,
+       0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f,
+       0x001d, 0x001a, 0x0018, 0x0015, 0x0012, 0x000e,
+       0x000b, 0x0007, 0x0002, 0x00fd,
+};
+
+static const u16 b43_httab_0x1c[] = {
+       0x0055, 0x0054, 0x0054, 0x0053, 0x0052, 0x0052,
+       0x0051, 0x0051, 0x0050, 0x004f, 0x004f, 0x004e,
+       0x004e, 0x004d, 0x004c, 0x004c, 0x004b, 0x004a,
+       0x0049, 0x0049, 0x0048, 0x0047, 0x0046, 0x0046,
+       0x0045, 0x0044, 0x0043, 0x0042, 0x0041, 0x0040,
+       0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003a,
+       0x0039, 0x0038, 0x0037, 0x0036, 0x0035, 0x0033,
+       0x0032, 0x0031, 0x002f, 0x002e, 0x002c, 0x002b,
+       0x0029, 0x0027, 0x0025, 0x0023, 0x0021, 0x001f,
+       0x001d, 0x001a, 0x0018, 0x0015, 0x0012, 0x000e,
+       0x000b, 0x0007, 0x0002, 0x00fd,
+};
+
+static const u32 b43_httab_0x1a_0xc0[] = {
+       0x5bf70044, 0x5bf70042, 0x5bf70040, 0x5bf7003e,
+       0x5bf7003c, 0x5bf7003b, 0x5bf70039, 0x5bf70037,
+       0x5bf70036, 0x5bf70034, 0x5bf70033, 0x5bf70031,
+       0x5bf70030, 0x5ba70044, 0x5ba70042, 0x5ba70040,
+       0x5ba7003e, 0x5ba7003c, 0x5ba7003b, 0x5ba70039,
+       0x5ba70037, 0x5ba70036, 0x5ba70034, 0x5ba70033,
+       0x5b770044, 0x5b770042, 0x5b770040, 0x5b77003e,
+       0x5b77003c, 0x5b77003b, 0x5b770039, 0x5b770037,
+       0x5b770036, 0x5b770034, 0x5b770033, 0x5b770031,
+       0x5b770030, 0x5b77002f, 0x5b77002d, 0x5b77002c,
+       0x5b470044, 0x5b470042, 0x5b470040, 0x5b47003e,
+       0x5b47003c, 0x5b47003b, 0x5b470039, 0x5b470037,
+       0x5b470036, 0x5b470034, 0x5b470033, 0x5b470031,
+       0x5b470030, 0x5b47002f, 0x5b47002d, 0x5b47002c,
+       0x5b47002b, 0x5b47002a, 0x5b270044, 0x5b270042,
+       0x5b270040, 0x5b27003e, 0x5b27003c, 0x5b27003b,
+       0x5b270039, 0x5b270037, 0x5b270036, 0x5b270034,
+       0x5b270033, 0x5b270031, 0x5b270030, 0x5b27002f,
+       0x5b170044, 0x5b170042, 0x5b170040, 0x5b17003e,
+       0x5b17003c, 0x5b17003b, 0x5b170039, 0x5b170037,
+       0x5b170036, 0x5b170034, 0x5b170033, 0x5b170031,
+       0x5b170030, 0x5b17002f, 0x5b17002d, 0x5b17002c,
+       0x5b17002b, 0x5b17002a, 0x5b170028, 0x5b170027,
+       0x5b170026, 0x5b170025, 0x5b170024, 0x5b170023,
+       0x5b070044, 0x5b070042, 0x5b070040, 0x5b07003e,
+       0x5b07003c, 0x5b07003b, 0x5b070039, 0x5b070037,
+       0x5b070036, 0x5b070034, 0x5b070033, 0x5b070031,
+       0x5b070030, 0x5b07002f, 0x5b07002d, 0x5b07002c,
+       0x5b07002b, 0x5b07002a, 0x5b070028, 0x5b070027,
+       0x5b070026, 0x5b070025, 0x5b070024, 0x5b070023,
+       0x5b070022, 0x5b070021, 0x5b070020, 0x5b07001f,
+       0x5b07001e, 0x5b07001d, 0x5b07001d, 0x5b07001c,
+};
+
+static const u32 b43_httab_0x1a_0x140[] = {
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u32 b43_httab_0x1b_0x140[] = {
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u32 b43_httab_0x1c_0x140[] = {
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static const u16 b43_httab_0x1a_0x1c0[] = {
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000,
+};
+
+static const u16 b43_httab_0x1b_0x1c0[] = {
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000,
+};
+
+static const u16 b43_httab_0x1c_0x1c0[] = {
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000,
+};
+
+static const u16 b43_httab_0x1a_0x240[] = {
+       0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036,
+       0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036,
+       0x0036, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a,
+       0x002a, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a,
+       0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e,
+       0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e,
+       0x001e, 0x001e, 0x001e, 0x001e, 0x000e, 0x000e,
+       0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e,
+       0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e,
+       0x000e, 0x000e, 0x000e, 0x000e, 0x01fc, 0x01fc,
+       0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc,
+       0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc,
+       0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee,
+       0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee,
+       0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee,
+       0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6,
+};
+
+static const u16 b43_httab_0x1b_0x240[] = {
+       0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036,
+       0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036,
+       0x0036, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a,
+       0x002a, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a,
+       0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e,
+       0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e,
+       0x001e, 0x001e, 0x001e, 0x001e, 0x000e, 0x000e,
+       0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e,
+       0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e,
+       0x000e, 0x000e, 0x000e, 0x000e, 0x01fc, 0x01fc,
+       0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc,
+       0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc,
+       0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee,
+       0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee,
+       0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee,
+       0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6,
+};
+
+static const u16 b43_httab_0x1c_0x240[] = {
+       0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036,
+       0x0036, 0x0036, 0x0036, 0x0036, 0x0036, 0x0036,
+       0x0036, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a,
+       0x002a, 0x002a, 0x002a, 0x002a, 0x002a, 0x002a,
+       0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e,
+       0x001e, 0x001e, 0x001e, 0x001e, 0x001e, 0x001e,
+       0x001e, 0x001e, 0x001e, 0x001e, 0x000e, 0x000e,
+       0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e,
+       0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e,
+       0x000e, 0x000e, 0x000e, 0x000e, 0x01fc, 0x01fc,
+       0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc,
+       0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc, 0x01fc,
+       0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee,
+       0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee,
+       0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee,
+       0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee, 0x01ee,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6, 0x01d6,
+       0x01d6, 0x01d6,
+};
+
+static const u32 b43_httab_0x1f[] = {
+       0x00000000, 0x00000000, 0x00016023, 0x00006028,
+       0x00034036, 0x0003402e, 0x0007203c, 0x0006e037,
+       0x00070030, 0x0009401f, 0x0009a00f, 0x000b600d,
+       0x000c8007, 0x000ce007, 0x00101fff, 0x00121ff9,
+       0x0012e004, 0x0014dffc, 0x0016dff6, 0x0018dfe9,
+       0x001b3fe5, 0x001c5fd0, 0x001ddfc2, 0x001f1fb6,
+       0x00207fa4, 0x00219f8f, 0x0022ff7d, 0x00247f6c,
+       0x0024df5b, 0x00267f4b, 0x0027df3b, 0x0029bf3b,
+       0x002b5f2f, 0x002d3f2e, 0x002f5f2a, 0x002fff15,
+       0x00315f0b, 0x0032defa, 0x0033beeb, 0x0034fed9,
+       0x00353ec5, 0x00361eb0, 0x00363e9b, 0x0036be87,
+       0x0036be70, 0x0038fe67, 0x0044beb2, 0x00513ef3,
+       0x00595f11, 0x00669f3d, 0x0078dfdf, 0x00a143aa,
+       0x01642fff, 0x0162afff, 0x01620fff, 0x0160cfff,
+       0x015f0fff, 0x015dafff, 0x015bcfff, 0x015bcfff,
+       0x015b4fff, 0x015acfff, 0x01590fff, 0x0156cfff,
+};
+
+static const u32 b43_httab_0x21[] = {
+       0x00000000, 0x00000000, 0x00016023, 0x00006028,
+       0x00034036, 0x0003402e, 0x0007203c, 0x0006e037,
+       0x00070030, 0x0009401f, 0x0009a00f, 0x000b600d,
+       0x000c8007, 0x000ce007, 0x00101fff, 0x00121ff9,
+       0x0012e004, 0x0014dffc, 0x0016dff6, 0x0018dfe9,
+       0x001b3fe5, 0x001c5fd0, 0x001ddfc2, 0x001f1fb6,
+       0x00207fa4, 0x00219f8f, 0x0022ff7d, 0x00247f6c,
+       0x0024df5b, 0x00267f4b, 0x0027df3b, 0x0029bf3b,
+       0x002b5f2f, 0x002d3f2e, 0x002f5f2a, 0x002fff15,
+       0x00315f0b, 0x0032defa, 0x0033beeb, 0x0034fed9,
+       0x00353ec5, 0x00361eb0, 0x00363e9b, 0x0036be87,
+       0x0036be70, 0x0038fe67, 0x0044beb2, 0x00513ef3,
+       0x00595f11, 0x00669f3d, 0x0078dfdf, 0x00a143aa,
+       0x01642fff, 0x0162afff, 0x01620fff, 0x0160cfff,
+       0x015f0fff, 0x015dafff, 0x015bcfff, 0x015bcfff,
+       0x015b4fff, 0x015acfff, 0x01590fff, 0x0156cfff,
+};
+
+static const u32 b43_httab_0x23[] = {
+       0x00000000, 0x00000000, 0x00016023, 0x00006028,
+       0x00034036, 0x0003402e, 0x0007203c, 0x0006e037,
+       0x00070030, 0x0009401f, 0x0009a00f, 0x000b600d,
+       0x000c8007, 0x000ce007, 0x00101fff, 0x00121ff9,
+       0x0012e004, 0x0014dffc, 0x0016dff6, 0x0018dfe9,
+       0x001b3fe5, 0x001c5fd0, 0x001ddfc2, 0x001f1fb6,
+       0x00207fa4, 0x00219f8f, 0x0022ff7d, 0x00247f6c,
+       0x0024df5b, 0x00267f4b, 0x0027df3b, 0x0029bf3b,
+       0x002b5f2f, 0x002d3f2e, 0x002f5f2a, 0x002fff15,
+       0x00315f0b, 0x0032defa, 0x0033beeb, 0x0034fed9,
+       0x00353ec5, 0x00361eb0, 0x00363e9b, 0x0036be87,
+       0x0036be70, 0x0038fe67, 0x0044beb2, 0x00513ef3,
+       0x00595f11, 0x00669f3d, 0x0078dfdf, 0x00a143aa,
+       0x01642fff, 0x0162afff, 0x01620fff, 0x0160cfff,
+       0x015f0fff, 0x015dafff, 0x015bcfff, 0x015bcfff,
+       0x015b4fff, 0x015acfff, 0x01590fff, 0x0156cfff,
+};
+
+static const u32 b43_httab_0x20[] = {
+       0x0b5e002d, 0x0ae2002f, 0x0a3b0032, 0x09a70035,
+       0x09220038, 0x08ab003b, 0x081f003f, 0x07a20043,
+       0x07340047, 0x06d2004b, 0x067a004f, 0x06170054,
+       0x05bf0059, 0x0571005e, 0x051e0064, 0x04d3006a,
+       0x04910070, 0x044c0077, 0x040f007e, 0x03d90085,
+       0x03a1008d, 0x036f0095, 0x033d009e, 0x030b00a8,
+       0x02e000b2, 0x02b900bc, 0x029200c7, 0x026d00d3,
+       0x024900e0, 0x022900ed, 0x020a00fb, 0x01ec010a,
+       0x01d20119, 0x01b7012a, 0x019e013c, 0x0188014e,
+       0x01720162, 0x015d0177, 0x0149018e, 0x013701a5,
+       0x012601be, 0x011501d8, 0x010601f4, 0x00f70212,
+       0x00e90231, 0x00dc0253, 0x00d00276, 0x00c4029b,
+       0x00b902c3, 0x00af02ed, 0x00a50319, 0x009c0348,
+       0x0093037a, 0x008b03af, 0x008303e6, 0x007c0422,
+       0x00750460, 0x006e04a3, 0x006804e9, 0x00620533,
+       0x005d0582, 0x005805d6, 0x0053062e, 0x004e068c,
+};
+
+static const u32 b43_httab_0x22[] = {
+       0x0b5e002d, 0x0ae2002f, 0x0a3b0032, 0x09a70035,
+       0x09220038, 0x08ab003b, 0x081f003f, 0x07a20043,
+       0x07340047, 0x06d2004b, 0x067a004f, 0x06170054,
+       0x05bf0059, 0x0571005e, 0x051e0064, 0x04d3006a,
+       0x04910070, 0x044c0077, 0x040f007e, 0x03d90085,
+       0x03a1008d, 0x036f0095, 0x033d009e, 0x030b00a8,
+       0x02e000b2, 0x02b900bc, 0x029200c7, 0x026d00d3,
+       0x024900e0, 0x022900ed, 0x020a00fb, 0x01ec010a,
+       0x01d20119, 0x01b7012a, 0x019e013c, 0x0188014e,
+       0x01720162, 0x015d0177, 0x0149018e, 0x013701a5,
+       0x012601be, 0x011501d8, 0x010601f4, 0x00f70212,
+       0x00e90231, 0x00dc0253, 0x00d00276, 0x00c4029b,
+       0x00b902c3, 0x00af02ed, 0x00a50319, 0x009c0348,
+       0x0093037a, 0x008b03af, 0x008303e6, 0x007c0422,
+       0x00750460, 0x006e04a3, 0x006804e9, 0x00620533,
+       0x005d0582, 0x005805d6, 0x0053062e, 0x004e068c,
+};
+
+static const u32 b43_httab_0x24[] = {
+       0x0b5e002d, 0x0ae2002f, 0x0a3b0032, 0x09a70035,
+       0x09220038, 0x08ab003b, 0x081f003f, 0x07a20043,
+       0x07340047, 0x06d2004b, 0x067a004f, 0x06170054,
+       0x05bf0059, 0x0571005e, 0x051e0064, 0x04d3006a,
+       0x04910070, 0x044c0077, 0x040f007e, 0x03d90085,
+       0x03a1008d, 0x036f0095, 0x033d009e, 0x030b00a8,
+       0x02e000b2, 0x02b900bc, 0x029200c7, 0x026d00d3,
+       0x024900e0, 0x022900ed, 0x020a00fb, 0x01ec010a,
+       0x01d20119, 0x01b7012a, 0x019e013c, 0x0188014e,
+       0x01720162, 0x015d0177, 0x0149018e, 0x013701a5,
+       0x012601be, 0x011501d8, 0x010601f4, 0x00f70212,
+       0x00e90231, 0x00dc0253, 0x00d00276, 0x00c4029b,
+       0x00b902c3, 0x00af02ed, 0x00a50319, 0x009c0348,
+       0x0093037a, 0x008b03af, 0x008303e6, 0x007c0422,
+       0x00750460, 0x006e04a3, 0x006804e9, 0x00620533,
+       0x005d0582, 0x005805d6, 0x0053062e, 0x004e068c,
+};
+
+/**************************************************
+ * R/W ops.
+ **************************************************/
+
+u32 b43_httab_read(struct b43_wldev *dev, u32 offset)
+{
+       u32 type, value;
+
+       type = offset & B43_HTTAB_TYPEMASK;
+       offset &= ~B43_HTTAB_TYPEMASK;
+       B43_WARN_ON(offset > 0xFFFF);
+
+       switch (type) {
+       case B43_HTTAB_8BIT:
+               b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset);
+               value = b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO) & 0xFF;
+               break;
+       case B43_HTTAB_16BIT:
+               b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset);
+               value = b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO);
+               break;
+       case B43_HTTAB_32BIT:
+               b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset);
+               value = b43_phy_read(dev, B43_PHY_HT_TABLE_DATAHI);
+               value <<= 16;
+               value |= b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO);
+               break;
+       default:
+               B43_WARN_ON(1);
+               value = 0;
+       }
+
+       return value;
+}
+
+void b43_httab_read_bulk(struct b43_wldev *dev, u32 offset,
+                        unsigned int nr_elements, void *_data)
+{
+       u32 type;
+       u8 *data = _data;
+       unsigned int i;
+
+       type = offset & B43_HTTAB_TYPEMASK;
+       offset &= ~B43_HTTAB_TYPEMASK;
+       B43_WARN_ON(offset > 0xFFFF);
+
+       b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset);
+
+       for (i = 0; i < nr_elements; i++) {
+               switch (type) {
+               case B43_HTTAB_8BIT:
+                       *data = b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO) & 0xFF;
+                       data++;
+                       break;
+               case B43_HTTAB_16BIT:
+                       *((u16 *)data) = b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO);
+                       data += 2;
+                       break;
+               case B43_HTTAB_32BIT:
+                       *((u32 *)data) = b43_phy_read(dev, B43_PHY_HT_TABLE_DATAHI);
+                       *((u32 *)data) <<= 16;
+                       *((u32 *)data) |= b43_phy_read(dev, B43_PHY_HT_TABLE_DATALO);
+                       data += 4;
+                       break;
+               default:
+                       B43_WARN_ON(1);
+               }
+       }
+}
+
+void b43_httab_write(struct b43_wldev *dev, u32 offset, u32 value)
+{
+       u32 type;
+
+       type = offset & B43_HTTAB_TYPEMASK;
+       offset &= 0xFFFF;
+
+       switch (type) {
+       case B43_HTTAB_8BIT:
+               B43_WARN_ON(value & ~0xFF);
+               b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset);
+               b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value);
+               break;
+       case B43_HTTAB_16BIT:
+               B43_WARN_ON(value & ~0xFFFF);
+               b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset);
+               b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value);
+               break;
+       case B43_HTTAB_32BIT:
+               b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset);
+               b43_phy_write(dev, B43_PHY_HT_TABLE_DATAHI, value >> 16);
+               b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value & 0xFFFF);
+               break;
+       default:
+               B43_WARN_ON(1);
+       }
+
+       return;
+}
+
+void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset,
+                         unsigned int nr_elements, const void *_data)
+{
+       u32 type, value;
+       const u8 *data = _data;
+       unsigned int i;
+
+       type = offset & B43_HTTAB_TYPEMASK;
+       offset &= ~B43_HTTAB_TYPEMASK;
+       B43_WARN_ON(offset > 0xFFFF);
+
+       b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, offset);
+
+       for (i = 0; i < nr_elements; i++) {
+               switch (type) {
+               case B43_HTTAB_8BIT:
+                       value = *data;
+                       data++;
+                       B43_WARN_ON(value & ~0xFF);
+                       b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value);
+                       break;
+               case B43_HTTAB_16BIT:
+                       value = *((u16 *)data);
+                       data += 2;
+                       B43_WARN_ON(value & ~0xFFFF);
+                       b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, value);
+                       break;
+               case B43_HTTAB_32BIT:
+                       value = *((u32 *)data);
+                       data += 4;
+                       b43_phy_write(dev, B43_PHY_HT_TABLE_DATAHI, value >> 16);
+                       b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO,
+                                       value & 0xFFFF);
+                       break;
+               default:
+                       B43_WARN_ON(1);
+               }
+       }
+}
+
+/**************************************************
+ * Tables ops.
+ **************************************************/
+
+#define httab_upload(dev, offset, data) do { \
+               b43_httab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
+       } while (0)
+void b43_phy_ht_tables_init(struct b43_wldev *dev)
+{
+       httab_upload(dev, B43_HTTAB16(0x12, 0), b43_httab_0x12);
+       httab_upload(dev, B43_HTTAB16(0x27, 0), b43_httab_0x27);
+       httab_upload(dev, B43_HTTAB16(0x26, 0), b43_httab_0x26);
+       httab_upload(dev, B43_HTTAB32(0x25, 0), b43_httab_0x25);
+       httab_upload(dev, B43_HTTAB32(0x2f, 0), b43_httab_0x2f);
+       httab_upload(dev, B43_HTTAB16(0x1a, 0), b43_httab_0x1a);
+       httab_upload(dev, B43_HTTAB16(0x1b, 0), b43_httab_0x1b);
+       httab_upload(dev, B43_HTTAB16(0x1c, 0), b43_httab_0x1c);
+       httab_upload(dev, B43_HTTAB32(0x1a, 0x0c0), b43_httab_0x1a_0xc0);
+       httab_upload(dev, B43_HTTAB32(0x1a, 0x140), b43_httab_0x1a_0x140);
+       httab_upload(dev, B43_HTTAB32(0x1b, 0x140), b43_httab_0x1b_0x140);
+       httab_upload(dev, B43_HTTAB32(0x1c, 0x140), b43_httab_0x1c_0x140);
+       httab_upload(dev, B43_HTTAB16(0x1a, 0x1c0), b43_httab_0x1a_0x1c0);
+       httab_upload(dev, B43_HTTAB16(0x1b, 0x1c0), b43_httab_0x1b_0x1c0);
+       httab_upload(dev, B43_HTTAB16(0x1c, 0x1c0), b43_httab_0x1c_0x1c0);
+       httab_upload(dev, B43_HTTAB16(0x1a, 0x240), b43_httab_0x1a_0x240);
+       httab_upload(dev, B43_HTTAB16(0x1b, 0x240), b43_httab_0x1b_0x240);
+       httab_upload(dev, B43_HTTAB16(0x1c, 0x240), b43_httab_0x1c_0x240);
+       httab_upload(dev, B43_HTTAB32(0x1f, 0), b43_httab_0x1f);
+       httab_upload(dev, B43_HTTAB32(0x21, 0), b43_httab_0x21);
+       httab_upload(dev, B43_HTTAB32(0x23, 0), b43_httab_0x23);
+       httab_upload(dev, B43_HTTAB32(0x20, 0), b43_httab_0x20);
+       httab_upload(dev, B43_HTTAB32(0x22, 0), b43_httab_0x22);
+       httab_upload(dev, B43_HTTAB32(0x24, 0), b43_httab_0x24);
+}
diff --git a/drivers/net/wireless/b43/tables_phy_ht.h b/drivers/net/wireless/b43/tables_phy_ht.h
new file mode 100644 (file)
index 0000000..ea3be38
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef B43_TABLES_PHY_HT_H_
+#define B43_TABLES_PHY_HT_H_
+
+/* The HT-PHY tables. */
+#define B43_HTTAB_TYPEMASK             0xF0000000
+#define B43_HTTAB_8BIT                 0x10000000
+#define B43_HTTAB_16BIT                        0x20000000
+#define B43_HTTAB_32BIT                        0x30000000
+#define B43_HTTAB8(table, offset)      (((table) << 10) | (offset) | B43_HTTAB_8BIT)
+#define B43_HTTAB16(table, offset)     (((table) << 10) | (offset) | B43_HTTAB_16BIT)
+#define B43_HTTAB32(table, offset)     (((table) << 10) | (offset) | B43_HTTAB_32BIT)
+
+u32 b43_httab_read(struct b43_wldev *dev, u32 offset);
+void b43_httab_read_bulk(struct b43_wldev *dev, u32 offset,
+                        unsigned int nr_elements, void *_data);
+void b43_httab_write(struct b43_wldev *dev, u32 offset, u32 value);
+void b43_httab_write_bulk(struct b43_wldev *dev, u32 offset,
+                         unsigned int nr_elements, const void *_data);
+
+void b43_phy_ht_tables_init(struct b43_wldev *dev);
+
+#endif /* B43_TABLES_PHY_HT_H_ */
index a2de7e9..84da793 100644 (file)
@@ -484,7 +484,7 @@ static inline u16 iwl_legacy_pcie_link_ctl(struct iwl_priv *priv)
 {
        int pos;
        u16 pci_lnk_ctl;
-       pos = pci_find_capability(priv->pci_dev, PCI_CAP_ID_EXP);
+       pos = pci_pcie_cap(priv->pci_dev);
        pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
        return pci_lnk_ctl;
 }
index 2daca80..e57fad9 100644 (file)
@@ -34,6 +34,7 @@
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
+#include <linux/stringify.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
 #define IWL100_UCODE_API_MIN 5
 
 #define IWL1000_FW_PRE "iwlwifi-1000-"
-#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
+#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE __stringify(api) ".ucode"
 
 #define IWL100_FW_PRE "iwlwifi-100-"
-#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode"
+#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE __stringify(api) ".ucode"
 
 
 /*
index 1c13300..64ed1f2 100644 (file)
@@ -34,6 +34,7 @@
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
+#include <linux/stringify.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
 #define IWL105_UCODE_API_MIN 5
 
 #define IWL2030_FW_PRE "iwlwifi-2030-"
-#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode"
+#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) ".ucode"
 
 #define IWL2000_FW_PRE "iwlwifi-2000-"
-#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode"
+#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE __stringify(api) ".ucode"
 
 #define IWL105_FW_PRE "iwlwifi-105-"
-#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE #api ".ucode"
+#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE __stringify(api) ".ucode"
 
 static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
 {
index 937a8f1..269dfdb 100644 (file)
@@ -35,6 +35,7 @@
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
+#include <linux/stringify.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
 #define IWL5150_UCODE_API_MIN 1
 
 #define IWL5000_FW_PRE "iwlwifi-5000-"
-#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode"
+#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE __stringify(api) ".ucode"
 
 #define IWL5150_FW_PRE "iwlwifi-5150-"
-#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode"
+#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) ".ucode"
 
 /* NIC configuration for 5000 series */
 static void iwl5000_nic_config(struct iwl_priv *priv)
index 3fcc092..f1c1db7 100644 (file)
@@ -34,6 +34,7 @@
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
+#include <linux/stringify.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
 #define IWL6000G2_UCODE_API_MIN 4
 
 #define IWL6000_FW_PRE "iwlwifi-6000-"
-#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
+#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE __stringify(api) ".ucode"
 
 #define IWL6050_FW_PRE "iwlwifi-6050-"
-#define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
+#define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE __stringify(api) ".ucode"
 
 #define IWL6005_FW_PRE "iwlwifi-6000g2a-"
-#define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode"
+#define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE __stringify(api) ".ucode"
 
 #define IWL6030_FW_PRE "iwlwifi-6000g2b-"
-#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode"
+#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode"
 
 static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
 {
index a7c66c4..8fa43d4 100644 (file)
@@ -210,6 +210,8 @@ static int iwlagn_rxon_disconn(struct iwl_priv *priv,
         * keys, so we have to restore those afterwards.
         */
        iwl_clear_ucode_stations(priv, ctx);
+       /* update -- might need P2P now */
+       iwl_update_bcast_station(priv, ctx);
        iwl_restore_stations(priv, ctx);
        ret = iwl_restore_default_wep_keys(priv, ctx);
        if (ret) {
index 0bd722c..9b32f83 100644 (file)
@@ -35,7 +35,7 @@
 #include "iwl-agn.h"
 
 static struct iwl_link_quality_cmd *
-iwl_sta_alloc_lq(struct iwl_priv *priv, u8 sta_id)
+iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id)
 {
        int i, r;
        struct iwl_link_quality_cmd *link_cmd;
@@ -47,10 +47,15 @@ iwl_sta_alloc_lq(struct iwl_priv *priv, u8 sta_id)
                IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
                return NULL;
        }
+
+       lockdep_assert_held(&priv->mutex);
+
        /* Set up the rate scaling to start at selected rate, fall back
         * all the way down to 1M in IEEE order, and then spin on 1M */
        if (priv->band == IEEE80211_BAND_5GHZ)
                r = IWL_RATE_6M_INDEX;
+       else if (ctx && ctx->vif && ctx->vif->p2p)
+               r = IWL_RATE_6M_INDEX;
        else
                r = IWL_RATE_1M_INDEX;
 
@@ -115,7 +120,7 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
        /* Set up default rate scaling table in device's station table */
-       link_cmd = iwl_sta_alloc_lq(priv, sta_id);
+       link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id);
        if (!link_cmd) {
                IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n",
                        addr);
@@ -554,7 +559,7 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
        priv->stations[sta_id].used |= IWL_STA_BCAST;
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
-       link_cmd = iwl_sta_alloc_lq(priv, sta_id);
+       link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id);
        if (!link_cmd) {
                IWL_ERR(priv,
                        "Unable to initialize rate scaling for bcast station.\n");
@@ -574,14 +579,14 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
  * Only used by iwlagn. Placed here to have all bcast station management
  * code together.
  */
-static int iwl_update_bcast_station(struct iwl_priv *priv,
-                                   struct iwl_rxon_context *ctx)
+int iwl_update_bcast_station(struct iwl_priv *priv,
+                            struct iwl_rxon_context *ctx)
 {
        unsigned long flags;
        struct iwl_link_quality_cmd *link_cmd;
        u8 sta_id = ctx->bcast_sta_id;
 
-       link_cmd = iwl_sta_alloc_lq(priv, sta_id);
+       link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id);
        if (!link_cmd) {
                IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n");
                return -ENOMEM;
index 77ceb8d..e2f6b2a 100644 (file)
@@ -132,6 +132,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
        struct iwl_host_cmd cmd = {
                .id = REPLY_TX_BEACON,
        };
+       struct ieee80211_tx_info *info;
        u32 frame_size;
        u32 rate_flags;
        u32 rate;
@@ -172,14 +173,31 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
                           frame_size);
 
        /* Set up packet rate and flags */
-       rate = iwl_rate_get_lowest_plcp(priv, priv->beacon_ctx);
+       info = IEEE80211_SKB_CB(priv->beacon_skb);
+
+       /*
+        * Let's set up the rate at least somewhat correctly;
+        * it will currently not actually be used by the uCode,
+        * it uses the broadcast station's rate instead.
+        */
+       if (info->control.rates[0].idx < 0 ||
+           info->control.rates[0].flags & IEEE80211_TX_RC_MCS)
+               rate = 0;
+       else
+               rate = info->control.rates[0].idx;
+
        priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
                                              priv->hw_params.valid_tx_ant);
        rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
-       if ((rate >= IWL_FIRST_CCK_RATE) && (rate <= IWL_LAST_CCK_RATE))
+
+       /* In mac80211, rates for 5 GHz start at 0 */
+       if (info->band == IEEE80211_BAND_5GHZ)
+               rate += IWL_FIRST_OFDM_RATE;
+       else if (rate >= IWL_FIRST_CCK_RATE && rate <= IWL_LAST_CCK_RATE)
                rate_flags |= RATE_MCS_CCK_MSK;
-       tx_beacon_cmd->tx.rate_n_flags = iwl_hw_set_rate_n_flags(rate,
-                       rate_flags);
+
+       tx_beacon_cmd->tx.rate_n_flags =
+                       iwl_hw_set_rate_n_flags(rate, rate_flags);
 
        /* Submit command */
        cmd.len[0] = sizeof(*tx_beacon_cmd);
index 6d5584a..dcdf225 100644 (file)
@@ -304,6 +304,8 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
 int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
                        int tid);
 void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
+int iwl_update_bcast_station(struct iwl_priv *priv,
+                            struct iwl_rxon_context *ctx);
 int iwl_update_bcast_stations(struct iwl_priv *priv);
 void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
                           struct ieee80211_vif *vif,
index cde7253..7f16d12 100644 (file)
@@ -526,19 +526,6 @@ int iwl_full_rxon_required(struct iwl_priv *priv,
        return 0;
 }
 
-u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv,
-                           struct iwl_rxon_context *ctx)
-{
-       /*
-        * Assign the lowest rate -- should really get this from
-        * the beacon skb from mac80211.
-        */
-       if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK)
-               return IWL_RATE_1M_PLCP;
-       else
-               return IWL_RATE_6M_PLCP;
-}
-
 static void _iwl_set_rxon_ht(struct iwl_priv *priv,
                             struct iwl_ht_config *ht_conf,
                             struct iwl_rxon_context *ctx)
@@ -1717,6 +1704,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
        struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
        struct iwl_rxon_context *tmp;
+       enum nl80211_iftype newviftype = newtype;
        u32 interface_modes;
        int err;
 
@@ -1772,7 +1760,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
        /* success */
        iwl_teardown_interface(priv, vif, true);
-       vif->type = newtype;
+       vif->type = newviftype;
        vif->p2p = newp2p;
        err = iwl_setup_interface(priv, ctx);
        WARN_ON(err);
index adf9f9b..f881678 100644 (file)
@@ -409,13 +409,6 @@ void iwl_setup_watchdog(struct iwl_priv *priv);
 int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
 
 /*******************************************************************************
- * Rate
- ******************************************************************************/
-
-u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv,
-                           struct iwl_rxon_context *ctx);
-
-/*******************************************************************************
  * Scanning
  ******************************************************************************/
 void iwl_init_scan_params(struct iwl_priv *priv);
index 7cdb1ec..e3e5fb6 100644 (file)
@@ -113,7 +113,7 @@ const char *get_cmd_string(u8 cmd)
        }
 }
 
-#define HOST_COMPLETE_TIMEOUT (HZ / 2)
+#define HOST_COMPLETE_TIMEOUT (2 * HZ)
 
 static void iwl_generic_cmd_callback(struct iwl_priv *priv,
                                     struct iwl_device_cmd *cmd,
index 7328fbf..3b5844b 100644 (file)
@@ -383,7 +383,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
        struct iwl_pci_bus *bus;
-       u8 rev_id;
        u16 pci_cmd;
        int err;
 
@@ -440,8 +439,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                (unsigned long long) pci_resource_len(pdev, 0));
        pr_info("pci_resource_base = %p\n", bus->hw_base);
 
-       pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
-       pr_info("HW Revision ID = 0x%X\n", rev_id);
+       pr_info("HW Revision ID = 0x%X\n", pdev->revision);
 
        /* We disable the RETRY_TIMEOUT register (0x41) to keep
         * PCI Tx retries from interfering with C3 CPU state */
@@ -496,14 +494,11 @@ static void iwl_pci_down(void *bus)
 static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 {
        struct iwl_priv *priv = pci_get_drvdata(pdev);
-
-       /* This can happen if probe failed */
-       if (unlikely(!priv))
-               return;
+       void *bus_specific = priv->bus.bus_specific;
 
        iwl_remove(priv);
 
-       iwl_pci_down(IWL_BUS_GET_PCI_BUS(&priv->bus));
+       iwl_pci_down(bus_specific);
 }
 
 #ifdef CONFIG_PM
@@ -530,14 +525,7 @@ static int iwl_pci_resume(struct device *device)
        return iwl_resume(priv);
 }
 
-static const struct dev_pm_ops iwl_dev_pm_ops = {
-       .suspend = iwl_pci_suspend,
-       .resume = iwl_pci_resume,
-       .freeze = iwl_pci_suspend,
-       .thaw = iwl_pci_resume,
-       .poweroff = iwl_pci_suspend,
-       .restore = iwl_pci_resume,
-};
+static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume);
 
 #define IWL_PM_OPS     (&iwl_dev_pm_ops)
 
index fd8aee9..e72d227 100644 (file)
@@ -126,7 +126,7 @@ static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
 }
 
 static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta,
-                            struct iwl_tfd *tfd)
+                            struct iwl_tfd *tfd, enum dma_data_direction dma_dir)
 {
        int i;
        int num_tbs;
@@ -150,7 +150,7 @@ static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta,
        /* Unmap chunks, if any. */
        for (i = 1; i < num_tbs; i++)
                dma_unmap_single(priv->bus.dev, iwl_tfd_tb_get_addr(tfd, i),
-                               iwl_tfd_tb_get_len(tfd, i), DMA_TO_DEVICE);
+                               iwl_tfd_tb_get_len(tfd, i), dma_dir);
 }
 
 /**
@@ -166,7 +166,8 @@ void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
        struct iwl_tfd *tfd_tmp = txq->tfds;
        int index = txq->q.read_ptr;
 
-       iwlagn_unmap_tfd(priv, &txq->meta[index], &tfd_tmp[index]);
+       iwlagn_unmap_tfd(priv, &txq->meta[index], &tfd_tmp[index],
+                        DMA_TO_DEVICE);
 
        /* free SKB */
        if (txq->txb) {
@@ -309,9 +310,7 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv)
                i = get_cmd_index(q, q->read_ptr);
 
                if (txq->meta[i].flags & CMD_MAPPED) {
-                       dma_unmap_single(priv->bus.dev,
-                                        dma_unmap_addr(&txq->meta[i], mapping),
-                                        dma_unmap_len(&txq->meta[i], len),
+                       iwlagn_unmap_tfd(priv, &txq->meta[i], &txq->tfds[i],
                                         DMA_BIDIRECTIONAL);
                        txq->meta[i].flags = 0;
                }
@@ -534,12 +533,7 @@ out_free_arrays:
 void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
                        int slots_num, u32 txq_id)
 {
-       int actual_slots = slots_num;
-
-       if (txq_id == priv->cmd_queue)
-               actual_slots++;
-
-       memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
+       memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * slots_num);
 
        txq->need_update = 0;
 
@@ -699,10 +693,11 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
                if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
                        continue;
                phys_addr = dma_map_single(priv->bus.dev, (void *)cmd->data[i],
-                                          cmd->len[i], DMA_TO_DEVICE);
+                                          cmd->len[i], DMA_BIDIRECTIONAL);
                if (dma_mapping_error(priv->bus.dev, phys_addr)) {
                        iwlagn_unmap_tfd(priv, out_meta,
-                                        &txq->tfds[q->write_ptr]);
+                                        &txq->tfds[q->write_ptr],
+                                        DMA_BIDIRECTIONAL);
                        idx = -ENOMEM;
                        goto out;
                }
@@ -806,7 +801,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
        cmd = txq->cmd[cmd_index];
        meta = &txq->meta[cmd_index];
 
-       iwlagn_unmap_tfd(priv, meta, &txq->tfds[index]);
+       iwlagn_unmap_tfd(priv, meta, &txq->tfds[index], DMA_BIDIRECTIONAL);
 
        /* Input error checking is done when commands are added to queue. */
        if (meta->flags & CMD_WANT_SKB) {
index 5beb581..acc461a 100644 (file)
@@ -586,7 +586,7 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
        need_padding ^= ieee80211_has_a4(hdr->frame_control);
        need_padding ^= ieee80211_is_data_qos(hdr->frame_control) &&
                        (*ieee80211_get_qos_ctl(hdr) &
-                        IEEE80211_QOS_CONTROL_A_MSDU_PRESENT);
+                        IEEE80211_QOS_CTL_A_MSDU_PRESENT);
 
        if (need_padding) {
                memmove(skb->data + 2, skb->data, skb->len);
index 7e1fa96..031cd89 100644 (file)
@@ -1130,6 +1130,8 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
        for (i = 0; i < req->n_channels; i++)
                printk(KERN_DEBUG "hwsim hw_scan freq %d\n",
                        req->channels[i]->center_freq);
+       print_hex_dump(KERN_DEBUG, "scan IEs: ", DUMP_PREFIX_OFFSET,
+                       16, 1, req->ie, req->ie_len, 1);
 
        ieee80211_queue_delayed_work(hw, &hsd->w, 2 * HZ);
 
index d85a0a6..49b9c13 100644 (file)
@@ -779,6 +779,8 @@ static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd,
        case HostCmd_ACT_GEN_SET:
                if (enable)
                        ibss_coal->enable = cpu_to_le16(*enable);
+               else
+                       ibss_coal->enable = 0;
                break;
 
                /* In other case.. Nothing to do */
index ad64c87..6804239 100644 (file)
@@ -183,30 +183,32 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
  */
 static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv,
                                       struct host_cmd_ds_command *resp,
-                                      u32 *ul_temp)
+                                      u32 *data_buf)
 {
        struct host_cmd_ds_802_11_snmp_mib *smib = &resp->params.smib;
        u16 oid = le16_to_cpu(smib->oid);
        u16 query_type = le16_to_cpu(smib->query_type);
+       u32 ul_temp;
 
        dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x,"
                        " query_type = %#x, buf size = %#x\n",
                        oid, query_type, le16_to_cpu(smib->buf_size));
        if (query_type == HostCmd_ACT_GEN_GET) {
-               if (ul_temp)
-                       *ul_temp = le16_to_cpu(*((__le16 *) (smib->value)));
+               ul_temp = le16_to_cpu(*((__le16 *) (smib->value)));
+               if (data_buf)
+                       *data_buf = ul_temp;
                switch (oid) {
                case FRAG_THRESH_I:
                        dev_dbg(priv->adapter->dev,
-                               "info: SNMP_RESP: FragThsd =%u\n", *ul_temp);
+                               "info: SNMP_RESP: FragThsd =%u\n", ul_temp);
                        break;
                case RTS_THRESH_I:
                        dev_dbg(priv->adapter->dev,
-                               "info: SNMP_RESP: RTSThsd =%u\n", *ul_temp);
+                               "info: SNMP_RESP: RTSThsd =%u\n", ul_temp);
                        break;
                case SHORT_RETRY_LIM_I:
                        dev_dbg(priv->adapter->dev,
-                               "info: SNMP_RESP: TxRetryCount=%u\n", *ul_temp);
+                               "info: SNMP_RESP: TxRetryCount=%u\n", ul_temp);
                        break;
                default:
                        break;
@@ -622,22 +624,23 @@ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv,
  */
 static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv,
                                         struct host_cmd_ds_command *resp,
-                                        u16 *new_channel)
+                                        u16 *data_buf)
 {
        struct host_cmd_ds_802_11_rf_channel *rf_channel =
                &resp->params.rf_channel;
+       u16 new_channel = le16_to_cpu(rf_channel->current_channel);
 
-       if (new_channel)
-               *new_channel = le16_to_cpu(rf_channel->current_channel);
-
-       if (priv->curr_bss_params.bss_descriptor.channel != *new_channel) {
+       if (priv->curr_bss_params.bss_descriptor.channel != new_channel) {
                dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n",
                       priv->curr_bss_params.bss_descriptor.channel,
-                      *new_channel);
+                      new_channel);
                /* Update the channel again */
-               priv->curr_bss_params.bss_descriptor.channel = *new_channel;
+               priv->curr_bss_params.bss_descriptor.channel = new_channel;
        }
 
+       if (data_buf)
+               *data_buf = new_channel;
+
        return 0;
 }
 
index 167d458..5900474 100644 (file)
@@ -54,7 +54,7 @@
  * @QID_RX: RX queue
  * @QID_OTHER: None of the above (don't use, only present for completeness)
  * @QID_BEACON: Beacon queue (value unspecified, don't send it to device)
- * @QID_ATIM: Atim queue (value unspeficied, don't send it to device)
+ * @QID_ATIM: Atim queue (value unspecified, don't send it to device)
  */
 enum data_queue_qid {
        QID_AC_VO = 0,
index 5aee8b2..45e1476 100644 (file)
@@ -21,6 +21,17 @@ config RTL8192SE
 
        If you choose to build it as a module, it will be called rtl8192se
 
+config RTL8192DE
+       tristate "Realtek RTL8192DE/RTL8188DE PCIe Wireless Network Adapter"
+       depends on MAC80211 && EXPERIMENTAL
+       select FW_LOADER
+       select RTLWIFI
+       ---help---
+       This is the driver for Realtek RTL8192DE/RTL8188DE 802.11n PCIe
+       wireless network adapters.
+
+       If you choose to build it as a module, it will be called rtl8192de
+
 config RTL8192CU
        tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter"
        depends on MAC80211 && USB && EXPERIMENTAL
@@ -35,10 +46,10 @@ config RTL8192CU
 
 config RTLWIFI
        tristate
-       depends on RTL8192CE || RTL8192CU || RTL8192SE
+       depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE
        default m
 
 config RTL8192C_COMMON
        tristate
-       depends on RTL8192CE || RTL8192CU || RTL8192SE
+       depends on RTL8192CE || RTL8192CU
        default m
index 7acce83..97935c5 100644 (file)
@@ -23,5 +23,6 @@ obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/
 obj-$(CONFIG_RTL8192CE)                += rtl8192ce/
 obj-$(CONFIG_RTL8192CU)                += rtl8192cu/
 obj-$(CONFIG_RTL8192SE)                += rtl8192se/
+obj-$(CONFIG_RTL8192DE)                += rtl8192de/
 
 ccflags-y += -D__CHECK_ENDIAN__
index ad39af4..532c7d3 100644 (file)
 #include "efuse.h"
 
 static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {
-       INTEL_VENDOR_ID,
-       ATI_VENDOR_ID,
-       AMD_VENDOR_ID,
-       SIS_VENDOR_ID
+       PCI_VENDOR_ID_INTEL,
+       PCI_VENDOR_ID_ATI,
+       PCI_VENDOR_ID_AMD,
+       PCI_VENDOR_ID_SI
 };
 
 static const u8 ac_to_hwq[] = {
@@ -390,7 +390,7 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev,
        u8 linkctrl_reg;
 
        /*Link Control Register */
-       pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+       pos = pci_pcie_cap(pdev);
        pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg);
        pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg;
 
@@ -1615,6 +1615,16 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
        pci_read_config_byte(pdev, 0x8, &revisionid);
        pci_read_config_word(pdev, 0x3C, &irqline);
 
+       /* PCI ID 0x10ec:0x8192 occurs for both RTL8192E, which uses
+        * r8192e_pci, and RTL8192SE, which uses this driver. If the
+        * revision ID is RTL_PCI_REVISION_ID_8192PCIE (0x01), then
+        * the correct driver is r8192e_pci, thus this routine should
+        * return false.
+        */
+       if (deviceid == RTL_PCI_8192SE_DID &&
+           revisionid == RTL_PCI_REVISION_ID_8192PCIE)
+               return false;
+
        if (deviceid == RTL_PCI_8192_DID ||
            deviceid == RTL_PCI_0044_DID ||
            deviceid == RTL_PCI_0047_DID ||
@@ -1847,7 +1857,8 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
        pci_write_config_byte(pdev, 0x04, 0x07);
 
        /* find adapter */
-       _rtl_pci_find_adapter(pdev, hw);
+       if (!_rtl_pci_find_adapter(pdev, hw))
+               goto fail3;
 
        /* Init IO handler */
        _rtl_pci_io_handler_init(&pdev->dev, hw);
index 671b1f5..a50e551 100644 (file)
        .subdevice = PCI_ANY_ID,\
        .driver_data = (kernel_ulong_t)&(cfg)
 
-#define INTEL_VENDOR_ID                                0x8086
-#define SIS_VENDOR_ID                          0x1039
-#define ATI_VENDOR_ID                          0x1002
-#define ATI_DEVICE_ID                          0x7914
-#define AMD_VENDOR_ID                          0x1022
-
 #define PCI_MAX_BRIDGE_NUMBER                  255
 #define PCI_MAX_DEVICES                                32
 #define PCI_MAX_FUNCTION                       8
 #define PCI_CONF_ADDRESS       0x0CF8  /*PCI Configuration Space Address */
 #define PCI_CONF_DATA          0x0CFC  /*PCI Configuration Space Data */
 
-#define PCI_CLASS_BRIDGE_DEV           0x06
-#define PCI_SUBCLASS_BR_PCI_TO_PCI     0x04
-#define PCI_CAPABILITY_ID_PCI_EXPRESS  0x10
-#define PCI_CAP_ID_EXP                 0x10
-
 #define U1DONTCARE                     0xFF
 #define U2DONTCARE                     0xFFFF
 #define U4DONTCARE                     0xFFFFFFFF
index 598cecc..72a3d54 100644 (file)
 #define EPROM_CMD_CONFIG                       0x3
 #define EPROM_CMD_LOAD                         1
 
+#define HWSET_MAX_SIZE                         128
 #define        HWSET_MAX_SIZE_92S                      HWSET_MAX_SIZE
+#define EFUSE_MAX_SECTION                      16
 
 #define        WL_HWPDN_EN                             BIT(0)
 
index bee7c14..092e342 100644 (file)
@@ -53,6 +53,8 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
 static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
+       const struct firmware *firmware;
+       int err;
 
        rtlpriv->dm.dm_initialgain_enable = 1;
        rtlpriv->dm.dm_flag = 0;
@@ -64,6 +66,24 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
                         ("Can't alloc buffer for fw.\n"));
                return 1;
        }
+       /* request fw */
+       err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
+                       rtlpriv->io.dev);
+       if (err) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("Failed to request firmware!\n"));
+               return 1;
+       }
+       if (firmware->size > 0x4000) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("Firmware is too big!\n"));
+               release_firmware(firmware);
+               return 1;
+       }
+       memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
+       rtlpriv->rtlhal.fwsize = firmware->size;
+       release_firmware(firmware);
+
        return 0;
 }
 
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/Makefile b/drivers/net/wireless/rtlwifi/rtl8192de/Makefile
new file mode 100644 (file)
index 0000000..e3213c8
--- /dev/null
@@ -0,0 +1,14 @@
+rtl8192de-objs :=              \
+               dm.o            \
+               fw.o            \
+               hw.o            \
+               led.o           \
+               phy.o           \
+               rf.o            \
+               sw.o            \
+               table.o         \
+               trx.o
+
+obj-$(CONFIG_RTL8192DE) += rtl8192de.o
+
+ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/def.h b/drivers/net/wireless/rtlwifi/rtl8192de/def.h
new file mode 100644 (file)
index 0000000..f0f5f9b
--- /dev/null
@@ -0,0 +1,269 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92D_DEF_H__
+#define __RTL92D_DEF_H__
+
+/* Min Spacing related settings. */
+#define        MAX_MSS_DENSITY_2T                              0x13
+#define        MAX_MSS_DENSITY_1T                              0x0A
+
+#define RF6052_MAX_TX_PWR                              0x3F
+#define RF6052_MAX_REG                                 0x3F
+#define RF6052_MAX_PATH                                        2
+
+#define HAL_RETRY_LIMIT_INFRA                          48
+#define HAL_RETRY_LIMIT_AP_ADHOC                       7
+
+#define        PHY_RSSI_SLID_WIN_MAX                           100
+#define        PHY_LINKQUALITY_SLID_WIN_MAX                    20
+#define        PHY_BEACON_RSSI_SLID_WIN_MAX                    10
+
+#define RESET_DELAY_8185                               20
+
+#define RT_IBSS_INT_MASKS      (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
+#define RT_AC_INT_MASKS                (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
+
+#define NUM_OF_FIRMWARE_QUEUE                          10
+#define NUM_OF_PAGES_IN_FW                             0x100
+#define NUM_OF_PAGE_IN_FW_QUEUE_BK                     0x07
+#define NUM_OF_PAGE_IN_FW_QUEUE_BE                     0x07
+#define NUM_OF_PAGE_IN_FW_QUEUE_VI                     0x07
+#define NUM_OF_PAGE_IN_FW_QUEUE_VO                     0x07
+#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA                   0x0
+#define NUM_OF_PAGE_IN_FW_QUEUE_CMD                    0x0
+#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT                   0x02
+#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH                   0x02
+#define NUM_OF_PAGE_IN_FW_QUEUE_BCN                    0x2
+#define NUM_OF_PAGE_IN_FW_QUEUE_PUB                    0xA1
+
+#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM                 0x026
+#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM                 0x048
+#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM                 0x048
+#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM                 0x026
+#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM                        0x00
+
+#define MAX_LINES_HWCONFIG_TXT                         1000
+#define MAX_BYTES_LINE_HWCONFIG_TXT                    256
+
+#define SW_THREE_WIRE                                  0
+#define HW_THREE_WIRE                                  2
+
+#define BT_DEMO_BOARD                                  0
+#define BT_QA_BOARD                                    1
+#define BT_FPGA                                                2
+
+#define RX_SMOOTH_FACTOR                               20
+
+#define HAL_PRIME_CHNL_OFFSET_DONT_CARE                        0
+#define HAL_PRIME_CHNL_OFFSET_LOWER                    1
+#define HAL_PRIME_CHNL_OFFSET_UPPER                    2
+
+#define MAX_H2C_QUEUE_NUM                              10
+
+#define RX_MPDU_QUEUE                                  0
+#define RX_CMD_QUEUE                                   1
+#define RX_MAX_QUEUE                                   2
+
+#define        C2H_RX_CMD_HDR_LEN                              8
+#define        GET_C2H_CMD_CMD_LEN(__prxhdr)                   \
+       LE_BITS_TO_4BYTE((__prxhdr), 0, 16)
+#define        GET_C2H_CMD_ELEMENT_ID(__prxhdr)                \
+       LE_BITS_TO_4BYTE((__prxhdr), 16, 8)
+#define        GET_C2H_CMD_CMD_SEQ(__prxhdr)                   \
+       LE_BITS_TO_4BYTE((__prxhdr), 24, 7)
+#define        GET_C2H_CMD_CONTINUE(__prxhdr)                  \
+       LE_BITS_TO_4BYTE((__prxhdr), 31, 1)
+#define        GET_C2H_CMD_CONTENT(__prxhdr)                   \
+       ((u8 *)(__prxhdr) + C2H_RX_CMD_HDR_LEN)
+
+#define        GET_C2H_CMD_FEEDBACK_ELEMENT_ID(__pcmdfbhdr)    \
+       LE_BITS_TO_4BYTE((__pcmdfbhdr), 0, 8)
+#define        GET_C2H_CMD_FEEDBACK_CCX_LEN(__pcmdfbhdr)       \
+       LE_BITS_TO_4BYTE((__pcmdfbhdr), 8, 8)
+#define        GET_C2H_CMD_FEEDBACK_CCX_CMD_CNT(__pcmdfbhdr)   \
+       LE_BITS_TO_4BYTE((__pcmdfbhdr), 16, 16)
+#define        GET_C2H_CMD_FEEDBACK_CCX_MAC_ID(__pcmdfbhdr)    \
+       LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 0, 5)
+#define        GET_C2H_CMD_FEEDBACK_CCX_VALID(__pcmdfbhdr)     \
+       LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 7, 1)
+#define        GET_C2H_CMD_FEEDBACK_CCX_RETRY_CNT(__pcmdfbhdr) \
+       LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 8, 5)
+#define        GET_C2H_CMD_FEEDBACK_CCX_TOK(__pcmdfbhdr)       \
+       LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 15, 1)
+#define        GET_C2H_CMD_FEEDBACK_CCX_QSEL(__pcmdfbhdr)      \
+       LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 16, 4)
+#define        GET_C2H_CMD_FEEDBACK_CCX_SEQ(__pcmdfbhdr)       \
+       LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12)
+
+/*
+ * 92D chip ver:
+ * BIT8: IS 92D
+ * BIT9: single phy
+ * BIT10: C-cut
+ * BIT11: D-cut
+ */
+
+/* Chip specific */
+#define CHIP_92C                       BIT(0)
+#define CHIP_92C_1T2R                  BIT(1)
+#define CHIP_8723                      BIT(2) /* RTL8723 With BT feature */
+#define CHIP_8723_DRV_REV              BIT(3) /* RTL8723 Driver Revised */
+#define NORMAL_CHIP                    BIT(4)
+#define CHIP_VENDOR_UMC                        BIT(5)
+#define CHIP_VENDOR_UMC_B_CUT          BIT(6) /* Chip version for ECO */
+
+/* for 92D */
+#define CHIP_92D                       BIT(8)
+#define CHIP_92D_SINGLEPHY             BIT(9)
+#define CHIP_92D_C_CUT                 BIT(10)
+#define CHIP_92D_D_CUT                 BIT(11)
+
+enum version_8192d {
+       VERSION_TEST_CHIP_88C = 0x00,
+       VERSION_TEST_CHIP_92C = 0x01,
+       VERSION_NORMAL_TSMC_CHIP_88C = 0x10,
+       VERSION_NORMAL_TSMC_CHIP_92C = 0x11,
+       VERSION_NORMAL_TSMC_CHIP_92C_1T2R = 0x13,
+       VERSION_NORMAL_UMC_CHIP_88C_A_CUT = 0x30,
+       VERSION_NORMAL_UMC_CHIP_92C_A_CUT = 0x31,
+       VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT = 0x33,
+       VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT = 0x34,
+       VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT = 0x3c,
+       VERSION_NORMAL_UMC_CHIP_88C_B_CUT = 0x70,
+       VERSION_NORMAL_UMC_CHIP_92C_B_CUT = 0x71,
+       VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT = 0x73,
+       VERSION_TEST_CHIP_92D_SINGLEPHY = 0x300,
+       VERSION_TEST_CHIP_92D_DUALPHY = 0x100,
+       VERSION_NORMAL_CHIP_92D_SINGLEPHY = 0x310,
+       VERSION_NORMAL_CHIP_92D_DUALPHY = 0x110,
+       VERSION_NORMAL_CHIP_92D_C_CUT_SINGLEPHY = 0x710,
+       VERSION_NORMAL_CHIP_92D_C_CUT_DUALPHY = 0x510,
+       VERSION_NORMAL_CHIP_92D_D_CUT_SINGLEPHY = 0xB10,
+       VERSION_NORMAL_CHIP_92D_D_CUT_DUALPHY = 0x910,
+};
+
+#define IS_92D_SINGLEPHY(version)              \
+       ((version & CHIP_92D_SINGLEPHY) ? true : false)
+#define IS_92D_C_CUT(version)                  \
+       ((version & CHIP_92D_C_CUT) ? true : false)
+#define IS_92D_D_CUT(version)                  \
+       ((version & CHIP_92D_D_CUT) ? true : false)
+
+enum rf_optype {
+       RF_OP_BY_SW_3WIRE = 0,
+       RF_OP_BY_FW,
+       RF_OP_MAX
+};
+
+enum rtl_desc_qsel {
+       QSLT_BK = 0x2,
+       QSLT_BE = 0x0,
+       QSLT_VI = 0x5,
+       QSLT_VO = 0x7,
+       QSLT_BEACON = 0x10,
+       QSLT_HIGH = 0x11,
+       QSLT_MGNT = 0x12,
+       QSLT_CMD = 0x13,
+};
+
+enum rtl_desc92d_rate {
+       DESC92D_RATE1M = 0x00,
+       DESC92D_RATE2M = 0x01,
+       DESC92D_RATE5_5M = 0x02,
+       DESC92D_RATE11M = 0x03,
+
+       DESC92D_RATE6M = 0x04,
+       DESC92D_RATE9M = 0x05,
+       DESC92D_RATE12M = 0x06,
+       DESC92D_RATE18M = 0x07,
+       DESC92D_RATE24M = 0x08,
+       DESC92D_RATE36M = 0x09,
+       DESC92D_RATE48M = 0x0a,
+       DESC92D_RATE54M = 0x0b,
+
+       DESC92D_RATEMCS0 = 0x0c,
+       DESC92D_RATEMCS1 = 0x0d,
+       DESC92D_RATEMCS2 = 0x0e,
+       DESC92D_RATEMCS3 = 0x0f,
+       DESC92D_RATEMCS4 = 0x10,
+       DESC92D_RATEMCS5 = 0x11,
+       DESC92D_RATEMCS6 = 0x12,
+       DESC92D_RATEMCS7 = 0x13,
+       DESC92D_RATEMCS8 = 0x14,
+       DESC92D_RATEMCS9 = 0x15,
+       DESC92D_RATEMCS10 = 0x16,
+       DESC92D_RATEMCS11 = 0x17,
+       DESC92D_RATEMCS12 = 0x18,
+       DESC92D_RATEMCS13 = 0x19,
+       DESC92D_RATEMCS14 = 0x1a,
+       DESC92D_RATEMCS15 = 0x1b,
+       DESC92D_RATEMCS15_SG = 0x1c,
+       DESC92D_RATEMCS32 = 0x20,
+};
+
+enum channel_plan {
+       CHPL_FCC        = 0,
+       CHPL_IC         = 1,
+       CHPL_ETSI       = 2,
+       CHPL_SPAIN      = 3,
+       CHPL_FRANCE     = 4,
+       CHPL_MKK        = 5,
+       CHPL_MKK1       = 6,
+       CHPL_ISRAEL     = 7,
+       CHPL_TELEC      = 8,
+       CHPL_GLOBAL     = 9,
+       CHPL_WORLD      = 10,
+};
+
+struct phy_sts_cck_8192d {
+       u8 adc_pwdb_X[4];
+       u8 sq_rpt;
+       u8 cck_agc_rpt;
+};
+
+struct h2c_cmd_8192c {
+       u8 element_id;
+       u32 cmd_len;
+       u8 *p_cmdbuffer;
+};
+
+struct txpower_info {
+       u8 cck_index[RF6052_MAX_PATH][CHANNEL_GROUP_MAX];
+       u8 ht40_1sindex[RF6052_MAX_PATH][CHANNEL_GROUP_MAX];
+       u8 ht40_2sindexdiff[RF6052_MAX_PATH][CHANNEL_GROUP_MAX];
+       u8 ht20indexdiff[RF6052_MAX_PATH][CHANNEL_GROUP_MAX];
+       u8 ofdmindexdiff[RF6052_MAX_PATH][CHANNEL_GROUP_MAX];
+       u8 ht40maxoffset[RF6052_MAX_PATH][CHANNEL_GROUP_MAX];
+       u8 ht20maxoffset[RF6052_MAX_PATH][CHANNEL_GROUP_MAX];
+       u8 tssi_a[3];           /* 5GL/5GM/5GH */
+       u8 tssi_b[3];
+};
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
new file mode 100644 (file)
index 0000000..3cd0736
--- /dev/null
@@ -0,0 +1,1355 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "fw.h"
+
+#define UNDEC_SM_PWDB  entry_min_undecoratedsmoothed_pwdb
+
+struct dig_t de_digtable;
+
+static const u32 ofdmswing_table[OFDM_TABLE_SIZE_92D] = {
+       0x7f8001fe,             /* 0, +6.0dB */
+       0x788001e2,             /* 1, +5.5dB */
+       0x71c001c7,             /* 2, +5.0dB */
+       0x6b8001ae,             /* 3, +4.5dB */
+       0x65400195,             /* 4, +4.0dB */
+       0x5fc0017f,             /* 5, +3.5dB */
+       0x5a400169,             /* 6, +3.0dB */
+       0x55400155,             /* 7, +2.5dB */
+       0x50800142,             /* 8, +2.0dB */
+       0x4c000130,             /* 9, +1.5dB */
+       0x47c0011f,             /* 10, +1.0dB */
+       0x43c0010f,             /* 11, +0.5dB */
+       0x40000100,             /* 12, +0dB */
+       0x3c8000f2,             /* 13, -0.5dB */
+       0x390000e4,             /* 14, -1.0dB */
+       0x35c000d7,             /* 15, -1.5dB */
+       0x32c000cb,             /* 16, -2.0dB */
+       0x300000c0,             /* 17, -2.5dB */
+       0x2d4000b5,             /* 18, -3.0dB */
+       0x2ac000ab,             /* 19, -3.5dB */
+       0x288000a2,             /* 20, -4.0dB */
+       0x26000098,             /* 21, -4.5dB */
+       0x24000090,             /* 22, -5.0dB */
+       0x22000088,             /* 23, -5.5dB */
+       0x20000080,             /* 24, -6.0dB */
+       0x1e400079,             /* 25, -6.5dB */
+       0x1c800072,             /* 26, -7.0dB */
+       0x1b00006c,             /* 27. -7.5dB */
+       0x19800066,             /* 28, -8.0dB */
+       0x18000060,             /* 29, -8.5dB */
+       0x16c0005b,             /* 30, -9.0dB */
+       0x15800056,             /* 31, -9.5dB */
+       0x14400051,             /* 32, -10.0dB */
+       0x1300004c,             /* 33, -10.5dB */
+       0x12000048,             /* 34, -11.0dB */
+       0x11000044,             /* 35, -11.5dB */
+       0x10000040,             /* 36, -12.0dB */
+       0x0f00003c,             /* 37, -12.5dB */
+       0x0e400039,             /* 38, -13.0dB */
+       0x0d800036,             /* 39, -13.5dB */
+       0x0cc00033,             /* 40, -14.0dB */
+       0x0c000030,             /* 41, -14.5dB */
+       0x0b40002d,             /* 42, -15.0dB */
+};
+
+static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
+       {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},    /* 0, +0dB */
+       {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},    /* 1, -0.5dB */
+       {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},    /* 2, -1.0dB */
+       {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},    /* 3, -1.5dB */
+       {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},    /* 4, -2.0dB */
+       {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},    /* 5, -2.5dB */
+       {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},    /* 6, -3.0dB */
+       {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},    /* 7, -3.5dB */
+       {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},    /* 8, -4.0dB */
+       {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},    /* 9, -4.5dB */
+       {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},    /* 10, -5.0dB */
+       {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},    /* 11, -5.5dB */
+       {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},    /* 12, -6.0dB */
+       {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},    /* 13, -6.5dB */
+       {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},    /* 14, -7.0dB */
+       {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},    /* 15, -7.5dB */
+       {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},    /* 16, -8.0dB */
+       {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},    /* 17, -8.5dB */
+       {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},    /* 18, -9.0dB */
+       {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},    /* 19, -9.5dB */
+       {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},    /* 20, -10.0dB */
+       {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},    /* 21, -10.5dB */
+       {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},    /* 22, -11.0dB */
+       {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},    /* 23, -11.5dB */
+       {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},    /* 24, -12.0dB */
+       {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},    /* 25, -12.5dB */
+       {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},    /* 26, -13.0dB */
+       {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},    /* 27, -13.5dB */
+       {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},    /* 28, -14.0dB */
+       {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},    /* 29, -14.5dB */
+       {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},    /* 30, -15.0dB */
+       {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},    /* 31, -15.5dB */
+       {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}     /* 32, -16.0dB */
+};
+
+static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
+       {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},    /* 0, +0dB */
+       {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},    /* 1, -0.5dB */
+       {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},    /* 2, -1.0dB */
+       {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},    /* 3, -1.5dB */
+       {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},    /* 4, -2.0dB */
+       {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},    /* 5, -2.5dB */
+       {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},    /* 6, -3.0dB */
+       {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},    /* 7, -3.5dB */
+       {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},    /* 8, -4.0dB */
+       {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},    /* 9, -4.5dB */
+       {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},    /* 10, -5.0dB */
+       {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},    /* 11, -5.5dB */
+       {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},    /* 12, -6.0dB */
+       {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},    /* 13, -6.5dB */
+       {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},    /* 14, -7.0dB */
+       {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},    /* 15, -7.5dB */
+       {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},    /* 16, -8.0dB */
+       {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},    /* 17, -8.5dB */
+       {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},    /* 18, -9.0dB */
+       {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},    /* 19, -9.5dB */
+       {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},    /* 20, -10.0dB */
+       {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},    /* 21, -10.5dB */
+       {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},    /* 22, -11.0dB */
+       {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},    /* 23, -11.5dB */
+       {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},    /* 24, -12.0dB */
+       {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},    /* 25, -12.5dB */
+       {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},    /* 26, -13.0dB */
+       {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},    /* 27, -13.5dB */
+       {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},    /* 28, -14.0dB */
+       {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},    /* 29, -14.5dB */
+       {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},    /* 30, -15.0dB */
+       {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},    /* 31, -15.5dB */
+       {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}     /* 32, -16.0dB */
+};
+
+static void rtl92d_dm_diginit(struct ieee80211_hw *hw)
+{
+       de_digtable.dig_enable_flag = true;
+       de_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
+       de_digtable.cur_igvalue = 0x20;
+       de_digtable.pre_igvalue = 0x0;
+       de_digtable.cursta_connectctate = DIG_STA_DISCONNECT;
+       de_digtable.presta_connectstate = DIG_STA_DISCONNECT;
+       de_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT;
+       de_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW;
+       de_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH;
+       de_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
+       de_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
+       de_digtable.rx_gain_range_max = DM_DIG_FA_UPPER;
+       de_digtable.rx_gain_range_min = DM_DIG_FA_LOWER;
+       de_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT;
+       de_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX;
+       de_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN;
+       de_digtable.pre_cck_pd_state = CCK_PD_STAGE_LOWRSSI;
+       de_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX;
+       de_digtable.large_fa_hit = 0;
+       de_digtable.recover_cnt = 0;
+       de_digtable.forbidden_igi = DM_DIG_FA_LOWER;
+}
+
+static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
+{
+       u32 ret_value;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
+       unsigned long flag = 0;
+
+       /* hold ofdm counter */
+       rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 1); /* hold page C counter */
+       rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 1); /*hold page D counter */
+
+       ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, BMASKDWORD);
+       falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff);
+       falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16);
+       ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, BMASKDWORD);
+       falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
+       ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, BMASKDWORD);
+       falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
+       falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
+       ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, BMASKDWORD);
+       falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
+       falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
+                                     falsealm_cnt->cnt_rate_illegal +
+                                     falsealm_cnt->cnt_crc8_fail +
+                                     falsealm_cnt->cnt_mcs_fail +
+                                     falsealm_cnt->cnt_fast_fsync_fail +
+                                     falsealm_cnt->cnt_sb_search_fail;
+
+       if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) {
+               /* hold cck counter */
+               rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
+               ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, BMASKBYTE0);
+               falsealm_cnt->cnt_cck_fail = ret_value;
+               ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, BMASKBYTE3);
+               falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
+               rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
+       } else {
+               falsealm_cnt->cnt_cck_fail = 0;
+       }
+
+       /* reset false alarm counter registers */
+       falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail +
+                               falsealm_cnt->cnt_sb_search_fail +
+                               falsealm_cnt->cnt_parity_fail +
+                               falsealm_cnt->cnt_rate_illegal +
+                               falsealm_cnt->cnt_crc8_fail +
+                               falsealm_cnt->cnt_mcs_fail +
+                               falsealm_cnt->cnt_cck_fail;
+
+       rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
+       /* update ofdm counter */
+       rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
+       /* update page C counter */
+       rtl_set_bbreg(hw, ROFDM0_LSTF, BIT(31), 0);
+       /* update page D counter */
+       rtl_set_bbreg(hw, ROFDM1_LSTF, BIT(31), 0);
+       if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) {
+               /* reset cck counter */
+               rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
+               rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
+               /* enable cck counter */
+               rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
+               rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
+       }
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Cnt_Fast_Fsync_fail = %x, "
+                "Cnt_SB_Search_fail = %x\n",
+                falsealm_cnt->cnt_fast_fsync_fail,
+                falsealm_cnt->cnt_sb_search_fail));
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Cnt_Parity_Fail = %x, "
+                "Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, "
+                "Cnt_Mcs_fail = %x\n",
+                falsealm_cnt->cnt_parity_fail,
+                falsealm_cnt->cnt_rate_illegal,
+                falsealm_cnt->cnt_crc8_fail,
+                falsealm_cnt->cnt_mcs_fail));
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+                ("Cnt_Ofdm_fail = %x, " "Cnt_Cck_fail = %x, "
+                "Cnt_all = %x\n",
+                falsealm_cnt->cnt_ofdm_fail,
+                falsealm_cnt->cnt_cck_fail,
+                falsealm_cnt->cnt_all));
+}
+
+static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtlpriv);
+
+       /* Determine the minimum RSSI  */
+       if ((mac->link_state < MAC80211_LINKED) &&
+           (rtlpriv->dm.UNDEC_SM_PWDB == 0)) {
+               de_digtable.min_undecorated_pwdb_for_dm = 0;
+               RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
+                        ("Not connected to any\n"));
+       }
+       if (mac->link_state >= MAC80211_LINKED) {
+               if (mac->opmode == NL80211_IFTYPE_AP ||
+                   mac->opmode == NL80211_IFTYPE_ADHOC) {
+                       de_digtable.min_undecorated_pwdb_for_dm =
+                           rtlpriv->dm.UNDEC_SM_PWDB;
+                       RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
+                                ("AP Client PWDB = 0x%lx\n",
+                                 rtlpriv->dm.UNDEC_SM_PWDB));
+               } else {
+                       de_digtable.min_undecorated_pwdb_for_dm =
+                           rtlpriv->dm.undecorated_smoothed_pwdb;
+                       RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
+                                ("STA Default Port PWDB = 0x%x\n",
+                                 de_digtable.min_undecorated_pwdb_for_dm));
+               }
+       } else {
+               de_digtable.min_undecorated_pwdb_for_dm =
+                   rtlpriv->dm.UNDEC_SM_PWDB;
+               RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
+                        ("AP Ext Port or disconnet PWDB = 0x%x\n",
+                         de_digtable.min_undecorated_pwdb_for_dm));
+       }
+
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n",
+                       de_digtable.min_undecorated_pwdb_for_dm));
+}
+
+static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       unsigned long flag = 0;
+
+       if (de_digtable.cursta_connectctate == DIG_STA_CONNECT) {
+               if (de_digtable.pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
+                       if (de_digtable.min_undecorated_pwdb_for_dm <= 25)
+                               de_digtable.cur_cck_pd_state =
+                                                        CCK_PD_STAGE_LOWRSSI;
+                       else
+                               de_digtable.cur_cck_pd_state =
+                                                        CCK_PD_STAGE_HIGHRSSI;
+               } else {
+                       if (de_digtable.min_undecorated_pwdb_for_dm <= 20)
+                               de_digtable.cur_cck_pd_state =
+                                                        CCK_PD_STAGE_LOWRSSI;
+                       else
+                               de_digtable.cur_cck_pd_state =
+                                                        CCK_PD_STAGE_HIGHRSSI;
+               }
+       } else {
+               de_digtable.cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI;
+       }
+       if (de_digtable.pre_cck_pd_state != de_digtable.cur_cck_pd_state) {
+               if (de_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
+                       rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
+                       rtl_set_bbreg(hw, RCCK0_CCA, BMASKBYTE2, 0x83);
+                       rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
+               } else {
+                       rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
+                       rtl_set_bbreg(hw, RCCK0_CCA, BMASKBYTE2, 0xcd);
+                       rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
+               }
+               de_digtable.pre_cck_pd_state = de_digtable.cur_cck_pd_state;
+       }
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CurSTAConnectState=%s\n",
+                (de_digtable.cursta_connectctate == DIG_STA_CONNECT ?
+                "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT")));
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CCKPDStage=%s\n",
+                (de_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ?
+                "Low RSSI " : "High RSSI ")));
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("is92d single phy =%x\n",
+                IS_92D_SINGLEPHY(rtlpriv->rtlhal.version)));
+
+}
+
+void rtl92d_dm_write_dig(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("cur_igvalue = 0x%x, "
+                "pre_igvalue = 0x%x, backoff_val = %d\n",
+                de_digtable.cur_igvalue, de_digtable.pre_igvalue,
+                de_digtable.backoff_val));
+       if (de_digtable.dig_enable_flag == false) {
+               RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("DIG is disabled\n"));
+               de_digtable.pre_igvalue = 0x17;
+               return;
+       }
+       if (de_digtable.pre_igvalue != de_digtable.cur_igvalue) {
+               rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
+                             de_digtable.cur_igvalue);
+               rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
+                             de_digtable.cur_igvalue);
+               de_digtable.pre_igvalue = de_digtable.cur_igvalue;
+       }
+}
+
+static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv)
+{
+       if ((rtlpriv->mac80211.link_state >= MAC80211_LINKED) &&
+           (rtlpriv->mac80211.vendor == PEER_CISCO)) {
+               RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+                        ("IOT_PEER = CISCO\n"));
+               if (de_digtable.last_min_undecorated_pwdb_for_dm >= 50
+                   && de_digtable.min_undecorated_pwdb_for_dm < 50) {
+                       rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00);
+                       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+                                ("Early Mode Off\n"));
+               } else if (de_digtable.last_min_undecorated_pwdb_for_dm <= 55 &&
+                          de_digtable.min_undecorated_pwdb_for_dm > 55) {
+                       rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f);
+                       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+                                ("Early Mode On\n"));
+               }
+       } else if (!(rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL) & 0xf)) {
+               rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f);
+               RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Early Mode On\n"));
+       }
+}
+
+static void rtl92d_dm_dig(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 value_igi = de_digtable.cur_igvalue;
+       struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
+
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("==>\n"));
+       if (rtlpriv->rtlhal.earlymode_enable) {
+               rtl92d_early_mode_enabled(rtlpriv);
+               de_digtable.last_min_undecorated_pwdb_for_dm =
+                                de_digtable.min_undecorated_pwdb_for_dm;
+       }
+       if (rtlpriv->dm.dm_initialgain_enable == false)
+               return;
+
+       /* because we will send data pkt when scanning
+        * this will cause some ap like gear-3700 wep TP
+        * lower if we retrun here, this is the diff of
+        * mac80211 driver vs ieee80211 driver */
+       /* if (rtlpriv->mac80211.act_scanning)
+        *      return; */
+
+       /* Not STA mode return tmp */
+       if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
+               return;
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("progress\n"));
+       /* Decide the current status and if modify initial gain or not */
+       if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
+               de_digtable.cursta_connectctate = DIG_STA_CONNECT;
+       else
+               de_digtable.cursta_connectctate = DIG_STA_DISCONNECT;
+
+       /* adjust initial gain according to false alarm counter */
+       if (falsealm_cnt->cnt_all < DM_DIG_FA_TH0)
+               value_igi--;
+       else if (falsealm_cnt->cnt_all < DM_DIG_FA_TH1)
+               value_igi += 0;
+       else if (falsealm_cnt->cnt_all < DM_DIG_FA_TH2)
+               value_igi++;
+       else if (falsealm_cnt->cnt_all >= DM_DIG_FA_TH2)
+               value_igi += 2;
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+                ("dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n",
+                de_digtable.large_fa_hit, de_digtable.forbidden_igi));
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+                ("dm_DIG() Before: Recover_cnt=%d, rx_gain_range_min=%x\n",
+                de_digtable.recover_cnt, de_digtable.rx_gain_range_min));
+
+       /* deal with abnorally large false alarm */
+       if (falsealm_cnt->cnt_all > 10000) {
+               RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+                        ("dm_DIG(): Abnornally false alarm case.\n"));
+
+               de_digtable.large_fa_hit++;
+               if (de_digtable.forbidden_igi < de_digtable.cur_igvalue) {
+                       de_digtable.forbidden_igi = de_digtable.cur_igvalue;
+                       de_digtable.large_fa_hit = 1;
+               }
+               if (de_digtable.large_fa_hit >= 3) {
+                       if ((de_digtable.forbidden_igi + 1) > DM_DIG_MAX)
+                               de_digtable.rx_gain_range_min = DM_DIG_MAX;
+                       else
+                               de_digtable.rx_gain_range_min =
+                                   (de_digtable.forbidden_igi + 1);
+                       de_digtable.recover_cnt = 3600; /* 3600=2hr */
+               }
+       } else {
+               /* Recovery mechanism for IGI lower bound */
+               if (de_digtable.recover_cnt != 0) {
+                       de_digtable.recover_cnt--;
+               } else {
+                       if (de_digtable.large_fa_hit == 0) {
+                               if ((de_digtable.forbidden_igi - 1) <
+                                   DM_DIG_FA_LOWER) {
+                                       de_digtable.forbidden_igi =
+                                                        DM_DIG_FA_LOWER;
+                                       de_digtable.rx_gain_range_min =
+                                                        DM_DIG_FA_LOWER;
+
+                               } else {
+                                       de_digtable.forbidden_igi--;
+                                       de_digtable.rx_gain_range_min =
+                                           (de_digtable.forbidden_igi + 1);
+                               }
+                       } else if (de_digtable.large_fa_hit == 3) {
+                               de_digtable.large_fa_hit = 0;
+                       }
+               }
+       }
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+                ("dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n",
+                 de_digtable.large_fa_hit, de_digtable.forbidden_igi));
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+                ("dm_DIG() After: recover_cnt=%d, rx_gain_range_min=%x\n",
+                 de_digtable.recover_cnt, de_digtable.rx_gain_range_min));
+
+       if (value_igi > DM_DIG_MAX)
+               value_igi = DM_DIG_MAX;
+       else if (value_igi < de_digtable.rx_gain_range_min)
+               value_igi = de_digtable.rx_gain_range_min;
+       de_digtable.cur_igvalue = value_igi;
+       rtl92d_dm_write_dig(hw);
+       if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G)
+               rtl92d_dm_cck_packet_detection_thresh(hw);
+       RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("<<==\n"));
+}
+
+static void rtl92d_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpriv->dm.dynamic_txpower_enable = true;
+       rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
+       rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
+}
+
+static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       long undecorated_smoothed_pwdb;
+
+       if ((!rtlpriv->dm.dynamic_txpower_enable)
+           || rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
+               rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
+               return;
+       }
+       if ((mac->link_state < MAC80211_LINKED) &&
+           (rtlpriv->dm.UNDEC_SM_PWDB == 0)) {
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
+                        ("Not connected to any\n"));
+               rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
+               rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
+               return;
+       }
+       if (mac->link_state >= MAC80211_LINKED) {
+               if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+                       undecorated_smoothed_pwdb =
+                           rtlpriv->dm.UNDEC_SM_PWDB;
+                       RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                                ("IBSS Client PWDB = 0x%lx\n",
+                                 undecorated_smoothed_pwdb));
+               } else {
+                       undecorated_smoothed_pwdb =
+                           rtlpriv->dm.undecorated_smoothed_pwdb;
+                       RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                                ("STA Default Port PWDB = 0x%lx\n",
+                                 undecorated_smoothed_pwdb));
+               }
+       } else {
+               undecorated_smoothed_pwdb =
+                   rtlpriv->dm.UNDEC_SM_PWDB;
+
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                        ("AP Ext Port PWDB = 0x%lx\n",
+                         undecorated_smoothed_pwdb));
+       }
+       if (rtlhal->current_bandtype == BAND_ON_5G) {
+               if (undecorated_smoothed_pwdb >= 0x33) {
+                       rtlpriv->dm.dynamic_txhighpower_lvl =
+                                                TXHIGHPWRLEVEL_LEVEL2;
+                       RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD,
+                                ("5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n"));
+               } else if ((undecorated_smoothed_pwdb < 0x33)
+                          && (undecorated_smoothed_pwdb >= 0x2b)) {
+                       rtlpriv->dm.dynamic_txhighpower_lvl =
+                                                TXHIGHPWRLEVEL_LEVEL1;
+                       RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD,
+                                ("5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n"));
+               } else if (undecorated_smoothed_pwdb < 0x2b) {
+                       rtlpriv->dm.dynamic_txhighpower_lvl =
+                                                TXHIGHPWRLEVEL_NORMAL;
+                       RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD,
+                                ("5G:TxHighPwrLevel_Normal\n"));
+               }
+       } else {
+               if (undecorated_smoothed_pwdb >=
+                   TX_POWER_NEAR_FIELD_THRESH_LVL2) {
+                       rtlpriv->dm.dynamic_txhighpower_lvl =
+                                                TXHIGHPWRLEVEL_LEVEL2;
+                       RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                                ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
+               } else
+                   if ((undecorated_smoothed_pwdb <
+                        (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3))
+                       && (undecorated_smoothed_pwdb >=
+                           TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
+
+                       rtlpriv->dm.dynamic_txhighpower_lvl =
+                                                TXHIGHPWRLEVEL_LEVEL1;
+                       RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                                ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
+               } else if (undecorated_smoothed_pwdb <
+                          (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
+                       rtlpriv->dm.dynamic_txhighpower_lvl =
+                                                TXHIGHPWRLEVEL_NORMAL;
+                       RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                                ("TXHIGHPWRLEVEL_NORMAL\n"));
+               }
+       }
+       if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                        ("PHY_SetTxPowerLevel8192S() Channel = %d\n",
+                         rtlphy->current_channel));
+               rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel);
+       }
+       rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
+}
+
+static void rtl92d_dm_pwdb_monitor(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       /* AP & ADHOC & MESH will return tmp */
+       if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
+               return;
+       /* Indicate Rx signal strength to FW. */
+       if (rtlpriv->dm.useramask) {
+               u32 temp = rtlpriv->dm.undecorated_smoothed_pwdb;
+
+               temp <<= 16;
+               temp |= 0x100;
+               /* fw v12 cmdid 5:use max macid ,for nic ,
+                * default macid is 0 ,max macid is 1 */
+               rtl92d_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, (u8 *) (&temp));
+       } else {
+               rtl_write_byte(rtlpriv, 0x4fe,
+                              (u8) rtlpriv->dm.undecorated_smoothed_pwdb);
+       }
+}
+
+void rtl92d_dm_init_edca_turbo(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpriv->dm.current_turbo_edca = false;
+       rtlpriv->dm.is_any_nonbepkts = false;
+       rtlpriv->dm.is_cur_rdlstate = false;
+}
+
+static void rtl92d_dm_check_edca_turbo(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       static u64 last_txok_cnt;
+       static u64 last_rxok_cnt;
+       u64 cur_txok_cnt;
+       u64 cur_rxok_cnt;
+       u32 edca_be_ul = 0x5ea42b;
+       u32 edca_be_dl = 0x5ea42b;
+
+       if (mac->link_state != MAC80211_LINKED) {
+               rtlpriv->dm.current_turbo_edca = false;
+               goto exit;
+       }
+
+       /* Enable BEQ TxOP limit configuration in wireless G-mode. */
+       /* To check whether we shall force turn on TXOP configuration. */
+       if ((!rtlpriv->dm.disable_framebursting) &&
+           (rtlpriv->sec.pairwise_enc_algorithm == WEP40_ENCRYPTION ||
+           rtlpriv->sec.pairwise_enc_algorithm == WEP104_ENCRYPTION ||
+           rtlpriv->sec.pairwise_enc_algorithm == TKIP_ENCRYPTION)) {
+               /* Force TxOP limit to 0x005e for UL. */
+               if (!(edca_be_ul & 0xffff0000))
+                       edca_be_ul |= 0x005e0000;
+               /* Force TxOP limit to 0x005e for DL. */
+               if (!(edca_be_dl & 0xffff0000))
+                       edca_be_dl |= 0x005e0000;
+       }
+
+       if ((!rtlpriv->dm.is_any_nonbepkts) &&
+           (!rtlpriv->dm.disable_framebursting)) {
+               cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
+               cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
+               if (cur_rxok_cnt > 4 * cur_txok_cnt) {
+                       if (!rtlpriv->dm.is_cur_rdlstate ||
+                           !rtlpriv->dm.current_turbo_edca) {
+                               rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM,
+                                               edca_be_dl);
+                               rtlpriv->dm.is_cur_rdlstate = true;
+                       }
+               } else {
+                       if (rtlpriv->dm.is_cur_rdlstate ||
+                           !rtlpriv->dm.current_turbo_edca) {
+                               rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM,
+                                               edca_be_ul);
+                               rtlpriv->dm.is_cur_rdlstate = false;
+                       }
+               }
+               rtlpriv->dm.current_turbo_edca = true;
+       } else {
+               if (rtlpriv->dm.current_turbo_edca) {
+                       u8 tmp = AC0_BE;
+                       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
+                                                     (u8 *) (&tmp));
+                       rtlpriv->dm.current_turbo_edca = false;
+               }
+       }
+
+exit:
+       rtlpriv->dm.is_any_nonbepkts = false;
+       last_txok_cnt = rtlpriv->stats.txbytesunicast;
+       last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
+}
+
+static void rtl92d_dm_rxgain_tracking_thermalmeter(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 index_mapping[RX_INDEX_MAPPING_NUM] = {
+               0x0f, 0x0f, 0x0d, 0x0c, 0x0b,
+               0x0a, 0x09, 0x08, 0x07, 0x06,
+               0x05, 0x04, 0x04, 0x03, 0x02
+       };
+       int i;
+       u32 u4tmp;
+
+       u4tmp = (index_mapping[(rtlpriv->efuse.eeprom_thermalmeter -
+                               rtlpriv->dm.thermalvalue_rxgain)]) << 12;
+       RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                ("===> Rx Gain %x\n", u4tmp));
+       for (i = RF90_PATH_A; i < rtlpriv->phy.num_total_rfpath; i++)
+               rtl_set_rfreg(hw, i, 0x3C, BRFREGOFFSETMASK,
+                             (rtlpriv->phy.reg_rf3c[i] & (~(0xF000))) | u4tmp);
+}
+
+static void rtl92d_bandtype_2_4G(struct ieee80211_hw *hw, long *temp_cckg,
+                                u8 *cck_index_old)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int i;
+       unsigned long flag = 0;
+       long temp_cck;
+
+       /* Query CCK default setting From 0xa24 */
+       rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
+       temp_cck = rtl_get_bbreg(hw, RCCK0_TXFILTER2,
+                                BMASKDWORD) & BMASKCCK;
+       rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
+       for (i = 0; i < CCK_TABLE_LENGTH; i++) {
+               if (rtlpriv->dm.cck_inch14) {
+                       if (!memcmp((void *)&temp_cck,
+                           (void *)&cckswing_table_ch14[i][2], 4)) {
+                               *cck_index_old = (u8) i;
+                               RT_TRACE(rtlpriv,
+                                        COMP_POWER_TRACKING,
+                                        DBG_LOUD,
+                                        ("Initial reg0x%x = 0x%lx, "
+                                         "cck_index=0x%x, ch 14 %d\n",
+                                         RCCK0_TXFILTER2,
+                                         temp_cck, *cck_index_old,
+                                         rtlpriv->dm.cck_inch14));
+                               break;
+                       }
+               } else {
+                       if (!memcmp((void *) &temp_cck,
+                           &cckswing_table_ch1ch13[i][2], 4)) {
+                               *cck_index_old = (u8) i;
+                               RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
+                                        DBG_LOUD,
+                                        ("Initial reg0x%x = 0x%lx, "
+                                        "cck_index = 0x%x, ch14 %d\n",
+                                        RCCK0_TXFILTER2,
+                                        temp_cck, *cck_index_old,
+                                        rtlpriv->dm.cck_inch14));
+                               break;
+                       }
+               }
+       }
+       *temp_cckg = temp_cck;
+}
+
+static void rtl92d_bandtype_5G(struct rtl_hal *rtlhal, u8 *ofdm_index,
+                              bool *internal_pa, u8 thermalvalue, u8 delta,
+                              u8 rf, struct rtl_efuse *rtlefuse,
+                              struct rtl_priv *rtlpriv, struct rtl_phy *rtlphy,
+                              u8 index_mapping[5][INDEX_MAPPING_NUM],
+                              u8 index_mapping_pa[8][INDEX_MAPPING_NUM])
+{
+       int i;
+       u8 index;
+       u8 offset = 0;
+
+       for (i = 0; i < rf; i++) {
+               if (rtlhal->macphymode == DUALMAC_DUALPHY &&
+                   rtlhal->interfaceindex == 1)        /* MAC 1 5G */
+                       *internal_pa = rtlefuse->internal_pa_5g[1];
+               else
+                       *internal_pa = rtlefuse->internal_pa_5g[i];
+               if (*internal_pa) {
+                       if (rtlhal->interfaceindex == 1 || i == rf)
+                               offset = 4;
+                       else
+                               offset = 0;
+                       if (rtlphy->current_channel >= 100 &&
+                               rtlphy->current_channel <= 165)
+                               offset += 2;
+               } else {
+                       if (rtlhal->interfaceindex == 1 || i == rf)
+                               offset = 2;
+                       else
+                               offset = 0;
+               }
+               if (thermalvalue > rtlefuse->eeprom_thermalmeter)
+                       offset++;
+               if (*internal_pa) {
+                       if (delta > INDEX_MAPPING_NUM - 1)
+                               index = index_mapping_pa[offset]
+                                                   [INDEX_MAPPING_NUM - 1];
+                       else
+                               index =
+                                    index_mapping_pa[offset][delta];
+               } else {
+                       if (delta > INDEX_MAPPING_NUM - 1)
+                               index =
+                                  index_mapping[offset][INDEX_MAPPING_NUM - 1];
+                       else
+                               index = index_mapping[offset][delta];
+               }
+               if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
+                       if (*internal_pa && thermalvalue > 0x12) {
+                               ofdm_index[i] = rtlpriv->dm.ofdm_index[i] -
+                                               ((delta / 2) * 3 + (delta % 2));
+                       } else {
+                               ofdm_index[i] -= index;
+                       }
+               } else {
+                       ofdm_index[i] += index;
+               }
+       }
+}
+
+static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
+                       struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u8 thermalvalue, delta, delta_lck, delta_iqk, delta_rxgain;
+       u8 offset, thermalvalue_avg_count = 0;
+       u32 thermalvalue_avg = 0;
+       bool internal_pa = false;
+       long ele_a = 0, ele_d, temp_cck, val_x, value32;
+       long val_y, ele_c = 0;
+       u8 ofdm_index[2];
+       u8 cck_index = 0;
+       u8 ofdm_index_old[2];
+       u8 cck_index_old = 0;
+       u8 index;
+       int i;
+       bool is2t = IS_92D_SINGLEPHY(rtlhal->version);
+       u8 ofdm_min_index = 6, ofdm_min_index_internal_pa = 3, rf;
+       u8 indexforchannel =
+           rtl92d_get_rightchnlplace_for_iqk(rtlphy->current_channel);
+       u8 index_mapping[5][INDEX_MAPPING_NUM] = {
+               /* 5G, path A/MAC 0, decrease power  */
+               {0, 1, 3, 6, 8, 9,      11, 13, 14, 16, 17, 18, 18},
+               /* 5G, path A/MAC 0, increase power  */
+               {0, 2, 4, 5, 7, 10,     12, 14, 16, 18, 18, 18, 18},
+               /* 5G, path B/MAC 1, decrease power */
+               {0, 2, 3, 6, 8, 9,      11, 13, 14, 16, 17, 18, 18},
+               /* 5G, path B/MAC 1, increase power */
+               {0, 2, 4, 5, 7, 10,     13, 16, 16, 18, 18, 18, 18},
+               /* 2.4G, for decreas power */
+               {0, 1, 2, 3, 4, 5,      6, 7, 7, 8, 9, 10, 10},
+       };
+       u8 index_mapping_internal_pa[8][INDEX_MAPPING_NUM] = {
+               /* 5G, path A/MAC 0, ch36-64, decrease power  */
+               {0, 1, 2, 4, 6, 7,      9, 11, 12, 14, 15, 16, 16},
+               /* 5G, path A/MAC 0, ch36-64, increase power  */
+               {0, 2, 4, 5, 7, 10,     12, 14, 16, 18, 18, 18, 18},
+               /* 5G, path A/MAC 0, ch100-165, decrease power  */
+               {0, 1, 2, 3, 5, 6,      8, 10, 11, 13, 14, 15, 15},
+               /* 5G, path A/MAC 0, ch100-165, increase power  */
+               {0, 2, 4, 5, 7, 10,     12, 14, 16, 18, 18, 18, 18},
+               /* 5G, path B/MAC 1, ch36-64, decrease power */
+               {0, 1, 2, 4, 6, 7,      9, 11, 12, 14, 15, 16, 16},
+               /* 5G, path B/MAC 1, ch36-64, increase power */
+               {0, 2, 4, 5, 7, 10,     13, 16, 16, 18, 18, 18, 18},
+               /* 5G, path B/MAC 1, ch100-165, decrease power */
+               {0, 1, 2, 3, 5, 6,      8, 9, 10, 12, 13, 14, 14},
+               /* 5G, path B/MAC 1, ch100-165, increase power */
+               {0, 2, 4, 5, 7, 10,     13, 16, 16, 18, 18, 18, 18},
+       };
+
+       rtlpriv->dm.txpower_trackinginit = true;
+       RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("\n"));
+       thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0xf800);
+       RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
+                "eeprom_thermalmeter 0x%x\n", thermalvalue,
+                rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter));
+       rtl92d_phy_ap_calibrate(hw, (thermalvalue -
+                                    rtlefuse->eeprom_thermalmeter));
+       if (is2t)
+               rf = 2;
+       else
+               rf = 1;
+       if (thermalvalue) {
+               ele_d = rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
+                                     BMASKDWORD) & BMASKOFDM_D;
+               for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
+                       if (ele_d == (ofdmswing_table[i] & BMASKOFDM_D)) {
+                               ofdm_index_old[0] = (u8) i;
+
+                               RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                                        ("Initial pathA ele_d reg0x%x = 0x%lx,"
+                                        " ofdm_index=0x%x\n",
+                                        ROFDM0_XATxIQIMBALANCE,
+                                        ele_d, ofdm_index_old[0]));
+                               break;
+                       }
+               }
+               if (is2t) {
+                       ele_d = rtl_get_bbreg(hw, ROFDM0_XBTxIQIMBALANCE,
+                                             BMASKDWORD) & BMASKOFDM_D;
+                       for (i = 0; i < OFDM_TABLE_SIZE_92D; i++) {
+                               if (ele_d ==
+                                   (ofdmswing_table[i] & BMASKOFDM_D)) {
+                                       ofdm_index_old[1] = (u8) i;
+                                       RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
+                                                DBG_LOUD,
+                                                ("Initial pathB ele_d reg "
+                                                "0x%x = 0x%lx, ofdm_index "
+                                                "= 0x%x\n",
+                                                ROFDM0_XBTxIQIMBALANCE, ele_d,
+                                                ofdm_index_old[1]));
+                                       break;
+                               }
+                       }
+               }
+               if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+                       rtl92d_bandtype_2_4G(hw, &temp_cck, &cck_index_old);
+               } else {
+                       temp_cck = 0x090e1317;
+                       cck_index_old = 12;
+               }
+
+               if (!rtlpriv->dm.thermalvalue) {
+                       rtlpriv->dm.thermalvalue =
+                                rtlefuse->eeprom_thermalmeter;
+                       rtlpriv->dm.thermalvalue_lck = thermalvalue;
+                       rtlpriv->dm.thermalvalue_iqk = thermalvalue;
+                       rtlpriv->dm.thermalvalue_rxgain =
+                                        rtlefuse->eeprom_thermalmeter;
+                       for (i = 0; i < rf; i++)
+                               rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
+                       rtlpriv->dm.cck_index = cck_index_old;
+               }
+               if (rtlhal->reloadtxpowerindex) {
+                       for (i = 0; i < rf; i++)
+                               rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
+                       rtlpriv->dm.cck_index = cck_index_old;
+                       RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                                ("reload ofdm index for band switch\n"));
+               }
+               rtlpriv->dm.thermalvalue_avg
+                           [rtlpriv->dm.thermalvalue_avg_index] = thermalvalue;
+               rtlpriv->dm.thermalvalue_avg_index++;
+               if (rtlpriv->dm.thermalvalue_avg_index == AVG_THERMAL_NUM)
+                       rtlpriv->dm.thermalvalue_avg_index = 0;
+               for (i = 0; i < AVG_THERMAL_NUM; i++) {
+                       if (rtlpriv->dm.thermalvalue_avg[i]) {
+                               thermalvalue_avg +=
+                                        rtlpriv->dm.thermalvalue_avg[i];
+                               thermalvalue_avg_count++;
+                       }
+               }
+               if (thermalvalue_avg_count)
+                       thermalvalue = (u8) (thermalvalue_avg /
+                                       thermalvalue_avg_count);
+               if (rtlhal->reloadtxpowerindex) {
+                       delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
+                           (thermalvalue - rtlefuse->eeprom_thermalmeter) :
+                           (rtlefuse->eeprom_thermalmeter - thermalvalue);
+                       rtlhal->reloadtxpowerindex = false;
+                       rtlpriv->dm.done_txpower = false;
+               } else if (rtlpriv->dm.done_txpower) {
+                       delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
+                           (thermalvalue - rtlpriv->dm.thermalvalue) :
+                           (rtlpriv->dm.thermalvalue - thermalvalue);
+               } else {
+                       delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
+                           (thermalvalue - rtlefuse->eeprom_thermalmeter) :
+                           (rtlefuse->eeprom_thermalmeter - thermalvalue);
+               }
+               delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
+                   (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
+                   (rtlpriv->dm.thermalvalue_lck - thermalvalue);
+               delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
+                   (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
+                   (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
+               delta_rxgain =
+                       (thermalvalue > rtlpriv->dm.thermalvalue_rxgain) ?
+                       (thermalvalue - rtlpriv->dm.thermalvalue_rxgain) :
+                       (rtlpriv->dm.thermalvalue_rxgain - thermalvalue);
+               RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                        ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x"
+                         " eeprom_thermalmeter 0x%x delta 0x%x "
+                         "delta_lck 0x%x delta_iqk 0x%x\n",
+                         thermalvalue, rtlpriv->dm.thermalvalue,
+                         rtlefuse->eeprom_thermalmeter, delta, delta_lck,
+                         delta_iqk));
+               if ((delta_lck > rtlefuse->delta_lck) &&
+                   (rtlefuse->delta_lck != 0)) {
+                       rtlpriv->dm.thermalvalue_lck = thermalvalue;
+                       rtl92d_phy_lc_calibrate(hw);
+               }
+               if (delta > 0 && rtlpriv->dm.txpower_track_control) {
+                       rtlpriv->dm.done_txpower = true;
+                       delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
+                           (thermalvalue - rtlefuse->eeprom_thermalmeter) :
+                           (rtlefuse->eeprom_thermalmeter - thermalvalue);
+                       if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+                               offset = 4;
+                               if (delta > INDEX_MAPPING_NUM - 1)
+                                       index = index_mapping[offset]
+                                               [INDEX_MAPPING_NUM - 1];
+                               else
+                                       index = index_mapping[offset][delta];
+                               if (thermalvalue > rtlpriv->dm.thermalvalue) {
+                                       for (i = 0; i < rf; i++)
+                                               ofdm_index[i] -= delta;
+                                       cck_index -= delta;
+                               } else {
+                                       for (i = 0; i < rf; i++)
+                                               ofdm_index[i] += index;
+                                       cck_index += index;
+                               }
+                       } else if (rtlhal->current_bandtype == BAND_ON_5G) {
+                               rtl92d_bandtype_5G(rtlhal, ofdm_index,
+                                                  &internal_pa, thermalvalue,
+                                                  delta, rf, rtlefuse, rtlpriv,
+                                                  rtlphy, index_mapping,
+                                                  index_mapping_internal_pa);
+                       }
+                       if (is2t) {
+                               RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                                        ("temp OFDM_A_index=0x%x, OFDM_B_index"
+                                        " = 0x%x,cck_index=0x%x\n",
+                                         rtlpriv->dm.ofdm_index[0],
+                                         rtlpriv->dm.ofdm_index[1],
+                                         rtlpriv->dm.cck_index));
+                       } else {
+                               RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                                        ("temp OFDM_A_index=0x%x,cck_index = "
+                                        "0x%x\n",
+                                         rtlpriv->dm.ofdm_index[0],
+                                                       rtlpriv->dm.cck_index));
+                       }
+                       for (i = 0; i < rf; i++) {
+                               if (ofdm_index[i] > OFDM_TABLE_SIZE_92D - 1)
+                                       ofdm_index[i] = OFDM_TABLE_SIZE_92D - 1;
+                               else if (ofdm_index[i] < ofdm_min_index)
+                                       ofdm_index[i] = ofdm_min_index;
+                       }
+                       if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+                               if (cck_index > CCK_TABLE_SIZE - 1) {
+                                       cck_index = CCK_TABLE_SIZE - 1;
+                               } else if (internal_pa ||
+                                          rtlhal->current_bandtype ==
+                                          BAND_ON_2_4G) {
+                                       if (ofdm_index[i] <
+                                           ofdm_min_index_internal_pa)
+                                               ofdm_index[i] =
+                                                    ofdm_min_index_internal_pa;
+                               } else if (cck_index < 0) {
+                                       cck_index = 0;
+                               }
+                       }
+                       if (is2t) {
+                               RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                                        ("new OFDM_A_index=0x%x, OFDM_B_index "
+                                        "= 0x%x, cck_index=0x%x\n",
+                                        ofdm_index[0], ofdm_index[1],
+                                        cck_index));
+                       } else {
+                               RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                                        ("new OFDM_A_index=0x%x,cck_index = "
+                                        "0x%x\n",
+                                         ofdm_index[0], cck_index));
+                       }
+                       ele_d = (ofdmswing_table[(u8) ofdm_index[0]] &
+                                                0xFFC00000) >> 22;
+                       val_x = rtlphy->iqk_matrix_regsetting
+                                               [indexforchannel].value[0][0];
+                       val_y = rtlphy->iqk_matrix_regsetting
+                                               [indexforchannel].value[0][1];
+                       if (val_x != 0) {
+                               if ((val_x & 0x00000200) != 0)
+                                       val_x = val_x | 0xFFFFFC00;
+                               ele_a =
+                                   ((val_x * ele_d) >> 8) & 0x000003FF;
+
+                               /* new element C = element D x Y */
+                               if ((val_y & 0x00000200) != 0)
+                                       val_y = val_y | 0xFFFFFC00;
+                               ele_c = ((val_y * ele_d) >> 8) & 0x000003FF;
+
+                               /* wirte new elements A, C, D to regC80 and
+                                * regC94, element B is always 0 */
+                               value32 = (ele_d << 22) | ((ele_c & 0x3F) <<
+                                         16) | ele_a;
+                               rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
+                                             BMASKDWORD, value32);
+
+                               value32 = (ele_c & 0x000003C0) >> 6;
+                               rtl_set_bbreg(hw, ROFDM0_XCTxAFE, BMASKH4BITS,
+                                             value32);
+
+                               value32 = ((val_x * ele_d) >> 7) & 0x01;
+                               rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
+                                             value32);
+
+                       } else {
+                               rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
+                                             BMASKDWORD,
+                                             ofdmswing_table
+                                             [(u8)ofdm_index[0]]);
+                               rtl_set_bbreg(hw, ROFDM0_XCTxAFE, BMASKH4BITS,
+                                             0x00);
+                               rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
+                                             BIT(24), 0x00);
+                       }
+
+                       RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                                ("TxPwrTracking for interface %d path A: X ="
+                                " 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = "
+                                "0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = "
+                                "0x%lx\n", rtlhal->interfaceindex,
+                                val_x, val_y, ele_a, ele_c, ele_d,
+                                val_x, val_y));
+
+                       if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+                               /* Adjust CCK according to IQK result */
+                               if (!rtlpriv->dm.cck_inch14) {
+                                       rtl_write_byte(rtlpriv, 0xa22,
+                                                      cckswing_table_ch1ch13
+                                                      [(u8)cck_index][0]);
+                                       rtl_write_byte(rtlpriv, 0xa23,
+                                                      cckswing_table_ch1ch13
+                                                      [(u8)cck_index][1]);
+                                       rtl_write_byte(rtlpriv, 0xa24,
+                                                      cckswing_table_ch1ch13
+                                                      [(u8)cck_index][2]);
+                                       rtl_write_byte(rtlpriv, 0xa25,
+                                                      cckswing_table_ch1ch13
+                                                      [(u8)cck_index][3]);
+                                       rtl_write_byte(rtlpriv, 0xa26,
+                                                      cckswing_table_ch1ch13
+                                                      [(u8)cck_index][4]);
+                                       rtl_write_byte(rtlpriv, 0xa27,
+                                                      cckswing_table_ch1ch13
+                                                      [(u8)cck_index][5]);
+                                       rtl_write_byte(rtlpriv, 0xa28,
+                                                      cckswing_table_ch1ch13
+                                                      [(u8)cck_index][6]);
+                                       rtl_write_byte(rtlpriv, 0xa29,
+                                                      cckswing_table_ch1ch13
+                                                      [(u8)cck_index][7]);
+                               } else {
+                                       rtl_write_byte(rtlpriv, 0xa22,
+                                                      cckswing_table_ch14
+                                                      [(u8)cck_index][0]);
+                                       rtl_write_byte(rtlpriv, 0xa23,
+                                                      cckswing_table_ch14
+                                                      [(u8)cck_index][1]);
+                                       rtl_write_byte(rtlpriv, 0xa24,
+                                                      cckswing_table_ch14
+                                                      [(u8)cck_index][2]);
+                                       rtl_write_byte(rtlpriv, 0xa25,
+                                                      cckswing_table_ch14
+                                                      [(u8)cck_index][3]);
+                                       rtl_write_byte(rtlpriv, 0xa26,
+                                                      cckswing_table_ch14
+                                                      [(u8)cck_index][4]);
+                                       rtl_write_byte(rtlpriv, 0xa27,
+                                                      cckswing_table_ch14
+                                                      [(u8)cck_index][5]);
+                                       rtl_write_byte(rtlpriv, 0xa28,
+                                                      cckswing_table_ch14
+                                                      [(u8)cck_index][6]);
+                                       rtl_write_byte(rtlpriv, 0xa29,
+                                                      cckswing_table_ch14
+                                                      [(u8)cck_index][7]);
+                               }
+                       }
+                       if (is2t) {
+                               ele_d = (ofdmswing_table[(u8) ofdm_index[1]] &
+                                               0xFFC00000) >> 22;
+                               val_x = rtlphy->iqk_matrix_regsetting
+                                               [indexforchannel].value[0][4];
+                               val_y = rtlphy->iqk_matrix_regsetting
+                                               [indexforchannel].value[0][5];
+                               if (val_x != 0) {
+                                       if ((val_x & 0x00000200) != 0)
+                                               /* consider minus */
+                                               val_x = val_x | 0xFFFFFC00;
+                                       ele_a = ((val_x * ele_d) >> 8) &
+                                               0x000003FF;
+                                       /* new element C = element D x Y */
+                                       if ((val_y & 0x00000200) != 0)
+                                               val_y =
+                                                   val_y | 0xFFFFFC00;
+                                       ele_c =
+                                           ((val_y *
+                                             ele_d) >> 8) & 0x00003FF;
+                                       /* write new elements A, C, D to regC88
+                                        * and regC9C, element B is always 0
+                                        */
+                                       value32 = (ele_d << 22) |
+                                                 ((ele_c & 0x3F) << 16) |
+                                                 ele_a;
+                                       rtl_set_bbreg(hw,
+                                                     ROFDM0_XBTxIQIMBALANCE,
+                                                     BMASKDWORD, value32);
+                                       value32 = (ele_c & 0x000003C0) >> 6;
+                                       rtl_set_bbreg(hw, ROFDM0_XDTxAFE,
+                                                     BMASKH4BITS, value32);
+                                       value32 = ((val_x * ele_d) >> 7) & 0x01;
+                                       rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
+                                                     BIT(28), value32);
+                               } else {
+                                       rtl_set_bbreg(hw,
+                                                     ROFDM0_XBTxIQIMBALANCE,
+                                                     BMASKDWORD,
+                                                     ofdmswing_table
+                                                     [(u8) ofdm_index[1]]);
+                                       rtl_set_bbreg(hw, ROFDM0_XDTxAFE,
+                                                     BMASKH4BITS, 0x00);
+                                       rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
+                                                     BIT(28), 0x00);
+                               }
+                               RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                                        ("TxPwrTracking path B: X = 0x%lx, "
+                                        "Y = 0x%lx ele_A = 0x%lx ele_C = 0x"
+                                        "%lx ele_D = 0x%lx 0xeb4 = 0x%lx "
+                                        "0xebc = 0x%lx\n",
+                                         val_x, val_y, ele_a, ele_c,
+                                         ele_d, val_x, val_y));
+                       }
+                       RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                                ("TxPwrTracking 0xc80 = 0x%x, 0xc94 = "
+                                "0x%x RF 0x24 = 0x%x\n",
+                                rtl_get_bbreg(hw, 0xc80, BMASKDWORD),
+                                rtl_get_bbreg(hw, 0xc94, BMASKDWORD),
+                                rtl_get_rfreg(hw, RF90_PATH_A, 0x24,
+                                BRFREGOFFSETMASK)));
+               }
+               if ((delta_iqk > rtlefuse->delta_iqk) &&
+                   (rtlefuse->delta_iqk != 0)) {
+                       rtl92d_phy_reset_iqk_result(hw);
+                       rtlpriv->dm.thermalvalue_iqk = thermalvalue;
+                       rtl92d_phy_iq_calibrate(hw);
+               }
+               if (delta_rxgain > 0 && rtlhal->current_bandtype == BAND_ON_5G
+                   && thermalvalue <= rtlefuse->eeprom_thermalmeter) {
+                       rtlpriv->dm.thermalvalue_rxgain = thermalvalue;
+                       rtl92d_dm_rxgain_tracking_thermalmeter(hw);
+               }
+               if (rtlpriv->dm.txpower_track_control)
+                       rtlpriv->dm.thermalvalue = thermalvalue;
+       }
+
+       RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n"));
+}
+
+static void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpriv->dm.txpower_tracking = true;
+       rtlpriv->dm.txpower_trackinginit = false;
+       rtlpriv->dm.txpower_track_control = true;
+       RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                ("pMgntInfo->txpower_tracking = %d\n",
+                rtlpriv->dm.txpower_tracking));
+}
+
+void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       static u8 tm_trigger;
+
+       if (!rtlpriv->dm.txpower_tracking)
+               return;
+
+       if (!tm_trigger) {
+               rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) |
+                             BIT(16), 0x03);
+               RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                        ("Trigger 92S Thermal Meter!!\n"));
+               tm_trigger = 1;
+               return;
+       } else {
+               RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+                        ("Schedule TxPowerTracking direct call!!\n"));
+               rtl92d_dm_txpower_tracking_callback_thermalmeter(hw);
+               tm_trigger = 0;
+       }
+}
+
+void rtl92d_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rate_adaptive *ra = &(rtlpriv->ra);
+
+       ra->ratr_state = DM_RATR_STA_INIT;
+       ra->pre_ratr_state = DM_RATR_STA_INIT;
+       if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
+               rtlpriv->dm.useramask = true;
+       else
+               rtlpriv->dm.useramask = false;
+}
+
+void rtl92d_dm_init(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
+       rtl92d_dm_diginit(hw);
+       rtl92d_dm_init_dynamic_txpower(hw);
+       rtl92d_dm_init_edca_turbo(hw);
+       rtl92d_dm_init_rate_adaptive_mask(hw);
+       rtl92d_dm_initialize_txpower_tracking(hw);
+}
+
+void rtl92d_dm_watchdog(struct ieee80211_hw *hw)
+{
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       bool fw_current_inpsmode = false;
+       bool fwps_awake = true;
+
+       /* 1. RF is OFF. (No need to do DM.)
+        * 2. Fw is under power saving mode for FwLPS.
+        *    (Prevent from SW/FW I/O racing.)
+        * 3. IPS workitem is scheduled. (Prevent from IPS sequence
+        *    to be swapped with DM.
+        * 4. RFChangeInProgress is TRUE.
+        *    (Prevent from broken by IPS/HW/SW Rf off.) */
+
+       if ((ppsc->rfpwr_state == ERFON) && ((!fw_current_inpsmode) &&
+           fwps_awake) && (!ppsc->rfchange_inprogress)) {
+               rtl92d_dm_pwdb_monitor(hw);
+               rtl92d_dm_false_alarm_counter_statistics(hw);
+               rtl92d_dm_find_minimum_rssi(hw);
+               rtl92d_dm_dig(hw);
+               /* rtl92d_dm_dynamic_bb_powersaving(hw); */
+               rtl92d_dm_dynamic_txpower(hw);
+               /* rtl92d_dm_check_txpower_tracking_thermal_meter(hw); */
+               /* rtl92d_dm_refresh_rate_adaptive_mask(hw); */
+               /* rtl92d_dm_interrupt_migration(hw); */
+               rtl92d_dm_check_edca_turbo(hw);
+       }
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h
new file mode 100644 (file)
index 0000000..6935465
--- /dev/null
@@ -0,0 +1,212 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef        __RTL92C_DM_H__
+#define __RTL92C_DM_H__
+
+#define HAL_DM_DIG_DISABLE                     BIT(0)
+#define HAL_DM_HIPWR_DISABLE                   BIT(1)
+
+#define OFDM_TABLE_LENGTH                      37
+#define OFDM_TABLE_SIZE_92D                    43
+#define CCK_TABLE_LENGTH                       33
+
+#define CCK_TABLE_SIZE                         33
+
+#define BW_AUTO_SWITCH_HIGH_LOW                        25
+#define BW_AUTO_SWITCH_LOW_HIGH                        30
+
+#define DM_DIG_THRESH_HIGH                     40
+#define DM_DIG_THRESH_LOW                      35
+
+#define DM_FALSEALARM_THRESH_LOW               400
+#define DM_FALSEALARM_THRESH_HIGH              1000
+
+#define DM_DIG_MAX                             0x3e
+#define DM_DIG_MIN                             0x1c
+
+#define DM_DIG_FA_UPPER                                0x32
+#define DM_DIG_FA_LOWER                                0x20
+#define DM_DIG_FA_TH0                          0x100
+#define DM_DIG_FA_TH1                          0x400
+#define DM_DIG_FA_TH2                          0x600
+
+#define DM_DIG_BACKOFF_MAX                     12
+#define DM_DIG_BACKOFF_MIN                     -4
+#define DM_DIG_BACKOFF_DEFAULT                 10
+
+#define RXPATHSELECTION_SS_TH_lOW              30
+#define RXPATHSELECTION_DIFF_TH                        18
+
+#define DM_RATR_STA_INIT                       0
+#define DM_RATR_STA_HIGH                       1
+#define DM_RATR_STA_MIDDLE                     2
+#define DM_RATR_STA_LOW                                3
+
+#define CTS2SELF_THVAL                         30
+#define REGC38_TH                              20
+
+#define WAIOTTHVAL                             25
+
+#define TXHIGHPWRLEVEL_NORMAL                  0
+#define TXHIGHPWRLEVEL_LEVEL1                  1
+#define TXHIGHPWRLEVEL_LEVEL2                  2
+#define TXHIGHPWRLEVEL_BT1                     3
+#define TXHIGHPWRLEVEL_BT2                     4
+
+#define DM_TYPE_BYFW                           0
+#define DM_TYPE_BYDRIVER                       1
+
+#define TX_POWER_NEAR_FIELD_THRESH_LVL2                74
+#define TX_POWER_NEAR_FIELD_THRESH_LVL1                67
+#define INDEX_MAPPING_NUM                      13
+
+struct ps_t {
+       u8 pre_ccastate;
+       u8 cur_ccasate;
+
+       u8 pre_rfstate;
+       u8 cur_rfstate;
+
+       long rssi_val_min;
+};
+
+struct dig_t {
+       u8 dig_enable_flag;
+       u8 dig_ext_port_stage;
+
+       u32 rssi_lowthresh;
+       u32 rssi_highthresh;
+
+       u32 fa_lowthresh;
+       u32 fa_highthresh;
+
+       u8 cursta_connectctate;
+       u8 presta_connectstate;
+       u8 curmultista_connectstate;
+
+       u8 pre_igvalue;
+       u8 cur_igvalue;
+
+       char backoff_val;
+       char backoff_val_range_max;
+       char backoff_val_range_min;
+       u8 rx_gain_range_max;
+       u8 rx_gain_range_min;
+       u8 min_undecorated_pwdb_for_dm;
+       long last_min_undecorated_pwdb_for_dm;
+
+       u8 pre_cck_pd_state;
+       u8 cur_cck_pd_state;
+
+       u8 pre_cck_fa_state;
+       u8 cur_cck_fa_state;
+
+       u8 pre_ccastate;
+       u8 cur_ccasate;
+
+       u8 large_fa_hit;
+       u8 forbidden_igi;
+       u32 recover_cnt;
+};
+
+struct swat {
+       u8 failure_cnt;
+       u8 try_flag;
+       u8 stop_trying;
+       long pre_rssi;
+       long trying_threshold;
+       u8 cur_antenna;
+       u8 pre_antenna;
+};
+
+enum tag_dynamic_init_gain_operation_type_definition {
+       DIG_TYPE_THRESH_HIGH = 0,
+       DIG_TYPE_THRESH_LOW = 1,
+       DIG_TYPE_BACKOFF = 2,
+       DIG_TYPE_RX_GAIN_MIN = 3,
+       DIG_TYPE_RX_GAIN_MAX = 4,
+       DIG_TYPE_ENABLE = 5,
+       DIG_TYPE_DISABLE = 6,
+       DIG_OP_TYPE_MAX
+};
+
+enum tag_cck_packet_detection_threshold_type_definition {
+       CCK_PD_STAGE_LOWRSSI = 0,
+       CCK_PD_STAGE_HIGHRSSI = 1,
+       CCK_FA_STAGE_LOW = 2,
+       CCK_FA_STAGE_HIGH = 3,
+       CCK_PD_STAGE_MAX = 4,
+};
+
+enum dm_1r_cca {
+       CCA_1R = 0,
+       CCA_2R = 1,
+       CCA_MAX = 2,
+};
+
+enum dm_rf {
+       RF_SAVE = 0,
+       RF_NORMAL = 1,
+       RF_MAX = 2,
+};
+
+enum dm_sw_ant_switch {
+       ANS_ANTENNA_B = 1,
+       ANS_ANTENNA_A = 2,
+       ANS_ANTENNA_MAX = 3,
+};
+
+enum dm_dig_ext_port_alg {
+       DIG_EXT_PORT_STAGE_0 = 0,
+       DIG_EXT_PORT_STAGE_1 = 1,
+       DIG_EXT_PORT_STAGE_2 = 2,
+       DIG_EXT_PORT_STAGE_3 = 3,
+       DIG_EXT_PORT_STAGE_MAX = 4,
+};
+
+enum dm_dig_connect {
+       DIG_STA_DISCONNECT = 0,
+       DIG_STA_CONNECT = 1,
+       DIG_STA_BEFORE_CONNECT = 2,
+       DIG_MULTISTA_DISCONNECT = 3,
+       DIG_MULTISTA_CONNECT = 4,
+       DIG_CONNECT_MAX
+};
+
+extern struct dig_t de_digtable;
+
+void rtl92d_dm_init(struct ieee80211_hw *hw);
+void rtl92d_dm_watchdog(struct ieee80211_hw *hw);
+void rtl92d_dm_init_edca_turbo(struct ieee80211_hw *hw);
+void rtl92d_dm_write_dig(struct ieee80211_hw *hw);
+void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw);
+void rtl92d_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
new file mode 100644 (file)
index 0000000..82f060b
--- /dev/null
@@ -0,0 +1,790 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "fw.h"
+#include "sw.h"
+
+static bool _rtl92d_is_fw_downloaded(struct rtl_priv *rtlpriv)
+{
+       return (rtl_read_dword(rtlpriv, REG_MCUFWDL) & MCUFWDL_RDY) ?
+               true : false;
+}
+
+static void _rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 tmp;
+
+       if (enable) {
+               tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
+               rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04);
+               tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
+               rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01);
+               tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2);
+               rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7);
+       } else {
+               tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL);
+               rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe);
+               /* Reserved for fw extension.
+                * 0x81[7] is used for mac0 status ,
+                * so don't write this reg here
+                * rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00);*/
+       }
+}
+
+static void _rtl92d_fw_block_write(struct ieee80211_hw *hw,
+                                  const u8 *buffer, u32 size)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 blocksize = sizeof(u32);
+       u8 *bufferptr = (u8 *) buffer;
+       u32 *pu4BytePtr = (u32 *) buffer;
+       u32 i, offset, blockCount, remainSize;
+
+       blockCount = size / blocksize;
+       remainSize = size % blocksize;
+       for (i = 0; i < blockCount; i++) {
+               offset = i * blocksize;
+               rtl_write_dword(rtlpriv, (FW_8192D_START_ADDRESS + offset),
+                               *(pu4BytePtr + i));
+       }
+       if (remainSize) {
+               offset = blockCount * blocksize;
+               bufferptr += offset;
+               for (i = 0; i < remainSize; i++) {
+                       rtl_write_byte(rtlpriv, (FW_8192D_START_ADDRESS +
+                                                offset + i), *(bufferptr + i));
+               }
+       }
+}
+
+static void _rtl92d_fw_page_write(struct ieee80211_hw *hw,
+                                 u32 page, const u8 *buffer, u32 size)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 value8;
+       u8 u8page = (u8) (page & 0x07);
+
+       value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
+       rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
+       _rtl92d_fw_block_write(hw, buffer, size);
+}
+
+static void _rtl92d_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
+{
+       u32 fwlen = *pfwlen;
+       u8 remain = (u8) (fwlen % 4);
+
+       remain = (remain == 0) ? 0 : (4 - remain);
+       while (remain > 0) {
+               pfwbuf[fwlen] = 0;
+               fwlen++;
+               remain--;
+       }
+       *pfwlen = fwlen;
+}
+
+static void _rtl92d_write_fw(struct ieee80211_hw *hw,
+                            enum version_8192d version, u8 *buffer, u32 size)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 *bufferPtr = (u8 *) buffer;
+       u32 pagenums, remainSize;
+       u32 page, offset;
+
+       RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size));
+       if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE)
+               _rtl92d_fill_dummy(bufferPtr, &size);
+       pagenums = size / FW_8192D_PAGE_SIZE;
+       remainSize = size % FW_8192D_PAGE_SIZE;
+       if (pagenums > 8) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("Page numbers should not greater then 8\n"));
+       }
+       for (page = 0; page < pagenums; page++) {
+               offset = page * FW_8192D_PAGE_SIZE;
+               _rtl92d_fw_page_write(hw, page, (bufferPtr + offset),
+                                     FW_8192D_PAGE_SIZE);
+       }
+       if (remainSize) {
+               offset = pagenums * FW_8192D_PAGE_SIZE;
+               page = pagenums;
+               _rtl92d_fw_page_write(hw, page, (bufferPtr + offset),
+                                     remainSize);
+       }
+}
+
+static int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 counter = 0;
+       u32 value32;
+
+       do {
+               value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
+       } while ((counter++ < FW_8192D_POLLING_TIMEOUT_COUNT) &&
+                (!(value32 & FWDL_ChkSum_rpt)));
+       if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
+                        value32));
+               return -EIO;
+       }
+       RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
+                ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
+       value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
+       value32 |= MCUFWDL_RDY;
+       rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
+       return 0;
+}
+
+void rtl92d_firmware_selfreset(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 u1b_tmp;
+       u8 delay = 100;
+
+       /* Set (REG_HMETFR + 3) to  0x20 is reset 8051 */
+       rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20);
+       u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
+       while (u1b_tmp & BIT(2)) {
+               delay--;
+               if (delay == 0)
+                       break;
+               udelay(50);
+               u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
+       }
+       RT_ASSERT((delay > 0), ("8051 reset failed!\n"));
+       RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
+                ("=====> 8051 reset success (%d) .\n", delay));
+}
+
+static int _rtl92d_fw_init(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u32 counter;
+
+       RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, ("FW already have download\n"));
+       /* polling for FW ready */
+       counter = 0;
+       do {
+               if (rtlhal->interfaceindex == 0) {
+                       if (rtl_read_byte(rtlpriv, FW_MAC0_READY) &
+                           MAC0_READY) {
+                               RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
+                                        ("Polling FW ready success!! "
+                                        "REG_MCUFWDL: 0x%x .\n",
+                                        rtl_read_byte(rtlpriv,
+                                        FW_MAC0_READY)));
+                               return 0;
+                       }
+                       udelay(5);
+               } else {
+                       if (rtl_read_byte(rtlpriv, FW_MAC1_READY) &
+                           MAC1_READY) {
+                               RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
+                                        ("Polling FW ready success!! "
+                                        "REG_MCUFWDL: 0x%x .\n",
+                                        rtl_read_byte(rtlpriv,
+                                                      FW_MAC1_READY)));
+                               return 0;
+                       }
+                       udelay(5);
+               }
+       } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
+
+       if (rtlhal->interfaceindex == 0) {
+               RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
+                        ("Polling FW ready fail!! MAC0 FW init not ready: "
+                        "0x%x .\n",
+                        rtl_read_byte(rtlpriv, FW_MAC0_READY)));
+       } else {
+               RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
+                        ("Polling FW ready fail!! MAC1 FW init not ready: "
+                        "0x%x .\n",
+                        rtl_read_byte(rtlpriv, FW_MAC1_READY)));
+       }
+       RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
+                ("Polling FW ready fail!! REG_MCUFWDL:0x%08ul .\n",
+                rtl_read_dword(rtlpriv, REG_MCUFWDL)));
+       return -1;
+}
+
+int rtl92d_download_fw(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 *pfwheader;
+       u8 *pfwdata;
+       u32 fwsize;
+       int err;
+       enum version_8192d version = rtlhal->version;
+       u8 value;
+       u32 count;
+       bool fw_downloaded = false, fwdl_in_process = false;
+       unsigned long flags;
+
+       if (!rtlhal->pfirmware)
+               return 1;
+       fwsize = rtlhal->fwsize;
+       pfwheader = (u8 *) rtlhal->pfirmware;
+       pfwdata = (u8 *) rtlhal->pfirmware;
+       rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader);
+       rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader);
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, (" FirmwareVersion(%d),"
+                "FirmwareSubVersion(%d), Signature(%#x)\n",
+                rtlhal->fw_version,    rtlhal->fw_subversion,
+                GET_FIRMWARE_HDR_SIGNATURE(pfwheader)));
+       if (IS_FW_HEADER_EXIST(pfwheader)) {
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                        ("Shift 32 bytes for FW header!!\n"));
+               pfwdata = pfwdata + 32;
+               fwsize = fwsize - 32;
+       }
+
+       spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
+       fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
+       if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
+               fwdl_in_process = true;
+       else
+               fwdl_in_process = false;
+       if (fw_downloaded) {
+               spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
+               goto exit;
+       } else if (fwdl_in_process) {
+               spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
+               for (count = 0; count < 5000; count++) {
+                       udelay(500);
+                       spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
+                       fw_downloaded = _rtl92d_is_fw_downloaded(rtlpriv);
+                       if ((rtl_read_byte(rtlpriv, 0x1f) & BIT(5)) == BIT(5))
+                               fwdl_in_process = true;
+                       else
+                               fwdl_in_process = false;
+                       spin_unlock_irqrestore(&globalmutex_for_fwdownload,
+                                              flags);
+                       if (fw_downloaded)
+                               goto exit;
+                       else if (!fwdl_in_process)
+                               break;
+                       else
+                               RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
+                                        ("Wait for another mac "
+                                        "download fw\n"));
+               }
+               spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
+               value = rtl_read_byte(rtlpriv, 0x1f);
+               value |= BIT(5);
+               rtl_write_byte(rtlpriv, 0x1f, value);
+               spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
+       } else {
+               value = rtl_read_byte(rtlpriv, 0x1f);
+               value |= BIT(5);
+               rtl_write_byte(rtlpriv, 0x1f, value);
+               spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
+       }
+
+       /* If 8051 is running in RAM code, driver should
+        * inform Fw to reset by itself, or it will cause
+        * download Fw fail.*/
+       /* 8051 RAM code */
+       if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) {
+               rtl92d_firmware_selfreset(hw);
+               rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
+       }
+       _rtl92d_enable_fw_download(hw, true);
+       _rtl92d_write_fw(hw, version, pfwdata, fwsize);
+       _rtl92d_enable_fw_download(hw, false);
+       spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
+       err = _rtl92d_fw_free_to_go(hw);
+       /* download fw over,clear 0x1f[5] */
+       value = rtl_read_byte(rtlpriv, 0x1f);
+       value &= (~BIT(5));
+       rtl_write_byte(rtlpriv, 0x1f, value);
+       spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
+       if (err) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("fw is not ready to run!\n"));
+               goto exit;
+       } else {
+               RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
+                        ("fw is ready to run!\n"));
+       }
+exit:
+       err = _rtl92d_fw_init(hw);
+       return err;
+}
+
+static bool _rtl92d_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 val_hmetfr;
+       bool result = false;
+
+       val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR);
+       if (((val_hmetfr >> boxnum) & BIT(0)) == 0)
+               result = true;
+       return result;
+}
+
+static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
+                             u8 element_id, u32 cmd_len, u8 *cmdbuffer)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       u8 boxnum;
+       u16 box_reg = 0, box_extreg = 0;
+       u8 u1b_tmp;
+       bool isfw_read = false;
+       u8 buf_index = 0;
+       bool bwrite_sucess = false;
+       u8 wait_h2c_limmit = 100;
+       u8 wait_writeh2c_limmit = 100;
+       u8 boxcontent[4], boxextcontent[2];
+       u32 h2c_waitcounter = 0;
+       unsigned long flag;
+       u8 idx;
+
+       if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) {
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+                        ("Return as RF is off!!!\n"));
+               return;
+       }
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n"));
+       while (true) {
+               spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
+               if (rtlhal->h2c_setinprogress) {
+                       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+                                ("H2C set in progress! Wait to set.."
+                                "element_id(%d).\n", element_id));
+
+                       while (rtlhal->h2c_setinprogress) {
+                               spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
+                                                      flag);
+                               h2c_waitcounter++;
+                               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+                                        ("Wait 100 us (%d times)...\n",
+                                        h2c_waitcounter));
+                               udelay(100);
+
+                               if (h2c_waitcounter > 1000)
+                                       return;
+
+                               spin_lock_irqsave(&rtlpriv->locks.h2c_lock,
+                                                 flag);
+                       }
+                       spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
+               } else {
+                       rtlhal->h2c_setinprogress = true;
+                       spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
+                       break;
+               }
+       }
+       while (!bwrite_sucess) {
+               wait_writeh2c_limmit--;
+               if (wait_writeh2c_limmit == 0) {
+                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                                ("Write H2C fail because no trigger "
+                                "for FW INT!\n"));
+                       break;
+               }
+               boxnum = rtlhal->last_hmeboxnum;
+               switch (boxnum) {
+               case 0:
+                       box_reg = REG_HMEBOX_0;
+                       box_extreg = REG_HMEBOX_EXT_0;
+                       break;
+               case 1:
+                       box_reg = REG_HMEBOX_1;
+                       box_extreg = REG_HMEBOX_EXT_1;
+                       break;
+               case 2:
+                       box_reg = REG_HMEBOX_2;
+                       box_extreg = REG_HMEBOX_EXT_2;
+                       break;
+               case 3:
+                       box_reg = REG_HMEBOX_3;
+                       box_extreg = REG_HMEBOX_EXT_3;
+                       break;
+               default:
+                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                                ("switch case not process\n"));
+                       break;
+               }
+               isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
+               while (!isfw_read) {
+                       wait_h2c_limmit--;
+                       if (wait_h2c_limmit == 0) {
+                               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+                                        ("Wating too long for FW read "
+                                        "clear HMEBox(%d)!\n", boxnum));
+                               break;
+                       }
+                       udelay(10);
+                       isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
+                       u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
+                       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+                                ("Wating for FW read clear HMEBox(%d)!!! "
+                                "0x1BF = %2x\n", boxnum, u1b_tmp));
+               }
+               if (!isfw_read) {
+                       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+                                ("Write H2C register BOX[%d] fail!!!!! "
+                                "Fw do not read.\n", boxnum));
+                       break;
+               }
+               memset(boxcontent, 0, sizeof(boxcontent));
+               memset(boxextcontent, 0, sizeof(boxextcontent));
+               boxcontent[0] = element_id;
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+                        ("Write element_id box_reg(%4x) = %2x\n",
+                        box_reg, element_id));
+               switch (cmd_len) {
+               case 1:
+                       boxcontent[0] &= ~(BIT(7));
+                       memcpy(boxcontent + 1, cmdbuffer + buf_index, 1);
+                       for (idx = 0; idx < 4; idx++)
+                               rtl_write_byte(rtlpriv, box_reg + idx,
+                                              boxcontent[idx]);
+                       break;
+               case 2:
+                       boxcontent[0] &= ~(BIT(7));
+                       memcpy(boxcontent + 1, cmdbuffer + buf_index, 2);
+                       for (idx = 0; idx < 4; idx++)
+                               rtl_write_byte(rtlpriv, box_reg + idx,
+                                              boxcontent[idx]);
+                       break;
+               case 3:
+                       boxcontent[0] &= ~(BIT(7));
+                       memcpy(boxcontent + 1, cmdbuffer + buf_index, 3);
+                       for (idx = 0; idx < 4; idx++)
+                               rtl_write_byte(rtlpriv, box_reg + idx,
+                                              boxcontent[idx]);
+                       break;
+               case 4:
+                       boxcontent[0] |= (BIT(7));
+                       memcpy(boxextcontent, cmdbuffer + buf_index, 2);
+                       memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 2);
+                       for (idx = 0; idx < 2; idx++)
+                               rtl_write_byte(rtlpriv, box_extreg + idx,
+                                              boxextcontent[idx]);
+                       for (idx = 0; idx < 4; idx++)
+                               rtl_write_byte(rtlpriv, box_reg + idx,
+                                              boxcontent[idx]);
+                       break;
+               case 5:
+                       boxcontent[0] |= (BIT(7));
+                       memcpy(boxextcontent, cmdbuffer + buf_index, 2);
+                       memcpy(boxcontent + 1, cmdbuffer + buf_index + 2, 3);
+                       for (idx = 0; idx < 2; idx++)
+                               rtl_write_byte(rtlpriv, box_extreg + idx,
+                                              boxextcontent[idx]);
+                       for (idx = 0; idx < 4; idx++)
+                               rtl_write_byte(rtlpriv, box_reg + idx,
+                                              boxcontent[idx]);
+                       break;
+               default:
+                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                               ("switch case not process\n"));
+                       break;
+               }
+               bwrite_sucess = true;
+               rtlhal->last_hmeboxnum = boxnum + 1;
+               if (rtlhal->last_hmeboxnum == 4)
+                       rtlhal->last_hmeboxnum = 0;
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+                        ("pHalData->last_hmeboxnum  = %d\n",
+                         rtlhal->last_hmeboxnum));
+       }
+       spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
+       rtlhal->h2c_setinprogress = false;
+       spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
+}
+
+void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
+                        u8 element_id, u32 cmd_len, u8 *cmdbuffer)
+{
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u32 tmp_cmdbuf[2];
+
+       if (rtlhal->fw_ready == false) {
+               RT_ASSERT(false, ("return H2C cmd because of Fw "
+                                 "download fail!!!\n"));
+               return;
+       }
+       memset(tmp_cmdbuf, 0, 8);
+       memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
+       _rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
+       return;
+}
+
+void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 u1_h2c_set_pwrmode[3] = { 0 };
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+       RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
+       SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
+       SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
+       SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
+                                             ppsc->reg_max_lps_awakeintvl);
+       RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
+                     "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
+                     u1_h2c_set_pwrmode, 3);
+       rtl92d_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
+}
+
+static bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw,
+                                   struct sk_buff *skb)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl8192_tx_ring *ring;
+       struct rtl_tx_desc *pdesc;
+       u8 idx = 0;
+       unsigned long flags;
+       struct sk_buff *pskb;
+
+       ring = &rtlpci->tx_ring[BEACON_QUEUE];
+       pskb = __skb_dequeue(&ring->queue);
+       if (pskb)
+               kfree_skb(pskb);
+       spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+       pdesc = &ring->desc[idx];
+       /* discard output from call below */
+       rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
+       rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
+       __skb_queue_tail(&ring->queue, skb);
+       spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+       rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
+       return true;
+}
+
+#define BEACON_PG              0       /*->1 */
+#define PSPOLL_PG              2
+#define NULL_PG                        3
+#define PROBERSP_PG            4       /*->5 */
+#define TOTAL_RESERVED_PKT_LEN 768
+
+static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {
+       /* page 0 beacon */
+       0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+       0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
+       0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
+       0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
+       0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
+       0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
+       0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
+       0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
+       0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
+       0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       /* page 1 beacon */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       /* page 2  ps-poll */
+       0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10,
+       0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+       0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       /* page 3  null */
+       0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
+       0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
+       0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+       0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       /* page 4  probe_resp */
+       0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10,
+       0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42,
+       0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00,
+       0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00,
+       0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69,
+       0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C,
+       0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96,
+       0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A,
+       0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C,
+       0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18,
+       0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02,
+       0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+       /* page 5  probe_resp */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct sk_buff *skb = NULL;
+       u32 totalpacketlen;
+       bool rtstatus;
+       u8 u1RsvdPageLoc[3] = { 0 };
+       bool dlok = false;
+       u8 *beacon;
+       u8 *p_pspoll;
+       u8 *nullfunc;
+       u8 *p_probersp;
+       /*---------------------------------------------------------
+                                               (1) beacon
+       ---------------------------------------------------------*/
+       beacon = &reserved_page_packet[BEACON_PG * 128];
+       SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr);
+       SET_80211_HDR_ADDRESS3(beacon, mac->bssid);
+       /*-------------------------------------------------------
+                                               (2) ps-poll
+       --------------------------------------------------------*/
+       p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
+       SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
+       SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
+       SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
+       SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
+       /*--------------------------------------------------------
+                                               (3) null data
+       ---------------------------------------------------------*/
+       nullfunc = &reserved_page_packet[NULL_PG * 128];
+       SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid);
+       SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr);
+       SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid);
+       SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG);
+       /*---------------------------------------------------------
+                                               (4) probe response
+       ----------------------------------------------------------*/
+       p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
+       SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
+       SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
+       SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
+       SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
+       totalpacketlen = TOTAL_RESERVED_PKT_LEN;
+       RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
+                     "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+                     &reserved_page_packet[0], totalpacketlen);
+       RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
+                     "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+                     u1RsvdPageLoc, 3);
+       skb = dev_alloc_skb(totalpacketlen);
+       memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet,
+               totalpacketlen);
+       rtstatus = _rtl92d_cmd_send_packet(hw, skb);
+
+       if (rtstatus)
+               dlok = true;
+       if (dlok) {
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                       ("Set RSVD page location to Fw.\n"));
+               RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
+                             "H2C_RSVDPAGE:\n", u1RsvdPageLoc, 3);
+               rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE,
+                       sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
+       } else
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+                       ("Set RSVD page location to Fw FAIL!!!!!!.\n"));
+}
+
+void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
+{
+       u8 u1_joinbssrpt_parm[1] = {0};
+
+       SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus);
+       rtl92d_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm);
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.h b/drivers/net/wireless/rtlwifi/rtl8192de/fw.h
new file mode 100644 (file)
index 0000000..0c4d489
--- /dev/null
@@ -0,0 +1,155 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92D__FW__H__
+#define __RTL92D__FW__H__
+
+#define FW_8192D_START_ADDRESS                 0x1000
+#define FW_8192D_PAGE_SIZE                             4096
+#define FW_8192D_POLLING_TIMEOUT_COUNT 1000
+
+#define IS_FW_HEADER_EXIST(_pfwhdr)    \
+               ((GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFF0) == 0x92C0 || \
+               (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFF0) == 0x88C0 ||  \
+               (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D0 ||  \
+               (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D1 ||  \
+               (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D2 ||  \
+               (GET_FIRMWARE_HDR_SIGNATURE(_pfwhdr) & 0xFFFF) == 0x92D3)
+
+/* Define a macro that takes an le32 word, converts it to host ordering,
+ * right shifts by a specified count, creates a mask of the specified
+ * bit count, and extracts that number of bits.
+ */
+
+#define SHIFT_AND_MASK_LE(__pdesc, __shift, __mask)            \
+       ((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \
+       BIT_LEN_MASK_32(__mask))
+
+/* Firmware Header(8-byte alinment required) */
+/* --- LONG WORD 0 ---- */
+#define GET_FIRMWARE_HDR_SIGNATURE(__fwhdr)            \
+       SHIFT_AND_MASK_LE(__fwhdr, 0, 16)
+#define GET_FIRMWARE_HDR_CATEGORY(__fwhdr)             \
+       SHIFT_AND_MASK_LE(__fwhdr, 16, 8)
+#define GET_FIRMWARE_HDR_FUNCTION(__fwhdr)             \
+       SHIFT_AND_MASK_LE(__fwhdr, 24, 8)
+#define GET_FIRMWARE_HDR_VERSION(__fwhdr)              \
+       SHIFT_AND_MASK_LE(__fwhdr + 4, 0, 16)
+#define GET_FIRMWARE_HDR_SUB_VER(__fwhdr)              \
+       SHIFT_AND_MASK_LE(__fwhdr + 4, 16, 8)
+#define GET_FIRMWARE_HDR_RSVD1(__fwhdr)                        \
+       SHIFT_AND_MASK_LE(__fwhdr + 4, 24, 8)
+
+/* --- LONG WORD 1 ---- */
+#define GET_FIRMWARE_HDR_MONTH(__fwhdr)                        \
+       SHIFT_AND_MASK_LE(__fwhdr + 8, 0, 8)
+#define GET_FIRMWARE_HDR_DATE(__fwhdr)                 \
+       SHIFT_AND_MASK_LE(__fwhdr + 8, 8, 8)
+#define GET_FIRMWARE_HDR_HOUR(__fwhdr)                 \
+       SHIFT_AND_MASK_LE(__fwhdr + 8, 16, 8)
+#define GET_FIRMWARE_HDR_MINUTE(__fwhdr)               \
+       SHIFT_AND_MASK_LE(__fwhdr + 8, 24, 8)
+#define GET_FIRMWARE_HDR_ROMCODE_SIZE(__fwhdr)         \
+       SHIFT_AND_MASK_LE(__fwhdr + 12, 0, 16)
+#define GET_FIRMWARE_HDR_RSVD2(__fwhdr)                        \
+       SHIFT_AND_MASK_LE(__fwhdr + 12, 16, 16)
+
+/* --- LONG WORD 2 ---- */
+#define GET_FIRMWARE_HDR_SVN_IDX(__fwhdr)              \
+       SHIFT_AND_MASK_LE(__fwhdr + 16, 0, 32)
+#define GET_FIRMWARE_HDR_RSVD3(__fwhdr)                        \
+       SHIFT_AND_MASK_LE(__fwhdr + 20, 0, 32)
+
+/* --- LONG WORD 3 ---- */
+#define GET_FIRMWARE_HDR_RSVD4(__fwhdr)                        \
+       SHIFT_AND_MASK_LE(__fwhdr + 24, 0, 32)
+#define GET_FIRMWARE_HDR_RSVD5(__fwhdr)                        \
+       SHIFT_AND_MASK_LE(__fwhdr + 28, 0, 32)
+
+#define pagenum_128(_len) \
+       (u32)(((_len) >> 7) + ((_len) & 0x7F ? 1 : 0))
+
+#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val)         \
+       SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
+#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val)     \
+       SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 0, 8, __val)
+#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val)        \
+       SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 2, 0, 8, __val)
+#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val)    \
+       SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
+#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val)    \
+       SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val)
+#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val)       \
+       SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 0, 8, __val)
+#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val)    \
+       SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 2, 0, 8, __val)
+
+struct rtl92d_firmware_header {
+       u16 signature;
+       u8 category;
+       u8 function;
+       u16 version;
+       u8 subversion;
+       u8 rsvd1;
+
+       u8 month;
+       u8 date;
+       u8 hour;
+       u8 minute;
+       u16 ramcodeSize;
+       u16 rsvd2;
+
+       u32 svnindex;
+       u32 rsvd3;
+
+       u32 rsvd4;
+       u32 rsvd5;
+};
+
+enum rtl8192d_h2c_cmd {
+       H2C_AP_OFFLOAD = 0,
+       H2C_SETPWRMODE = 1,
+       H2C_JOINBSSRPT = 2,
+       H2C_RSVDPAGE = 3,
+       H2C_RSSI_REPORT = 5,
+       H2C_RA_MASK = 6,
+       H2C_MAC_MODE_SEL = 9,
+       H2C_PWRM = 15,
+       MAX_H2CCMD
+};
+
+int rtl92d_download_fw(struct ieee80211_hw *hw);
+void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
+                        u32 cmd_len, u8 *p_cmdbuffer);
+void rtl92d_firmware_selfreset(struct ieee80211_hw *hw);
+void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
+void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
+void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
new file mode 100644 (file)
index 0000000..e833bbf
--- /dev/null
@@ -0,0 +1,2326 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../efuse.h"
+#include "../base.h"
+#include "../regd.h"
+#include "../cam.h"
+#include "../ps.h"
+#include "../pci.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "fw.h"
+#include "led.h"
+#include "sw.h"
+#include "hw.h"
+
+u32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset, u8 direct)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 value;
+
+       rtl_write_word(rtlpriv, REG_DBI_CTRL, (offset & 0xFFC));
+       rtl_write_byte(rtlpriv, REG_DBI_FLAG, BIT(1) | direct);
+       udelay(10);
+       value = rtl_read_dword(rtlpriv, REG_DBI_RDATA);
+       return value;
+}
+
+void rtl92de_write_dword_dbi(struct ieee80211_hw *hw,
+                            u16 offset, u32 value, u8 direct)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtl_write_word(rtlpriv, REG_DBI_CTRL, ((offset & 0xFFC) | 0xF000));
+       rtl_write_dword(rtlpriv, REG_DBI_WDATA, value);
+       rtl_write_byte(rtlpriv, REG_DBI_FLAG, BIT(0) | direct);
+}
+
+static void _rtl92de_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
+                                     u8 set_bits, u8 clear_bits)
+{
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpci->reg_bcn_ctrl_val |= set_bits;
+       rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
+       rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val);
+}
+
+static void _rtl92de_stop_tx_beacon(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 tmp1byte;
+
+       tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
+       rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
+       rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff);
+       rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
+       tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
+       tmp1byte &= ~(BIT(0));
+       rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
+}
+
+static void _rtl92de_resume_tx_beacon(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 tmp1byte;
+
+       tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
+       rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
+       rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0x0a);
+       rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
+       tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
+       tmp1byte |= BIT(0);
+       rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
+}
+
+static void _rtl92de_enable_bcn_sub_func(struct ieee80211_hw *hw)
+{
+       _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(1));
+}
+
+static void _rtl92de_disable_bcn_sub_func(struct ieee80211_hw *hw)
+{
+       _rtl92de_set_bcn_ctrl_reg(hw, BIT(1), 0);
+}
+
+void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       switch (variable) {
+       case HW_VAR_RCR:
+               *((u32 *) (val)) = rtlpci->receive_config;
+               break;
+       case HW_VAR_RF_STATE:
+               *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
+               break;
+       case HW_VAR_FWLPS_RF_ON:{
+               enum rf_pwrstate rfState;
+               u32 val_rcr;
+
+               rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
+                                             (u8 *) (&rfState));
+               if (rfState == ERFOFF) {
+                       *((bool *) (val)) = true;
+               } else {
+                       val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
+                       val_rcr &= 0x00070000;
+                       if (val_rcr)
+                               *((bool *) (val)) = false;
+                       else
+                               *((bool *) (val)) = true;
+               }
+               break;
+       }
+       case HW_VAR_FW_PSMODE_STATUS:
+               *((bool *) (val)) = ppsc->fw_current_inpsmode;
+               break;
+       case HW_VAR_CORRECT_TSF:{
+               u64 tsf;
+               u32 *ptsf_low = (u32 *)&tsf;
+               u32 *ptsf_high = ((u32 *)&tsf) + 1;
+
+               *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
+               *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
+               *((u64 *) (val)) = tsf;
+               break;
+       }
+       case HW_VAR_INT_MIGRATION:
+               *((bool *)(val)) = rtlpriv->dm.interrupt_migration;
+               break;
+       case HW_VAR_INT_AC:
+               *((bool *)(val)) = rtlpriv->dm.disable_tx_int;
+               break;
+       default:
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("switch case not process\n"));
+               break;
+       }
+}
+
+void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       u8 idx;
+
+       switch (variable) {
+       case HW_VAR_ETHER_ADDR:
+               for (idx = 0; idx < ETH_ALEN; idx++) {
+                       rtl_write_byte(rtlpriv, (REG_MACID + idx),
+                                      val[idx]);
+               }
+               break;
+       case HW_VAR_BASIC_RATE: {
+               u16 rate_cfg = ((u16 *) val)[0];
+               u8 rate_index = 0;
+
+               rate_cfg = rate_cfg & 0x15f;
+               if (mac->vendor == PEER_CISCO &&
+                   ((rate_cfg & 0x150) == 0))
+                       rate_cfg |= 0x01;
+               rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff);
+               rtl_write_byte(rtlpriv, REG_RRSR + 1,
+                              (rate_cfg >> 8) & 0xff);
+               while (rate_cfg > 0x1) {
+                       rate_cfg = (rate_cfg >> 1);
+                       rate_index++;
+               }
+               if (rtlhal->fw_version > 0xe)
+                       rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL,
+                                      rate_index);
+               break;
+       }
+       case HW_VAR_BSSID:
+               for (idx = 0; idx < ETH_ALEN; idx++) {
+                       rtl_write_byte(rtlpriv, (REG_BSSID + idx),
+                                      val[idx]);
+               }
+               break;
+       case HW_VAR_SIFS:
+               rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
+               rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
+               rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
+               rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
+               if (!mac->ht_enable)
+                       rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
+                                      0x0e0e);
+               else
+                       rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
+                                      *((u16 *) val));
+               break;
+       case HW_VAR_SLOT_TIME: {
+               u8 e_aci;
+
+               RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+                        ("HW_VAR_SLOT_TIME %x\n", val[0]));
+               rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
+               for (e_aci = 0; e_aci < AC_MAX; e_aci++)
+                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                                     HW_VAR_AC_PARAM,
+                                                     (u8 *) (&e_aci));
+               break;
+       }
+       case HW_VAR_ACK_PREAMBLE: {
+               u8 reg_tmp;
+               u8 short_preamble = (bool) (*(u8 *) val);
+
+               reg_tmp = (mac->cur_40_prime_sc) << 5;
+               if (short_preamble)
+                       reg_tmp |= 0x80;
+               rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp);
+               break;
+       }
+       case HW_VAR_AMPDU_MIN_SPACE: {
+               u8 min_spacing_to_set;
+               u8 sec_min_space;
+
+               min_spacing_to_set = *((u8 *) val);
+               if (min_spacing_to_set <= 7) {
+                       sec_min_space = 0;
+                       if (min_spacing_to_set < sec_min_space)
+                               min_spacing_to_set = sec_min_space;
+                       mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) |
+                                             min_spacing_to_set);
+                       *val = min_spacing_to_set;
+                       RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+                                ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
+                                mac->min_space_cfg));
+                       rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
+                                      mac->min_space_cfg);
+               }
+               break;
+       }
+       case HW_VAR_SHORTGI_DENSITY: {
+               u8 density_to_set;
+
+               density_to_set = *((u8 *) val);
+               mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg;
+               mac->min_space_cfg |= (density_to_set << 3);
+               RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+                        ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
+                        mac->min_space_cfg));
+               rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
+                              mac->min_space_cfg);
+               break;
+       }
+       case HW_VAR_AMPDU_FACTOR: {
+               u8 factor_toset;
+               u32 regtoSet;
+               u8 *ptmp_byte = NULL;
+               u8 index;
+
+               if (rtlhal->macphymode == DUALMAC_DUALPHY)
+                       regtoSet = 0xb9726641;
+               else if (rtlhal->macphymode == DUALMAC_SINGLEPHY)
+                       regtoSet = 0x66626641;
+               else
+                       regtoSet = 0xb972a841;
+               factor_toset = *((u8 *) val);
+               if (factor_toset <= 3) {
+                       factor_toset = (1 << (factor_toset + 2));
+                       if (factor_toset > 0xf)
+                               factor_toset = 0xf;
+                       for (index = 0; index < 4; index++) {
+                               ptmp_byte = (u8 *) (&regtoSet) + index;
+                               if ((*ptmp_byte & 0xf0) >
+                                   (factor_toset << 4))
+                                       *ptmp_byte = (*ptmp_byte & 0x0f)
+                                                | (factor_toset << 4);
+                               if ((*ptmp_byte & 0x0f) > factor_toset)
+                                       *ptmp_byte = (*ptmp_byte & 0xf0)
+                                                    | (factor_toset);
+                       }
+                       rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, regtoSet);
+                       RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+                                ("Set HW_VAR_AMPDU_FACTOR: %#x\n",
+                                factor_toset));
+               }
+               break;
+       }
+       case HW_VAR_AC_PARAM: {
+               u8 e_aci = *((u8 *) val);
+               rtl92d_dm_init_edca_turbo(hw);
+               if (rtlpci->acm_method != eAcmWay2_SW)
+                       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
+                                                     (u8 *) (&e_aci));
+               break;
+       }
+       case HW_VAR_ACM_CTRL: {
+               u8 e_aci = *((u8 *) val);
+               union aci_aifsn *p_aci_aifsn =
+                   (union aci_aifsn *)(&(mac->ac[0].aifs));
+               u8 acm = p_aci_aifsn->f.acm;
+               u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
+
+               acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ?  0x0 : 0x1);
+               if (acm) {
+                       switch (e_aci) {
+                       case AC0_BE:
+                               acm_ctrl |= ACMHW_BEQEN;
+                               break;
+                       case AC2_VI:
+                               acm_ctrl |= ACMHW_VIQEN;
+                               break;
+                       case AC3_VO:
+                               acm_ctrl |= ACMHW_VOQEN;
+                               break;
+                       default:
+                               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+                                        ("HW_VAR_ACM_CTRL acm set "
+                                        "failed: eACI is %d\n", acm));
+                               break;
+                       }
+               } else {
+                       switch (e_aci) {
+                       case AC0_BE:
+                               acm_ctrl &= (~ACMHW_BEQEN);
+                               break;
+                       case AC2_VI:
+                               acm_ctrl &= (~ACMHW_VIQEN);
+                               break;
+                       case AC3_VO:
+                               acm_ctrl &= (~ACMHW_VOQEN);
+                               break;
+                       default:
+                               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                                        ("switch case not process\n"));
+                               break;
+                       }
+               }
+               RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
+                        ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] "
+                        "Write 0x%X\n", acm_ctrl));
+               rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
+               break;
+       }
+       case HW_VAR_RCR:
+               rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]);
+               rtlpci->receive_config = ((u32 *) (val))[0];
+               break;
+       case HW_VAR_RETRY_LIMIT: {
+               u8 retry_limit = ((u8 *) (val))[0];
+
+               rtl_write_word(rtlpriv, REG_RL,
+                              retry_limit << RETRY_LIMIT_SHORT_SHIFT |
+                              retry_limit << RETRY_LIMIT_LONG_SHIFT);
+               break;
+       }
+       case HW_VAR_DUAL_TSF_RST:
+               rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
+               break;
+       case HW_VAR_EFUSE_BYTES:
+               rtlefuse->efuse_usedbytes = *((u16 *) val);
+               break;
+       case HW_VAR_EFUSE_USAGE:
+               rtlefuse->efuse_usedpercentage = *((u8 *) val);
+               break;
+       case HW_VAR_IO_CMD:
+               rtl92d_phy_set_io_cmd(hw, (*(enum io_type *)val));
+               break;
+       case HW_VAR_WPA_CONFIG:
+               rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val));
+               break;
+       case HW_VAR_SET_RPWM:
+               rtl92d_fill_h2c_cmd(hw, H2C_PWRM, 1, (u8 *) (val));
+               break;
+       case HW_VAR_H2C_FW_PWRMODE:
+               break;
+       case HW_VAR_FW_PSMODE_STATUS:
+               ppsc->fw_current_inpsmode = *((bool *) val);
+               break;
+       case HW_VAR_H2C_FW_JOINBSSRPT: {
+               u8 mstatus = (*(u8 *) val);
+               u8 tmp_regcr, tmp_reg422;
+               bool recover = false;
+
+               if (mstatus == RT_MEDIA_CONNECT) {
+                       rtlpriv->cfg->ops->set_hw_reg(hw,
+                                                     HW_VAR_AID, NULL);
+                       tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
+                       rtl_write_byte(rtlpriv, REG_CR + 1,
+                                      (tmp_regcr | BIT(0)));
+                       _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(3));
+                       _rtl92de_set_bcn_ctrl_reg(hw, BIT(4), 0);
+                       tmp_reg422 = rtl_read_byte(rtlpriv,
+                                                REG_FWHW_TXQ_CTRL + 2);
+                       if (tmp_reg422 & BIT(6))
+                               recover = true;
+                       rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
+                                      tmp_reg422 & (~BIT(6)));
+                       rtl92d_set_fw_rsvdpagepkt(hw, 0);
+                       _rtl92de_set_bcn_ctrl_reg(hw, BIT(3), 0);
+                       _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(4));
+                       if (recover)
+                               rtl_write_byte(rtlpriv,
+                                              REG_FWHW_TXQ_CTRL + 2,
+                                              tmp_reg422);
+                       rtl_write_byte(rtlpriv, REG_CR + 1,
+                                      (tmp_regcr & ~(BIT(0))));
+               }
+               rtl92d_set_fw_joinbss_report_cmd(hw, (*(u8 *) val));
+               break;
+       }
+       case HW_VAR_AID: {
+               u16 u2btmp;
+               u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
+               u2btmp &= 0xC000;
+               rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp |
+                              mac->assoc_id));
+               break;
+       }
+       case HW_VAR_CORRECT_TSF: {
+               u8 btype_ibss = ((u8 *) (val))[0];
+
+               if (btype_ibss == true)
+                       _rtl92de_stop_tx_beacon(hw);
+               _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(3));
+               rtl_write_dword(rtlpriv, REG_TSFTR,
+                               (u32) (mac->tsf & 0xffffffff));
+               rtl_write_dword(rtlpriv, REG_TSFTR + 4,
+                               (u32) ((mac->tsf >> 32) & 0xffffffff));
+               _rtl92de_set_bcn_ctrl_reg(hw, BIT(3), 0);
+               if (btype_ibss == true)
+                       _rtl92de_resume_tx_beacon(hw);
+
+               break;
+       }
+       case HW_VAR_INT_MIGRATION: {
+               bool int_migration = *(bool *) (val);
+
+               if (int_migration) {
+                       /* Set interrrupt migration timer and
+                        * corresponging Tx/Rx counter.
+                        * timer 25ns*0xfa0=100us for 0xf packets.
+                        * 0x306:Rx, 0x307:Tx */
+                       rtl_write_dword(rtlpriv, REG_INT_MIG, 0xfe000fa0);
+                       rtlpriv->dm.interrupt_migration = int_migration;
+               } else {
+                       /* Reset all interrupt migration settings. */
+                       rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
+                       rtlpriv->dm.interrupt_migration = int_migration;
+               }
+               break;
+       }
+       case HW_VAR_INT_AC: {
+               bool disable_ac_int = *((bool *) val);
+
+               /* Disable four ACs interrupts. */
+               if (disable_ac_int) {
+                       /* Disable VO, VI, BE and BK four AC interrupts
+                        * to gain more efficient CPU utilization.
+                        * When extremely highly Rx OK occurs,
+                        * we will disable Tx interrupts.
+                        */
+                       rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
+                                                RT_AC_INT_MASKS);
+                       rtlpriv->dm.disable_tx_int = disable_ac_int;
+               /* Enable four ACs interrupts. */
+               } else {
+                       rtlpriv->cfg->ops->update_interrupt_mask(hw,
+                                                RT_AC_INT_MASKS, 0);
+                       rtlpriv->dm.disable_tx_int = disable_ac_int;
+               }
+               break;
+       }
+       default:
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("switch case not process\n"));
+               break;
+       }
+}
+
+static bool _rtl92de_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       bool status = true;
+       long count = 0;
+       u32 value = _LLT_INIT_ADDR(address) |
+           _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
+
+       rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
+       do {
+               value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
+               if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
+                       break;
+               if (count > POLLING_LLT_THRESHOLD) {
+                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                                ("Failed to polling write LLT done at "
+                                 "address %d!\n", address));
+                       status = false;
+                       break;
+               }
+       } while (++count);
+       return status;
+}
+
+static bool _rtl92de_llt_table_init(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       unsigned short i;
+       u8 txpktbuf_bndy;
+       u8 maxPage;
+       bool status;
+       u32 value32; /* High+low page number */
+       u8 value8;       /* normal page number */
+
+       if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) {
+               maxPage = 255;
+               txpktbuf_bndy = 246;
+               value8 = 0;
+               value32 = 0x80bf0d29;
+       } else if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) {
+               maxPage = 127;
+               txpktbuf_bndy = 123;
+               value8 = 0;
+               value32 = 0x80750005;
+       }
+
+       /* Set reserved page for each queue */
+       /* 11.  RQPN 0x200[31:0] = 0x80BD1C1C */
+       /* load RQPN */
+       rtl_write_byte(rtlpriv, REG_RQPN_NPQ, value8);
+       rtl_write_dword(rtlpriv, REG_RQPN, value32);
+
+       /* 12.  TXRKTBUG_PG_BNDY 0x114[31:0] = 0x27FF00F6 */
+       /* TXRKTBUG_PG_BNDY */
+       rtl_write_dword(rtlpriv, REG_TRXFF_BNDY,
+                       (rtl_read_word(rtlpriv, REG_TRXFF_BNDY + 2) << 16 |
+                       txpktbuf_bndy));
+
+       /* 13.  TDECTRL[15:8] 0x209[7:0] = 0xF6 */
+       /* Beacon Head for TXDMA */
+       rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
+
+       /* 14.  BCNQ_PGBNDY 0x424[7:0] =  0xF6 */
+       /* BCNQ_PGBNDY */
+       rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
+       rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
+
+       /* 15.  WMAC_LBK_BF_HD 0x45D[7:0] =  0xF6 */
+       /* WMAC_LBK_BF_HD */
+       rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
+
+       /* Set Tx/Rx page size (Tx must be 128 Bytes, */
+       /* Rx can be 64,128,256,512,1024 bytes) */
+       /* 16.  PBP [7:0] = 0x11 */
+       /* TRX page size */
+       rtl_write_byte(rtlpriv, REG_PBP, 0x11);
+
+       /* 17.  DRV_INFO_SZ = 0x04 */
+       rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
+
+       /* 18.  LLT_table_init(Adapter);  */
+       for (i = 0; i < (txpktbuf_bndy - 1); i++) {
+               status = _rtl92de_llt_write(hw, i, i + 1);
+               if (true != status)
+                       return status;
+       }
+
+       /* end of list */
+       status = _rtl92de_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
+       if (true != status)
+               return status;
+
+       /* Make the other pages as ring buffer */
+       /* This ring buffer is used as beacon buffer if we */
+       /* config this MAC as two MAC transfer. */
+       /* Otherwise used as local loopback buffer.  */
+       for (i = txpktbuf_bndy; i < maxPage; i++) {
+               status = _rtl92de_llt_write(hw, i, (i + 1));
+               if (true != status)
+                       return status;
+       }
+
+       /* Let last entry point to the start entry of ring buffer */
+       status = _rtl92de_llt_write(hw, maxPage, txpktbuf_bndy);
+       if (true != status)
+               return status;
+
+       return true;
+}
+
+static void _rtl92de_gen_refresh_led_state(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
+
+       if (rtlpci->up_first_time)
+               return;
+       if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
+               rtl92de_sw_led_on(hw, pLed0);
+       else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
+               rtl92de_sw_led_on(hw, pLed0);
+       else
+               rtl92de_sw_led_off(hw, pLed0);
+}
+
+static bool _rtl92de_init_mac(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       unsigned char bytetmp;
+       unsigned short wordtmp;
+       u16 retry;
+
+       rtl92d_phy_set_poweron(hw);
+       /* Add for resume sequence of power domain according
+        * to power document V11. Chapter V.11....  */
+       /* 0.   RSV_CTRL 0x1C[7:0] = 0x00  */
+       /* unlock ISO/CLK/Power control register */
+       rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
+       rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x05);
+
+       /* 1.   AFE_XTAL_CTRL [7:0] = 0x0F  enable XTAL */
+       /* 2.   SPS0_CTRL 0x11[7:0] = 0x2b  enable SPS into PWM mode  */
+       /* 3.   delay (1ms) this is not necessary when initially power on */
+
+       /* C.   Resume Sequence */
+       /* a.   SPS0_CTRL 0x11[7:0] = 0x2b */
+       rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
+
+       /* b.   AFE_XTAL_CTRL [7:0] = 0x0F */
+       rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F);
+
+       /* c.   DRV runs power on init flow */
+
+       /* auto enable WLAN */
+       /* 4.   APS_FSMCO 0x04[8] = 1; wait till 0x04[8] = 0   */
+       /* Power On Reset for MAC Block */
+       bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0);
+       udelay(2);
+       rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
+       udelay(2);
+
+       /* 5.   Wait while 0x04[8] == 0 goto 2, otherwise goto 1 */
+       bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
+       udelay(50);
+       retry = 0;
+       while ((bytetmp & BIT(0)) && retry < 1000) {
+               retry++;
+               bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
+               udelay(50);
+       }
+
+       /* Enable Radio off, GPIO, and LED function */
+       /* 6.   APS_FSMCO 0x04[15:0] = 0x0012  when enable HWPDN */
+       rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x1012);
+
+       /* release RF digital isolation  */
+       /* 7.  SYS_ISO_CTRL 0x01[1]    = 0x0;  */
+       /*Set REG_SYS_ISO_CTRL 0x1=0x82 to prevent wake# problem. */
+       rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82);
+       udelay(2);
+
+       /* make sure that BB reset OK. */
+       /* rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); */
+
+       /* Disable REG_CR before enable it to assure reset */
+       rtl_write_word(rtlpriv, REG_CR, 0x0);
+
+       /* Release MAC IO register reset */
+       rtl_write_word(rtlpriv, REG_CR, 0x2ff);
+
+       /* clear stopping tx/rx dma   */
+       rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0x0);
+
+       /* rtl_write_word(rtlpriv,REG_CR+2, 0x2); */
+
+       /* System init */
+       /* 18.  LLT_table_init(Adapter);  */
+       if (_rtl92de_llt_table_init(hw) == false)
+               return false;
+
+       /* Clear interrupt and enable interrupt */
+       /* 19.  HISR 0x124[31:0] = 0xffffffff;  */
+       /*      HISRE 0x12C[7:0] = 0xFF */
+       rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
+       rtl_write_byte(rtlpriv, REG_HISRE, 0xff);
+
+       /* 20.  HIMR 0x120[31:0] |= [enable INT mask bit map];  */
+       /* 21.  HIMRE 0x128[7:0] = [enable INT mask bit map] */
+       /* The IMR should be enabled later after all init sequence
+        * is finished. */
+
+       /* 22.  PCIE configuration space configuration */
+       /* 23.  Ensure PCIe Device 0x80[15:0] = 0x0143 (ASPM+CLKREQ),  */
+       /*      and PCIe gated clock function is enabled.    */
+       /* PCIE configuration space will be written after
+        * all init sequence.(Or by BIOS) */
+
+       rtl92d_phy_config_maccoexist_rfpage(hw);
+
+       /* THe below section is not related to power document Vxx . */
+       /* This is only useful for driver and OS setting. */
+       /* -------------------Software Relative Setting---------------------- */
+       wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
+       wordtmp &= 0xf;
+       wordtmp |= 0xF771;
+       rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
+
+       /* Reported Tx status from HW for rate adaptive. */
+       /* This should be realtive to power on step 14. But in document V11  */
+       /* still not contain the description.!!! */
+       rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
+
+       /* Set Tx/Rx page size (Tx must be 128 Bytes,
+        * Rx can be 64,128,256,512,1024 bytes) */
+       /* rtl_write_byte(rtlpriv,REG_PBP, 0x11); */
+
+       /* Set RCR register */
+       rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
+       /* rtl_write_byte(rtlpriv,REG_RX_DRVINFO_SZ, 4); */
+
+       /*  Set TCR register */
+       rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
+
+       /* disable earlymode */
+       rtl_write_byte(rtlpriv, 0x4d0, 0x0);
+
+       /* Set TX/RX descriptor physical address(from OS API). */
+       rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
+                       rtlpci->tx_ring[BEACON_QUEUE].dma);
+       rtl_write_dword(rtlpriv, REG_MGQ_DESA, rtlpci->tx_ring[MGNT_QUEUE].dma);
+       rtl_write_dword(rtlpriv, REG_VOQ_DESA, rtlpci->tx_ring[VO_QUEUE].dma);
+       rtl_write_dword(rtlpriv, REG_VIQ_DESA, rtlpci->tx_ring[VI_QUEUE].dma);
+       rtl_write_dword(rtlpriv, REG_BEQ_DESA, rtlpci->tx_ring[BE_QUEUE].dma);
+       rtl_write_dword(rtlpriv, REG_BKQ_DESA, rtlpci->tx_ring[BK_QUEUE].dma);
+       rtl_write_dword(rtlpriv, REG_HQ_DESA, rtlpci->tx_ring[HIGH_QUEUE].dma);
+       /* Set RX Desc Address */
+       rtl_write_dword(rtlpriv, REG_RX_DESA,
+                       rtlpci->rx_ring[RX_MPDU_QUEUE].dma);
+
+       /* if we want to support 64 bit DMA, we should set it here,
+        * but now we do not support 64 bit DMA*/
+
+       rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x33);
+
+       /* Reset interrupt migration setting when initialization */
+       rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
+
+       /* Reconsider when to do this operation after asking HWSD. */
+       bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
+       rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6));
+       do {
+               retry++;
+               bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
+       } while ((retry < 200) && !(bytetmp & BIT(7)));
+
+       /* After MACIO reset,we must refresh LED state. */
+       _rtl92de_gen_refresh_led_state(hw);
+
+       /* Reset H2C protection register */
+       rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
+
+       return true;
+}
+
+static void _rtl92de_hw_configure(struct ieee80211_hw *hw)
+{
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 reg_bw_opmode = BW_OPMODE_20MHZ;
+       u32 reg_rrsr;
+
+       reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+       rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8);
+       rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
+       rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr);
+       rtl_write_byte(rtlpriv, REG_SLOT, 0x09);
+       rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0);
+       rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80);
+       rtl_write_word(rtlpriv, REG_RL, 0x0707);
+       rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802);
+       rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF);
+       rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
+       rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
+       rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
+       rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
+       /* Aggregation threshold */
+       if (rtlhal->macphymode == DUALMAC_DUALPHY)
+               rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb9726641);
+       else if (rtlhal->macphymode == DUALMAC_SINGLEPHY)
+               rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x66626641);
+       else
+               rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841);
+       rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2);
+       rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0x0a);
+       rtlpci->reg_bcn_ctrl_val = 0x1f;
+       rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val);
+       rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
+       rtl_write_byte(rtlpriv, REG_PIFS, 0x1C);
+       rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
+       rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
+       /* For throughput */
+       rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0x6666);
+       /* ACKTO for IOT issue. */
+       rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
+       /* Set Spec SIFS (used in NAV) */
+       rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010);
+       rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010);
+       /* Set SIFS for CCK */
+       rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010);
+       /* Set SIFS for OFDM */
+       rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010);
+       /* Set Multicast Address. */
+       rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff);
+       rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff);
+       switch (rtlpriv->phy.rf_type) {
+       case RF_1T2R:
+       case RF_1T1R:
+               rtlhal->minspace_cfg = (MAX_MSS_DENSITY_1T << 3);
+               break;
+       case RF_2T2R:
+       case RF_2T2R_GREEN:
+               rtlhal->minspace_cfg = (MAX_MSS_DENSITY_2T << 3);
+               break;
+       }
+}
+
+static void _rtl92de_enable_aspm_back_door(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+       rtl_write_byte(rtlpriv, 0x34b, 0x93);
+       rtl_write_word(rtlpriv, 0x350, 0x870c);
+       rtl_write_byte(rtlpriv, 0x352, 0x1);
+       if (ppsc->support_backdoor)
+               rtl_write_byte(rtlpriv, 0x349, 0x1b);
+       else
+               rtl_write_byte(rtlpriv, 0x349, 0x03);
+       rtl_write_word(rtlpriv, 0x350, 0x2718);
+       rtl_write_byte(rtlpriv, 0x352, 0x1);
+}
+
+void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 sec_reg_value;
+
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
+                 rtlpriv->sec.pairwise_enc_algorithm,
+                 rtlpriv->sec.group_enc_algorithm));
+       if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
+               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+                        ("not open hw encryption\n"));
+               return;
+       }
+       sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE;
+       if (rtlpriv->sec.use_defaultkey) {
+               sec_reg_value |= SCR_TXUSEDK;
+               sec_reg_value |= SCR_RXUSEDK;
+       }
+       sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
+       rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
+       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+                ("The SECR-value %x\n", sec_reg_value));
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
+}
+
+int rtl92de_hw_init(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       bool rtstatus = true;
+       u8 tmp_u1b;
+       int i;
+       int err;
+       unsigned long flags;
+
+       rtlpci->being_init_adapter = true;
+       rtlpci->init_ready = false;
+       spin_lock_irqsave(&globalmutex_for_power_and_efuse, flags);
+       /* we should do iqk after disable/enable */
+       rtl92d_phy_reset_iqk_result(hw);
+       /* rtlpriv->intf_ops->disable_aspm(hw); */
+       rtstatus = _rtl92de_init_mac(hw);
+       if (rtstatus != true) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n"));
+               err = 1;
+               spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags);
+               return err;
+       }
+       err = rtl92d_download_fw(hw);
+       spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags);
+       if (err) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+                        ("Failed to download FW. Init HW "
+                        "without FW..\n"));
+               err = 1;
+               rtlhal->fw_ready = false;
+       } else {
+               rtlhal->fw_ready = true;
+       }
+       rtlhal->last_hmeboxnum = 0;
+       rtlpriv->psc.fw_current_inpsmode = false;
+
+       tmp_u1b = rtl_read_byte(rtlpriv, 0x605);
+       tmp_u1b = tmp_u1b | 0x30;
+       rtl_write_byte(rtlpriv, 0x605, tmp_u1b);
+
+       if (rtlhal->earlymode_enable) {
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                        ("EarlyMode Enabled!!!\n"));
+
+               tmp_u1b = rtl_read_byte(rtlpriv, 0x4d0);
+               tmp_u1b = tmp_u1b | 0x1f;
+               rtl_write_byte(rtlpriv, 0x4d0, tmp_u1b);
+
+               rtl_write_byte(rtlpriv, 0x4d3, 0x80);
+
+               tmp_u1b = rtl_read_byte(rtlpriv, 0x605);
+               tmp_u1b = tmp_u1b | 0x40;
+               rtl_write_byte(rtlpriv, 0x605, tmp_u1b);
+       }
+
+       if (mac->rdg_en) {
+               rtl_write_byte(rtlpriv, REG_RD_CTRL, 0xff);
+               rtl_write_word(rtlpriv, REG_RD_NAV_NXT, 0x200);
+               rtl_write_byte(rtlpriv, REG_RD_RESP_PKT_TH, 0x05);
+       }
+
+       rtl92d_phy_mac_config(hw);
+       /* because last function modify RCR, so we update
+        * rcr var here, or TP will unstable for receive_config
+        * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx
+        * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252*/
+       rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
+       rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
+
+       rtl92d_phy_bb_config(hw);
+
+       rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
+       /* set before initialize RF */
+       rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf);
+
+       /* config RF */
+       rtl92d_phy_rf_config(hw);
+
+       /* After read predefined TXT, we must set BB/MAC/RF
+        * register as our requirement */
+       /* After load BB,RF params,we need do more for 92D. */
+       rtl92d_update_bbrf_configuration(hw);
+       /* set default value after initialize RF,  */
+       rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0);
+       rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
+                       RF_CHNLBW, BRFREGOFFSETMASK);
+       rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
+                       RF_CHNLBW, BRFREGOFFSETMASK);
+
+       /*---- Set CCK and OFDM Block "ON"----*/
+       if (rtlhal->current_bandtype == BAND_ON_2_4G)
+               rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
+       rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
+       if (rtlhal->interfaceindex == 0) {
+               /* RFPGA0_ANALOGPARAMETER2: cck clock select,
+                *  set to 20MHz by default */
+               rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) |
+                             BIT(11), 3);
+       } else {
+               /* Mac1 */
+               rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(11) |
+                             BIT(10), 3);
+       }
+
+       _rtl92de_hw_configure(hw);
+
+       /* reset hw sec */
+       rtl_cam_reset_all_entry(hw);
+       rtl92de_enable_hw_security_config(hw);
+
+       /* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct */
+       /* TX power index for different rate set. */
+       rtl92d_phy_get_hw_reg_originalvalue(hw);
+       rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel);
+
+       ppsc->rfpwr_state = ERFON;
+
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
+
+       _rtl92de_enable_aspm_back_door(hw);
+       /* rtlpriv->intf_ops->enable_aspm(hw); */
+
+       rtl92d_dm_init(hw);
+       rtlpci->being_init_adapter = false;
+
+       if (ppsc->rfpwr_state == ERFON) {
+               rtl92d_phy_lc_calibrate(hw);
+               /* 5G and 2.4G must wait sometime to let RF LO ready */
+               if (rtlhal->macphymode == DUALMAC_DUALPHY) {
+                       u32 tmp_rega;
+                       for (i = 0; i < 10000; i++) {
+                               udelay(MAX_STALL_TIME);
+
+                               tmp_rega = rtl_get_rfreg(hw,
+                                                 (enum radio_path)RF90_PATH_A,
+                                                 0x2a, BMASKDWORD);
+
+                               if (((tmp_rega & BIT(11)) == BIT(11)))
+                                       break;
+                       }
+               }
+       }
+       rtlpci->init_ready = true;
+       return err;
+}
+
+static enum version_8192d _rtl92de_read_chip_version(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       enum version_8192d version = VERSION_NORMAL_CHIP_92D_SINGLEPHY;
+       u32 value32;
+
+       value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
+       if (!(value32 & 0x000f0000)) {
+               version = VERSION_TEST_CHIP_92D_SINGLEPHY;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("TEST CHIP!!!\n"));
+       } else {
+               version = VERSION_NORMAL_CHIP_92D_SINGLEPHY;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Normal CHIP!!!\n"));
+       }
+       return version;
+}
+
+static int _rtl92de_set_media_status(struct ieee80211_hw *hw,
+                                    enum nl80211_iftype type)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 bt_msr = rtl_read_byte(rtlpriv, MSR);
+       enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
+       u8 bcnfunc_enable;
+
+       bt_msr &= 0xfc;
+
+       if (type == NL80211_IFTYPE_UNSPECIFIED ||
+           type == NL80211_IFTYPE_STATION) {
+               _rtl92de_stop_tx_beacon(hw);
+               _rtl92de_enable_bcn_sub_func(hw);
+       } else if (type == NL80211_IFTYPE_ADHOC ||
+               type == NL80211_IFTYPE_AP) {
+               _rtl92de_resume_tx_beacon(hw);
+               _rtl92de_disable_bcn_sub_func(hw);
+       } else {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+                        ("Set HW_VAR_MEDIA_STATUS: No such media "
+                        "status(%x).\n", type));
+       }
+       bcnfunc_enable = rtl_read_byte(rtlpriv, REG_BCN_CTRL);
+       switch (type) {
+       case NL80211_IFTYPE_UNSPECIFIED:
+               bt_msr |= MSR_NOLINK;
+               ledaction = LED_CTL_LINK;
+               bcnfunc_enable &= 0xF7;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("Set Network type to NO LINK!\n"));
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               bt_msr |= MSR_ADHOC;
+               bcnfunc_enable |= 0x08;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("Set Network type to Ad Hoc!\n"));
+               break;
+       case NL80211_IFTYPE_STATION:
+               bt_msr |= MSR_INFRA;
+               ledaction = LED_CTL_LINK;
+               bcnfunc_enable &= 0xF7;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("Set Network type to STA!\n"));
+               break;
+       case NL80211_IFTYPE_AP:
+               bt_msr |= MSR_AP;
+               bcnfunc_enable |= 0x08;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("Set Network type to AP!\n"));
+               break;
+       default:
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("Network type %d not support!\n", type));
+               return 1;
+               break;
+
+       }
+       rtl_write_byte(rtlpriv, REG_CR + 2, bt_msr);
+       rtlpriv->cfg->ops->led_control(hw, ledaction);
+       if ((bt_msr & 0xfc) == MSR_AP)
+               rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
+       else
+               rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
+       return 0;
+}
+
+void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       u32 reg_rcr = rtlpci->receive_config;
+
+       if (rtlpriv->psc.rfpwr_state != ERFON)
+               return;
+       if (check_bssid == true) {
+               reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
+               _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(4));
+       } else if (check_bssid == false) {
+               reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
+               _rtl92de_set_bcn_ctrl_reg(hw, BIT(4), 0);
+               rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
+       }
+}
+
+int rtl92de_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (_rtl92de_set_media_status(hw, type))
+               return -EOPNOTSUPP;
+
+       /* check bssid */
+       if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
+               if (type != NL80211_IFTYPE_AP)
+                       rtl92de_set_check_bssid(hw, true);
+       } else {
+               rtl92de_set_check_bssid(hw, false);
+       }
+       return 0;
+}
+
+/* do iqk or reload iqk */
+/* windows just rtl92d_phy_reload_iqk_setting in set channel,
+ * but it's very strict for time sequence so we add
+ * rtl92d_phy_reload_iqk_setting here */
+void rtl92d_linked_set_reg(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 indexforchannel;
+       u8 channel = rtlphy->current_channel;
+
+       indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel);
+       if (!rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done) {
+               RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_DMESG,
+                               ("Do IQK for channel:%d.\n", channel));
+               rtl92d_phy_iq_calibrate(hw);
+       }
+}
+
+/* don't set REG_EDCA_BE_PARAM here because
+ * mac80211 will send pkt when scan */
+void rtl92de_set_qos(struct ieee80211_hw *hw, int aci)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       rtl92d_dm_init_edca_turbo(hw);
+       return;
+       switch (aci) {
+       case AC1_BK:
+               rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
+               break;
+       case AC0_BE:
+               break;
+       case AC2_VI:
+               rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
+               break;
+       case AC3_VO:
+               rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
+               break;
+       default:
+               RT_ASSERT(false, ("invalid aci: %d !\n", aci));
+               break;
+       }
+}
+
+void rtl92de_enable_interrupt(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
+       rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
+       rtlpci->irq_enabled = true;
+}
+
+void rtl92de_disable_interrupt(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED);
+       rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED);
+       rtlpci->irq_enabled = false;
+       synchronize_irq(rtlpci->pdev->irq);
+}
+
+static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 u1b_tmp;
+       unsigned long flags;
+
+       rtlpriv->intf_ops->enable_aspm(hw);
+       rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);
+       rtl_set_bbreg(hw, RFPGA0_XCD_RFPARAMETER, BIT(3), 0);
+       rtl_set_bbreg(hw, RFPGA0_XCD_RFPARAMETER, BIT(15), 0);
+
+       /* 0x20:value 05-->04 */
+       rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x04);
+
+       /*  ==== Reset digital sequence   ====== */
+       rtl92d_firmware_selfreset(hw);
+
+       /* f.   SYS_FUNC_EN 0x03[7:0]=0x51 reset MCU, MAC register, DCORE */
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51);
+
+       /* g.   MCUFWDL 0x80[1:0]=0 reset MCU ready status */
+       rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
+
+       /*  ==== Pull GPIO PIN to balance level and LED control ====== */
+
+       /* h.     GPIO_PIN_CTRL 0x44[31:0]=0x000  */
+       rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000);
+
+       /* i.    Value = GPIO_PIN_CTRL[7:0] */
+       u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL);
+
+       /* j.    GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); */
+       /* write external PIN level  */
+       rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL,
+                       0x00FF0000 | (u1b_tmp << 8));
+
+       /* k.   GPIO_MUXCFG 0x42 [15:0] = 0x0780 */
+       rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790);
+
+       /* l.   LEDCFG 0x4C[15:0] = 0x8080 */
+       rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080);
+
+       /*  ==== Disable analog sequence === */
+
+       /* m.   AFE_PLL_CTRL[7:0] = 0x80  disable PLL */
+       rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80);
+
+       /* n.   SPS0_CTRL 0x11[7:0] = 0x22  enter PFM mode */
+       rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);
+
+       /* o.   AFE_XTAL_CTRL 0x24[7:0] = 0x0E  disable XTAL, if No BT COEX */
+       rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e);
+
+       /* p.   RSV_CTRL 0x1C[7:0] = 0x0E lock ISO/CLK/Power control register */
+       rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
+
+       /*  ==== interface into suspend === */
+
+       /* q.   APS_FSMCO[15:8] = 0x58 PCIe suspend mode */
+       /* According to power document V11, we need to set this */
+       /* value as 0x18. Otherwise, we may not L0s sometimes. */
+       /* This indluences power consumption. Bases on SD1's test, */
+       /* set as 0x00 do not affect power current. And if it */
+       /* is set as 0x18, they had ever met auto load fail problem. */
+       rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10);
+
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                ("In PowerOff,reg0x%x=%X\n", REG_SPS0_CTRL,
+                 rtl_read_byte(rtlpriv, REG_SPS0_CTRL)));
+       /* r.   Note: for PCIe interface, PON will not turn */
+       /* off m-bias and BandGap in PCIe suspend mode.  */
+
+       /* 0x17[7] 1b': power off in process  0b' : power off over */
+       if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) {
+               spin_lock_irqsave(&globalmutex_power, flags);
+               u1b_tmp = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS);
+               u1b_tmp &= (~BIT(7));
+               rtl_write_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS, u1b_tmp);
+               spin_unlock_irqrestore(&globalmutex_power, flags);
+       }
+
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<=======\n"));
+}
+
+void rtl92de_card_disable(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       enum nl80211_iftype opmode;
+
+       mac->link_state = MAC80211_NOLINK;
+       opmode = NL80211_IFTYPE_UNSPECIFIED;
+       _rtl92de_set_media_status(hw, opmode);
+
+       if (rtlpci->driver_is_goingto_unload ||
+           ppsc->rfoff_reason > RF_CHANGE_BY_PS)
+               rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
+       RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+       /* Power sequence for each MAC. */
+       /* a. stop tx DMA  */
+       /* b. close RF */
+       /* c. clear rx buf */
+       /* d. stop rx DMA */
+       /* e.  reset MAC */
+
+       /* a. stop tx DMA */
+       rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFE);
+       udelay(50);
+
+       /* b. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue */
+
+       /* c. ========RF OFF sequence==========  */
+       /* 0x88c[23:20] = 0xf. */
+       rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf);
+       rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00);
+
+       /* APSD_CTRL 0x600[7:0] = 0x40 */
+       rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
+
+       /* Close antenna 0,0xc04,0xd04 */
+       rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0);
+       rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0);
+
+       /*  SYS_FUNC_EN 0x02[7:0] = 0xE2   reset BB state machine */
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+
+       /* Mac0 can not do Global reset. Mac1 can do. */
+       /* SYS_FUNC_EN 0x02[7:0] = 0xE0  reset BB state machine  */
+       if (rtlpriv->rtlhal.interfaceindex == 1)
+               rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0);
+       udelay(50);
+
+       /* d.  stop tx/rx dma before disable REG_CR (0x100) to fix */
+       /* dma hang issue when disable/enable device.  */
+       rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xff);
+       udelay(50);
+       rtl_write_byte(rtlpriv, REG_CR, 0x0);
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==> Do power off.......\n"));
+       if (rtl92d_phy_check_poweroff(hw))
+               _rtl92de_poweroff_adapter(hw);
+       return;
+}
+
+void rtl92de_interrupt_recognized(struct ieee80211_hw *hw,
+                                 u32 *p_inta, u32 *p_intb)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
+       rtl_write_dword(rtlpriv, ISR, *p_inta);
+
+       /*
+        * *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1];
+        * rtl_write_dword(rtlpriv, ISR + 4, *p_intb);
+        */
+}
+
+void rtl92de_set_beacon_related_registers(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       u16 bcn_interval, atim_window;
+
+       bcn_interval = mac->beacon_interval;
+       atim_window = 2;
+       /*rtl92de_disable_interrupt(hw);  */
+       rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
+       rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
+       rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
+       rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x20);
+       if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G)
+               rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x30);
+       else
+               rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x20);
+       rtl_write_byte(rtlpriv, 0x606, 0x30);
+}
+
+void rtl92de_set_beacon_interval(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       u16 bcn_interval = mac->beacon_interval;
+
+       RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
+                ("beacon_interval:%d\n", bcn_interval));
+       /* rtl92de_disable_interrupt(hw); */
+       rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
+       /* rtl92de_enable_interrupt(hw); */
+}
+
+void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw,
+                                  u32 add_msr, u32 rm_msr)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
+                ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
+       if (add_msr)
+               rtlpci->irq_mask[0] |= add_msr;
+       if (rm_msr)
+               rtlpci->irq_mask[0] &= (~rm_msr);
+       rtl92de_disable_interrupt(hw);
+       rtl92de_enable_interrupt(hw);
+}
+
+static void _rtl92de_readpowervalue_fromprom(struct txpower_info *pwrinfo,
+                                u8 *rom_content, bool autoLoadfail)
+{
+       u32 rfpath, eeaddr, group, offset1, offset2;
+       u8 i;
+
+       memset(pwrinfo, 0, sizeof(struct txpower_info));
+       if (autoLoadfail) {
+               for (group = 0; group < CHANNEL_GROUP_MAX; group++) {
+                       for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) {
+                               if (group < CHANNEL_GROUP_MAX_2G) {
+                                       pwrinfo->cck_index[rfpath][group] =
+                                           EEPROM_DEFAULT_TXPOWERLEVEL_2G;
+                                       pwrinfo->ht40_1sindex[rfpath][group] =
+                                           EEPROM_DEFAULT_TXPOWERLEVEL_2G;
+                               } else {
+                                       pwrinfo->ht40_1sindex[rfpath][group] =
+                                           EEPROM_DEFAULT_TXPOWERLEVEL_5G;
+                               }
+                               pwrinfo->ht40_2sindexdiff[rfpath][group] =
+                                   EEPROM_DEFAULT_HT40_2SDIFF;
+                               pwrinfo->ht20indexdiff[rfpath][group] =
+                                   EEPROM_DEFAULT_HT20_DIFF;
+                               pwrinfo->ofdmindexdiff[rfpath][group] =
+                                   EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF;
+                               pwrinfo->ht40maxoffset[rfpath][group] =
+                                   EEPROM_DEFAULT_HT40_PWRMAXOFFSET;
+                               pwrinfo->ht20maxoffset[rfpath][group] =
+                                   EEPROM_DEFAULT_HT20_PWRMAXOFFSET;
+                       }
+               }
+               for (i = 0; i < 3; i++) {
+                       pwrinfo->tssi_a[i] = EEPROM_DEFAULT_TSSI;
+                       pwrinfo->tssi_b[i] = EEPROM_DEFAULT_TSSI;
+               }
+               return;
+       }
+
+       /* Maybe autoload OK,buf the tx power index value is not filled.
+        * If we find it, we set it to default value. */
+       for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) {
+               for (group = 0; group < CHANNEL_GROUP_MAX_2G; group++) {
+                       eeaddr = EEPROM_CCK_TX_PWR_INX_2G + (rfpath * 3)
+                                + group;
+                       pwrinfo->cck_index[rfpath][group] =
+                                       (rom_content[eeaddr] == 0xFF) ?
+                                            (eeaddr > 0x7B ?
+                                            EEPROM_DEFAULT_TXPOWERLEVEL_5G :
+                                            EEPROM_DEFAULT_TXPOWERLEVEL_2G) :
+                                            rom_content[eeaddr];
+               }
+       }
+       for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) {
+               for (group = 0; group < CHANNEL_GROUP_MAX; group++) {
+                       offset1 = group / 3;
+                       offset2 = group % 3;
+                       eeaddr = EEPROM_HT40_1S_TX_PWR_INX_2G + (rfpath * 3) +
+                           offset2 + offset1 * 21;
+                       pwrinfo->ht40_1sindex[rfpath][group] =
+                           (rom_content[eeaddr] == 0xFF) ? (eeaddr > 0x7B ?
+                                            EEPROM_DEFAULT_TXPOWERLEVEL_5G :
+                                            EEPROM_DEFAULT_TXPOWERLEVEL_2G) :
+                                                rom_content[eeaddr];
+               }
+       }
+       /* These just for 92D efuse offset. */
+       for (group = 0; group < CHANNEL_GROUP_MAX; group++) {
+               for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) {
+                       int base1 = EEPROM_HT40_2S_TX_PWR_INX_DIFF_2G;
+
+                       offset1 = group / 3;
+                       offset2 = group % 3;
+
+                       if (rom_content[base1 + offset2 + offset1 * 21] != 0xFF)
+                               pwrinfo->ht40_2sindexdiff[rfpath][group] =
+                                   (rom_content[base1 +
+                                    offset2 + offset1 * 21] >> (rfpath * 4))
+                                    & 0xF;
+                       else
+                               pwrinfo->ht40_2sindexdiff[rfpath][group] =
+                                   EEPROM_DEFAULT_HT40_2SDIFF;
+                       if (rom_content[EEPROM_HT20_TX_PWR_INX_DIFF_2G + offset2
+                           + offset1 * 21] != 0xFF)
+                               pwrinfo->ht20indexdiff[rfpath][group] =
+                                   (rom_content[EEPROM_HT20_TX_PWR_INX_DIFF_2G
+                                   + offset2 + offset1 * 21] >> (rfpath * 4))
+                                   & 0xF;
+                       else
+                               pwrinfo->ht20indexdiff[rfpath][group] =
+                                   EEPROM_DEFAULT_HT20_DIFF;
+                       if (rom_content[EEPROM_OFDM_TX_PWR_INX_DIFF_2G + offset2
+                           + offset1 * 21] != 0xFF)
+                               pwrinfo->ofdmindexdiff[rfpath][group] =
+                                   (rom_content[EEPROM_OFDM_TX_PWR_INX_DIFF_2G
+                                    + offset2 + offset1 * 21] >> (rfpath * 4))
+                                    & 0xF;
+                       else
+                               pwrinfo->ofdmindexdiff[rfpath][group] =
+                                   EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF;
+                       if (rom_content[EEPROM_HT40_MAX_PWR_OFFSET_2G + offset2
+                           + offset1 * 21] != 0xFF)
+                               pwrinfo->ht40maxoffset[rfpath][group] =
+                                   (rom_content[EEPROM_HT40_MAX_PWR_OFFSET_2G
+                                   + offset2 + offset1 * 21] >> (rfpath * 4))
+                                   & 0xF;
+                       else
+                               pwrinfo->ht40maxoffset[rfpath][group] =
+                                   EEPROM_DEFAULT_HT40_PWRMAXOFFSET;
+                       if (rom_content[EEPROM_HT20_MAX_PWR_OFFSET_2G + offset2
+                           + offset1 * 21] != 0xFF)
+                               pwrinfo->ht20maxoffset[rfpath][group] =
+                                   (rom_content[EEPROM_HT20_MAX_PWR_OFFSET_2G +
+                                    offset2 + offset1 * 21] >> (rfpath * 4)) &
+                                    0xF;
+                       else
+                               pwrinfo->ht20maxoffset[rfpath][group] =
+                                   EEPROM_DEFAULT_HT20_PWRMAXOFFSET;
+               }
+       }
+       if (rom_content[EEPROM_TSSI_A_5G] != 0xFF) {
+               /* 5GL */
+               pwrinfo->tssi_a[0] = rom_content[EEPROM_TSSI_A_5G] & 0x3F;
+               pwrinfo->tssi_b[0] = rom_content[EEPROM_TSSI_B_5G] & 0x3F;
+               /* 5GM */
+               pwrinfo->tssi_a[1] = rom_content[EEPROM_TSSI_AB_5G] & 0x3F;
+               pwrinfo->tssi_b[1] =
+                   (rom_content[EEPROM_TSSI_AB_5G] & 0xC0) >> 6 |
+                   (rom_content[EEPROM_TSSI_AB_5G + 1] & 0x0F) << 2;
+               /* 5GH */
+               pwrinfo->tssi_a[2] = (rom_content[EEPROM_TSSI_AB_5G + 1] &
+                                     0xF0) >> 4 |
+                   (rom_content[EEPROM_TSSI_AB_5G + 2] & 0x03) << 4;
+               pwrinfo->tssi_b[2] = (rom_content[EEPROM_TSSI_AB_5G + 2] &
+                                     0xFC) >> 2;
+       } else {
+               for (i = 0; i < 3; i++) {
+                       pwrinfo->tssi_a[i] = EEPROM_DEFAULT_TSSI;
+                       pwrinfo->tssi_b[i] = EEPROM_DEFAULT_TSSI;
+               }
+       }
+}
+
+static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw,
+                                      bool autoload_fail, u8 *hwinfo)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct txpower_info pwrinfo;
+       u8 tempval[2], i, pwr, diff;
+       u32 ch, rfPath, group;
+
+       _rtl92de_readpowervalue_fromprom(&pwrinfo, hwinfo, autoload_fail);
+       if (!autoload_fail) {
+               /* bit0~2 */
+               rtlefuse->eeprom_regulatory = (hwinfo[EEPROM_RF_OPT1] & 0x7);
+               rtlefuse->eeprom_thermalmeter =
+                        hwinfo[EEPROM_THERMAL_METER] & 0x1f;
+               rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_K];
+               tempval[0] = hwinfo[EEPROM_IQK_DELTA] & 0x03;
+               tempval[1] = (hwinfo[EEPROM_LCK_DELTA] & 0x0C) >> 2;
+               rtlefuse->txpwr_fromeprom = true;
+               if (IS_92D_D_CUT(rtlpriv->rtlhal.version)) {
+                       rtlefuse->internal_pa_5g[0] =
+                                !((hwinfo[EEPROM_TSSI_A_5G] &
+                                BIT(6)) >> 6);
+                       rtlefuse->internal_pa_5g[1] =
+                                !((hwinfo[EEPROM_TSSI_B_5G] &
+                                BIT(6)) >> 6);
+                       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                                ("Is D cut,Internal PA0 %d Internal PA1 %d\n",
+                                 rtlefuse->internal_pa_5g[0],
+                                 rtlefuse->internal_pa_5g[1]))
+               }
+               rtlefuse->eeprom_c9 = hwinfo[EEPROM_RF_OPT6];
+               rtlefuse->eeprom_cc = hwinfo[EEPROM_RF_OPT7];
+       } else {
+               rtlefuse->eeprom_regulatory = 0;
+               rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
+               rtlefuse->crystalcap = EEPROM_DEFAULT_CRYSTALCAP;
+               tempval[0] = tempval[1] = 3;
+       }
+
+       /* Use default value to fill parameters if
+        * efuse is not filled on some place. */
+
+       /* ThermalMeter from EEPROM */
+       if (rtlefuse->eeprom_thermalmeter < 0x06 ||
+           rtlefuse->eeprom_thermalmeter > 0x1c)
+               rtlefuse->eeprom_thermalmeter = 0x12;
+       rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
+
+       /* check XTAL_K */
+       if (rtlefuse->crystalcap == 0xFF)
+               rtlefuse->crystalcap = 0;
+       if (rtlefuse->eeprom_regulatory > 3)
+               rtlefuse->eeprom_regulatory = 0;
+
+       for (i = 0; i < 2; i++) {
+               switch (tempval[i]) {
+               case 0:
+                       tempval[i] = 5;
+                       break;
+               case 1:
+                       tempval[i] = 4;
+                       break;
+               case 2:
+                       tempval[i] = 3;
+                       break;
+               case 3:
+               default:
+                       tempval[i] = 0;
+                       break;
+               }
+       }
+
+       rtlefuse->delta_iqk = tempval[0];
+       if (tempval[1] > 0)
+               rtlefuse->delta_lck = tempval[1] - 1;
+       if (rtlefuse->eeprom_c9 == 0xFF)
+               rtlefuse->eeprom_c9 = 0x00;
+       RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
+                ("EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory));
+       RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
+                ("ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter));
+       RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
+                ("CrystalCap = 0x%x\n", rtlefuse->crystalcap));
+       RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
+                ("Delta_IQK = 0x%x Delta_LCK = 0x%x\n", rtlefuse->delta_iqk,
+                rtlefuse->delta_lck));
+
+       for (rfPath = 0; rfPath < RF6052_MAX_PATH; rfPath++) {
+               for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
+                       group = rtl92d_get_chnlgroup_fromarray((u8) ch);
+                       if (ch < CHANNEL_MAX_NUMBER_2G)
+                               rtlefuse->txpwrlevel_cck[rfPath][ch] =
+                                   pwrinfo.cck_index[rfPath][group];
+                       rtlefuse->txpwrlevel_ht40_1s[rfPath][ch] =
+                                   pwrinfo.ht40_1sindex[rfPath][group];
+                       rtlefuse->txpwr_ht20diff[rfPath][ch] =
+                                   pwrinfo.ht20indexdiff[rfPath][group];
+                       rtlefuse->txpwr_legacyhtdiff[rfPath][ch] =
+                                   pwrinfo.ofdmindexdiff[rfPath][group];
+                       rtlefuse->pwrgroup_ht20[rfPath][ch] =
+                                   pwrinfo.ht20maxoffset[rfPath][group];
+                       rtlefuse->pwrgroup_ht40[rfPath][ch] =
+                                   pwrinfo.ht40maxoffset[rfPath][group];
+                       pwr = pwrinfo.ht40_1sindex[rfPath][group];
+                       diff = pwrinfo.ht40_2sindexdiff[rfPath][group];
+                       rtlefuse->txpwrlevel_ht40_2s[rfPath][ch] =
+                                   (pwr > diff) ? (pwr - diff) : 0;
+               }
+       }
+}
+
+static void _rtl92de_read_macphymode_from_prom(struct ieee80211_hw *hw,
+                                              u8 *content)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 macphy_crvalue = content[EEPROM_MAC_FUNCTION];
+
+       if (macphy_crvalue & BIT(3)) {
+               rtlhal->macphymode = SINGLEMAC_SINGLEPHY;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                        ("MacPhyMode SINGLEMAC_SINGLEPHY\n"));
+       } else {
+               rtlhal->macphymode = DUALMAC_DUALPHY;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                        ("MacPhyMode DUALMAC_DUALPHY\n"));
+       }
+}
+
+static void _rtl92de_read_macphymode_and_bandtype(struct ieee80211_hw *hw,
+                                                 u8 *content)
+{
+       _rtl92de_read_macphymode_from_prom(hw, content);
+       rtl92d_phy_config_macphymode(hw);
+       rtl92d_phy_config_macphymode_info(hw);
+}
+
+static void _rtl92de_efuse_update_chip_version(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       enum version_8192d chipver = rtlpriv->rtlhal.version;
+       u8 cutvalue[2];
+       u16 chipvalue;
+
+       rtlpriv->intf_ops->read_efuse_byte(hw, EEPROME_CHIP_VERSION_H,
+                                          &cutvalue[1]);
+       rtlpriv->intf_ops->read_efuse_byte(hw, EEPROME_CHIP_VERSION_L,
+                                          &cutvalue[0]);
+       chipvalue = (cutvalue[1] << 8) | cutvalue[0];
+       switch (chipvalue) {
+       case 0xAA55:
+               chipver |= CHIP_92D_C_CUT;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("C-CUT!!!\n"));
+               break;
+       case 0x9966:
+               chipver |= CHIP_92D_D_CUT;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("D-CUT!!!\n"));
+               break;
+       default:
+               chipver |= CHIP_92D_D_CUT;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("Unkown CUT!\n"));
+               break;
+       }
+       rtlpriv->rtlhal.version = chipver;
+}
+
+static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u16 i, usvalue;
+       u8 hwinfo[HWSET_MAX_SIZE];
+       u16 eeprom_id;
+       unsigned long flags;
+
+       if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
+               spin_lock_irqsave(&globalmutex_for_power_and_efuse, flags);
+               rtl_efuse_shadow_map_update(hw);
+               _rtl92de_efuse_update_chip_version(hw);
+               spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags);
+               memcpy((void *)hwinfo, (void *)&rtlefuse->efuse_map
+                      [EFUSE_INIT_MAP][0],
+                      HWSET_MAX_SIZE);
+       } else if (rtlefuse->epromtype == EEPROM_93C46) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("RTL819X Not boot from eeprom, check it !!"));
+       }
+       RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
+                     hwinfo, HWSET_MAX_SIZE);
+
+       eeprom_id = *((u16 *)&hwinfo[0]);
+       if (eeprom_id != RTL8190_EEPROM_ID) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+                        ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
+               rtlefuse->autoload_failflag = true;
+       } else {
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+               rtlefuse->autoload_failflag = false;
+       }
+       if (rtlefuse->autoload_failflag == true) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("RTL819X Not boot from eeprom, check it !!"));
+               return;
+       }
+       rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
+       _rtl92de_read_macphymode_and_bandtype(hw, hwinfo);
+
+       /* VID, DID  SE     0xA-D */
+       rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
+       rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
+       rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID];
+       rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID];
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                ("EEPROMId = 0x%4x\n", eeprom_id));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid));
+
+       /* Read Permanent MAC address */
+       if (rtlhal->interfaceindex == 0) {
+               for (i = 0; i < 6; i += 2) {
+                       usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR_MAC0_92D + i];
+                       *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
+               }
+       } else {
+               for (i = 0; i < 6; i += 2) {
+                       usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR_MAC1_92D + i];
+                       *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
+               }
+       }
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR,
+                                     rtlefuse->dev_addr);
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+                (MAC_FMT "\n", MAC_ARG(rtlefuse->dev_addr)));
+       _rtl92de_read_txpower_info(hw, rtlefuse->autoload_failflag, hwinfo);
+
+       /* Read Channel Plan */
+       switch (rtlhal->bandset) {
+       case BAND_ON_2_4G:
+               rtlefuse->channel_plan = COUNTRY_CODE_TELEC;
+               break;
+       case BAND_ON_5G:
+               rtlefuse->channel_plan = COUNTRY_CODE_FCC;
+               break;
+       case BAND_ON_BOTH:
+               rtlefuse->channel_plan = COUNTRY_CODE_FCC;
+               break;
+       default:
+               rtlefuse->channel_plan = COUNTRY_CODE_FCC;
+               break;
+       }
+       rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
+       rtlefuse->txpwr_fromeprom = true;
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid));
+}
+
+void rtl92de_read_eeprom_info(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 tmp_u1b;
+
+       rtlhal->version = _rtl92de_read_chip_version(hw);
+       tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
+       rtlefuse->autoload_status = tmp_u1b;
+       if (tmp_u1b & BIT(4)) {
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n"));
+               rtlefuse->epromtype = EEPROM_93C46;
+       } else {
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n"));
+               rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
+       }
+       if (tmp_u1b & BIT(5)) {
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+
+               rtlefuse->autoload_failflag = false;
+               _rtl92de_read_adapter_info(hw);
+       } else {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
+       }
+       return;
+}
+
+static void rtl92de_update_hal_rate_table(struct ieee80211_hw *hw,
+                                         struct ieee80211_sta *sta)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u32 ratr_value;
+       u8 ratr_index = 0;
+       u8 nmode = mac->ht_enable;
+       u8 mimo_ps = IEEE80211_SMPS_OFF;
+       u16 shortgi_rate;
+       u32 tmp_ratr_value;
+       u8 curtxbw_40mhz = mac->bw_40;
+       u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+                                                       1 : 0;
+       u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+                                                       1 : 0;
+       enum wireless_mode wirelessmode = mac->mode;
+
+       if (rtlhal->current_bandtype == BAND_ON_5G)
+               ratr_value = sta->supp_rates[1] << 4;
+       else
+               ratr_value = sta->supp_rates[0];
+       ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+                      sta->ht_cap.mcs.rx_mask[0] << 12);
+       switch (wirelessmode) {
+       case WIRELESS_MODE_A:
+               ratr_value &= 0x00000FF0;
+               break;
+       case WIRELESS_MODE_B:
+               if (ratr_value & 0x0000000c)
+                       ratr_value &= 0x0000000d;
+               else
+                       ratr_value &= 0x0000000f;
+               break;
+       case WIRELESS_MODE_G:
+               ratr_value &= 0x00000FF5;
+               break;
+       case WIRELESS_MODE_N_24G:
+       case WIRELESS_MODE_N_5G:
+               nmode = 1;
+               if (mimo_ps == IEEE80211_SMPS_STATIC) {
+                       ratr_value &= 0x0007F005;
+               } else {
+                       u32 ratr_mask;
+
+                       if (get_rf_type(rtlphy) == RF_1T2R ||
+                           get_rf_type(rtlphy) == RF_1T1R) {
+                               ratr_mask = 0x000ff005;
+                       } else {
+                               ratr_mask = 0x0f0ff005;
+                       }
+
+                       ratr_value &= ratr_mask;
+               }
+               break;
+       default:
+               if (rtlphy->rf_type == RF_1T2R)
+                       ratr_value &= 0x000ff0ff;
+               else
+                       ratr_value &= 0x0f0ff0ff;
+
+               break;
+       }
+       ratr_value &= 0x0FFFFFFF;
+       if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) ||
+           (!curtxbw_40mhz && curshortgi_20mhz))) {
+               ratr_value |= 0x10000000;
+               tmp_ratr_value = (ratr_value >> 12);
+               for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
+                       if ((1 << shortgi_rate) & tmp_ratr_value)
+                               break;
+               }
+               shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
+                   (shortgi_rate << 4) | (shortgi_rate);
+       }
+       rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
+       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
+                ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)));
+}
+
+static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw,
+               struct ieee80211_sta *sta, u8 rssi_level)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_sta_info *sta_entry = NULL;
+       u32 ratr_bitmap;
+       u8 ratr_index;
+       u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+                                                       ? 1 : 0;
+       u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+                                                       1 : 0;
+       u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+                                                       1 : 0;
+       enum wireless_mode wirelessmode = 0;
+       bool shortgi = false;
+       u32 value[2];
+       u8 macid = 0;
+       u8 mimo_ps = IEEE80211_SMPS_OFF;
+
+       sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+       mimo_ps = sta_entry->mimo_ps;
+       wirelessmode = sta_entry->wireless_mode;
+       if (mac->opmode == NL80211_IFTYPE_STATION)
+               curtxbw_40mhz = mac->bw_40;
+       else if (mac->opmode == NL80211_IFTYPE_AP ||
+               mac->opmode == NL80211_IFTYPE_ADHOC)
+               macid = sta->aid + 1;
+
+       if (rtlhal->current_bandtype == BAND_ON_5G)
+               ratr_bitmap = sta->supp_rates[1] << 4;
+       else
+               ratr_bitmap = sta->supp_rates[0];
+       ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+                       sta->ht_cap.mcs.rx_mask[0] << 12);
+       switch (wirelessmode) {
+       case WIRELESS_MODE_B:
+               ratr_index = RATR_INX_WIRELESS_B;
+               if (ratr_bitmap & 0x0000000c)
+                       ratr_bitmap &= 0x0000000d;
+               else
+                       ratr_bitmap &= 0x0000000f;
+               break;
+       case WIRELESS_MODE_G:
+               ratr_index = RATR_INX_WIRELESS_GB;
+
+               if (rssi_level == 1)
+                       ratr_bitmap &= 0x00000f00;
+               else if (rssi_level == 2)
+                       ratr_bitmap &= 0x00000ff0;
+               else
+                       ratr_bitmap &= 0x00000ff5;
+               break;
+       case WIRELESS_MODE_A:
+               ratr_index = RATR_INX_WIRELESS_G;
+               ratr_bitmap &= 0x00000ff0;
+               break;
+       case WIRELESS_MODE_N_24G:
+       case WIRELESS_MODE_N_5G:
+               if (wirelessmode == WIRELESS_MODE_N_24G)
+                       ratr_index = RATR_INX_WIRELESS_NGB;
+               else
+                       ratr_index = RATR_INX_WIRELESS_NG;
+               if (mimo_ps == IEEE80211_SMPS_STATIC) {
+                       if (rssi_level == 1)
+                               ratr_bitmap &= 0x00070000;
+                       else if (rssi_level == 2)
+                               ratr_bitmap &= 0x0007f000;
+                       else
+                               ratr_bitmap &= 0x0007f005;
+               } else {
+                       if (rtlphy->rf_type == RF_1T2R ||
+                           rtlphy->rf_type == RF_1T1R) {
+                               if (curtxbw_40mhz) {
+                                       if (rssi_level == 1)
+                                               ratr_bitmap &= 0x000f0000;
+                                       else if (rssi_level == 2)
+                                               ratr_bitmap &= 0x000ff000;
+                                       else
+                                               ratr_bitmap &= 0x000ff015;
+                               } else {
+                                       if (rssi_level == 1)
+                                               ratr_bitmap &= 0x000f0000;
+                                       else if (rssi_level == 2)
+                                               ratr_bitmap &= 0x000ff000;
+                                       else
+                                               ratr_bitmap &= 0x000ff005;
+                               }
+                       } else {
+                               if (curtxbw_40mhz) {
+                                       if (rssi_level == 1)
+                                               ratr_bitmap &= 0x0f0f0000;
+                                       else if (rssi_level == 2)
+                                               ratr_bitmap &= 0x0f0ff000;
+                                       else
+                                               ratr_bitmap &= 0x0f0ff015;
+                               } else {
+                                       if (rssi_level == 1)
+                                               ratr_bitmap &= 0x0f0f0000;
+                                       else if (rssi_level == 2)
+                                               ratr_bitmap &= 0x0f0ff000;
+                                       else
+                                               ratr_bitmap &= 0x0f0ff005;
+                               }
+                       }
+               }
+               if ((curtxbw_40mhz && curshortgi_40mhz) ||
+                   (!curtxbw_40mhz && curshortgi_20mhz)) {
+
+                       if (macid == 0)
+                               shortgi = true;
+                       else if (macid == 1)
+                               shortgi = false;
+               }
+               break;
+       default:
+               ratr_index = RATR_INX_WIRELESS_NGB;
+
+               if (rtlphy->rf_type == RF_1T2R)
+                       ratr_bitmap &= 0x000ff0ff;
+               else
+                       ratr_bitmap &= 0x0f0ff0ff;
+               break;
+       }
+
+       value[0] = (ratr_bitmap & 0x0fffffff) | (ratr_index << 28);
+       value[1] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
+       RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
+                ("ratr_bitmap :%x value0:%x value1:%x\n",
+                 ratr_bitmap, value[0], value[1]));
+       rtl92d_fill_h2c_cmd(hw, H2C_RA_MASK, 5, (u8 *) value);
+       if (macid != 0)
+               sta_entry->ratr_index = ratr_index;
+}
+
+void rtl92de_update_hal_rate_tbl(struct ieee80211_hw *hw,
+               struct ieee80211_sta *sta, u8 rssi_level)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (rtlpriv->dm.useramask)
+               rtl92de_update_hal_rate_mask(hw, sta, rssi_level);
+       else
+               rtl92de_update_hal_rate_table(hw, sta);
+}
+
+void rtl92de_update_channel_access_setting(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       u16 sifs_timer;
+
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
+                                     (u8 *)&mac->slot_time);
+       if (!mac->ht_enable)
+               sifs_timer = 0x0a0a;
+       else
+               sifs_timer = 0x1010;
+       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
+}
+
+bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       enum rf_pwrstate e_rfpowerstate_toset;
+       u8 u1tmp;
+       bool actuallyset = false;
+       unsigned long flag;
+
+       if (rtlpci->being_init_adapter)
+               return false;
+       if (ppsc->swrf_processing)
+               return false;
+       spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+       if (ppsc->rfchange_inprogress) {
+               spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+               return false;
+       } else {
+               ppsc->rfchange_inprogress = true;
+               spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+       }
+       rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv,
+                         REG_MAC_PINMUX_CFG) & ~(BIT(3)));
+       u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL);
+       e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF;
+       if ((ppsc->hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) {
+               RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+                        ("GPIOChangeRF  - HW Radio ON, RF ON\n"));
+               e_rfpowerstate_toset = ERFON;
+               ppsc->hwradiooff = false;
+               actuallyset = true;
+       } else if ((ppsc->hwradiooff == false)
+               && (e_rfpowerstate_toset == ERFOFF)) {
+               RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+                        ("GPIOChangeRF  - HW Radio OFF, RF OFF\n"));
+               e_rfpowerstate_toset = ERFOFF;
+               ppsc->hwradiooff = true;
+               actuallyset = true;
+       }
+       if (actuallyset) {
+               spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+               ppsc->rfchange_inprogress = false;
+               spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+       } else {
+               if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
+                       RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+               spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+               ppsc->rfchange_inprogress = false;
+               spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+       }
+       *valid = 1;
+       return !ppsc->hwradiooff;
+}
+
+void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
+                    u8 *p_macaddr, bool is_group, u8 enc_algo,
+                    bool is_wepkey, bool clear_all)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u8 *macaddr = p_macaddr;
+       u32 entry_id;
+       bool is_pairwise = false;
+       static u8 cam_const_addr[4][6] = {
+               {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+               {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+               {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
+       };
+       static u8 cam_const_broad[] = {
+               0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+       };
+
+       if (clear_all) {
+               u8 idx;
+               u8 cam_offset = 0;
+               u8 clear_number = 5;
+               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
+               for (idx = 0; idx < clear_number; idx++) {
+                       rtl_cam_mark_invalid(hw, cam_offset + idx);
+                       rtl_cam_empty_entry(hw, cam_offset + idx);
+
+                       if (idx < 5) {
+                               memset(rtlpriv->sec.key_buf[idx], 0,
+                                      MAX_KEY_LEN);
+                               rtlpriv->sec.key_len[idx] = 0;
+                       }
+               }
+       } else {
+               switch (enc_algo) {
+               case WEP40_ENCRYPTION:
+                       enc_algo = CAM_WEP40;
+                       break;
+               case WEP104_ENCRYPTION:
+                       enc_algo = CAM_WEP104;
+                       break;
+               case TKIP_ENCRYPTION:
+                       enc_algo = CAM_TKIP;
+                       break;
+               case AESCCMP_ENCRYPTION:
+                       enc_algo = CAM_AES;
+                       break;
+               default:
+                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
+                                               "not process\n"));
+                       enc_algo = CAM_TKIP;
+                       break;
+               }
+               if (is_wepkey || rtlpriv->sec.use_defaultkey) {
+                       macaddr = cam_const_addr[key_index];
+                       entry_id = key_index;
+               } else {
+                       if (is_group) {
+                               macaddr = cam_const_broad;
+                               entry_id = key_index;
+                       } else {
+                               if (mac->opmode == NL80211_IFTYPE_AP) {
+                                       entry_id = rtl_cam_get_free_entry(hw,
+                                                                p_macaddr);
+                                       if (entry_id >=  TOTAL_CAM_ENTRY) {
+                                               RT_TRACE(rtlpriv, COMP_SEC,
+                                                        DBG_EMERG, ("Can not "
+                                                        "find free hw security"
+                                                        " cam entry\n"));
+                                               return;
+                                       }
+                               } else {
+                                       entry_id = CAM_PAIRWISE_KEY_POSITION;
+                               }
+                               key_index = PAIRWISE_KEYIDX;
+                               is_pairwise = true;
+                       }
+               }
+               if (rtlpriv->sec.key_len[key_index] == 0) {
+                       RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+                                ("delete one entry, entry_id is %d\n",
+                                entry_id));
+                       if (mac->opmode == NL80211_IFTYPE_AP)
+                               rtl_cam_del_entry(hw, p_macaddr);
+                       rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
+               } else {
+                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+                                ("The insert KEY length is %d\n",
+                                 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
+                       RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+                                ("The insert KEY  is %x %x\n",
+                                 rtlpriv->sec.key_buf[0][0],
+                                 rtlpriv->sec.key_buf[0][1]));
+                       RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+                                ("add one entry\n"));
+                       if (is_pairwise) {
+                               RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
+                                             "Pairwiase Key content :",
+                                             rtlpriv->sec.pairwise_key,
+                                             rtlpriv->
+                                             sec.key_len[PAIRWISE_KEYIDX]);
+                               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+                                        ("set Pairwiase key\n"));
+                               rtl_cam_add_one_entry(hw, macaddr, key_index,
+                                                     entry_id, enc_algo,
+                                                     CAM_CONFIG_NO_USEDK,
+                                                     rtlpriv->
+                                                     sec.key_buf[key_index]);
+                       } else {
+                               RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+                                        ("set group key\n"));
+                               if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+                                       rtl_cam_add_one_entry(hw,
+                                               rtlefuse->dev_addr,
+                                               PAIRWISE_KEYIDX,
+                                               CAM_PAIRWISE_KEY_POSITION,
+                                               enc_algo, CAM_CONFIG_NO_USEDK,
+                                               rtlpriv->sec.key_buf[entry_id]);
+                               }
+                               rtl_cam_add_one_entry(hw, macaddr, key_index,
+                                               entry_id, enc_algo,
+                                               CAM_CONFIG_NO_USEDK,
+                                               rtlpriv->sec.key_buf
+                                               [entry_id]);
+                       }
+               }
+       }
+}
+
+void rtl92de_suspend(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtlpriv->rtlhal.macphyctl_reg = rtl_read_byte(rtlpriv,
+               REG_MAC_PHY_CTRL_NORMAL);
+}
+
+void rtl92de_resume(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL,
+                      rtlpriv->rtlhal.macphyctl_reg);
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h
new file mode 100644 (file)
index 0000000..ad44ffa
--- /dev/null
@@ -0,0 +1,66 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92DE_HW_H__
+#define __RTL92DE_HW_H__
+
+void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
+void rtl92de_read_eeprom_info(struct ieee80211_hw *hw);
+void rtl92de_interrupt_recognized(struct ieee80211_hw *hw,
+                                 u32 *p_inta, u32 *p_intb);
+int rtl92de_hw_init(struct ieee80211_hw *hw);
+void rtl92de_card_disable(struct ieee80211_hw *hw);
+void rtl92de_enable_interrupt(struct ieee80211_hw *hw);
+void rtl92de_disable_interrupt(struct ieee80211_hw *hw);
+int rtl92de_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
+void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
+void rtl92de_set_qos(struct ieee80211_hw *hw, int aci);
+void rtl92de_set_beacon_related_registers(struct ieee80211_hw *hw);
+void rtl92de_set_beacon_interval(struct ieee80211_hw *hw);
+void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw,
+                                  u32 add_msr, u32 rm_msr);
+void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
+void rtl92de_update_hal_rate_tbl(struct ieee80211_hw *hw,
+                                struct ieee80211_sta *sta, u8 rssi_level);
+void rtl92de_update_channel_access_setting(struct ieee80211_hw *hw);
+bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
+void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw);
+void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
+                    u8 *p_macaddr, bool is_group, u8 enc_algo,
+                    bool is_wepkey, bool clear_all);
+
+extern void rtl92de_write_dword_dbi(struct ieee80211_hw *hw, u16 offset,
+                                   u32 value, u8 direct);
+extern u32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset,
+                                 u8 direct);
+void rtl92de_suspend(struct ieee80211_hw *hw);
+void rtl92de_resume(struct ieee80211_hw *hw);
+void rtl92d_linked_set_reg(struct ieee80211_hw *hw);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.c b/drivers/net/wireless/rtlwifi/rtl8192de/led.c
new file mode 100644 (file)
index 0000000..719972c
--- /dev/null
@@ -0,0 +1,159 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "reg.h"
+#include "led.h"
+
+static void _rtl92ce_init_led(struct ieee80211_hw *hw,
+                             struct rtl_led *pled, enum rtl_led_pin ledpin)
+{
+       pled->hw = hw;
+       pled->ledpin = ledpin;
+       pled->ledon = false;
+}
+
+void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
+{
+       u8 ledcfg;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
+                ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+
+       switch (pled->ledpin) {
+       case LED_PIN_GPIO0:
+               break;
+       case LED_PIN_LED0:
+               ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
+
+               if ((rtlpriv->efuse.eeprom_did == 0x8176) ||
+                       (rtlpriv->efuse.eeprom_did == 0x8193))
+                       /* BIT7 of REG_LEDCFG2 should be set to
+                        * make sure we could emit the led2. */
+                       rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) |
+                                      BIT(7) | BIT(5) | BIT(6));
+               else
+                       rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0xf0) |
+                                      BIT(7) | BIT(5));
+               break;
+       case LED_PIN_LED1:
+               ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
+
+               rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5));
+               break;
+       default:
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("switch case not process\n"));
+               break;
+       }
+       pled->ledon = true;
+}
+
+void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       u8 ledcfg;
+
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
+                ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+
+       ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
+
+       switch (pled->ledpin) {
+       case LED_PIN_GPIO0:
+               break;
+       case LED_PIN_LED0:
+               ledcfg &= 0xf0;
+               if (pcipriv->ledctl.led_opendrain == true)
+                       rtl_write_byte(rtlpriv, REG_LEDCFG2,
+                                      (ledcfg | BIT(1) | BIT(5) | BIT(6)));
+               else
+                       rtl_write_byte(rtlpriv, REG_LEDCFG2,
+                                      (ledcfg | BIT(3) | BIT(5) | BIT(6)));
+               break;
+       case LED_PIN_LED1:
+               ledcfg &= 0x0f;
+               rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3)));
+               break;
+       default:
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("switch case not process\n"));
+               break;
+       }
+       pled->ledon = false;
+}
+
+void rtl92de_init_sw_leds(struct ieee80211_hw *hw)
+{
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
+       _rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
+}
+
+static void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
+                                   enum led_ctl_mode ledaction)
+{
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
+       switch (ledaction) {
+       case LED_CTL_POWER_ON:
+       case LED_CTL_LINK:
+       case LED_CTL_NO_LINK:
+               rtl92de_sw_led_on(hw, pLed0);
+               break;
+       case LED_CTL_POWER_OFF:
+               rtl92de_sw_led_off(hw, pLed0);
+               break;
+       default:
+               break;
+       }
+}
+
+void rtl92de_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+       if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
+           (ledaction == LED_CTL_TX ||
+            ledaction == LED_CTL_RX ||
+            ledaction == LED_CTL_SITE_SURVEY ||
+            ledaction == LED_CTL_LINK ||
+            ledaction == LED_CTL_NO_LINK ||
+            ledaction == LED_CTL_START_TO_LINK ||
+            ledaction == LED_CTL_POWER_ON)) {
+               return;
+       }
+       RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", ledaction));
+
+       _rtl92ce_sw_led_control(hw, ledaction);
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.h b/drivers/net/wireless/rtlwifi/rtl8192de/led.h
new file mode 100644 (file)
index 0000000..57f4a3c
--- /dev/null
@@ -0,0 +1,38 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92CE_LED_H__
+#define __RTL92CE_LED_H__
+
+void rtl92de_init_sw_leds(struct ieee80211_hw *hw);
+void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
+void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
+void rtl92de_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
new file mode 100644 (file)
index 0000000..97fb6ca
--- /dev/null
@@ -0,0 +1,3837 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "../ps.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "rf.h"
+#include "dm.h"
+#include "table.h"
+#include "sw.h"
+#include "hw.h"
+
+#define MAX_RF_IMR_INDEX                       12
+#define MAX_RF_IMR_INDEX_NORMAL                        13
+#define RF_REG_NUM_FOR_C_CUT_5G                        6
+#define RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA     7
+#define RF_REG_NUM_FOR_C_CUT_2G                        5
+#define RF_CHNL_NUM_5G                         19
+#define RF_CHNL_NUM_5G_40M                     17
+#define TARGET_CHNL_NUM_5G                     221
+#define TARGET_CHNL_NUM_2G                     14
+#define CV_CURVE_CNT                           64
+
+static u32 rf_reg_for_5g_swchnl_normal[MAX_RF_IMR_INDEX_NORMAL] = {
+       0, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x0
+};
+
+static u8 rf_reg_for_c_cut_5g[RF_REG_NUM_FOR_C_CUT_5G] = {
+       RF_SYN_G1, RF_SYN_G2, RF_SYN_G3, RF_SYN_G4, RF_SYN_G5, RF_SYN_G6
+};
+
+static u8 rf_reg_for_c_cut_2g[RF_REG_NUM_FOR_C_CUT_2G] = {
+       RF_SYN_G1, RF_SYN_G2, RF_SYN_G3, RF_SYN_G7, RF_SYN_G8
+};
+
+static u8 rf_for_c_cut_5g_internal_pa[RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA] = {
+       0x0B, 0x48, 0x49, 0x4B, 0x03, 0x04, 0x0E
+};
+
+static u32 rf_reg_mask_for_c_cut_2g[RF_REG_NUM_FOR_C_CUT_2G] = {
+       BIT(19) | BIT(18) | BIT(17) | BIT(14) | BIT(1),
+       BIT(10) | BIT(9),
+       BIT(18) | BIT(17) | BIT(16) | BIT(1),
+       BIT(2) | BIT(1),
+       BIT(15) | BIT(14) | BIT(13) | BIT(12) | BIT(11)
+};
+
+static u8 rf_chnl_5g[RF_CHNL_NUM_5G] = {
+       36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108,
+       112, 116, 120, 124, 128, 132, 136, 140
+};
+
+static u8 rf_chnl_5g_40m[RF_CHNL_NUM_5G_40M] = {
+       38, 42, 46, 50, 54, 58, 62, 102, 106, 110, 114,
+       118, 122, 126, 130, 134, 138
+};
+static u32 rf_reg_pram_c_5g[5][RF_REG_NUM_FOR_C_CUT_5G] = {
+       {0xE43BE, 0xFC638, 0x77C0A, 0xDE471, 0xd7110, 0x8EB04},
+       {0xE43BE, 0xFC078, 0xF7C1A, 0xE0C71, 0xD7550, 0xAEB04},
+       {0xE43BF, 0xFF038, 0xF7C0A, 0xDE471, 0xE5550, 0xAEB04},
+       {0xE43BF, 0xFF079, 0xF7C1A, 0xDE471, 0xE5550, 0xAEB04},
+       {0xE43BF, 0xFF038, 0xF7C1A, 0xDE471, 0xd7550, 0xAEB04}
+};
+
+static u32 rf_reg_param_for_c_cut_2g[3][RF_REG_NUM_FOR_C_CUT_2G] = {
+       {0x643BC, 0xFC038, 0x77C1A, 0x41289, 0x01840},
+       {0x643BC, 0xFC038, 0x07C1A, 0x41289, 0x01840},
+       {0x243BC, 0xFC438, 0x07C1A, 0x4128B, 0x0FC41}
+};
+
+static u32 rf_syn_g4_for_c_cut_2g = 0xD1C31 & 0x7FF;
+
+static u32 rf_pram_c_5g_int_pa[3][RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA] = {
+       {0x01a00, 0x40443, 0x00eb5, 0x89bec, 0x94a12, 0x94a12, 0x94a12},
+       {0x01800, 0xc0443, 0x00730, 0x896ee, 0x94a52, 0x94a52, 0x94a52},
+       {0x01800, 0xc0443, 0x00730, 0x896ee, 0x94a12, 0x94a12, 0x94a12}
+};
+
+/* [mode][patha+b][reg] */
+static u32 rf_imr_param_normal[1][3][MAX_RF_IMR_INDEX_NORMAL] = {
+       {
+               /* channel 1-14. */
+               {
+                       0x70000, 0x00ff0, 0x4400f, 0x00ff0, 0x0, 0x0, 0x0,
+                       0x0, 0x0, 0x64888, 0xe266c, 0x00090, 0x22fff
+               },
+               /* path 36-64 */
+               {
+                       0x70000, 0x22880, 0x4470f, 0x55880, 0x00070, 0x88000,
+                       0x0, 0x88080, 0x70000, 0x64a82, 0xe466c, 0x00090,
+                       0x32c9a
+               },
+               /* 100 -165 */
+               {
+                       0x70000, 0x44880, 0x4477f, 0x77880, 0x00070, 0x88000,
+                       0x0, 0x880b0, 0x0, 0x64b82, 0xe466c, 0x00090, 0x32c9a
+               }
+       }
+};
+
+static u32 curveindex_5g[TARGET_CHNL_NUM_5G] = {0};
+
+static u32 curveindex_2g[TARGET_CHNL_NUM_2G] = {0};
+
+static u32 targetchnl_5g[TARGET_CHNL_NUM_5G] = {
+       25141, 25116, 25091, 25066, 25041,
+       25016, 24991, 24966, 24941, 24917,
+       24892, 24867, 24843, 24818, 24794,
+       24770, 24765, 24721, 24697, 24672,
+       24648, 24624, 24600, 24576, 24552,
+       24528, 24504, 24480, 24457, 24433,
+       24409, 24385, 24362, 24338, 24315,
+       24291, 24268, 24245, 24221, 24198,
+       24175, 24151, 24128, 24105, 24082,
+       24059, 24036, 24013, 23990, 23967,
+       23945, 23922, 23899, 23876, 23854,
+       23831, 23809, 23786, 23764, 23741,
+       23719, 23697, 23674, 23652, 23630,
+       23608, 23586, 23564, 23541, 23519,
+       23498, 23476, 23454, 23432, 23410,
+       23388, 23367, 23345, 23323, 23302,
+       23280, 23259, 23237, 23216, 23194,
+       23173, 23152, 23130, 23109, 23088,
+       23067, 23046, 23025, 23003, 22982,
+       22962, 22941, 22920, 22899, 22878,
+       22857, 22837, 22816, 22795, 22775,
+       22754, 22733, 22713, 22692, 22672,
+       22652, 22631, 22611, 22591, 22570,
+       22550, 22530, 22510, 22490, 22469,
+       22449, 22429, 22409, 22390, 22370,
+       22350, 22336, 22310, 22290, 22271,
+       22251, 22231, 22212, 22192, 22173,
+       22153, 22134, 22114, 22095, 22075,
+       22056, 22037, 22017, 21998, 21979,
+       21960, 21941, 21921, 21902, 21883,
+       21864, 21845, 21826, 21807, 21789,
+       21770, 21751, 21732, 21713, 21695,
+       21676, 21657, 21639, 21620, 21602,
+       21583, 21565, 21546, 21528, 21509,
+       21491, 21473, 21454, 21436, 21418,
+       21400, 21381, 21363, 21345, 21327,
+       21309, 21291, 21273, 21255, 21237,
+       21219, 21201, 21183, 21166, 21148,
+       21130, 21112, 21095, 21077, 21059,
+       21042, 21024, 21007, 20989, 20972,
+       25679, 25653, 25627, 25601, 25575,
+       25549, 25523, 25497, 25471, 25446,
+       25420, 25394, 25369, 25343, 25318,
+       25292, 25267, 25242, 25216, 25191,
+       25166
+};
+
+/* channel 1~14 */
+static u32 targetchnl_2g[TARGET_CHNL_NUM_2G] = {
+       26084, 26030, 25976, 25923, 25869, 25816, 25764,
+       25711, 25658, 25606, 25554, 25502, 25451, 25328
+};
+
+static u32 _rtl92d_phy_calculate_bit_shift(u32 bitmask)
+{
+       u32 i;
+
+       for (i = 0; i <= 31; i++) {
+               if (((bitmask >> i) & 0x1) == 1)
+                       break;
+       }
+
+       return i;
+}
+
+u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       u32 returnvalue, originalvalue, bitshift;
+       u8 dbi_direct;
+
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
+               "bitmask(%#x)\n", regaddr, bitmask));
+       if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) {
+               /* mac1 use phy0 read radio_b. */
+               /* mac0 use phy1 read radio_b. */
+               if (rtlhal->during_mac1init_radioa)
+                       dbi_direct = BIT(3);
+               else if (rtlhal->during_mac0init_radiob)
+                       dbi_direct = BIT(3) | BIT(2);
+               originalvalue = rtl92de_read_dword_dbi(hw, (u16)regaddr,
+                       dbi_direct);
+       } else {
+               originalvalue = rtl_read_dword(rtlpriv, regaddr);
+       }
+       bitshift = _rtl92d_phy_calculate_bit_shift(bitmask);
+       returnvalue = (originalvalue & bitmask) >> bitshift;
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x "
+               "Addr[0x%x]=0x%x\n", bitmask, regaddr, originalvalue));
+       return returnvalue;
+}
+
+void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw,
+                          u32 regaddr, u32 bitmask, u32 data)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       u8 dbi_direct = 0;
+       u32 originalvalue, bitshift;
+
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
+               " data(%#x)\n", regaddr, bitmask, data));
+       if (rtlhal->during_mac1init_radioa)
+               dbi_direct = BIT(3);
+       else if (rtlhal->during_mac0init_radiob)
+               /* mac0 use phy1 write radio_b. */
+               dbi_direct = BIT(3) | BIT(2);
+       if (bitmask != BMASKDWORD) {
+               if (rtlhal->during_mac1init_radioa ||
+                   rtlhal->during_mac0init_radiob)
+                       originalvalue = rtl92de_read_dword_dbi(hw,
+                                       (u16) regaddr,
+                                       dbi_direct);
+               else
+                       originalvalue = rtl_read_dword(rtlpriv, regaddr);
+               bitshift = _rtl92d_phy_calculate_bit_shift(bitmask);
+               data = ((originalvalue & (~bitmask)) | (data << bitshift));
+       }
+       if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob)
+               rtl92de_write_dword_dbi(hw, (u16) regaddr, data, dbi_direct);
+       else
+               rtl_write_dword(rtlpriv, regaddr, data);
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
+                " data(%#x)\n", regaddr, bitmask, data));
+}
+
+static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw,
+                                     enum radio_path rfpath, u32 offset)
+{
+
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
+       u32 newoffset;
+       u32 tmplong, tmplong2;
+       u8 rfpi_enable = 0;
+       u32 retvalue;
+
+       newoffset = offset;
+       tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD);
+       if (rfpath == RF90_PATH_A)
+               tmplong2 = tmplong;
+       else
+               tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, BMASKDWORD);
+       tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
+               (newoffset << 23) | BLSSIREADEDGE;
+       rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD,
+               tmplong & (~BLSSIREADEDGE));
+       udelay(10);
+       rtl_set_bbreg(hw, pphyreg->rfhssi_para2, BMASKDWORD, tmplong2);
+       udelay(50);
+       udelay(50);
+       rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD,
+               tmplong | BLSSIREADEDGE);
+       udelay(10);
+       if (rfpath == RF90_PATH_A)
+               rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
+                             BIT(8));
+       else if (rfpath == RF90_PATH_B)
+               rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
+                             BIT(8));
+       if (rfpi_enable)
+               retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi,
+                       BLSSIREADBACKDATA);
+       else
+               retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
+                       BLSSIREADBACKDATA);
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x] = 0x%x\n",
+                rfpath, pphyreg->rflssi_readback, retvalue));
+       return retvalue;
+}
+
+static void _rtl92d_phy_rf_serial_write(struct ieee80211_hw *hw,
+                                       enum radio_path rfpath,
+                                       u32 offset, u32 data)
+{
+       u32 data_and_addr;
+       u32 newoffset;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
+
+       newoffset = offset;
+       /* T65 RF */
+       data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
+       rtl_set_bbreg(hw, pphyreg->rf3wire_offset, BMASKDWORD, data_and_addr);
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
+               rfpath, pphyreg->rf3wire_offset, data_and_addr));
+}
+
+u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw,
+                           enum radio_path rfpath, u32 regaddr, u32 bitmask)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 original_value, readback_value, bitshift;
+       unsigned long flags;
+
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
+               "rfpath(%#x), bitmask(%#x)\n",
+               regaddr, rfpath, bitmask));
+       spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+       original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr);
+       bitshift = _rtl92d_phy_calculate_bit_shift(bitmask);
+       readback_value = (original_value & bitmask) >> bitshift;
+       spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
+               "bitmask(%#x), original_value(%#x)\n",
+               regaddr, rfpath, bitmask, original_value));
+       return readback_value;
+}
+
+void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
+       u32 regaddr, u32 bitmask, u32 data)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u32 original_value, bitshift;
+       unsigned long flags;
+
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+               ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+               regaddr, bitmask, data, rfpath));
+       if (bitmask == 0)
+               return;
+       spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+       if (rtlphy->rf_mode != RF_OP_BY_FW) {
+               if (bitmask != BRFREGOFFSETMASK) {
+                       original_value = _rtl92d_phy_rf_serial_read(hw,
+                               rfpath, regaddr);
+                       bitshift = _rtl92d_phy_calculate_bit_shift(bitmask);
+                       data = ((original_value & (~bitmask)) |
+                               (data << bitshift));
+               }
+               _rtl92d_phy_rf_serial_write(hw, rfpath, regaddr, data);
+       }
+       spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
+               "bitmask(%#x), data(%#x), rfpath(%#x)\n",
+               regaddr, bitmask, data, rfpath));
+}
+
+bool rtl92d_phy_mac_config(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+       u32 arraylength;
+       u32 *ptrarray;
+
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n"));
+       arraylength = MAC_2T_ARRAYLENGTH;
+       ptrarray = rtl8192de_mac_2tarray;
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Img:Rtl819XMAC_Array\n"));
+       for (i = 0; i < arraylength; i = i + 2)
+               rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
+       if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) {
+               /* improve 2-stream TX EVM */
+               /* rtl_write_byte(rtlpriv, 0x14,0x71); */
+               /* AMPDU aggregation number 9 */
+               /* rtl_write_word(rtlpriv, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); */
+               rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x0B);
+       } else {
+               /* 92D need to test to decide the num. */
+               rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x07);
+       }
+       return true;
+}
+
+static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       /* RF Interface Sowrtware Control */
+       /* 16 LSBs if read 32-bit from 0x870 */
+       rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
+       /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */
+       rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
+       /* 16 LSBs if read 32-bit from 0x874 */
+       rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
+       /* 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) */
+
+       rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
+       /* RF Interface Readback Value */
+       /* 16 LSBs if read 32-bit from 0x8E0 */
+       rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
+       /* 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */
+       rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
+       /* 16 LSBs if read 32-bit from 0x8E4 */
+       rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
+       /* 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) */
+       rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
+
+       /* RF Interface Output (and Enable) */
+       /* 16 LSBs if read 32-bit from 0x860 */
+       rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
+       /* 16 LSBs if read 32-bit from 0x864 */
+       rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
+
+       /* RF Interface (Output and)  Enable */
+       /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
+       rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
+       /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */
+       rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
+
+       /* Addr of LSSI. Wirte RF register by driver */
+       /* LSSI Parameter */
+       rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
+                                RFPGA0_XA_LSSIPARAMETER;
+       rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
+                                RFPGA0_XB_LSSIPARAMETER;
+
+       /* RF parameter */
+       /* BB Band Select */
+       rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER;
+       rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER;
+       rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER;
+       rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER;
+
+       /* Tx AGC Gain Stage (same for all path. Should we remove this?) */
+       /* Tx gain stage */
+       rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+       /* Tx gain stage */
+       rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+       /* Tx gain stage */
+       rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+       /* Tx gain stage */
+       rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+
+       /* Tranceiver A~D HSSI Parameter-1 */
+       /* wire control parameter1 */
+       rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
+       /* wire control parameter1 */
+       rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
+
+       /* Tranceiver A~D HSSI Parameter-2 */
+       /* wire control parameter2 */
+       rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
+       /* wire control parameter2 */
+       rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
+
+       /* RF switch Control */
+       /* TR/Ant switch control */
+       rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control =
+               RFPGA0_XAB_SWITCHCONTROL;
+       rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control =
+           RFPGA0_XAB_SWITCHCONTROL;
+       rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control =
+           RFPGA0_XCD_SWITCHCONTROL;
+       rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control =
+           RFPGA0_XCD_SWITCHCONTROL;
+
+       /* AGC control 1 */
+       rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
+       rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
+       rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
+       rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
+
+       /* AGC control 2  */
+       rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
+       rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
+       rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
+       rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
+
+       /* RX AFE control 1 */
+       rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance =
+           ROFDM0_XARXIQIMBALANCE;
+       rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance =
+           ROFDM0_XBRXIQIMBALANCE;
+       rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance =
+           ROFDM0_XCRXIQIMBALANCE;
+       rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance =
+           ROFDM0_XDRXIQIMBALANCE;
+
+       /*RX AFE control 1 */
+       rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
+       rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
+       rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
+       rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
+
+       /* Tx AFE control 1 */
+       rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance =
+           ROFDM0_XATxIQIMBALANCE;
+       rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance =
+           ROFDM0_XBTxIQIMBALANCE;
+       rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance =
+           ROFDM0_XCTxIQIMBALANCE;
+       rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance =
+           ROFDM0_XDTxIQIMBALANCE;
+
+       /* Tx AFE control 2 */
+       rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATxAFE;
+       rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTxAFE;
+       rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTxAFE;
+       rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTxAFE;
+
+       /* Tranceiver LSSI Readback SI mode */
+       rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback =
+           RFPGA0_XA_LSSIREADBACK;
+       rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback =
+           RFPGA0_XB_LSSIREADBACK;
+       rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback =
+           RFPGA0_XC_LSSIREADBACK;
+       rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback =
+           RFPGA0_XD_LSSIREADBACK;
+
+       /* Tranceiver LSSI Readback PI mode */
+       rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi =
+           TRANSCEIVERA_HSPI_READBACK;
+       rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi =
+           TRANSCEIVERB_HSPI_READBACK;
+}
+
+static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
+       u8 configtype)
+{
+       int i;
+       u32 *phy_regarray_table;
+       u32 *agctab_array_table = NULL;
+       u32 *agctab_5garray_table;
+       u16 phy_reg_arraylen, agctab_arraylen = 0, agctab_5garraylen;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+       /* Normal chip,Mac0 use AGC_TAB.txt for 2G and 5G band. */
+       if (rtlhal->interfaceindex == 0) {
+               agctab_arraylen = AGCTAB_ARRAYLENGTH;
+               agctab_array_table = rtl8192de_agctab_array;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                        (" ===> phy:MAC0, Rtl819XAGCTAB_Array\n"));
+       } else {
+               if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+                       agctab_arraylen = AGCTAB_2G_ARRAYLENGTH;
+                       agctab_array_table = rtl8192de_agctab_2garray;
+                       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                                (" ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n"));
+               } else {
+                       agctab_5garraylen = AGCTAB_5G_ARRAYLENGTH;
+                       agctab_5garray_table = rtl8192de_agctab_5garray;
+                       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                                (" ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n"));
+
+               }
+       }
+       phy_reg_arraylen = PHY_REG_2T_ARRAYLENGTH;
+       phy_regarray_table = rtl8192de_phy_reg_2tarray;
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                (" ===> phy:Rtl819XPHY_REG_Array_PG\n"));
+       if (configtype == BASEBAND_CONFIG_PHY_REG) {
+               for (i = 0; i < phy_reg_arraylen; i = i + 2) {
+                       if (phy_regarray_table[i] == 0xfe)
+                               mdelay(50);
+                       else if (phy_regarray_table[i] == 0xfd)
+                               mdelay(5);
+                       else if (phy_regarray_table[i] == 0xfc)
+                               mdelay(1);
+                       else if (phy_regarray_table[i] == 0xfb)
+                               udelay(50);
+                       else if (phy_regarray_table[i] == 0xfa)
+                               udelay(5);
+                       else if (phy_regarray_table[i] == 0xf9)
+                               udelay(1);
+                       rtl_set_bbreg(hw, phy_regarray_table[i], BMASKDWORD,
+                                     phy_regarray_table[i + 1]);
+                       udelay(1);
+                       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                                ("The phy_regarray_table[0] is %x"
+                                 " Rtl819XPHY_REGArray[1] is %x\n",
+                                 phy_regarray_table[i],
+                                 phy_regarray_table[i + 1]));
+               }
+       } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
+               if (rtlhal->interfaceindex == 0) {
+                       for (i = 0; i < agctab_arraylen; i = i + 2) {
+                               rtl_set_bbreg(hw, agctab_array_table[i],
+                                       BMASKDWORD,
+                                       agctab_array_table[i + 1]);
+                               /* Add 1us delay between BB/RF register
+                                * setting. */
+                               udelay(1);
+                               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                                        ("The Rtl819XAGCTAB_Array_"
+                                        "Table[0] is %ul "
+                                        "Rtl819XPHY_REGArray[1] is %ul\n",
+                                        agctab_array_table[i],
+                                        agctab_array_table[i + 1]));
+                       }
+                       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                                ("Normal Chip, MAC0, load "
+                                "Rtl819XAGCTAB_Array\n"));
+               } else {
+                       if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+                               for (i = 0; i < agctab_arraylen; i = i + 2) {
+                                       rtl_set_bbreg(hw, agctab_array_table[i],
+                                               BMASKDWORD,
+                                               agctab_array_table[i + 1]);
+                                       /* Add 1us delay between BB/RF register
+                                        * setting. */
+                                       udelay(1);
+                                       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                                                ("The Rtl819XAGCTAB_Array_"
+                                                "Table[0] is %ul Rtl819XPHY_"
+                                                "REGArray[1] is %ul\n",
+                                                agctab_array_table[i],
+                                                agctab_array_table[i + 1]));
+                               }
+                               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                                        ("Load Rtl819XAGCTAB_2GArray\n"));
+                       } else {
+                               for (i = 0; i < agctab_5garraylen; i = i + 2) {
+                                       rtl_set_bbreg(hw,
+                                               agctab_5garray_table[i],
+                                               BMASKDWORD,
+                                               agctab_5garray_table[i + 1]);
+                                       /* Add 1us delay between BB/RF registeri
+                                        * setting. */
+                                       udelay(1);
+                                       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                                                ("The Rtl819XAGCTAB_5GArray_"
+                                                "Table[0] is %ul Rtl819XPHY_"
+                                                "REGArray[1] is %ul\n",
+                                                agctab_5garray_table[i],
+                                                agctab_5garray_table[i + 1]));
+                               }
+                               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                                       ("Load Rtl819XAGCTAB_5GArray\n"));
+                       }
+               }
+       }
+       return true;
+}
+
+static void _rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
+                                                  u32 regaddr, u32 bitmask,
+                                                  u32 data)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       if (regaddr == RTXAGC_A_RATE18_06) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%ulx\n",
+                        rtlphy->pwrgroup_cnt,
+                        rtlphy->mcs_txpwrlevel_origoffset
+                        [rtlphy->pwrgroup_cnt][0]));
+       }
+       if (regaddr == RTXAGC_A_RATE54_24) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%ulx\n",
+                        rtlphy->pwrgroup_cnt,
+                        rtlphy->mcs_txpwrlevel_origoffset
+                        [rtlphy->pwrgroup_cnt][1]));
+       }
+       if (regaddr == RTXAGC_A_CCK1_MCS32) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%ulx\n",
+                        rtlphy->pwrgroup_cnt,
+                        rtlphy->mcs_txpwrlevel_origoffset
+                        [rtlphy->pwrgroup_cnt][6]));
+       }
+       if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%ulx\n",
+                        rtlphy->pwrgroup_cnt,
+                        rtlphy->mcs_txpwrlevel_origoffset
+                        [rtlphy->pwrgroup_cnt][7]));
+       }
+       if (regaddr == RTXAGC_A_MCS03_MCS00) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%ulx\n",
+                        rtlphy->pwrgroup_cnt,
+                        rtlphy->mcs_txpwrlevel_origoffset
+                        [rtlphy->pwrgroup_cnt][2]));
+       }
+       if (regaddr == RTXAGC_A_MCS07_MCS04) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%ulx\n",
+                        rtlphy->pwrgroup_cnt,
+                        rtlphy->mcs_txpwrlevel_origoffset
+                        [rtlphy->pwrgroup_cnt][3]));
+       }
+       if (regaddr == RTXAGC_A_MCS11_MCS08) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%ulx\n",
+                        rtlphy->pwrgroup_cnt,
+                        rtlphy->mcs_txpwrlevel_origoffset
+                        [rtlphy->pwrgroup_cnt][4]));
+       }
+       if (regaddr == RTXAGC_A_MCS15_MCS12) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%ulx\n",
+                        rtlphy->pwrgroup_cnt,
+                        rtlphy->mcs_txpwrlevel_origoffset
+                        [rtlphy->pwrgroup_cnt][5]));
+       }
+       if (regaddr == RTXAGC_B_RATE18_06) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%ulx\n",
+                        rtlphy->pwrgroup_cnt,
+                        rtlphy->mcs_txpwrlevel_origoffset
+                        [rtlphy->pwrgroup_cnt][8]));
+       }
+       if (regaddr == RTXAGC_B_RATE54_24) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%ulx\n",
+                        rtlphy->pwrgroup_cnt,
+                        rtlphy->mcs_txpwrlevel_origoffset
+                        [rtlphy->pwrgroup_cnt][9]));
+       }
+       if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%ulx\n",
+                        rtlphy->pwrgroup_cnt,
+                        rtlphy->mcs_txpwrlevel_origoffset
+                        [rtlphy->pwrgroup_cnt][14]));
+       }
+       if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%ulx\n",
+                        rtlphy->pwrgroup_cnt,
+                        rtlphy->mcs_txpwrlevel_origoffset
+                        [rtlphy->pwrgroup_cnt][15]));
+       }
+       if (regaddr == RTXAGC_B_MCS03_MCS00) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%ulx\n",
+                        rtlphy->pwrgroup_cnt,
+                        rtlphy->mcs_txpwrlevel_origoffset
+                        [rtlphy->pwrgroup_cnt][10]));
+       }
+       if (regaddr == RTXAGC_B_MCS07_MCS04) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%ulx\n",
+                        rtlphy->pwrgroup_cnt,
+                        rtlphy->mcs_txpwrlevel_origoffset
+                        [rtlphy->pwrgroup_cnt][11]));
+       }
+       if (regaddr == RTXAGC_B_MCS11_MCS08) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%ulx\n",
+                         rtlphy->pwrgroup_cnt,
+                         rtlphy->mcs_txpwrlevel_origoffset
+                                       [rtlphy->pwrgroup_cnt][12]));
+       }
+       if (regaddr == RTXAGC_B_MCS15_MCS12) {
+               rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] =
+                                                                        data;
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                        ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%ulx\n",
+                         rtlphy->pwrgroup_cnt,
+                         rtlphy->mcs_txpwrlevel_origoffset
+                                       [rtlphy->pwrgroup_cnt][13]));
+               rtlphy->pwrgroup_cnt++;
+       }
+}
+
+static bool _rtl92d_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
+       u8 configtype)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int i;
+       u32 *phy_regarray_table_pg;
+       u16 phy_regarray_pg_len;
+
+       phy_regarray_pg_len = PHY_REG_ARRAY_PG_LENGTH;
+       phy_regarray_table_pg = rtl8192de_phy_reg_array_pg;
+       if (configtype == BASEBAND_CONFIG_PHY_REG) {
+               for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
+                       if (phy_regarray_table_pg[i] == 0xfe)
+                               mdelay(50);
+                       else if (phy_regarray_table_pg[i] == 0xfd)
+                               mdelay(5);
+                       else if (phy_regarray_table_pg[i] == 0xfc)
+                               mdelay(1);
+                       else if (phy_regarray_table_pg[i] == 0xfb)
+                               udelay(50);
+                       else if (phy_regarray_table_pg[i] == 0xfa)
+                               udelay(5);
+                       else if (phy_regarray_table_pg[i] == 0xf9)
+                               udelay(1);
+                       _rtl92d_store_pwrindex_diffrate_offset(hw,
+                               phy_regarray_table_pg[i],
+                               phy_regarray_table_pg[i + 1],
+                               phy_regarray_table_pg[i + 2]);
+               }
+       } else {
+               RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+                        ("configtype != BaseBand_Config_PHY_REG\n"));
+       }
+       return true;
+}
+
+static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       bool rtstatus = true;
+
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n"));
+       rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw,
+               BASEBAND_CONFIG_PHY_REG);
+       if (rtstatus != true) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!"));
+               return false;
+       }
+
+       /* if (rtlphy->rf_type == RF_1T2R) {
+        *      _rtl92c_phy_bb_config_1t(hw);
+        *     RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n"));
+        *} */
+
+       if (rtlefuse->autoload_failflag == false) {
+               rtlphy->pwrgroup_cnt = 0;
+               rtstatus = _rtl92d_phy_config_bb_with_pgheaderfile(hw,
+                       BASEBAND_CONFIG_PHY_REG);
+       }
+       if (rtstatus != true) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!"));
+               return false;
+       }
+       rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw,
+               BASEBAND_CONFIG_AGC_TAB);
+       if (rtstatus != true) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n"));
+               return false;
+       }
+       rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
+               RFPGA0_XA_HSSIPARAMETER2, 0x200));
+
+       return true;
+}
+
+bool rtl92d_phy_bb_config(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u16 regval;
+       u32 regvaldw;
+       u8 value;
+
+       _rtl92d_phy_init_bb_rf_register_definition(hw);
+       regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
+       rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
+                      regval | BIT(13) | BIT(0) | BIT(1));
+       rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
+       rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
+       /* 0x1f bit7 bit6 represent for mac0/mac1 driver ready */
+       value = rtl_read_byte(rtlpriv, REG_RF_CTRL);
+       rtl_write_byte(rtlpriv, REG_RF_CTRL, value | RF_EN | RF_RSTB |
+               RF_SDMRSTB);
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_PPLL | FEN_PCIEA |
+               FEN_DIO_PCIE | FEN_BB_GLB_RSTn | FEN_BBRSTB);
+       rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
+       if (!(IS_92D_SINGLEPHY(rtlpriv->rtlhal.version))) {
+               regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
+               rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
+       }
+
+       return _rtl92d_phy_bb_config(hw);
+}
+
+bool rtl92d_phy_rf_config(struct ieee80211_hw *hw)
+{
+       return rtl92d_phy_rf6052_config(hw);
+}
+
+bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
+                                         enum rf_content content,
+                                         enum radio_path rfpath)
+{
+       int i, j;
+       u32 *radioa_array_table;
+       u32 *radiob_array_table;
+       u16 radioa_arraylen, radiob_arraylen;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       radioa_arraylen = RADIOA_2T_ARRAYLENGTH;
+       radioa_array_table = rtl8192de_radioa_2tarray;
+       radiob_arraylen = RADIOB_2T_ARRAYLENGTH;
+       radiob_array_table = rtl8192de_radiob_2tarray;
+       if (rtlpriv->efuse.internal_pa_5g[0]) {
+               radioa_arraylen = RADIOA_2T_INT_PA_ARRAYLENGTH;
+               radioa_array_table = rtl8192de_radioa_2t_int_paarray;
+       }
+       if (rtlpriv->efuse.internal_pa_5g[1]) {
+               radiob_arraylen = RADIOB_2T_INT_PA_ARRAYLENGTH;
+               radiob_array_table = rtl8192de_radiob_2t_int_paarray;
+       }
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                ("PHY_ConfigRFWithHeaderFile() "
+                "Radio_A:Rtl819XRadioA_1TArray\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                ("PHY_ConfigRFWithHeaderFile() "
+                "Radio_B:Rtl819XRadioB_1TArray\n"));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath));
+
+       /* this only happens when DMDP, mac0 start on 2.4G,
+        * mac1 start on 5G, mac 0 has to set phy0&phy1
+        * pathA or mac1 has to set phy0&phy1 pathA */
+       if ((content == radiob_txt) && (rfpath == RF90_PATH_A)) {
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                        (" ===> althougth Path A, we load radiob.txt\n"));
+               radioa_arraylen = radiob_arraylen;
+               radioa_array_table = radiob_array_table;
+       }
+       switch (rfpath) {
+       case RF90_PATH_A:
+               for (i = 0; i < radioa_arraylen; i = i + 2) {
+                       if (radioa_array_table[i] == 0xfe) {
+                               mdelay(50);
+                       } else if (radioa_array_table[i] == 0xfd) {
+                               /* delay_ms(5); */
+                               for (j = 0; j < 100; j++)
+                                       udelay(MAX_STALL_TIME);
+                       } else if (radioa_array_table[i] == 0xfc) {
+                               /* delay_ms(1); */
+                               for (j = 0; j < 20; j++)
+                                       udelay(MAX_STALL_TIME);
+
+                       } else if (radioa_array_table[i] == 0xfb) {
+                               udelay(50);
+                       } else if (radioa_array_table[i] == 0xfa) {
+                               udelay(5);
+                       } else if (radioa_array_table[i] == 0xf9) {
+                               udelay(1);
+                       } else {
+                               rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
+                                             BRFREGOFFSETMASK,
+                                             radioa_array_table[i + 1]);
+                               /*  Add 1us delay between BB/RF register set. */
+                               udelay(1);
+                       }
+               }
+               break;
+       case RF90_PATH_B:
+               for (i = 0; i < radiob_arraylen; i = i + 2) {
+                       if (radiob_array_table[i] == 0xfe) {
+                               /* Delay specific ms. Only RF configuration
+                                * requires delay. */
+                               mdelay(50);
+                       } else if (radiob_array_table[i] == 0xfd) {
+                               /* delay_ms(5); */
+                               for (j = 0; j < 100; j++)
+                                       udelay(MAX_STALL_TIME);
+                       } else if (radiob_array_table[i] == 0xfc) {
+                               /* delay_ms(1); */
+                               for (j = 0; j < 20; j++)
+                                       udelay(MAX_STALL_TIME);
+                       } else if (radiob_array_table[i] == 0xfb) {
+                               udelay(50);
+                       } else if (radiob_array_table[i] == 0xfa) {
+                               udelay(5);
+                       } else if (radiob_array_table[i] == 0xf9) {
+                               udelay(1);
+                       } else {
+                               rtl_set_rfreg(hw, rfpath, radiob_array_table[i],
+                                             BRFREGOFFSETMASK,
+                                             radiob_array_table[i + 1]);
+                               /*  Add 1us delay between BB/RF register set. */
+                               udelay(1);
+                       }
+               }
+               break;
+       case RF90_PATH_C:
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("switch case not process\n"));
+               break;
+       case RF90_PATH_D:
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("switch case not process\n"));
+               break;
+       }
+       return true;
+}
+
+void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       rtlphy->default_initialgain[0] =
+           (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, BMASKBYTE0);
+       rtlphy->default_initialgain[1] =
+           (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, BMASKBYTE0);
+       rtlphy->default_initialgain[2] =
+           (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, BMASKBYTE0);
+       rtlphy->default_initialgain[3] =
+           (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, BMASKBYTE0);
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                ("Default initial gain (c50=0x%x, "
+                 "c58=0x%x, c60=0x%x, c68=0x%x\n",
+                 rtlphy->default_initialgain[0],
+                 rtlphy->default_initialgain[1],
+                 rtlphy->default_initialgain[2],
+                 rtlphy->default_initialgain[3]));
+       rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
+                                             BMASKBYTE0);
+       rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
+                                             BMASKDWORD);
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                ("Default framesync (0x%x) = 0x%x\n",
+                 ROFDM0_RXDETECTOR3, rtlphy->framesync));
+}
+
+static void _rtl92d_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
+       u8 *cckpowerlevel, u8 *ofdmpowerlevel)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u8 index = (channel - 1);
+
+       /* 1. CCK */
+       if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+               /* RF-A */
+               cckpowerlevel[RF90_PATH_A] =
+                                rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
+               /* RF-B */
+               cckpowerlevel[RF90_PATH_B] =
+                                rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
+       } else {
+               cckpowerlevel[RF90_PATH_A] = 0;
+               cckpowerlevel[RF90_PATH_B] = 0;
+       }
+       /* 2. OFDM for 1S or 2S */
+       if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) {
+               /*  Read HT 40 OFDM TX power */
+               ofdmpowerlevel[RF90_PATH_A] =
+                   rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
+               ofdmpowerlevel[RF90_PATH_B] =
+                   rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
+       } else if (rtlphy->rf_type == RF_2T2R) {
+               /* Read HT 40 OFDM TX power */
+               ofdmpowerlevel[RF90_PATH_A] =
+                   rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
+               ofdmpowerlevel[RF90_PATH_B] =
+                   rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
+       }
+}
+
+static void _rtl92d_ccxpower_index_check(struct ieee80211_hw *hw,
+       u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
+       rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
+}
+
+static u8 _rtl92c_phy_get_rightchnlplace(u8 chnl)
+{
+       u8 channel_5g[59] = {
+               1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+               36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
+               60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
+               114, 116, 118, 120, 122, 124, 126, 128,
+               130, 132, 134, 136, 138, 140, 149, 151,
+               153, 155, 157, 159, 161, 163, 165
+       };
+       u8 place = chnl;
+
+       if (chnl > 14) {
+               for (place = 14; place < sizeof(channel_5g); place++) {
+                       if (channel_5g[place] == chnl) {
+                               place++;
+                               break;
+                       }
+               }
+       }
+       return place;
+}
+
+void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
+{
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 cckpowerlevel[2], ofdmpowerlevel[2];
+
+       if (rtlefuse->txpwr_fromeprom == false)
+               return;
+       channel = _rtl92c_phy_get_rightchnlplace(channel);
+       _rtl92d_get_txpower_index(hw, channel, &cckpowerlevel[0],
+               &ofdmpowerlevel[0]);
+       if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
+               _rtl92d_ccxpower_index_check(hw, channel, &cckpowerlevel[0],
+                               &ofdmpowerlevel[0]);
+       if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
+               rtl92d_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
+       rtl92d_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
+}
+
+void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       enum io_type iotype;
+
+       if (!is_hal_stop(rtlhal)) {
+               switch (operation) {
+               case SCAN_OPT_BACKUP:
+                       rtlhal->current_bandtypebackup =
+                                                rtlhal->current_bandtype;
+                       iotype = IO_CMD_PAUSE_DM_BY_SCAN;
+                       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
+                                                     (u8 *)&iotype);
+                       break;
+               case SCAN_OPT_RESTORE:
+                       iotype = IO_CMD_RESUME_DM_BY_SCAN;
+                       rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
+                                                     (u8 *)&iotype);
+                       break;
+               default:
+                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                                ("Unknown Scan Backup operation.\n"));
+                       break;
+               }
+       }
+}
+
+void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
+                           enum nl80211_channel_type ch_type)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       unsigned long flag = 0;
+       u8 reg_prsr_rsc;
+       u8 reg_bw_opmode;
+
+       if (rtlphy->set_bwmode_inprogress)
+               return;
+       if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+                        ("FALSE driver sleep or unload\n"));
+               return;
+       }
+       rtlphy->set_bwmode_inprogress = true;
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
+                ("Switch to %s bandwidth\n",
+                 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
+                 "20MHz" : "40MHz"));
+       reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
+       reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
+       switch (rtlphy->current_chan_bw) {
+       case HT_CHANNEL_WIDTH_20:
+               reg_bw_opmode |= BW_OPMODE_20MHZ;
+               rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
+               break;
+       case HT_CHANNEL_WIDTH_20_40:
+               reg_bw_opmode &= ~BW_OPMODE_20MHZ;
+               rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
+
+               reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
+                       (mac->cur_40_prime_sc << 5);
+               rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
+               break;
+       default:
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+               break;
+       }
+       switch (rtlphy->current_chan_bw) {
+       case HT_CHANNEL_WIDTH_20:
+               rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
+               rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
+               /* SET BIT10 BIT11  for receive cck */
+               rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) |
+                             BIT(11), 3);
+               break;
+       case HT_CHANNEL_WIDTH_20_40:
+               rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
+               rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
+               /* Set Control channel to upper or lower.
+                * These settings are required only for 40MHz */
+               if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+                       rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
+                       rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCKSIDEBAND,
+                               (mac->cur_40_prime_sc >> 1));
+                       rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
+               }
+               rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
+               /* SET BIT10 BIT11  for receive cck */
+               rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) |
+                             BIT(11), 0);
+               rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
+                       (mac->cur_40_prime_sc ==
+                       HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
+               break;
+       default:
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+               break;
+
+       }
+       rtl92d_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
+       rtlphy->set_bwmode_inprogress = false;
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+}
+
+static void _rtl92d_phy_stop_trx_before_changeband(struct ieee80211_hw *hw)
+{
+       rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0);
+       rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0);
+       rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x00);
+       rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x0);
+}
+
+static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 i, value8;
+
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n"));
+       rtlhal->bandset = band;
+       rtlhal->current_bandtype = band;
+       if (IS_92D_SINGLEPHY(rtlhal->version))
+               rtlhal->bandset = BAND_ON_BOTH;
+       /* stop RX/Tx */
+       _rtl92d_phy_stop_trx_before_changeband(hw);
+       /* reconfig BB/RF according to wireless mode */
+       if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+               /* BB & RF Config */
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("====>2.4G\n"));
+               if (rtlhal->interfaceindex == 1)
+                       _rtl92d_phy_config_bb_with_headerfile(hw,
+                               BASEBAND_CONFIG_AGC_TAB);
+       } else {
+               /* 5G band */
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("====>5G\n"));
+               if (rtlhal->interfaceindex == 1)
+                       _rtl92d_phy_config_bb_with_headerfile(hw,
+                               BASEBAND_CONFIG_AGC_TAB);
+       }
+       rtl92d_update_bbrf_configuration(hw);
+       if (rtlhal->current_bandtype == BAND_ON_2_4G)
+               rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
+       rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
+
+       /* 20M BW. */
+       /* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); */
+       rtlhal->reloadtxpowerindex = true;
+       /* notice fw know band status  0x81[1]/0x53[1] = 0: 5G, 1: 2G */
+       if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+               value8 = rtl_read_byte(rtlpriv, (rtlhal->interfaceindex ==
+                       0 ? REG_MAC0 : REG_MAC1));
+               value8 |= BIT(1);
+               rtl_write_byte(rtlpriv, (rtlhal->interfaceindex ==
+                       0 ? REG_MAC0 : REG_MAC1), value8);
+       } else {
+               value8 = rtl_read_byte(rtlpriv, (rtlhal->interfaceindex ==
+                       0 ? REG_MAC0 : REG_MAC1));
+               value8 &= (~BIT(1));
+               rtl_write_byte(rtlpriv, (rtlhal->interfaceindex ==
+                       0 ? REG_MAC0 : REG_MAC1), value8);
+       }
+       for (i = 0; i < 20; i++)
+               udelay(MAX_STALL_TIME);
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==Switch Band OK.\n"));
+}
+
+static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,
+       u8 channel, u8 rfpath)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 imr_num = MAX_RF_IMR_INDEX;
+       u32 rfmask = BRFREGOFFSETMASK;
+       u8 group, i;
+       unsigned long flag = 0;
+
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>path %d\n", rfpath));
+       if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>5G\n"));
+               rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0);
+               rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf);
+               /* fc area 0xd2c */
+               if (channel > 99)
+                       rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(13) |
+                                     BIT(14), 2);
+               else
+                       rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(13) |
+                                     BIT(14), 1);
+               /* leave 0 for channel1-14. */
+               group = channel <= 64 ? 1 : 2;
+               imr_num = MAX_RF_IMR_INDEX_NORMAL;
+               for (i = 0; i < imr_num; i++)
+                       rtl_set_rfreg(hw, (enum radio_path)rfpath,
+                                     rf_reg_for_5g_swchnl_normal[i], rfmask,
+                                     rf_imr_param_normal[0][group][i]);
+               rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0);
+               rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 1);
+       } else {
+               /* G band. */
+               RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
+                        ("Load RF IMR parameters for G band. IMR already "
+                        "setting %d\n",
+                         rtlpriv->rtlhal.load_imrandiqk_setting_for2g));
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>2.4G\n"));
+               if (!rtlpriv->rtlhal.load_imrandiqk_setting_for2g) {
+                       RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
+                               ("Load RF IMR parameters "
+                               "for G band. %d\n", rfpath));
+                       rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
+                       rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0);
+                       rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4,
+                                     0x00f00000, 0xf);
+                       imr_num = MAX_RF_IMR_INDEX_NORMAL;
+                       for (i = 0; i < imr_num; i++) {
+                               rtl_set_rfreg(hw, (enum radio_path)rfpath,
+                                             rf_reg_for_5g_swchnl_normal[i],
+                                             BRFREGOFFSETMASK,
+                                             rf_imr_param_normal[0][0][i]);
+                       }
+                       rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4,
+                                     0x00f00000, 0);
+                       rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN | BCCKEN, 3);
+                       rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
+               }
+       }
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n"));
+}
+
+static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw,
+       u8 rfpath, u32 *pu4_regval)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
+
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n"));
+       /*----Store original RFENV control type----*/
+       switch (rfpath) {
+       case RF90_PATH_A:
+       case RF90_PATH_C:
+               *pu4_regval = rtl_get_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV);
+               break;
+       case RF90_PATH_B:
+       case RF90_PATH_D:
+               *pu4_regval =
+                   rtl_get_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16);
+               break;
+       }
+       /*----Set RF_ENV enable----*/
+       rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
+       udelay(1);
+       /*----Set RF_ENV output high----*/
+       rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
+       udelay(1);
+       /* Set bit number of Address and Data for RF register */
+       /* Set 1 to 4 bits for 8255 */
+       rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREADDRESSLENGTH, 0x0);
+       udelay(1);
+       /*Set 0 to 12 bits for 8255 */
+       rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
+       udelay(1);
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n"));
+}
+
+static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath,
+                                      u32 *pu4_regval)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
+
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("=====>\n"));
+       /*----Restore RFENV control type----*/ ;
+       switch (rfpath) {
+       case RF90_PATH_A:
+       case RF90_PATH_C:
+               rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV, *pu4_regval);
+               break;
+       case RF90_PATH_B:
+       case RF90_PATH_D:
+               rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16,
+                             *pu4_regval);
+               break;
+       }
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<=====\n"));
+}
+
+static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
+       u8 path = rtlhal->current_bandtype ==
+           BAND_ON_5G ? RF90_PATH_A : RF90_PATH_B;
+       u8 index = 0, i = 0, rfpath = RF90_PATH_A;
+       bool need_pwr_down = false, internal_pa = false;
+       u32 u4regvalue, mask = 0x1C000, value = 0, u4tmp, u4tmp2;
+
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>\n"));
+       /* config path A for 5G */
+       if (rtlhal->current_bandtype == BAND_ON_5G) {
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>5G\n"));
+               u4tmp = curveindex_5g[channel - 1];
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 1 set RF-A, 5G, "
+                       "0x28 = 0x%x !!\n", u4tmp));
+               for (i = 0; i < RF_CHNL_NUM_5G; i++) {
+                       if (channel == rf_chnl_5g[i] && channel <= 140)
+                               index = 0;
+               }
+               for (i = 0; i < RF_CHNL_NUM_5G_40M; i++) {
+                       if (channel == rf_chnl_5g_40m[i] && channel <= 140)
+                               index = 1;
+               }
+               if (channel == 149 || channel == 155 || channel == 161)
+                       index = 2;
+               else if (channel == 151 || channel == 153 || channel == 163
+                        || channel == 165)
+                       index = 3;
+               else if (channel == 157 || channel == 159)
+                       index = 4;
+
+               if (rtlhal->macphymode == DUALMAC_DUALPHY
+                   && rtlhal->interfaceindex == 1) {
+                       need_pwr_down = rtl92d_phy_enable_anotherphy(hw, false);
+                       rtlhal->during_mac1init_radioa = true;
+                       /* asume no this case */
+                       if (need_pwr_down)
+                               _rtl92d_phy_enable_rf_env(hw, path,
+                                                         &u4regvalue);
+               }
+               for (i = 0; i < RF_REG_NUM_FOR_C_CUT_5G; i++) {
+                       if (i == 0 && (rtlhal->macphymode == DUALMAC_DUALPHY)) {
+                               rtl_set_rfreg(hw, (enum radio_path)path,
+                                             rf_reg_for_c_cut_5g[i],
+                                             BRFREGOFFSETMASK, 0xE439D);
+                       } else if (rf_reg_for_c_cut_5g[i] == RF_SYN_G4) {
+                               u4tmp2 = (rf_reg_pram_c_5g[index][i] &
+                                    0x7FF) | (u4tmp << 11);
+                               if (channel == 36)
+                                       u4tmp2 &= ~(BIT(7) | BIT(6));
+                               rtl_set_rfreg(hw, (enum radio_path)path,
+                                             rf_reg_for_c_cut_5g[i],
+                                             BRFREGOFFSETMASK, u4tmp2);
+                       } else {
+                               rtl_set_rfreg(hw, (enum radio_path)path,
+                                             rf_reg_for_c_cut_5g[i],
+                                             BRFREGOFFSETMASK,
+                                             rf_reg_pram_c_5g[index][i]);
+                       }
+                       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                               ("offset 0x%x value 0x%x "
+                               "path %d index %d readback 0x%x\n",
+                               rf_reg_for_c_cut_5g[i],
+                               rf_reg_pram_c_5g[index][i], path,
+                               index, rtl_get_rfreg(hw, (enum radio_path)path,
+                               rf_reg_for_c_cut_5g[i], BRFREGOFFSETMASK)));
+               }
+               if (need_pwr_down)
+                       _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue);
+               if (rtlhal->during_mac1init_radioa)
+                       rtl92d_phy_powerdown_anotherphy(hw, false);
+               if (channel < 149)
+                       value = 0x07;
+               else if (channel >= 149)
+                       value = 0x02;
+               if (channel >= 36 && channel <= 64)
+                       index = 0;
+               else if (channel >= 100 && channel <= 140)
+                       index = 1;
+               else
+                       index = 2;
+               for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
+                       rfpath++) {
+                       if (rtlhal->macphymode == DUALMAC_DUALPHY &&
+                               rtlhal->interfaceindex == 1)    /* MAC 1 5G */
+                               internal_pa = rtlpriv->efuse.internal_pa_5g[1];
+                       else
+                               internal_pa =
+                                        rtlpriv->efuse.internal_pa_5g[rfpath];
+                       if (internal_pa) {
+                               for (i = 0;
+                                    i < RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA;
+                                    i++) {
+                                       rtl_set_rfreg(hw, rfpath,
+                                               rf_for_c_cut_5g_internal_pa[i],
+                                               BRFREGOFFSETMASK,
+                                               rf_pram_c_5g_int_pa[index][i]);
+                                       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
+                                                ("offset 0x%x value 0x%x "
+                                                "path %d index %d\n",
+                                                rf_for_c_cut_5g_internal_pa[i],
+                                                rf_pram_c_5g_int_pa[index][i],
+                                                rfpath, index));
+                               }
+                       } else {
+                               rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B,
+                                             mask, value);
+                       }
+               }
+       } else if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+               RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>2.4G\n"));
+               u4tmp = curveindex_2g[channel - 1];
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 3 set RF-B, 2G, "
+                       "0x28 = 0x%x !!\n", u4tmp));
+               if (channel == 1 || channel == 2 || channel == 4 || channel == 9
+                   || channel == 10 || channel == 11 || channel == 12)
+                       index = 0;
+               else if (channel == 3 || channel == 13 || channel == 14)
+                       index = 1;
+               else if (channel >= 5 && channel <= 8)
+                       index = 2;
+               if (rtlhal->macphymode == DUALMAC_DUALPHY) {
+                       path = RF90_PATH_A;
+                       if (rtlhal->interfaceindex == 0) {
+                               need_pwr_down =
+                                        rtl92d_phy_enable_anotherphy(hw, true);
+                               rtlhal->during_mac0init_radiob = true;
+
+                               if (need_pwr_down)
+                                       _rtl92d_phy_enable_rf_env(hw, path,
+                                                                 &u4regvalue);
+                       }
+               }
+               for (i = 0; i < RF_REG_NUM_FOR_C_CUT_2G; i++) {
+                       if (rf_reg_for_c_cut_2g[i] == RF_SYN_G7)
+                               rtl_set_rfreg(hw, (enum radio_path)path,
+                                       rf_reg_for_c_cut_2g[i],
+                                       BRFREGOFFSETMASK,
+                                       (rf_reg_param_for_c_cut_2g[index][i] |
+                                       BIT(17)));
+                       else
+                               rtl_set_rfreg(hw, (enum radio_path)path,
+                                             rf_reg_for_c_cut_2g[i],
+                                             BRFREGOFFSETMASK,
+                                             rf_reg_param_for_c_cut_2g
+                                             [index][i]);
+                       RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+                               ("offset 0x%x value 0x%x mak 0x%x path %d "
+                               "index %d readback 0x%x\n",
+                               rf_reg_for_c_cut_2g[i],
+                               rf_reg_param_for_c_cut_2g[index][i],
+                               rf_reg_mask_for_c_cut_2g[i], path, index,
+                               rtl_get_rfreg(hw, (enum radio_path)path,
+                               rf_reg_for_c_cut_2g[i],
+                               BRFREGOFFSETMASK)));
+               }
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       ("cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n",
+                       rf_syn_g4_for_c_cut_2g | (u4tmp << 11)));
+
+               rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4,
+                             BRFREGOFFSETMASK,
+                             rf_syn_g4_for_c_cut_2g | (u4tmp << 11));
+               if (need_pwr_down)
+                       _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue);
+               if (rtlhal->during_mac0init_radiob)
+                       rtl92d_phy_powerdown_anotherphy(hw, true);
+       }
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n"));
+}
+
+u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl)
+{
+       u8 channel_all[59] = {
+               1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+               36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
+               60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
+               114, 116, 118, 120, 122, 124, 126, 128, 130,
+               132, 134, 136, 138, 140, 149, 151, 153, 155,
+               157, 159, 161, 163, 165
+       };
+       u8 place = chnl;
+
+       if (chnl > 14) {
+               for (place = 14; place < sizeof(channel_all); place++) {
+                       if (channel_all[place] == chnl)
+                               return place - 13;
+               }
+       }
+
+       return 0;
+}
+
+#define MAX_TOLERANCE          5
+#define IQK_DELAY_TIME         1       /* ms */
+#define MAX_TOLERANCE_92D      3
+
+/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
+static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u32 regeac, rege94, rege9c, regea4;
+       u8 result = 0;
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK!\n"));
+       /* path-A IQK setting */
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n"));
+       if (rtlhal->interfaceindex == 0) {
+               rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c1f);
+               rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c1f);
+       } else {
+               rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c22);
+               rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c22);
+       }
+       rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140102);
+       rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x28160206);
+       /* path-B IQK setting */
+       if (configpathb) {
+               rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x10008c22);
+               rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x10008c22);
+               rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82140102);
+               rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x28160206);
+       }
+       /* LO calibration setting */
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n"));
+       rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
+       /* One shot, path A LOK & IQK */
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n"));
+       rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000);
+       rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
+       /* delay x ms */
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+               ("Delay %d ms for One shot, path A LOK & IQK.\n",
+               IQK_DELAY_TIME));
+       udelay(IQK_DELAY_TIME * 1000);
+       /* Check failed */
+       regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac));
+       rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD);
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe94 = 0x%x\n", rege94));
+       rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD);
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe9c = 0x%x\n", rege9c));
+       regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD);
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regea4));
+       if (!(regeac & BIT(28)) && (((rege94 & 0x03FF0000) >> 16) != 0x142) &&
+           (((rege9c & 0x03FF0000) >> 16) != 0x42))
+               result |= 0x01;
+       else                    /* if Tx not OK, ignore Rx */
+               return result;
+       /* if Tx is OK, check whether Rx is OK */
+       if (!(regeac & BIT(27)) && (((regea4 & 0x03FF0000) >> 16) != 0x132) &&
+           (((regeac & 0x03FF0000) >> 16) != 0x36))
+               result |= 0x02;
+       else
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A Rx IQK fail!!\n"));
+       return result;
+}
+
+/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
+static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,
+                                         bool configpathb)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u32 regeac, rege94, rege9c, regea4;
+       u8 result = 0;
+       u8 i;
+       u8 retrycount = 2;
+       u32 TxOKBit = BIT(28), RxOKBit = BIT(27);
+
+       if (rtlhal->interfaceindex == 1) {      /* PHY1 */
+               TxOKBit = BIT(31);
+               RxOKBit = BIT(30);
+       }
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK!\n"));
+       /* path-A IQK setting */
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n"));
+       rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f);
+       rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f);
+       rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140307);
+       rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x68160960);
+       /* path-B IQK setting */
+       if (configpathb) {
+               rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x18008c2f);
+               rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x18008c2f);
+               rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82110000);
+               rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68110000);
+       }
+       /* LO calibration setting */
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n"));
+       rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
+       /* path-A PA on */
+       rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x07000f60);
+       rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BMASKDWORD, 0x66e60e30);
+       for (i = 0; i < retrycount; i++) {
+               /* One shot, path A LOK & IQK */
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       ("One shot, path A LOK & IQK!\n"));
+               rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000);
+               rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
+               /* delay x ms */
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       ("Delay %d ms for One shot, path A LOK & IQK.\n",
+                       IQK_DELAY_TIME));
+               udelay(IQK_DELAY_TIME * 1000 * 10);
+               /* Check failed */
+               regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac));
+               rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe94 = 0x%x\n", rege94));
+               rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe9c = 0x%x\n", rege9c));
+               regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regea4));
+               if (!(regeac & TxOKBit) &&
+                    (((rege94 & 0x03FF0000) >> 16) != 0x142)) {
+                       result |= 0x01;
+               } else { /* if Tx not OK, ignore Rx */
+                       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                               ("Path A Tx IQK fail!!\n"));
+                       continue;
+               }
+
+               /* if Tx is OK, check whether Rx is OK */
+               if (!(regeac & RxOKBit) &&
+                   (((regea4 & 0x03FF0000) >> 16) != 0x132)) {
+                       result |= 0x02;
+                       break;
+               } else {
+                       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                               ("Path A Rx IQK fail!!\n"));
+               }
+       }
+       /* path A PA off */
+       rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD,
+                     rtlphy->iqk_bb_backup[0]);
+       rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BMASKDWORD,
+                     rtlphy->iqk_bb_backup[1]);
+       return result;
+}
+
+/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
+static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 regeac, regeb4, regebc, regec4, regecc;
+       u8 result = 0;
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQK!\n"));
+       /* One shot, path B LOK & IQK */
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n"));
+       rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000002);
+       rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000000);
+       /* delay x ms  */
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+               ("Delay %d ms for One shot, path B LOK & IQK.\n",
+               IQK_DELAY_TIME));
+       udelay(IQK_DELAY_TIME * 1000);
+       /* Check failed */
+       regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac));
+       regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD);
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regeb4));
+       regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD);
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xebc = 0x%x\n", regebc));
+       regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD);
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regec4));
+       regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD);
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xecc = 0x%x\n", regecc));
+       if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142) &&
+           (((regebc & 0x03FF0000) >> 16) != 0x42))
+               result |= 0x01;
+       else
+               return result;
+       if (!(regeac & BIT(30)) && (((regec4 & 0x03FF0000) >> 16) != 0x132) &&
+           (((regecc & 0x03FF0000) >> 16) != 0x36))
+               result |= 0x02;
+       else
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B Rx IQK fail!!\n"));
+       return result;
+}
+
+/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
+static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u32 regeac, regeb4, regebc, regec4, regecc;
+       u8 result = 0;
+       u8 i;
+       u8 retrycount = 2;
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQK!\n"));
+       /* path-A IQK setting */
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n"));
+       rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f);
+       rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f);
+       rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82110000);
+       rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x68110000);
+
+       /* path-B IQK setting */
+       rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x18008c2f);
+       rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x18008c2f);
+       rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82140307);
+       rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68160960);
+
+       /* LO calibration setting */
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n"));
+       rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
+
+       /* path-B PA on */
+       rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x0f600700);
+       rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BMASKDWORD, 0x061f0d30);
+
+       for (i = 0; i < retrycount; i++) {
+               /* One shot, path B LOK & IQK */
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       ("One shot, path A LOK & IQK!\n"));
+               rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xfa000000);
+               rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
+
+               /* delay x ms */
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       ("Delay %d ms for One shot, path B LOK & IQK.\n", 10));
+               udelay(IQK_DELAY_TIME * 1000 * 10);
+
+               /* Check failed */
+               regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac));
+               regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regeb4));
+               regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xebc = 0x%x\n", regebc));
+               regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regec4));
+               regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xecc = 0x%x\n", regecc));
+               if (!(regeac & BIT(31)) &&
+                   (((regeb4 & 0x03FF0000) >> 16) != 0x142))
+                       result |= 0x01;
+               else
+                       continue;
+               if (!(regeac & BIT(30)) &&
+                   (((regec4 & 0x03FF0000) >> 16) != 0x132)) {
+                       result |= 0x02;
+                       break;
+               } else {
+                       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                               ("Path B Rx IQK fail!!\n"));
+               }
+       }
+
+       /* path B PA off */
+       rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD,
+                     rtlphy->iqk_bb_backup[0]);
+       rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BMASKDWORD,
+                     rtlphy->iqk_bb_backup[2]);
+       return result;
+}
+
+static void _rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw,
+                                           u32 *adda_reg, u32 *adda_backup,
+                                           u32 regnum)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Save ADDA parameters.\n"));
+       for (i = 0; i < regnum; i++)
+               adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], BMASKDWORD);
+}
+
+static void _rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw,
+       u32 *macreg, u32 *macbackup)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Save MAC parameters.\n"));
+       for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
+               macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
+       macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
+}
+
+static void _rtl92d_phy_reload_adda_registers(struct ieee80211_hw *hw,
+                                             u32 *adda_reg, u32 *adda_backup,
+                                             u32 regnum)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+               ("Reload ADDA power saving parameters !\n"));
+       for (i = 0; i < regnum; i++)
+               rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, adda_backup[i]);
+}
+
+static void _rtl92d_phy_reload_mac_registers(struct ieee80211_hw *hw,
+                                            u32 *macreg, u32 *macbackup)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Reload MAC parameters !\n"));
+       for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
+               rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
+       rtl_write_byte(rtlpriv, macreg[i], macbackup[i]);
+}
+
+static void _rtl92d_phy_path_adda_on(struct ieee80211_hw *hw,
+               u32 *adda_reg, bool patha_on, bool is2t)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 pathon;
+       u32 i;
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ADDA ON.\n"));
+       pathon = patha_on ? 0x04db25a4 : 0x0b1b25a4;
+       if (patha_on)
+               pathon = rtlpriv->rtlhal.interfaceindex == 0 ?
+                   0x04db25a4 : 0x0b1b25a4;
+       for (i = 0; i < IQK_ADDA_REG_NUM; i++)
+               rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, pathon);
+}
+
+static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw,
+                                               u32 *macreg, u32 *macbackup)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 i;
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("MAC settings for Calibration.\n"));
+       rtl_write_byte(rtlpriv, macreg[0], 0x3F);
+
+       for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
+               rtl_write_byte(rtlpriv, macreg[i], (u8)(macbackup[i] &
+                              (~BIT(3))));
+       rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
+}
+
+static void _rtl92d_phy_patha_standby(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A standby mode!\n"));
+
+       rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x0);
+       rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD, 0x00010000);
+       rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000);
+}
+
+static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 mode;
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+               ("BB Switch to %s mode!\n", (pi_mode ? "PI" : "SI")));
+       mode = pi_mode ? 0x01000100 : 0x01000000;
+       rtl_set_bbreg(hw, 0x820, BMASKDWORD, mode);
+       rtl_set_bbreg(hw, 0x828, BMASKDWORD, mode);
+}
+
+static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
+                                    u8 t, bool is2t)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u32 i;
+       u8 patha_ok, pathb_ok;
+       static u32 adda_reg[IQK_ADDA_REG_NUM] = {
+               RFPGA0_XCD_SWITCHCONTROL, 0xe6c, 0xe70, 0xe74,
+               0xe78, 0xe7c, 0xe80, 0xe84,
+               0xe88, 0xe8c, 0xed0, 0xed4,
+               0xed8, 0xedc, 0xee0, 0xeec
+       };
+       static u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
+               0x522, 0x550, 0x551, 0x040
+       };
+       static u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
+               RFPGA0_XAB_RFINTERFACESW, RFPGA0_XA_RFINTERFACEOE,
+               RFPGA0_XB_RFINTERFACEOE, ROFDM0_TRMUXPAR,
+               RFPGA0_XCD_RFINTERFACESW, ROFDM0_TRXPATHENABLE,
+               RFPGA0_RFMOD, RFPGA0_ANALOGPARAMETER4,
+               ROFDM0_XAAGCCORE1, ROFDM0_XBAGCCORE1
+       };
+       const u32 retrycount = 2;
+       u32 bbvalue;
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 2.4G :Start!!!\n"));
+       if (t == 0) {
+               bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQ Calibration for %s\n",
+                       (is2t ? "2T2R" : "1T1R")));
+
+               /*  Save ADDA parameters, turn Path A ADDA on */
+               _rtl92d_phy_save_adda_registers(hw, adda_reg,
+                       rtlphy->adda_backup, IQK_ADDA_REG_NUM);
+               _rtl92d_phy_save_mac_registers(hw, iqk_mac_reg,
+                       rtlphy->iqk_mac_backup);
+               _rtl92d_phy_save_adda_registers(hw, iqk_bb_reg,
+                       rtlphy->iqk_bb_backup, IQK_BB_REG_NUM);
+       }
+       _rtl92d_phy_path_adda_on(hw, adda_reg, true, is2t);
+       if (t == 0)
+               rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
+                               RFPGA0_XA_HSSIPARAMETER1, BIT(8));
+
+       /*  Switch BB to PI mode to do IQ Calibration. */
+       if (!rtlphy->rfpi_enable)
+               _rtl92d_phy_pimode_switch(hw, true);
+
+       rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00);
+       rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKDWORD, 0x03a05600);
+       rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, BMASKDWORD, 0x000800e4);
+       rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, BMASKDWORD, 0x22204000);
+       rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f);
+       if (is2t) {
+               rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD,
+                             0x00010000);
+               rtl_set_bbreg(hw, RFPGA0_XB_LSSIPARAMETER, BMASKDWORD,
+                             0x00010000);
+       }
+       /* MAC settings */
+       _rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg,
+                                           rtlphy->iqk_mac_backup);
+       /* Page B init */
+       rtl_set_bbreg(hw, 0xb68, BMASKDWORD, 0x0f600000);
+       if (is2t)
+               rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000);
+       /* IQ calibration setting */
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK setting!\n"));
+       rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000);
+       rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x01007c00);
+       rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800);
+       for (i = 0; i < retrycount; i++) {
+               patha_ok = _rtl92d_phy_patha_iqk(hw, is2t);
+               if (patha_ok == 0x03) {
+                       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                               ("Path A IQK Success!!\n"));
+                       result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
+                                       0x3FF0000) >> 16;
+                       result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
+                                       0x3FF0000) >> 16;
+                       result[t][2] = (rtl_get_bbreg(hw, 0xea4, BMASKDWORD) &
+                                       0x3FF0000) >> 16;
+                       result[t][3] = (rtl_get_bbreg(hw, 0xeac, BMASKDWORD) &
+                                       0x3FF0000) >> 16;
+                       break;
+               } else if (i == (retrycount - 1) && patha_ok == 0x01) {
+                       /* Tx IQK OK */
+                       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                               ("Path A IQK Only  Tx Success!!\n"));
+
+                       result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
+                                       0x3FF0000) >> 16;
+                       result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
+                                       0x3FF0000) >> 16;
+               }
+       }
+       if (0x00 == patha_ok)
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK failed!!\n"));
+       if (is2t) {
+               _rtl92d_phy_patha_standby(hw);
+               /* Turn Path B ADDA on */
+               _rtl92d_phy_path_adda_on(hw, adda_reg, false, is2t);
+               for (i = 0; i < retrycount; i++) {
+                       pathb_ok = _rtl92d_phy_pathb_iqk(hw);
+                       if (pathb_ok == 0x03) {
+                               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                                       ("Path B IQK Success!!\n"));
+                               result[t][4] = (rtl_get_bbreg(hw, 0xeb4,
+                                              BMASKDWORD) & 0x3FF0000) >> 16;
+                               result[t][5] = (rtl_get_bbreg(hw, 0xebc,
+                                              BMASKDWORD) & 0x3FF0000) >> 16;
+                               result[t][6] = (rtl_get_bbreg(hw, 0xec4,
+                                              BMASKDWORD) & 0x3FF0000) >> 16;
+                               result[t][7] = (rtl_get_bbreg(hw, 0xecc,
+                                              BMASKDWORD) & 0x3FF0000) >> 16;
+                               break;
+                       } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
+                               /* Tx IQK OK */
+                               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                                       ("Path B Only Tx IQK Success!!\n"));
+                               result[t][4] = (rtl_get_bbreg(hw, 0xeb4,
+                                              BMASKDWORD) & 0x3FF0000) >> 16;
+                               result[t][5] = (rtl_get_bbreg(hw, 0xebc,
+                                              BMASKDWORD) & 0x3FF0000) >> 16;
+                       }
+               }
+               if (0x00 == pathb_ok)
+                       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                               ("Path B IQK failed!!\n"));
+       }
+
+       /* Back to BB mode, load original value */
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+               ("IQK:Back to BB mode, load original value!\n"));
+
+       rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0);
+       if (t != 0) {
+               /* Switch back BB to SI mode after finish IQ Calibration. */
+               if (!rtlphy->rfpi_enable)
+                       _rtl92d_phy_pimode_switch(hw, false);
+               /* Reload ADDA power saving parameters */
+               _rtl92d_phy_reload_adda_registers(hw, adda_reg,
+                               rtlphy->adda_backup, IQK_ADDA_REG_NUM);
+               /* Reload MAC parameters */
+               _rtl92d_phy_reload_mac_registers(hw, iqk_mac_reg,
+                                       rtlphy->iqk_mac_backup);
+               if (is2t)
+                       _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg,
+                                                         rtlphy->iqk_bb_backup,
+                                                         IQK_BB_REG_NUM);
+               else
+                       _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg,
+                                                         rtlphy->iqk_bb_backup,
+                                                         IQK_BB_REG_NUM - 1);
+               /* load 0xe30 IQC default value */
+               rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x01008c00);
+               rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x01008c00);
+       }
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("<==\n"));
+}
+
+static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
+                                              long result[][8], u8 t)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
+       u8 patha_ok, pathb_ok;
+       static u32 adda_reg[IQK_ADDA_REG_NUM] = {
+               RFPGA0_XCD_SWITCHCONTROL, 0xe6c, 0xe70, 0xe74,
+               0xe78, 0xe7c, 0xe80, 0xe84,
+               0xe88, 0xe8c, 0xed0, 0xed4,
+               0xed8, 0xedc, 0xee0, 0xeec
+       };
+       static u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
+               0x522, 0x550, 0x551, 0x040
+       };
+       static u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
+               RFPGA0_XAB_RFINTERFACESW, RFPGA0_XA_RFINTERFACEOE,
+               RFPGA0_XB_RFINTERFACEOE, ROFDM0_TRMUXPAR,
+               RFPGA0_XCD_RFINTERFACESW, ROFDM0_TRXPATHENABLE,
+               RFPGA0_RFMOD, RFPGA0_ANALOGPARAMETER4,
+               ROFDM0_XAAGCCORE1, ROFDM0_XBAGCCORE1
+       };
+       u32 bbvalue;
+       bool is2t = IS_92D_SINGLEPHY(rtlhal->version);
+
+       /* Note: IQ calibration must be performed after loading
+        * PHY_REG.txt , and radio_a, radio_b.txt */
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 5G NORMAL:Start!!!\n"));
+       udelay(IQK_DELAY_TIME * 1000 * 20);
+       if (t == 0) {
+               bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQ Calibration for %s\n",
+                       (is2t ? "2T2R" : "1T1R")));
+               /* Save ADDA parameters, turn Path A ADDA on */
+               _rtl92d_phy_save_adda_registers(hw, adda_reg,
+                                               rtlphy->adda_backup,
+                                               IQK_ADDA_REG_NUM);
+               _rtl92d_phy_save_mac_registers(hw, iqk_mac_reg,
+                                              rtlphy->iqk_mac_backup);
+               if (is2t)
+                       _rtl92d_phy_save_adda_registers(hw, iqk_bb_reg,
+                                                       rtlphy->iqk_bb_backup,
+                                                       IQK_BB_REG_NUM);
+               else
+                       _rtl92d_phy_save_adda_registers(hw, iqk_bb_reg,
+                                                       rtlphy->iqk_bb_backup,
+                                                       IQK_BB_REG_NUM - 1);
+       }
+       _rtl92d_phy_path_adda_on(hw, adda_reg, true, is2t);
+       /* MAC settings */
+       _rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg,
+                       rtlphy->iqk_mac_backup);
+       if (t == 0)
+               rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
+                       RFPGA0_XA_HSSIPARAMETER1, BIT(8));
+       /*  Switch BB to PI mode to do IQ Calibration. */
+       if (!rtlphy->rfpi_enable)
+               _rtl92d_phy_pimode_switch(hw, true);
+       rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00);
+       rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKDWORD, 0x03a05600);
+       rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, BMASKDWORD, 0x000800e4);
+       rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, BMASKDWORD, 0x22208000);
+       rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f);
+
+       /* Page B init */
+       rtl_set_bbreg(hw, 0xb68, BMASKDWORD, 0x0f600000);
+       if (is2t)
+               rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000);
+       /* IQ calibration setting  */
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK setting!\n"));
+       rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000);
+       rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x10007c00);
+       rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800);
+       patha_ok = _rtl92d_phy_patha_iqk_5g_normal(hw, is2t);
+       if (patha_ok == 0x03) {
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK Success!!\n"));
+               result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
+                               0x3FF0000) >> 16;
+               result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
+                               0x3FF0000) >> 16;
+               result[t][2] = (rtl_get_bbreg(hw, 0xea4, BMASKDWORD) &
+                               0x3FF0000) >> 16;
+               result[t][3] = (rtl_get_bbreg(hw, 0xeac, BMASKDWORD) &
+                               0x3FF0000) >> 16;
+       } else if (patha_ok == 0x01) {  /* Tx IQK OK */
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       ("Path A IQK Only  Tx Success!!\n"));
+
+               result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
+                               0x3FF0000) >> 16;
+               result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
+                               0x3FF0000) >> 16;
+       } else {
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK Fail!!\n"));
+       }
+       if (is2t) {
+               /* _rtl92d_phy_patha_standby(hw); */
+               /* Turn Path B ADDA on  */
+               _rtl92d_phy_path_adda_on(hw, adda_reg, false, is2t);
+               pathb_ok = _rtl92d_phy_pathb_iqk_5g_normal(hw);
+               if (pathb_ok == 0x03) {
+                       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                               ("Path B IQK Success!!\n"));
+                       result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) &
+                            0x3FF0000) >> 16;
+                       result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) &
+                            0x3FF0000) >> 16;
+                       result[t][6] = (rtl_get_bbreg(hw, 0xec4, BMASKDWORD) &
+                            0x3FF0000) >> 16;
+                       result[t][7] = (rtl_get_bbreg(hw, 0xecc, BMASKDWORD) &
+                            0x3FF0000) >> 16;
+               } else if (pathb_ok == 0x01) { /* Tx IQK OK */
+                       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                               ("Path B Only Tx IQK Success!!\n"));
+                       result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) &
+                            0x3FF0000) >> 16;
+                       result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) &
+                            0x3FF0000) >> 16;
+               } else {
+                       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                               ("Path B IQK failed!!\n"));
+               }
+       }
+
+       /* Back to BB mode, load original value */
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+               ("IQK:Back to BB mode, load original value!\n"));
+       rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0);
+       if (t != 0) {
+               if (is2t)
+                       _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg,
+                                                         rtlphy->iqk_bb_backup,
+                                                         IQK_BB_REG_NUM);
+               else
+                       _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg,
+                                                         rtlphy->iqk_bb_backup,
+                                                         IQK_BB_REG_NUM - 1);
+               /* Reload MAC parameters */
+               _rtl92d_phy_reload_mac_registers(hw, iqk_mac_reg,
+                               rtlphy->iqk_mac_backup);
+               /*  Switch back BB to SI mode after finish IQ Calibration. */
+               if (!rtlphy->rfpi_enable)
+                       _rtl92d_phy_pimode_switch(hw, false);
+               /* Reload ADDA power saving parameters */
+               _rtl92d_phy_reload_adda_registers(hw, adda_reg,
+                                                 rtlphy->adda_backup,
+                                                 IQK_ADDA_REG_NUM);
+       }
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("<==\n"));
+}
+
+static bool _rtl92d_phy_simularity_compare(struct ieee80211_hw *hw,
+       long result[][8], u8 c1, u8 c2)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
+       u32 i, j, diff, sim_bitmap, bound;
+       u8 final_candidate[2] = {0xFF, 0xFF};   /* for path A and path B */
+       bool bresult = true;
+       bool is2t = IS_92D_SINGLEPHY(rtlhal->version);
+
+       if (is2t)
+               bound = 8;
+       else
+               bound = 4;
+       sim_bitmap = 0;
+       for (i = 0; i < bound; i++) {
+               diff = (result[c1][i] > result[c2][i]) ? (result[c1][i] -
+                      result[c2][i]) : (result[c2][i] - result[c1][i]);
+               if (diff > MAX_TOLERANCE_92D) {
+                       if ((i == 2 || i == 6) && !sim_bitmap) {
+                               if (result[c1][i] + result[c1][i + 1] == 0)
+                                       final_candidate[(i / 4)] = c2;
+                               else if (result[c2][i] + result[c2][i + 1] == 0)
+                                       final_candidate[(i / 4)] = c1;
+                               else
+                                       sim_bitmap = sim_bitmap | (1 << i);
+                       } else {
+                               sim_bitmap = sim_bitmap | (1 << i);
+                       }
+               }
+       }
+       if (sim_bitmap == 0) {
+               for (i = 0; i < (bound / 4); i++) {
+                       if (final_candidate[i] != 0xFF) {
+                               for (j = i * 4; j < (i + 1) * 4 - 2; j++)
+                                       result[3][j] =
+                                                result[final_candidate[i]][j];
+                               bresult = false;
+                       }
+               }
+               return bresult;
+       }
+       if (!(sim_bitmap & 0x0F)) { /* path A OK */
+               for (i = 0; i < 4; i++)
+                       result[3][i] = result[c1][i];
+       } else if (!(sim_bitmap & 0x03)) { /* path A, Tx OK */
+               for (i = 0; i < 2; i++)
+                       result[3][i] = result[c1][i];
+       }
+       if (!(sim_bitmap & 0xF0) && is2t) { /* path B OK */
+               for (i = 4; i < 8; i++)
+                       result[3][i] = result[c1][i];
+       } else if (!(sim_bitmap & 0x30)) { /* path B, Tx OK */
+               for (i = 4; i < 6; i++)
+                       result[3][i] = result[c1][i];
+       }
+       return false;
+}
+
+static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,
+                                             bool iqk_ok, long result[][8],
+                                             u8 final_candidate, bool txonly)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
+       u32 oldval_0, val_x, tx0_a, reg;
+       long val_y, tx0_c;
+       bool is2t = IS_92D_SINGLEPHY(rtlhal->version) ||
+           rtlhal->macphymode == DUALMAC_DUALPHY;
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+               ("Path A IQ Calibration %s !\n",
+               (iqk_ok) ? "Success" : "Failed"));
+       if (final_candidate == 0xFF) {
+               return;
+       } else if (iqk_ok) {
+               oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
+                       BMASKDWORD) >> 22) & 0x3FF;     /* OFDM0_D */
+               val_x = result[final_candidate][0];
+               if ((val_x & 0x00000200) != 0)
+                       val_x = val_x | 0xFFFFFC00;
+               tx0_a = (val_x * oldval_0) >> 8;
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("X = 0x%x, tx0_a = 0x%x,"
+                       " oldval_0 0x%x\n",     val_x, tx0_a, oldval_0));
+               rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x3FF, tx0_a);
+               rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
+                             ((val_x * oldval_0 >> 7) & 0x1));
+               val_y = result[final_candidate][1];
+               if ((val_y & 0x00000200) != 0)
+                       val_y = val_y | 0xFFFFFC00;
+               /* path B IQK result + 3 */
+               if (rtlhal->interfaceindex == 1 &&
+                       rtlhal->current_bandtype == BAND_ON_5G)
+                       val_y += 3;
+               tx0_c = (val_y * oldval_0) >> 8;
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Y = 0x%lx, tx0_c = 0x%lx\n",
+                       val_y, tx0_c));
+               rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000,
+                             ((tx0_c & 0x3C0) >> 6));
+               rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x003F0000,
+                             (tx0_c & 0x3F));
+               if (is2t)
+                       rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(26),
+                                     ((val_y * oldval_0 >> 7) & 0x1));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xC80 = 0x%x\n",
+                        rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
+                                      BMASKDWORD)));
+               if (txonly) {
+                       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("only Tx OK\n"));
+                       return;
+               }
+               reg = result[final_candidate][2];
+               rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
+               reg = result[final_candidate][3] & 0x3F;
+               rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
+               reg = (result[final_candidate][3] >> 6) & 0xF;
+               rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
+       }
+}
+
+static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw,
+       bool iqk_ok, long result[][8], u8 final_candidate, bool txonly)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
+       u32 oldval_1, val_x, tx1_a, reg;
+       long val_y, tx1_c;
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQ Calibration %s !\n",
+                (iqk_ok) ? "Success" : "Failed"));
+       if (final_candidate == 0xFF) {
+               return;
+       } else if (iqk_ok) {
+               oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTxIQIMBALANCE,
+                                         BMASKDWORD) >> 22) & 0x3FF;
+               val_x = result[final_candidate][4];
+               if ((val_x & 0x00000200) != 0)
+                       val_x = val_x | 0xFFFFFC00;
+               tx1_a = (val_x * oldval_1) >> 8;
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("X = 0x%x, tx1_a = 0x%x\n",
+                       val_x, tx1_a));
+               rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x3FF, tx1_a);
+               rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28),
+                             ((val_x * oldval_1 >> 7) & 0x1));
+               val_y = result[final_candidate][5];
+               if ((val_y & 0x00000200) != 0)
+                       val_y = val_y | 0xFFFFFC00;
+               if (rtlhal->current_bandtype == BAND_ON_5G)
+                       val_y += 3;
+               tx1_c = (val_y * oldval_1) >> 8;
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Y = 0x%lx, tx1_c = 0x%lx\n",
+                       val_y, tx1_c));
+               rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 0xF0000000,
+                             ((tx1_c & 0x3C0) >> 6));
+               rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x003F0000,
+                             (tx1_c & 0x3F));
+               rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30),
+                             ((val_y * oldval_1 >> 7) & 0x1));
+               if (txonly)
+                       return;
+               reg = result[final_candidate][6];
+               rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
+               reg = result[final_candidate][7] & 0x3F;
+               rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
+               reg = (result[final_candidate][7] >> 6) & 0xF;
+               rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg);
+       }
+}
+
+void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
+       long result[4][8];
+       u8 i, final_candidate, indexforchannel;
+       bool patha_ok, pathb_ok;
+       long rege94, rege9c, regea4, regeac, regeb4;
+       long regebc, regec4, regecc, regtmp = 0;
+       bool is12simular, is13simular, is23simular;
+       unsigned long flag = 0;
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+               ("IQK:Start!!!channel %d\n", rtlphy->current_channel));
+       for (i = 0; i < 8; i++) {
+               result[0][i] = 0;
+               result[1][i] = 0;
+               result[2][i] = 0;
+               result[3][i] = 0;
+       }
+       final_candidate = 0xff;
+       patha_ok = false;
+       pathb_ok = false;
+       is12simular = false;
+       is23simular = false;
+       is13simular = false;
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+               ("IQK !!!currentband %d\n", rtlhal->current_bandtype));
+       rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
+       for (i = 0; i < 3; i++) {
+               if (rtlhal->current_bandtype == BAND_ON_5G) {
+                       _rtl92d_phy_iq_calibrate_5g_normal(hw, result, i);
+               } else if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+                       if (IS_92D_SINGLEPHY(rtlhal->version))
+                               _rtl92d_phy_iq_calibrate(hw, result, i, true);
+                       else
+                               _rtl92d_phy_iq_calibrate(hw, result, i, false);
+               }
+               if (i == 1) {
+                       is12simular = _rtl92d_phy_simularity_compare(hw, result,
+                                                                    0, 1);
+                       if (is12simular) {
+                               final_candidate = 0;
+                               break;
+                       }
+               }
+               if (i == 2) {
+                       is13simular = _rtl92d_phy_simularity_compare(hw, result,
+                                                                    0, 2);
+                       if (is13simular) {
+                               final_candidate = 0;
+                               break;
+                       }
+                       is23simular = _rtl92d_phy_simularity_compare(hw, result,
+                                                                    1, 2);
+                       if (is23simular) {
+                               final_candidate = 1;
+                       } else {
+                               for (i = 0; i < 8; i++)
+                                       regtmp += result[3][i];
+
+                               if (regtmp != 0)
+                                       final_candidate = 3;
+                               else
+                                       final_candidate = 0xFF;
+                       }
+               }
+       }
+       rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
+       for (i = 0; i < 4; i++) {
+               rege94 = result[i][0];
+               rege9c = result[i][1];
+               regea4 = result[i][2];
+               regeac = result[i][3];
+               regeb4 = result[i][4];
+               regebc = result[i][5];
+               regec4 = result[i][6];
+               regecc = result[i][7];
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       ("IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx "
+                       "regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n ",
+                       rege94, rege9c, regea4, regeac, regeb4, regebc, regec4,
+                       regecc));
+       }
+       if (final_candidate != 0xff) {
+               rtlphy->reg_e94 = rege94 = result[final_candidate][0];
+               rtlphy->reg_e9c = rege9c = result[final_candidate][1];
+               regea4 = result[final_candidate][2];
+               regeac = result[final_candidate][3];
+               rtlphy->reg_eb4 = regeb4 = result[final_candidate][4];
+               rtlphy->reg_ebc = regebc = result[final_candidate][5];
+               regec4 = result[final_candidate][6];
+               regecc = result[final_candidate][7];
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       ("IQK: final_candidate is %x\n", final_candidate));
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       ("IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx "
+                       "regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n ",
+                       rege94, rege9c, regea4, regeac, regeb4, regebc, regec4,
+                       regecc));
+               patha_ok = pathb_ok = true;
+       } else {
+               rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; /* X default value */
+               rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;   /* Y default value */
+       }
+       if ((rege94 != 0) /*&&(regea4 != 0) */)
+               _rtl92d_phy_patha_fill_iqk_matrix(hw, patha_ok, result,
+                               final_candidate, (regea4 == 0));
+       if (IS_92D_SINGLEPHY(rtlhal->version)) {
+               if ((regeb4 != 0) /*&&(regec4 != 0) */)
+                       _rtl92d_phy_pathb_fill_iqk_matrix(hw, pathb_ok, result,
+                                               final_candidate, (regec4 == 0));
+       }
+       if (final_candidate != 0xFF) {
+               indexforchannel = rtl92d_get_rightchnlplace_for_iqk(
+                                 rtlphy->current_channel);
+
+               for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
+                       rtlphy->iqk_matrix_regsetting[indexforchannel].
+                               value[0][i] = result[final_candidate][i];
+               rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done =
+                       true;
+
+               RT_TRACE(rtlpriv, COMP_SCAN | COMP_MLME, DBG_LOUD,
+                        ("\nIQK OK indexforchannel %d.\n", indexforchannel));
+       }
+}
+
+void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
+       u8 indexforchannel;
+
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("channel %d\n", channel));
+       /*------Do IQK for normal chip and test chip 5G band------- */
+       indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel);
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+               ("indexforchannel %d done %d\n", indexforchannel,
+               rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done));
+       if (0 && !rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done &&
+               rtlphy->need_iqk) {
+               /* Re Do IQK. */
+               RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_LOUD,
+                        ("Do IQK Matrix reg for channel:%d....\n", channel));
+               rtl92d_phy_iq_calibrate(hw);
+       } else {
+               /* Just load the value. */
+               /* 2G band just load once. */
+               if (((!rtlhal->load_imrandiqk_setting_for2g) &&
+                   indexforchannel == 0) || indexforchannel > 0) {
+                       RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
+                                ("Just Read IQK Matrix reg for channel:%d"
+                                "....\n", channel));
+                       if ((rtlphy->iqk_matrix_regsetting[indexforchannel].
+                            value[0] != NULL)
+                               /*&&(regea4 != 0) */)
+                               _rtl92d_phy_patha_fill_iqk_matrix(hw, true,
+                                       rtlphy->iqk_matrix_regsetting[
+                                       indexforchannel].value, 0,
+                                       (rtlphy->iqk_matrix_regsetting[
+                                       indexforchannel].value[0][2] == 0));
+                       if (IS_92D_SINGLEPHY(rtlhal->version)) {
+                               if ((rtlphy->iqk_matrix_regsetting[
+                                       indexforchannel].value[0][4] != 0)
+                                       /*&&(regec4 != 0) */)
+                                       _rtl92d_phy_pathb_fill_iqk_matrix(hw,
+                                               true,
+                                               rtlphy->iqk_matrix_regsetting[
+                                               indexforchannel].value, 0,
+                                               (rtlphy->iqk_matrix_regsetting[
+                                               indexforchannel].value[0][6]
+                                               == 0));
+                       }
+               }
+       }
+       rtlphy->need_iqk = false;
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n"));
+}
+
+static u32 _rtl92d_phy_get_abs(u32 val1, u32 val2)
+{
+       u32 ret;
+
+       if (val1 >= val2)
+               ret = val1 - val2;
+       else
+               ret = val2 - val1;
+       return ret;
+}
+
+static bool _rtl92d_is_legal_5g_channel(struct ieee80211_hw *hw, u8 channel)
+{
+
+       int i;
+       u8 channel_5g[45] = {
+               36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
+               60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
+               114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
+               134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
+               161, 163, 165
+       };
+
+       for (i = 0; i < sizeof(channel_5g); i++)
+               if (channel == channel_5g[i])
+                       return true;
+       return false;
+}
+
+static void _rtl92d_phy_calc_curvindex(struct ieee80211_hw *hw,
+                                      u32 *targetchnl, u32 * curvecount_val,
+                                      bool is5g, u32 *curveindex)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 smallest_abs_val = 0xffffffff, u4tmp;
+       u8 i, j;
+       u8 chnl_num = is5g ? TARGET_CHNL_NUM_5G : TARGET_CHNL_NUM_2G;
+
+       for (i = 0; i < chnl_num; i++) {
+               if (is5g && !_rtl92d_is_legal_5g_channel(hw, i + 1))
+                       continue;
+               curveindex[i] = 0;
+               for (j = 0; j < (CV_CURVE_CNT * 2); j++) {
+                       u4tmp = _rtl92d_phy_get_abs(targetchnl[i],
+                               curvecount_val[j]);
+
+                       if (u4tmp < smallest_abs_val) {
+                               curveindex[i] = j;
+                               smallest_abs_val = u4tmp;
+                       }
+               }
+               smallest_abs_val = 0xffffffff;
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("curveindex[%d] = %x\n", i,
+                       curveindex[i]));
+       }
+}
+
+static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw,
+               u8 channel)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 erfpath = rtlpriv->rtlhal.current_bandtype ==
+               BAND_ON_5G ? RF90_PATH_A :
+               IS_92D_SINGLEPHY(rtlpriv->rtlhal.version) ?
+               RF90_PATH_B : RF90_PATH_A;
+       u32 u4tmp = 0, u4regvalue = 0;
+       bool bneed_powerdown_radio = false;
+
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("path %d\n", erfpath));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("band type = %d\n",
+               rtlpriv->rtlhal.current_bandtype));
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("channel = %d\n", channel));
+       if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */
+               u4tmp = curveindex_5g[channel-1];
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       ("ver 1 set RF-A, 5G,   0x28 = 0x%ulx !!\n", u4tmp));
+               if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY &&
+                       rtlpriv->rtlhal.interfaceindex == 1) {
+                       bneed_powerdown_radio =
+                               rtl92d_phy_enable_anotherphy(hw, false);
+                       rtlpriv->rtlhal.during_mac1init_radioa = true;
+                       /* asume no this case */
+                       if (bneed_powerdown_radio)
+                               _rtl92d_phy_enable_rf_env(hw, erfpath,
+                                                         &u4regvalue);
+               }
+               rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp);
+               if (bneed_powerdown_radio)
+                       _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue);
+               if (rtlpriv->rtlhal.during_mac1init_radioa)
+                       rtl92d_phy_powerdown_anotherphy(hw, false);
+       } else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) {
+               u4tmp = curveindex_2g[channel-1];
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       ("ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp));
+               if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY &&
+                       rtlpriv->rtlhal.interfaceindex == 0) {
+                       bneed_powerdown_radio =
+                               rtl92d_phy_enable_anotherphy(hw, true);
+                       rtlpriv->rtlhal.during_mac0init_radiob = true;
+                       if (bneed_powerdown_radio)
+                               _rtl92d_phy_enable_rf_env(hw, erfpath,
+                                                         &u4regvalue);
+               }
+               rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       ("ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n",
+                       rtl_get_rfreg(hw,  erfpath, RF_SYN_G4, 0x3f800)));
+               if (bneed_powerdown_radio)
+                       _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue);
+               if (rtlpriv->rtlhal.during_mac0init_radiob)
+                       rtl92d_phy_powerdown_anotherphy(hw, true);
+       }
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n"));
+}
+
+static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       u8 tmpreg, index, rf_mode[2];
+       u8 path = is2t ? 2 : 1;
+       u8 i;
+       u32 u4tmp, offset;
+       u32 curvecount_val[CV_CURVE_CNT * 2] = {0};
+       u16 timeout = 800, timecount = 0;
+
+       /* Check continuous TX and Packet TX */
+       tmpreg = rtl_read_byte(rtlpriv, 0xd03);
+       /* if Deal with contisuous TX case, disable all continuous TX */
+       /* if Deal with Packet TX case, block all queues */
+       if ((tmpreg & 0x70) != 0)
+               rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
+       else
+               rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
+       rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xF00000, 0x0F);
+       for (index = 0; index < path; index++) {
+               /* 1. Read original RF mode */
+               offset = index == 0 ? ROFDM0_XAAGCCORE1 : ROFDM0_XBAGCCORE1;
+               rf_mode[index] = rtl_read_byte(rtlpriv, offset);
+               /* 2. Set RF mode = standby mode */
+               rtl_set_rfreg(hw, (enum radio_path)index, RF_AC,
+                             BRFREGOFFSETMASK, 0x010000);
+               if (rtlpci->init_ready) {
+                       /* switch CV-curve control by LC-calibration */
+                       rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7,
+                                     BIT(17), 0x0);
+                       /* 4. Set LC calibration begin */
+                       rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW,
+                                     0x08000, 0x01);
+               }
+               u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, RF_SYN_G6,
+                                 BRFREGOFFSETMASK);
+               while ((!(u4tmp & BIT(11))) && timecount <= timeout) {
+                       mdelay(50);
+                       timecount += 50;
+                       u4tmp = rtl_get_rfreg(hw, (enum radio_path)index,
+                                             RF_SYN_G6, BRFREGOFFSETMASK);
+               }
+               RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                       ("PHY_LCK finish delay for %d ms=2\n", timecount));
+               u4tmp = rtl_get_rfreg(hw, index, RF_SYN_G4, BRFREGOFFSETMASK);
+               if (index == 0 && rtlhal->interfaceindex == 0) {
+                       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                               ("path-A / 5G LCK\n"));
+               } else {
+                       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+                               ("path-B / 2.4G LCK\n"));
+               }
+               memset(&curvecount_val[0], 0, CV_CURVE_CNT * 2);
+               /* Set LC calibration off */
+               rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW,
+                             0x08000, 0x0);
+               RTPRINT(rtlpriv, FINIT, INIT_IQK, ("set RF 0x18[15] = 0\n"));
+               /* save Curve-counting number */
+               for (i = 0; i < CV_CURVE_CNT; i++) {
+                       u32 readval = 0, readval2 = 0;
+                       rtl_set_rfreg(hw, (enum radio_path)index, 0x3F,
+                                     0x7f, i);
+
+                       rtl_set_rfreg(hw, (enum radio_path)index, 0x4D,
+                               BRFREGOFFSETMASK, 0x0);
+                       readval = rtl_get_rfreg(hw, (enum radio_path)index,
+                                         0x4F, BRFREGOFFSETMASK);
+                       curvecount_val[2 * i + 1] = (readval & 0xfffe0) >> 5;
+                       /* reg 0x4f [4:0] */
+                       /* reg 0x50 [19:10] */
+                       readval2 = rtl_get_rfreg(hw, (enum radio_path)index,
+                                                0x50, 0xffc00);
+                       curvecount_val[2 * i] = (((readval & 0x1F) << 10) |
+                                                readval2);
+               }
+               if (index == 0 && rtlhal->interfaceindex == 0)
+                       _rtl92d_phy_calc_curvindex(hw, targetchnl_5g,
+                                                  curvecount_val,
+                                                  true, curveindex_5g);
+               else
+                       _rtl92d_phy_calc_curvindex(hw, targetchnl_2g,
+                                                  curvecount_val,
+                                                  false, curveindex_2g);
+               /* switch CV-curve control mode */
+               rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7,
+                             BIT(17), 0x1);
+       }
+
+       /* Restore original situation  */
+       for (index = 0; index < path; index++) {
+               offset = index == 0 ? ROFDM0_XAAGCCORE1 : ROFDM0_XBAGCCORE1;
+               rtl_write_byte(rtlpriv, offset, 0x50);
+               rtl_write_byte(rtlpriv, offset, rf_mode[index]);
+       }
+       if ((tmpreg & 0x70) != 0)
+               rtl_write_byte(rtlpriv, 0xd03, tmpreg);
+       else /*Deal with Packet TX case */
+               rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
+       rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xF00000, 0x00);
+       _rtl92d_phy_reload_lck_setting(hw, rtlpriv->phy.current_channel);
+}
+
+static void _rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("cosa PHY_LCK ver=2\n"));
+       _rtl92d_phy_lc_calibrate_sw(hw, is2t);
+}
+
+void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
+       u32 timeout = 2000, timecount = 0;
+
+       while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
+               udelay(50);
+               timecount += 50;
+       }
+
+       rtlphy->lck_inprogress = true;
+       RTPRINT(rtlpriv, FINIT, INIT_IQK,
+               ("LCK:Start!!! currentband %x delay %d ms\n",
+                rtlhal->current_bandtype, timecount));
+       if (IS_92D_SINGLEPHY(rtlhal->version)) {
+               _rtl92d_phy_lc_calibrate(hw, true);
+       } else {
+               /* For 1T1R */
+               _rtl92d_phy_lc_calibrate(hw, false);
+       }
+       rtlphy->lck_inprogress = false;
+       RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LCK:Finish!!!\n"));
+}
+
+void rtl92d_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
+{
+       return;
+}
+
+static bool _rtl92d_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
+               u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid,
+               u32 para1, u32 para2, u32 msdelay)
+{
+       struct swchnlcmd *pcmd;
+
+       if (cmdtable == NULL) {
+               RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
+               return false;
+       }
+       if (cmdtableidx >= cmdtablesz)
+               return false;
+
+       pcmd = cmdtable + cmdtableidx;
+       pcmd->cmdid = cmdid;
+       pcmd->para1 = para1;
+       pcmd->para2 = para2;
+       pcmd->msdelay = msdelay;
+       return true;
+}
+
+void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 i;
+
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                       ("settings regs %d default regs %d\n",
+                       (int)(sizeof(rtlphy->iqk_matrix_regsetting) /
+                       sizeof(struct iqk_matrix_regs)),
+                       IQK_MATRIX_REG_NUM));
+       /* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */
+       for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
+               rtlphy->iqk_matrix_regsetting[i].value[0][0] = 0x100;
+               rtlphy->iqk_matrix_regsetting[i].value[0][2] = 0x100;
+               rtlphy->iqk_matrix_regsetting[i].value[0][4] = 0x100;
+               rtlphy->iqk_matrix_regsetting[i].value[0][6] = 0x100;
+               rtlphy->iqk_matrix_regsetting[i].value[0][1] = 0x0;
+               rtlphy->iqk_matrix_regsetting[i].value[0][3] = 0x0;
+               rtlphy->iqk_matrix_regsetting[i].value[0][5] = 0x0;
+               rtlphy->iqk_matrix_regsetting[i].value[0][7] = 0x0;
+               rtlphy->iqk_matrix_regsetting[i].iqk_done = false;
+       }
+}
+
+static bool _rtl92d_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
+                                            u8 channel, u8 *stage, u8 *step,
+                                            u32 *delay)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
+       u32 precommoncmdcnt;
+       struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
+       u32 postcommoncmdcnt;
+       struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
+       u32 rfdependcmdcnt;
+       struct swchnlcmd *currentcmd = NULL;
+       u8 rfpath;
+       u8 num_total_rfpath = rtlphy->num_total_rfpath;
+
+       precommoncmdcnt = 0;
+       _rtl92d_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
+                                        MAX_PRECMD_CNT,
+                                        CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
+       _rtl92d_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
+                                        MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
+       postcommoncmdcnt = 0;
+       _rtl92d_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
+                                        MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
+       rfdependcmdcnt = 0;
+       _rtl92d_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
+                                        MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
+                                        RF_CHNLBW, channel, 0);
+       _rtl92d_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
+                                        MAX_RFDEPENDCMD_CNT, CMDID_END,
+                                        0, 0, 0);
+
+       do {
+               switch (*stage) {
+               case 0:
+                       currentcmd = &precommoncmd[*step];
+                       break;
+               case 1:
+                       currentcmd = &rfdependcmd[*step];
+                       break;
+               case 2:
+                       currentcmd = &postcommoncmd[*step];
+                       break;
+               }
+               if (currentcmd->cmdid == CMDID_END) {
+                       if ((*stage) == 2) {
+                               return true;
+                       } else {
+                               (*stage)++;
+                               (*step) = 0;
+                               continue;
+                       }
+               }
+               switch (currentcmd->cmdid) {
+               case CMDID_SET_TXPOWEROWER_LEVEL:
+                       rtl92d_phy_set_txpower_level(hw, channel);
+                       break;
+               case CMDID_WRITEPORT_ULONG:
+                       rtl_write_dword(rtlpriv, currentcmd->para1,
+                                       currentcmd->para2);
+                       break;
+               case CMDID_WRITEPORT_USHORT:
+                       rtl_write_word(rtlpriv, currentcmd->para1,
+                                      (u16)currentcmd->para2);
+                       break;
+               case CMDID_WRITEPORT_UCHAR:
+                       rtl_write_byte(rtlpriv, currentcmd->para1,
+                                      (u8)currentcmd->para2);
+                       break;
+               case CMDID_RF_WRITEREG:
+                       for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
+                               rtlphy->rfreg_chnlval[rfpath] =
+                                       ((rtlphy->rfreg_chnlval[rfpath] &
+                                       0xffffff00) | currentcmd->para2);
+                               if (rtlpriv->rtlhal.current_bandtype ==
+                                   BAND_ON_5G) {
+                                       if (currentcmd->para2 > 99)
+                                               rtlphy->rfreg_chnlval[rfpath] =
+                                                   rtlphy->rfreg_chnlval
+                                                   [rfpath] | (BIT(18));
+                                       else
+                                               rtlphy->rfreg_chnlval[rfpath] =
+                                                   rtlphy->rfreg_chnlval
+                                                   [rfpath] & (~BIT(18));
+                                       rtlphy->rfreg_chnlval[rfpath] |=
+                                                (BIT(16) | BIT(8));
+                               } else {
+                                       rtlphy->rfreg_chnlval[rfpath] &=
+                                               ~(BIT(8) | BIT(16) | BIT(18));
+                               }
+                               rtl_set_rfreg(hw, (enum radio_path)rfpath,
+                                             currentcmd->para1,
+                                             BRFREGOFFSETMASK,
+                                             rtlphy->rfreg_chnlval[rfpath]);
+                               _rtl92d_phy_reload_imr_setting(hw, channel,
+                                                              rfpath);
+                       }
+                       _rtl92d_phy_switch_rf_setting(hw, channel);
+                       /* do IQK when all parameters are ready */
+                       rtl92d_phy_reload_iqk_setting(hw, channel);
+                       break;
+               default:
+                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                                ("switch case not process\n"));
+                       break;
+               }
+               break;
+       } while (true);
+       (*delay) = currentcmd->msdelay;
+       (*step)++;
+       return false;
+}
+
+u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u32 delay;
+       u32 timeout = 1000, timecount = 0;
+       u8 channel = rtlphy->current_channel;
+       u32 ret_value;
+
+       if (rtlphy->sw_chnl_inprogress)
+               return 0;
+       if (rtlphy->set_bwmode_inprogress)
+               return 0;
+
+       if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
+               RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
+                        ("sw_chnl_inprogress false driver sleep or unload\n"));
+               return 0;
+       }
+       while (rtlphy->lck_inprogress && timecount < timeout) {
+               mdelay(50);
+               timecount += 50;
+       }
+       if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY &&
+           rtlhal->bandset == BAND_ON_BOTH) {
+               ret_value = rtl_get_bbreg(hw, RFPGA0_XAB_RFPARAMETER,
+                                         BMASKDWORD);
+               if (rtlphy->current_channel > 14 && !(ret_value & BIT(0)))
+                       rtl92d_phy_switch_wirelessband(hw, BAND_ON_5G);
+               else if (rtlphy->current_channel <= 14 && (ret_value & BIT(0)))
+                       rtl92d_phy_switch_wirelessband(hw, BAND_ON_2_4G);
+       }
+       switch (rtlhal->current_bandtype) {
+       case BAND_ON_5G:
+               /* Get first channel error when change between
+                * 5G and 2.4G band. */
+               if (channel <= 14)
+                       return 0;
+               RT_ASSERT((channel > 14), ("5G but channel<=14"));
+               break;
+       case BAND_ON_2_4G:
+               /* Get first channel error when change between
+                * 5G and 2.4G band. */
+               if (channel > 14)
+                       return 0;
+               RT_ASSERT((channel <= 14), ("2G but channel>14"));
+               break;
+       default:
+               RT_ASSERT(false,
+                         ("Invalid WirelessMode(%#x)!!\n",
+                          rtlpriv->mac80211.mode));
+               break;
+       }
+       rtlphy->sw_chnl_inprogress = true;
+       if (channel == 0)
+               channel = 1;
+       rtlphy->sw_chnl_stage = 0;
+       rtlphy->sw_chnl_step = 0;
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
+                ("switch to channel%d\n", rtlphy->current_channel));
+
+       do {
+               if (!rtlphy->sw_chnl_inprogress)
+                       break;
+               if (!_rtl92d_phy_sw_chnl_step_by_step(hw,
+                                                     rtlphy->current_channel,
+                   &rtlphy->sw_chnl_stage, &rtlphy->sw_chnl_step, &delay)) {
+                       if (delay > 0)
+                               mdelay(delay);
+                       else
+                               continue;
+               } else {
+                       rtlphy->sw_chnl_inprogress = false;
+               }
+               break;
+       } while (true);
+       RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+       rtlphy->sw_chnl_inprogress = false;
+       return 1;
+}
+
+static void rtl92d_phy_set_io(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
+                ("--->Cmd(%#x), set_io_inprogress(%d)\n",
+                rtlphy->current_io_type, rtlphy->set_io_inprogress));
+       switch (rtlphy->current_io_type) {
+       case IO_CMD_RESUME_DM_BY_SCAN:
+               de_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1;
+               rtl92d_dm_write_dig(hw);
+               rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel);
+               break;
+       case IO_CMD_PAUSE_DM_BY_SCAN:
+               rtlphy->initgain_backup.xaagccore1 = de_digtable.cur_igvalue;
+               de_digtable.cur_igvalue = 0x17;
+               rtl92d_dm_write_dig(hw);
+               break;
+       default:
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("switch case not process\n"));
+               break;
+       }
+       rtlphy->set_io_inprogress = false;
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
+                ("<---(%#x)\n", rtlphy->current_io_type));
+}
+
+bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       bool postprocessing = false;
+
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
+                ("-->IO Cmd(%#x), set_io_inprogress(%d)\n",
+                iotype, rtlphy->set_io_inprogress));
+       do {
+               switch (iotype) {
+               case IO_CMD_RESUME_DM_BY_SCAN:
+                       RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
+                                ("[IO CMD] Resume DM after scan.\n"));
+                       postprocessing = true;
+                       break;
+               case IO_CMD_PAUSE_DM_BY_SCAN:
+                       RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
+                                ("[IO CMD] Pause DM before scan.\n"));
+                       postprocessing = true;
+                       break;
+               default:
+                       RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                                ("switch case not process\n"));
+                       break;
+               }
+       } while (false);
+       if (postprocessing && !rtlphy->set_io_inprogress) {
+               rtlphy->set_io_inprogress = true;
+               rtlphy->current_io_type = iotype;
+       } else {
+               return false;
+       }
+       rtl92d_phy_set_io(hw);
+       RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype));
+       return true;
+}
+
+static void _rtl92d_phy_set_rfon(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       /* a.  SYS_CLKR 0x08[11] = 1  restore MAC clock */
+       /* b.  SPS_CTRL 0x11[7:0] = 0x2b */
+       if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY)
+               rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
+       /* c.  For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE3 enable BB TRX function */
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
+       /* RF_ON_EXCEP(d~g): */
+       /* d.  APSD_CTRL 0x600[7:0] = 0x00 */
+       rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
+       /* e.  SYS_FUNC_EN 0x02[7:0] = 0xE2  reset BB TRX function again */
+       /* f.  SYS_FUNC_EN 0x02[7:0] = 0xE3  enable BB TRX function*/
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
+       /* g.   txpause 0x522[7:0] = 0x00  enable mac tx queue */
+       rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
+}
+
+static void _rtl92d_phy_set_rfsleep(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 u4btmp;
+       u8 delay = 5;
+
+       /* a.   TXPAUSE 0x522[7:0] = 0xFF  Pause MAC TX queue  */
+       rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
+       /* b.   RF path 0 offset 0x00 = 0x00  disable RF  */
+       rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00);
+       /* c.   APSD_CTRL 0x600[7:0] = 0x40 */
+       rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
+       /* d. APSD_CTRL 0x600[7:0] = 0x00
+        * APSD_CTRL 0x600[7:0] = 0x00
+        * RF path 0 offset 0x00 = 0x00
+        * APSD_CTRL 0x600[7:0] = 0x40
+        * */
+       u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, BRFREGOFFSETMASK);
+       while (u4btmp != 0 && delay > 0) {
+               rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
+               rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00);
+               rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
+               u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, BRFREGOFFSETMASK);
+               delay--;
+       }
+       if (delay == 0) {
+               /* Jump out the LPS turn off sequence to RF_ON_EXCEP */
+               rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
+
+               rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+               rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
+               rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                       ("Fail !!! Switch RF timeout.\n"));
+               return;
+       }
+       /* e.   For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function */
+       rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+       /* f.   SPS_CTRL 0x11[7:0] = 0x22 */
+       if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY)
+               rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
+       /* g.    SYS_CLKR 0x08[11] = 0  gated MAC clock */
+}
+
+bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw,
+                                  enum rf_pwrstate rfpwr_state)
+{
+
+       bool bresult = true;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       u8 i, queue_id;
+       struct rtl8192_tx_ring *ring = NULL;
+
+       if (rfpwr_state == ppsc->rfpwr_state)
+               return false;
+       switch (rfpwr_state) {
+       case ERFON:
+               if ((ppsc->rfpwr_state == ERFOFF) &&
+                   RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
+                       bool rtstatus;
+                       u32 InitializeCount = 0;
+                       do {
+                               InitializeCount++;
+                               RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+                                        ("IPS Set eRf nic enable\n"));
+                               rtstatus = rtl_ps_enable_nic(hw);
+                       } while ((rtstatus != true) &&
+                                (InitializeCount < 10));
+
+                       RT_CLEAR_PS_LEVEL(ppsc,
+                                         RT_RF_OFF_LEVL_HALT_NIC);
+               } else {
+                       RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+                                ("awake, sleeped:%d ms state_"
+                                "inap:%x\n",
+                                jiffies_to_msecs(jiffies -
+                                ppsc->last_sleep_jiffies),
+                                rtlpriv->psc.state_inap));
+                       ppsc->last_awake_jiffies = jiffies;
+                       _rtl92d_phy_set_rfon(hw);
+               }
+
+               if (mac->link_state == MAC80211_LINKED)
+                       rtlpriv->cfg->ops->led_control(hw,
+                                        LED_CTL_LINK);
+               else
+                       rtlpriv->cfg->ops->led_control(hw,
+                                        LED_CTL_NO_LINK);
+               break;
+       case ERFOFF:
+               if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
+                       RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+                                ("IPS Set eRf nic disable\n"));
+                       rtl_ps_disable_nic(hw);
+                       RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+               } else {
+                       if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
+                               rtlpriv->cfg->ops->led_control(hw,
+                                                LED_CTL_NO_LINK);
+                       else
+                               rtlpriv->cfg->ops->led_control(hw,
+                                                LED_CTL_POWER_OFF);
+               }
+               break;
+       case ERFSLEEP:
+               if (ppsc->rfpwr_state == ERFOFF)
+                       break;
+
+               for (queue_id = 0, i = 0;
+                    queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
+                       ring = &pcipriv->dev.tx_ring[queue_id];
+                       if (skb_queue_len(&ring->queue) == 0 ||
+                           queue_id == BEACON_QUEUE) {
+                               queue_id++;
+                               continue;
+                       } else if (rtlpci->pdev->current_state != PCI_D0) {
+                               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                                        ("eRf Off/Sleep: %d times TcbBusyQueu"
+                                        "e[%d] !=0 but lower power state!\n",
+                                        (i + 1), queue_id));
+                               break;
+                       } else {
+                               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+                                        ("eRf Off/Sleep: %d times TcbBusyQueu"
+                                        "e[%d] =%d "
+                                        "before doze!\n", (i + 1), queue_id,
+                                         skb_queue_len(&ring->queue)));
+                               udelay(10);
+                               i++;
+                       }
+
+                       if (i >= MAX_DOZE_WAITING_TIMES_9x) {
+                               RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+                                        ("\nERFOFF: %d times TcbBusyQueue[%d] "
+                                        "= %d !\n",
+                                         MAX_DOZE_WAITING_TIMES_9x, queue_id,
+                                         skb_queue_len(&ring->queue)));
+                               break;
+                       }
+               }
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+                        ("Set rfsleep awaked:%d ms\n",
+                        jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)));
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("sleep awaked:%d ms "
+                        "state_inap:%x\n", jiffies_to_msecs(jiffies -
+                        ppsc->last_awake_jiffies), rtlpriv->psc.state_inap));
+               ppsc->last_sleep_jiffies = jiffies;
+               _rtl92d_phy_set_rfsleep(hw);
+               break;
+       default:
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("switch case not process\n"));
+               bresult = false;
+               break;
+       }
+       if (bresult)
+               ppsc->rfpwr_state = rfpwr_state;
+       return bresult;
+}
+
+void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 offset = REG_MAC_PHY_CTRL_NORMAL;
+
+       switch (rtlhal->macphymode) {
+       case DUALMAC_DUALPHY:
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                        ("MacPhyMode: DUALMAC_DUALPHY\n"));
+               rtl_write_byte(rtlpriv, offset, 0xF3);
+               break;
+       case SINGLEMAC_SINGLEPHY:
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                        ("MacPhyMode: SINGLEMAC_SINGLEPHY\n"));
+               rtl_write_byte(rtlpriv, offset, 0xF4);
+               break;
+       case DUALMAC_SINGLEPHY:
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                        ("MacPhyMode: DUALMAC_SINGLEPHY\n"));
+               rtl_write_byte(rtlpriv, offset, 0xF1);
+               break;
+       }
+}
+
+void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+       switch (rtlhal->macphymode) {
+       case DUALMAC_SINGLEPHY:
+               rtlphy->rf_type = RF_2T2R;
+               rtlhal->version |= CHIP_92D_SINGLEPHY;
+               rtlhal->bandset = BAND_ON_BOTH;
+               rtlhal->current_bandtype = BAND_ON_2_4G;
+               break;
+
+       case SINGLEMAC_SINGLEPHY:
+               rtlphy->rf_type = RF_2T2R;
+               rtlhal->version |= CHIP_92D_SINGLEPHY;
+               rtlhal->bandset = BAND_ON_BOTH;
+               rtlhal->current_bandtype = BAND_ON_2_4G;
+               break;
+
+       case DUALMAC_DUALPHY:
+               rtlphy->rf_type = RF_1T1R;
+               rtlhal->version &= (~CHIP_92D_SINGLEPHY);
+               /* Now we let MAC0 run on 5G band. */
+               if (rtlhal->interfaceindex == 0) {
+                       rtlhal->bandset = BAND_ON_5G;
+                       rtlhal->current_bandtype = BAND_ON_5G;
+               } else {
+                       rtlhal->bandset = BAND_ON_2_4G;
+                       rtlhal->current_bandtype = BAND_ON_2_4G;
+               }
+               break;
+       default:
+               break;
+       }
+}
+
+u8 rtl92d_get_chnlgroup_fromarray(u8 chnl)
+{
+       u8 group;
+       u8 channel_info[59] = {
+               1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+               36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56,
+               58, 60, 62, 64, 100, 102, 104, 106, 108,
+               110, 112, 114, 116, 118, 120, 122, 124,
+               126, 128, 130, 132, 134, 136, 138, 140,
+               149, 151, 153, 155, 157, 159, 161, 163,
+               165
+       };
+
+       if (channel_info[chnl] <= 3)
+               group = 0;
+       else if (channel_info[chnl] <= 9)
+               group = 1;
+       else if (channel_info[chnl] <= 14)
+               group = 2;
+       else if (channel_info[chnl] <= 44)
+               group = 3;
+       else if (channel_info[chnl] <= 54)
+               group = 4;
+       else if (channel_info[chnl] <= 64)
+               group = 5;
+       else if (channel_info[chnl] <= 112)
+               group = 6;
+       else if (channel_info[chnl] <= 126)
+               group = 7;
+       else if (channel_info[chnl] <= 140)
+               group = 8;
+       else if (channel_info[chnl] <= 153)
+               group = 9;
+       else if (channel_info[chnl] <= 159)
+               group = 10;
+       else
+               group = 11;
+       return group;
+}
+
+void rtl92d_phy_set_poweron(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       unsigned long flags;
+       u8 value8;
+       u16 i;
+       u32 mac_reg = (rtlhal->interfaceindex == 0 ? REG_MAC0 : REG_MAC1);
+
+       /* notice fw know band status  0x81[1]/0x53[1] = 0: 5G, 1: 2G */
+       if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+               value8 = rtl_read_byte(rtlpriv, mac_reg);
+               value8 |= BIT(1);
+               rtl_write_byte(rtlpriv, mac_reg, value8);
+       } else {
+               value8 = rtl_read_byte(rtlpriv, mac_reg);
+               value8 &= (~BIT(1));
+               rtl_write_byte(rtlpriv, mac_reg, value8);
+       }
+
+       if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) {
+               value8 = rtl_read_byte(rtlpriv, REG_MAC0);
+               rtl_write_byte(rtlpriv, REG_MAC0, value8 | MAC0_ON);
+       } else {
+               spin_lock_irqsave(&globalmutex_power, flags);
+               if (rtlhal->interfaceindex == 0) {
+                       value8 = rtl_read_byte(rtlpriv, REG_MAC0);
+                       rtl_write_byte(rtlpriv, REG_MAC0, value8 | MAC0_ON);
+               } else {
+                       value8 = rtl_read_byte(rtlpriv, REG_MAC1);
+                       rtl_write_byte(rtlpriv, REG_MAC1, value8 | MAC1_ON);
+               }
+               value8 = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS);
+               spin_unlock_irqrestore(&globalmutex_power, flags);
+               for (i = 0; i < 200; i++) {
+                       if ((value8 & BIT(7)) == 0) {
+                               break;
+                       } else {
+                               udelay(500);
+                               spin_lock_irqsave(&globalmutex_power, flags);
+                               value8 = rtl_read_byte(rtlpriv,
+                                                   REG_POWER_OFF_IN_PROCESS);
+                               spin_unlock_irqrestore(&globalmutex_power,
+                                                      flags);
+                       }
+               }
+               if (i == 200)
+                       RT_ASSERT(false, ("Another mac power off over time\n"));
+       }
+}
+
+void rtl92d_phy_config_maccoexist_rfpage(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       switch (rtlpriv->rtlhal.macphymode) {
+       case DUALMAC_DUALPHY:
+               rtl_write_byte(rtlpriv, REG_DMC, 0x0);
+               rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x08);
+               rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x13ff);
+               break;
+       case DUALMAC_SINGLEPHY:
+               rtl_write_byte(rtlpriv, REG_DMC, 0xf8);
+               rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x08);
+               rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x13ff);
+               break;
+       case SINGLEMAC_SINGLEPHY:
+               rtl_write_byte(rtlpriv, REG_DMC, 0x0);
+               rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x10);
+               rtl_write_word(rtlpriv, (REG_TRXFF_BNDY + 2), 0x27FF);
+               break;
+       default:
+               break;
+       }
+}
+
+void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u8 rfpath, i;
+
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n"));
+       /* r_select_5G for path_A/B 0 for 2.4G, 1 for 5G */
+       if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+               /* r_select_5G for path_A/B,0x878 */
+               rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(0), 0x0);
+               rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0x0);
+               if (rtlhal->macphymode != DUALMAC_DUALPHY) {
+                       rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(16), 0x0);
+                       rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(31), 0x0);
+               }
+               /* rssi_table_select:index 0 for 2.4G.1~3 for 5G,0xc78 */
+               rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, BIT(6) | BIT(7), 0x0);
+               /* fc_area  0xd2c */
+               rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(14) | BIT(13), 0x0);
+               /* 5G LAN ON */
+               rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0xa);
+               /* TX BB gain shift*1,Just for testchip,0xc80,0xc88 */
+               rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD,
+                             0x40000100);
+               rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD,
+                             0x40000100);
+               if (rtlhal->macphymode == DUALMAC_DUALPHY) {
+                       rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
+                                     BIT(10) | BIT(6) | BIT(5),
+                                     ((rtlefuse->eeprom_c9 & BIT(3)) >> 3) |
+                                     (rtlefuse->eeprom_c9 & BIT(1)) |
+                                     ((rtlefuse->eeprom_cc & BIT(1)) << 4));
+                       rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
+                                     BIT(10) | BIT(6) | BIT(5),
+                                     ((rtlefuse->eeprom_c9 & BIT(2)) >> 2) |
+                                     ((rtlefuse->eeprom_c9 & BIT(0)) << 1) |
+                                     ((rtlefuse->eeprom_cc & BIT(0)) << 5));
+                       rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0);
+               } else {
+                       rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
+                                     BIT(26) | BIT(22) | BIT(21) | BIT(10) |
+                                     BIT(6) | BIT(5),
+                                     ((rtlefuse->eeprom_c9 & BIT(3)) >> 3) |
+                                     (rtlefuse->eeprom_c9 & BIT(1)) |
+                                     ((rtlefuse->eeprom_cc & BIT(1)) << 4) |
+                                     ((rtlefuse->eeprom_c9 & BIT(7)) << 9) |
+                                     ((rtlefuse->eeprom_c9 & BIT(5)) << 12) |
+                                     ((rtlefuse->eeprom_cc & BIT(3)) << 18));
+                       rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
+                                     BIT(10) | BIT(6) | BIT(5),
+                                     ((rtlefuse->eeprom_c9 & BIT(2)) >> 2) |
+                                     ((rtlefuse->eeprom_c9 & BIT(0)) << 1) |
+                                     ((rtlefuse->eeprom_cc & BIT(0)) << 5));
+                       rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
+                                     BIT(10) | BIT(6) | BIT(5),
+                                     ((rtlefuse->eeprom_c9 & BIT(6)) >> 6) |
+                                     ((rtlefuse->eeprom_c9 & BIT(4)) >> 3) |
+                                     ((rtlefuse->eeprom_cc & BIT(2)) << 3));
+                       rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER,
+                                     BIT(31) | BIT(15), 0);
+               }
+               /* 1.5V_LDO */
+       } else {
+               /* r_select_5G for path_A/B */
+               rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(0), 0x1);
+               rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0x1);
+               if (rtlhal->macphymode != DUALMAC_DUALPHY) {
+                       rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(16), 0x1);
+                       rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(31), 0x1);
+               }
+               /* rssi_table_select:index 0 for 2.4G.1~3 for 5G */
+               rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, BIT(6) | BIT(7), 0x1);
+               /* fc_area */
+               rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(14) | BIT(13), 0x1);
+               /* 5G LAN ON */
+               rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0x0);
+               /* TX BB gain shift,Just for testchip,0xc80,0xc88 */
+               if (rtlefuse->internal_pa_5g[0])
+                       rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD,
+                                     0x2d4000b5);
+               else
+                       rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD,
+                                     0x20000080);
+               if (rtlefuse->internal_pa_5g[1])
+                       rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD,
+                                     0x2d4000b5);
+               else
+                       rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD,
+                                     0x20000080);
+               if (rtlhal->macphymode == DUALMAC_DUALPHY) {
+                       rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
+                                     BIT(10) | BIT(6) | BIT(5),
+                                     (rtlefuse->eeprom_cc & BIT(5)));
+                       rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10),
+                                     ((rtlefuse->eeprom_cc & BIT(4)) >> 4));
+                       rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15),
+                                     (rtlefuse->eeprom_cc & BIT(4)) >> 4);
+               } else {
+                       rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
+                                     BIT(26) | BIT(22) | BIT(21) | BIT(10) |
+                                     BIT(6) | BIT(5),
+                                     (rtlefuse->eeprom_cc & BIT(5)) |
+                                     ((rtlefuse->eeprom_cc & BIT(7)) << 14));
+                       rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10),
+                                     ((rtlefuse->eeprom_cc & BIT(4)) >> 4));
+                       rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(10),
+                                     ((rtlefuse->eeprom_cc & BIT(6)) >> 6));
+                       rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER,
+                                     BIT(31) | BIT(15),
+                                     ((rtlefuse->eeprom_cc & BIT(4)) >> 4) |
+                                     ((rtlefuse->eeprom_cc & BIT(6)) << 10));
+               }
+       }
+       /* update IQK related settings */
+       rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, BMASKDWORD, 0x40000100);
+       rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, BMASKDWORD, 0x40000100);
+       rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000, 0x00);
+       rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30) | BIT(28) |
+                     BIT(26) | BIT(24), 0x00);
+       rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 0xF0000000, 0x00);
+       rtl_set_bbreg(hw, 0xca0, 0xF0000000, 0x00);
+       rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, 0x00);
+
+       /* Update RF */
+       for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
+            rfpath++) {
+               if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+                       /* MOD_AG for RF paht_A 0x18 BIT8,BIT16 */
+                       rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(8) | BIT(16) |
+                                     BIT(18), 0);
+                       /* RF0x0b[16:14] =3b'111 */
+                       rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B,
+                                     0x1c000, 0x07);
+               } else {
+                       /* MOD_AG for RF paht_A 0x18 BIT8,BIT16 */
+                       rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(8) |
+                                     BIT(16) | BIT(18),
+                                     (BIT(16) | BIT(8)) >> 8);
+               }
+       }
+       /* Update for all band. */
+       /* DMDP */
+       if (rtlphy->rf_type == RF_1T1R) {
+               /* Use antenna 0,0xc04,0xd04 */
+               rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x11);
+               rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x1);
+
+               /* enable ad/da clock1 for dual-phy reg0x888 */
+               if (rtlhal->interfaceindex == 0) {
+                       rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) |
+                                     BIT(13), 0x3);
+               } else {
+                       rtl92d_phy_enable_anotherphy(hw, false);
+                       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+                                ("MAC1 use DBI to update 0x888"));
+                       /* 0x888 */
+                       rtl92de_write_dword_dbi(hw, RFPGA0_ADDALLOCKEN,
+                                               rtl92de_read_dword_dbi(hw,
+                                               RFPGA0_ADDALLOCKEN,
+                                               BIT(3)) | BIT(12) | BIT(13),
+                                               BIT(3));
+                       rtl92d_phy_powerdown_anotherphy(hw, false);
+               }
+       } else {
+               /* Single PHY */
+               /* Use antenna 0 & 1,0xc04,0xd04 */
+               rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x33);
+               rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x3);
+               /* disable ad/da clock1,0x888 */
+               rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) | BIT(13), 0);
+       }
+       for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
+            rfpath++) {
+               rtlphy->rfreg_chnlval[rfpath] = rtl_get_rfreg(hw, rfpath,
+                                               RF_CHNLBW, BRFREGOFFSETMASK);
+               rtlphy->reg_rf3c[rfpath] = rtl_get_rfreg(hw, rfpath, 0x3C,
+                       BRFREGOFFSETMASK);
+       }
+       for (i = 0; i < 2; i++)
+               RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("RF 0x18 = 0x%x\n",
+                         rtlphy->rfreg_chnlval[i]));
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==\n"));
+
+}
+
+bool rtl92d_phy_check_poweroff(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       u8 u1btmp;
+       unsigned long flags;
+
+       if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) {
+               u1btmp = rtl_read_byte(rtlpriv, REG_MAC0);
+               rtl_write_byte(rtlpriv, REG_MAC0, u1btmp & (~MAC0_ON));
+               return true;
+       }
+       spin_lock_irqsave(&globalmutex_power, flags);
+       if (rtlhal->interfaceindex == 0) {
+               u1btmp = rtl_read_byte(rtlpriv, REG_MAC0);
+               rtl_write_byte(rtlpriv, REG_MAC0, u1btmp & (~MAC0_ON));
+               u1btmp = rtl_read_byte(rtlpriv, REG_MAC1);
+               u1btmp &= MAC1_ON;
+       } else {
+               u1btmp = rtl_read_byte(rtlpriv, REG_MAC1);
+               rtl_write_byte(rtlpriv, REG_MAC1, u1btmp & (~MAC1_ON));
+               u1btmp = rtl_read_byte(rtlpriv, REG_MAC0);
+               u1btmp &= MAC0_ON;
+       }
+       if (u1btmp) {
+               spin_unlock_irqrestore(&globalmutex_power, flags);
+               return false;
+       }
+       u1btmp = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS);
+       u1btmp |= BIT(7);
+       rtl_write_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS, u1btmp);
+       spin_unlock_irqrestore(&globalmutex_power, flags);
+       return true;
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h
new file mode 100644 (file)
index 0000000..a52c824
--- /dev/null
@@ -0,0 +1,178 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92D_PHY_H__
+#define __RTL92D_PHY_H__
+
+#define MAX_PRECMD_CNT                         16
+#define MAX_RFDEPENDCMD_CNT                    16
+#define MAX_POSTCMD_CNT                                16
+
+#define MAX_DOZE_WAITING_TIMES_9x              64
+
+#define RT_CANNOT_IO(hw)                       false
+#define HIGHPOWER_RADIOA_ARRAYLEN              22
+
+#define IQK_ADDA_REG_NUM                       16
+#define MAX_TOLERANCE                          5
+#define        IQK_DELAY_TIME                          1
+
+#define        APK_BB_REG_NUM                          5
+#define        APK_AFE_REG_NUM                         16
+#define        APK_CURVE_REG_NUM                       4
+#define        PATH_NUM                                2
+
+#define LOOP_LIMIT                             5
+#define MAX_STALL_TIME                         50
+#define ANTENNA_DIVERSITY_VALUE                        0x80
+#define MAX_TXPWR_IDX_NMODE_92S                        63
+#define RESET_CNT_LIMIT                                3
+
+#define IQK_ADDA_REG_NUM                       16
+#define IQK_BB_REG_NUM                         10
+#define IQK_BB_REG_NUM_test                    6
+#define IQK_MAC_REG_NUM                                4
+#define RX_INDEX_MAPPING_NUM                   15
+
+#define IQK_DELAY_TIME                         1
+
+#define CT_OFFSET_MAC_ADDR                     0X16
+
+#define CT_OFFSET_CCK_TX_PWR_IDX               0x5A
+#define CT_OFFSET_HT401S_TX_PWR_IDX            0x60
+#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF       0x66
+#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF         0x69
+#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF         0x6C
+
+#define CT_OFFSET_HT40_MAX_PWR_OFFSET          0x6F
+#define CT_OFFSET_HT20_MAX_PWR_OFFSET          0x72
+
+#define CT_OFFSET_CHANNEL_PLAH                 0x75
+#define CT_OFFSET_THERMAL_METER                        0x78
+#define CT_OFFSET_RF_OPTION                    0x79
+#define CT_OFFSET_VERSION                      0x7E
+#define CT_OFFSET_CUSTOMER_ID                  0x7F
+
+enum swchnlcmd_id {
+       CMDID_END,
+       CMDID_SET_TXPOWEROWER_LEVEL,
+       CMDID_BBREGWRITE10,
+       CMDID_WRITEPORT_ULONG,
+       CMDID_WRITEPORT_USHORT,
+       CMDID_WRITEPORT_UCHAR,
+       CMDID_RF_WRITEREG,
+};
+
+struct swchnlcmd {
+       enum swchnlcmd_id cmdid;
+       u32 para1;
+       u32 para2;
+       u32 msdelay;
+};
+
+enum baseband_config_type {
+       BASEBAND_CONFIG_PHY_REG = 0,
+       BASEBAND_CONFIG_AGC_TAB = 1,
+};
+
+enum rf_content {
+       radioa_txt = 0,
+       radiob_txt = 1,
+       radioc_txt = 2,
+       radiod_txt = 3
+};
+
+static inline void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
+                                                    unsigned long *flag)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (rtlpriv->rtlhal.interfaceindex == 1)
+               spin_lock_irqsave(&rtlpriv->locks.cck_and_rw_pagea_lock, *flag);
+}
+
+static inline void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
+                                                    unsigned long *flag)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (rtlpriv->rtlhal.interfaceindex == 1)
+               spin_unlock_irqrestore(&rtlpriv->locks.cck_and_rw_pagea_lock,
+                       *flag);
+}
+
+extern u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw,
+                                  u32 regaddr, u32 bitmask);
+extern void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw,
+                                 u32 regaddr, u32 bitmask, u32 data);
+extern u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw,
+                                  enum radio_path rfpath, u32 regaddr,
+                                  u32 bitmask);
+extern void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw,
+                                 enum radio_path rfpath, u32 regaddr,
+                                 u32 bitmask, u32 data);
+extern bool rtl92d_phy_mac_config(struct ieee80211_hw *hw);
+extern bool rtl92d_phy_bb_config(struct ieee80211_hw *hw);
+extern bool rtl92d_phy_rf_config(struct ieee80211_hw *hw);
+extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
+                                                enum radio_path rfpath);
+extern void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
+extern void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
+extern void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw,
+                                            u8 operation);
+extern void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
+                                  enum nl80211_channel_type ch_type);
+extern u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw);
+bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
+                                         enum rf_content content,
+                                         enum radio_path rfpath);
+bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
+extern bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw,
+                                         enum rf_pwrstate rfpwr_state);
+
+void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw);
+void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw);
+u8 rtl92d_get_chnlgroup_fromarray(u8 chnl);
+void rtl92d_phy_set_poweron(struct ieee80211_hw *hw);
+void rtl92d_phy_config_maccoexist_rfpage(struct ieee80211_hw *hw);
+bool rtl92d_phy_check_poweroff(struct ieee80211_hw *hw);
+void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw);
+void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw);
+void rtl92d_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
+void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw);
+void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw);
+void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
+                                      unsigned long *flag);
+void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw,
+                                      unsigned long *flag);
+u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl);
+void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel);
+void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
new file mode 100644 (file)
index 0000000..131acc3
--- /dev/null
@@ -0,0 +1,1313 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92D_REG_H__
+#define __RTL92D_REG_H__
+
+/* ----------------------------------------------------- */
+/* 0x0000h ~ 0x00FFh System Configuration */
+/* ----------------------------------------------------- */
+#define REG_SYS_ISO_CTRL               0x0000
+#define REG_SYS_FUNC_EN                        0x0002
+#define REG_APS_FSMCO                  0x0004
+#define REG_SYS_CLKR                   0x0008
+#define REG_9346CR                     0x000A
+#define REG_EE_VPD                     0x000C
+#define REG_AFE_MISC                   0x0010
+#define REG_SPS0_CTRL                  0x0011
+#define REG_POWER_OFF_IN_PROCESS       0x0017
+#define REG_SPS_OCP_CFG                        0x0018
+#define REG_RSV_CTRL                   0x001C
+#define REG_RF_CTRL                    0x001F
+#define REG_LDOA15_CTRL                        0x0020
+#define REG_LDOV12D_CTRL               0x0021
+#define REG_LDOHCI12_CTRL              0x0022
+#define REG_LPLDO_CTRL                 0x0023
+#define REG_AFE_XTAL_CTRL              0x0024
+#define REG_AFE_PLL_CTRL               0x0028
+/* for 92d, DMDP,SMSP,DMSP contrl */
+#define REG_MAC_PHY_CTRL               0x002c
+#define REG_EFUSE_CTRL                 0x0030
+#define REG_EFUSE_TEST                 0x0034
+#define REG_PWR_DATA                   0x0038
+#define REG_CAL_TIMER                  0x003C
+#define REG_ACLK_MON                   0x003E
+#define REG_GPIO_MUXCFG                        0x0040
+#define REG_GPIO_IO_SEL                        0x0042
+#define REG_MAC_PINMUX_CFG             0x0043
+#define REG_GPIO_PIN_CTRL              0x0044
+#define REG_GPIO_INTM                  0x0048
+#define REG_LEDCFG0                    0x004C
+#define REG_LEDCFG1                    0x004D
+#define REG_LEDCFG2                    0x004E
+#define REG_LEDCFG3                    0x004F
+#define REG_FSIMR                      0x0050
+#define REG_FSISR                      0x0054
+
+#define REG_MCUFWDL                    0x0080
+
+#define REG_HMEBOX_EXT_0               0x0088
+#define REG_HMEBOX_EXT_1               0x008A
+#define REG_HMEBOX_EXT_2               0x008C
+#define REG_HMEBOX_EXT_3               0x008E
+
+#define REG_BIST_SCAN                  0x00D0
+#define REG_BIST_RPT                   0x00D4
+#define REG_BIST_ROM_RPT               0x00D8
+#define REG_USB_SIE_INTF               0x00E0
+#define REG_PCIE_MIO_INTF              0x00E4
+#define REG_PCIE_MIO_INTD              0x00E8
+#define REG_HPON_FSM                   0x00EC
+#define REG_SYS_CFG                    0x00F0
+#define REG_MAC_PHY_CTRL_NORMAL                0x00f8
+
+#define  REG_MAC0                      0x0081
+#define  REG_MAC1                      0x0053
+#define  FW_MAC0_READY                 0x18
+#define  FW_MAC1_READY                 0x1A
+#define  MAC0_ON                       BIT(7)
+#define  MAC1_ON                       BIT(0)
+#define  MAC0_READY                    BIT(0)
+#define  MAC1_READY                    BIT(0)
+
+/* ----------------------------------------------------- */
+/* 0x0100h ~ 0x01FFh   MACTOP General Configuration */
+/* ----------------------------------------------------- */
+#define REG_CR                         0x0100
+#define REG_PBP                                0x0104
+#define REG_TRXDMA_CTRL                        0x010C
+#define REG_TRXFF_BNDY                 0x0114
+#define REG_TRXFF_STATUS               0x0118
+#define REG_RXFF_PTR                   0x011C
+#define REG_HIMR                       0x0120
+#define REG_HISR                       0x0124
+#define REG_HIMRE                      0x0128
+#define REG_HISRE                      0x012C
+#define REG_CPWM                       0x012F
+#define REG_FWIMR                      0x0130
+#define REG_FWISR                      0x0134
+#define REG_PKTBUF_DBG_CTRL            0x0140
+#define REG_PKTBUF_DBG_DATA_L          0x0144
+#define REG_PKTBUF_DBG_DATA_H          0x0148
+
+#define REG_TC0_CTRL                   0x0150
+#define REG_TC1_CTRL                   0x0154
+#define REG_TC2_CTRL                   0x0158
+#define REG_TC3_CTRL                   0x015C
+#define REG_TC4_CTRL                   0x0160
+#define REG_TCUNIT_BASE                        0x0164
+#define REG_MBIST_START                        0x0174
+#define REG_MBIST_DONE                 0x0178
+#define REG_MBIST_FAIL                 0x017C
+#define REG_C2HEVT_MSG_NORMAL          0x01A0
+#define REG_C2HEVT_MSG_TEST            0x01B8
+#define REG_C2HEVT_CLEAR               0x01BF
+#define REG_MCUTST_1                   0x01c0
+#define REG_FMETHR                     0x01C8
+#define REG_HMETFR                     0x01CC
+#define REG_HMEBOX_0                   0x01D0
+#define REG_HMEBOX_1                   0x01D4
+#define REG_HMEBOX_2                   0x01D8
+#define REG_HMEBOX_3                   0x01DC
+
+#define REG_LLT_INIT                   0x01E0
+#define REG_BB_ACCEESS_CTRL            0x01E8
+#define REG_BB_ACCESS_DATA             0x01EC
+
+
+/* ----------------------------------------------------- */
+/*     0x0200h ~ 0x027Fh       TXDMA Configuration */
+/* ----------------------------------------------------- */
+#define REG_RQPN                       0x0200
+#define REG_FIFOPAGE                   0x0204
+#define REG_TDECTRL                    0x0208
+#define REG_TXDMA_OFFSET_CHK           0x020C
+#define REG_TXDMA_STATUS               0x0210
+#define REG_RQPN_NPQ                   0x0214
+
+/* ----------------------------------------------------- */
+/*     0x0280h ~ 0x02FFh       RXDMA Configuration */
+/* ----------------------------------------------------- */
+#define REG_RXDMA_AGG_PG_TH            0x0280
+#define REG_RXPKT_NUM                  0x0284
+#define REG_RXDMA_STATUS               0x0288
+
+/* ----------------------------------------------------- */
+/*     0x0300h ~ 0x03FFh       PCIe  */
+/* ----------------------------------------------------- */
+#define        REG_PCIE_CTRL_REG               0x0300
+#define        REG_INT_MIG                     0x0304
+#define        REG_BCNQ_DESA                   0x0308
+#define        REG_HQ_DESA                     0x0310
+#define        REG_MGQ_DESA                    0x0318
+#define        REG_VOQ_DESA                    0x0320
+#define        REG_VIQ_DESA                    0x0328
+#define        REG_BEQ_DESA                    0x0330
+#define        REG_BKQ_DESA                    0x0338
+#define        REG_RX_DESA                     0x0340
+#define        REG_DBI                         0x0348
+#define        REG_DBI_WDATA                   0x0348
+#define REG_DBI_RDATA                  0x034C
+#define REG_DBI_CTRL                   0x0350
+#define REG_DBI_FLAG                   0x0352
+#define        REG_MDIO                        0x0354
+#define        REG_DBG_SEL                     0x0360
+#define        REG_PCIE_HRPWM                  0x0361
+#define        REG_PCIE_HCPWM                  0x0363
+#define        REG_UART_CTRL                   0x0364
+#define        REG_UART_TX_DESA                0x0370
+#define        REG_UART_RX_DESA                0x0378
+
+/* ----------------------------------------------------- */
+/*     0x0400h ~ 0x047Fh       Protocol Configuration  */
+/* ----------------------------------------------------- */
+#define REG_VOQ_INFORMATION            0x0400
+#define REG_VIQ_INFORMATION            0x0404
+#define REG_BEQ_INFORMATION            0x0408
+#define REG_BKQ_INFORMATION            0x040C
+#define REG_MGQ_INFORMATION            0x0410
+#define REG_HGQ_INFORMATION            0x0414
+#define REG_BCNQ_INFORMATION           0x0418
+
+
+#define REG_CPU_MGQ_INFORMATION                0x041C
+#define REG_FWHW_TXQ_CTRL              0x0420
+#define REG_HWSEQ_CTRL                 0x0423
+#define REG_TXPKTBUF_BCNQ_BDNY         0x0424
+#define REG_TXPKTBUF_MGQ_BDNY          0x0425
+#define REG_MULTI_BCNQ_EN              0x0426
+#define REG_MULTI_BCNQ_OFFSET          0x0427
+#define REG_SPEC_SIFS                  0x0428
+#define REG_RL                         0x042A
+#define REG_DARFRC                     0x0430
+#define REG_RARFRC                     0x0438
+#define REG_RRSR                       0x0440
+#define REG_ARFR0                      0x0444
+#define REG_ARFR1                      0x0448
+#define REG_ARFR2                      0x044C
+#define REG_ARFR3                      0x0450
+#define REG_AGGLEN_LMT                 0x0458
+#define REG_AMPDU_MIN_SPACE            0x045C
+#define REG_TXPKTBUF_WMAC_LBK_BF_HD    0x045D
+#define REG_FAST_EDCA_CTRL             0x0460
+#define REG_RD_RESP_PKT_TH             0x0463
+#define REG_INIRTS_RATE_SEL            0x0480
+#define REG_INIDATA_RATE_SEL           0x0484
+#define REG_POWER_STATUS               0x04A4
+#define REG_POWER_STAGE1               0x04B4
+#define REG_POWER_STAGE2               0x04B8
+#define REG_PKT_LIFE_TIME              0x04C0
+#define REG_STBC_SETTING               0x04C4
+#define REG_PROT_MODE_CTRL             0x04C8
+#define REG_MAX_AGGR_NUM               0x04CA
+#define REG_RTS_MAX_AGGR_NUM           0x04CB
+#define REG_BAR_MODE_CTRL              0x04CC
+#define REG_RA_TRY_RATE_AGG_LMT                0x04CF
+#define REG_EARLY_MODE_CONTROL         0x4D0
+#define REG_NQOS_SEQ                   0x04DC
+#define REG_QOS_SEQ                    0x04DE
+#define REG_NEED_CPU_HANDLE            0x04E0
+#define REG_PKT_LOSE_RPT               0x04E1
+#define REG_PTCL_ERR_STATUS            0x04E2
+#define REG_DUMMY                      0x04FC
+
+/* ----------------------------------------------------- */
+/*     0x0500h ~ 0x05FFh       EDCA Configuration   */
+/* ----------------------------------------------------- */
+#define REG_EDCA_VO_PARAM              0x0500
+#define REG_EDCA_VI_PARAM              0x0504
+#define REG_EDCA_BE_PARAM              0x0508
+#define REG_EDCA_BK_PARAM              0x050C
+#define REG_BCNTCFG                    0x0510
+#define REG_PIFS                       0x0512
+#define REG_RDG_PIFS                   0x0513
+#define REG_SIFS_CTX                   0x0514
+#define REG_SIFS_TRX                   0x0516
+#define REG_AGGR_BREAK_TIME            0x051A
+#define REG_SLOT                       0x051B
+#define REG_TX_PTCL_CTRL               0x0520
+#define REG_TXPAUSE                    0x0522
+#define REG_DIS_TXREQ_CLR              0x0523
+#define REG_RD_CTRL                    0x0524
+#define REG_TBTT_PROHIBIT              0x0540
+#define REG_RD_NAV_NXT                 0x0544
+#define REG_NAV_PROT_LEN               0x0546
+#define REG_BCN_CTRL                   0x0550
+#define REG_USTIME_TSF                 0x0551
+#define REG_MBID_NUM                   0x0552
+#define REG_DUAL_TSF_RST               0x0553
+#define REG_BCN_INTERVAL               0x0554
+#define REG_MBSSID_BCN_SPACE           0x0554
+#define REG_DRVERLYINT                 0x0558
+#define REG_BCNDMATIM                  0x0559
+#define REG_ATIMWND                    0x055A
+#define REG_BCN_MAX_ERR                        0x055D
+#define REG_RXTSF_OFFSET_CCK           0x055E
+#define REG_RXTSF_OFFSET_OFDM          0x055F
+#define REG_TSFTR                      0x0560
+#define REG_INIT_TSFTR                 0x0564
+#define REG_PSTIMER                    0x0580
+#define REG_TIMER0                     0x0584
+#define REG_TIMER1                     0x0588
+#define REG_ACMHWCTRL                  0x05C0
+#define REG_ACMRSTCTRL                 0x05C1
+#define REG_ACMAVG                     0x05C2
+#define REG_VO_ADMTIME                 0x05C4
+#define REG_VI_ADMTIME                 0x05C6
+#define REG_BE_ADMTIME                 0x05C8
+#define REG_EDCA_RANDOM_GEN            0x05CC
+#define REG_SCH_TXCMD                  0x05D0
+
+/* Dual MAC Co-Existence Register  */
+#define REG_DMC                                0x05F0
+
+/* ----------------------------------------------------- */
+/*     0x0600h ~ 0x07FFh       WMAC Configuration */
+/* ----------------------------------------------------- */
+#define REG_APSD_CTRL                  0x0600
+#define REG_BWOPMODE                   0x0603
+#define REG_TCR                                0x0604
+#define REG_RCR                                0x0608
+#define REG_RX_PKT_LIMIT               0x060C
+#define REG_RX_DLK_TIME                        0x060D
+#define REG_RX_DRVINFO_SZ              0x060F
+
+#define REG_MACID                      0x0610
+#define REG_BSSID                      0x0618
+#define REG_MAR                                0x0620
+#define REG_MBIDCAMCFG                 0x0628
+
+#define REG_USTIME_EDCA                        0x0638
+#define REG_MAC_SPEC_SIFS              0x063A
+#define REG_RESP_SIFS_CCK              0x063C
+#define REG_RESP_SIFS_OFDM             0x063E
+#define REG_ACKTO                      0x0640
+#define REG_CTS2TO                     0x0641
+#define REG_EIFS                       0x0642
+
+
+/* WMA, BA, CCX */
+#define REG_NAV_CTRL                   0x0650
+#define REG_BACAMCMD                   0x0654
+#define REG_BACAMCONTENT               0x0658
+#define REG_LBDLY                      0x0660
+#define REG_FWDLY                      0x0661
+#define REG_RXERR_RPT                  0x0664
+#define REG_WMAC_TRXPTCL_CTL           0x0668
+
+
+/* Security  */
+#define REG_CAMCMD                     0x0670
+#define REG_CAMWRITE                   0x0674
+#define REG_CAMREAD                    0x0678
+#define REG_CAMDBG                     0x067C
+#define REG_SECCFG                     0x0680
+
+/* Power  */
+#define REG_WOW_CTRL                   0x0690
+#define REG_PSSTATUS                   0x0691
+#define REG_PS_RX_INFO                 0x0692
+#define REG_LPNAV_CTRL                 0x0694
+#define REG_WKFMCAM_CMD                        0x0698
+#define REG_WKFMCAM_RWD                        0x069C
+#define REG_RXFLTMAP0                  0x06A0
+#define REG_RXFLTMAP1                  0x06A2
+#define REG_RXFLTMAP2                  0x06A4
+#define REG_BCN_PSR_RPT                        0x06A8
+#define REG_CALB32K_CTRL               0x06AC
+#define REG_PKT_MON_CTRL               0x06B4
+#define REG_BT_COEX_TABLE              0x06C0
+#define REG_WMAC_RESP_TXINFO           0x06D8
+
+
+/* ----------------------------------------------------- */
+/*     Redifine 8192C register definition for compatibility */
+/* ----------------------------------------------------- */
+#define        CR9346                          REG_9346CR
+#define        MSR                             (REG_CR + 2)
+#define        ISR                             REG_HISR
+#define        TSFR                            REG_TSFTR
+
+#define        MACIDR0                         REG_MACID
+#define        MACIDR4                         (REG_MACID + 4)
+
+#define PBP                            REG_PBP
+
+#define        IDR0                            MACIDR0
+#define        IDR4                            MACIDR4
+
+/* ----------------------------------------------------- */
+/* 8192C (MSR) Media Status Register(Offset 0x4C, 8 bits)*/
+/* ----------------------------------------------------- */
+#define        MSR_NOLINK                      0x00
+#define        MSR_ADHOC                       0x01
+#define        MSR_INFRA                       0x02
+#define        MSR_AP                          0x03
+
+/* 6. Adaptive Control Registers  (Offset: 0x0160 - 0x01CF) */
+/* ----------------------------------------------------- */
+/* 8192C Response Rate Set Register(offset 0x181, 24bits)*/
+/* ----------------------------------------------------- */
+#define        RRSR_RSC_OFFSET                 21
+#define        RRSR_SHORT_OFFSET               23
+#define        RRSR_RSC_BW_40M                 0x600000
+#define        RRSR_RSC_UPSUBCHNL              0x400000
+#define        RRSR_RSC_LOWSUBCHNL             0x200000
+#define        RRSR_SHORT                      0x800000
+#define        RRSR_1M                         BIT0
+#define        RRSR_2M                         BIT1
+#define        RRSR_5_5M                       BIT2
+#define        RRSR_11M                        BIT3
+#define        RRSR_6M                         BIT4
+#define        RRSR_9M                         BIT5
+#define        RRSR_12M                        BIT6
+#define        RRSR_18M                        BIT7
+#define        RRSR_24M                        BIT8
+#define        RRSR_36M                        BIT9
+#define        RRSR_48M                        BIT10
+#define        RRSR_54M                        BIT11
+#define        RRSR_MCS0                       BIT12
+#define        RRSR_MCS1                       BIT13
+#define        RRSR_MCS2                       BIT14
+#define        RRSR_MCS3                       BIT15
+#define        RRSR_MCS4                       BIT16
+#define        RRSR_MCS5                       BIT17
+#define        RRSR_MCS6                       BIT18
+#define        RRSR_MCS7                       BIT19
+#define        BRSR_ACKSHORTPMB                BIT23
+
+/* ----------------------------------------------------- */
+/*       8192C Rate Definition  */
+/* ----------------------------------------------------- */
+/* CCK */
+#define        RATR_1M                         0x00000001
+#define        RATR_2M                         0x00000002
+#define        RATR_55M                        0x00000004
+#define        RATR_11M                        0x00000008
+/* OFDM */
+#define        RATR_6M                         0x00000010
+#define        RATR_9M                         0x00000020
+#define        RATR_12M                        0x00000040
+#define        RATR_18M                        0x00000080
+#define        RATR_24M                        0x00000100
+#define        RATR_36M                        0x00000200
+#define        RATR_48M                        0x00000400
+#define        RATR_54M                        0x00000800
+/* MCS 1 Spatial Stream        */
+#define        RATR_MCS0                       0x00001000
+#define        RATR_MCS1                       0x00002000
+#define        RATR_MCS2                       0x00004000
+#define        RATR_MCS3                       0x00008000
+#define        RATR_MCS4                       0x00010000
+#define        RATR_MCS5                       0x00020000
+#define        RATR_MCS6                       0x00040000
+#define        RATR_MCS7                       0x00080000
+/* MCS 2 Spatial Stream */
+#define        RATR_MCS8                       0x00100000
+#define        RATR_MCS9                       0x00200000
+#define        RATR_MCS10                      0x00400000
+#define        RATR_MCS11                      0x00800000
+#define        RATR_MCS12                      0x01000000
+#define        RATR_MCS13                      0x02000000
+#define        RATR_MCS14                      0x04000000
+#define        RATR_MCS15                      0x08000000
+
+/* CCK */
+#define RATE_1M                                BIT(0)
+#define RATE_2M                                BIT(1)
+#define RATE_5_5M                      BIT(2)
+#define RATE_11M                       BIT(3)
+/* OFDM  */
+#define RATE_6M                                BIT(4)
+#define RATE_9M                                BIT(5)
+#define RATE_12M                       BIT(6)
+#define RATE_18M                       BIT(7)
+#define RATE_24M                       BIT(8)
+#define RATE_36M                       BIT(9)
+#define RATE_48M                       BIT(10)
+#define RATE_54M                       BIT(11)
+/* MCS 1 Spatial Stream */
+#define RATE_MCS0                      BIT(12)
+#define RATE_MCS1                      BIT(13)
+#define RATE_MCS2                      BIT(14)
+#define RATE_MCS3                      BIT(15)
+#define RATE_MCS4                      BIT(16)
+#define RATE_MCS5                      BIT(17)
+#define RATE_MCS6                      BIT(18)
+#define RATE_MCS7                      BIT(19)
+/* MCS 2 Spatial Stream */
+#define RATE_MCS8                      BIT(20)
+#define RATE_MCS9                      BIT(21)
+#define RATE_MCS10                     BIT(22)
+#define RATE_MCS11                     BIT(23)
+#define RATE_MCS12                     BIT(24)
+#define RATE_MCS13                     BIT(25)
+#define RATE_MCS14                     BIT(26)
+#define RATE_MCS15                     BIT(27)
+
+/* ALL CCK Rate */
+#define        RATE_ALL_CCK                    (RATR_1M | RATR_2M | RATR_55M | \
+                                       RATR_11M)
+#define        RATE_ALL_OFDM_AG                (RATR_6M | RATR_9M | RATR_12M | \
+                                       RATR_18M | RATR_24M | \
+                                       RATR_36M | RATR_48M | RATR_54M)
+#define        RATE_ALL_OFDM_1SS               (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \
+                                       RATR_MCS3 | RATR_MCS4 | RATR_MCS5 | \
+                                       RATR_MCS6 | RATR_MCS7)
+#define        RATE_ALL_OFDM_2SS               (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \
+                                       RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \
+                                       RATR_MCS14 | RATR_MCS15)
+
+/* ----------------------------------------------------- */
+/*    8192C BW_OPMODE bits             (Offset 0x203, 8bit)     */
+/* ----------------------------------------------------- */
+#define        BW_OPMODE_20MHZ                 BIT(2)
+#define        BW_OPMODE_5G                    BIT(1)
+#define        BW_OPMODE_11J                   BIT(0)
+
+
+/* ----------------------------------------------------- */
+/*     8192C CAM Config Setting (offset 0x250, 1 byte)   */
+/* ----------------------------------------------------- */
+#define        CAM_VALID                       BIT(15)
+#define        CAM_NOTVALID                    0x0000
+#define        CAM_USEDK                       BIT(5)
+
+#define        CAM_NONE                        0x0
+#define        CAM_WEP40                       0x01
+#define        CAM_TKIP                        0x02
+#define        CAM_AES                         0x04
+#define        CAM_WEP104                      0x05
+#define        CAM_SMS4                        0x6
+
+
+#define        TOTAL_CAM_ENTRY                 32
+#define        HALF_CAM_ENTRY                  16
+
+#define        CAM_WRITE                       BIT(16)
+#define        CAM_READ                        0x00000000
+#define        CAM_POLLINIG                    BIT(31)
+
+/* 10. Power Save Control Registers     (Offset: 0x0260 - 0x02DF) */
+#define        WOW_PMEN                        BIT0 /* Power management Enable. */
+#define        WOW_WOMEN                       BIT1 /* WoW function on or off. */
+#define        WOW_MAGIC                       BIT2 /* Magic packet */
+#define        WOW_UWF                         BIT3 /* Unicast Wakeup frame. */
+
+/* 12. Host Interrupt Status Registers  (Offset: 0x0300 - 0x030F) */
+/* ----------------------------------------------------- */
+/*      8190 IMR/ISR bits      (offset 0xfd,  8bits) */
+/* ----------------------------------------------------- */
+#define        IMR8190_DISABLED                0x0
+#define        IMR_BCNDMAINT6                  BIT(31)
+#define        IMR_BCNDMAINT5                  BIT(30)
+#define        IMR_BCNDMAINT4                  BIT(29)
+#define        IMR_BCNDMAINT3                  BIT(28)
+#define        IMR_BCNDMAINT2                  BIT(27)
+#define        IMR_BCNDMAINT1                  BIT(26)
+#define        IMR_BCNDOK8                     BIT(25)
+#define        IMR_BCNDOK7                     BIT(24)
+#define        IMR_BCNDOK6                     BIT(23)
+#define        IMR_BCNDOK5                     BIT(22)
+#define        IMR_BCNDOK4                     BIT(21)
+#define        IMR_BCNDOK3                     BIT(20)
+#define        IMR_BCNDOK2                     BIT(19)
+#define        IMR_BCNDOK1                     BIT(18)
+#define        IMR_TIMEOUT2                    BIT(17)
+#define        IMR_TIMEOUT1                    BIT(16)
+#define        IMR_TXFOVW                      BIT(15)
+#define        IMR_PSTIMEOUT                   BIT(14)
+#define        IMR_BcnInt                      BIT(13)
+#define        IMR_RXFOVW                      BIT(12)
+#define        IMR_RDU                         BIT(11)
+#define        IMR_ATIMEND                     BIT(10)
+#define        IMR_BDOK                        BIT(9)
+#define        IMR_HIGHDOK                     BIT(8)
+#define        IMR_TBDOK                       BIT(7)
+#define        IMR_MGNTDOK                     BIT(6)
+#define        IMR_TBDER                       BIT(5)
+#define        IMR_BKDOK                       BIT(4)
+#define        IMR_BEDOK                       BIT(3)
+#define        IMR_VIDOK                       BIT(2)
+#define        IMR_VODOK                       BIT(1)
+#define        IMR_ROK                         BIT(0)
+
+#define        IMR_TXERR                       BIT(11)
+#define        IMR_RXERR                       BIT(10)
+#define        IMR_C2HCMD                      BIT(9)
+#define        IMR_CPWM                        BIT(8)
+#define        IMR_OCPINT                      BIT(1)
+#define        IMR_WLANOFF                     BIT(0)
+
+/* ----------------------------------------------------- */
+/* 8192C EFUSE */
+/* ----------------------------------------------------- */
+#define        HWSET_MAX_SIZE                  256
+#define EFUSE_MAX_SECTION              32
+#define EFUSE_REAL_CONTENT_LEN         512
+
+/* ----------------------------------------------------- */
+/*     8192C EEPROM/EFUSE share register definition. */
+/* ----------------------------------------------------- */
+#define        EEPROM_DEFAULT_TSSI                     0x0
+#define EEPROM_DEFAULT_CRYSTALCAP              0x0
+#define        EEPROM_DEFAULT_THERMALMETER             0x12
+
+#define        EEPROM_DEFAULT_TXPOWERLEVEL_2G          0x2C
+#define        EEPROM_DEFAULT_TXPOWERLEVEL_5G          0x22
+
+#define        EEPROM_DEFAULT_HT40_2SDIFF              0x0
+/* HT20<->40 default Tx Power Index Difference */
+#define EEPROM_DEFAULT_HT20_DIFF               2
+/* OFDM Tx Power index diff */
+#define        EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF      0x4
+#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET       0
+#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET       0
+
+#define        EEPROM_CHANNEL_PLAN_FCC                 0x0
+#define        EEPROM_CHANNEL_PLAN_IC                  0x1
+#define        EEPROM_CHANNEL_PLAN_ETSI                0x2
+#define        EEPROM_CHANNEL_PLAN_SPAIN               0x3
+#define        EEPROM_CHANNEL_PLAN_FRANCE              0x4
+#define        EEPROM_CHANNEL_PLAN_MKK                 0x5
+#define        EEPROM_CHANNEL_PLAN_MKK1                0x6
+#define        EEPROM_CHANNEL_PLAN_ISRAEL              0x7
+#define        EEPROM_CHANNEL_PLAN_TELEC               0x8
+#define        EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN       0x9
+#define        EEPROM_CHANNEL_PLAN_WORLD_WIDE_13       0xA
+#define        EEPROM_CHANNEL_PLAN_NCC                 0xB
+#define        EEPROM_CHANNEL_PLAN_BY_HW_MASK          0x80
+
+#define EEPROM_CID_DEFAULT                     0x0
+#define EEPROM_CID_TOSHIBA                     0x4
+#define        EEPROM_CID_CCX                          0x10
+#define        EEPROM_CID_QMI                          0x0D
+#define EEPROM_CID_WHQL                                0xFE
+
+
+#define        RTL8192_EEPROM_ID                       0x8129
+#define        EEPROM_WAPI_SUPPORT                     0x78
+
+
+#define RTL8190_EEPROM_ID              0x8129  /* 0-1 */
+#define EEPROM_HPON                    0x02 /* LDO settings.2-5 */
+#define EEPROM_CLK                     0x06 /* Clock settings.6-7 */
+#define EEPROM_MAC_FUNCTION            0x08 /* SE Test mode.8 */
+
+#define EEPROM_VID                     0x28 /* SE Vendor ID.A-B */
+#define EEPROM_DID                     0x2A /* SE Device ID. C-D */
+#define EEPROM_SVID                    0x2C /* SE Vendor ID.E-F */
+#define EEPROM_SMID                    0x2E /* SE PCI Subsystem ID. 10-11 */
+
+#define EEPROM_MAC_ADDR                        0x16 /* SEMAC Address. 12-17 */
+#define EEPROM_MAC_ADDR_MAC0_92D       0x55
+#define EEPROM_MAC_ADDR_MAC1_92D       0x5B
+
+/* 2.4G band Tx power index setting */
+#define EEPROM_CCK_TX_PWR_INX_2G       0x61
+#define EEPROM_HT40_1S_TX_PWR_INX_2G   0x67
+#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_2G      0x6D
+#define EEPROM_HT20_TX_PWR_INX_DIFF_2G         0x70
+#define EEPROM_OFDM_TX_PWR_INX_DIFF_2G         0x73
+#define EEPROM_HT40_MAX_PWR_OFFSET_2G          0x76
+#define EEPROM_HT20_MAX_PWR_OFFSET_2G          0x79
+
+/*5GL channel 32-64 */
+#define EEPROM_HT40_1S_TX_PWR_INX_5GL          0x7C
+#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GL     0x82
+#define EEPROM_HT20_TX_PWR_INX_DIFF_5GL                0x85
+#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GL                0x88
+#define EEPROM_HT40_MAX_PWR_OFFSET_5GL         0x8B
+#define EEPROM_HT20_MAX_PWR_OFFSET_5GL         0x8E
+
+/* 5GM channel 100-140 */
+#define EEPROM_HT40_1S_TX_PWR_INX_5GM          0x91
+#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GM     0x97
+#define EEPROM_HT20_TX_PWR_INX_DIFF_5GM                0x9A
+#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GM                0x9D
+#define EEPROM_HT40_MAX_PWR_OFFSET_5GM         0xA0
+#define EEPROM_HT20_MAX_PWR_OFFSET_5GM         0xA3
+
+/* 5GH channel 149-165 */
+#define EEPROM_HT40_1S_TX_PWR_INX_5GH          0xA6
+#define EEPROM_HT40_2S_TX_PWR_INX_DIFF_5GH     0xAC
+#define EEPROM_HT20_TX_PWR_INX_DIFF_5GH                0xAF
+#define EEPROM_OFDM_TX_PWR_INX_DIFF_5GH                0xB2
+#define EEPROM_HT40_MAX_PWR_OFFSET_5GH         0xB5
+#define EEPROM_HT20_MAX_PWR_OFFSET_5GH         0xB8
+
+/* Map of supported channels. */
+#define EEPROM_CHANNEL_PLAN                    0xBB
+#define EEPROM_IQK_DELTA                       0xBC
+#define EEPROM_LCK_DELTA                       0xBC
+#define EEPROM_XTAL_K                          0xBD    /* [7:5] */
+#define EEPROM_TSSI_A_5G                       0xBE
+#define EEPROM_TSSI_B_5G                       0xBF
+#define EEPROM_TSSI_AB_5G                      0xC0
+#define EEPROM_THERMAL_METER                   0xC3    /* [4:0] */
+#define EEPROM_RF_OPT1                         0xC4
+#define EEPROM_RF_OPT2                         0xC5
+#define EEPROM_RF_OPT3                         0xC6
+#define EEPROM_RF_OPT4                         0xC7
+#define EEPROM_RF_OPT5                         0xC8
+#define EEPROM_RF_OPT6                         0xC9
+#define EEPROM_VERSION                         0xCA
+#define EEPROM_CUSTOMER_ID                     0xCB
+#define EEPROM_RF_OPT7                         0xCC
+
+#define EEPROM_DEF_PART_NO                     0x3FD    /* Byte */
+#define EEPROME_CHIP_VERSION_L                 0x3FF
+#define EEPROME_CHIP_VERSION_H                 0x3FE
+
+/*
+ * Current IOREG MAP
+ * 0x0000h ~ 0x00FFh   System Configuration (256 Bytes)
+ * 0x0100h ~ 0x01FFh   MACTOP General Configuration (256 Bytes)
+ * 0x0200h ~ 0x027Fh   TXDMA Configuration (128 Bytes)
+ * 0x0280h ~ 0x02FFh   RXDMA Configuration (128 Bytes)
+ * 0x0300h ~ 0x03FFh   PCIE EMAC Reserved Region (256 Bytes)
+ * 0x0400h ~ 0x04FFh   Protocol Configuration (256 Bytes)
+ * 0x0500h ~ 0x05FFh   EDCA Configuration (256 Bytes)
+ * 0x0600h ~ 0x07FFh   WMAC Configuration (512 Bytes)
+ * 0x2000h ~ 0x3FFFh   8051 FW Download Region (8196 Bytes)
+ */
+
+/* ----------------------------------------------------- */
+/* 8192C (RCR) (Offset 0x608, 32 bits) */
+/* ----------------------------------------------------- */
+#define        RCR_APPFCS                              BIT(31)
+#define        RCR_APP_MIC                             BIT(30)
+#define        RCR_APP_ICV                             BIT(29)
+#define        RCR_APP_PHYST_RXFF                      BIT(28)
+#define        RCR_APP_BA_SSN                          BIT(27)
+#define        RCR_ENMBID                              BIT(24)
+#define        RCR_LSIGEN                              BIT(23)
+#define        RCR_MFBEN                               BIT(22)
+#define        RCR_HTC_LOC_CTRL                        BIT(14)
+#define        RCR_AMF                                 BIT(13)
+#define        RCR_ACF                                 BIT(12)
+#define        RCR_ADF                                 BIT(11)
+#define        RCR_AICV                                BIT(9)
+#define        RCR_ACRC32                              BIT(8)
+#define        RCR_CBSSID_BCN                          BIT(7)
+#define        RCR_CBSSID_DATA                         BIT(6)
+#define        RCR_APWRMGT                             BIT(5)
+#define        RCR_ADD3                                BIT(4)
+#define        RCR_AB                                  BIT(3)
+#define        RCR_AM                                  BIT(2)
+#define        RCR_APM                                 BIT(1)
+#define        RCR_AAP                                 BIT(0)
+#define        RCR_MXDMA_OFFSET                        8
+#define        RCR_FIFO_OFFSET                         13
+
+/* ----------------------------------------------------- */
+/*       8192C Regsiter Bit and Content definition      */
+/* ----------------------------------------------------- */
+/* ----------------------------------------------------- */
+/*     0x0000h ~ 0x00FFh       System Configuration */
+/* ----------------------------------------------------- */
+
+/* SPS0_CTRL */
+#define SW18_FPWM                              BIT(3)
+
+
+/* SYS_ISO_CTRL */
+#define ISO_MD2PP                              BIT(0)
+#define ISO_UA2USB                             BIT(1)
+#define ISO_UD2CORE                            BIT(2)
+#define ISO_PA2PCIE                            BIT(3)
+#define ISO_PD2CORE                            BIT(4)
+#define ISO_IP2MAC                             BIT(5)
+#define ISO_DIOP                               BIT(6)
+#define ISO_DIOE                               BIT(7)
+#define ISO_EB2CORE                            BIT(8)
+#define ISO_DIOR                               BIT(9)
+
+#define PWC_EV25V                              BIT(14)
+#define PWC_EV12V                              BIT(15)
+
+
+/* SYS_FUNC_EN */
+#define FEN_BBRSTB                             BIT(0)
+#define FEN_BB_GLB_RSTn                                BIT(1)
+#define FEN_USBA                               BIT(2)
+#define FEN_UPLL                               BIT(3)
+#define FEN_USBD                               BIT(4)
+#define FEN_DIO_PCIE                           BIT(5)
+#define FEN_PCIEA                              BIT(6)
+#define FEN_PPLL                               BIT(7)
+#define FEN_PCIED                              BIT(8)
+#define FEN_DIOE                               BIT(9)
+#define FEN_CPUEN                              BIT(10)
+#define FEN_DCORE                              BIT(11)
+#define FEN_ELDR                               BIT(12)
+#define FEN_DIO_RF                             BIT(13)
+#define FEN_HWPDN                              BIT(14)
+#define FEN_MREGEN                             BIT(15)
+
+/* APS_FSMCO */
+#define PFM_LDALL                              BIT(0)
+#define PFM_ALDN                               BIT(1)
+#define PFM_LDKP                               BIT(2)
+#define PFM_WOWL                               BIT(3)
+#define EnPDN                                  BIT(4)
+#define PDN_PL                                 BIT(5)
+#define APFM_ONMAC                             BIT(8)
+#define APFM_OFF                               BIT(9)
+#define APFM_RSM                               BIT(10)
+#define AFSM_HSUS                              BIT(11)
+#define AFSM_PCIE                              BIT(12)
+#define APDM_MAC                               BIT(13)
+#define APDM_HOST                              BIT(14)
+#define APDM_HPDN                              BIT(15)
+#define RDY_MACON                              BIT(16)
+#define SUS_HOST                               BIT(17)
+#define ROP_ALD                                        BIT(20)
+#define ROP_PWR                                        BIT(21)
+#define ROP_SPS                                        BIT(22)
+#define SOP_MRST                               BIT(25)
+#define SOP_FUSE                               BIT(26)
+#define SOP_ABG                                        BIT(27)
+#define SOP_AMB                                        BIT(28)
+#define SOP_RCK                                        BIT(29)
+#define SOP_A8M                                        BIT(30)
+#define XOP_BTCK                               BIT(31)
+
+/* SYS_CLKR */
+#define ANAD16V_EN                             BIT(0)
+#define ANA8M                                  BIT(1)
+#define MACSLP                                 BIT(4)
+#define LOADER_CLK_EN                          BIT(5)
+#define _80M_SSC_DIS                           BIT(7)
+#define _80M_SSC_EN_HO                         BIT(8)
+#define PHY_SSC_RSTB                           BIT(9)
+#define SEC_CLK_EN                             BIT(10)
+#define MAC_CLK_EN                             BIT(11)
+#define SYS_CLK_EN                             BIT(12)
+#define RING_CLK_EN                            BIT(13)
+
+
+/* 9346CR */
+#define        BOOT_FROM_EEPROM                        BIT(4)
+#define        EEPROM_EN                               BIT(5)
+
+/* AFE_MISC */
+#define AFE_BGEN                               BIT(0)
+#define AFE_MBEN                               BIT(1)
+#define MAC_ID_EN                              BIT(7)
+
+/* RSV_CTRL */
+#define WLOCK_ALL                              BIT(0)
+#define WLOCK_00                               BIT(1)
+#define WLOCK_04                               BIT(2)
+#define WLOCK_08                               BIT(3)
+#define WLOCK_40                               BIT(4)
+#define R_DIS_PRST_0                           BIT(5)
+#define R_DIS_PRST_1                           BIT(6)
+#define LOCK_ALL_EN                            BIT(7)
+
+/* RF_CTRL */
+#define RF_EN                                  BIT(0)
+#define RF_RSTB                                        BIT(1)
+#define RF_SDMRSTB                             BIT(2)
+
+
+
+/* LDOA15_CTRL */
+#define LDA15_EN                               BIT(0)
+#define LDA15_STBY                             BIT(1)
+#define LDA15_OBUF                             BIT(2)
+#define LDA15_REG_VOS                          BIT(3)
+#define _LDA15_VOADJ(x)                                (((x) & 0x7) << 4)
+
+
+
+/* LDOV12D_CTRL */
+#define LDV12_EN                               BIT(0)
+#define LDV12_SDBY                             BIT(1)
+#define LPLDO_HSM                              BIT(2)
+#define LPLDO_LSM_DIS                          BIT(3)
+#define _LDV12_VADJ(x)                         (((x) & 0xF) << 4)
+
+
+/* AFE_XTAL_CTRL */
+#define XTAL_EN                                        BIT(0)
+#define XTAL_BSEL                              BIT(1)
+#define _XTAL_BOSC(x)                          (((x) & 0x3) << 2)
+#define _XTAL_CADJ(x)                          (((x) & 0xF) << 4)
+#define XTAL_GATE_USB                          BIT(8)
+#define _XTAL_USB_DRV(x)                       (((x) & 0x3) << 9)
+#define XTAL_GATE_AFE                          BIT(11)
+#define _XTAL_AFE_DRV(x)                       (((x) & 0x3) << 12)
+#define XTAL_RF_GATE                           BIT(14)
+#define _XTAL_RF_DRV(x)                                (((x) & 0x3) << 15)
+#define XTAL_GATE_DIG                          BIT(17)
+#define _XTAL_DIG_DRV(x)                       (((x) & 0x3) << 18)
+#define XTAL_BT_GATE                           BIT(20)
+#define _XTAL_BT_DRV(x)                                (((x) & 0x3) << 21)
+#define _XTAL_GPIO(x)                          (((x) & 0x7) << 23)
+
+
+#define CKDLY_AFE                              BIT(26)
+#define CKDLY_USB                              BIT(27)
+#define CKDLY_DIG                              BIT(28)
+#define CKDLY_BT                               BIT(29)
+
+
+/* AFE_PLL_CTRL */
+#define APLL_EN                                        BIT(0)
+#define APLL_320_EN                            BIT(1)
+#define APLL_FREF_SEL                          BIT(2)
+#define APLL_EDGE_SEL                          BIT(3)
+#define APLL_WDOGB                             BIT(4)
+#define APLL_LPFEN                             BIT(5)
+
+#define APLL_REF_CLK_13MHZ                     0x1
+#define APLL_REF_CLK_19_2MHZ                   0x2
+#define APLL_REF_CLK_20MHZ                     0x3
+#define APLL_REF_CLK_25MHZ                     0x4
+#define APLL_REF_CLK_26MHZ                     0x5
+#define APLL_REF_CLK_38_4MHZ                   0x6
+#define APLL_REF_CLK_40MHZ                     0x7
+
+#define APLL_320EN                             BIT(14)
+#define APLL_80EN                              BIT(15)
+#define APLL_1MEN                              BIT(24)
+
+
+/* EFUSE_CTRL */
+#define ALD_EN                                 BIT(18)
+#define EF_PD                                  BIT(19)
+#define EF_FLAG                                        BIT(31)
+
+/* EFUSE_TEST  */
+#define EF_TRPT                                        BIT(7)
+#define LDOE25_EN                              BIT(31)
+
+/* MCUFWDL  */
+#define MCUFWDL_EN                             BIT(0)
+#define MCUFWDL_RDY                            BIT(1)
+#define FWDL_ChkSum_rpt                                BIT(2)
+#define MACINI_RDY                             BIT(3)
+#define BBINI_RDY                              BIT(4)
+#define RFINI_RDY                              BIT(5)
+#define WINTINI_RDY                            BIT(6)
+#define MAC1_WINTINI_RDY                       BIT(11)
+#define CPRST                                  BIT(23)
+
+/*  REG_SYS_CFG */
+#define XCLK_VLD                               BIT(0)
+#define ACLK_VLD                               BIT(1)
+#define UCLK_VLD                               BIT(2)
+#define PCLK_VLD                               BIT(3)
+#define PCIRSTB                                        BIT(4)
+#define V15_VLD                                        BIT(5)
+#define TRP_B15V_EN                            BIT(7)
+#define SIC_IDLE                               BIT(8)
+#define BD_MAC2                                        BIT(9)
+#define BD_MAC1                                        BIT(10)
+#define IC_MACPHY_MODE                         BIT(11)
+#define PAD_HWPD_IDN                           BIT(22)
+#define TRP_VAUX_EN                            BIT(23)
+#define TRP_BT_EN                              BIT(24)
+#define BD_PKG_SEL                             BIT(25)
+#define BD_HCI_SEL                             BIT(26)
+#define TYPE_ID                                        BIT(27)
+
+/* LLT_INIT */
+#define _LLT_NO_ACTIVE                         0x0
+#define _LLT_WRITE_ACCESS                      0x1
+#define _LLT_READ_ACCESS                       0x2
+
+#define _LLT_INIT_DATA(x)                      ((x) & 0xFF)
+#define _LLT_INIT_ADDR(x)                      (((x) & 0xFF) << 8)
+#define _LLT_OP(x)                             (((x) & 0x3) << 30)
+#define _LLT_OP_VALUE(x)                       (((x) >> 30) & 0x3)
+
+
+/* ----------------------------------------------------- */
+/*     0x0400h ~ 0x047Fh       Protocol Configuration   */
+/* ----------------------------------------------------- */
+#define        RETRY_LIMIT_SHORT_SHIFT                 8
+#define        RETRY_LIMIT_LONG_SHIFT                  0
+
+
+/* ----------------------------------------------------- */
+/*     0x0500h ~ 0x05FFh       EDCA Configuration */
+/* ----------------------------------------------------- */
+/* EDCA setting */
+#define AC_PARAM_TXOP_LIMIT_OFFSET             16
+#define AC_PARAM_ECW_MAX_OFFSET                        12
+#define AC_PARAM_ECW_MIN_OFFSET                        8
+#define AC_PARAM_AIFS_OFFSET                   0
+
+/* ACMHWCTRL */
+#define        ACMHW_HWEN                              BIT(0)
+#define        ACMHW_BEQEN                             BIT(1)
+#define        ACMHW_VIQEN                             BIT(2)
+#define        ACMHW_VOQEN                             BIT(3)
+
+/* ----------------------------------------------------- */
+/*     0x0600h ~ 0x07FFh       WMAC Configuration */
+/* ----------------------------------------------------- */
+
+/* TCR */
+#define TSFRST                                 BIT(0)
+#define DIS_GCLK                               BIT(1)
+#define PAD_SEL                                        BIT(2)
+#define PWR_ST                                 BIT(6)
+#define PWRBIT_OW_EN                           BIT(7)
+#define ACRC                                   BIT(8)
+#define CFENDFORM                              BIT(9)
+#define ICV                                    BIT(10)
+
+/* SECCFG */
+#define        SCR_TXUSEDK                             BIT(0)
+#define        SCR_RXUSEDK                             BIT(1)
+#define        SCR_TXENCENABLE                         BIT(2)
+#define        SCR_RXENCENABLE                         BIT(3)
+#define        SCR_SKBYA2                              BIT(4)
+#define        SCR_NOSKMC                              BIT(5)
+#define SCR_TXBCUSEDK                          BIT(6)
+#define SCR_RXBCUSEDK                          BIT(7)
+
+/* General definitions */
+#define MAC_ADDR_LEN                           6
+#define LAST_ENTRY_OF_TX_PKT_BUFFER            255
+#define LAST_ENTRY_OF_TX_PKT_BUFFER_DUAL_MAC   127
+
+#define POLLING_LLT_THRESHOLD                  20
+#define POLLING_READY_TIMEOUT_COUNT            1000
+
+/* Min Spacing related settings. */
+#define        MAX_MSS_DENSITY_2T                      0x13
+#define        MAX_MSS_DENSITY_1T                      0x0A
+
+
+/* BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF */
+/* 1. PMAC duplicate register due to connection: */
+/*    RF_Mode, TRxRN, NumOf L-STF */
+/* 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 */
+/* 3. RF register 0x00-2E */
+/* 4. Bit Mask for BB/RF register */
+/* 5. Other defintion for BB/RF R/W */
+
+/* 3. Page8(0x800) */
+#define        RFPGA0_RFMOD                            0x800
+
+#define        RFPGA0_TXINFO                           0x804
+#define        RFPGA0_PSDFUNCTION                      0x808
+
+#define        RFPGA0_TXGAINSTAGE                      0x80c
+
+#define        RFPGA0_RFTIMING1                        0x810
+#define        RFPGA0_RFTIMING2                        0x814
+
+#define        RFPGA0_XA_HSSIPARAMETER1                0x820
+#define        RFPGA0_XA_HSSIPARAMETER2                0x824
+#define        RFPGA0_XB_HSSIPARAMETER1                0x828
+#define        RFPGA0_XB_HSSIPARAMETER2                0x82c
+
+#define        RFPGA0_XA_LSSIPARAMETER                 0x840
+#define        RFPGA0_XB_LSSIPARAMETER                 0x844
+
+#define        RFPGA0_RFWAkEUPPARAMETER                0x850
+#define        RFPGA0_RFSLEEPUPPARAMETER               0x854
+
+#define        RFPGA0_XAB_SWITCHCONTROL                0x858
+#define        RFPGA0_XCD_SWITCHCONTROL                0x85c
+
+#define        RFPGA0_XA_RFINTERFACEOE                 0x860
+#define        RFPGA0_XB_RFINTERFACEOE                 0x864
+
+#define        RFPGA0_XAB_RFINTERFACESW                0x870
+#define        RFPGA0_XCD_RFINTERFACESW                0x874
+
+#define        RFPGA0_XAB_RFPARAMETER                  0x878
+#define        RFPGA0_XCD_RFPARAMETER                  0x87c
+
+#define        RFPGA0_ANALOGPARAMETER1                 0x880
+#define        RFPGA0_ANALOGPARAMETER2                 0x884
+#define        RFPGA0_ANALOGPARAMETER3                 0x888
+#define        RFPGA0_ADDALLOCKEN                      0x888
+#define        RFPGA0_ANALOGPARAMETER4                 0x88c
+
+#define        RFPGA0_XA_LSSIREADBACK                  0x8a0
+#define        RFPGA0_XB_LSSIREADBACK                  0x8a4
+#define        RFPGA0_XC_LSSIREADBACK                  0x8a8
+#define        RFPGA0_XD_LSSIREADBACK                  0x8ac
+
+#define        RFPGA0_PSDREPORT                        0x8b4
+#define        TRANSCEIVERA_HSPI_READBACK              0x8b8
+#define        TRANSCEIVERB_HSPI_READBACK              0x8bc
+#define        RFPGA0_XAB_RFINTERFACERB                0x8e0
+#define        RFPGA0_XCD_RFINTERFACERB                0x8e4
+
+/* 4. Page9(0x900) */
+#define        RFPGA1_RFMOD                            0x900
+
+#define        RFPGA1_TXBLOCK                          0x904
+#define        RFPGA1_DEBUGSELECT                      0x908
+#define        RFPGA1_TXINFO                           0x90c
+
+/* 5. PageA(0xA00)  */
+#define        RCCK0_SYSTEM                            0xa00
+
+#define        RCCK0_AFESSTTING                        0xa04
+#define        RCCK0_CCA                               0xa08
+
+#define        RCCK0_RXAGC1                            0xa0c
+#define        RCCK0_RXAGC2                            0xa10
+
+#define        RCCK0_RXHP                              0xa14
+
+#define        RCCK0_DSPPARAMETER1                     0xa18
+#define        RCCK0_DSPPARAMETER2                     0xa1c
+
+#define        RCCK0_TXFILTER1                         0xa20
+#define        RCCK0_TXFILTER2                         0xa24
+#define        RCCK0_DEBUGPORT                         0xa28
+#define        RCCK0_FALSEALARMREPORT                  0xa2c
+#define        RCCK0_TRSSIREPORT                       0xa50
+#define        RCCK0_RXREPORT                          0xa54
+#define        RCCK0_FACOUNTERLOWER                    0xa5c
+#define        RCCK0_FACOUNTERUPPER                    0xa58
+
+/* 6. PageC(0xC00) */
+#define        ROFDM0_LSTF                             0xc00
+
+#define        ROFDM0_TRXPATHENABLE                    0xc04
+#define        ROFDM0_TRMUXPAR                         0xc08
+#define        ROFDM0_TRSWISOLATION                    0xc0c
+
+#define        ROFDM0_XARXAFE                          0xc10
+#define        ROFDM0_XARXIQIMBALANCE                  0xc14
+#define        ROFDM0_XBRXAFE                          0xc18
+#define        ROFDM0_XBRXIQIMBALANCE                  0xc1c
+#define        ROFDM0_XCRXAFE                          0xc20
+#define        ROFDM0_XCRXIQIMBALANCE                  0xc24
+#define        ROFDM0_XDRXAFE                          0xc28
+#define        ROFDM0_XDRXIQIMBALANCE                  0xc2c
+
+#define        ROFDM0_RXDETECTOR1                      0xc30
+#define        ROFDM0_RXDETECTOR2                      0xc34
+#define        ROFDM0_RXDETECTOR3                      0xc38
+#define        ROFDM0_RXDETECTOR4                      0xc3c
+
+#define        ROFDM0_RXDSP                            0xc40
+#define        ROFDM0_CFOANDDAGC                       0xc44
+#define        ROFDM0_CCADROPTHRESHOLD                 0xc48
+#define        ROFDM0_ECCATHRESHOLD                    0xc4c
+
+#define        ROFDM0_XAAGCCORE1                       0xc50
+#define        ROFDM0_XAAGCCORE2                       0xc54
+#define        ROFDM0_XBAGCCORE1                       0xc58
+#define        ROFDM0_XBAGCCORE2                       0xc5c
+#define        ROFDM0_XCAGCCORE1                       0xc60
+#define        ROFDM0_XCAGCCORE2                       0xc64
+#define        ROFDM0_XDAGCCORE1                       0xc68
+#define        ROFDM0_XDAGCCORE2                       0xc6c
+
+#define        ROFDM0_AGCPARAMETER1                    0xc70
+#define        ROFDM0_AGCPARAMETER2                    0xc74
+#define        ROFDM0_AGCRSSITABLE                     0xc78
+#define        ROFDM0_HTSTFAGC                         0xc7c
+
+#define        ROFDM0_XATxIQIMBALANCE                  0xc80
+#define        ROFDM0_XATxAFE                          0xc84
+#define        ROFDM0_XBTxIQIMBALANCE                  0xc88
+#define        ROFDM0_XBTxAFE                          0xc8c
+#define        ROFDM0_XCTxIQIMBALANCE                  0xc90
+#define        ROFDM0_XCTxAFE                          0xc94
+#define        ROFDM0_XDTxIQIMBALANCE                  0xc98
+#define        ROFDM0_XDTxAFE                          0xc9c
+
+#define        ROFDM0_RXHPPARAMETER                    0xce0
+#define        ROFDM0_TXPSEUDONOISEWGT                 0xce4
+#define        ROFDM0_FRAMESYNC                        0xcf0
+#define        ROFDM0_DFSREPORT                        0xcf4
+#define        ROFDM0_TXCOEFF1                         0xca4
+#define        ROFDM0_TXCOEFF2                         0xca8
+#define        ROFDM0_TXCOEFF3                         0xcac
+#define        ROFDM0_TXCOEFF4                         0xcb0
+#define        ROFDM0_TXCOEFF5                         0xcb4
+#define        ROFDM0_TXCOEFF6                         0xcb8
+
+/* 7. PageD(0xD00) */
+#define        ROFDM1_LSTF                             0xd00
+#define        ROFDM1_TRXPATHENABLE                    0xd04
+
+#define        ROFDM1_CFO                              0xd08
+#define        ROFDM1_CSI1                             0xd10
+#define        ROFDM1_SBD                              0xd14
+#define        ROFDM1_CSI2                             0xd18
+#define        ROFDM1_CFOTRACKING                      0xd2c
+#define        ROFDM1_TRXMESAURE1                      0xd34
+#define        ROFDM1_INTFDET                          0xd3c
+#define        ROFDM1_PSEUDONOISESTATEAB               0xd50
+#define        ROFDM1_PSEUDONOISESTATECD               0xd54
+#define        ROFDM1_RXPSEUDONOISEWGT                 0xd58
+
+#define        ROFDM_PHYCOUNTER1                       0xda0
+#define        ROFDM_PHYCOUNTER2                       0xda4
+#define        ROFDM_PHYCOUNTER3                       0xda8
+
+#define        ROFDM_SHORTCFOAB                        0xdac
+#define        ROFDM_SHORTCFOCD                        0xdb0
+#define        ROFDM_LONGCFOAB                         0xdb4
+#define        ROFDM_LONGCFOCD                         0xdb8
+#define        ROFDM_TAILCFOAB                         0xdbc
+#define        ROFDM_TAILCFOCD                         0xdc0
+#define        ROFDM_PWMEASURE1                        0xdc4
+#define        ROFDM_PWMEASURE2                        0xdc8
+#define        ROFDM_BWREPORT                          0xdcc
+#define        ROFDM_AGCREPORT                         0xdd0
+#define        ROFDM_RXSNR                             0xdd4
+#define        ROFDM_RXEVMCSI                          0xdd8
+#define        ROFDM_SIGReport                         0xddc
+
+/* 8. PageE(0xE00) */
+#define        RTXAGC_A_RATE18_06                      0xe00
+#define        RTXAGC_A_RATE54_24                      0xe04
+#define        RTXAGC_A_CCK1_MCS32                     0xe08
+#define        RTXAGC_A_MCS03_MCS00                    0xe10
+#define        RTXAGC_A_MCS07_MCS04                    0xe14
+#define        RTXAGC_A_MCS11_MCS08                    0xe18
+#define        RTXAGC_A_MCS15_MCS12                    0xe1c
+
+#define        RTXAGC_B_RATE18_06                      0x830
+#define        RTXAGC_B_RATE54_24                      0x834
+#define        RTXAGC_B_CCK1_55_MCS32                  0x838
+#define        RTXAGC_B_MCS03_MCS00                    0x83c
+#define        RTXAGC_B_MCS07_MCS04                    0x848
+#define        RTXAGC_B_MCS11_MCS08                    0x84c
+#define        RTXAGC_B_MCS15_MCS12                    0x868
+#define        RTXAGC_B_CCK11_A_CCK2_11                0x86c
+
+/* RL6052 Register definition */
+#define        RF_AC                                   0x00
+
+#define        RF_IQADJ_G1                             0x01
+#define        RF_IQADJ_G2                             0x02
+#define        RF_POW_TRSW                             0x05
+
+#define        RF_GAIN_RX                              0x06
+#define        RF_GAIN_TX                              0x07
+
+#define        RF_TXM_IDAC                             0x08
+#define        RF_BS_IQGEN                             0x0F
+
+#define        RF_MODE1                                0x10
+#define        RF_MODE2                                0x11
+
+#define        RF_RX_AGC_HP                            0x12
+#define        RF_TX_AGC                               0x13
+#define        RF_BIAS                                 0x14
+#define        RF_IPA                                  0x15
+#define        RF_POW_ABILITY                          0x17
+#define        RF_MODE_AG                              0x18
+#define        rRfChannel                              0x18
+#define        RF_CHNLBW                               0x18
+#define        RF_TOP                                  0x19
+
+#define        RF_RX_G1                                0x1A
+#define        RF_RX_G2                                0x1B
+
+#define        RF_RX_BB2                               0x1C
+#define        RF_RX_BB1                               0x1D
+
+#define        RF_RCK1                                 0x1E
+#define        RF_RCK2                                 0x1F
+
+#define        RF_TX_G1                                0x20
+#define        RF_TX_G2                                0x21
+#define        RF_TX_G3                                0x22
+
+#define        RF_TX_BB1                               0x23
+
+#define        RF_T_METER                              0x42
+
+#define        RF_SYN_G1                               0x25
+#define        RF_SYN_G2                               0x26
+#define        RF_SYN_G3                               0x27
+#define        RF_SYN_G4                               0x28
+#define        RF_SYN_G5                               0x29
+#define        RF_SYN_G6                               0x2A
+#define        RF_SYN_G7                               0x2B
+#define        RF_SYN_G8                               0x2C
+
+#define        RF_RCK_OS                               0x30
+
+#define        RF_TXPA_G1                              0x31
+#define        RF_TXPA_G2                              0x32
+#define        RF_TXPA_G3                              0x33
+
+/* Bit Mask */
+
+/* 2. Page8(0x800) */
+#define        BRFMOD                                  0x1
+#define        BCCKTXSC                                0x30
+#define        BCCKEN                                  0x1000000
+#define        BOFDMEN                                 0x2000000
+
+#define        B3WIREDATALENGTH                        0x800
+#define        B3WIREADDRESSLENGTH                     0x400
+
+#define        BRFSI_RFENV                             0x10
+
+#define        BLSSIREADADDRESS                        0x7f800000
+#define        BLSSIREADEDGE                           0x80000000
+#define        BLSSIREADBACKDATA                       0xfffff
+/* 4. PageA(0xA00) */
+#define BCCKSIDEBAND                           0x10
+
+/* Other Definition */
+#define        BBYTE0                                  0x1
+#define        BBYTE1                                  0x2
+#define        BBYTE2                                  0x4
+#define        BBYTE3                                  0x8
+#define        BWORD0                                  0x3
+#define        BWORD1                                  0xc
+#define        BDWORD                                  0xf
+
+#define        BMASKBYTE0                              0xff
+#define        BMASKBYTE1                              0xff00
+#define        BMASKBYTE2                              0xff0000
+#define        BMASKBYTE3                              0xff000000
+#define        BMASKHWORD                              0xffff0000
+#define        BMASKLWORD                              0x0000ffff
+#define        BMASKDWORD                              0xffffffff
+#define        BMASK12BITS                             0xfff
+#define        BMASKH4BITS                             0xf0000000
+#define BMASKOFDM_D                            0xffc00000
+#define        BMASKCCK                                0x3f3f3f3f
+
+#define BRFREGOFFSETMASK                       0xfffff
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c
new file mode 100644 (file)
index 0000000..c326372
--- /dev/null
@@ -0,0 +1,628 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "rf.h"
+#include "dm.h"
+#include "hw.h"
+
+void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 rfpath;
+
+       switch (bandwidth) {
+       case HT_CHANNEL_WIDTH_20:
+               for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
+                       rtlphy->rfreg_chnlval[rfpath] = ((rtlphy->rfreg_chnlval
+                                       [rfpath] & 0xfffff3ff) | 0x0400);
+                       rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) |
+                                     BIT(11), 0x01);
+
+                       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
+                                ("20M RF 0x18 = 0x%x\n",
+                                rtlphy->rfreg_chnlval[rfpath]));
+               }
+
+               break;
+       case HT_CHANNEL_WIDTH_20_40:
+               for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
+                       rtlphy->rfreg_chnlval[rfpath] =
+                           ((rtlphy->rfreg_chnlval[rfpath] & 0xfffff3ff));
+                       rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) | BIT(11),
+                                     0x00);
+                       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
+                                ("40M RF 0x18 = 0x%x\n",
+                                rtlphy->rfreg_chnlval[rfpath]));
+               }
+               break;
+       default:
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("unknown bandwidth: %#X\n", bandwidth));
+               break;
+       }
+}
+
+void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
+                                      u8 *ppowerlevel)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u32 tx_agc[2] = {0, 0}, tmpval;
+       bool turbo_scanoff = false;
+       u8 idx1, idx2;
+       u8 *ptr;
+
+       if (rtlefuse->eeprom_regulatory != 0)
+               turbo_scanoff = true;
+       if (mac->act_scanning == true) {
+               tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
+               tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
+               if (turbo_scanoff) {
+                       for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
+                               tx_agc[idx1] = ppowerlevel[idx1] |
+                                   (ppowerlevel[idx1] << 8) |
+                                   (ppowerlevel[idx1] << 16) |
+                                   (ppowerlevel[idx1] << 24);
+                       }
+               }
+       } else {
+               for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
+                       tx_agc[idx1] = ppowerlevel[idx1] |
+                           (ppowerlevel[idx1] << 8) |
+                           (ppowerlevel[idx1] << 16) |
+                           (ppowerlevel[idx1] << 24);
+               }
+               if (rtlefuse->eeprom_regulatory == 0) {
+                       tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][6]) +
+                           (rtlphy->mcs_txpwrlevel_origoffset[0][7] << 8);
+                       tx_agc[RF90_PATH_A] += tmpval;
+                       tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) +
+                           (rtlphy->mcs_txpwrlevel_origoffset[0][15] << 24);
+                       tx_agc[RF90_PATH_B] += tmpval;
+               }
+       }
+
+       for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
+               ptr = (u8 *) (&(tx_agc[idx1]));
+               for (idx2 = 0; idx2 < 4; idx2++) {
+                       if (*ptr > RF6052_MAX_TX_PWR)
+                               *ptr = RF6052_MAX_TX_PWR;
+                       ptr++;
+               }
+       }
+
+       tmpval = tx_agc[RF90_PATH_A] & 0xff;
+       rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, BMASKBYTE1, tmpval);
+       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+               ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
+               RTXAGC_A_CCK1_MCS32));
+       tmpval = tx_agc[RF90_PATH_A] >> 8;
+       rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
+       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+               ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
+               RTXAGC_B_CCK11_A_CCK2_11));
+       tmpval = tx_agc[RF90_PATH_B] >> 24;
+       rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, BMASKBYTE0, tmpval);
+       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+               ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
+               RTXAGC_B_CCK11_A_CCK2_11));
+       tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
+       rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
+       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+               ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
+               RTXAGC_B_CCK1_55_MCS32));
+}
+
+static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw,
+                                      u8 *ppowerlevel, u8 channel,
+                                      u32 *ofdmbase, u32 *mcsbase)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u32 powerbase0, powerbase1;
+       u8 legacy_pwrdiff, ht20_pwrdiff;
+       u8 i, powerlevel[2];
+
+       for (i = 0; i < 2; i++) {
+               powerlevel[i] = ppowerlevel[i];
+               legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
+               powerbase0 = powerlevel[i] + legacy_pwrdiff;
+               powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) |
+                   (powerbase0 << 8) | powerbase0;
+               *(ofdmbase + i) = powerbase0;
+               RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                       (" [OFDM power base index rf(%c) = 0x%x]\n",
+                       ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)));
+       }
+
+       for (i = 0; i < 2; i++) {
+               if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
+                       ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1];
+                       powerlevel[i] += ht20_pwrdiff;
+               }
+               powerbase1 = powerlevel[i];
+               powerbase1 = (powerbase1 << 24) | (powerbase1 << 16) |
+                            (powerbase1 << 8) | powerbase1;
+               *(mcsbase + i) = powerbase1;
+               RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                       (" [MCS power base index rf(%c) = 0x%x]\n",
+                       ((i == 0) ? 'A' : 'B'), *(mcsbase + i)));
+       }
+}
+
+static u8 _rtl92d_phy_get_chnlgroup_bypg(u8 chnlindex)
+{
+       u8 group;
+       u8 channel_info[59] = {
+               1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+               36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
+               60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
+               114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
+               134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
+               161, 163, 165
+       };
+
+       if (channel_info[chnlindex] <= 3)       /* Chanel 1-3 */
+               group = 0;
+       else if (channel_info[chnlindex] <= 9)  /* Channel 4-9 */
+               group = 1;
+       else if (channel_info[chnlindex] <= 14) /* Channel 10-14 */
+               group = 2;
+       else if (channel_info[chnlindex] <= 64)
+               group = 6;
+       else if (channel_info[chnlindex] <= 140)
+               group = 7;
+       else
+               group = 8;
+       return group;
+}
+
+static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
+                                                      u8 channel, u8 index,
+                                                      u32 *powerbase0,
+                                                      u32 *powerbase1,
+                                                      u32 *p_outwriteval)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       u8 i, chnlgroup = 0, pwr_diff_limit[4];
+       u32 writeval = 0, customer_limit, rf;
+
+       for (rf = 0; rf < 2; rf++) {
+               switch (rtlefuse->eeprom_regulatory) {
+               case 0:
+                       chnlgroup = 0;
+                       writeval = rtlphy->mcs_txpwrlevel_origoffset
+                                       [chnlgroup][index +
+                                       (rf ? 8 : 0)] + ((index < 2) ?
+                                       powerbase0[rf] :
+                                       powerbase1[rf]);
+                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better "
+                               "performance, writeval(%c) = 0x%x\n",
+                               ((rf == 0) ? 'A' : 'B'), writeval));
+                       break;
+               case 1:
+                       if (rtlphy->pwrgroup_cnt == 1)
+                               chnlgroup = 0;
+                       if (rtlphy->pwrgroup_cnt >= MAX_PG_GROUP) {
+                               chnlgroup = _rtl92d_phy_get_chnlgroup_bypg(
+                                                               channel - 1);
+                               if (rtlphy->current_chan_bw ==
+                                   HT_CHANNEL_WIDTH_20)
+                                       chnlgroup++;
+                               else
+                                       chnlgroup += 4;
+                               writeval = rtlphy->mcs_txpwrlevel_origoffset
+                                               [chnlgroup][index +
+                                               (rf ? 8 : 0)] + ((index < 2) ?
+                                               powerbase0[rf] :
+                                               powerbase1[rf]);
+                               RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                                       ("Realtek regulatory, "
+                                       "20MHz, writeval(%c) = 0x%x\n",
+                                       ((rf == 0) ? 'A' : 'B'),
+                                       writeval));
+                       }
+                       break;
+               case 2:
+                       writeval = ((index < 2) ? powerbase0[rf] :
+                                  powerbase1[rf]);
+                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("Better regulatory, "
+                               "writeval(%c) = 0x%x\n",
+                               ((rf == 0) ? 'A' : 'B'), writeval));
+                       break;
+               case 3:
+                       chnlgroup = 0;
+                       if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+                               RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                                       ("customer's limit, 40MHz rf(%c) = "
+                                       "0x%x\n", ((rf == 0) ? 'A' : 'B'),
+                                       rtlefuse->pwrgroup_ht40[rf]
+                                       [channel - 1]));
+                       } else {
+                               RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                                       ("customer's limit, 20MHz rf(%c) = "
+                                       "0x%x\n", ((rf == 0) ? 'A' : 'B'),
+                                       rtlefuse->pwrgroup_ht20[rf]
+                                       [channel - 1]));
+                       }
+                       for (i = 0; i < 4; i++) {
+                               pwr_diff_limit[i] =
+                                       (u8)((rtlphy->mcs_txpwrlevel_origoffset
+                                       [chnlgroup][index + (rf ? 8 : 0)] &
+                                       (0x7f << (i * 8))) >> (i * 8));
+                               if (rtlphy->current_chan_bw ==
+                                   HT_CHANNEL_WIDTH_20_40) {
+                                       if (pwr_diff_limit[i] >
+                                           rtlefuse->pwrgroup_ht40[rf]
+                                          [channel - 1])
+                                               pwr_diff_limit[i] =
+                                                       rtlefuse->pwrgroup_ht40
+                                                       [rf][channel - 1];
+                               } else {
+                                       if (pwr_diff_limit[i] >
+                                           rtlefuse->pwrgroup_ht20[rf][
+                                               channel - 1])
+                                               pwr_diff_limit[i] =
+                                                  rtlefuse->pwrgroup_ht20[rf]
+                                                  [channel - 1];
+                               }
+                       }
+                       customer_limit = (pwr_diff_limit[3] << 24) |
+                                        (pwr_diff_limit[2] << 16) |
+                                        (pwr_diff_limit[1] << 8) |
+                                        (pwr_diff_limit[0]);
+                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                               ("Customer's limit rf(%c) = 0x%x\n",
+                               ((rf == 0) ? 'A' : 'B'), customer_limit));
+                       writeval = customer_limit + ((index < 2) ?
+                                  powerbase0[rf] : powerbase1[rf]);
+                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                               ("Customer, writeval rf(%c)= 0x%x\n",
+                               ((rf == 0) ? 'A' : 'B'), writeval));
+                       break;
+               default:
+                       chnlgroup = 0;
+                       writeval = rtlphy->mcs_txpwrlevel_origoffset
+                                  [chnlgroup][index +
+                                  (rf ? 8 : 0)] + ((index < 2) ?
+                                  powerbase0[rf] : powerbase1[rf]);
+                       RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                               ("RTK better performance, writeval "
+                               "rf(%c) = 0x%x\n",
+                               ((rf == 0) ? 'A' : 'B'), writeval));
+                       break;
+               }
+               *(p_outwriteval + rf) = writeval;
+       }
+}
+
+static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw,
+                                        u8 index, u32 *pvalue)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       static u16 regoffset_a[6] = {
+               RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
+               RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
+               RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
+       };
+       static u16 regoffset_b[6] = {
+               RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
+               RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
+               RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
+       };
+       u8 i, rf, pwr_val[4];
+       u32 writeval;
+       u16 regoffset;
+
+       for (rf = 0; rf < 2; rf++) {
+               writeval = pvalue[rf];
+               for (i = 0; i < 4; i++) {
+                       pwr_val[i] = (u8) ((writeval & (0x7f <<
+                                    (i * 8))) >> (i * 8));
+                       if (pwr_val[i] > RF6052_MAX_TX_PWR)
+                               pwr_val[i] = RF6052_MAX_TX_PWR;
+               }
+               writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
+                          (pwr_val[1] << 8) | pwr_val[0];
+               if (rf == 0)
+                       regoffset = regoffset_a[index];
+               else
+                       regoffset = regoffset_b[index];
+               rtl_set_bbreg(hw, regoffset, BMASKDWORD, writeval);
+               RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+                       ("Set 0x%x = %08x\n", regoffset, writeval));
+               if (((get_rf_type(rtlphy) == RF_2T2R) &&
+                   (regoffset == RTXAGC_A_MCS15_MCS12 ||
+                   regoffset == RTXAGC_B_MCS15_MCS12)) ||
+                   ((get_rf_type(rtlphy) != RF_2T2R) &&
+                   (regoffset == RTXAGC_A_MCS07_MCS04 ||
+                   regoffset == RTXAGC_B_MCS07_MCS04))) {
+                       writeval = pwr_val[3];
+                       if (regoffset == RTXAGC_A_MCS15_MCS12 ||
+                           regoffset == RTXAGC_A_MCS07_MCS04)
+                               regoffset = 0xc90;
+                       if (regoffset == RTXAGC_B_MCS15_MCS12 ||
+                           regoffset == RTXAGC_B_MCS07_MCS04)
+                               regoffset = 0xc98;
+                       for (i = 0; i < 3; i++) {
+                               if (i != 2)
+                                       writeval = (writeval > 8) ?
+                                                  (writeval - 8) : 0;
+                               else
+                                       writeval = (writeval > 6) ?
+                                                  (writeval - 6) : 0;
+                               rtl_write_byte(rtlpriv, (u32) (regoffset + i),
+                                              (u8) writeval);
+                       }
+               }
+       }
+}
+
+void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
+                                       u8 *ppowerlevel, u8 channel)
+{
+       u32 writeval[2], powerbase0[2], powerbase1[2];
+       u8 index;
+
+       _rtl92d_phy_get_power_base(hw, ppowerlevel, channel,
+                       &powerbase0[0], &powerbase1[0]);
+       for (index = 0; index < 6; index++) {
+               _rtl92d_get_txpower_writeval_by_regulatory(hw,
+                               channel, index, &powerbase0[0],
+                               &powerbase1[0], &writeval[0]);
+               _rtl92d_write_ofdm_power_reg(hw, index, &writeval[0]);
+       }
+}
+
+bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
+       u8 u1btmp;
+       u8 direct = bmac0 == true ? BIT(3) | BIT(2) : BIT(3);
+       u8 mac_reg = bmac0 == true ? REG_MAC1 : REG_MAC0;
+       u8 mac_on_bit = bmac0 == true ? MAC1_ON : MAC0_ON;
+       bool bresult = true; /* true: need to enable BB/RF power */
+
+       rtlhal->during_mac0init_radiob = false;
+       rtlhal->during_mac1init_radioa = false;
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("===>\n"));
+       /* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */
+       u1btmp = rtl_read_byte(rtlpriv, mac_reg);
+       if (!(u1btmp & mac_on_bit)) {
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable BB & RF\n"));
+               /* Enable BB and RF power */
+               rtl92de_write_dword_dbi(hw, REG_SYS_ISO_CTRL,
+                       rtl92de_read_dword_dbi(hw, REG_SYS_ISO_CTRL, direct) |
+                               BIT(29) | BIT(16) | BIT(17), direct);
+       } else {
+               /* We think if MAC1 is ON,then radio_a.txt
+                * and radio_b.txt has been load. */
+               bresult = false;
+       }
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<===\n"));
+       return bresult;
+
+}
+
+void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
+       u8 u1btmp;
+       u8 direct = bmac0 == true ? BIT(3) | BIT(2) : BIT(3);
+       u8 mac_reg = bmac0 == true ? REG_MAC1 : REG_MAC0;
+       u8 mac_on_bit = bmac0 == true ? MAC1_ON : MAC0_ON;
+
+       rtlhal->during_mac0init_radiob = false;
+       rtlhal->during_mac1init_radioa = false;
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n"));
+       /* check MAC0 enable or not again now, if
+        * enabled, not power down radio A. */
+       u1btmp = rtl_read_byte(rtlpriv, mac_reg);
+       if (!(u1btmp & mac_on_bit)) {
+               RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("power down\n"));
+               /* power down RF radio A according to YuNan's advice. */
+               rtl92de_write_dword_dbi(hw, RFPGA0_XA_LSSIPARAMETER,
+                                       0x00000000, direct);
+       }
+       RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n"));
+}
+
+bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       bool rtstatus = true;
+       struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
+       u32 u4_regvalue = 0;
+       u8 rfpath;
+       struct bb_reg_def *pphyreg;
+       bool mac1_initradioa_first = false, mac0_initradiob_first = false;
+       bool need_pwrdown_radioa = false, need_pwrdown_radiob = false;
+       bool true_bpath = false;
+
+       if (rtlphy->rf_type == RF_1T1R)
+               rtlphy->num_total_rfpath = 1;
+       else
+               rtlphy->num_total_rfpath = 2;
+
+       /* Single phy mode: use radio_a radio_b config path_A path_B */
+       /* seperately by MAC0, and MAC1 needn't configure RF; */
+       /* Dual PHY mode:MAC0 use radio_a config 1st phy path_A, */
+       /* MAC1 use radio_b config 2nd PHY path_A. */
+       /* DMDP,MAC0 on G band,MAC1 on A band. */
+       if (rtlhal->macphymode == DUALMAC_DUALPHY) {
+               if (rtlhal->current_bandtype == BAND_ON_2_4G &&
+                   rtlhal->interfaceindex == 0) {
+                       /* MAC0 needs PHY1 load radio_b.txt.
+                        * Driver use DBI to write. */
+                       if (rtl92d_phy_enable_anotherphy(hw, true)) {
+                               rtlphy->num_total_rfpath = 2;
+                               mac0_initradiob_first = true;
+                       } else {
+                               /* We think if MAC1 is ON,then radio_a.txt and
+                                * radio_b.txt has been load. */
+                               return rtstatus;
+                       }
+               } else if (rtlhal->current_bandtype == BAND_ON_5G &&
+                          rtlhal->interfaceindex == 1) {
+                       /* MAC1 needs PHY0 load radio_a.txt.
+                        * Driver use DBI to write. */
+                       if (rtl92d_phy_enable_anotherphy(hw, false)) {
+                               rtlphy->num_total_rfpath = 2;
+                               mac1_initradioa_first = true;
+                       } else {
+                               /* We think if MAC0 is ON,then radio_a.txt and
+                                * radio_b.txt has been load. */
+                               return rtstatus;
+                       }
+               } else if (rtlhal->interfaceindex == 1) {
+                       /* MAC0 enabled, only init radia B.   */
+                       true_bpath = true;
+               }
+       }
+
+       for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
+               /* Mac1 use PHY0 write */
+               if (mac1_initradioa_first) {
+                       if (rfpath == RF90_PATH_A) {
+                               rtlhal->during_mac1init_radioa = true;
+                               need_pwrdown_radioa = true;
+                       } else if (rfpath == RF90_PATH_B) {
+                               rtlhal->during_mac1init_radioa = false;
+                               mac1_initradioa_first = false;
+                               rfpath = RF90_PATH_A;
+                               true_bpath = true;
+                               rtlphy->num_total_rfpath = 1;
+                       }
+               } else if (mac0_initradiob_first) {
+                       /* Mac0 use PHY1 write */
+                       if (rfpath == RF90_PATH_A)
+                               rtlhal->during_mac0init_radiob = false;
+                       if (rfpath == RF90_PATH_B) {
+                               rtlhal->during_mac0init_radiob = true;
+                               mac0_initradiob_first = false;
+                               need_pwrdown_radiob = true;
+                               rfpath = RF90_PATH_A;
+                               true_bpath = true;
+                               rtlphy->num_total_rfpath = 1;
+                       }
+               }
+               pphyreg = &rtlphy->phyreg_def[rfpath];
+               switch (rfpath) {
+               case RF90_PATH_A:
+               case RF90_PATH_C:
+                       u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
+                                                   BRFSI_RFENV);
+                       break;
+               case RF90_PATH_B:
+               case RF90_PATH_D:
+                       u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
+                               BRFSI_RFENV << 16);
+                       break;
+               }
+               rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
+               udelay(1);
+               rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
+               udelay(1);
+               /* Set bit number of Address and Data for RF register */
+               /* Set 1 to 4 bits for 8255 */
+               rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
+                             B3WIREADDRESSLENGTH, 0x0);
+               udelay(1);
+               /* Set 0 to 12  bits for 8255 */
+               rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
+               udelay(1);
+               switch (rfpath) {
+               case RF90_PATH_A:
+                       if (true_bpath == true)
+                               rtstatus = rtl92d_phy_config_rf_with_headerfile(
+                                               hw, radiob_txt,
+                                               (enum radio_path)rfpath);
+                       else
+                               rtstatus = rtl92d_phy_config_rf_with_headerfile(
+                                            hw, radioa_txt,
+                                            (enum radio_path)rfpath);
+                       break;
+               case RF90_PATH_B:
+                       rtstatus =
+                           rtl92d_phy_config_rf_with_headerfile(hw, radiob_txt,
+                                               (enum radio_path) rfpath);
+                       break;
+               case RF90_PATH_C:
+                       break;
+               case RF90_PATH_D:
+                       break;
+               }
+               switch (rfpath) {
+               case RF90_PATH_A:
+               case RF90_PATH_C:
+                       rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV,
+                                     u4_regvalue);
+                       break;
+               case RF90_PATH_B:
+               case RF90_PATH_D:
+                       rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16,
+                                     u4_regvalue);
+                       break;
+               }
+               if (rtstatus != true) {
+                       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+                               ("Radio[%d] Fail!!", rfpath));
+                       goto phy_rf_cfg_fail;
+               }
+
+       }
+
+       /* check MAC0 enable or not again, if enabled,
+        * not power down radio A. */
+       /* check MAC1 enable or not again, if enabled,
+        * not power down radio B. */
+       if (need_pwrdown_radioa)
+               rtl92d_phy_powerdown_anotherphy(hw, false);
+       else if (need_pwrdown_radiob)
+               rtl92d_phy_powerdown_anotherphy(hw, true);
+       RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n"));
+       return rtstatus;
+
+phy_rf_cfg_fail:
+       return rtstatus;
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h
new file mode 100644 (file)
index 0000000..74b9cfc
--- /dev/null
@@ -0,0 +1,44 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92D_RF_H__
+#define __RTL92D_RF_H__
+
+extern void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
+                                           u8 bandwidth);
+extern void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
+                                             u8 *ppowerlevel);
+extern void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
+                                              u8 *ppowerlevel, u8 channel);
+extern bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw);
+extern bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0);
+extern void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw,
+                                           bool bmac0);
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
new file mode 100644 (file)
index 0000000..0883774
--- /dev/null
@@ -0,0 +1,423 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include <linux/vmalloc.h>
+
+#include "../wifi.h"
+#include "../core.h"
+#include "../pci.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "hw.h"
+#include "sw.h"
+#include "trx.h"
+#include "led.h"
+
+static void rtl92d_init_aspm_vars(struct ieee80211_hw *hw)
+{
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+       /*close ASPM for AMD defaultly */
+       rtlpci->const_amdpci_aspm = 0;
+
+       /*
+        * ASPM PS mode.
+        * 0 - Disable ASPM,
+        * 1 - Enable ASPM without Clock Req,
+        * 2 - Enable ASPM with Clock Req,
+        * 3 - Alwyas Enable ASPM with Clock Req,
+        * 4 - Always Enable ASPM without Clock Req.
+        * set defult to RTL8192CE:3 RTL8192E:2
+        * */
+       rtlpci->const_pci_aspm = 3;
+
+       /*Setting for PCI-E device */
+       rtlpci->const_devicepci_aspm_setting = 0x03;
+
+       /*Setting for PCI-E bridge */
+       rtlpci->const_hostpci_aspm_setting = 0x02;
+
+       /*
+        * In Hw/Sw Radio Off situation.
+        * 0 - Default,
+        * 1 - From ASPM setting without low Mac Pwr,
+        * 2 - From ASPM setting with low Mac Pwr,
+        * 3 - Bus D3
+        * set default to RTL8192CE:0 RTL8192SE:2
+        */
+       rtlpci->const_hwsw_rfoff_d3 = 0;
+
+       /*
+        * This setting works for those device with
+        * backdoor ASPM setting such as EPHY setting.
+        * 0 - Not support ASPM,
+        * 1 - Support ASPM,
+        * 2 - According to chipset.
+        */
+       rtlpci->const_support_pciaspm = 1;
+}
+
+static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
+{
+       int err;
+       u8 tid;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       const struct firmware *firmware;
+       static int header_print;
+
+       rtlpriv->dm.dm_initialgain_enable = true;
+       rtlpriv->dm.dm_flag = 0;
+       rtlpriv->dm.disable_framebursting = 0;
+       rtlpriv->dm.thermalvalue = 0;
+       rtlpriv->dm.useramask = 1;
+
+       /* dual mac */
+       if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G)
+               rtlpriv->phy.current_channel = 36;
+       else
+               rtlpriv->phy.current_channel = 1;
+
+       if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) {
+               rtlpriv->rtlhal.disable_amsdu_8k = true;
+               /* No long RX - reduce fragmentation */
+               rtlpci->rxbuffersize = 4096;
+       }
+
+       rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13);
+
+       rtlpci->receive_config = (
+                       RCR_APPFCS
+                       | RCR_AMF
+                       | RCR_ADF
+                       | RCR_APP_MIC
+                       | RCR_APP_ICV
+                       | RCR_AICV
+                       | RCR_ACRC32
+                       | RCR_AB
+                       | RCR_AM
+                       | RCR_APM
+                       | RCR_APP_PHYST_RXFF
+                       | RCR_HTC_LOC_CTRL
+       );
+
+       rtlpci->irq_mask[0] = (u32) (
+                       IMR_ROK
+                       | IMR_VODOK
+                       | IMR_VIDOK
+                       | IMR_BEDOK
+                       | IMR_BKDOK
+                       | IMR_MGNTDOK
+                       | IMR_HIGHDOK
+                       | IMR_BDOK
+                       | IMR_RDU
+                       | IMR_RXFOVW
+       );
+
+       rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD);
+
+       /* for LPS & IPS */
+       rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
+       rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
+       rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
+       rtlpriv->psc.reg_fwctrl_lps = 3;
+       rtlpriv->psc.reg_max_lps_awakeintvl = 5;
+       /* for ASPM, you can close aspm through
+        * set const_support_pciaspm = 0 */
+       rtl92d_init_aspm_vars(hw);
+
+       if (rtlpriv->psc.reg_fwctrl_lps == 1)
+               rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
+       else if (rtlpriv->psc.reg_fwctrl_lps == 2)
+               rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
+       else if (rtlpriv->psc.reg_fwctrl_lps == 3)
+               rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
+
+       /* for firmware buf */
+       rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
+       if (!rtlpriv->rtlhal.pfirmware) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("Can't alloc buffer for fw.\n"));
+               return 1;
+       }
+
+       if (!header_print) {
+               printk(KERN_INFO "rtl8192de: Driver for Realtek RTL8192DE"
+                      " WLAN interface");
+               printk(KERN_INFO "rtl8192de: Loading firmware file %s\n",
+                      rtlpriv->cfg->fw_name);
+               header_print++;
+       }
+       /* request fw */
+       err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
+                              rtlpriv->io.dev);
+       if (err) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("Failed to request firmware!\n"));
+               return 1;
+       }
+       if (firmware->size > 0x8000) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("Firmware is too big!\n"));
+               release_firmware(firmware);
+               return 1;
+       }
+       memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
+       rtlpriv->rtlhal.fwsize = firmware->size;
+       release_firmware(firmware);
+
+       /* for early mode */
+       rtlpriv->rtlhal.earlymode_enable = true;
+       for (tid = 0; tid < 8; tid++)
+               skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
+       return 0;
+}
+
+static void rtl92d_deinit_sw_vars(struct ieee80211_hw *hw)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 tid;
+
+       if (rtlpriv->rtlhal.pfirmware) {
+               vfree(rtlpriv->rtlhal.pfirmware);
+               rtlpriv->rtlhal.pfirmware = NULL;
+       }
+       for (tid = 0; tid < 8; tid++)
+               skb_queue_purge(&rtlpriv->mac80211.skb_waitq[tid]);
+}
+
+static struct rtl_hal_ops rtl8192de_hal_ops = {
+       .init_sw_vars = rtl92d_init_sw_vars,
+       .deinit_sw_vars = rtl92d_deinit_sw_vars,
+       .read_eeprom_info = rtl92de_read_eeprom_info,
+       .interrupt_recognized = rtl92de_interrupt_recognized,
+       .hw_init = rtl92de_hw_init,
+       .hw_disable = rtl92de_card_disable,
+       .hw_suspend = rtl92de_suspend,
+       .hw_resume = rtl92de_resume,
+       .enable_interrupt = rtl92de_enable_interrupt,
+       .disable_interrupt = rtl92de_disable_interrupt,
+       .set_network_type = rtl92de_set_network_type,
+       .set_chk_bssid = rtl92de_set_check_bssid,
+       .set_qos = rtl92de_set_qos,
+       .set_bcn_reg = rtl92de_set_beacon_related_registers,
+       .set_bcn_intv = rtl92de_set_beacon_interval,
+       .update_interrupt_mask = rtl92de_update_interrupt_mask,
+       .get_hw_reg = rtl92de_get_hw_reg,
+       .set_hw_reg = rtl92de_set_hw_reg,
+       .update_rate_tbl = rtl92de_update_hal_rate_tbl,
+       .fill_tx_desc = rtl92de_tx_fill_desc,
+       .fill_tx_cmddesc = rtl92de_tx_fill_cmddesc,
+       .query_rx_desc = rtl92de_rx_query_desc,
+       .set_channel_access = rtl92de_update_channel_access_setting,
+       .radio_onoff_checking = rtl92de_gpio_radio_on_off_checking,
+       .set_bw_mode = rtl92d_phy_set_bw_mode,
+       .switch_channel = rtl92d_phy_sw_chnl,
+       .dm_watchdog = rtl92d_dm_watchdog,
+       .scan_operation_backup = rtl92d_phy_scan_operation_backup,
+       .set_rf_power_state = rtl92d_phy_set_rf_power_state,
+       .led_control = rtl92de_led_control,
+       .set_desc = rtl92de_set_desc,
+       .get_desc = rtl92de_get_desc,
+       .tx_polling = rtl92de_tx_polling,
+       .enable_hw_sec = rtl92de_enable_hw_security_config,
+       .set_key = rtl92de_set_key,
+       .init_sw_leds = rtl92de_init_sw_leds,
+       .get_bbreg = rtl92d_phy_query_bb_reg,
+       .set_bbreg = rtl92d_phy_set_bb_reg,
+       .get_rfreg = rtl92d_phy_query_rf_reg,
+       .set_rfreg = rtl92d_phy_set_rf_reg,
+       .linked_set_reg = rtl92d_linked_set_reg,
+};
+
+static struct rtl_mod_params rtl92de_mod_params = {
+       .sw_crypto = false,
+       .inactiveps = true,
+       .swctrl_lps = true,
+       .fwctrl_lps = false,
+};
+
+static struct rtl_hal_cfg rtl92de_hal_cfg = {
+       .bar_id = 2,
+       .write_readback = true,
+       .name = "rtl8192de",
+       .fw_name = "rtlwifi/rtl8192defw.bin",
+       .ops = &rtl8192de_hal_ops,
+       .mod_params = &rtl92de_mod_params,
+
+       .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
+       .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
+       .maps[SYS_CLK] = REG_SYS_CLKR,
+       .maps[MAC_RCR_AM] = RCR_AM,
+       .maps[MAC_RCR_AB] = RCR_AB,
+       .maps[MAC_RCR_ACRC32] = RCR_ACRC32,
+       .maps[MAC_RCR_ACF] = RCR_ACF,
+       .maps[MAC_RCR_AAP] = RCR_AAP,
+
+       .maps[EFUSE_TEST] = REG_EFUSE_TEST,
+       .maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
+       .maps[EFUSE_CLK] = 0,   /* just for 92se */
+       .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
+       .maps[EFUSE_PWC_EV12V] = PWC_EV12V,
+       .maps[EFUSE_FEN_ELDR] = FEN_ELDR,
+       .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
+       .maps[EFUSE_ANA8M] = 0, /* just for 92se */
+       .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
+       .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
+       .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
+
+       .maps[RWCAM] = REG_CAMCMD,
+       .maps[WCAMI] = REG_CAMWRITE,
+       .maps[RCAMO] = REG_CAMREAD,
+       .maps[CAMDBG] = REG_CAMDBG,
+       .maps[SECR] = REG_SECCFG,
+       .maps[SEC_CAM_NONE] = CAM_NONE,
+       .maps[SEC_CAM_WEP40] = CAM_WEP40,
+       .maps[SEC_CAM_TKIP] = CAM_TKIP,
+       .maps[SEC_CAM_AES] = CAM_AES,
+       .maps[SEC_CAM_WEP104] = CAM_WEP104,
+
+       .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
+       .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
+       .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
+       .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
+       .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
+       .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
+       .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,
+       .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
+       .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
+       .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
+       .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
+       .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
+       .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
+       .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
+       .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,
+       .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,
+
+       .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
+       .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
+       .maps[RTL_IMR_BcnInt] = IMR_BcnInt,
+       .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
+       .maps[RTL_IMR_RDU] = IMR_RDU,
+       .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
+       .maps[RTL_IMR_BDOK] = IMR_BDOK,
+       .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
+       .maps[RTL_IMR_TBDER] = IMR_TBDER,
+       .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
+       .maps[RTL_IMR_TBDOK] = IMR_TBDOK,
+       .maps[RTL_IMR_BKDOK] = IMR_BKDOK,
+       .maps[RTL_IMR_BEDOK] = IMR_BEDOK,
+       .maps[RTL_IMR_VIDOK] = IMR_VIDOK,
+       .maps[RTL_IMR_VODOK] = IMR_VODOK,
+       .maps[RTL_IMR_ROK] = IMR_ROK,
+       .maps[RTL_IBSS_INT_MASKS] = (IMR_BcnInt | IMR_TBDOK | IMR_TBDER),
+
+       .maps[RTL_RC_CCK_RATE1M] = DESC92D_RATE1M,
+       .maps[RTL_RC_CCK_RATE2M] = DESC92D_RATE2M,
+       .maps[RTL_RC_CCK_RATE5_5M] = DESC92D_RATE5_5M,
+       .maps[RTL_RC_CCK_RATE11M] = DESC92D_RATE11M,
+       .maps[RTL_RC_OFDM_RATE6M] = DESC92D_RATE6M,
+       .maps[RTL_RC_OFDM_RATE9M] = DESC92D_RATE9M,
+       .maps[RTL_RC_OFDM_RATE12M] = DESC92D_RATE12M,
+       .maps[RTL_RC_OFDM_RATE18M] = DESC92D_RATE18M,
+       .maps[RTL_RC_OFDM_RATE24M] = DESC92D_RATE24M,
+       .maps[RTL_RC_OFDM_RATE36M] = DESC92D_RATE36M,
+       .maps[RTL_RC_OFDM_RATE48M] = DESC92D_RATE48M,
+       .maps[RTL_RC_OFDM_RATE54M] = DESC92D_RATE54M,
+
+       .maps[RTL_RC_HT_RATEMCS7] = DESC92D_RATEMCS7,
+       .maps[RTL_RC_HT_RATEMCS15] = DESC92D_RATEMCS15,
+};
+
+static struct pci_device_id rtl92de_pci_ids[] __devinitdata = {
+       {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8193, rtl92de_hal_cfg)},
+       {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x002B, rtl92de_hal_cfg)},
+       {},
+};
+
+MODULE_DEVICE_TABLE(pci, rtl92de_pci_ids);
+
+MODULE_AUTHOR("lizhaoming      <chaoming_li@realsil.com.cn>");
+MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
+MODULE_AUTHOR("Larry Finger    <Larry.Finger@lwfinger.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek 8192DE 802.11n Dual Mac PCI wireless");
+MODULE_FIRMWARE("rtlwifi/rtl8192defw.bin");
+
+module_param_named(swenc, rtl92de_mod_params.sw_crypto, bool, 0444);
+module_param_named(ips, rtl92de_mod_params.inactiveps, bool, 0444);
+module_param_named(swlps, rtl92de_mod_params.swctrl_lps, bool, 0444);
+module_param_named(fwlps, rtl92de_mod_params.fwctrl_lps, bool, 0444);
+MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n");
+MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n");
+MODULE_PARM_DESC(swlps, "using linked sw control power save (default 1"
+                " is open)\n");
+
+static struct pci_driver rtl92de_driver = {
+       .name = KBUILD_MODNAME,
+       .id_table = rtl92de_pci_ids,
+       .probe = rtl_pci_probe,
+       .remove = rtl_pci_disconnect,
+
+#ifdef CONFIG_PM
+       .suspend = rtl_pci_suspend,
+       .resume = rtl_pci_resume,
+#endif
+
+};
+
+/* add global spin lock to solve the problem that
+ * Dul mac register operation on the same time */
+spinlock_t globalmutex_power;
+spinlock_t globalmutex_for_fwdownload;
+spinlock_t globalmutex_for_power_and_efuse;
+
+static int __init rtl92de_module_init(void)
+{
+       int ret = 0;
+
+       spin_lock_init(&globalmutex_power);
+       spin_lock_init(&globalmutex_for_fwdownload);
+       spin_lock_init(&globalmutex_for_power_and_efuse);
+
+       ret = pci_register_driver(&rtl92de_driver);
+       if (ret)
+               RT_ASSERT(false, (": No device found\n"));
+       return ret;
+}
+
+static void __exit rtl92de_module_exit(void)
+{
+       pci_unregister_driver(&rtl92de_driver);
+}
+
+module_init(rtl92de_module_init);
+module_exit(rtl92de_module_exit);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.h b/drivers/net/wireless/rtlwifi/rtl8192de/sw.h
new file mode 100644 (file)
index 0000000..c95e47d
--- /dev/null
@@ -0,0 +1,37 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92DE_SW_H__
+#define __RTL92DE_SW_H__
+
+extern spinlock_t globalmutex_power;
+extern spinlock_t globalmutex_for_fwdownload;
+extern spinlock_t globalmutex_for_power_and_efuse;
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/table.c b/drivers/net/wireless/rtlwifi/rtl8192de/table.c
new file mode 100644 (file)
index 0000000..bad7f94
--- /dev/null
@@ -0,0 +1,1690 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ * Created on  2010/12/23,  6:38
+ *****************************************************************************/
+
+#include <linux/types.h>
+
+#include "table.h"
+
+u32 rtl8192de_phy_reg_2tarray[PHY_REG_2T_ARRAYLENGTH] = {
+       0x024, 0x0011800d,
+       0x028, 0x00ffdb83,
+       0x014, 0x088ba955,
+       0x010, 0x49022b03,
+       0x800, 0x80040002,
+       0x804, 0x00000003,
+       0x808, 0x0000fc00,
+       0x80c, 0x0000000a,
+       0x810, 0x80706388,
+       0x814, 0x020c3d10,
+       0x818, 0x02200385,
+       0x81c, 0x00000000,
+       0x820, 0x01000100,
+       0x824, 0x00390004,
+       0x828, 0x01000100,
+       0x82c, 0x00390004,
+       0x830, 0x27272727,
+       0x834, 0x27272727,
+       0x838, 0x27272727,
+       0x83c, 0x27272727,
+       0x840, 0x00010000,
+       0x844, 0x00010000,
+       0x848, 0x27272727,
+       0x84c, 0x27272727,
+       0x850, 0x00000000,
+       0x854, 0x00000000,
+       0x858, 0x569a569a,
+       0x85c, 0x0c1b25a4,
+       0x860, 0x66e60230,
+       0x864, 0x061f0130,
+       0x868, 0x27272727,
+       0x86c, 0x272b2b2b,
+       0x870, 0x07000700,
+       0x874, 0x22188000,
+       0x878, 0x08080808,
+       0x87c, 0x00007ff8,
+       0x880, 0xc0083070,
+       0x884, 0x00000cd5,
+       0x888, 0x00000000,
+       0x88c, 0xcc0000c0,
+       0x890, 0x00000800,
+       0x894, 0xfffffffe,
+       0x898, 0x40302010,
+       0x89c, 0x00706050,
+       0x900, 0x00000000,
+       0x904, 0x00000023,
+       0x908, 0x00000000,
+       0x90c, 0x81121313,
+       0xa00, 0x00d047c8,
+       0xa04, 0x80ff000c,
+       0xa08, 0x8c838300,
+       0xa0c, 0x2e68120f,
+       0xa10, 0x9500bb78,
+       0xa14, 0x11144028,
+       0xa18, 0x00881117,
+       0xa1c, 0x89140f00,
+       0xa20, 0x1a1b0000,
+       0xa24, 0x090e1317,
+       0xa28, 0x00000204,
+       0xa2c, 0x00d30000,
+       0xa70, 0x101fbf00,
+       0xa74, 0x00000007,
+       0xc00, 0x40071d40,
+       0xc04, 0x03a05633,
+       0xc08, 0x001000e4,
+       0xc0c, 0x6c6c6c6c,
+       0xc10, 0x08800000,
+       0xc14, 0x40000100,
+       0xc18, 0x08800000,
+       0xc1c, 0x40000100,
+       0xc20, 0x00000000,
+       0xc24, 0x00000000,
+       0xc28, 0x00000000,
+       0xc2c, 0x00000000,
+       0xc30, 0x69e9ac44,
+       0xc34, 0x469652cf,
+       0xc38, 0x49795994,
+       0xc3c, 0x0a979718,
+       0xc40, 0x1f7c403f,
+       0xc44, 0x000100b7,
+       0xc48, 0xec020107,
+       0xc4c, 0x007f037f,
+       0xc50, 0x69543420,
+       0xc54, 0x43bc009e,
+       0xc58, 0x69543420,
+       0xc5c, 0x433c00a8,
+       0xc60, 0x00000000,
+       0xc64, 0x5116848b,
+       0xc68, 0x47c00bff,
+       0xc6c, 0x00000036,
+       0xc70, 0x2c7f000d,
+       0xc74, 0x058610db,
+       0xc78, 0x0000001f,
+       0xc7c, 0x40b95612,
+       0xc80, 0x40000100,
+       0xc84, 0x20f60000,
+       0xc88, 0x40000100,
+       0xc8c, 0x20e00000,
+       0xc90, 0x00121820,
+       0xc94, 0x00000007,
+       0xc98, 0x00121820,
+       0xc9c, 0x00007f7f,
+       0xca0, 0x00000000,
+       0xca4, 0x00000080,
+       0xca8, 0x00000000,
+       0xcac, 0x00000000,
+       0xcb0, 0x00000000,
+       0xcb4, 0x00000000,
+       0xcb8, 0x00000000,
+       0xcbc, 0x28000000,
+       0xcc0, 0x00000000,
+       0xcc4, 0x00000000,
+       0xcc8, 0x00000000,
+       0xccc, 0x00000000,
+       0xcd0, 0x00000000,
+       0xcd4, 0x00000000,
+       0xcd8, 0x64b11e20,
+       0xcdc, 0xe8767533,
+       0xce0, 0x00222222,
+       0xce4, 0x00000000,
+       0xce8, 0x37644302,
+       0xcec, 0x2f97d40c,
+       0xd00, 0x00080740,
+       0xd04, 0x00020403,
+       0xd08, 0x0000907f,
+       0xd0c, 0x20010201,
+       0xd10, 0xa0633333,
+       0xd14, 0x3333bc43,
+       0xd18, 0x7a8f5b6b,
+       0xd2c, 0xcc979975,
+       0xd30, 0x00000000,
+       0xd34, 0x80608404,
+       0xd38, 0x00000000,
+       0xd3c, 0x00027293,
+       0xd40, 0x00000000,
+       0xd44, 0x00000000,
+       0xd48, 0x00000000,
+       0xd4c, 0x00000000,
+       0xd50, 0x6437140a,
+       0xd54, 0x00000000,
+       0xd58, 0x00000000,
+       0xd5c, 0x30032064,
+       0xd60, 0x4653de68,
+       0xd64, 0x04518a3c,
+       0xd68, 0x00002101,
+       0xd6c, 0x2a201c16,
+       0xd70, 0x1812362e,
+       0xd74, 0x322c2220,
+       0xd78, 0x000e3c24,
+       0xe00, 0x2a2a2a2a,
+       0xe04, 0x2a2a2a2a,
+       0xe08, 0x03902a2a,
+       0xe10, 0x2a2a2a2a,
+       0xe14, 0x2a2a2a2a,
+       0xe18, 0x2a2a2a2a,
+       0xe1c, 0x2a2a2a2a,
+       0xe28, 0x00000000,
+       0xe30, 0x1000dc1f,
+       0xe34, 0x10008c1f,
+       0xe38, 0x02140102,
+       0xe3c, 0x681604c2,
+       0xe40, 0x01007c00,
+       0xe44, 0x01004800,
+       0xe48, 0xfb000000,
+       0xe4c, 0x000028d1,
+       0xe50, 0x1000dc1f,
+       0xe54, 0x10008c1f,
+       0xe58, 0x02140102,
+       0xe5c, 0x28160d05,
+       0xe60, 0x00000010,
+       0xe68, 0x001b25a4,
+       0xe6c, 0x63db25a4,
+       0xe70, 0x63db25a4,
+       0xe74, 0x0c126da4,
+       0xe78, 0x0c126da4,
+       0xe7c, 0x0c126da4,
+       0xe80, 0x0c126da4,
+       0xe84, 0x63db25a4,
+       0xe88, 0x0c126da4,
+       0xe8c, 0x63db25a4,
+       0xed0, 0x63db25a4,
+       0xed4, 0x63db25a4,
+       0xed8, 0x63db25a4,
+       0xedc, 0x001b25a4,
+       0xee0, 0x001b25a4,
+       0xeec, 0x6fdb25a4,
+       0xf14, 0x00000003,
+       0xf1c, 0x00000064,
+       0xf4c, 0x00000004,
+       0xf00, 0x00000300,
+};
+
+u32 rtl8192de_phy_reg_array_pg[PHY_REG_ARRAY_PG_LENGTH] = {
+       0xe00, 0xffffffff, 0x07090c0c,
+       0xe04, 0xffffffff, 0x01020405,
+       0xe08, 0x0000ff00, 0x00000000,
+       0x86c, 0xffffff00, 0x00000000,
+       0xe10, 0xffffffff, 0x0b0c0c0e,
+       0xe14, 0xffffffff, 0x01030506,
+       0xe18, 0xffffffff, 0x0b0c0d0e,
+       0xe1c, 0xffffffff, 0x01030509,
+       0x830, 0xffffffff, 0x07090c0c,
+       0x834, 0xffffffff, 0x01020405,
+       0x838, 0xffffff00, 0x00000000,
+       0x86c, 0x000000ff, 0x00000000,
+       0x83c, 0xffffffff, 0x0b0c0c0e,
+       0x848, 0xffffffff, 0x01030506,
+       0x84c, 0xffffffff, 0x0b0c0d0e,
+       0x868, 0xffffffff, 0x01030509,
+       0xe00, 0xffffffff, 0x00000000,
+       0xe04, 0xffffffff, 0x00000000,
+       0xe08, 0x0000ff00, 0x00000000,
+       0x86c, 0xffffff00, 0x00000000,
+       0xe10, 0xffffffff, 0x00000000,
+       0xe14, 0xffffffff, 0x00000000,
+       0xe18, 0xffffffff, 0x00000000,
+       0xe1c, 0xffffffff, 0x00000000,
+       0x830, 0xffffffff, 0x00000000,
+       0x834, 0xffffffff, 0x00000000,
+       0x838, 0xffffff00, 0x00000000,
+       0x86c, 0x000000ff, 0x00000000,
+       0x83c, 0xffffffff, 0x00000000,
+       0x848, 0xffffffff, 0x00000000,
+       0x84c, 0xffffffff, 0x00000000,
+       0x868, 0xffffffff, 0x00000000,
+       0xe00, 0xffffffff, 0x04040404,
+       0xe04, 0xffffffff, 0x00020204,
+       0xe08, 0x0000ff00, 0x00000000,
+       0x86c, 0xffffff00, 0x00000000,
+       0xe10, 0xffffffff, 0x06060606,
+       0xe14, 0xffffffff, 0x00020406,
+       0xe18, 0xffffffff, 0x00000000,
+       0xe1c, 0xffffffff, 0x00000000,
+       0x830, 0xffffffff, 0x04040404,
+       0x834, 0xffffffff, 0x00020204,
+       0x838, 0xffffff00, 0x00000000,
+       0x86c, 0x000000ff, 0x00000000,
+       0x83c, 0xffffffff, 0x06060606,
+       0x848, 0xffffffff, 0x00020406,
+       0x84c, 0xffffffff, 0x00000000,
+       0x868, 0xffffffff, 0x00000000,
+       0xe00, 0xffffffff, 0x00000000,
+       0xe04, 0xffffffff, 0x00000000,
+       0xe08, 0x0000ff00, 0x00000000,
+       0x86c, 0xffffff00, 0x00000000,
+       0xe10, 0xffffffff, 0x00000000,
+       0xe14, 0xffffffff, 0x00000000,
+       0xe18, 0xffffffff, 0x00000000,
+       0xe1c, 0xffffffff, 0x00000000,
+       0x830, 0xffffffff, 0x00000000,
+       0x834, 0xffffffff, 0x00000000,
+       0x838, 0xffffff00, 0x00000000,
+       0x86c, 0x000000ff, 0x00000000,
+       0x83c, 0xffffffff, 0x00000000,
+       0x848, 0xffffffff, 0x00000000,
+       0x84c, 0xffffffff, 0x00000000,
+       0x868, 0xffffffff, 0x00000000,
+       0xe00, 0xffffffff, 0x00000000,
+       0xe04, 0xffffffff, 0x00000000,
+       0xe08, 0x0000ff00, 0x00000000,
+       0x86c, 0xffffff00, 0x00000000,
+       0xe10, 0xffffffff, 0x00000000,
+       0xe14, 0xffffffff, 0x00000000,
+       0xe18, 0xffffffff, 0x00000000,
+       0xe1c, 0xffffffff, 0x00000000,
+       0x830, 0xffffffff, 0x00000000,
+       0x834, 0xffffffff, 0x00000000,
+       0x838, 0xffffff00, 0x00000000,
+       0x86c, 0x000000ff, 0x00000000,
+       0x83c, 0xffffffff, 0x00000000,
+       0x848, 0xffffffff, 0x00000000,
+       0x84c, 0xffffffff, 0x00000000,
+       0x868, 0xffffffff, 0x00000000,
+       0xe00, 0xffffffff, 0x04040404,
+       0xe04, 0xffffffff, 0x00020204,
+       0xe08, 0x0000ff00, 0x00000000,
+       0x86c, 0xffffff00, 0x00000000,
+       0xe10, 0xffffffff, 0x00000000,
+       0xe14, 0xffffffff, 0x00000000,
+       0xe18, 0xffffffff, 0x00000000,
+       0xe1c, 0xffffffff, 0x00000000,
+       0x830, 0xffffffff, 0x04040404,
+       0x834, 0xffffffff, 0x00020204,
+       0x838, 0xffffff00, 0x00000000,
+       0x86c, 0x000000ff, 0x00000000,
+       0x83c, 0xffffffff, 0x00000000,
+       0x848, 0xffffffff, 0x00000000,
+       0x84c, 0xffffffff, 0x00000000,
+       0x868, 0xffffffff, 0x00000000,
+       0xe00, 0xffffffff, 0x00000000,
+       0xe04, 0xffffffff, 0x00000000,
+       0xe08, 0x0000ff00, 0x00000000,
+       0x86c, 0xffffff00, 0x00000000,
+       0xe10, 0xffffffff, 0x00000000,
+       0xe14, 0xffffffff, 0x00000000,
+       0xe18, 0xffffffff, 0x00000000,
+       0xe1c, 0xffffffff, 0x00000000,
+       0x830, 0xffffffff, 0x00000000,
+       0x834, 0xffffffff, 0x00000000,
+       0x838, 0xffffff00, 0x00000000,
+       0x86c, 0x000000ff, 0x00000000,
+       0x83c, 0xffffffff, 0x00000000,
+       0x848, 0xffffffff, 0x00000000,
+       0x84c, 0xffffffff, 0x00000000,
+       0x868, 0xffffffff, 0x00000000,
+       0xe00, 0xffffffff, 0x04040404,
+       0xe04, 0xffffffff, 0x00020204,
+       0xe08, 0x0000ff00, 0x00000000,
+       0x86c, 0xffffff00, 0x00000000,
+       0xe10, 0xffffffff, 0x08080808,
+       0xe14, 0xffffffff, 0x00040408,
+       0xe18, 0xffffffff, 0x00000000,
+       0xe1c, 0xffffffff, 0x00000000,
+       0x830, 0xffffffff, 0x04040404,
+       0x834, 0xffffffff, 0x00020204,
+       0x838, 0xffffff00, 0x00000000,
+       0x86c, 0x000000ff, 0x00000000,
+       0x83c, 0xffffffff, 0x08080808,
+       0x848, 0xffffffff, 0x00040408,
+       0x84c, 0xffffffff, 0x00000000,
+       0x868, 0xffffffff, 0x00000000,
+       0xe00, 0xffffffff, 0x04040404,
+       0xe04, 0xffffffff, 0x00020204,
+       0xe08, 0x0000ff00, 0x00000000,
+       0x86c, 0xffffff00, 0x00000000,
+       0xe10, 0xffffffff, 0x08080808,
+       0xe14, 0xffffffff, 0x00040408,
+       0xe18, 0xffffffff, 0x00000000,
+       0xe1c, 0xffffffff, 0x00000000,
+       0x830, 0xffffffff, 0x04040404,
+       0x834, 0xffffffff, 0x00020204,
+       0x838, 0xffffff00, 0x00000000,
+       0x86c, 0x000000ff, 0x00000000,
+       0x83c, 0xffffffff, 0x08080808,
+       0x848, 0xffffffff, 0x00040408,
+       0x84c, 0xffffffff, 0x00000000,
+       0x868, 0xffffffff, 0x00000000,
+       0xe00, 0xffffffff, 0x04040404,
+       0xe04, 0xffffffff, 0x00020204,
+       0xe08, 0x0000ff00, 0x00000000,
+       0x86c, 0xffffff00, 0x00000000,
+       0xe10, 0xffffffff, 0x08080808,
+       0xe14, 0xffffffff, 0x00040408,
+       0xe18, 0xffffffff, 0x00000000,
+       0xe1c, 0xffffffff, 0x00000000,
+       0x830, 0xffffffff, 0x04040404,
+       0x834, 0xffffffff, 0x00020204,
+       0x838, 0xffffff00, 0x00000000,
+       0x86c, 0x000000ff, 0x00000000,
+       0x83c, 0xffffffff, 0x08080808,
+       0x848, 0xffffffff, 0x00040408,
+       0x84c, 0xffffffff, 0x00000000,
+       0x868, 0xffffffff, 0x00000000,
+       0xe00, 0xffffffff, 0x04040404,
+       0xe04, 0xffffffff, 0x00020204,
+       0xe08, 0x0000ff00, 0x00000000,
+       0x86c, 0xffffff00, 0x00000000,
+       0xe10, 0xffffffff, 0x08080808,
+       0xe14, 0xffffffff, 0x00040408,
+       0xe18, 0xffffffff, 0x00000000,
+       0xe1c, 0xffffffff, 0x00000000,
+       0x830, 0xffffffff, 0x04040404,
+       0x834, 0xffffffff, 0x00020204,
+       0x838, 0xffffff00, 0x00000000,
+       0x86c, 0x000000ff, 0x00000000,
+       0x83c, 0xffffffff, 0x08080808,
+       0x848, 0xffffffff, 0x00040408,
+       0x84c, 0xffffffff, 0x00000000,
+       0x868, 0xffffffff, 0x00000000,
+       0xe00, 0xffffffff, 0x04040404,
+       0xe04, 0xffffffff, 0x00020204,
+       0xe08, 0x0000ff00, 0x00000000,
+       0x86c, 0xffffff00, 0x00000000,
+       0xe10, 0xffffffff, 0x08080808,
+       0xe14, 0xffffffff, 0x00040408,
+       0xe18, 0xffffffff, 0x00000000,
+       0xe1c, 0xffffffff, 0x00000000,
+       0x830, 0xffffffff, 0x04040404,
+       0x834, 0xffffffff, 0x00020204,
+       0x838, 0xffffff00, 0x00000000,
+       0x86c, 0x000000ff, 0x00000000,
+       0x83c, 0xffffffff, 0x08080808,
+       0x848, 0xffffffff, 0x00040408,
+       0x84c, 0xffffffff, 0x00000000,
+       0x868, 0xffffffff, 0x00000000,
+       0xe00, 0xffffffff, 0x04040404,
+       0xe04, 0xffffffff, 0x00020204,
+       0xe08, 0x0000ff00, 0x00000000,
+       0x86c, 0xffffff00, 0x00000000,
+       0xe10, 0xffffffff, 0x08080808,
+       0xe14, 0xffffffff, 0x00040408,
+       0xe18, 0xffffffff, 0x00000000,
+       0xe1c, 0xffffffff, 0x00000000,
+       0x830, 0xffffffff, 0x04040404,
+       0x834, 0xffffffff, 0x00020204,
+       0x838, 0xffffff00, 0x00000000,
+       0x86c, 0x000000ff, 0x00000000,
+       0x83c, 0xffffffff, 0x08080808,
+       0x848, 0xffffffff, 0x00040408,
+       0x84c, 0xffffffff, 0x00000000,
+       0x868, 0xffffffff, 0x00000000,
+};
+
+u32 rtl8192de_radioa_2tarray[RADIOA_2T_ARRAYLENGTH] = {
+       0x000, 0x00030000,
+       0x001, 0x00030000,
+       0x002, 0x00000000,
+       0x003, 0x00018c63,
+       0x004, 0x00018c63,
+       0x008, 0x00084000,
+       0x00b, 0x0001c000,
+       0x00e, 0x00018c67,
+       0x00f, 0x00000851,
+       0x014, 0x00021440,
+       0x018, 0x00017524,
+       0x019, 0x00000000,
+       0x01d, 0x000a1290,
+       0x023, 0x00001558,
+       0x01a, 0x00030a99,
+       0x01b, 0x00040b00,
+       0x01c, 0x000fc339,
+       0x03a, 0x000a57eb,
+       0x03b, 0x00020000,
+       0x03c, 0x000ff454,
+       0x020, 0x0000aa52,
+       0x021, 0x00054000,
+       0x040, 0x0000aa52,
+       0x041, 0x00014000,
+       0x025, 0x000803be,
+       0x026, 0x000fc638,
+       0x027, 0x00077c18,
+       0x028, 0x000de471,
+       0x029, 0x000d7110,
+       0x02a, 0x0008cb04,
+       0x02b, 0x0004128b,
+       0x02c, 0x00001840,
+       0x043, 0x0002444f,
+       0x044, 0x0001adb0,
+       0x045, 0x00056467,
+       0x046, 0x0008992c,
+       0x047, 0x0000452c,
+       0x048, 0x000f9c43,
+       0x049, 0x00002e0c,
+       0x04a, 0x000546eb,
+       0x04b, 0x0008966c,
+       0x04c, 0x0000dde9,
+       0x018, 0x00007401,
+       0x000, 0x00070000,
+       0x012, 0x000dc000,
+       0x012, 0x00090000,
+       0x012, 0x00051000,
+       0x012, 0x00012000,
+       0x013, 0x000287b7,
+       0x013, 0x000247ab,
+       0x013, 0x0002079f,
+       0x013, 0x0001c793,
+       0x013, 0x0001839b,
+       0x013, 0x00014392,
+       0x013, 0x0001019a,
+       0x013, 0x0000c191,
+       0x013, 0x00008194,
+       0x013, 0x000040a0,
+       0x013, 0x00000018,
+       0x015, 0x0000f424,
+       0x015, 0x0004f424,
+       0x015, 0x0008f424,
+       0x016, 0x000e1330,
+       0x016, 0x000a1330,
+       0x016, 0x00061330,
+       0x016, 0x00021330,
+       0x018, 0x00017524,
+       0x000, 0x00070000,
+       0x012, 0x000cf000,
+       0x012, 0x000bc000,
+       0x012, 0x00078000,
+       0x012, 0x00000000,
+       0x013, 0x000287bc,
+       0x013, 0x000247b0,
+       0x013, 0x000203b4,
+       0x013, 0x0001c3a8,
+       0x013, 0x000181b4,
+       0x013, 0x000141a8,
+       0x013, 0x000100b0,
+       0x013, 0x0000c0a4,
+       0x013, 0x0000b02c,
+       0x013, 0x00004020,
+       0x013, 0x00000014,
+       0x015, 0x0000f4c3,
+       0x015, 0x0004f4c3,
+       0x015, 0x0008f4c3,
+       0x016, 0x000e085f,
+       0x016, 0x000a085f,
+       0x016, 0x0006085f,
+       0x016, 0x0002085f,
+       0x018, 0x00037524,
+       0x000, 0x00070000,
+       0x012, 0x000cf000,
+       0x012, 0x000bc000,
+       0x012, 0x00078000,
+       0x012, 0x00000000,
+       0x013, 0x000287bc,
+       0x013, 0x000247b0,
+       0x013, 0x000203b4,
+       0x013, 0x0001c3a8,
+       0x013, 0x000181b4,
+       0x013, 0x000141a8,
+       0x013, 0x000100b0,
+       0x013, 0x0000c0a4,
+       0x013, 0x0000b02c,
+       0x013, 0x00004020,
+       0x013, 0x00000014,
+       0x015, 0x0000f4c3,
+       0x015, 0x0004f4c3,
+       0x015, 0x0008f4c3,
+       0x016, 0x000e085f,
+       0x016, 0x000a085f,
+       0x016, 0x0006085f,
+       0x016, 0x0002085f,
+       0x018, 0x00057568,
+       0x000, 0x00070000,
+       0x012, 0x000cf000,
+       0x012, 0x000bc000,
+       0x012, 0x00078000,
+       0x012, 0x00000000,
+       0x013, 0x000287bc,
+       0x013, 0x000247b0,
+       0x013, 0x000203b4,
+       0x013, 0x0001c3a8,
+       0x013, 0x000181b4,
+       0x013, 0x000141a8,
+       0x013, 0x000100b0,
+       0x013, 0x0000c0a4,
+       0x013, 0x0000b02c,
+       0x013, 0x00004020,
+       0x013, 0x00000014,
+       0x015, 0x0000f4c3,
+       0x015, 0x0004f4c3,
+       0x015, 0x0008f4c3,
+       0x016, 0x000e085f,
+       0x016, 0x000a085f,
+       0x016, 0x0006085f,
+       0x016, 0x0002085f,
+       0x030, 0x0004470f,
+       0x031, 0x00044ff0,
+       0x032, 0x00000070,
+       0x033, 0x000dd480,
+       0x034, 0x000ffac0,
+       0x035, 0x000b80c0,
+       0x036, 0x00077000,
+       0x037, 0x00064ff2,
+       0x038, 0x000e7661,
+       0x039, 0x00000e90,
+       0x000, 0x00030000,
+       0x018, 0x0000f401,
+       0x0fe, 0x00000000,
+       0x0fe, 0x00000000,
+       0x01e, 0x00088009,
+       0x01f, 0x00080003,
+       0x0fe, 0x00000000,
+       0x01e, 0x00088001,
+       0x01f, 0x00080000,
+       0x0fe, 0x00000000,
+       0x018, 0x00097524,
+       0x0fe, 0x00000000,
+       0x0fe, 0x00000000,
+       0x0fe, 0x00000000,
+       0x0fe, 0x00000000,
+       0x02b, 0x00041289,
+       0x0fe, 0x00000000,
+       0x02d, 0x0006aaaa,
+       0x02e, 0x000b4d01,
+       0x02d, 0x00080000,
+       0x02e, 0x00004d02,
+       0x02d, 0x00095555,
+       0x02e, 0x00054d03,
+       0x02d, 0x000aaaaa,
+       0x02e, 0x000b4d04,
+       0x02d, 0x000c0000,
+       0x02e, 0x00004d05,
+       0x02d, 0x000d5555,
+       0x02e, 0x00054d06,
+       0x02d, 0x000eaaaa,
+       0x02e, 0x000b4d07,
+       0x02d, 0x00000000,
+       0x02e, 0x00005108,
+       0x02d, 0x00015555,
+       0x02e, 0x00055109,
+       0x02d, 0x0002aaaa,
+       0x02e, 0x000b510a,
+       0x02d, 0x00040000,
+       0x02e, 0x0000510b,
+       0x02d, 0x00055555,
+       0x02e, 0x0005510c,
+};
+
+u32 rtl8192de_radiob_2tarray[RADIOB_2T_ARRAYLENGTH] = {
+       0x000, 0x00030000,
+       0x001, 0x00030000,
+       0x002, 0x00000000,
+       0x003, 0x00018c63,
+       0x004, 0x00018c63,
+       0x008, 0x00084000,
+       0x00b, 0x0001c000,
+       0x00e, 0x00018c67,
+       0x00f, 0x00000851,
+       0x014, 0x00021440,
+       0x018, 0x00007401,
+       0x019, 0x00000060,
+       0x01d, 0x000a1290,
+       0x023, 0x00001558,
+       0x01a, 0x00030a99,
+       0x01b, 0x00040b00,
+       0x01c, 0x000fc339,
+       0x03a, 0x000a57eb,
+       0x03b, 0x00020000,
+       0x03c, 0x000ff454,
+       0x020, 0x0000aa52,
+       0x021, 0x00054000,
+       0x040, 0x0000aa52,
+       0x041, 0x00014000,
+       0x025, 0x000803be,
+       0x026, 0x000fc638,
+       0x027, 0x00077c18,
+       0x028, 0x000d1c31,
+       0x029, 0x000d7110,
+       0x02a, 0x000aeb04,
+       0x02b, 0x0004128b,
+       0x02c, 0x00001840,
+       0x043, 0x0002444f,
+       0x044, 0x0001adb0,
+       0x045, 0x00056467,
+       0x046, 0x0008992c,
+       0x047, 0x0000452c,
+       0x048, 0x000f9c43,
+       0x049, 0x00002e0c,
+       0x04a, 0x000546eb,
+       0x04b, 0x0008966c,
+       0x04c, 0x0000dde9,
+       0x018, 0x00007401,
+       0x000, 0x00070000,
+       0x012, 0x000dc000,
+       0x012, 0x00090000,
+       0x012, 0x00051000,
+       0x012, 0x00012000,
+       0x013, 0x000287b7,
+       0x013, 0x000247ab,
+       0x013, 0x0002079f,
+       0x013, 0x0001c793,
+       0x013, 0x0001839b,
+       0x013, 0x00014392,
+       0x013, 0x0001019a,
+       0x013, 0x0000c191,
+       0x013, 0x00008194,
+       0x013, 0x000040a0,
+       0x013, 0x00000018,
+       0x015, 0x0000f424,
+       0x015, 0x0004f424,
+       0x015, 0x0008f424,
+       0x016, 0x000e1330,
+       0x016, 0x000a1330,
+       0x016, 0x00061330,
+       0x016, 0x00021330,
+       0x018, 0x00017524,
+       0x000, 0x00070000,
+       0x012, 0x000cf000,
+       0x012, 0x000bc000,
+       0x012, 0x00078000,
+       0x012, 0x00000000,
+       0x013, 0x000287bc,
+       0x013, 0x000247b0,
+       0x013, 0x000203b4,
+       0x013, 0x0001c3a8,
+       0x013, 0x000181b4,
+       0x013, 0x000141a8,
+       0x013, 0x000100b0,
+       0x013, 0x0000c0a4,
+       0x013, 0x0000b02c,
+       0x013, 0x00004020,
+       0x013, 0x00000014,
+       0x015, 0x0000f4c3,
+       0x015, 0x0004f4c3,
+       0x015, 0x0008f4c3,
+       0x016, 0x000e085f,
+       0x016, 0x000a085f,
+       0x016, 0x0006085f,
+       0x016, 0x0002085f,
+       0x018, 0x00037524,
+       0x000, 0x00070000,
+       0x012, 0x000cf000,
+       0x012, 0x000bc000,
+       0x012, 0x00078000,
+       0x012, 0x00000000,
+       0x013, 0x000287bc,
+       0x013, 0x000247b0,
+       0x013, 0x000203b4,
+       0x013, 0x0001c3a8,
+       0x013, 0x000181b4,
+       0x013, 0x000141a8,
+       0x013, 0x000100b0,
+       0x013, 0x0000c0a4,
+       0x013, 0x0000b02c,
+       0x013, 0x00004020,
+       0x013, 0x00000014,
+       0x015, 0x0000f4c3,
+       0x015, 0x0004f4c3,
+       0x015, 0x0008f4c3,
+       0x016, 0x000e085f,
+       0x016, 0x000a085f,
+       0x016, 0x0006085f,
+       0x016, 0x0002085f,
+       0x018, 0x00057524,
+       0x000, 0x00070000,
+       0x012, 0x000cf000,
+       0x012, 0x000bc000,
+       0x012, 0x00078000,
+       0x012, 0x00000000,
+       0x013, 0x000287bc,
+       0x013, 0x000247b0,
+       0x013, 0x000203b4,
+       0x013, 0x0001c3a8,
+       0x013, 0x000181b4,
+       0x013, 0x000141a8,
+       0x013, 0x000100b0,
+       0x013, 0x0000c0a4,
+       0x013, 0x0000b02c,
+       0x013, 0x00004020,
+       0x013, 0x00000014,
+       0x015, 0x0000f4c3,
+       0x015, 0x0004f4c3,
+       0x015, 0x0008f4c3,
+       0x016, 0x000e085f,
+       0x016, 0x000a085f,
+       0x016, 0x0006085f,
+       0x016, 0x0002085f,
+       0x030, 0x0004470f,
+       0x031, 0x00044ff0,
+       0x032, 0x00000070,
+       0x033, 0x000dd480,
+       0x034, 0x000ffac0,
+       0x035, 0x000b80c0,
+       0x036, 0x00077000,
+       0x037, 0x00064ff2,
+       0x038, 0x000e7661,
+       0x039, 0x00000e90,
+       0x000, 0x00030000,
+       0x018, 0x0000f401,
+       0x0fe, 0x00000000,
+       0x0fe, 0x00000000,
+       0x01e, 0x00088009,
+       0x01f, 0x00080003,
+       0x0fe, 0x00000000,
+       0x01e, 0x00088001,
+       0x01f, 0x00080000,
+       0x0fe, 0x00000000,
+       0x018, 0x00087401,
+       0x0fe, 0x00000000,
+       0x0fe, 0x00000000,
+       0x0fe, 0x00000000,
+       0x02b, 0x00041289,
+       0x0fe, 0x00000000,
+       0x02d, 0x00066666,
+       0x02e, 0x00064001,
+       0x02d, 0x00091111,
+       0x02e, 0x00014002,
+       0x02d, 0x000bbbbb,
+       0x02e, 0x000b4003,
+       0x02d, 0x000e6666,
+       0x02e, 0x00064004,
+       0x02d, 0x00088888,
+       0x02e, 0x00084005,
+       0x02d, 0x0009dddd,
+       0x02e, 0x000d4006,
+       0x02d, 0x000b3333,
+       0x02e, 0x00034007,
+       0x02d, 0x00048888,
+       0x02e, 0x00084408,
+       0x02d, 0x000bbbbb,
+       0x02e, 0x000b4409,
+       0x02d, 0x000e6666,
+       0x02e, 0x0006440a,
+       0x02d, 0x00011111,
+       0x02e, 0x0001480b,
+       0x02d, 0x0003bbbb,
+       0x02e, 0x000b480c,
+       0x02d, 0x00066666,
+       0x02e, 0x0006480d,
+       0x02d, 0x000ccccc,
+       0x02e, 0x000c480e,
+};
+
+u32 rtl8192de_radioa_2t_int_paarray[RADIOA_2T_INT_PA_ARRAYLENGTH] = {
+       0x000, 0x00030000,
+       0x001, 0x00030000,
+       0x002, 0x00000000,
+       0x003, 0x00018c63,
+       0x004, 0x00018c63,
+       0x008, 0x00084000,
+       0x00b, 0x0001c000,
+       0x00e, 0x00018c67,
+       0x00f, 0x00000851,
+       0x014, 0x00021440,
+       0x018, 0x00017524,
+       0x019, 0x00000000,
+       0x01d, 0x000a1290,
+       0x023, 0x00001558,
+       0x01a, 0x00030a99,
+       0x01b, 0x00040b00,
+       0x01c, 0x000fc339,
+       0x03a, 0x000a57eb,
+       0x03b, 0x00020000,
+       0x03c, 0x000ff454,
+       0x020, 0x0000aa52,
+       0x021, 0x00054000,
+       0x040, 0x0000aa52,
+       0x041, 0x00014000,
+       0x025, 0x000803be,
+       0x026, 0x000fc638,
+       0x027, 0x00077c18,
+       0x028, 0x000de471,
+       0x029, 0x000d7110,
+       0x02a, 0x0008eb04,
+       0x02b, 0x0004128b,
+       0x02c, 0x00001840,
+       0x043, 0x0002444f,
+       0x044, 0x0001adb0,
+       0x045, 0x00056467,
+       0x046, 0x0008992c,
+       0x047, 0x0000452c,
+       0x048, 0x000c0443,
+       0x049, 0x00000730,
+       0x04a, 0x00050f0f,
+       0x04b, 0x000896ee,
+       0x04c, 0x0000ddee,
+       0x018, 0x00007401,
+       0x000, 0x00070000,
+       0x012, 0x000dc000,
+       0x012, 0x00090000,
+       0x012, 0x00051000,
+       0x012, 0x00012000,
+       0x013, 0x000287b7,
+       0x013, 0x000247ab,
+       0x013, 0x0002079f,
+       0x013, 0x0001c793,
+       0x013, 0x0001839b,
+       0x013, 0x00014392,
+       0x013, 0x0001019a,
+       0x013, 0x0000c191,
+       0x013, 0x00008194,
+       0x013, 0x000040a0,
+       0x013, 0x00000018,
+       0x015, 0x0000f424,
+       0x015, 0x0004f424,
+       0x015, 0x0008f424,
+       0x016, 0x000e1330,
+       0x016, 0x000a1330,
+       0x016, 0x00061330,
+       0x016, 0x00021330,
+       0x018, 0x00017524,
+       0x000, 0x00070000,
+       0x012, 0x000cf000,
+       0x012, 0x000bc000,
+       0x012, 0x00078000,
+       0x012, 0x00000000,
+       0x013, 0x000287bf,
+       0x013, 0x000247b3,
+       0x013, 0x000207a7,
+       0x013, 0x0001c79b,
+       0x013, 0x0001839f,
+       0x013, 0x00014393,
+       0x013, 0x00010399,
+       0x013, 0x0000c38d,
+       0x013, 0x00008199,
+       0x013, 0x0000418d,
+       0x013, 0x00000099,
+       0x015, 0x0000f495,
+       0x015, 0x0004f495,
+       0x015, 0x0008f495,
+       0x016, 0x000e1874,
+       0x016, 0x000a1874,
+       0x016, 0x00061874,
+       0x016, 0x00021874,
+       0x018, 0x00037564,
+       0x000, 0x00070000,
+       0x012, 0x000cf000,
+       0x012, 0x000bc000,
+       0x012, 0x00078000,
+       0x012, 0x00000000,
+       0x013, 0x000287bf,
+       0x013, 0x000247b3,
+       0x013, 0x000207a7,
+       0x013, 0x0001c79b,
+       0x013, 0x0001839f,
+       0x013, 0x00014393,
+       0x013, 0x00010399,
+       0x013, 0x0000c38d,
+       0x013, 0x00008199,
+       0x013, 0x0000418d,
+       0x013, 0x00000099,
+       0x015, 0x0000f495,
+       0x015, 0x0004f495,
+       0x015, 0x0008f495,
+       0x016, 0x000e1874,
+       0x016, 0x000a1874,
+       0x016, 0x00061874,
+       0x016, 0x00021874,
+       0x018, 0x00057595,
+       0x000, 0x00070000,
+       0x012, 0x000cf000,
+       0x012, 0x000bc000,
+       0x012, 0x00078000,
+       0x012, 0x00000000,
+       0x013, 0x000287bf,
+       0x013, 0x000247b3,
+       0x013, 0x000207a7,
+       0x013, 0x0001c79b,
+       0x013, 0x0001839f,
+       0x013, 0x00014393,
+       0x013, 0x00010399,
+       0x013, 0x0000c38d,
+       0x013, 0x00008199,
+       0x013, 0x0000418d,
+       0x013, 0x00000099,
+       0x015, 0x0000f495,
+       0x015, 0x0004f495,
+       0x015, 0x0008f495,
+       0x016, 0x000e1874,
+       0x016, 0x000a1874,
+       0x016, 0x00061874,
+       0x016, 0x00021874,
+       0x030, 0x0004470f,
+       0x031, 0x00044ff0,
+       0x032, 0x00000070,
+       0x033, 0x000dd480,
+       0x034, 0x000ffac0,
+       0x035, 0x000b80c0,
+       0x036, 0x00077000,
+       0x037, 0x00064ff2,
+       0x038, 0x000e7661,
+       0x039, 0x00000e90,
+       0x000, 0x00030000,
+       0x018, 0x0000f401,
+       0x0fe, 0x00000000,
+       0x0fe, 0x00000000,
+       0x01e, 0x00088009,
+       0x01f, 0x00080003,
+       0x0fe, 0x00000000,
+       0x01e, 0x00088001,
+       0x01f, 0x00080000,
+       0x0fe, 0x00000000,
+       0x018, 0x00097524,
+       0x0fe, 0x00000000,
+       0x0fe, 0x00000000,
+       0x0fe, 0x00000000,
+       0x0fe, 0x00000000,
+       0x02b, 0x00041289,
+       0x0fe, 0x00000000,
+       0x02d, 0x0006aaaa,
+       0x02e, 0x000b4d01,
+       0x02d, 0x00080000,
+       0x02e, 0x00004d02,
+       0x02d, 0x00095555,
+       0x02e, 0x00054d03,
+       0x02d, 0x000aaaaa,
+       0x02e, 0x000b4d04,
+       0x02d, 0x000c0000,
+       0x02e, 0x00004d05,
+       0x02d, 0x000d5555,
+       0x02e, 0x00054d06,
+       0x02d, 0x000eaaaa,
+       0x02e, 0x000b4d07,
+       0x02d, 0x00000000,
+       0x02e, 0x00005108,
+       0x02d, 0x00015555,
+       0x02e, 0x00055109,
+       0x02d, 0x0002aaaa,
+       0x02e, 0x000b510a,
+       0x02d, 0x00040000,
+       0x02e, 0x0000510b,
+       0x02d, 0x00055555,
+       0x02e, 0x0005510c,
+};
+
+u32 rtl8192de_radiob_2t_int_paarray[RADIOB_2T_INT_PA_ARRAYLENGTH] = {
+       0x000, 0x00030000,
+       0x001, 0x00030000,
+       0x002, 0x00000000,
+       0x003, 0x00018c63,
+       0x004, 0x00018c63,
+       0x008, 0x00084000,
+       0x00b, 0x0001c000,
+       0x00e, 0x00018c67,
+       0x00f, 0x00000851,
+       0x014, 0x00021440,
+       0x018, 0x00007401,
+       0x019, 0x00000060,
+       0x01d, 0x000a1290,
+       0x023, 0x00001558,
+       0x01a, 0x00030a99,
+       0x01b, 0x00040b00,
+       0x01c, 0x000fc339,
+       0x03a, 0x000a57eb,
+       0x03b, 0x00020000,
+       0x03c, 0x000ff454,
+       0x020, 0x0000aa52,
+       0x021, 0x00054000,
+       0x040, 0x0000aa52,
+       0x041, 0x00014000,
+       0x025, 0x000803be,
+       0x026, 0x000fc638,
+       0x027, 0x00077c18,
+       0x028, 0x000d1c31,
+       0x029, 0x000d7110,
+       0x02a, 0x000aeb04,
+       0x02b, 0x0004128b,
+       0x02c, 0x00001840,
+       0x043, 0x0002444f,
+       0x044, 0x0001adb0,
+       0x045, 0x00056467,
+       0x046, 0x0008992c,
+       0x047, 0x0000452c,
+       0x048, 0x000c0443,
+       0x049, 0x00000730,
+       0x04a, 0x00050f0f,
+       0x04b, 0x000896ee,
+       0x04c, 0x0000ddee,
+       0x018, 0x00007401,
+       0x000, 0x00070000,
+       0x012, 0x000dc000,
+       0x012, 0x00090000,
+       0x012, 0x00051000,
+       0x012, 0x00012000,
+       0x013, 0x000287b7,
+       0x013, 0x000247ab,
+       0x013, 0x0002079f,
+       0x013, 0x0001c793,
+       0x013, 0x0001839b,
+       0x013, 0x00014392,
+       0x013, 0x0001019a,
+       0x013, 0x0000c191,
+       0x013, 0x00008194,
+       0x013, 0x000040a0,
+       0x013, 0x00000018,
+       0x015, 0x0000f424,
+       0x015, 0x0004f424,
+       0x015, 0x0008f424,
+       0x016, 0x000e1330,
+       0x016, 0x000a1330,
+       0x016, 0x00061330,
+       0x016, 0x00021330,
+       0x018, 0x00017524,
+       0x000, 0x00070000,
+       0x012, 0x000cf000,
+       0x012, 0x000bc000,
+       0x012, 0x00078000,
+       0x012, 0x00000000,
+       0x013, 0x000287bf,
+       0x013, 0x000247b3,
+       0x013, 0x000207a7,
+       0x013, 0x0001c79b,
+       0x013, 0x0001839f,
+       0x013, 0x00014393,
+       0x013, 0x00010399,
+       0x013, 0x0000c38d,
+       0x013, 0x00008199,
+       0x013, 0x0000418d,
+       0x013, 0x00000099,
+       0x015, 0x0000f495,
+       0x015, 0x0004f495,
+       0x015, 0x0008f495,
+       0x016, 0x000e1874,
+       0x016, 0x000a1874,
+       0x016, 0x00061874,
+       0x016, 0x00021874,
+       0x018, 0x00037564,
+       0x000, 0x00070000,
+       0x012, 0x000cf000,
+       0x012, 0x000bc000,
+       0x012, 0x00078000,
+       0x012, 0x00000000,
+       0x013, 0x000287bf,
+       0x013, 0x000247b3,
+       0x013, 0x000207a7,
+       0x013, 0x0001c79b,
+       0x013, 0x0001839f,
+       0x013, 0x00014393,
+       0x013, 0x00010399,
+       0x013, 0x0000c38d,
+       0x013, 0x00008199,
+       0x013, 0x0000418d,
+       0x013, 0x00000099,
+       0x015, 0x0000f495,
+       0x015, 0x0004f495,
+       0x015, 0x0008f495,
+       0x016, 0x000e1874,
+       0x016, 0x000a1874,
+       0x016, 0x00061874,
+       0x016, 0x00021874,
+       0x018, 0x00057595,
+       0x000, 0x00070000,
+       0x012, 0x000cf000,
+       0x012, 0x000bc000,
+       0x012, 0x00078000,
+       0x012, 0x00000000,
+       0x013, 0x000287bf,
+       0x013, 0x000247b3,
+       0x013, 0x000207a7,
+       0x013, 0x0001c79b,
+       0x013, 0x0001839f,
+       0x013, 0x00014393,
+       0x013, 0x00010399,
+       0x013, 0x0000c38d,
+       0x013, 0x00008199,
+       0x013, 0x0000418d,
+       0x013, 0x00000099,
+       0x015, 0x0000f495,
+       0x015, 0x0004f495,
+       0x015, 0x0008f495,
+       0x016, 0x000e1874,
+       0x016, 0x000a1874,
+       0x016, 0x00061874,
+       0x016, 0x00021874,
+       0x030, 0x0004470f,
+       0x031, 0x00044ff0,
+       0x032, 0x00000070,
+       0x033, 0x000dd480,
+       0x034, 0x000ffac0,
+       0x035, 0x000b80c0,
+       0x036, 0x00077000,
+       0x037, 0x00064ff2,
+       0x038, 0x000e7661,
+       0x039, 0x00000e90,
+       0x000, 0x00030000,
+       0x018, 0x0000f401,
+       0x0fe, 0x00000000,
+       0x0fe, 0x00000000,
+       0x01e, 0x00088009,
+       0x01f, 0x00080003,
+       0x0fe, 0x00000000,
+       0x01e, 0x00088001,
+       0x01f, 0x00080000,
+       0x0fe, 0x00000000,
+       0x018, 0x00087401,
+       0x0fe, 0x00000000,
+       0x0fe, 0x00000000,
+       0x0fe, 0x00000000,
+       0x02b, 0x00041289,
+       0x0fe, 0x00000000,
+       0x02d, 0x00066666,
+       0x02e, 0x00064001,
+       0x02d, 0x00091111,
+       0x02e, 0x00014002,
+       0x02d, 0x000bbbbb,
+       0x02e, 0x000b4003,
+       0x02d, 0x000e6666,
+       0x02e, 0x00064004,
+       0x02d, 0x00088888,
+       0x02e, 0x00084005,
+       0x02d, 0x0009dddd,
+       0x02e, 0x000d4006,
+       0x02d, 0x000b3333,
+       0x02e, 0x00034007,
+       0x02d, 0x00048888,
+       0x02e, 0x00084408,
+       0x02d, 0x000bbbbb,
+       0x02e, 0x000b4409,
+       0x02d, 0x000e6666,
+       0x02e, 0x0006440a,
+       0x02d, 0x00011111,
+       0x02e, 0x0001480b,
+       0x02d, 0x0003bbbb,
+       0x02e, 0x000b480c,
+       0x02d, 0x00066666,
+       0x02e, 0x0006480d,
+       0x02d, 0x000ccccc,
+       0x02e, 0x000c480e,
+};
+
+u32 rtl8192de_mac_2tarray[MAC_2T_ARRAYLENGTH] = {
+       0x420, 0x00000080,
+       0x423, 0x00000000,
+       0x430, 0x00000000,
+       0x431, 0x00000000,
+       0x432, 0x00000000,
+       0x433, 0x00000001,
+       0x434, 0x00000004,
+       0x435, 0x00000005,
+       0x436, 0x00000006,
+       0x437, 0x00000007,
+       0x438, 0x00000000,
+       0x439, 0x00000000,
+       0x43a, 0x00000000,
+       0x43b, 0x00000001,
+       0x43c, 0x00000004,
+       0x43d, 0x00000005,
+       0x43e, 0x00000006,
+       0x43f, 0x00000007,
+       0x440, 0x00000050,
+       0x441, 0x00000001,
+       0x442, 0x00000000,
+       0x444, 0x00000015,
+       0x445, 0x000000f0,
+       0x446, 0x0000000f,
+       0x447, 0x00000000,
+       0x462, 0x00000008,
+       0x463, 0x00000003,
+       0x4c8, 0x000000ff,
+       0x4c9, 0x00000008,
+       0x4cc, 0x000000ff,
+       0x4cd, 0x000000ff,
+       0x4ce, 0x00000001,
+       0x500, 0x00000026,
+       0x501, 0x000000a2,
+       0x502, 0x0000002f,
+       0x503, 0x00000000,
+       0x504, 0x00000028,
+       0x505, 0x000000a3,
+       0x506, 0x0000005e,
+       0x507, 0x00000000,
+       0x508, 0x0000002b,
+       0x509, 0x000000a4,
+       0x50a, 0x0000005e,
+       0x50b, 0x00000000,
+       0x50c, 0x0000004f,
+       0x50d, 0x000000a4,
+       0x50e, 0x00000000,
+       0x50f, 0x00000000,
+       0x512, 0x0000001c,
+       0x514, 0x0000000a,
+       0x515, 0x00000010,
+       0x516, 0x0000000a,
+       0x517, 0x00000010,
+       0x51a, 0x00000016,
+       0x524, 0x0000000f,
+       0x525, 0x0000004f,
+       0x546, 0x00000040,
+       0x547, 0x00000000,
+       0x550, 0x00000010,
+       0x551, 0x00000010,
+       0x559, 0x00000002,
+       0x55a, 0x00000002,
+       0x55d, 0x000000ff,
+       0x605, 0x00000030,
+       0x608, 0x0000000e,
+       0x609, 0x0000002a,
+       0x652, 0x00000020,
+       0x63c, 0x0000000a,
+       0x63d, 0x0000000a,
+       0x63e, 0x0000000e,
+       0x63f, 0x0000000e,
+       0x66e, 0x00000005,
+       0x700, 0x00000021,
+       0x701, 0x00000043,
+       0x702, 0x00000065,
+       0x703, 0x00000087,
+       0x708, 0x00000021,
+       0x709, 0x00000043,
+       0x70a, 0x00000065,
+       0x70b, 0x00000087,
+};
+
+u32 rtl8192de_agctab_array[AGCTAB_ARRAYLENGTH] = {
+       0xc78, 0x7b000001,
+       0xc78, 0x7b010001,
+       0xc78, 0x7b020001,
+       0xc78, 0x7b030001,
+       0xc78, 0x7b040001,
+       0xc78, 0x7b050001,
+       0xc78, 0x7b060001,
+       0xc78, 0x7a070001,
+       0xc78, 0x79080001,
+       0xc78, 0x78090001,
+       0xc78, 0x770a0001,
+       0xc78, 0x760b0001,
+       0xc78, 0x750c0001,
+       0xc78, 0x740d0001,
+       0xc78, 0x730e0001,
+       0xc78, 0x720f0001,
+       0xc78, 0x71100001,
+       0xc78, 0x70110001,
+       0xc78, 0x6f120001,
+       0xc78, 0x6e130001,
+       0xc78, 0x6d140001,
+       0xc78, 0x6c150001,
+       0xc78, 0x6b160001,
+       0xc78, 0x6a170001,
+       0xc78, 0x69180001,
+       0xc78, 0x68190001,
+       0xc78, 0x671a0001,
+       0xc78, 0x661b0001,
+       0xc78, 0x651c0001,
+       0xc78, 0x641d0001,
+       0xc78, 0x631e0001,
+       0xc78, 0x621f0001,
+       0xc78, 0x61200001,
+       0xc78, 0x60210001,
+       0xc78, 0x49220001,
+       0xc78, 0x48230001,
+       0xc78, 0x47240001,
+       0xc78, 0x46250001,
+       0xc78, 0x45260001,
+       0xc78, 0x44270001,
+       0xc78, 0x43280001,
+       0xc78, 0x42290001,
+       0xc78, 0x412a0001,
+       0xc78, 0x402b0001,
+       0xc78, 0x262c0001,
+       0xc78, 0x252d0001,
+       0xc78, 0x242e0001,
+       0xc78, 0x232f0001,
+       0xc78, 0x22300001,
+       0xc78, 0x21310001,
+       0xc78, 0x20320001,
+       0xc78, 0x06330001,
+       0xc78, 0x05340001,
+       0xc78, 0x04350001,
+       0xc78, 0x03360001,
+       0xc78, 0x02370001,
+       0xc78, 0x01380001,
+       0xc78, 0x00390001,
+       0xc78, 0x003a0001,
+       0xc78, 0x003b0001,
+       0xc78, 0x003c0001,
+       0xc78, 0x003d0001,
+       0xc78, 0x003e0001,
+       0xc78, 0x003f0001,
+       0xc78, 0x7b400001,
+       0xc78, 0x7b410001,
+       0xc78, 0x7a420001,
+       0xc78, 0x79430001,
+       0xc78, 0x78440001,
+       0xc78, 0x77450001,
+       0xc78, 0x76460001,
+       0xc78, 0x75470001,
+       0xc78, 0x74480001,
+       0xc78, 0x73490001,
+       0xc78, 0x724a0001,
+       0xc78, 0x714b0001,
+       0xc78, 0x704c0001,
+       0xc78, 0x6f4d0001,
+       0xc78, 0x6e4e0001,
+       0xc78, 0x6d4f0001,
+       0xc78, 0x6c500001,
+       0xc78, 0x6b510001,
+       0xc78, 0x6a520001,
+       0xc78, 0x69530001,
+       0xc78, 0x68540001,
+       0xc78, 0x67550001,
+       0xc78, 0x66560001,
+       0xc78, 0x65570001,
+       0xc78, 0x64580001,
+       0xc78, 0x63590001,
+       0xc78, 0x625a0001,
+       0xc78, 0x615b0001,
+       0xc78, 0x605c0001,
+       0xc78, 0x485d0001,
+       0xc78, 0x475e0001,
+       0xc78, 0x465f0001,
+       0xc78, 0x45600001,
+       0xc78, 0x44610001,
+       0xc78, 0x43620001,
+       0xc78, 0x42630001,
+       0xc78, 0x41640001,
+       0xc78, 0x40650001,
+       0xc78, 0x27660001,
+       0xc78, 0x26670001,
+       0xc78, 0x25680001,
+       0xc78, 0x24690001,
+       0xc78, 0x236a0001,
+       0xc78, 0x226b0001,
+       0xc78, 0x216c0001,
+       0xc78, 0x206d0001,
+       0xc78, 0x206e0001,
+       0xc78, 0x206f0001,
+       0xc78, 0x20700001,
+       0xc78, 0x20710001,
+       0xc78, 0x20720001,
+       0xc78, 0x20730001,
+       0xc78, 0x20740001,
+       0xc78, 0x20750001,
+       0xc78, 0x20760001,
+       0xc78, 0x20770001,
+       0xc78, 0x20780001,
+       0xc78, 0x20790001,
+       0xc78, 0x207a0001,
+       0xc78, 0x207b0001,
+       0xc78, 0x207c0001,
+       0xc78, 0x207d0001,
+       0xc78, 0x207e0001,
+       0xc78, 0x207f0001,
+       0xc78, 0x38000002,
+       0xc78, 0x38010002,
+       0xc78, 0x38020002,
+       0xc78, 0x38030002,
+       0xc78, 0x38040002,
+       0xc78, 0x38050002,
+       0xc78, 0x38060002,
+       0xc78, 0x38070002,
+       0xc78, 0x38080002,
+       0xc78, 0x3c090002,
+       0xc78, 0x3e0a0002,
+       0xc78, 0x400b0002,
+       0xc78, 0x440c0002,
+       0xc78, 0x480d0002,
+       0xc78, 0x4c0e0002,
+       0xc78, 0x500f0002,
+       0xc78, 0x52100002,
+       0xc78, 0x56110002,
+       0xc78, 0x5a120002,
+       0xc78, 0x5e130002,
+       0xc78, 0x60140002,
+       0xc78, 0x60150002,
+       0xc78, 0x60160002,
+       0xc78, 0x62170002,
+       0xc78, 0x62180002,
+       0xc78, 0x62190002,
+       0xc78, 0x621a0002,
+       0xc78, 0x621b0002,
+       0xc78, 0x621c0002,
+       0xc78, 0x621d0002,
+       0xc78, 0x621e0002,
+       0xc78, 0x621f0002,
+       0xc78, 0x32000044,
+       0xc78, 0x32010044,
+       0xc78, 0x32020044,
+       0xc78, 0x32030044,
+       0xc78, 0x32040044,
+       0xc78, 0x32050044,
+       0xc78, 0x32060044,
+       0xc78, 0x32070044,
+       0xc78, 0x32080044,
+       0xc78, 0x34090044,
+       0xc78, 0x350a0044,
+       0xc78, 0x360b0044,
+       0xc78, 0x370c0044,
+       0xc78, 0x380d0044,
+       0xc78, 0x390e0044,
+       0xc78, 0x3a0f0044,
+       0xc78, 0x3e100044,
+       0xc78, 0x42110044,
+       0xc78, 0x44120044,
+       0xc78, 0x46130044,
+       0xc78, 0x4a140044,
+       0xc78, 0x4e150044,
+       0xc78, 0x50160044,
+       0xc78, 0x55170044,
+       0xc78, 0x5a180044,
+       0xc78, 0x5e190044,
+       0xc78, 0x641a0044,
+       0xc78, 0x6e1b0044,
+       0xc78, 0x6e1c0044,
+       0xc78, 0x6e1d0044,
+       0xc78, 0x6e1e0044,
+       0xc78, 0x6e1f0044,
+       0xc78, 0x6e1f0000,
+};
+
+u32 rtl8192de_agctab_5garray[AGCTAB_5G_ARRAYLENGTH] = {
+       0xc78, 0x7b000001,
+       0xc78, 0x7b010001,
+       0xc78, 0x7a020001,
+       0xc78, 0x79030001,
+       0xc78, 0x78040001,
+       0xc78, 0x77050001,
+       0xc78, 0x76060001,
+       0xc78, 0x75070001,
+       0xc78, 0x74080001,
+       0xc78, 0x73090001,
+       0xc78, 0x720a0001,
+       0xc78, 0x710b0001,
+       0xc78, 0x700c0001,
+       0xc78, 0x6f0d0001,
+       0xc78, 0x6e0e0001,
+       0xc78, 0x6d0f0001,
+       0xc78, 0x6c100001,
+       0xc78, 0x6b110001,
+       0xc78, 0x6a120001,
+       0xc78, 0x69130001,
+       0xc78, 0x68140001,
+       0xc78, 0x67150001,
+       0xc78, 0x66160001,
+       0xc78, 0x65170001,
+       0xc78, 0x64180001,
+       0xc78, 0x63190001,
+       0xc78, 0x621a0001,
+       0xc78, 0x611b0001,
+       0xc78, 0x601c0001,
+       0xc78, 0x481d0001,
+       0xc78, 0x471e0001,
+       0xc78, 0x461f0001,
+       0xc78, 0x45200001,
+       0xc78, 0x44210001,
+       0xc78, 0x43220001,
+       0xc78, 0x42230001,
+       0xc78, 0x41240001,
+       0xc78, 0x40250001,
+       0xc78, 0x27260001,
+       0xc78, 0x26270001,
+       0xc78, 0x25280001,
+       0xc78, 0x24290001,
+       0xc78, 0x232a0001,
+       0xc78, 0x222b0001,
+       0xc78, 0x212c0001,
+       0xc78, 0x202d0001,
+       0xc78, 0x202e0001,
+       0xc78, 0x202f0001,
+       0xc78, 0x20300001,
+       0xc78, 0x20310001,
+       0xc78, 0x20320001,
+       0xc78, 0x20330001,
+       0xc78, 0x20340001,
+       0xc78, 0x20350001,
+       0xc78, 0x20360001,
+       0xc78, 0x20370001,
+       0xc78, 0x20380001,
+       0xc78, 0x20390001,
+       0xc78, 0x203a0001,
+       0xc78, 0x203b0001,
+       0xc78, 0x203c0001,
+       0xc78, 0x203d0001,
+       0xc78, 0x203e0001,
+       0xc78, 0x203f0001,
+       0xc78, 0x32000044,
+       0xc78, 0x32010044,
+       0xc78, 0x32020044,
+       0xc78, 0x32030044,
+       0xc78, 0x32040044,
+       0xc78, 0x32050044,
+       0xc78, 0x32060044,
+       0xc78, 0x32070044,
+       0xc78, 0x32080044,
+       0xc78, 0x34090044,
+       0xc78, 0x350a0044,
+       0xc78, 0x360b0044,
+       0xc78, 0x370c0044,
+       0xc78, 0x380d0044,
+       0xc78, 0x390e0044,
+       0xc78, 0x3a0f0044,
+       0xc78, 0x3e100044,
+       0xc78, 0x42110044,
+       0xc78, 0x44120044,
+       0xc78, 0x46130044,
+       0xc78, 0x4a140044,
+       0xc78, 0x4e150044,
+       0xc78, 0x50160044,
+       0xc78, 0x55170044,
+       0xc78, 0x5a180044,
+       0xc78, 0x5e190044,
+       0xc78, 0x641a0044,
+       0xc78, 0x6e1b0044,
+       0xc78, 0x6e1c0044,
+       0xc78, 0x6e1d0044,
+       0xc78, 0x6e1e0044,
+       0xc78, 0x6e1f0044,
+       0xc78, 0x6e1f0000,
+};
+
+u32 rtl8192de_agctab_2garray[AGCTAB_2G_ARRAYLENGTH] = {
+       0xc78, 0x7b000001,
+       0xc78, 0x7b010001,
+       0xc78, 0x7b020001,
+       0xc78, 0x7b030001,
+       0xc78, 0x7b040001,
+       0xc78, 0x7b050001,
+       0xc78, 0x7b060001,
+       0xc78, 0x7a070001,
+       0xc78, 0x79080001,
+       0xc78, 0x78090001,
+       0xc78, 0x770a0001,
+       0xc78, 0x760b0001,
+       0xc78, 0x750c0001,
+       0xc78, 0x740d0001,
+       0xc78, 0x730e0001,
+       0xc78, 0x720f0001,
+       0xc78, 0x71100001,
+       0xc78, 0x70110001,
+       0xc78, 0x6f120001,
+       0xc78, 0x6e130001,
+       0xc78, 0x6d140001,
+       0xc78, 0x6c150001,
+       0xc78, 0x6b160001,
+       0xc78, 0x6a170001,
+       0xc78, 0x69180001,
+       0xc78, 0x68190001,
+       0xc78, 0x671a0001,
+       0xc78, 0x661b0001,
+       0xc78, 0x651c0001,
+       0xc78, 0x641d0001,
+       0xc78, 0x631e0001,
+       0xc78, 0x621f0001,
+       0xc78, 0x61200001,
+       0xc78, 0x60210001,
+       0xc78, 0x49220001,
+       0xc78, 0x48230001,
+       0xc78, 0x47240001,
+       0xc78, 0x46250001,
+       0xc78, 0x45260001,
+       0xc78, 0x44270001,
+       0xc78, 0x43280001,
+       0xc78, 0x42290001,
+       0xc78, 0x412a0001,
+       0xc78, 0x402b0001,
+       0xc78, 0x262c0001,
+       0xc78, 0x252d0001,
+       0xc78, 0x242e0001,
+       0xc78, 0x232f0001,
+       0xc78, 0x22300001,
+       0xc78, 0x21310001,
+       0xc78, 0x20320001,
+       0xc78, 0x06330001,
+       0xc78, 0x05340001,
+       0xc78, 0x04350001,
+       0xc78, 0x03360001,
+       0xc78, 0x02370001,
+       0xc78, 0x01380001,
+       0xc78, 0x00390001,
+       0xc78, 0x003a0001,
+       0xc78, 0x003b0001,
+       0xc78, 0x003c0001,
+       0xc78, 0x003d0001,
+       0xc78, 0x003e0001,
+       0xc78, 0x003f0001,
+       0xc78, 0x38000002,
+       0xc78, 0x38010002,
+       0xc78, 0x38020002,
+       0xc78, 0x38030002,
+       0xc78, 0x38040002,
+       0xc78, 0x38050002,
+       0xc78, 0x38060002,
+       0xc78, 0x38070002,
+       0xc78, 0x38080002,
+       0xc78, 0x3c090002,
+       0xc78, 0x3e0a0002,
+       0xc78, 0x400b0002,
+       0xc78, 0x440c0002,
+       0xc78, 0x480d0002,
+       0xc78, 0x4c0e0002,
+       0xc78, 0x500f0002,
+       0xc78, 0x52100002,
+       0xc78, 0x56110002,
+       0xc78, 0x5a120002,
+       0xc78, 0x5e130002,
+       0xc78, 0x60140002,
+       0xc78, 0x60150002,
+       0xc78, 0x60160002,
+       0xc78, 0x62170002,
+       0xc78, 0x62180002,
+       0xc78, 0x62190002,
+       0xc78, 0x621a0002,
+       0xc78, 0x621b0002,
+       0xc78, 0x621c0002,
+       0xc78, 0x621d0002,
+       0xc78, 0x621e0002,
+       0xc78, 0x621f0002,
+       0xc78, 0x6e1f0000,
+};
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/table.h b/drivers/net/wireless/rtlwifi/rtl8192de/table.h
new file mode 100644 (file)
index 0000000..93f30ca
--- /dev/null
@@ -0,0 +1,57 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ * Created on  2010/ 5/18,  1:41
+ *****************************************************************************/
+
+#ifndef __RTL92DE_TABLE__H_
+#define __RTL92DE_TABLE__H_
+
+/*Created on  2011/ 1/14,  1:35*/
+
+#define PHY_REG_2T_ARRAYLENGTH 380
+extern u32 rtl8192de_phy_reg_2tarray[PHY_REG_2T_ARRAYLENGTH];
+#define PHY_REG_ARRAY_PG_LENGTH 624
+extern u32 rtl8192de_phy_reg_array_pg[PHY_REG_ARRAY_PG_LENGTH];
+#define RADIOA_2T_ARRAYLENGTH 378
+extern u32 rtl8192de_radioa_2tarray[RADIOA_2T_ARRAYLENGTH];
+#define RADIOB_2T_ARRAYLENGTH 384
+extern u32 rtl8192de_radiob_2tarray[RADIOB_2T_ARRAYLENGTH];
+#define RADIOA_2T_INT_PA_ARRAYLENGTH 378
+extern u32 rtl8192de_radioa_2t_int_paarray[RADIOA_2T_INT_PA_ARRAYLENGTH];
+#define RADIOB_2T_INT_PA_ARRAYLENGTH 384
+extern u32 rtl8192de_radiob_2t_int_paarray[RADIOB_2T_INT_PA_ARRAYLENGTH];
+#define MAC_2T_ARRAYLENGTH 160
+extern u32 rtl8192de_mac_2tarray[MAC_2T_ARRAYLENGTH];
+#define AGCTAB_ARRAYLENGTH 386
+extern u32 rtl8192de_agctab_array[AGCTAB_ARRAYLENGTH];
+#define AGCTAB_5G_ARRAYLENGTH 194
+extern u32 rtl8192de_agctab_5garray[AGCTAB_5G_ARRAYLENGTH];
+#define AGCTAB_2G_ARRAYLENGTH 194
+extern u32 rtl8192de_agctab_2garray[AGCTAB_2G_ARRAYLENGTH];
+
+#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
new file mode 100644 (file)
index 0000000..bf1462f
--- /dev/null
@@ -0,0 +1,959 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "trx.h"
+#include "led.h"
+
+static u8 _rtl92de_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
+{
+       __le16 fc = rtl_get_fc(skb);
+
+       if (unlikely(ieee80211_is_beacon(fc)))
+               return QSLT_BEACON;
+       if (ieee80211_is_mgmt(fc))
+               return QSLT_MGNT;
+
+       return skb->priority;
+}
+
+static int _rtl92de_rate_mapping(bool isht, u8 desc_rate)
+{
+       int rate_idx;
+
+       if (false == isht) {
+               switch (desc_rate) {
+               case DESC92D_RATE1M:
+                       rate_idx = 0;
+                       break;
+               case DESC92D_RATE2M:
+                       rate_idx = 1;
+                       break;
+               case DESC92D_RATE5_5M:
+                       rate_idx = 2;
+                       break;
+               case DESC92D_RATE11M:
+                       rate_idx = 3;
+                       break;
+               case DESC92D_RATE6M:
+                       rate_idx = 4;
+                       break;
+               case DESC92D_RATE9M:
+                       rate_idx = 5;
+                       break;
+               case DESC92D_RATE12M:
+                       rate_idx = 6;
+                       break;
+               case DESC92D_RATE18M:
+                       rate_idx = 7;
+                       break;
+               case DESC92D_RATE24M:
+                       rate_idx = 8;
+                       break;
+               case DESC92D_RATE36M:
+                       rate_idx = 9;
+                       break;
+               case DESC92D_RATE48M:
+                       rate_idx = 10;
+                       break;
+               case DESC92D_RATE54M:
+                       rate_idx = 11;
+                       break;
+               default:
+                       rate_idx = 0;
+                       break;
+               }
+               return rate_idx;
+       } else {
+               switch (desc_rate) {
+               case DESC92D_RATE1M:
+                       rate_idx = 0;
+                       break;
+               case DESC92D_RATE2M:
+                       rate_idx = 1;
+                       break;
+               case DESC92D_RATE5_5M:
+                       rate_idx = 2;
+                       break;
+               case DESC92D_RATE11M:
+                       rate_idx = 3;
+                       break;
+               case DESC92D_RATE6M:
+                       rate_idx = 4;
+                       break;
+               case DESC92D_RATE9M:
+                       rate_idx = 5;
+                       break;
+               case DESC92D_RATE12M:
+                       rate_idx = 6;
+                       break;
+               case DESC92D_RATE18M:
+                       rate_idx = 7;
+                       break;
+               case DESC92D_RATE24M:
+                       rate_idx = 8;
+                       break;
+               case DESC92D_RATE36M:
+                       rate_idx = 9;
+                       break;
+               case DESC92D_RATE48M:
+                       rate_idx = 10;
+                       break;
+               case DESC92D_RATE54M:
+                       rate_idx = 11;
+                       break;
+               default:
+                       rate_idx = 11;
+                       break;
+               }
+               return rate_idx;
+       }
+}
+
+static u8 _rtl92d_query_rxpwrpercentage(char antpower)
+{
+       if ((antpower <= -100) || (antpower >= 20))
+               return 0;
+       else if (antpower >= 0)
+               return 100;
+       else
+               return 100 + antpower;
+}
+
+static u8 _rtl92d_evm_db_to_percentage(char value)
+{
+       char ret_val = value;
+
+       if (ret_val >= 0)
+               ret_val = 0;
+       if (ret_val <= -33)
+               ret_val = -33;
+       ret_val = 0 - ret_val;
+       ret_val *= 3;
+       if (ret_val == 99)
+               ret_val = 100;
+       return ret_val;
+}
+
+static long _rtl92de_translate_todbm(struct ieee80211_hw *hw,
+                                    u8 signal_strength_index)
+{
+       long signal_power;
+
+       signal_power = (long)((signal_strength_index + 1) >> 1);
+       signal_power -= 95;
+       return signal_power;
+}
+
+static long _rtl92de_signal_scale_mapping(struct ieee80211_hw *hw, long currsig)
+{
+       long retsig;
+
+       if (currsig >= 61 && currsig <= 100)
+               retsig = 90 + ((currsig - 60) / 4);
+       else if (currsig >= 41 && currsig <= 60)
+               retsig = 78 + ((currsig - 40) / 2);
+       else if (currsig >= 31 && currsig <= 40)
+               retsig = 66 + (currsig - 30);
+       else if (currsig >= 21 && currsig <= 30)
+               retsig = 54 + (currsig - 20);
+       else if (currsig >= 5 && currsig <= 20)
+               retsig = 42 + (((currsig - 5) * 2) / 3);
+       else if (currsig == 4)
+               retsig = 36;
+       else if (currsig == 3)
+               retsig = 27;
+       else if (currsig == 2)
+               retsig = 18;
+       else if (currsig == 1)
+               retsig = 9;
+       else
+               retsig = currsig;
+       return retsig;
+}
+
+static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw,
+                                      struct rtl_stats *pstats,
+                                      struct rx_desc_92d *pdesc,
+                                      struct rx_fwinfo_92d *p_drvinfo,
+                                      bool packet_match_bssid,
+                                      bool packet_toself,
+                                      bool packet_beacon)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
+       struct phy_sts_cck_8192d *cck_buf;
+       s8 rx_pwr_all, rx_pwr[4];
+       u8 rf_rx_num = 0, evm, pwdb_all;
+       u8 i, max_spatial_stream;
+       u32 rssi, total_rssi = 0;
+       bool is_cck_rate;
+
+       is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
+       pstats->packet_matchbssid = packet_match_bssid;
+       pstats->packet_toself = packet_toself;
+       pstats->packet_beacon = packet_beacon;
+       pstats->is_cck = is_cck_rate;
+       pstats->rx_mimo_signalquality[0] = -1;
+       pstats->rx_mimo_signalquality[1] = -1;
+
+       if (is_cck_rate) {
+               u8 report, cck_highpwr;
+               cck_buf = (struct phy_sts_cck_8192d *)p_drvinfo;
+               if (ppsc->rfpwr_state == ERFON)
+                       cck_highpwr = (u8) rtl_get_bbreg(hw,
+                                                RFPGA0_XA_HSSIPARAMETER2,
+                                                BIT(9));
+               else
+                       cck_highpwr = false;
+               if (!cck_highpwr) {
+                       u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
+                       report = cck_buf->cck_agc_rpt & 0xc0;
+                       report = report >> 6;
+                       switch (report) {
+                       case 0x3:
+                               rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
+                               break;
+                       case 0x2:
+                               rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
+                               break;
+                       case 0x1:
+                               rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
+                               break;
+                       case 0x0:
+                               rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
+                               break;
+                       }
+               } else {
+                       u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
+                       report = p_drvinfo->cfosho[0] & 0x60;
+                       report = report >> 5;
+                       switch (report) {
+                       case 0x3:
+                               rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1);
+                               break;
+                       case 0x2:
+                               rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1);
+                               break;
+                       case 0x1:
+                               rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1);
+                               break;
+                       case 0x0:
+                               rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1);
+                               break;
+                       }
+               }
+               pwdb_all = _rtl92d_query_rxpwrpercentage(rx_pwr_all);
+               /* CCK gain is smaller than OFDM/MCS gain,  */
+               /* so we add gain diff by experiences, the val is 6 */
+               pwdb_all += 6;
+               if (pwdb_all > 100)
+                       pwdb_all = 100;
+               /* modify the offset to make the same gain index with OFDM. */
+               if (pwdb_all > 34 && pwdb_all <= 42)
+                       pwdb_all -= 2;
+               else if (pwdb_all > 26 && pwdb_all <= 34)
+                       pwdb_all -= 6;
+               else if (pwdb_all > 14 && pwdb_all <= 26)
+                       pwdb_all -= 8;
+               else if (pwdb_all > 4 && pwdb_all <= 14)
+                       pwdb_all -= 4;
+               pstats->rx_pwdb_all = pwdb_all;
+               pstats->recvsignalpower = rx_pwr_all;
+               if (packet_match_bssid) {
+                       u8 sq;
+                       if (pstats->rx_pwdb_all > 40) {
+                               sq = 100;
+                       } else {
+                               sq = cck_buf->sq_rpt;
+                               if (sq > 64)
+                                       sq = 0;
+                               else if (sq < 20)
+                                       sq = 100;
+                               else
+                                       sq = ((64 - sq) * 100) / 44;
+                       }
+                       pstats->signalquality = sq;
+                       pstats->rx_mimo_signalquality[0] = sq;
+                       pstats->rx_mimo_signalquality[1] = -1;
+               }
+       } else {
+               rtlpriv->dm.rfpath_rxenable[0] = true;
+               rtlpriv->dm.rfpath_rxenable[1] = true;
+               for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) {
+                       if (rtlpriv->dm.rfpath_rxenable[i])
+                               rf_rx_num++;
+                       rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f) * 2)
+                                   - 110;
+                       rssi = _rtl92d_query_rxpwrpercentage(rx_pwr[i]);
+                       total_rssi += rssi;
+                       rtlpriv->stats.rx_snr_db[i] =
+                                        (long)(p_drvinfo->rxsnr[i] / 2);
+                       if (packet_match_bssid)
+                               pstats->rx_mimo_signalstrength[i] = (u8) rssi;
+               }
+               rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 106;
+               pwdb_all = _rtl92d_query_rxpwrpercentage(rx_pwr_all);
+               pstats->rx_pwdb_all = pwdb_all;
+               pstats->rxpower = rx_pwr_all;
+               pstats->recvsignalpower = rx_pwr_all;
+               if (pdesc->rxht && pdesc->rxmcs >= DESC92D_RATEMCS8 &&
+                   pdesc->rxmcs <= DESC92D_RATEMCS15)
+                       max_spatial_stream = 2;
+               else
+                       max_spatial_stream = 1;
+               for (i = 0; i < max_spatial_stream; i++) {
+                       evm = _rtl92d_evm_db_to_percentage(p_drvinfo->rxevm[i]);
+                       if (packet_match_bssid) {
+                               if (i == 0)
+                                       pstats->signalquality =
+                                                (u8)(evm & 0xff);
+                               pstats->rx_mimo_signalquality[i] =
+                                                (u8)(evm & 0xff);
+                       }
+               }
+       }
+       if (is_cck_rate)
+               pstats->signalstrength = (u8)(_rtl92de_signal_scale_mapping(hw,
+                               pwdb_all));
+       else if (rf_rx_num != 0)
+               pstats->signalstrength = (u8)(_rtl92de_signal_scale_mapping(hw,
+                               total_rssi /= rf_rx_num));
+}
+
+static void rtl92d_loop_over_paths(struct ieee80211_hw *hw,
+                                  struct rtl_stats *pstats)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_phy *rtlphy = &(rtlpriv->phy);
+       u8 rfpath;
+
+       for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
+            rfpath++) {
+               if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
+                       rtlpriv->stats.rx_rssi_percentage[rfpath] =
+                           pstats->rx_mimo_signalstrength[rfpath];
+
+               }
+               if (pstats->rx_mimo_signalstrength[rfpath] >
+                   rtlpriv->stats.rx_rssi_percentage[rfpath]) {
+                       rtlpriv->stats.rx_rssi_percentage[rfpath] =
+                           ((rtlpriv->stats.rx_rssi_percentage[rfpath] *
+                             (RX_SMOOTH_FACTOR - 1)) +
+                            (pstats->rx_mimo_signalstrength[rfpath])) /
+                           (RX_SMOOTH_FACTOR);
+                       rtlpriv->stats.rx_rssi_percentage[rfpath] =
+                           rtlpriv->stats.rx_rssi_percentage[rfpath] + 1;
+               } else {
+                       rtlpriv->stats.rx_rssi_percentage[rfpath] =
+                           ((rtlpriv->stats.rx_rssi_percentage[rfpath] *
+                             (RX_SMOOTH_FACTOR - 1)) +
+                            (pstats->rx_mimo_signalstrength[rfpath])) /
+                           (RX_SMOOTH_FACTOR);
+               }
+       }
+}
+
+static void _rtl92de_process_ui_rssi(struct ieee80211_hw *hw,
+                                    struct rtl_stats *pstats)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 last_rssi, tmpval;
+
+       if (pstats->packet_toself || pstats->packet_beacon) {
+               rtlpriv->stats.rssi_calculate_cnt++;
+               if (rtlpriv->stats.ui_rssi.total_num++ >=
+                   PHY_RSSI_SLID_WIN_MAX) {
+                       rtlpriv->stats.ui_rssi.total_num =
+                                                PHY_RSSI_SLID_WIN_MAX;
+                       last_rssi = rtlpriv->stats.ui_rssi.elements[
+                               rtlpriv->stats.ui_rssi.index];
+                       rtlpriv->stats.ui_rssi.total_val -= last_rssi;
+               }
+               rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
+               rtlpriv->stats.ui_rssi.elements
+                       [rtlpriv->stats.ui_rssi.index++] =
+                       pstats->signalstrength;
+               if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
+                       rtlpriv->stats.ui_rssi.index = 0;
+               tmpval = rtlpriv->stats.ui_rssi.total_val /
+                       rtlpriv->stats.ui_rssi.total_num;
+               rtlpriv->stats.signal_strength = _rtl92de_translate_todbm(hw,
+                       (u8) tmpval);
+               pstats->rssi = rtlpriv->stats.signal_strength;
+       }
+       if (!pstats->is_cck && pstats->packet_toself)
+               rtl92d_loop_over_paths(hw, pstats);
+}
+
+static void _rtl92de_update_rxsignalstatistics(struct ieee80211_hw *hw,
+                                              struct rtl_stats *pstats)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int weighting = 0;
+
+       if (rtlpriv->stats.recv_signal_power == 0)
+               rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
+       if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
+               weighting = 5;
+       else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
+               weighting = (-5);
+       rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power *
+               5 + pstats->recvsignalpower + weighting) / 6;
+}
+
+static void _rtl92de_process_pwdb(struct ieee80211_hw *hw,
+                                 struct rtl_stats *pstats)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       long undecorated_smoothed_pwdb;
+
+       if (mac->opmode == NL80211_IFTYPE_ADHOC ||
+               mac->opmode == NL80211_IFTYPE_AP)
+               return;
+       else
+               undecorated_smoothed_pwdb =
+                   rtlpriv->dm.undecorated_smoothed_pwdb;
+
+       if (pstats->packet_toself || pstats->packet_beacon) {
+               if (undecorated_smoothed_pwdb < 0)
+                       undecorated_smoothed_pwdb = pstats->rx_pwdb_all;
+               if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) {
+                       undecorated_smoothed_pwdb =
+                             (((undecorated_smoothed_pwdb) *
+                             (RX_SMOOTH_FACTOR - 1)) +
+                             (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
+                       undecorated_smoothed_pwdb =
+                             undecorated_smoothed_pwdb + 1;
+               } else {
+                       undecorated_smoothed_pwdb =
+                             (((undecorated_smoothed_pwdb) *
+                             (RX_SMOOTH_FACTOR - 1)) +
+                             (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
+               }
+               rtlpriv->dm.undecorated_smoothed_pwdb =
+                                undecorated_smoothed_pwdb;
+               _rtl92de_update_rxsignalstatistics(hw, pstats);
+       }
+}
+
+static void rtl92d_loop_over_streams(struct ieee80211_hw *hw,
+                                    struct rtl_stats *pstats)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       int stream;
+
+       for (stream = 0; stream < 2; stream++) {
+               if (pstats->rx_mimo_signalquality[stream] != -1) {
+                       if (rtlpriv->stats.rx_evm_percentage[stream] == 0) {
+                               rtlpriv->stats.rx_evm_percentage[stream] =
+                                   pstats->rx_mimo_signalquality[stream];
+                       }
+                       rtlpriv->stats.rx_evm_percentage[stream] =
+                           ((rtlpriv->stats.rx_evm_percentage[stream]
+                             * (RX_SMOOTH_FACTOR - 1)) +
+                            (pstats->rx_mimo_signalquality[stream] * 1)) /
+                           (RX_SMOOTH_FACTOR);
+               }
+       }
+}
+
+static void _rtl92de_process_ui_link_quality(struct ieee80211_hw *hw,
+                                            struct rtl_stats *pstats)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u32 last_evm, tmpval;
+
+       if (pstats->signalquality == 0)
+               return;
+       if (pstats->packet_toself || pstats->packet_beacon) {
+               if (rtlpriv->stats.ui_link_quality.total_num++ >=
+                   PHY_LINKQUALITY_SLID_WIN_MAX) {
+                       rtlpriv->stats.ui_link_quality.total_num =
+                           PHY_LINKQUALITY_SLID_WIN_MAX;
+                       last_evm = rtlpriv->stats.ui_link_quality.elements[
+                               rtlpriv->stats.ui_link_quality.index];
+                       rtlpriv->stats.ui_link_quality.total_val -= last_evm;
+               }
+               rtlpriv->stats.ui_link_quality.total_val +=
+                                                pstats->signalquality;
+               rtlpriv->stats.ui_link_quality.elements[
+                       rtlpriv->stats.ui_link_quality.index++] =
+                                                pstats->signalquality;
+               if (rtlpriv->stats.ui_link_quality.index >=
+                   PHY_LINKQUALITY_SLID_WIN_MAX)
+                       rtlpriv->stats.ui_link_quality.index = 0;
+               tmpval = rtlpriv->stats.ui_link_quality.total_val /
+                   rtlpriv->stats.ui_link_quality.total_num;
+               rtlpriv->stats.signal_quality = tmpval;
+               rtlpriv->stats.last_sigstrength_inpercent = tmpval;
+               rtl92d_loop_over_streams(hw, pstats);
+       }
+}
+
+static void _rtl92de_process_phyinfo(struct ieee80211_hw *hw,
+                                    u8 *buffer,
+                                    struct rtl_stats *pcurrent_stats)
+{
+
+       if (!pcurrent_stats->packet_matchbssid &&
+           !pcurrent_stats->packet_beacon)
+               return;
+
+       _rtl92de_process_ui_rssi(hw, pcurrent_stats);
+       _rtl92de_process_pwdb(hw, pcurrent_stats);
+       _rtl92de_process_ui_link_quality(hw, pcurrent_stats);
+}
+
+static void _rtl92de_translate_rx_signal_stuff(struct ieee80211_hw *hw,
+                                              struct sk_buff *skb,
+                                              struct rtl_stats *pstats,
+                                              struct rx_desc_92d *pdesc,
+                                              struct rx_fwinfo_92d *p_drvinfo)
+{
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+       struct ieee80211_hdr *hdr;
+       u8 *tmp_buf;
+       u8 *praddr;
+       u16 type, cfc;
+       __le16 fc;
+       bool packet_matchbssid, packet_toself, packet_beacon;
+
+       tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
+       hdr = (struct ieee80211_hdr *)tmp_buf;
+       fc = hdr->frame_control;
+       cfc = le16_to_cpu(fc);
+       type = WLAN_FC_GET_TYPE(fc);
+       praddr = hdr->addr1;
+       packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
+            (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ?
+                 hdr->addr1 : (cfc & IEEE80211_FCTL_FROMDS) ?
+                 hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) &&
+                 (!pstats->crc) && (!pstats->icv));
+       packet_toself = packet_matchbssid &&
+                       (!compare_ether_addr(praddr, rtlefuse->dev_addr));
+       if (ieee80211_is_beacon(fc))
+               packet_beacon = true;
+       _rtl92de_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
+                                  packet_matchbssid, packet_toself,
+                                  packet_beacon);
+       _rtl92de_process_phyinfo(hw, tmp_buf, pstats);
+}
+
+bool rtl92de_rx_query_desc(struct ieee80211_hw *hw,    struct rtl_stats *stats,
+               struct ieee80211_rx_status *rx_status,
+               u8 *p_desc, struct sk_buff *skb)
+{
+       struct rx_fwinfo_92d *p_drvinfo;
+       struct rx_desc_92d *pdesc = (struct rx_desc_92d *)p_desc;
+       u32 phystatus = GET_RX_DESC_PHYST(pdesc);
+
+       stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
+       stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
+                                RX_DRV_INFO_SIZE_UNIT;
+       stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
+       stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
+       stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
+       stats->hwerror = (stats->crc | stats->icv);
+       stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
+       stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
+       stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
+       stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
+       stats->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
+                                        && (GET_RX_DESC_FAGGR(pdesc) == 1));
+       stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
+       stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
+       rx_status->freq = hw->conf.channel->center_freq;
+       rx_status->band = hw->conf.channel->band;
+       if (GET_RX_DESC_CRC32(pdesc))
+               rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+       if (!GET_RX_DESC_SWDEC(pdesc))
+               rx_status->flag |= RX_FLAG_DECRYPTED;
+       if (GET_RX_DESC_BW(pdesc))
+               rx_status->flag |= RX_FLAG_40MHZ;
+       if (GET_RX_DESC_RXHT(pdesc))
+               rx_status->flag |= RX_FLAG_HT;
+       rx_status->flag |= RX_FLAG_MACTIME_MPDU;
+       if (stats->decrypted)
+               rx_status->flag |= RX_FLAG_DECRYPTED;
+       rx_status->rate_idx = _rtl92de_rate_mapping((bool)
+                                                   GET_RX_DESC_RXHT(pdesc),
+                                                   (u8)
+                                                   GET_RX_DESC_RXMCS(pdesc));
+       rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
+       if (phystatus == true) {
+               p_drvinfo = (struct rx_fwinfo_92d *)(skb->data +
+                                                    stats->rx_bufshift);
+               _rtl92de_translate_rx_signal_stuff(hw,
+                                                  skb, stats, pdesc,
+                                                  p_drvinfo);
+       }
+       /*rx_status->qual = stats->signal; */
+       rx_status->signal = stats->rssi + 10;
+       /*rx_status->noise = -stats->noise; */
+       return true;
+}
+
+static void _rtl92de_insert_emcontent(struct rtl_tcb_desc *ptcb_desc,
+                                     u8 *virtualaddress)
+{
+       memset(virtualaddress, 0, 8);
+
+       SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num);
+       SET_EARLYMODE_LEN0(virtualaddress, ptcb_desc->empkt_len[0]);
+       SET_EARLYMODE_LEN1(virtualaddress, ptcb_desc->empkt_len[1]);
+       SET_EARLYMODE_LEN2_1(virtualaddress, ptcb_desc->empkt_len[2] & 0xF);
+       SET_EARLYMODE_LEN2_2(virtualaddress, ptcb_desc->empkt_len[2] >> 4);
+       SET_EARLYMODE_LEN3(virtualaddress, ptcb_desc->empkt_len[3]);
+       SET_EARLYMODE_LEN4(virtualaddress, ptcb_desc->empkt_len[4]);
+}
+
+void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
+                         struct ieee80211_hdr *hdr, u8 *pdesc_tx,
+                         struct ieee80211_tx_info *info, struct sk_buff *skb,
+                         u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+       struct ieee80211_sta *sta = info->control.sta;
+       u8 *pdesc = (u8 *) pdesc_tx;
+       u16 seq_number;
+       __le16 fc = hdr->frame_control;
+       unsigned int buf_len = 0;
+       unsigned int skb_len = skb->len;
+       u8 fw_qsel = _rtl92de_map_hwqueue_to_fwqueue(skb, hw_queue);
+       bool firstseg = ((hdr->seq_ctrl &
+                       cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
+       bool lastseg = ((hdr->frame_control &
+                       cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
+       dma_addr_t mapping;
+       u8 bw_40 = 0;
+
+       if (mac->opmode == NL80211_IFTYPE_STATION) {
+               bw_40 = mac->bw_40;
+       } else if (mac->opmode == NL80211_IFTYPE_AP ||
+               mac->opmode == NL80211_IFTYPE_ADHOC) {
+               if (sta)
+                       bw_40 = sta->ht_cap.cap &
+                               IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+       }
+       seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
+       rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
+       /* reserve 8 byte for AMPDU early mode */
+       if (rtlhal->earlymode_enable) {
+               skb_push(skb, EM_HDR_LEN);
+               memset(skb->data, 0, EM_HDR_LEN);
+       }
+       buf_len = skb->len;
+       mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
+                                PCI_DMA_TODEVICE);
+       CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92d));
+       if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
+               firstseg = true;
+               lastseg = true;
+       }
+       if (firstseg) {
+               if (rtlhal->earlymode_enable) {
+                       SET_TX_DESC_PKT_OFFSET(pdesc, 1);
+                       SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN +
+                                          EM_HDR_LEN);
+                       if (ptcb_desc->empkt_num) {
+                               RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD,
+                                        ("Insert 8 byte.pTcb->EMPktNum:%d\n",
+                                         ptcb_desc->empkt_num));
+                               _rtl92de_insert_emcontent(ptcb_desc,
+                                                         (u8 *)(skb->data));
+                       }
+               } else {
+                       SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
+               }
+               /* 5G have no CCK rate */
+               if (rtlhal->current_bandtype == BAND_ON_5G)
+                       if (ptcb_desc->hw_rate < DESC92D_RATE6M)
+                               ptcb_desc->hw_rate = DESC92D_RATE6M;
+               SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
+               if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
+                       SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
+
+               if (rtlhal->macphymode == DUALMAC_DUALPHY &&
+                       ptcb_desc->hw_rate == DESC92D_RATEMCS7)
+                       SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
+
+               if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+                       SET_TX_DESC_AGG_ENABLE(pdesc, 1);
+                       SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
+               }
+               SET_TX_DESC_SEQ(pdesc, seq_number);
+               SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
+                                      !ptcb_desc->cts_enable) ? 1 : 0));
+               SET_TX_DESC_HW_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable
+                                         || ptcb_desc->cts_enable) ? 1 : 0));
+               SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0));
+               SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
+               /* 5G have no CCK rate */
+               if (rtlhal->current_bandtype == BAND_ON_5G)
+                       if (ptcb_desc->rts_rate < DESC92D_RATE6M)
+                               ptcb_desc->rts_rate = DESC92D_RATE6M;
+               SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
+               SET_TX_DESC_RTS_BW(pdesc, 0);
+               SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
+               SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
+                       DESC92D_RATE54M) ?
+                       (ptcb_desc->rts_use_shortpreamble ? 1 : 0) :
+                       (ptcb_desc->rts_use_shortgi ? 1 : 0)));
+               if (bw_40) {
+                       if (ptcb_desc->packet_bw) {
+                               SET_TX_DESC_DATA_BW(pdesc, 1);
+                               SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
+                       } else {
+                               SET_TX_DESC_DATA_BW(pdesc, 0);
+                               SET_TX_DESC_TX_SUB_CARRIER(pdesc,
+                                                       mac->cur_40_prime_sc);
+                       }
+               } else {
+                       SET_TX_DESC_DATA_BW(pdesc, 0);
+                       SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
+               }
+               SET_TX_DESC_LINIP(pdesc, 0);
+               SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb_len);
+               if (sta) {
+                       u8 ampdu_density = sta->ht_cap.ampdu_density;
+                       SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
+               }
+               if (info->control.hw_key) {
+                       struct ieee80211_key_conf *keyconf;
+
+                       keyconf = info->control.hw_key;
+                       switch (keyconf->cipher) {
+                       case WLAN_CIPHER_SUITE_WEP40:
+                       case WLAN_CIPHER_SUITE_WEP104:
+                       case WLAN_CIPHER_SUITE_TKIP:
+                               SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
+                               break;
+                       case WLAN_CIPHER_SUITE_CCMP:
+                               SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
+                               break;
+                       default:
+                               SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
+                               break;
+
+                       }
+               }
+               SET_TX_DESC_PKT_ID(pdesc, 0);
+               SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
+               SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
+               SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
+               SET_TX_DESC_DISABLE_FB(pdesc, ptcb_desc->disable_ratefallback ?
+                                      1 : 0);
+               SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0);
+
+               /* Set TxRate and RTSRate in TxDesc  */
+               /* This prevent Tx initial rate of new-coming packets */
+               /* from being overwritten by retried  packet rate.*/
+               if (!ptcb_desc->use_driver_rate) {
+                       SET_TX_DESC_RTS_RATE(pdesc, 0x08);
+                       /* SET_TX_DESC_TX_RATE(pdesc, 0x0b); */
+               }
+               if (ieee80211_is_data_qos(fc)) {
+                       if (mac->rdg_en) {
+                               RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+                                       ("Enable RDG function.\n"));
+                               SET_TX_DESC_RDG_ENABLE(pdesc, 1);
+                               SET_TX_DESC_HTC(pdesc, 1);
+                       }
+               }
+       }
+
+       SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
+       SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
+       SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) buf_len);
+       SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
+       if (rtlpriv->dm.useramask) {
+               SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index);
+               SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
+       } else {
+               SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index);
+               SET_TX_DESC_MACID(pdesc, ptcb_desc->ratr_index);
+       }
+       if (ieee80211_is_data_qos(fc))
+               SET_TX_DESC_QOS(pdesc, 1);
+
+       if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
+               SET_TX_DESC_HWSEQ_EN(pdesc, 1);
+               SET_TX_DESC_PKT_ID(pdesc, 8);
+       }
+       SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
+       RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
+}
+
+void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
+                            u8 *pdesc, bool firstseg,
+                            bool lastseg, struct sk_buff *skb)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+       struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
+       struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+       u8 fw_queue = QSLT_BEACON;
+       dma_addr_t mapping = pci_map_single(rtlpci->pdev,
+                   skb->data, skb->len, PCI_DMA_TODEVICE);
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
+       __le16 fc = hdr->frame_control;
+
+       CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
+       if (firstseg)
+               SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
+       /* 5G have no CCK rate
+        * Caution: The macros below are multi-line expansions.
+        * The braces are needed no matter what checkpatch says
+        */
+       if (rtlhal->current_bandtype == BAND_ON_5G) {
+               SET_TX_DESC_TX_RATE(pdesc, DESC92D_RATE6M);
+       } else {
+               SET_TX_DESC_TX_RATE(pdesc, DESC92D_RATE1M);
+       }
+       SET_TX_DESC_SEQ(pdesc, 0);
+       SET_TX_DESC_LINIP(pdesc, 0);
+       SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
+       SET_TX_DESC_FIRST_SEG(pdesc, 1);
+       SET_TX_DESC_LAST_SEG(pdesc, 1);
+       SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
+       SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
+       SET_TX_DESC_RATE_ID(pdesc, 7);
+       SET_TX_DESC_MACID(pdesc, 0);
+       SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
+       SET_TX_DESC_FIRST_SEG(pdesc, 1);
+       SET_TX_DESC_LAST_SEG(pdesc, 1);
+       SET_TX_DESC_OFFSET(pdesc, 0x20);
+       SET_TX_DESC_USE_RATE(pdesc, 1);
+
+       if (!ieee80211_is_data_qos(fc) && ppsc->fwctrl_lps) {
+               SET_TX_DESC_HWSEQ_EN(pdesc, 1);
+               SET_TX_DESC_PKT_ID(pdesc, 8);
+       }
+
+       RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
+                     "H2C Tx Cmd Content\n", pdesc, TX_DESC_SIZE);
+       wmb();
+       SET_TX_DESC_OWN(pdesc, 1);
+}
+
+void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
+{
+       if (istx == true) {
+               switch (desc_name) {
+               case HW_DESC_OWN:
+                       wmb();
+                       SET_TX_DESC_OWN(pdesc, 1);
+                       break;
+               case HW_DESC_TX_NEXTDESC_ADDR:
+                       SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
+                       break;
+               default:
+                       RT_ASSERT(false, ("ERR txdesc :%d"
+                                         " not process\n", desc_name));
+                       break;
+               }
+       } else {
+               switch (desc_name) {
+               case HW_DESC_RXOWN:
+                       wmb();
+                       SET_RX_DESC_OWN(pdesc, 1);
+                       break;
+               case HW_DESC_RXBUFF_ADDR:
+                       SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val);
+                       break;
+               case HW_DESC_RXPKT_LEN:
+                       SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val);
+                       break;
+               case HW_DESC_RXERO:
+                       SET_RX_DESC_EOR(pdesc, 1);
+                       break;
+               default:
+                       RT_ASSERT(false, ("ERR rxdesc :%d "
+                                         "not process\n", desc_name));
+                       break;
+               }
+       }
+}
+
+u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name)
+{
+       u32 ret = 0;
+
+       if (istx == true) {
+               switch (desc_name) {
+               case HW_DESC_OWN:
+                       ret = GET_TX_DESC_OWN(p_desc);
+                       break;
+               case HW_DESC_TXBUFF_ADDR:
+                       ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
+                       break;
+               default:
+                       RT_ASSERT(false, ("ERR txdesc :%d "
+                                         "not process\n", desc_name));
+                       break;
+               }
+       } else {
+               struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
+               switch (desc_name) {
+               case HW_DESC_OWN:
+                       ret = GET_RX_DESC_OWN(pdesc);
+                       break;
+               case HW_DESC_RXPKT_LEN:
+                       ret = GET_RX_DESC_PKT_LEN(pdesc);
+                       break;
+               default:
+                       RT_ASSERT(false, ("ERR rxdesc :%d "
+                                         "not process\n", desc_name));
+                       break;
+               }
+       }
+       return ret;
+}
+
+void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       if (hw_queue == BEACON_QUEUE)
+               rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4));
+       else
+               rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG,
+                              BIT(0) << (hw_queue));
+}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h
new file mode 100644 (file)
index 0000000..992d676
--- /dev/null
@@ -0,0 +1,756 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL92DE_TRX_H__
+#define __RTL92DE_TRX_H__
+
+#define TX_DESC_SIZE                           64
+#define TX_DESC_AGGR_SUBFRAME_SIZE             32
+
+#define RX_DESC_SIZE                           32
+#define RX_DRV_INFO_SIZE_UNIT                  8
+
+#define        TX_DESC_NEXT_DESC_OFFSET                40
+#define USB_HWDESC_HEADER_LEN                  32
+#define CRCLENGTH                              4
+
+/* Define a macro that takes a le32 word, converts it to host ordering,
+ * right shifts by a specified count, creates a mask of the specified
+ * bit count, and extracts that number of bits.
+ */
+
+#define SHIFT_AND_MASK_LE(__pdesc, __shift, __mask)            \
+       ((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \
+       BIT_LEN_MASK_32(__mask))
+
+/* Define a macro that clears a bit field in an le32 word and
+ * sets the specified value into that bit field. The resulting
+ * value remains in le32 ordering; however, it is properly converted
+ * to host ordering for the clear and set operations before conversion
+ * back to le32.
+ */
+
+#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val)     \
+       (*(__le32 *)(__pdesc) =                                 \
+       (cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) &     \
+       (~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) |                \
+       (((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift)))));
+
+/* macros to read/write various fields in RX or TX descriptors */
+
+#define SET_TX_DESC_PKT_SIZE(__pdesc, __val)           \
+       SET_BITS_OFFSET_LE(__pdesc, 0, 16, __val)
+#define SET_TX_DESC_OFFSET(__pdesc, __val)             \
+       SET_BITS_OFFSET_LE(__pdesc, 16, 8, __val)
+#define SET_TX_DESC_BMC(__pdesc, __val)                        \
+       SET_BITS_OFFSET_LE(__pdesc, 24, 1, __val)
+#define SET_TX_DESC_HTC(__pdesc, __val)                        \
+       SET_BITS_OFFSET_LE(__pdesc, 25, 1, __val)
+#define SET_TX_DESC_LAST_SEG(__pdesc, __val)           \
+       SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val)
+#define SET_TX_DESC_FIRST_SEG(__pdesc, __val)          \
+       SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val)
+#define SET_TX_DESC_LINIP(__pdesc, __val)              \
+       SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val)
+#define SET_TX_DESC_NO_ACM(__pdesc, __val)             \
+       SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val)
+#define SET_TX_DESC_GF(__pdesc, __val)                 \
+       SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val)
+#define SET_TX_DESC_OWN(__pdesc, __val)                        \
+       SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val)
+
+#define GET_TX_DESC_PKT_SIZE(__pdesc)                  \
+       SHIFT_AND_MASK_LE(__pdesc, 0, 16)
+#define GET_TX_DESC_OFFSET(__pdesc)                    \
+       SHIFT_AND_MASK_LE(__pdesc, 16, 8)
+#define GET_TX_DESC_BMC(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc, 24, 1)
+#define GET_TX_DESC_HTC(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc, 25, 1)
+#define GET_TX_DESC_LAST_SEG(__pdesc)                  \
+       SHIFT_AND_MASK_LE(__pdesc, 26, 1)
+#define GET_TX_DESC_FIRST_SEG(__pdesc)                 \
+       SHIFT_AND_MASK_LE(__pdesc, 27, 1)
+#define GET_TX_DESC_LINIP(__pdesc)                     \
+       SHIFT_AND_MASK_LE(__pdesc, 28, 1)
+#define GET_TX_DESC_NO_ACM(__pdesc)                    \
+       SHIFT_AND_MASK_LE(__pdesc, 29, 1)
+#define GET_TX_DESC_GF(__pdesc)                                \
+       SHIFT_AND_MASK_LE(__pdesc, 30, 1)
+#define GET_TX_DESC_OWN(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc, 31, 1)
+
+#define SET_TX_DESC_MACID(__pdesc, __val)              \
+       SET_BITS_OFFSET_LE(__pdesc+4, 0, 5, __val)
+#define SET_TX_DESC_AGG_ENABLE(__pdesc, __val)         \
+       SET_BITS_OFFSET_LE(__pdesc+4, 5, 1, __val)
+#define SET_TX_DESC_BK(__pdesc, __val)                 \
+       SET_BITS_OFFSET_LE(__pdesc+4, 6, 1, __val)
+#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val)         \
+       SET_BITS_OFFSET_LE(__pdesc+4, 7, 1, __val)
+#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val)          \
+       SET_BITS_OFFSET_LE(__pdesc+4, 8, 5, __val)
+#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val)                \
+       SET_BITS_OFFSET_LE(__pdesc+4, 13, 1, __val)
+#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val)       \
+       SET_BITS_OFFSET_LE(__pdesc+4, 14, 1, __val)
+#define SET_TX_DESC_PIFS(__pdesc, __val)               \
+       SET_BITS_OFFSET_LE(__pdesc+4, 15, 1, __val)
+#define SET_TX_DESC_RATE_ID(__pdesc, __val)            \
+       SET_BITS_OFFSET_LE(__pdesc+4, 16, 4, __val)
+#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val)                \
+       SET_BITS_OFFSET_LE(__pdesc+4, 20, 1, __val)
+#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val)         \
+       SET_BITS_OFFSET_LE(__pdesc+4, 21, 1, __val)
+#define SET_TX_DESC_SEC_TYPE(__pdesc, __val)           \
+       SET_BITS_OFFSET_LE(__pdesc+4, 22, 2, __val)
+#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val)         \
+       SET_BITS_OFFSET_LE(__pdesc+4, 26, 8, __val)
+
+#define GET_TX_DESC_MACID(__pdesc)                                     \
+       SHIFT_AND_MASK_LE(__pdesc+4, 0, 5)
+#define GET_TX_DESC_AGG_ENABLE(__pdesc)                        \
+       SHIFT_AND_MASK_LE(__pdesc+4, 5, 1)
+#define GET_TX_DESC_AGG_BREAK(__pdesc)                 \
+       SHIFT_AND_MASK_LE(__pdesc+4, 6, 1)
+#define GET_TX_DESC_RDG_ENABLE(__pdesc)                        \
+       SHIFT_AND_MASK_LE(__pdesc+4, 7, 1)
+#define GET_TX_DESC_QUEUE_SEL(__pdesc)                 \
+       SHIFT_AND_MASK_LE(__pdesc+4, 8, 5)
+#define GET_TX_DESC_RDG_NAV_EXT(__pdesc)               \
+       SHIFT_AND_MASK_LE(__pdesc+4, 13, 1)
+#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc)              \
+       SHIFT_AND_MASK_LE(__pdesc+4, 14, 1)
+#define GET_TX_DESC_PIFS(__pdesc)                      \
+       SHIFT_AND_MASK_LE(__pdesc+4, 15, 1)
+#define GET_TX_DESC_RATE_ID(__pdesc)                   \
+       SHIFT_AND_MASK_LE(__pdesc+4, 16, 4)
+#define GET_TX_DESC_NAV_USE_HDR(__pdesc)               \
+       SHIFT_AND_MASK_LE(__pdesc+4, 20, 1)
+#define GET_TX_DESC_EN_DESC_ID(__pdesc)                        \
+       SHIFT_AND_MASK_LE(__pdesc+4, 21, 1)
+#define GET_TX_DESC_SEC_TYPE(__pdesc)                  \
+       SHIFT_AND_MASK_LE(__pdesc+4, 22, 2)
+#define GET_TX_DESC_PKT_OFFSET(__pdesc)                        \
+       SHIFT_AND_MASK_LE(__pdesc+4, 24, 8)
+
+#define SET_TX_DESC_RTS_RC(__pdesc, __val)             \
+       SET_BITS_OFFSET_LE(__pdesc+8, 0, 6, __val)
+#define SET_TX_DESC_DATA_RC(__pdesc, __val)            \
+       SET_BITS_OFFSET_LE(__pdesc+8, 6, 6, __val)
+#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val)         \
+       SET_BITS_OFFSET_LE(__pdesc+8, 14, 2, __val)
+#define SET_TX_DESC_MORE_FRAG(__pdesc, __val)          \
+       SET_BITS_OFFSET_LE(__pdesc+8, 17, 1, __val)
+#define SET_TX_DESC_RAW(__pdesc, __val)                        \
+       SET_BITS_OFFSET_LE(__pdesc+8, 18, 1, __val)
+#define SET_TX_DESC_CCX(__pdesc, __val)                        \
+       SET_BITS_OFFSET_LE(__pdesc+8, 19, 1, __val)
+#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val)      \
+       SET_BITS_OFFSET_LE(__pdesc+8, 20, 3, __val)
+#define SET_TX_DESC_ANTSEL_A(__pdesc, __val)           \
+       SET_BITS_OFFSET_LE(__pdesc+8, 24, 1, __val)
+#define SET_TX_DESC_ANTSEL_B(__pdesc, __val)           \
+       SET_BITS_OFFSET_LE(__pdesc+8, 25, 1, __val)
+#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val)         \
+       SET_BITS_OFFSET_LE(__pdesc+8, 26, 2, __val)
+#define SET_TX_DESC_TX_ANTL(__pdesc, __val)            \
+       SET_BITS_OFFSET_LE(__pdesc+8, 28, 2, __val)
+#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val)          \
+       SET_BITS_OFFSET_LE(__pdesc+8, 30, 2, __val)
+
+#define GET_TX_DESC_RTS_RC(__pdesc)                    \
+       SHIFT_AND_MASK_LE(__pdesc+8, 0, 6)
+#define GET_TX_DESC_DATA_RC(__pdesc)                   \
+       SHIFT_AND_MASK_LE(__pdesc+8, 6, 6)
+#define GET_TX_DESC_BAR_RTY_TH(__pdesc)                        \
+       SHIFT_AND_MASK_LE(__pdesc+8, 14, 2)
+#define GET_TX_DESC_MORE_FRAG(__pdesc)                 \
+       SHIFT_AND_MASK_LE(__pdesc+8, 17, 1)
+#define GET_TX_DESC_RAW(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc+8, 18, 1)
+#define GET_TX_DESC_CCX(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc+8, 19, 1)
+#define GET_TX_DESC_AMPDU_DENSITY(__pdesc)             \
+       SHIFT_AND_MASK_LE(__pdesc+8, 20, 3)
+#define GET_TX_DESC_ANTSEL_A(__pdesc)                  \
+       SHIFT_AND_MASK_LE(__pdesc+8, 24, 1)
+#define GET_TX_DESC_ANTSEL_B(__pdesc)                  \
+       SHIFT_AND_MASK_LE(__pdesc+8, 25, 1)
+#define GET_TX_DESC_TX_ANT_CCK(__pdesc)                        \
+       SHIFT_AND_MASK_LE(__pdesc+8, 26, 2)
+#define GET_TX_DESC_TX_ANTL(__pdesc)                   \
+       SHIFT_AND_MASK_LE(__pdesc+8, 28, 2)
+#define GET_TX_DESC_TX_ANT_HT(__pdesc)                 \
+       SHIFT_AND_MASK_LE(__pdesc+8, 30, 2)
+
+#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val)     \
+       SET_BITS_OFFSET_LE(__pdesc+12, 0, 8, __val)
+#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val)          \
+       SET_BITS_OFFSET_LE(__pdesc+12, 8, 8, __val)
+#define SET_TX_DESC_SEQ(__pdesc, __val)                        \
+       SET_BITS_OFFSET_LE(__pdesc+12, 16, 12, __val)
+#define SET_TX_DESC_PKT_ID(__pdesc, __val)             \
+       SET_BITS_OFFSET_LE(__pdesc+12, 28, 4, __val)
+
+#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc)            \
+       SHIFT_AND_MASK_LE(__pdesc+12, 0, 8)
+#define GET_TX_DESC_TAIL_PAGE(__pdesc)                 \
+       SHIFT_AND_MASK_LE(__pdesc+12, 8, 8)
+#define GET_TX_DESC_SEQ(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc+12, 16, 12)
+#define GET_TX_DESC_PKT_ID(__pdesc)                    \
+       SHIFT_AND_MASK_LE(__pdesc+12, 28, 4)
+
+#define SET_TX_DESC_RTS_RATE(__pdesc, __val)           \
+       SET_BITS_OFFSET_LE(__pdesc+16, 0, 5, __val)
+#define SET_TX_DESC_AP_DCFE(__pdesc, __val)            \
+       SET_BITS_OFFSET_LE(__pdesc+16, 5, 1, __val)
+#define SET_TX_DESC_QOS(__pdesc, __val)                        \
+       SET_BITS_OFFSET_LE(__pdesc+16, 6, 1, __val)
+#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val)           \
+       SET_BITS_OFFSET_LE(__pdesc+16, 7, 1, __val)
+#define SET_TX_DESC_USE_RATE(__pdesc, __val)           \
+       SET_BITS_OFFSET_LE(__pdesc+16, 8, 1, __val)
+#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val)     \
+       SET_BITS_OFFSET_LE(__pdesc+16, 9, 1, __val)
+#define SET_TX_DESC_DISABLE_FB(__pdesc, __val)         \
+       SET_BITS_OFFSET_LE(__pdesc+16, 10, 1, __val)
+#define SET_TX_DESC_CTS2SELF(__pdesc, __val)           \
+       SET_BITS_OFFSET_LE(__pdesc+16, 11, 1, __val)
+#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val)         \
+       SET_BITS_OFFSET_LE(__pdesc+16, 12, 1, __val)
+#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val)      \
+       SET_BITS_OFFSET_LE(__pdesc+16, 13, 1, __val)
+#define SET_TX_DESC_PORT_ID(__pdesc, __val)            \
+       SET_BITS_OFFSET_LE(__pdesc+16, 14, 1, __val)
+#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val)          \
+       SET_BITS_OFFSET_LE(__pdesc+16, 18, 1, __val)
+#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val)          \
+       SET_BITS_OFFSET_LE(__pdesc+16, 19, 1, __val)
+#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val)     \
+       SET_BITS_OFFSET_LE(__pdesc+16, 20, 2, __val)
+#define SET_TX_DESC_TX_STBC(__pdesc, __val)            \
+       SET_BITS_OFFSET_LE(__pdesc+16, 22, 2, __val)
+#define SET_TX_DESC_DATA_SHORT(__pdesc, __val)         \
+       SET_BITS_OFFSET_LE(__pdesc+16, 24, 1, __val)
+#define SET_TX_DESC_DATA_BW(__pdesc, __val)            \
+       SET_BITS_OFFSET_LE(__pdesc+16, 25, 1, __val)
+#define SET_TX_DESC_RTS_SHORT(__pdesc, __val)          \
+       SET_BITS_OFFSET_LE(__pdesc+16, 26, 1, __val)
+#define SET_TX_DESC_RTS_BW(__pdesc, __val)             \
+       SET_BITS_OFFSET_LE(__pdesc+16, 27, 1, __val)
+#define SET_TX_DESC_RTS_SC(__pdesc, __val)             \
+       SET_BITS_OFFSET_LE(__pdesc+16, 28, 2, __val)
+#define SET_TX_DESC_RTS_STBC(__pdesc, __val)           \
+       SET_BITS_OFFSET_LE(__pdesc+16, 30, 2, __val)
+
+#define GET_TX_DESC_RTS_RATE(__pdesc)                  \
+       SHIFT_AND_MASK_LE(__pdesc+16, 0, 5)
+#define GET_TX_DESC_AP_DCFE(__pdesc)                   \
+       SHIFT_AND_MASK_LE(__pdesc+16, 5, 1)
+#define GET_TX_DESC_QOS(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc+16, 6, 1)
+#define GET_TX_DESC_HWSEQ_EN(__pdesc)                  \
+       SHIFT_AND_MASK_LE(__pdesc+16, 7, 1)
+#define GET_TX_DESC_USE_RATE(__pdesc)                  \
+       SHIFT_AND_MASK_LE(__pdesc+16, 8, 1)
+#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc)            \
+       SHIFT_AND_MASK_LE(__pdesc+16, 9, 1)
+#define GET_TX_DESC_DISABLE_FB(__pdesc)                        \
+       SHIFT_AND_MASK_LE(__pdesc+16, 10, 1)
+#define GET_TX_DESC_CTS2SELF(__pdesc)                  \
+       SHIFT_AND_MASK_LE(__pdesc+16, 11, 1)
+#define GET_TX_DESC_RTS_ENABLE(__pdesc)                        \
+       SHIFT_AND_MASK_LE(__pdesc+16, 12, 1)
+#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc)             \
+       SHIFT_AND_MASK_LE(__pdesc+16, 13, 1)
+#define GET_TX_DESC_PORT_ID(__pdesc)                   \
+       SHIFT_AND_MASK_LE(__pdesc+16, 14, 1)
+#define GET_TX_DESC_WAIT_DCTS(__pdesc)                 \
+       SHIFT_AND_MASK_LE(__pdesc+16, 18, 1)
+#define GET_TX_DESC_CTS2AP_EN(__pdesc)                 \
+       SHIFT_AND_MASK_LE(__pdesc+16, 19, 1)
+#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc)            \
+       SHIFT_AND_MASK_LE(__pdesc+16, 20, 2)
+#define GET_TX_DESC_TX_STBC(__pdesc)                   \
+       SHIFT_AND_MASK_LE(__pdesc+16, 22, 2)
+#define GET_TX_DESC_DATA_SHORT(__pdesc)                        \
+       SHIFT_AND_MASK_LE(__pdesc+16, 24, 1)
+#define GET_TX_DESC_DATA_BW(__pdesc)                   \
+       SHIFT_AND_MASK_LE(__pdesc+16, 25, 1)
+#define GET_TX_DESC_RTS_SHORT(__pdesc)                 \
+       SHIFT_AND_MASK_LE(__pdesc+16, 26, 1)
+#define GET_TX_DESC_RTS_BW(__pdesc)                    \
+       SHIFT_AND_MASK_LE(__pdesc+16, 27, 1)
+#define GET_TX_DESC_RTS_SC(__pdesc)                    \
+       SHIFT_AND_MASK_LE(__pdesc+16, 28, 2)
+#define GET_TX_DESC_RTS_STBC(__pdesc)                  \
+       SHIFT_AND_MASK_LE(__pdesc+16, 30, 2)
+
+#define SET_TX_DESC_TX_RATE(__pdesc, __val)            \
+       SET_BITS_OFFSET_LE(__pdesc+20, 0, 6, __val)
+#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val)       \
+       SET_BITS_OFFSET_LE(__pdesc+20, 6, 1, __val)
+#define SET_TX_DESC_CCX_TAG(__pdesc, __val)            \
+       SET_BITS_OFFSET_LE(__pdesc+20, 7, 1, __val)
+#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
+       SET_BITS_OFFSET_LE(__pdesc+20, 8, 5, __val)
+#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val)  \
+       SET_BITS_OFFSET_LE(__pdesc+20, 13, 4, __val)
+#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
+       SET_BITS_OFFSET_LE(__pdesc+20, 17, 1, __val)
+#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val)   \
+       SET_BITS_OFFSET_LE(__pdesc+20, 18, 6, __val)
+#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val)      \
+       SET_BITS_OFFSET_LE(__pdesc+20, 24, 8, __val)
+
+#define GET_TX_DESC_TX_RATE(__pdesc)                   \
+       SHIFT_AND_MASK_LE(__pdesc+20, 0, 6)
+#define GET_TX_DESC_DATA_SHORTGI(__pdesc)              \
+       SHIFT_AND_MASK_LE(__pdesc+20, 6, 1)
+#define GET_TX_DESC_CCX_TAG(__pdesc)                   \
+       SHIFT_AND_MASK_LE(__pdesc+20, 7, 1)
+#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc)                \
+       SHIFT_AND_MASK_LE(__pdesc+20, 8, 5)
+#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc)         \
+       SHIFT_AND_MASK_LE(__pdesc+20, 13, 4)
+#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc)                \
+       SHIFT_AND_MASK_LE(__pdesc+20, 17, 1)
+#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc)          \
+       SHIFT_AND_MASK_LE(__pdesc+20, 18, 6)
+#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc)             \
+       SHIFT_AND_MASK_LE(__pdesc+20, 24, 8)
+
+#define SET_TX_DESC_TXAGC_A(__pdesc, __val)            \
+       SET_BITS_OFFSET_LE(__pdesc+24, 0, 5, __val)
+#define SET_TX_DESC_TXAGC_B(__pdesc, __val)            \
+       SET_BITS_OFFSET_LE(__pdesc+24, 5, 5, __val)
+#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val)                \
+       SET_BITS_OFFSET_LE(__pdesc+24, 10, 1, __val)
+#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val)                \
+       SET_BITS_OFFSET_LE(__pdesc+24, 11, 5, __val)
+#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val)      \
+       SET_BITS_OFFSET_LE(__pdesc+24, 16, 4, __val)
+#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val)      \
+       SET_BITS_OFFSET_LE(__pdesc+24, 20, 4, __val)
+#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val)      \
+       SET_BITS_OFFSET_LE(__pdesc+24, 24, 4, __val)
+#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val)   \
+       SET_BITS_OFFSET_LE(__pdesc+24, 28, 4, __val)
+
+#define GET_TX_DESC_TXAGC_A(__pdesc)                   \
+       SHIFT_AND_MASK_LE(__pdesc+24, 0, 5)
+#define GET_TX_DESC_TXAGC_B(__pdesc)                   \
+       SHIFT_AND_MASK_LE(__pdesc+24, 5, 5)
+#define GET_TX_DESC_USE_MAX_LEN(__pdesc)               \
+       SHIFT_AND_MASK_LE(__pdesc+24, 10, 1)
+#define GET_TX_DESC_MAX_AGG_NUM(__pdesc)               \
+       SHIFT_AND_MASK_LE(__pdesc+24, 11, 5)
+#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc)             \
+       SHIFT_AND_MASK_LE(__pdesc+24, 16, 4)
+#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc)             \
+       SHIFT_AND_MASK_LE(__pdesc+24, 20, 4)
+#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc)             \
+       SHIFT_AND_MASK_LE(__pdesc+24, 24, 4)
+#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc)          \
+       SHIFT_AND_MASK_LE(__pdesc+24, 28, 4)
+
+#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val)     \
+       SET_BITS_OFFSET_LE(__pdesc+28, 0, 16, __val)
+#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val)      \
+       SET_BITS_OFFSET_LE(__pdesc+28, 16, 4, __val)
+#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val)      \
+       SET_BITS_OFFSET_LE(__pdesc+28, 20, 4, __val)
+#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val)      \
+       SET_BITS_OFFSET_LE(__pdesc+28, 24, 4, __val)
+#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val)  \
+       SET_BITS_OFFSET_LE(__pdesc+28, 28, 4, __val)
+
+#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc)            \
+       SHIFT_AND_MASK_LE(__pdesc+28, 0, 16)
+#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc)             \
+       SHIFT_AND_MASK_LE(__pdesc+28, 16, 4)
+#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc)             \
+       SHIFT_AND_MASK_LE(__pdesc+28, 20, 4)
+#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc)             \
+       SHIFT_AND_MASK_LE(__pdesc+28, 24, 4)
+#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc)         \
+       SHIFT_AND_MASK_LE(__pdesc+28, 28, 4)
+
+#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val)  \
+       SET_BITS_OFFSET_LE(__pdesc+32, 0, 32, __val)
+#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \
+       SET_BITS_OFFSET_LE(__pdesc+36, 0, 32, __val)
+
+#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc)         \
+       SHIFT_AND_MASK_LE(__pdesc+32, 0, 32)
+#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc)       \
+       SHIFT_AND_MASK_LE(__pdesc+36, 0, 32)
+
+#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val)  \
+       SET_BITS_OFFSET_LE(__pdesc+40, 0, 32, __val)
+#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \
+       SET_BITS_OFFSET_LE(__pdesc+44, 0, 32, __val)
+
+#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc)         \
+       SHIFT_AND_MASK_LE(__pdesc+40, 0, 32)
+#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc)       \
+       SHIFT_AND_MASK_LE(__pdesc+44, 0, 32)
+
+#define GET_RX_DESC_PKT_LEN(__pdesc)                   \
+       SHIFT_AND_MASK_LE(__pdesc, 0, 14)
+#define GET_RX_DESC_CRC32(__pdesc)                     \
+       SHIFT_AND_MASK_LE(__pdesc, 14, 1)
+#define GET_RX_DESC_ICV(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc, 15, 1)
+#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc)             \
+       SHIFT_AND_MASK_LE(__pdesc, 16, 4)
+#define GET_RX_DESC_SECURITY(__pdesc)                  \
+       SHIFT_AND_MASK_LE(__pdesc, 20, 3)
+#define GET_RX_DESC_QOS(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc, 23, 1)
+#define GET_RX_DESC_SHIFT(__pdesc)                     \
+       SHIFT_AND_MASK_LE(__pdesc, 24, 2)
+#define GET_RX_DESC_PHYST(__pdesc)                     \
+       SHIFT_AND_MASK_LE(__pdesc, 26, 1)
+#define GET_RX_DESC_SWDEC(__pdesc)                     \
+       SHIFT_AND_MASK_LE(__pdesc, 27, 1)
+#define GET_RX_DESC_LS(__pdesc)                                \
+       SHIFT_AND_MASK_LE(__pdesc, 28, 1)
+#define GET_RX_DESC_FS(__pdesc)                                \
+       SHIFT_AND_MASK_LE(__pdesc, 29, 1)
+#define GET_RX_DESC_EOR(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc, 30, 1)
+#define GET_RX_DESC_OWN(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc, 31, 1)
+
+#define SET_RX_DESC_PKT_LEN(__pdesc, __val)            \
+       SET_BITS_OFFSET_LE(__pdesc, 0, 14, __val)
+#define SET_RX_DESC_EOR(__pdesc, __val)                        \
+       SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val)
+#define SET_RX_DESC_OWN(__pdesc, __val)                        \
+       SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val)
+
+#define GET_RX_DESC_MACID(__pdesc)                     \
+       SHIFT_AND_MASK_LE(__pdesc+4, 0, 5)
+#define GET_RX_DESC_TID(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc+4, 5, 4)
+#define GET_RX_DESC_HWRSVD(__pdesc)                    \
+       SHIFT_AND_MASK_LE(__pdesc+4, 9, 5)
+#define GET_RX_DESC_PAGGR(__pdesc)                     \
+       SHIFT_AND_MASK_LE(__pdesc+4, 14, 1)
+#define GET_RX_DESC_FAGGR(__pdesc)                     \
+       SHIFT_AND_MASK_LE(__pdesc+4, 15, 1)
+#define GET_RX_DESC_A1_FIT(__pdesc)                    \
+       SHIFT_AND_MASK_LE(__pdesc+4, 16, 4)
+#define GET_RX_DESC_A2_FIT(__pdesc)                    \
+       SHIFT_AND_MASK_LE(__pdesc+4, 20, 4)
+#define GET_RX_DESC_PAM(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc+4, 24, 1)
+#define GET_RX_DESC_PWR(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc+4, 25, 1)
+#define GET_RX_DESC_MD(__pdesc)                                \
+       SHIFT_AND_MASK_LE(__pdesc+4, 26, 1)
+#define GET_RX_DESC_MF(__pdesc)                                \
+       SHIFT_AND_MASK_LE(__pdesc+4, 27, 1)
+#define GET_RX_DESC_TYPE(__pdesc)                      \
+       SHIFT_AND_MASK_LE(__pdesc+4, 28, 2)
+#define GET_RX_DESC_MC(__pdesc)                                \
+       SHIFT_AND_MASK_LE(__pdesc+4, 30, 1)
+#define GET_RX_DESC_BC(__pdesc)                                \
+       SHIFT_AND_MASK_LE(__pdesc+4, 31, 1)
+#define GET_RX_DESC_SEQ(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc+8, 0, 12)
+#define GET_RX_DESC_FRAG(__pdesc)                      \
+       SHIFT_AND_MASK_LE(__pdesc+8, 12, 4)
+#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc)              \
+       SHIFT_AND_MASK_LE(__pdesc+8, 16, 14)
+#define GET_RX_DESC_NEXT_IND(__pdesc)                  \
+       SHIFT_AND_MASK_LE(__pdesc+8, 30, 1)
+#define GET_RX_DESC_RSVD(__pdesc)                      \
+       SHIFT_AND_MASK_LE(__pdesc+8, 31, 1)
+
+#define GET_RX_DESC_RXMCS(__pdesc)                     \
+       SHIFT_AND_MASK_LE(__pdesc+12, 0, 6)
+#define GET_RX_DESC_RXHT(__pdesc)                      \
+       SHIFT_AND_MASK_LE(__pdesc+12, 6, 1)
+#define GET_RX_DESC_SPLCP(__pdesc)                     \
+       SHIFT_AND_MASK_LE(__pdesc+12, 8, 1)
+#define GET_RX_DESC_BW(__pdesc)                                \
+       SHIFT_AND_MASK_LE(__pdesc+12, 9, 1)
+#define GET_RX_DESC_HTC(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc+12, 10, 1)
+#define GET_RX_DESC_HWPC_ERR(__pdesc)                  \
+       SHIFT_AND_MASK_LE(__pdesc+12, 14, 1)
+#define GET_RX_DESC_HWPC_IND(__pdesc)                  \
+       SHIFT_AND_MASK_LE(__pdesc+12, 15, 1)
+#define GET_RX_DESC_IV0(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc+12, 16, 16)
+
+#define GET_RX_DESC_IV1(__pdesc)                       \
+       SHIFT_AND_MASK_LE(__pdesc+16, 0, 32)
+#define GET_RX_DESC_TSFL(__pdesc)                      \
+       SHIFT_AND_MASK_LE(__pdesc+20, 0, 32)
+
+#define GET_RX_DESC_BUFF_ADDR(__pdesc)                 \
+       SHIFT_AND_MASK_LE(__pdesc+24, 0, 32)
+#define GET_RX_DESC_BUFF_ADDR64(__pdesc)               \
+       SHIFT_AND_MASK_LE(__pdesc+28, 0, 32)
+
+#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val)          \
+       SET_BITS_OFFSET_LE(__pdesc+24, 0, 32, __val)
+#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val)                \
+       SET_BITS_OFFSET_LE(__pdesc+28, 0, 32, __val)
+
+#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size)      \
+do {                                                   \
+       if (_size > TX_DESC_NEXT_DESC_OFFSET)           \
+               memset((void *)__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET);   \
+       else                                            \
+               memset((void *)__pdesc, 0, _size);      \
+} while (0);
+
+#define RX_HAL_IS_CCK_RATE(_pdesc)\
+       (_pdesc->rxmcs == DESC92D_RATE1M ||             \
+        _pdesc->rxmcs == DESC92D_RATE2M ||             \
+        _pdesc->rxmcs == DESC92D_RATE5_5M ||           \
+        _pdesc->rxmcs == DESC92D_RATE11M)
+
+/* For 92D early mode */
+#define SET_EARLYMODE_PKTNUM(__paddr, __value)         \
+       SET_BITS_OFFSET_LE(__paddr, 0, 3, __value)
+#define SET_EARLYMODE_LEN0(__paddr, __value)           \
+       SET_BITS_OFFSET_LE(__paddr, 4, 12, __value)
+#define SET_EARLYMODE_LEN1(__paddr, __value)           \
+       SET_BITS_OFFSET_LE(__paddr, 16, 12, __value)
+#define SET_EARLYMODE_LEN2_1(__paddr, __value)         \
+       SET_BITS_OFFSET_LE(__paddr, 28, 4, __value)
+#define SET_EARLYMODE_LEN2_2(__paddr, __value)         \
+       SET_BITS_OFFSET_LE(__paddr+4, 0, 8, __value)
+#define SET_EARLYMODE_LEN3(__paddr, __value)           \
+       SET_BITS_OFFSET_LE(__paddr+4, 8, 12, __value)
+#define SET_EARLYMODE_LEN4(__paddr, __value)           \
+       SET_BITS_OFFSET_LE(__paddr+4, 20, 12, __value)
+
+struct rx_fwinfo_92d {
+       u8 gain_trsw[4];
+       u8 pwdb_all;
+       u8 cfosho[4];
+       u8 cfotail[4];
+       char rxevm[2];
+       char rxsnr[4];
+       u8 pdsnr[2];
+       u8 csi_current[2];
+       u8 csi_target[2];
+       u8 sigevm;
+       u8 max_ex_pwr;
+       u8 ex_intf_flag:1;
+       u8 sgi_en:1;
+       u8 rxsc:2;
+       u8 reserve:4;
+} __packed;
+
+struct tx_desc_92d {
+       u32 pktsize:16;
+       u32 offset:8;
+       u32 bmc:1;
+       u32 htc:1;
+       u32 lastseg:1;
+       u32 firstseg:1;
+       u32 linip:1;
+       u32 noacm:1;
+       u32 gf:1;
+       u32 own:1;
+
+       u32 macid:5;
+       u32 agg_en:1;
+       u32 bk:1;
+       u32 rdg_en:1;
+       u32 queuesel:5;
+       u32 rd_nav_ext:1;
+       u32 lsig_txop_en:1;
+       u32 pifs:1;
+       u32 rateid:4;
+       u32 nav_usehdr:1;
+       u32 en_descid:1;
+       u32 sectype:2;
+       u32 pktoffset:8;
+
+       u32 rts_rc:6;
+       u32 data_rc:6;
+       u32 rsvd0:2;
+       u32 bar_retryht:2;
+       u32 rsvd1:1;
+       u32 morefrag:1;
+       u32 raw:1;
+       u32 ccx:1;
+       u32 ampdudensity:3;
+       u32 rsvd2:1;
+       u32 ant_sela:1;
+       u32 ant_selb:1;
+       u32 txant_cck:2;
+       u32 txant_l:2;
+       u32 txant_ht:2;
+
+       u32 nextheadpage:8;
+       u32 tailpage:8;
+       u32 seq:12;
+       u32 pktid:4;
+
+       u32 rtsrate:5;
+       u32 apdcfe:1;
+       u32 qos:1;
+       u32 hwseq_enable:1;
+       u32 userrate:1;
+       u32 dis_rtsfb:1;
+       u32 dis_datafb:1;
+       u32 cts2self:1;
+       u32 rts_en:1;
+       u32 hwrts_en:1;
+       u32 portid:1;
+       u32 rsvd3:3;
+       u32 waitdcts:1;
+       u32 cts2ap_en:1;
+       u32 txsc:2;
+       u32 stbc:2;
+       u32 txshort:1;
+       u32 txbw:1;
+       u32 rtsshort:1;
+       u32 rtsbw:1;
+       u32 rtssc:2;
+       u32 rtsstbc:2;
+
+       u32 txrate:6;
+       u32 shortgi:1;
+       u32 ccxt:1;
+       u32 txrate_fb_lmt:5;
+       u32 rtsrate_fb_lmt:4;
+       u32 retrylmt_en:1;
+       u32 txretrylmt:6;
+       u32 usb_txaggnum:8;
+
+       u32 txagca:5;
+       u32 txagcb:5;
+       u32 usemaxlen:1;
+       u32 maxaggnum:5;
+       u32 mcsg1maxlen:4;
+       u32 mcsg2maxlen:4;
+       u32 mcsg3maxlen:4;
+       u32 mcs7sgimaxlen:4;
+
+       u32 txbuffersize:16;
+       u32 mcsg4maxlen:4;
+       u32 mcsg5maxlen:4;
+       u32 mcsg6maxlen:4;
+       u32 mcsg15sgimaxlen:4;
+
+       u32 txbuffaddr;
+       u32 txbufferaddr64;
+       u32 nextdescaddress;
+       u32 nextdescaddress64;
+
+       u32 reserve_pass_pcie_mm_limit[4];
+} __packed;
+
+struct rx_desc_92d {
+       u32 length:14;
+       u32 crc32:1;
+       u32 icverror:1;
+       u32 drv_infosize:4;
+       u32 security:3;
+       u32 qos:1;
+       u32 shift:2;
+       u32 phystatus:1;
+       u32 swdec:1;
+       u32 lastseg:1;
+       u32 firstseg:1;
+       u32 eor:1;
+       u32 own:1;
+
+       u32 macid:5;
+       u32 tid:4;
+       u32 hwrsvd:5;
+       u32 paggr:1;
+       u32 faggr:1;
+       u32 a1_fit:4;
+       u32 a2_fit:4;
+       u32 pam:1;
+       u32 pwr:1;
+       u32 moredata:1;
+       u32 morefrag:1;
+       u32 type:2;
+       u32 mc:1;
+       u32 bc:1;
+
+       u32 seq:12;
+       u32 frag:4;
+       u32 nextpktlen:14;
+       u32 nextind:1;
+       u32 rsvd:1;
+
+       u32 rxmcs:6;
+       u32 rxht:1;
+       u32 amsdu:1;
+       u32 splcp:1;
+       u32 bandwidth:1;
+       u32 htc:1;
+       u32 tcpchk_rpt:1;
+       u32 ipcchk_rpt:1;
+       u32 tcpchk_valid:1;
+       u32 hwpcerr:1;
+       u32 hwpcind:1;
+       u32 iv0:16;
+
+       u32 iv1;
+
+       u32 tsfl;
+
+       u32 bufferaddress;
+       u32 bufferaddress64;
+
+} __packed;
+
+void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
+                         struct ieee80211_hdr *hdr,
+                         u8 *pdesc, struct ieee80211_tx_info *info,
+                         struct sk_buff *skb, u8 hw_queue,
+                         struct rtl_tcb_desc *ptcb_desc);
+bool rtl92de_rx_query_desc(struct ieee80211_hw *hw,
+                          struct rtl_stats *stats,
+                          struct ieee80211_rx_status *rx_status,
+                          u8 *pdesc, struct sk_buff *skb);
+void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val);
+u32 rtl92de_get_desc(u8 *pdesc, bool istx, u8 desc_name);
+void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
+void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
+                            bool b_firstseg, bool b_lastseg,
+                            struct sk_buff *skb);
+
+#endif
index 6890e19..d3c3ffd 100644 (file)
@@ -302,9 +302,6 @@ enum hw_variables {
        HW_VAR_DATA_FILTER,
 };
 
-#define HWSET_MAX_SIZE                         128
-#define EFUSE_MAX_SECTION                      16
-
 enum _RT_MEDIA_STATUS {
        RT_MEDIA_DISCONNECT = 0,
        RT_MEDIA_CONNECT = 1
index 42935ac..5d0ad2d 100644 (file)
@@ -1167,14 +1167,7 @@ int wl1271_cmd_add_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
        cmd->bss_index = WL1271_AP_BSS_INDEX;
        cmd->aid = sta->aid;
        cmd->hlid = hlid;
-
-       /*
-        * FIXME: Does STA support QOS? We need to propagate this info from
-        * hostapd. Currently not that important since this is only used for
-        * sending the correct flavor of null-data packet in response to a
-        * trigger.
-        */
-       cmd->wmm = 0;
+       cmd->wmm = sta->wme ? 1 : 0;
 
        cmd->supported_rates = cpu_to_le32(wl1271_tx_enabled_rates_get(wl,
                                                sta->supp_rates[wl->band]));
index e568664..57b7b64 100644 (file)
@@ -1002,8 +1002,8 @@ u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m)
        switch (plltype) {
        case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */
                if (m & SSB_CHIPCO_CLK_T6_MMASK)
-                       return SSB_CHIPCO_CLK_T6_M0;
-               return SSB_CHIPCO_CLK_T6_M1;
+                       return SSB_CHIPCO_CLK_T6_M1;
+               return SSB_CHIPCO_CLK_T6_M0;
        case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */
        case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
        case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */
index 45e5bab..8047f9a 100644 (file)
@@ -310,8 +310,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
        } else {
                if (bus->bustype == SSB_BUSTYPE_PCI) {
                        bus->chip_id = pcidev_to_chipid(bus->host_pci);
-                       pci_read_config_byte(bus->host_pci, PCI_REVISION_ID,
-                                            &bus->chip_rev);
+                       bus->chip_rev = bus->host_pci->revision;
                        bus->chip_package = 0;
                } else {
                        bus->chip_id = 0x4710;
index bf56b6f..a26108e 100644 (file)
 #define IEEE80211_MAX_MESH_ID_LEN      32
 
 #define IEEE80211_QOS_CTL_LEN          2
-#define IEEE80211_QOS_CTL_TID_MASK     0x000F
-#define IEEE80211_QOS_CTL_TAG1D_MASK   0x0007
+/* 1d tag mask */
+#define IEEE80211_QOS_CTL_TAG1D_MASK           0x0007
+/* TID mask */
+#define IEEE80211_QOS_CTL_TID_MASK             0x000f
+/* EOSP */
+#define IEEE80211_QOS_CTL_EOSP                 0x0010
+/* ACK policy */
+#define IEEE80211_QOS_CTL_ACK_POLICY_NORMAL    0x0000
+#define IEEE80211_QOS_CTL_ACK_POLICY_NOACK     0x0020
+#define IEEE80211_QOS_CTL_ACK_POLICY_NO_EXPL   0x0040
+#define IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK  0x0060
+/* A-MSDU 802.11n */
+#define IEEE80211_QOS_CTL_A_MSDU_PRESENT       0x0080
 
 /* U-APSD queue for WMM IEs sent by AP */
 #define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD      (1<<7)
@@ -1423,9 +1434,6 @@ enum ieee80211_sa_query_action {
 };
 
 
-/* A-MSDU 802.11n */
-#define IEEE80211_QOS_CONTROL_A_MSDU_PRESENT 0x0080
-
 /* cipher suite selectors */
 #define WLAN_CIPHER_SUITE_USE_GROUP    0x000FAC00
 #define WLAN_CIPHER_SUITE_WEP40                0x000FAC01
index 6cb2543..7202bce 100644 (file)
@@ -2697,7 +2697,7 @@ void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
  * @dev: network device
  * @addr: The source MAC address of the frame
  * @key_type: The key type that the received frame used
- * @key_id: Key identifier (0..3)
+ * @key_id: Key identifier (0..3). Can be -1 if missing.
  * @tsc: The TSC value of the frame that generated the MIC failure (6 octets)
  * @gfp: allocation flags
  *
index 120f102..c9def42 100644 (file)
@@ -933,6 +933,7 @@ enum set_key_cmd {
  * @aid: AID we assigned to the station if we're an AP
  * @supp_rates: Bitmap of supported rates (per band)
  * @ht_cap: HT capabilities of this STA; restricted to our own TX capabilities
+ * @wme: indicates whether the STA supports WME. Only valid during AP-mode.
  * @drv_priv: data area for driver use, will always be aligned to
  *     sizeof(void *), size is determined in hw information.
  */
@@ -941,6 +942,7 @@ struct ieee80211_sta {
        u8 addr[ETH_ALEN];
        u16 aid;
        struct ieee80211_sta_ht_cap ht_cap;
+       bool wme;
 
        /* must be last */
        u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
index f495dea..bfb3dc0 100644 (file)
@@ -6,6 +6,7 @@ menuconfig BT
        tristate "Bluetooth subsystem support"
        depends on NET && !S390
        depends on RFKILL || !RFKILL
+       select CRYPTO
        help
          Bluetooth is low-cost, low-power, short-range wireless technology.
          It was designed as a replacement for cables and other short-range
index 89b0b2c..ebadb9a 100644 (file)
@@ -262,7 +262,11 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
                                "%pM on tid %u\n",
                                mgmt->sa, tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
-               goto end;
+
+               /* delete existing Rx BA session on the same tid */
+               ___ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT,
+                                               WLAN_STATUS_UNSPECIFIED_QOS,
+                                               false);
        }
 
        /* prepare A-MPDU MLME for Rx aggregation */
index 6e56c6e..9fe22cc 100644 (file)
@@ -674,8 +674,11 @@ static void sta_apply_parameters(struct ieee80211_local *local,
 
        if (mask & BIT(NL80211_STA_FLAG_WME)) {
                sta->flags &= ~WLAN_STA_WME;
-               if (set & BIT(NL80211_STA_FLAG_WME))
+               sta->sta.wme = false;
+               if (set & BIT(NL80211_STA_FLAG_WME)) {
                        sta->flags |= WLAN_STA_WME;
+                       sta->sta.wme = true;
+               }
        }
 
        if (mask & BIT(NL80211_STA_FLAG_MFP)) {
index 090b0ec..25c15cc 100644 (file)
@@ -1350,10 +1350,12 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
                                          u8 *dst,
                                          const u8 *ssid, size_t ssid_len,
-                                         const u8 *ie, size_t ie_len);
+                                         const u8 *ie, size_t ie_len,
+                                         bool directed);
 void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
                              const u8 *ssid, size_t ssid_len,
-                             const u8 *ie, size_t ie_len);
+                             const u8 *ie, size_t ie_len,
+                             bool directed);
 
 void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
                                  const size_t supp_rates_len,
index faca503..b874200 100644 (file)
@@ -760,23 +760,34 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
        if (local->hw.conf.flags & IEEE80211_CONF_PS)
                return;
 
-       /*
-        * transmission can be stopped by others which leads to
-        * dynamic_ps_timer expiry. Postpond the ps timer if it
-        * is not the actual idle state.
-        */
-       spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
-       for (q = 0; q < local->hw.queues; q++) {
-               if (local->queue_stop_reasons[q]) {
-                       spin_unlock_irqrestore(&local->queue_stop_reason_lock,
-                                              flags);
+       if (!local->disable_dynamic_ps &&
+           local->hw.conf.dynamic_ps_timeout > 0) {
+               /* don't enter PS if TX frames are pending */
+               if (drv_tx_frames_pending(local)) {
                        mod_timer(&local->dynamic_ps_timer, jiffies +
                                  msecs_to_jiffies(
                                  local->hw.conf.dynamic_ps_timeout));
                        return;
                }
+
+               /*
+                * transmission can be stopped by others which leads to
+                * dynamic_ps_timer expiry. Postpone the ps timer if it
+                * is not the actual idle state.
+                */
+               spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+               for (q = 0; q < local->hw.queues; q++) {
+                       if (local->queue_stop_reasons[q]) {
+                               spin_unlock_irqrestore(&local->queue_stop_reason_lock,
+                                                      flags);
+                               mod_timer(&local->dynamic_ps_timer, jiffies +
+                                         msecs_to_jiffies(
+                                         local->hw.conf.dynamic_ps_timeout));
+                               return;
+                       }
+               }
+               spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
        }
-       spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 
        if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
            (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) {
@@ -801,7 +812,8 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
                ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
        }
 
-       netif_tx_wake_all_queues(sdata->dev);
+       if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
+               netif_tx_wake_all_queues(sdata->dev);
 }
 
 void ieee80211_dynamic_ps_timer(unsigned long data)
@@ -1204,7 +1216,8 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
                ieee80211_send_nullfunc(sdata->local, sdata, 0);
        } else {
                ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
-               ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0);
+               ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0,
+                                        true);
        }
 
        ifmgd->probe_send_count++;
@@ -1289,7 +1302,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
 
        ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
        skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid,
-                                       ssid + 2, ssid[1], NULL, 0);
+                                       ssid + 2, ssid[1], NULL, 0, true);
 
        return skb;
 }
index 7fa8c6b..b5493ec 100644 (file)
@@ -338,7 +338,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
                u8 *qc = ieee80211_get_qos_ctl(hdr);
                /* frame has qos control */
                tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
-               if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
+               if (*qc & IEEE80211_QOS_CTL_A_MSDU_PRESENT)
                        status->rx_flags |= IEEE80211_RX_AMSDU;
        } else {
                /*
index 1758b46..e5a6ea4 100644 (file)
@@ -228,6 +228,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
 static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
 {
        struct cfg80211_scan_request *req = local->scan_req;
+       struct ieee80211_sub_if_data *sdata = local->scan_sdata;
        enum ieee80211_band band;
        int i, ielen, n_chans;
 
@@ -251,8 +252,8 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
        local->hw_scan_req->n_channels = n_chans;
 
        ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie,
-                                        req->ie, req->ie_len, band, (u32) -1,
-                                        0);
+                                        req->ie, req->ie_len, band,
+                                        sdata->rc_rateidx_mask[band], 0);
        local->hw_scan_req->ie_len = ielen;
 
        return true;
@@ -658,7 +659,8 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
                        sdata, NULL,
                        local->scan_req->ssids[i].ssid,
                        local->scan_req->ssids[i].ssid_len,
-                       local->scan_req->ie, local->scan_req->ie_len);
+                       local->scan_req->ie, local->scan_req->ie_len,
+                       false);
 
        /*
         * After sending probe requests, wait for probe responses
index 05e3fb8..652e569 100644 (file)
@@ -1018,7 +1018,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
                                          u8 *dst,
                                          const u8 *ssid, size_t ssid_len,
-                                         const u8 *ie, size_t ie_len)
+                                         const u8 *ie, size_t ie_len,
+                                         bool directed)
 {
        struct ieee80211_local *local = sdata->local;
        struct sk_buff *skb;
@@ -1035,8 +1036,16 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
                return NULL;
        }
 
-       chan = ieee80211_frequency_to_channel(
-               local->hw.conf.channel->center_freq);
+       /*
+        * Do not send DS Channel parameter for directed probe requests
+        * in order to maximize the chance that we get a response.  Some
+        * badly-behaved APs don't respond when this parameter is included.
+        */
+       if (directed)
+               chan = 0;
+       else
+               chan = ieee80211_frequency_to_channel(
+                       local->hw.conf.channel->center_freq);
 
        buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len,
                                           local->hw.conf.channel->band,
@@ -1062,11 +1071,13 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
 
 void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
                              const u8 *ssid, size_t ssid_len,
-                             const u8 *ie, size_t ie_len)
+                             const u8 *ie, size_t ie_len,
+                             bool directed)
 {
        struct sk_buff *skb;
 
-       skb = ieee80211_build_probe_req(sdata, dst, ssid, ssid_len, ie, ie_len);
+       skb = ieee80211_build_probe_req(sdata, dst, ssid, ssid_len, ie, ie_len,
+                                       directed);
        if (skb)
                ieee80211_tx_skb(sdata, skb);
 }
index 28bc084..7a49532 100644 (file)
@@ -151,8 +151,7 @@ void ieee80211_set_qos_hdr(struct ieee80211_local *local, struct sk_buff *skb)
                tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
 
                if (unlikely(local->wifi_wme_noack_test))
-                       ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK <<
-                                       QOS_CONTROL_ACK_POLICY_SHIFT;
+                       ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK;
                /* qos header is 2 bytes, second reserved */
                *p++ = ack_policy | tid;
                *p = 0;
index 6053b1c..faead6d 100644 (file)
 #include <linux/netdevice.h>
 #include "ieee80211_i.h"
 
-#define QOS_CONTROL_ACK_POLICY_NORMAL 0
-#define QOS_CONTROL_ACK_POLICY_NOACK 1
-
-#define QOS_CONTROL_ACK_POLICY_SHIFT 5
-
 extern const int ieee802_1d_to_ac[8];
 
 u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
index d2e7f0e..edf8583 100644 (file)
@@ -450,7 +450,7 @@ ieee80211_direct_probe(struct ieee80211_work *wk)
         * will not answer to direct packet in unassociated state.
         */
        ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid,
-                                wk->probe_auth.ssid_len, NULL, 0);
+                                wk->probe_auth.ssid_len, NULL, 0, true);
 
        wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
        run_again(local, wk->timeout);
index 9dc3b5f..d91c1a2 100644 (file)
@@ -154,7 +154,13 @@ update_iv:
        return RX_CONTINUE;
 
 mic_fail:
-       mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,
+       /*
+        * In some cases the key can be unset - e.g. a multicast packet, in
+        * a driver that supports HW encryption. Send up the key idx only if
+        * the key is set.
+        */
+       mac80211_ev_michael_mic_failure(rx->sdata,
+                                       rx->key ? rx->key->conf.keyidx : -1,
                                        (void *) skb->data, NULL, GFP_ATOMIC);
        return RX_DROP_UNUSABLE;
 }
index aed6d2a..50ff82a 100644 (file)
@@ -6566,7 +6566,8 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
        if (addr)
                NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
        NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type);
-       NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id);
+       if (key_id != -1)
+               NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id);
        if (tsc)
                NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc);