From: Yan-Hsuan Chuang <yhchu...@realtek.com>

main files for Realtek 802.11ac wireless network chips

Signed-off-by: Yan-Hsuan Chuang <yhchu...@realtek.com>
---
 drivers/net/wireless/realtek/rtwlan/mac80211.c |  447 +++++++++
 drivers/net/wireless/realtek/rtwlan/main.c     | 1164 +++++++++++++++++++++++
 drivers/net/wireless/realtek/rtwlan/main.h     | 1188 ++++++++++++++++++++++++
 drivers/net/wireless/realtek/rtwlan/reg.h      |  399 ++++++++
 4 files changed, 3198 insertions(+)
 create mode 100644 drivers/net/wireless/realtek/rtwlan/mac80211.c
 create mode 100644 drivers/net/wireless/realtek/rtwlan/main.c
 create mode 100644 drivers/net/wireless/realtek/rtwlan/main.h
 create mode 100644 drivers/net/wireless/realtek/rtwlan/reg.h

diff --git a/drivers/net/wireless/realtek/rtwlan/mac80211.c 
b/drivers/net/wireless/realtek/rtwlan/mac80211.c
new file mode 100644
index 0000000..f218341
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtwlan/mac80211.c
@@ -0,0 +1,447 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "sec.h"
+#include "tx.h"
+#include "fw.h"
+#include "mac.h"
+#include "ps.h"
+#include "reg.h"
+#include "debug.h"
+
+static void rtw_ops_tx(struct ieee80211_hw *hw,
+                      struct ieee80211_tx_control *control,
+                      struct sk_buff *skb)
+{
+       struct rtw_dev *rtwdev = hw->priv;
+       struct rtw_tx_pkt_info pkt_info;
+
+       if (!rtw_flag_check(rtwdev, RTW_FLAG_RUNNING))
+               goto out;
+
+       memset(&pkt_info, 0, sizeof(pkt_info));
+       rtw_tx_pkt_info_update(rtwdev, &pkt_info, control, skb);
+       if (rtw_hci_tx(rtwdev, &pkt_info, skb))
+               goto out;
+
+       return;
+
+out:
+       dev_kfree_skb_any(skb);
+}
+
+static int rtw_ops_start(struct ieee80211_hw *hw)
+{
+       struct rtw_dev *rtwdev = hw->priv;
+
+       return rtw_core_start(rtwdev);
+}
+
+static void rtw_ops_stop(struct ieee80211_hw *hw)
+{
+       struct rtw_dev *rtwdev = hw->priv;
+
+       rtw_core_stop(rtwdev);
+}
+
+static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed)
+{
+       struct rtw_dev *rtwdev = hw->priv;
+       int ret;
+
+       if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+               if (hw->conf.flags & IEEE80211_CONF_IDLE) {
+                       rtw_enter_ips(rtwdev);
+               } else {
+                       ret = rtw_leave_ips(rtwdev);
+                       if (ret) {
+                               rtw_err(rtwdev, "failed to leave idle state\n");
+                               return ret;
+                       }
+               }
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
+               rtw_set_channel(rtwdev);
+
+       return 0;
+}
+
+static struct rtw_vif_port rtw_vif_port[] = {
+       [0] = {
+               .mac_addr       = {.addr = 0x0610},
+               .bssid          = {.addr = 0x0618},
+               .net_type       = {.addr = 0x0100, .mask = 0x30000},
+               .aid            = {.addr = 0x06a8, .mask = 0x7ff},
+       },
+       [1] = {
+               .mac_addr       = {.addr = 0x0700},
+               .bssid          = {.addr = 0x0708},
+               .net_type       = {.addr = 0x0100, .mask = 0xc0000},
+               .aid            = {.addr = 0x0710, .mask = 0x7ff},
+       },
+       [2] = {
+               .mac_addr       = {.addr = 0x1620},
+               .bssid          = {.addr = 0x1628},
+               .net_type       = {.addr = 0x1100, .mask = 0x3},
+               .aid            = {.addr = 0x1600, .mask = 0x7ff},
+       },
+       [3] = {
+               .mac_addr       = {.addr = 0x1630},
+               .bssid          = {.addr = 0x1638},
+               .net_type       = {.addr = 0x1100, .mask = 0xc},
+               .aid            = {.addr = 0x1604, .mask = 0x7ff},
+       },
+       [4] = {
+               .mac_addr       = {.addr = 0x1640},
+               .bssid          = {.addr = 0x1648},
+               .net_type       = {.addr = 0x1100, .mask = 0x30},
+               .aid            = {.addr = 0x1608, .mask = 0x7ff},
+       },
+};
+
+static int rtw_ops_add_interface(struct ieee80211_hw *hw,
+                                struct ieee80211_vif *vif)
+{
+       struct rtw_dev *rtwdev = hw->priv;
+       struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
+       enum rtw_net_type net_type;
+       u32 config = 0;
+       u8 port = 0;
+
+       vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+       rtwvif->port = port;
+       rtwvif->vif = vif;
+       rtwvif->stats.tx_unicast = 0;
+       rtwvif->stats.rx_unicast = 0;
+       rtwvif->stats.tx_cnt = 0;
+       rtwvif->stats.rx_cnt = 0;
+       rtwvif->in_lps = false;
+       list_add(&rtwvif->list, &rtwdev->vif_list);
+       INIT_LIST_HEAD(&rtwvif->sta_list);
+
+       rtwvif->conf = &rtw_vif_port[port];
+
+       switch (vif->type) {
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_MESH_POINT:
+               net_type = RTW_NET_AP_MODE;
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               net_type = RTW_NET_AD_HOC;
+               break;
+       default:
+               net_type = RTW_NET_NO_LINK;
+               break;
+       }
+
+       ether_addr_copy(rtwvif->mac_addr, vif->addr);
+       config |= PORT_SET_MAC_ADDR;
+       rtwvif->net_type = net_type;
+       config |= PORT_SET_NET_TYPE;
+       rtw_vif_port_config(rtwdev, rtwvif, config);
+
+       rtw_info(rtwdev, "start vif %pM on port %d", vif->addr, rtwvif->port);
+
+       return 0;
+}
+
+static void rtw_ops_remove_interface(struct ieee80211_hw *hw,
+                                    struct ieee80211_vif *vif)
+{
+       struct rtw_dev *rtwdev = hw->priv;
+       struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
+       u32 config = 0;
+
+       rtw_info(rtwdev, "stop vif %pM on port %d", vif->addr, rtwvif->port);
+
+       eth_zero_addr(rtwvif->mac_addr);
+       config |= PORT_SET_MAC_ADDR;
+       rtwvif->net_type = RTW_NET_NO_LINK;
+       config |= PORT_SET_NET_TYPE;
+       rtw_vif_port_config(rtwdev, rtwvif, config);
+
+       list_del(&rtwvif->list);
+}
+
+static void rtw_ops_configure_filter(struct ieee80211_hw *hw,
+                                    unsigned int changed_flags,
+                                    unsigned int *new_flags,
+                                    u64 multicast)
+{
+       struct rtw_dev *rtwdev = hw->priv;
+
+       *new_flags &= (FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL |
+                      FIF_BCN_PRBRESP_PROMISC);
+
+       if (changed_flags & FIF_ALLMULTI) {
+               if (*new_flags & FIF_ALLMULTI)
+                       rtwdev->hal.rcr |= BIT_AM | BIT_AB;
+               else
+                       rtwdev->hal.rcr &= ~(BIT_AM | BIT_AB);
+       }
+       if (changed_flags & FIF_FCSFAIL) {
+               if (*new_flags & FIF_FCSFAIL)
+                       rtwdev->hal.rcr |= BIT_ACRC32;
+               else
+                       rtwdev->hal.rcr &= ~(BIT_ACRC32);
+       }
+       if (changed_flags & FIF_OTHER_BSS) {
+               if (*new_flags & FIF_OTHER_BSS)
+                       rtwdev->hal.rcr |= BIT_AAP;
+               else
+                       rtwdev->hal.rcr &= ~(BIT_AAP);
+       }
+       if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+               if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
+                       rtwdev->hal.rcr &= ~(BIT_CBSSID_BCN | BIT_CBSSID_DATA);
+               else
+                       rtwdev->hal.rcr |= BIT_CBSSID_BCN;
+       }
+
+       rtw_dbg(rtwdev, "config rx filter, changed=0x%08x, new=0x%08x, 
rcr=0x%08x",
+               changed_flags, *new_flags, rtwdev->hal.rcr);
+
+       rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr);
+}
+
+static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
+                                    struct ieee80211_vif *vif,
+                                    struct ieee80211_bss_conf *conf,
+                                    u32 changed)
+{
+       struct rtw_dev *rtwdev = hw->priv;
+       struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
+       u32 config = 0;
+
+       if (changed & BSS_CHANGED_ASSOC) {
+               struct rtw_sta_info *ap;
+               struct rtw_chip_info *chip = rtwdev->chip;
+               enum rtw_net_type net_type;
+
+               ap = list_first_entry(&rtwvif->sta_list,
+                                     struct rtw_sta_info, list);
+               if (conf->assoc) {
+                       net_type = RTW_NET_MGD_LINKED;
+                       chip->ops->do_iqk(rtwdev);
+
+                       rtwvif->aid = conf->aid;
+                       rtw_add_rsvd_page(rtwdev, RSVD_PS_POLL, true);
+                       rtw_add_rsvd_page(rtwdev, RSVD_QOS_NULL, true);
+                       rtw_add_rsvd_page(rtwdev, RSVD_NULL, true);
+                       rtw_fw_download_rsvd_page(rtwdev, vif);
+               } else {
+                       net_type = RTW_NET_NO_LINK;
+                       rtwvif->aid = 0;
+                       rtw_reset_rsvd_page(rtwdev);
+               }
+
+               rtwvif->net_type = net_type;
+               config |= PORT_SET_NET_TYPE;
+               config |= PORT_SET_AID;
+               rtw_fw_media_status_report(rtwdev, ap->mac_id, conf->assoc);
+       }
+
+       if (changed & BSS_CHANGED_BSSID) {
+               ether_addr_copy(rtwvif->bssid, conf->bssid);
+               config |= PORT_SET_BSSID;
+       }
+
+       if (changed & BSS_CHANGED_BEACON)
+               rtw_fw_download_rsvd_page(rtwdev, vif);
+
+       rtw_vif_port_config(rtwdev, rtwvif, config);
+}
+
+static u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
+{
+       u8 i;
+
+       for (i = 0; i < RTW_MAX_MAC_ID_NUM; i++) {
+               if (!rtwdev->macid_used[i]) {
+                       rtwdev->macid_used[i] = true;
+                       return i;
+               }
+       }
+
+       return i;
+}
+
+static void rtw_release_macid(struct rtw_dev *rtwdev, u8 mac_id)
+{
+       rtwdev->macid_used[mac_id] = false;
+}
+
+static int rtw_ops_sta_add(struct ieee80211_hw *hw,
+                          struct ieee80211_vif *vif,
+                          struct ieee80211_sta *sta)
+{
+       struct rtw_dev *rtwdev = hw->priv;
+       struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
+       struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
+
+       si->mac_id = rtw_acquire_macid(rtwdev);
+       if (si->mac_id >= RTW_MAX_MAC_ID_NUM)
+               return -ENOSPC;
+
+       si->sta = sta;
+       si->vif = vif;
+       si->init_ra_lv = 1;
+       ewma_rssi_init(&si->avg_rssi);
+
+       rtw_update_sta_info(rtwdev, si);
+
+       list_add_tail(&si->list, &rtwvif->sta_list);
+
+       rtw_info(rtwdev, "sta %pM joined with macid %d", sta->addr, si->mac_id);
+
+       return 0;
+}
+
+static int rtw_ops_sta_remove(struct ieee80211_hw *hw,
+                             struct ieee80211_vif *vif,
+                             struct ieee80211_sta *sta)
+{
+       struct rtw_dev *rtwdev = hw->priv;
+       struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
+
+       rtw_release_macid(rtwdev, si->mac_id);
+
+       list_del(&si->list);
+
+       rtw_info(rtwdev, "sta %pM with macid %d left", sta->addr, si->mac_id);
+
+       return 0;
+}
+
+static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+                          struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+                          struct ieee80211_key_conf *key)
+{
+       struct rtw_dev *rtwdev = hw->priv;
+       struct rtw_sec_desc *sec = &rtwdev->sec;
+       u8 hw_key_type;
+       u8 hw_key_idx;
+       int ret = 0;
+
+       switch (key->cipher) {
+       case WLAN_CIPHER_SUITE_WEP40:
+               hw_key_type = RTW_CAM_WEP40;
+               break;
+       case WLAN_CIPHER_SUITE_WEP104:
+               hw_key_type = RTW_CAM_WEP104;
+               break;
+       case WLAN_CIPHER_SUITE_TKIP:
+               hw_key_type = RTW_CAM_TKIP;
+               key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+               hw_key_type = RTW_CAM_AES;
+               key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
+               break;
+       default:
+               return -ENOTSUPP;
+       }
+
+       mutex_lock(&sec->mutex);
+
+       if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+               hw_key_idx = rtw_sec_get_free_cam(sec);
+       } else {
+               /* multiple interfaces? */
+               hw_key_idx = key->keyidx;
+       }
+
+       if (hw_key_idx > sec->total_cam_num) {
+               ret = -ENOSPC;
+               goto out;
+       }
+
+       switch (cmd) {
+       case SET_KEY:
+               /* need sw generated IV */
+               key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+               key->hw_key_idx = hw_key_idx;
+               rtw_sec_write_cam(rtwdev, sec, sta, key,
+                                 hw_key_type, hw_key_idx);
+               break;
+       case DISABLE_KEY:
+               rtw_sec_clear_cam(rtwdev, sec, key->hw_key_idx);
+               break;
+       }
+
+out:
+       mutex_unlock(&sec->mutex);
+
+       return ret;
+}
+
+static int rtw_ops_ampdu_action(struct ieee80211_hw *hw,
+                               struct ieee80211_vif *vif,
+                               struct ieee80211_ampdu_params *params)
+{
+       struct ieee80211_sta *sta = params->sta;
+       u16 tid = params->tid;
+
+       switch (params->action) {
+       case IEEE80211_AMPDU_TX_START:
+               ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               break;
+       case IEEE80211_AMPDU_TX_STOP_CONT:
+       case IEEE80211_AMPDU_TX_STOP_FLUSH:
+       case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
+               ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               break;
+       case IEEE80211_AMPDU_TX_OPERATIONAL:
+       case IEEE80211_AMPDU_RX_START:
+       case IEEE80211_AMPDU_RX_STOP:
+               break;
+       default:
+               WARN_ON(1);
+               return -ENOTSUPP;
+       }
+
+       return 0;
+}
+
+static void rtw_ops_sw_scan_start(struct ieee80211_hw *hw,
+                                 struct ieee80211_vif *vif,
+                                 const u8 *mac_addr)
+{
+       struct rtw_dev *rtwdev = hw->priv;
+       struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
+
+       rtw_leave_lps(rtwdev, rtwvif);
+
+       rtw_flag_set(rtwdev, RTW_FLAG_DIG_DISABLE);
+       rtw_flag_set(rtwdev, RTW_FLAG_SCANNING);
+}
+
+static void rtw_ops_sw_scan_complete(struct ieee80211_hw *hw,
+                                    struct ieee80211_vif *vif)
+{
+       struct rtw_dev *rtwdev = hw->priv;
+
+       rtw_flag_clear(rtwdev, RTW_FLAG_SCANNING);
+       rtw_flag_clear(rtwdev, RTW_FLAG_DIG_DISABLE);
+}
+
+const struct ieee80211_ops rtw_ops = {
+       .tx                     = rtw_ops_tx,
+       .start                  = rtw_ops_start,
+       .stop                   = rtw_ops_stop,
+       .config                 = rtw_ops_config,
+       .add_interface          = rtw_ops_add_interface,
+       .remove_interface       = rtw_ops_remove_interface,
+       .configure_filter       = rtw_ops_configure_filter,
+       .bss_info_changed       = rtw_ops_bss_info_changed,
+       .sta_add                = rtw_ops_sta_add,
+       .sta_remove             = rtw_ops_sta_remove,
+       .set_key                = rtw_ops_set_key,
+       .ampdu_action           = rtw_ops_ampdu_action,
+       .sw_scan_start          = rtw_ops_sw_scan_start,
+       .sw_scan_complete       = rtw_ops_sw_scan_complete,
+};
+EXPORT_SYMBOL(rtw_ops);
diff --git a/drivers/net/wireless/realtek/rtwlan/main.c 
b/drivers/net/wireless/realtek/rtwlan/main.c
new file mode 100644
index 0000000..0462a9e
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtwlan/main.c
@@ -0,0 +1,1164 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#include "main.h"
+#include "regd.h"
+#include "fw.h"
+#include "ps.h"
+#include "sec.h"
+#include "mac.h"
+#include "phy.h"
+#include "reg.h"
+#include "efuse.h"
+#include "debug.h"
+
+static struct ieee80211_channel rtw_channeltable_2g[] = {
+       {.center_freq = 2412, .hw_value = 1,},
+       {.center_freq = 2417, .hw_value = 2,},
+       {.center_freq = 2422, .hw_value = 3,},
+       {.center_freq = 2427, .hw_value = 4,},
+       {.center_freq = 2432, .hw_value = 5,},
+       {.center_freq = 2437, .hw_value = 6,},
+       {.center_freq = 2442, .hw_value = 7,},
+       {.center_freq = 2447, .hw_value = 8,},
+       {.center_freq = 2452, .hw_value = 9,},
+       {.center_freq = 2457, .hw_value = 10,},
+       {.center_freq = 2462, .hw_value = 11,},
+       {.center_freq = 2467, .hw_value = 12,},
+       {.center_freq = 2472, .hw_value = 13,},
+       {.center_freq = 2484, .hw_value = 14,},
+};
+
+static struct ieee80211_channel rtw_channeltable_5g[] = {
+       {.center_freq = 5180, .hw_value = 36,},
+       {.center_freq = 5200, .hw_value = 40,},
+       {.center_freq = 5220, .hw_value = 44,},
+       {.center_freq = 5240, .hw_value = 48,},
+       {.center_freq = 5260, .hw_value = 52,},
+       {.center_freq = 5280, .hw_value = 56,},
+       {.center_freq = 5300, .hw_value = 60,},
+       {.center_freq = 5320, .hw_value = 64,},
+       {.center_freq = 5500, .hw_value = 100,},
+       {.center_freq = 5520, .hw_value = 104,},
+       {.center_freq = 5540, .hw_value = 108,},
+       {.center_freq = 5560, .hw_value = 112,},
+       {.center_freq = 5580, .hw_value = 116,},
+       {.center_freq = 5600, .hw_value = 120,},
+       {.center_freq = 5620, .hw_value = 124,},
+       {.center_freq = 5640, .hw_value = 128,},
+       {.center_freq = 5660, .hw_value = 132,},
+       {.center_freq = 5680, .hw_value = 136,},
+       {.center_freq = 5700, .hw_value = 140,},
+       {.center_freq = 5745, .hw_value = 149,},
+       {.center_freq = 5765, .hw_value = 153,},
+       {.center_freq = 5785, .hw_value = 157,},
+       {.center_freq = 5805, .hw_value = 161,},
+       {.center_freq = 5825, .hw_value = 165,
+        .flags = IEEE80211_CHAN_NO_HT40MINUS},
+};
+
+static struct ieee80211_rate rtw_ratetable_2g[] = {
+       {.bitrate = 10, .hw_value = 0x00,},
+       {.bitrate = 20, .hw_value = 0x01,},
+       {.bitrate = 55, .hw_value = 0x02,},
+       {.bitrate = 110, .hw_value = 0x03,},
+       {.bitrate = 60, .hw_value = 0x04,},
+       {.bitrate = 90, .hw_value = 0x05,},
+       {.bitrate = 120, .hw_value = 0x06,},
+       {.bitrate = 180, .hw_value = 0x07,},
+       {.bitrate = 240, .hw_value = 0x08,},
+       {.bitrate = 360, .hw_value = 0x09,},
+       {.bitrate = 480, .hw_value = 0x0a,},
+       {.bitrate = 540, .hw_value = 0x0b,},
+};
+
+static struct ieee80211_rate rtw_ratetable_5g[] = {
+       {.bitrate = 60, .hw_value = 0x04,},
+       {.bitrate = 90, .hw_value = 0x05,},
+       {.bitrate = 120, .hw_value = 0x06,},
+       {.bitrate = 180, .hw_value = 0x07,},
+       {.bitrate = 240, .hw_value = 0x08,},
+       {.bitrate = 360, .hw_value = 0x09,},
+       {.bitrate = 480, .hw_value = 0x0a,},
+       {.bitrate = 540, .hw_value = 0x0b,},
+};
+
+static struct ieee80211_supported_band rtw_band_2ghz = {
+       .band = NL80211_BAND_2GHZ,
+
+       .channels = rtw_channeltable_2g,
+       .n_channels = ARRAY_SIZE(rtw_channeltable_2g),
+
+       .bitrates = rtw_ratetable_2g,
+       .n_bitrates = ARRAY_SIZE(rtw_ratetable_2g),
+
+       .ht_cap = {0},
+       .vht_cap = {0},
+};
+
+static struct ieee80211_supported_band rtw_band_5ghz = {
+       .band = NL80211_BAND_5GHZ,
+
+       .channels = rtw_channeltable_5g,
+       .n_channels = ARRAY_SIZE(rtw_channeltable_5g),
+
+       .bitrates = rtw_ratetable_5g,
+       .n_bitrates = ARRAY_SIZE(rtw_ratetable_5g),
+
+       .ht_cap = {0},
+       .vht_cap = {0},
+};
+
+static struct ieee80211_iface_limit rtw_5port_limits[] = {
+       { .max = 1, .types = BIT(NL80211_IFTYPE_AP) |
+                            BIT(NL80211_IFTYPE_ADHOC) |
+                            BIT(NL80211_IFTYPE_MESH_POINT), },
+       { .max = 5, .types = BIT(NL80211_IFTYPE_STATION), },
+};
+
+static struct ieee80211_iface_combination rtw_5port_if_combs[] = {
+       {
+               .limits = rtw_5port_limits,
+               .n_limits = ARRAY_SIZE(rtw_5port_limits),
+               .max_interfaces = 5,
+               .num_different_channels = 1,
+       },
+};
+
+static void rtw_watch_dog_work(struct work_struct *work)
+{
+       struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
+                                             watch_dog_work.work);
+       struct rtw_vif *rtwvif;
+
+       if (!rtw_flag_check(rtwdev, RTW_FLAG_RUNNING))
+               return;
+
+       ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->watch_dog_work,
+                                    RTW_WATCH_DOG_DELAY_TIME);
+
+       /* check if we can enter lps */
+       rtw_lps_enter_check(rtwdev);
+
+       /* reset tx/rx statictics */
+       rtwdev->stats.tx_unicast = 0;
+       rtwdev->stats.rx_unicast = 0;
+       rtwdev->stats.tx_cnt = 0;
+       rtwdev->stats.rx_cnt = 0;
+       list_for_each_entry(rtwvif, &rtwdev->vif_list, list) {
+               rtwvif->stats.tx_unicast = 0;
+               rtwvif->stats.rx_unicast = 0;
+               rtwvif->stats.tx_cnt = 0;
+               rtwvif->stats.rx_cnt = 0;
+       }
+
+       if (rtw_flag_check(rtwdev, RTW_FLAG_SCANNING))
+               return;
+
+       rtw_phy_dynamic_mechanism(rtwdev);
+
+       rtwdev->watch_dog_cnt++;
+}
+
+static void rtw_c2h_work(struct work_struct *work)
+{
+       struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, c2h_work);
+       struct sk_buff *skb, *tmp;
+
+       skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) {
+               skb_unlink(skb, &rtwdev->c2h_queue);
+               rtw_fw_c2h_cmd_handle(rtwdev, skb);
+               dev_kfree_skb_any(skb);
+       }
+}
+
+void rtw_get_channel_params(struct cfg80211_chan_def *chandef,
+                           struct rtw_channel_params *chan_params)
+{
+       struct ieee80211_channel *channel = chandef->chan;
+       enum nl80211_chan_width width = chandef->width;
+       u32 primary_freq, center_freq;
+       u8 center_chan;
+       u8 bandwidth = RTW_CHANNEL_WIDTH_20;
+       u8 primary_chan_idx = 0;
+
+       center_chan = channel->hw_value;
+       primary_freq = channel->center_freq;
+       center_freq = chandef->center_freq1;
+
+       switch (width) {
+       case NL80211_CHAN_WIDTH_20_NOHT:
+       case NL80211_CHAN_WIDTH_20:
+               bandwidth = RTW_CHANNEL_WIDTH_20;
+               primary_chan_idx = 0;
+               break;
+       case NL80211_CHAN_WIDTH_40:
+               bandwidth = RTW_CHANNEL_WIDTH_40;
+               if (primary_freq > center_freq) {
+                       primary_chan_idx = 1;
+                       center_chan -= 2;
+               } else {
+                       primary_chan_idx = 2;
+                       center_chan += 2;
+               }
+               break;
+       case NL80211_CHAN_WIDTH_80:
+               bandwidth = RTW_CHANNEL_WIDTH_80;
+               if (primary_freq > center_freq) {
+                       if (primary_freq - center_freq == 10) {
+                               primary_chan_idx = 1;
+                               center_chan -= 2;
+                       } else {
+                               primary_chan_idx = 3;
+                               center_chan -= 6;
+                       }
+               } else {
+                       if (center_freq - primary_freq == 10) {
+                               primary_chan_idx = 2;
+                               center_chan += 2;
+                       } else {
+                               primary_chan_idx = 4;
+                               center_chan += 6;
+                       }
+               }
+               break;
+       default:
+               center_chan = 0;
+               break;
+       }
+
+       chan_params->center_chan = center_chan;
+       chan_params->bandwidth = bandwidth;
+       chan_params->primary_chan_idx = primary_chan_idx;
+}
+
+void rtw_set_channel(struct rtw_dev *rtwdev)
+{
+       struct ieee80211_hw *hw = rtwdev->hw;
+       struct rtw_hal *hal = &rtwdev->hal;
+       struct rtw_chip_info *chip = rtwdev->chip;
+       struct rtw_channel_params ch_param;
+       u8 center_chan, bandwidth, primary_chan_idx;
+
+       rtw_get_channel_params(&hw->conf.chandef, &ch_param);
+       if (WARN(ch_param.center_chan == 0, "Invalid channel"))
+               return;
+
+       center_chan = ch_param.center_chan;
+       bandwidth = ch_param.bandwidth;
+       primary_chan_idx = ch_param.primary_chan_idx;
+
+       hal->current_band_width = bandwidth;
+       hal->current_channel = center_chan;
+       hal->current_band_type = center_chan > 14 ? RTW_BAND_5G : RTW_BAND_2G;
+       chip->ops->set_channel(rtwdev, center_chan, bandwidth, 
primary_chan_idx);
+
+       rtw_phy_set_tx_power_level(rtwdev, center_chan);
+}
+
+static void rtw_vif_write_addr(struct rtw_dev *rtwdev, u32 start, u8 *addr)
+{
+       int i;
+
+       for (i = 0; i < ETH_ALEN; i++)
+               rtw_write8(rtwdev, start + i, addr[i]);
+}
+
+void rtw_vif_port_config(struct rtw_dev *rtwdev,
+                        struct rtw_vif *rtwvif,
+                        u32 config)
+{
+       u32 addr, mask;
+
+       if (config & PORT_SET_MAC_ADDR) {
+               addr = rtwvif->conf->mac_addr.addr;
+               rtw_vif_write_addr(rtwdev, addr, rtwvif->mac_addr);
+       }
+       if (config & PORT_SET_BSSID) {
+               addr = rtwvif->conf->bssid.addr;
+               rtw_vif_write_addr(rtwdev, addr, rtwvif->bssid);
+       }
+       if (config & PORT_SET_NET_TYPE) {
+               addr = rtwvif->conf->net_type.addr;
+               mask = rtwvif->conf->net_type.mask;
+               rtw_write32_mask(rtwdev, addr, mask, rtwvif->net_type);
+       }
+       if (config & PORT_SET_AID) {
+               addr = rtwvif->conf->aid.addr;
+               mask = rtwvif->conf->aid.mask;
+               rtw_write32_mask(rtwdev, addr, mask, rtwvif->aid);
+       }
+}
+
+static u8 hw_bw_cap_to_bitamp(u8 bw_cap)
+{
+       u8 bw = 0;
+
+       switch (bw_cap) {
+       case EFUSE_HW_CAP_IGNORE:
+       case EFUSE_HW_CAP_SUPP_BW80:
+               bw |= BIT(RTW_CHANNEL_WIDTH_80);
+       /* fall through */
+       case EFUSE_HW_CAP_SUPP_BW40:
+               bw |= BIT(RTW_CHANNEL_WIDTH_40);
+       /* fall through */
+       default:
+               bw |= BIT(RTW_CHANNEL_WIDTH_20);
+               break;
+       }
+
+       return bw;
+}
+
+static void rtw_hw_config_rf_ant_num(struct rtw_dev *rtwdev, u8 hw_ant_num)
+{
+       struct rtw_hal *hal = &rtwdev->hal;
+
+       if (hw_ant_num == EFUSE_HW_CAP_IGNORE ||
+           hw_ant_num >= hal->rf_path_num)
+               return;
+
+       switch (hw_ant_num) {
+       case 1:
+               hal->rf_type = RF_1T1R;
+               hal->rf_path_num = 1;
+               hal->antenna_tx = BB_PATH_A;
+               hal->antenna_rx = BB_PATH_A;
+               break;
+       default:
+               WARN(1, "invalid hw configuration from efuse");
+               break;
+       }
+}
+
+static u64 get_vht_ra_mask(struct ieee80211_sta *sta)
+{
+       u64 ra_mask = 0;
+       u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map);
+       u8 vht_mcs_cap;
+       int i, nss;
+
+       /* 4SS, every two bits for MCS7/8/9 */
+       for (i = 0, nss = 12; i < 4; i++, mcs_map >>= 2, nss += 10) {
+               vht_mcs_cap = mcs_map & 0x3;
+               switch (vht_mcs_cap) {
+               case 2: /* MCS9 */
+                       ra_mask |= 0x3ff << nss;
+                       break;
+               case 1: /* MCS8 */
+                       ra_mask |= 0x1ff << nss;
+                       break;
+               case 0: /* MCS7 */
+                       ra_mask |= 0x0ff << nss;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       return ra_mask;
+}
+
+static u8 get_rate_id(u8 wireless_set, enum rtw_bandwidth bw_mode, u8 tx_num)
+{
+       u8 rate_id = 0;
+
+       switch (wireless_set) {
+       case WIRELESS_CCK:
+               rate_id = RTW_RATEID_B_20M;
+               break;
+       case WIRELESS_OFDM:
+               rate_id = RTW_RATEID_G;
+               break;
+       case WIRELESS_CCK | WIRELESS_OFDM:
+               rate_id = RTW_RATEID_BG;
+               break;
+       case WIRELESS_OFDM | WIRELESS_HT:
+               if (tx_num == 1)
+                       rate_id = RTW_RATEID_GN_N1SS;
+               else if (tx_num == 2)
+                       rate_id = RTW_RATEID_GN_N2SS;
+               else if (tx_num == 3)
+                       rate_id = RTW_RATEID_ARFR5_N_3SS;
+               break;
+       case WIRELESS_CCK | WIRELESS_OFDM | WIRELESS_HT:
+               if (bw_mode == RTW_CHANNEL_WIDTH_40) {
+                       if (tx_num == 1)
+                               rate_id = RTW_RATEID_BGN_40M_1SS;
+                       else if (tx_num == 2)
+                               rate_id = RTW_RATEID_BGN_40M_2SS;
+                       else if (tx_num == 3)
+                               rate_id = RTW_RATEID_ARFR5_N_3SS;
+                       else if (tx_num == 4)
+                               rate_id = RTW_RATEID_ARFR7_N_4SS;
+               } else {
+                       if (tx_num == 1)
+                               rate_id = RTW_RATEID_BGN_20M_1SS;
+                       else if (tx_num == 2)
+                               rate_id = RTW_RATEID_BGN_20M_2SS;
+                       else if (tx_num == 3)
+                               rate_id = RTW_RATEID_ARFR5_N_3SS;
+                       else if (tx_num == 4)
+                               rate_id = RTW_RATEID_ARFR7_N_4SS;
+               }
+               break;
+       case WIRELESS_OFDM | WIRELESS_VHT:
+               if (tx_num == 1)
+                       rate_id = RTW_RATEID_ARFR1_AC_1SS;
+               else if (tx_num == 2)
+                       rate_id = RTW_RATEID_ARFR0_AC_2SS;
+               else if (tx_num == 3)
+                       rate_id = RTW_RATEID_ARFR4_AC_3SS;
+               else if (tx_num == 4)
+                       rate_id = RTW_RATEID_ARFR6_AC_4SS;
+               break;
+       case WIRELESS_CCK | WIRELESS_OFDM | WIRELESS_VHT:
+               if (bw_mode >= RTW_CHANNEL_WIDTH_80) {
+                       if (tx_num == 1)
+                               rate_id = RTW_RATEID_ARFR1_AC_1SS;
+                       else if (tx_num == 2)
+                               rate_id = RTW_RATEID_ARFR0_AC_2SS;
+                       else if (tx_num == 3)
+                               rate_id = RTW_RATEID_ARFR4_AC_3SS;
+                       else if (tx_num == 4)
+                               rate_id = RTW_RATEID_ARFR6_AC_4SS;
+               } else {
+                       if (tx_num == 1)
+                               rate_id = RTW_RATEID_ARFR2_AC_2G_1SS;
+                       else if (tx_num == 2)
+                               rate_id = RTW_RATEID_ARFR3_AC_2G_2SS;
+                       else if (tx_num == 3)
+                               rate_id = RTW_RATEID_ARFR4_AC_3SS;
+                       else if (tx_num == 4)
+                               rate_id = RTW_RATEID_ARFR6_AC_4SS;
+               }
+               break;
+       default:
+               break;
+       }
+
+       return rate_id;
+}
+
+#define RA_MASK_CCK_RATES      0x0000f
+#define RA_MASK_OFDM_RATES     0x00ff0
+#define RA_MASK_HT_RATES_1SS   (0xff000 << 0)
+#define RA_MASK_HT_RATES_2SS   (0xff000 << 8)
+#define RA_MASK_HT_RATES_3SS   (0xff000 << 16)
+#define RA_MASK_HT_RATES       (RA_MASK_HT_RATES_1SS | \
+                                RA_MASK_HT_RATES_2SS | \
+                                RA_MASK_HT_RATES_3SS)
+#define RA_MASK_VHT_RATES_1SS  (0x3ff000 << 0)
+#define RA_MASK_VHT_RATES_2SS  (0x3ff000 << 10)
+#define RA_MASK_VHT_RATES_3SS  (0x3ff000 << 20)
+#define RA_MASK_VHT_RATES      (RA_MASK_VHT_RATES_1SS | \
+                                RA_MASK_VHT_RATES_2SS | \
+                                RA_MASK_VHT_RATES_3SS)
+#define RA_MASK_CCK_IN_HT      0x00005
+#define RA_MASK_CCK_IN_VHT     0x00005
+#define RA_MASK_OFDM_IN_VHT    0x00010
+#define RA_MASK_OFDM_IN_HT_2G  0x00010
+#define RA_MASK_OFDM_IN_HT_5G  0x00030
+
+void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si)
+{
+       struct ieee80211_sta *sta = si->sta;
+       struct rtw_efuse *efuse = &rtwdev->efuse;
+       struct rtw_hal *hal = &rtwdev->hal;
+       u8 rssi_level;
+       u8 wireless_set;
+       u8 bw_mode;
+       u8 rate_id;
+       u8 rf_type = RF_1T1R;
+       u8 stbc_en = 0;
+       u8 ldpc_en = 0;
+       u8 tx_num = 1;
+       u64 ra_mask = 0;
+       bool is_vht_enable = false;
+       bool is_support_sgi = false;
+
+       if (sta->vht_cap.vht_supported) {
+               is_vht_enable = true;
+               ra_mask |= get_vht_ra_mask(sta);
+               if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK)
+                       stbc_en = VHT_STBC_EN;
+               if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)
+                       ldpc_en = VHT_LDPC_EN;
+               if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80)
+                       is_support_sgi = true;
+       } else if (sta->ht_cap.ht_supported) {
+               ra_mask |= (sta->ht_cap.mcs.rx_mask[NL80211_BAND_5GHZ] << 20) |
+                          (sta->ht_cap.mcs.rx_mask[NL80211_BAND_2GHZ] << 12);
+               if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
+                       stbc_en = HT_STBC_EN;
+               if (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)
+                       ldpc_en = HT_LDPC_EN;
+               if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20 ||
+                   sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
+                       is_support_sgi = true;
+       }
+
+       if (hal->current_band_type == RTW_BAND_5G) {
+               ra_mask |= (u64)sta->supp_rates[NL80211_BAND_5GHZ] << 4;
+               if (sta->vht_cap.vht_supported) {
+                       ra_mask &= RA_MASK_VHT_RATES | RA_MASK_OFDM_IN_VHT;
+                       wireless_set = WIRELESS_OFDM | WIRELESS_VHT;
+               } else if (sta->ht_cap.ht_supported) {
+                       ra_mask &= RA_MASK_HT_RATES | RA_MASK_OFDM_IN_HT_5G;
+                       wireless_set = WIRELESS_OFDM | WIRELESS_HT;
+               } else {
+                       wireless_set = WIRELESS_OFDM;
+               }
+       } else if (hal->current_band_type == RTW_BAND_2G) {
+               ra_mask |= sta->supp_rates[NL80211_BAND_2GHZ];
+               if (sta->vht_cap.vht_supported) {
+                       ra_mask &= RA_MASK_VHT_RATES | RA_MASK_CCK_IN_VHT |
+                                  RA_MASK_OFDM_IN_VHT;
+                       wireless_set = WIRELESS_CCK | WIRELESS_OFDM |
+                                      WIRELESS_HT | WIRELESS_VHT;
+               } else if (sta->ht_cap.ht_supported) {
+                       ra_mask &= RA_MASK_HT_RATES | RA_MASK_CCK_IN_HT |
+                                  RA_MASK_OFDM_IN_HT_2G;
+                       wireless_set = WIRELESS_CCK | WIRELESS_OFDM |
+                                      WIRELESS_HT;
+               } else if (sta->supp_rates[0] <= 0xf) {
+                       wireless_set = WIRELESS_CCK;
+               } else {
+                       wireless_set = WIRELESS_CCK | WIRELESS_OFDM;
+               }
+       } else {
+               pr_err("Unknown band type\n");
+               wireless_set = 0;
+       }
+
+       if (efuse->hw_cap.nss == 1) {
+               ra_mask &= RA_MASK_VHT_RATES_1SS;
+               ra_mask &= RA_MASK_HT_RATES_1SS;
+       }
+
+       switch (sta->bandwidth) {
+       case IEEE80211_STA_RX_BW_80:
+               bw_mode = RTW_CHANNEL_WIDTH_80;
+               break;
+       case IEEE80211_STA_RX_BW_40:
+               bw_mode = RTW_CHANNEL_WIDTH_40;
+               break;
+       default:
+               bw_mode = RTW_CHANNEL_WIDTH_20;
+               break;
+       }
+
+       if (sta->vht_cap.vht_supported && ra_mask & 0xffc00000) {
+               tx_num = 2;
+               rf_type = RF_2T2R;
+       } else if (sta->ht_cap.ht_supported && ra_mask & 0xfff00000) {
+               tx_num = 2;
+               rf_type = RF_2T2R;
+       }
+
+       rate_id = get_rate_id(wireless_set, bw_mode, tx_num);
+
+       if (wireless_set != WIRELESS_CCK) {
+               rssi_level = si->rssi_level;
+               if (rssi_level == 0)
+                       ra_mask &= 0xffffffffffffffffULL;
+               else if (rssi_level == 1)
+                       ra_mask &= 0xfffffffffffffff0ULL;
+               else if (rssi_level == 2)
+                       ra_mask &= 0xffffffffffffefe0ULL;
+               else if (rssi_level == 3)
+                       ra_mask &= 0xffffffffffffcfc0ULL;
+               else if (rssi_level == 4)
+                       ra_mask &= 0xffffffffffff8f80ULL;
+               else if (rssi_level >= 5)
+                       ra_mask &= 0xffffffffffff0f00ULL;
+       }
+
+       si->bw_mode = bw_mode;
+       si->stbc_en = stbc_en;
+       si->ldpc_en = ldpc_en;
+       si->rf_type = rf_type;
+       si->wireless_set = wireless_set;
+       si->sgi_enable = is_support_sgi;
+       si->vht_enable = is_vht_enable;
+       si->ra_mask = ra_mask;
+       si->rate_id = rate_id;
+
+       rtw_fw_send_ra_info(rtwdev, si);
+}
+
+static int rtw_power_on(struct rtw_dev *rtwdev)
+{
+       struct rtw_chip_info *chip = rtwdev->chip;
+       struct rtw_fw_state *fw = &rtwdev->fw;
+       int ret;
+
+       ret = rtw_hci_setup(rtwdev);
+       if (ret) {
+               rtw_err(rtwdev, "failed to setup hci\n");
+               goto err;
+       }
+
+       /* power on MAC before firmware downloaded */
+       ret = rtw_mac_power_on(rtwdev);
+       if (ret) {
+               rtw_err(rtwdev, "failed to power on mac\n");
+               goto err;
+       }
+
+       ret = rtw_download_firmware(rtwdev, fw->data, fw->size);
+       if (ret) {
+               rtw_err(rtwdev, "failed to download firmware\n");
+               goto err_off;
+       }
+
+       /* config mac after firmware downloaded */
+       ret = rtw_mac_init(rtwdev);
+       if (ret) {
+               rtw_err(rtwdev, "failed to configure mac\n");
+               goto err_off;
+       }
+
+       chip->ops->phy_set_param(rtwdev);
+
+       ret = rtw_hci_start(rtwdev);
+       if (ret) {
+               rtw_err(rtwdev, "failed to start hci\n");
+               goto err_off;
+       }
+
+       return 0;
+
+err_off:
+       rtw_mac_power_off(rtwdev);
+
+err:
+       return ret;
+}
+
+int rtw_core_start(struct rtw_dev *rtwdev)
+{
+       int ret;
+
+       ret = rtw_power_on(rtwdev);
+       if (ret)
+               return ret;
+
+       rtwdev->hal.last_box_num = 0;
+
+       rtw_sec_enable_sec_engine(rtwdev);
+
+       /* rcr reset after powered on */
+       rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr);
+
+       ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->watch_dog_work,
+                                    RTW_WATCH_DOG_DELAY_TIME);
+
+       rtw_flag_set(rtwdev, RTW_FLAG_RUNNING);
+
+       return 0;
+}
+
+static void rtw_power_off(struct rtw_dev *rtwdev)
+{
+       rtwdev->hci.ops->stop(rtwdev);
+       rtw_mac_power_off(rtwdev);
+}
+
+void rtw_core_stop(struct rtw_dev *rtwdev)
+{
+       rtw_flag_clear(rtwdev, RTW_FLAG_RUNNING);
+       rtw_flag_clear(rtwdev, RTW_FLAG_FW_RUNNING);
+
+       cancel_delayed_work_sync(&rtwdev->watch_dog_work);
+
+       rtw_power_off(rtwdev);
+}
+
+static void rtw_init_ht_cap(struct rtw_dev *rtwdev,
+                           struct ieee80211_sta_ht_cap *ht_cap)
+{
+       struct rtw_efuse *efuse = &rtwdev->efuse;
+
+       ht_cap->ht_supported = true;
+       ht_cap->cap = 0;
+       ht_cap->cap |= IEEE80211_HT_CAP_SGI_20 |
+                       IEEE80211_HT_CAP_MAX_AMSDU |
+                       IEEE80211_HT_CAP_LDPC_CODING |
+                       (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
+       if (efuse->hw_cap.bw & BIT(RTW_CHANNEL_WIDTH_40))
+               ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+                               IEEE80211_HT_CAP_DSSSCCK40 |
+                               IEEE80211_HT_CAP_SGI_40;
+       ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+       ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
+       ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+       if (efuse->hw_cap.nss > 1) {
+               ht_cap->mcs.rx_mask[0] = 0xFF;
+               ht_cap->mcs.rx_mask[1] = 0xFF;
+               ht_cap->mcs.rx_mask[4] = 0x01;
+               ht_cap->mcs.rx_highest = cpu_to_le16(300);
+       } else {
+               ht_cap->mcs.rx_mask[0] = 0xFF;
+               ht_cap->mcs.rx_mask[1] = 0x00;
+               ht_cap->mcs.rx_mask[4] = 0x01;
+               ht_cap->mcs.rx_highest = cpu_to_le16(150);
+       }
+}
+
+static void rtw_init_vht_cap(struct rtw_dev *rtwdev,
+                            struct ieee80211_sta_vht_cap *vht_cap)
+{
+       struct rtw_efuse *efuse = &rtwdev->efuse;
+       u16 mcs_map;
+       __le16 highest;
+
+       if (efuse->hw_cap.ptcl != EFUSE_HW_CAP_IGNORE &&
+           efuse->hw_cap.ptcl != EFUSE_HW_CAP_PTCL_VHT)
+               return;
+
+       vht_cap->vht_supported = true;
+       vht_cap->cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
+                      IEEE80211_VHT_CAP_RXLDPC |
+                      IEEE80211_VHT_CAP_SHORT_GI_80 |
+                      IEEE80211_VHT_CAP_TXSTBC |
+                      IEEE80211_VHT_CAP_RXSTBC_1 |
+                      IEEE80211_VHT_CAP_HTC_VHT |
+                      IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK |
+                      0;
+       mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
+                 IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
+                 IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
+                 IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
+                 IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
+                 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
+                 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14;
+       if (efuse->hw_cap.nss > 1) {
+               highest = cpu_to_le16(780);
+               mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << 2;
+       } else {
+               highest = cpu_to_le16(390);
+               mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << 2;
+       }
+
+       vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
+       vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
+       vht_cap->vht_mcs.rx_highest = highest;
+       vht_cap->vht_mcs.tx_highest = highest;
+}
+
+static void rtw_set_supported_band(struct ieee80211_hw *hw,
+                                  struct rtw_chip_info *chip)
+{
+       struct rtw_dev *rtwdev = hw->priv;
+       struct ieee80211_supported_band *sband;
+
+       if (chip->band & RTW_BAND_2G) {
+               sband = kmalloc(sizeof(*sband), GFP_KERNEL);
+               memcpy(sband, &rtw_band_2ghz, sizeof(rtw_band_2ghz));
+               if (chip->ht_supported)
+                       rtw_init_ht_cap(rtwdev, &sband->ht_cap);
+               hw->wiphy->bands[NL80211_BAND_2GHZ] = sband;
+       }
+
+       if (chip->band & RTW_BAND_5G) {
+               sband = kmalloc(sizeof(*sband), GFP_KERNEL);
+               memcpy(sband, &rtw_band_5ghz, sizeof(rtw_band_5ghz));
+               if (chip->ht_supported)
+                       rtw_init_ht_cap(rtwdev, &sband->ht_cap);
+               if (chip->vht_supported)
+                       rtw_init_vht_cap(rtwdev, &sband->vht_cap);
+               hw->wiphy->bands[NL80211_BAND_5GHZ] = sband;
+       }
+}
+
+static void rtw_unset_supported_band(struct ieee80211_hw *hw,
+                                    struct rtw_chip_info *chip)
+{
+       if (chip->band & RTW_BAND_2G)
+               kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]);
+       if (chip->band & RTW_BAND_5G)
+               kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]);
+}
+
+static int rtw_load_firmware(struct rtw_dev *rtwdev, const char *fw_name)
+{
+       struct rtw_fw_state *fw = &rtwdev->fw;
+       const struct firmware *firmware;
+       int ret;
+
+       ret = request_firmware(&firmware, fw_name, rtwdev->dev);
+       if (ret) {
+               rtw_err(rtwdev, "failed to request firmware\n");
+               return ret;
+       }
+
+       fw->firmware = firmware;
+       fw->data = firmware->data;
+       fw->size = firmware->size;
+
+       return 0;
+}
+
+static int rtw_chip_parameter_setup(struct rtw_dev *rtwdev)
+{
+       struct rtw_chip_info *chip = rtwdev->chip;
+       struct rtw_hal *hal = &rtwdev->hal;
+       struct rtw_efuse *efuse = &rtwdev->efuse;
+       u32 wl_bt_pwr_ctrl;
+       int ret = 0;
+
+       switch (rtw_hci_type(rtwdev)) {
+       case RTW_HCI_TYPE_PCIE:
+               rtwdev->hci.rpwm_addr = 0x03d9;
+               break;
+       default:
+               rtw_err(rtwdev, "unsupported hci type");
+               return -EINVAL;
+       }
+
+       wl_bt_pwr_ctrl = rtw_read32(rtwdev, REG_WL_BT_PWR_CTRL);
+       if (wl_bt_pwr_ctrl & BIT_BT_FUNC_EN)
+               rtwdev->efuse.btcoex = true;
+       hal->chip_version = rtw_read32(rtwdev, REG_SYS_CFG1);
+       hal->fab_version = BIT_GET_VENDOR_ID(hal->chip_version) >> 2;
+       hal->cut_version = BIT_GET_CHIP_VER(hal->chip_version);
+       hal->mp_chip = (hal->chip_version & BIT_RTL_ID) ? 0 : 1;
+       if (hal->chip_version & BIT_RF_TYPE_ID) {
+               hal->rf_type = RF_2T2R;
+               hal->rf_path_num = 2;
+               hal->antenna_tx = BB_PATH_AB;
+               hal->antenna_rx = BB_PATH_AB;
+       } else {
+               hal->rf_type = RF_1T1R;
+               hal->rf_path_num = 1;
+               hal->antenna_tx = BB_PATH_A;
+               hal->antenna_rx = BB_PATH_A;
+       }
+
+       if (hal->fab_version == 2)
+               hal->fab_version = 1;
+       else if (hal->fab_version == 1)
+               hal->fab_version = 2;
+
+       efuse->physical_size = chip->phy_efuse_size;
+       efuse->logical_size = chip->log_efuse_size;
+       efuse->protect_size = chip->ptct_efuse_size;
+
+       /* default use ack */
+       rtwdev->hal.rcr |= BIT_VHT_DACK;
+
+       return ret;
+}
+
+static int rtw_chip_efuse_enable(struct rtw_dev *rtwdev)
+{
+       struct rtw_fw_state *fw = &rtwdev->fw;
+       int ret;
+
+       ret = rtw_hci_setup(rtwdev);
+       if (ret) {
+               rtw_err(rtwdev, "failed to setup hci\n");
+               goto err;
+       }
+
+       ret = rtw_mac_power_on(rtwdev);
+       if (ret) {
+               rtw_err(rtwdev, "failed to power on mac\n");
+               goto err;
+       }
+
+       rtw_write8(rtwdev, REG_C2HEVT, C2H_HW_FEATURE_DUMP);
+       ret = rtw_download_firmware(rtwdev, fw->data, fw->size);
+       if (ret) {
+               rtw_err(rtwdev, "failed to download firmware\n");
+               goto err_off;
+       }
+
+       /* config mac after firmware downloaded */
+       ret = rtw_mac_init(rtwdev);
+       if (ret) {
+               rtw_err(rtwdev, "failed to configure mac\n");
+               goto err_off;
+       }
+
+       ret = rtw_hci_start(rtwdev);
+       if (ret) {
+               rtw_err(rtwdev, "failed to start hci\n");
+               goto err_off;
+       }
+
+       return 0;
+
+err_off:
+       rtw_mac_power_off(rtwdev);
+
+err:
+       return ret;
+}
+
+static int rtw_dump_hw_feature(struct rtw_dev *rtwdev)
+{
+       struct rtw_efuse *efuse = &rtwdev->efuse;
+       struct efuse_hw_cap *hw_cap;
+       u8 hw_feature[HW_FEATURE_LEN];
+       u8 id;
+       int i;
+
+       BUILD_BUG_ON(sizeof(*hw_cap) != HW_FEATURE_LEN);
+
+       id = rtw_read8(rtwdev, REG_C2HEVT);
+       if (id != C2H_HW_FEATURE_REPORT) {
+               rtw_err(rtwdev, "failed to read hw feature report\n");
+               return -EBUSY;
+       }
+
+       for (i = 0; i < HW_FEATURE_LEN; i++)
+               hw_feature[i] = rtw_read8(rtwdev, REG_C2HEVT + 2 + i);
+
+       rtw_write8(rtwdev, REG_C2HEVT, 0);
+
+       hw_cap = (struct efuse_hw_cap *)hw_feature;
+
+       efuse->hw_cap.bw = hw_bw_cap_to_bitamp(hw_cap->bw);
+       efuse->hw_cap.hci = hw_cap->hci;
+       efuse->hw_cap.nss = hw_cap->nss;
+       efuse->hw_cap.ptcl = hw_cap->ptcl;
+       efuse->hw_cap.ant_num = hw_cap->ant_num;
+
+       rtw_hw_config_rf_ant_num(rtwdev, efuse->hw_cap.ant_num);
+
+       if (efuse->hw_cap.nss == EFUSE_HW_CAP_IGNORE)
+               efuse->hw_cap.nss = rtwdev->hal.rf_path_num;
+
+       rtw_dbg(rtwdev, "hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, 
ant_num=%d, nss=%d",
+               efuse->hw_cap.hci, efuse->hw_cap.bw, efuse->hw_cap.ptcl,
+               efuse->hw_cap.ant_num, efuse->hw_cap.nss);
+
+       return 0;
+}
+
+static void rtw_chip_efuse_disable(struct rtw_dev *rtwdev)
+{
+       rtw_hci_stop(rtwdev);
+       rtw_mac_power_off(rtwdev);
+}
+
+static int rtw_chip_efuse_info_setup(struct rtw_dev *rtwdev)
+{
+       struct rtw_efuse *efuse = &rtwdev->efuse;
+       int ret;
+
+       /* power on mac to read efuse */
+       ret = rtw_chip_efuse_enable(rtwdev);
+       if (ret)
+               return ret;
+
+       ret = rtw_parse_efuse_map(rtwdev);
+       if (ret)
+               return ret;
+
+       ret = rtw_dump_hw_feature(rtwdev);
+       if (ret)
+               return ret;
+
+       ret = rtw_check_supported_rfe(rtwdev);
+       if (ret)
+               return ret;
+
+       if (efuse->crystal_cap == 0xff)
+               efuse->crystal_cap = 0;
+       if (efuse->pa_type_2g == 0xff)
+               efuse->pa_type_2g = 0;
+       if (efuse->pa_type_5g == 0xff)
+               efuse->pa_type_5g = 0;
+       if (efuse->lna_type_2g == 0xff)
+               efuse->lna_type_2g = 0;
+       if (efuse->lna_type_5g == 0xff)
+               efuse->lna_type_5g = 0;
+       if (efuse->channel_plan == 0xff)
+               efuse->channel_plan = 0x7f;
+       if (efuse->bt_setting & BIT(0))
+               efuse->share_ant = true;
+       if (efuse->regd == 0xff)
+               efuse->regd = 0;
+
+       efuse->ext_pa_2g = efuse->pa_type_2g & BIT(4) ? 1 : 0;
+       efuse->ext_lna_2g = efuse->lna_type_2g & BIT(3) ? 1 : 0;
+       efuse->ext_pa_5g = efuse->pa_type_5g & BIT(0) ? 1 : 0;
+       efuse->ext_lna_2g = efuse->lna_type_5g & BIT(3) ? 1 : 0;
+
+       rtw_chip_efuse_disable(rtwdev);
+
+       return 0;
+}
+
+static int rtw_chip_board_info_setup(struct rtw_dev *rtwdev)
+{
+       struct rtw_hal *hal = &rtwdev->hal;
+       const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev);
+
+       if (!rfe_def)
+               return -ENODEV;
+
+       rtw_phy_setup_phy_cond(rtwdev, 0);
+
+       rtw_hw_init_tx_power(hal);
+       if (rtwdev->chip->id != RTW_CHIP_TYPE_8822C)
+               rtw_load_table(rtwdev, rfe_def->phy_pg_tbl);
+       rtw_load_table(rtwdev, rfe_def->txpwr_lmt_tbl);
+       rtw_phy_tx_power_by_rate_config(hal);
+       rtw_phy_tx_power_limit_config(hal);
+
+       return 0;
+}
+
+int rtw_chip_info_setup(struct rtw_dev *rtwdev)
+{
+       int ret;
+
+       ret = rtw_chip_parameter_setup(rtwdev);
+       if (ret) {
+               rtw_err(rtwdev, "failed to setup chip parameters\n");
+               goto err_out;
+       }
+
+       ret = rtw_chip_efuse_info_setup(rtwdev);
+       if (ret) {
+               rtw_err(rtwdev, "failed to setup chip efuse info\n");
+               goto err_out;
+       }
+
+       ret = rtw_chip_board_info_setup(rtwdev);
+       if (ret) {
+               rtw_err(rtwdev, "failed to setup chip board info\n");
+               goto err_out;
+       }
+
+       return 0;
+
+err_out:
+       return ret;
+}
+EXPORT_SYMBOL(rtw_chip_info_setup);
+
+int rtw_core_init(struct rtw_dev *rtwdev)
+{
+       int ret;
+
+       INIT_LIST_HEAD(&rtwdev->vif_list);
+       INIT_LIST_HEAD(&rtwdev->rsvd_page_list);
+       rtw_add_rsvd_page(rtwdev, RSVD_BEACON, false);
+
+       INIT_DELAYED_WORK(&rtwdev->watch_dog_work, rtw_watch_dog_work);
+       INIT_DELAYED_WORK(&rtwdev->lps_work, rtw_lps_work);
+       INIT_WORK(&rtwdev->c2h_work, rtw_c2h_work);
+       skb_queue_head_init(&rtwdev->c2h_queue);
+
+       spin_lock_init(&rtwdev->dm_lock);
+       spin_lock_init(&rtwdev->rf_lock);
+
+       mutex_init(&rtwdev->sec.mutex);
+       mutex_init(&rtwdev->hal.h2c_mutex);
+       mutex_init(&rtwdev->hal.tx_power_mutex);
+       mutex_init(&rtwdev->efuse.mutex);
+       rtwdev->sec.total_cam_num = 32;
+       rtwdev->macid_used[RTW_BC_MC_MACID] = true;
+
+       /* default rx filter setting */
+       rtwdev->hal.rcr = BIT_APP_FCS | BIT_APP_MIC | BIT_APP_ICV |
+                         BIT_HTC_LOC_CTRL | BIT_APP_PHYSTS |
+                         BIT_AB | BIT_AM | BIT_APM;
+
+       ret = rtw_load_firmware(rtwdev, rtwdev->chip->fw_name);
+       if (ret) {
+               rtw_warn(rtwdev, "no firmware loaded");
+               return ret;
+       }
+
+       rtw_debugfs_init(rtwdev);
+
+       return 0;
+}
+EXPORT_SYMBOL(rtw_core_init);
+
+void rtw_core_deinit(struct rtw_dev *rtwdev)
+{
+       struct rtw_fw_state *fw = &rtwdev->fw;
+       struct rtw_rsvd_page *rsvd_pkt, *tmp;
+
+       if (fw->firmware)
+               release_firmware(fw->firmware);
+
+       list_for_each_entry_safe(rsvd_pkt, tmp, &rtwdev->rsvd_page_list, list) {
+               list_del(&rsvd_pkt->list);
+               kfree(rsvd_pkt);
+       }
+
+       rtw_debugfs_deinit();
+       mutex_destroy(&rtwdev->sec.mutex);
+       mutex_destroy(&rtwdev->hal.h2c_mutex);
+       mutex_destroy(&rtwdev->hal.tx_power_mutex);
+       mutex_destroy(&rtwdev->efuse.mutex);
+}
+EXPORT_SYMBOL(rtw_core_deinit);
+
+int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
+{
+       int max_tx_headroom = 0;
+       int ret;
+
+       /* TODO: USB & SDIO may need extra room? */
+       max_tx_headroom = rtwdev->chip->tx_pkt_desc_sz;
+
+       hw->extra_tx_headroom = max_tx_headroom;
+       hw->queues = IEEE80211_NUM_ACS;
+       hw->sta_data_size = sizeof(struct rtw_sta_info);
+       hw->vif_data_size = sizeof(struct rtw_vif);
+
+       ieee80211_hw_set(hw, SIGNAL_DBM);
+       ieee80211_hw_set(hw, RX_INCLUDES_FCS);
+       ieee80211_hw_set(hw, AMPDU_AGGREGATION);
+       ieee80211_hw_set(hw, MFP_CAPABLE);
+       ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
+       ieee80211_hw_set(hw, SUPPORTS_PS);
+       ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
+
+       hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+                                    BIT(NL80211_IFTYPE_AP) |
+                                    BIT(NL80211_IFTYPE_ADHOC) |
+                                    BIT(NL80211_IFTYPE_MESH_POINT);
+       hw->wiphy->iface_combinations = rtw_5port_if_combs;
+       hw->wiphy->n_iface_combinations = ARRAY_SIZE(rtw_5port_if_combs);
+
+       hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
+                           WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
+
+       rtw_set_supported_band(hw, rtwdev->chip);
+       SET_IEEE80211_PERM_ADDR(hw, rtwdev->efuse.addr);
+
+       rtw_regd_init(rtwdev, rtw_regd_notifier);
+
+       ret = ieee80211_register_hw(hw);
+       if (ret) {
+               rtw_err(rtwdev, "hw register failed");
+               return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(rtw_register_hw);
+
+void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw)
+{
+       struct rtw_chip_info *chip = rtwdev->chip;
+
+       ieee80211_unregister_hw(hw);
+       rtw_unset_supported_band(hw, chip);
+}
+EXPORT_SYMBOL(rtw_unregister_hw);
+
+MODULE_AUTHOR("Realtek Corporation");
+MODULE_DESCRIPTION("Realtek 802.11ac wireless core module");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/realtek/rtwlan/main.h 
b/drivers/net/wireless/realtek/rtwlan/main.h
new file mode 100644
index 0000000..6853266
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtwlan/main.h
@@ -0,0 +1,1188 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#ifndef __RTK_MAIN_H_
+#define __RTK_MAIN_H_
+
+#include <net/mac80211.h>
+#include <linux/vmalloc.h>
+#include <linux/firmware.h>
+#include <linux/average.h>
+
+#define RTW_MAX_MAC_ID_NUM             32
+#define RTW_MAX_SEC_CAM_NUM            32
+
+#define RTW_WATCH_DOG_DELAY_TIME       (HZ * 2)
+
+#define RFREG_MASK                     0xfffff
+#define INV_RF_DATA                    0xffffffff
+#define TX_PAGE_SIZE_SHIFT             7
+
+#define RTW_CHANNEL_WIDTH_MAX          3
+#define RTW_RF_PATH_MAX                        4
+#define HW_FEATURE_LEN                 13
+
+extern const struct ieee80211_ops rtw_ops;
+extern struct rtw_chip_info rtw8822b_hw_spec;
+extern struct rtw_chip_info rtw8822c_hw_spec;
+
+#define BIT_LEN_MASK_32(__bitlen) (0xFFFFFFFF >> (32 - (__bitlen)))
+#define BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen)                          
\
+       (BIT_LEN_MASK_32(__bitlen) << (__bitoffset))
+#define LE_P4BYTE_TO_HOST_4BYTE(__start) (le32_to_cpu(*((__le32 *)(__start))))
+#define LE_BITS_CLEARED_TO_4BYTE(__start, __bitoffset, __bitlen)               
\
+       (LE_P4BYTE_TO_HOST_4BYTE(__start) &                                    \
+        (~BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen)))
+#define LE_BITS_TO_4BYTE(__start, __bitoffset, __bitlen)                       
\
+       ((LE_P4BYTE_TO_HOST_4BYTE(__start) >> (__bitoffset)) &                 \
+        BIT_LEN_MASK_32(__bitlen))
+#define SET_BITS_TO_LE_4BYTE(__start, __bitoffset, __bitlen, __value)          
\
+       do {                                                                   \
+               *((__le32 *)(__start)) = \
+               cpu_to_le32( \
+               LE_BITS_CLEARED_TO_4BYTE(__start, __bitoffset, __bitlen) |     \
+               ((((u32)__value) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset))\
+               );                                                             \
+       } while (0)
+
+#define RTW_MAX_CHANNEL_NUM_2G 14
+#define RTW_MAX_CHANNEL_NUM_5G 49
+
+struct rtw_dev;
+
+enum rtw_hci_type {
+       RTW_HCI_TYPE_PCIE,
+       RTW_HCI_TYPE_USB,
+       RTW_HCI_TYPE_SDIO,
+
+       RTW_HCI_TYPE_UNDEFINE,
+};
+
+struct rtw_hci {
+       struct rtw_hci_ops *ops;
+       enum rtw_hci_type type;
+
+       u32 rpwm_addr;
+
+       u8 bulkout_num;
+};
+
+enum rtw_supported_band {
+       RTW_BAND_2G = 1 << 0,
+       RTW_BAND_5G = 1 << 1,
+       RTW_BAND_60G = 1 << 2,
+
+       RTW_BAND_MAX,
+};
+
+enum rtw_bandwidth {
+       RTW_CHANNEL_WIDTH_20    = 0,
+       RTW_CHANNEL_WIDTH_40    = 1,
+       RTW_CHANNEL_WIDTH_80    = 2,
+       RTW_CHANNEL_WIDTH_160   = 3,
+       RTW_CHANNEL_WIDTH_80_80 = 4,
+       RTW_CHANNEL_WIDTH_5     = 5,
+       RTW_CHANNEL_WIDTH_10    = 6,
+};
+
+enum rtw_net_type {
+       RTW_NET_NO_LINK         = 0,
+       RTW_NET_AD_HOC          = 1,
+       RTW_NET_MGD_LINKED      = 2,
+       RTW_NET_AP_MODE         = 3,
+};
+
+enum rtw_rf_type {
+       RF_1T1R                 = 0,
+       RF_1T2R                 = 1,
+       RF_2T2R                 = 2,
+       RF_2T3R                 = 3,
+       RF_2T4R                 = 4,
+       RF_3T3R                 = 5,
+       RF_3T4R                 = 6,
+       RF_4T4R                 = 7,
+       RF_TYPE_MAX,
+};
+
+enum rtw_rf_path {
+       RF_PATH_A = 0,
+       RF_PATH_B = 1,
+       RF_PATH_C = 2,
+       RF_PATH_D = 3,
+};
+
+enum rtw_bb_path {
+       BB_PATH_A = BIT(0),
+       BB_PATH_B = BIT(1),
+       BB_PATH_C = BIT(2),
+       BB_PATH_D = BIT(3),
+
+       BB_PATH_AB = (BB_PATH_A | BB_PATH_B),
+       BB_PATH_AC = (BB_PATH_A | BB_PATH_C),
+       BB_PATH_AD = (BB_PATH_A | BB_PATH_D),
+       BB_PATH_BC = (BB_PATH_B | BB_PATH_C),
+       BB_PATH_BD = (BB_PATH_B | BB_PATH_D),
+       BB_PATH_CD = (BB_PATH_C | BB_PATH_D),
+
+       BB_PATH_ABC = (BB_PATH_A | BB_PATH_B | BB_PATH_C),
+       BB_PATH_ABD = (BB_PATH_A | BB_PATH_B | BB_PATH_D),
+       BB_PATH_ACD = (BB_PATH_A | BB_PATH_C | BB_PATH_D),
+       BB_PATH_BCD = (BB_PATH_B | BB_PATH_C | BB_PATH_D),
+
+       BB_PATH_ABCD = (BB_PATH_A | BB_PATH_B | BB_PATH_C | BB_PATH_D),
+};
+
+enum rtw_rate_section {
+       RTW_RATE_SECTION_CCK = 0,
+       RTW_RATE_SECTION_OFDM,
+       RTW_RATE_SECTION_HT_1S,
+       RTW_RATE_SECTION_HT_2S,
+       RTW_RATE_SECTION_VHT_1S,
+       RTW_RATE_SECTION_VHT_2S,
+
+       /* keep last */
+       RTW_RATE_SECTION_MAX,
+};
+
+enum rtw_wireless_set {
+       WIRELESS_CCK    = 0x00000001,
+       WIRELESS_OFDM   = 0x00000002,
+       WIRELESS_HT     = 0x00000004,
+       WIRELESS_VHT    = 0x00000008,
+};
+
+#define HT_STBC_EN     BIT(0)
+#define VHT_STBC_EN    BIT(1)
+#define HT_LDPC_EN     BIT(0)
+#define VHT_LDPC_EN    BIT(1)
+
+enum rtw_chip_type {
+       RTW_CHIP_TYPE_8822B,
+       RTW_CHIP_TYPE_8822C,
+};
+
+enum rtw_tx_queue_type {
+       /* the order of AC queues matters */
+       RTW_TX_QUEUE_BK = 0x0,
+       RTW_TX_QUEUE_BE = 0x1,
+       RTW_TX_QUEUE_VI = 0x2,
+       RTW_TX_QUEUE_VO = 0x3,
+
+       RTW_TX_QUEUE_BCN = 0x4,
+       RTW_TX_QUEUE_MGMT = 0x5,
+       RTW_TX_QUEUE_HI0 = 0x6,
+       RTW_TX_QUEUE_H2C = 0x7,
+       /* keep it last */
+       RTK_MAX_TX_QUEUE_NUM
+};
+
+enum rtw_rx_queue_type {
+       RTW_RX_QUEUE_MPDU = 0x0,
+       RTW_RX_QUEUE_C2H = 0x1,
+       /* keep it last */
+       RTK_MAX_RX_QUEUE_NUM
+};
+
+enum rtw_rate_index {
+       RTW_RATEID_BGN_40M_2SS  = 0,
+       RTW_RATEID_BGN_40M_1SS  = 1,
+       RTW_RATEID_BGN_20M_2SS  = 2,
+       RTW_RATEID_BGN_20M_1SS  = 3,
+       RTW_RATEID_GN_N2SS      = 4,
+       RTW_RATEID_GN_N1SS      = 5,
+       RTW_RATEID_BG           = 6,
+       RTW_RATEID_G            = 7,
+       RTW_RATEID_B_20M        = 8,
+       RTW_RATEID_ARFR0_AC_2SS = 9,
+       RTW_RATEID_ARFR1_AC_1SS = 10,
+       RTW_RATEID_ARFR2_AC_2G_1SS = 11,
+       RTW_RATEID_ARFR3_AC_2G_2SS = 12,
+       RTW_RATEID_ARFR4_AC_3SS = 13,
+       RTW_RATEID_ARFR5_N_3SS  = 14,
+       RTW_RATEID_ARFR7_N_4SS  = 15,
+       RTW_RATEID_ARFR6_AC_4SS = 16
+};
+
+enum rtw_trx_desc_rate {
+       DESC_RATE1M     = 0x00,
+       DESC_RATE2M     = 0x01,
+       DESC_RATE5_5M   = 0x02,
+       DESC_RATE11M    = 0x03,
+
+       DESC_RATE6M     = 0x04,
+       DESC_RATE9M     = 0x05,
+       DESC_RATE12M    = 0x06,
+       DESC_RATE18M    = 0x07,
+       DESC_RATE24M    = 0x08,
+       DESC_RATE36M    = 0x09,
+       DESC_RATE48M    = 0x0a,
+       DESC_RATE54M    = 0x0b,
+
+       DESC_RATEMCS0   = 0x0c,
+       DESC_RATEMCS1   = 0x0d,
+       DESC_RATEMCS2   = 0x0e,
+       DESC_RATEMCS3   = 0x0f,
+       DESC_RATEMCS4   = 0x10,
+       DESC_RATEMCS5   = 0x11,
+       DESC_RATEMCS6   = 0x12,
+       DESC_RATEMCS7   = 0x13,
+       DESC_RATEMCS8   = 0x14,
+       DESC_RATEMCS9   = 0x15,
+       DESC_RATEMCS10  = 0x16,
+       DESC_RATEMCS11  = 0x17,
+       DESC_RATEMCS12  = 0x18,
+       DESC_RATEMCS13  = 0x19,
+       DESC_RATEMCS14  = 0x1a,
+       DESC_RATEMCS15  = 0x1b,
+       DESC_RATEMCS16  = 0x1c,
+       DESC_RATEMCS17  = 0x1d,
+       DESC_RATEMCS18  = 0x1e,
+       DESC_RATEMCS19  = 0x1f,
+       DESC_RATEMCS20  = 0x20,
+       DESC_RATEMCS21  = 0x21,
+       DESC_RATEMCS22  = 0x22,
+       DESC_RATEMCS23  = 0x23,
+       DESC_RATEMCS24  = 0x24,
+       DESC_RATEMCS25  = 0x25,
+       DESC_RATEMCS26  = 0x26,
+       DESC_RATEMCS27  = 0x27,
+       DESC_RATEMCS28  = 0x28,
+       DESC_RATEMCS29  = 0x29,
+       DESC_RATEMCS30  = 0x2a,
+       DESC_RATEMCS31  = 0x2b,
+
+       DESC_RATEVHT1SS_MCS0    = 0x2c,
+       DESC_RATEVHT1SS_MCS1    = 0x2d,
+       DESC_RATEVHT1SS_MCS2    = 0x2e,
+       DESC_RATEVHT1SS_MCS3    = 0x2f,
+       DESC_RATEVHT1SS_MCS4    = 0x30,
+       DESC_RATEVHT1SS_MCS5    = 0x31,
+       DESC_RATEVHT1SS_MCS6    = 0x32,
+       DESC_RATEVHT1SS_MCS7    = 0x33,
+       DESC_RATEVHT1SS_MCS8    = 0x34,
+       DESC_RATEVHT1SS_MCS9    = 0x35,
+
+       DESC_RATEVHT2SS_MCS0    = 0x36,
+       DESC_RATEVHT2SS_MCS1    = 0x37,
+       DESC_RATEVHT2SS_MCS2    = 0x38,
+       DESC_RATEVHT2SS_MCS3    = 0x39,
+       DESC_RATEVHT2SS_MCS4    = 0x3a,
+       DESC_RATEVHT2SS_MCS5    = 0x3b,
+       DESC_RATEVHT2SS_MCS6    = 0x3c,
+       DESC_RATEVHT2SS_MCS7    = 0x3d,
+       DESC_RATEVHT2SS_MCS8    = 0x3e,
+       DESC_RATEVHT2SS_MCS9    = 0x3f,
+
+       DESC_RATEVHT3SS_MCS0    = 0x40,
+       DESC_RATEVHT3SS_MCS1    = 0x41,
+       DESC_RATEVHT3SS_MCS2    = 0x42,
+       DESC_RATEVHT3SS_MCS3    = 0x43,
+       DESC_RATEVHT3SS_MCS4    = 0x44,
+       DESC_RATEVHT3SS_MCS5    = 0x45,
+       DESC_RATEVHT3SS_MCS6    = 0x46,
+       DESC_RATEVHT3SS_MCS7    = 0x47,
+       DESC_RATEVHT3SS_MCS8    = 0x48,
+       DESC_RATEVHT3SS_MCS9    = 0x49,
+
+       DESC_RATEVHT4SS_MCS0    = 0x4a,
+       DESC_RATEVHT4SS_MCS1    = 0x4b,
+       DESC_RATEVHT4SS_MCS2    = 0x4c,
+       DESC_RATEVHT4SS_MCS3    = 0x4d,
+       DESC_RATEVHT4SS_MCS4    = 0x4e,
+       DESC_RATEVHT4SS_MCS5    = 0x4f,
+       DESC_RATEVHT4SS_MCS6    = 0x50,
+       DESC_RATEVHT4SS_MCS7    = 0x51,
+       DESC_RATEVHT4SS_MCS8    = 0x52,
+       DESC_RATEVHT4SS_MCS9    = 0x53,
+
+       DESC_RATE_MAX,
+};
+
+enum rtw_regulatory_domains {
+       RTW_REGD_FCC    = 0,
+       RTW_REGD_MKK    = 1,
+       RTW_REGD_ETSI   = 2,
+       RTW_REGD_WW     = 3,
+
+       RTW_REGD_MAX
+};
+
+enum rtw_flags {
+       RTW_FLAG_RUNNING,
+       RTW_FLAG_FW_RUNNING,
+       RTW_FLAG_SCANNING,
+       RTW_FLAG_INACTIVE_PS,
+       RTW_FLAG_LEISURE_PS,
+       RTW_FLAG_DIG_DISABLE,
+
+       NUM_OF_RTW_FLAGS,
+};
+
+/* the power index is represented by differences, which cck-1s & ht40-1s are
+ * the base values, so for 1s's differences, there are only ht20 & ofdm
+ */
+struct rtw_2g_1s_pwr_idx_diff {
+#ifdef __LITTLE_ENDIAN
+       s8 ofdm:4;
+       s8 bw20:4;
+#else
+       s8 bw20:4;
+       s8 ofdm:4;
+#endif
+} __packed;
+
+struct rtw_2g_ns_pwr_idx_diff {
+#ifdef __LITTLE_ENDIAN
+       s8 bw20:4;
+       s8 bw40:4;
+       s8 cck:4;
+       s8 ofdm:4;
+#else
+       s8 ofdm:4;
+       s8 cck:4;
+       s8 bw40:4;
+       s8 bw20:4;
+#endif
+} __packed;
+
+struct rtw_2g_txpwr_idx {
+       u8 cck_base[6];
+       u8 bw40_base[5];
+       struct rtw_2g_1s_pwr_idx_diff ht_1s_diff;
+       struct rtw_2g_ns_pwr_idx_diff ht_2s_diff;
+       struct rtw_2g_ns_pwr_idx_diff ht_3s_diff;
+       struct rtw_2g_ns_pwr_idx_diff ht_4s_diff;
+};
+
+struct rtw_5g_ht_1s_pwr_idx_diff {
+#ifdef __LITTLE_ENDIAN
+       s8 ofdm:4;
+       s8 bw20:4;
+#else
+       s8 bw20:4;
+       s8 ofdm:4;
+#endif
+} __packed;
+
+struct rtw_5g_ht_ns_pwr_idx_diff {
+#ifdef __LITTLE_ENDIAN
+       s8 bw20:4;
+       s8 bw40:4;
+#else
+       s8 bw40:4;
+       s8 bw20:4;
+#endif
+} __packed;
+
+struct rtw_5g_ofdm_ns_pwr_idx_diff {
+#ifdef __LITTLE_ENDIAN
+       s8 ofdm_3s:4;
+       s8 ofdm_2s:4;
+       s8 ofdm_4s:4;
+       s8 res:4;
+#else
+       s8 res:4;
+       s8 ofdm_4s:4;
+       s8 ofdm_2s:4;
+       s8 ofdm_3s:4;
+#endif
+} __packed;
+
+struct rtw_5g_vht_ns_pwr_idx_diff {
+#ifdef __LITTLE_ENDIAN
+       s8 bw160:4;
+       s8 bw80:4;
+#else
+       s8 bw80:4;
+       s8 bw160:4;
+#endif
+} __packed;
+
+struct rtw_5g_txpwr_idx {
+       u8 bw40_base[14];
+       struct rtw_5g_ht_1s_pwr_idx_diff ht_1s_diff;
+       struct rtw_5g_ht_ns_pwr_idx_diff ht_2s_diff;
+       struct rtw_5g_ht_ns_pwr_idx_diff ht_3s_diff;
+       struct rtw_5g_ht_ns_pwr_idx_diff ht_4s_diff;
+       struct rtw_5g_ofdm_ns_pwr_idx_diff ofdm_diff;
+       struct rtw_5g_vht_ns_pwr_idx_diff vht_1s_diff;
+       struct rtw_5g_vht_ns_pwr_idx_diff vht_2s_diff;
+       struct rtw_5g_vht_ns_pwr_idx_diff vht_3s_diff;
+       struct rtw_5g_vht_ns_pwr_idx_diff vht_4s_diff;
+};
+
+struct rtw_txpwr_idx {
+       struct rtw_2g_txpwr_idx pwr_idx_2g;
+       struct rtw_5g_txpwr_idx pwr_idx_5g;
+};
+
+struct rtw_timer_list {
+       struct timer_list timer;
+       void (*function)(void *data);
+       void *args;
+};
+
+struct rtw_channel_params {
+       u8 center_chan;
+       u8 bandwidth;
+       u8 primary_chan_idx;
+};
+
+struct rtw_hw_reg {
+       u32 addr;
+       u32 mask;
+};
+
+struct rtw_backup_info {
+       u8 len;
+       u32 reg;
+       u32 val;
+};
+
+enum rtw_vif_port_set {
+       PORT_SET_MAC_ADDR       = BIT(0),
+       PORT_SET_BSSID          = BIT(1),
+       PORT_SET_NET_TYPE       = BIT(2),
+       PORT_SET_AID            = BIT(3),
+};
+
+struct rtw_vif_port {
+       struct rtw_hw_reg mac_addr;
+       struct rtw_hw_reg bssid;
+       struct rtw_hw_reg net_type;
+       struct rtw_hw_reg aid;
+};
+
+struct rtw_tx_pkt_info {
+       u32 tx_pkt_size;
+       u8 offset;
+       u8 pkt_offset;
+       u8 mac_id;
+       u8 rate_id;
+       u8 rate;
+       u8 qsel;
+       u8 bw;
+       u8 sec_type;
+       bool ampdu_en;
+       u8 ampdu_factor;
+       u8 ampdu_density;
+       u16 seq;
+       bool stbc;
+       bool ldpc;
+       bool dis_rate_fallback;
+       bool bmc;
+       bool use_rate;
+       bool ls;
+       bool fs;
+       bool short_gi;
+};
+
+struct rtw_rx_pkt_stat {
+       bool phy_status;
+       bool icv_err;
+       bool crc_err;
+       bool decrypted;
+       bool is_c2h;
+
+       s32 signal_power;
+       u16 pkt_len;
+       u8 bw;
+       u8 drv_info_sz;
+       u8 shift;
+       u8 rate;
+       u8 mac_id;
+       u8 cam_id;
+       u8 ppdu_cnt;
+       u32 tsf_low;
+       s8 rx_power[RTW_RF_PATH_MAX];
+       u8 rssi;
+       u8 rxsc;
+       struct rtw_sta_info *si;
+       struct ieee80211_vif *vif;
+};
+
+struct rtw_traffic_stats {
+       /* units in bytes */
+       u64 tx_unicast;
+       u64 rx_unicast;
+
+       /* count for packets */
+       u64 tx_cnt;
+       u64 rx_cnt;
+
+       /* units in Mbps */
+       u32 tx_throughput;
+       u32 rx_throughput;
+};
+
+enum rtw_lps_mode {
+       RTW_MODE_ACTIVE = 0,
+       RTW_MODE_LPS    = 1,
+       RTW_MODE_WMM_PS = 2,
+};
+
+enum rtw_pwr_state {
+       RTW_RF_OFF      = 0x0,
+       RTW_RF_ON       = 0x4,
+       RTW_ALL_ON      = 0xc,
+};
+
+struct rtw_lps_conf {
+       /* the interface to enter lps */
+       struct rtw_vif *rtwvif;
+       enum rtw_lps_mode mode;
+       enum rtw_pwr_state state;
+       u8 awake_interval;
+       u8 rlbm;
+       u8 smart_ps;
+       u8 port_id;
+};
+
+enum rtw_hw_key_type {
+       RTW_CAM_NONE    = 0,
+       RTW_CAM_WEP40   = 1,
+       RTW_CAM_TKIP    = 2,
+       RTW_CAM_AES     = 4,
+       RTW_CAM_WEP104  = 5,
+};
+
+struct rtw_cam_entry {
+       bool used;
+       bool valid;
+       bool group;
+       u8 addr[ETH_ALEN];
+       u8 hw_key_type;
+       struct ieee80211_key_conf *key;
+};
+
+struct rtw_sec_desc {
+       /* protect cam write/clear */
+       struct mutex mutex;
+
+       /* search strategy */
+       bool default_key_search;
+
+       u32 total_cam_num;
+       struct rtw_cam_entry cam_table[RTW_MAX_SEC_CAM_NUM];
+};
+
+#define RTW_BC_MC_MACID 1
+DECLARE_EWMA(rssi, 10, 16);
+
+struct rtw_sta_info {
+       struct list_head list;
+
+       struct ieee80211_sta *sta;
+       struct ieee80211_vif *vif;
+
+       struct ewma_rssi avg_rssi;
+       u8 rssi_level;
+
+       u8 mac_id;
+       u8 rate_id;
+       enum rtw_bandwidth bw_mode;
+       enum rtw_rf_type rf_type;
+       enum rtw_wireless_set wireless_set;
+       u8 stbc_en:2;
+       u8 ldpc_en:2;
+       bool sgi_enable;
+       bool vht_enable;
+       bool updated;
+       u8 init_ra_lv;
+       u64 ra_mask;
+};
+
+struct rtw_vif {
+       struct list_head list;
+
+       struct ieee80211_vif *vif;
+       enum rtw_net_type net_type;
+       u16 aid;
+       u8 mac_addr[ETH_ALEN];
+       u8 bssid[ETH_ALEN];
+
+       struct list_head sta_list;
+
+       u8 port;
+       struct rtw_vif_port *conf;
+
+       struct rtw_traffic_stats stats;
+       bool in_lps;
+};
+
+struct rtw_regulatory {
+       s8 alpha2[2];
+       u16 country_code;
+};
+
+struct rtw_chip_ops {
+       int (*mac_init)(struct rtw_dev *rtwdev);
+       int (*read_efuse)(struct rtw_dev *rtwdev, u8 *map);
+       void (*phy_set_param)(struct rtw_dev *rtwdev);
+       void (*set_channel)(struct rtw_dev *rtwdev, u8 channel,
+                           u8 bandwidth, u8 primary_chan_idx);
+       void (*query_rx_desc)(struct rtw_dev *rtwdev, u8 *rx_desc,
+                             struct rtw_rx_pkt_stat *pkt_stat,
+                             struct ieee80211_rx_status *rx_status);
+       u32 (*read_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
+                      u32 addr, u32 mask);
+       bool (*write_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
+                        u32 addr, u32 mask, u32 data);
+       void (*set_tx_power_index)(struct rtw_dev *rtwdev, u8 power_index,
+                                  u8 rf_path, u8 rate);
+       int (*rsvd_page_dump)(struct rtw_dev *rtwdev, u8 *buf, u32 offset,
+                             u32 size);
+       void (*set_antenna)(struct rtw_dev *rtwdev, u8 antenna_tx,
+                           u8 antenna_rx);
+       void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable);
+       void (*false_alarm_statistics)(struct rtw_dev *rtwdev);
+       void (*do_iqk)(struct rtw_dev *rtwdev);
+};
+
+#define RTW_PWR_POLLING_CNT    20000
+
+#define RTW_PWR_CMD_READ       0x00
+#define RTW_PWR_CMD_WRITE      0x01
+#define RTW_PWR_CMD_POLLING    0x02
+#define RTW_PWR_CMD_DELAY      0x03
+#define RTW_PWR_CMD_END                0x04
+
+/* define the base address of each block */
+#define RTW_PWR_ADDR_MAC       0x00
+#define RTW_PWR_ADDR_USB       0x01
+#define RTW_PWR_ADDR_PCIE      0x02
+#define RTW_PWR_ADDR_SDIO      0x03
+
+#define RTW_PWR_INTF_SDIO_MSK  BIT(0)
+#define RTW_PWR_INTF_USB_MSK   BIT(1)
+#define RTW_PWR_INTF_PCI_MSK   BIT(2)
+#define RTW_PWR_INTF_ALL_MSK   (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+
+#define RTW_PWR_CUT_A_MSK      BIT(1)
+#define RTW_PWR_CUT_B_MSK      BIT(2)
+#define RTW_PWR_CUT_C_MSK      BIT(3)
+#define RTW_PWR_CUT_D_MSK      BIT(4)
+#define RTW_PWR_CUT_E_MSK      BIT(5)
+#define RTW_PWR_CUT_F_MSK      BIT(6)
+#define RTW_PWR_CUT_G_MSK      BIT(7)
+#define RTW_PWR_CUT_ALL_MSK    0xFF
+
+enum rtw_pwr_seq_cmd_delay_unit {
+       RTW_PWR_DELAY_US,
+       RTW_PWR_DELAY_MS,
+};
+
+struct rtw_pwr_seq_cmd {
+       u16 offset;
+       u8 cut_mask;
+       u8 intf_mask;
+       u8 base:4;
+       u8 cmd:4;
+       u8 mask;
+       u8 value;
+};
+
+enum rtw_chip_ver {
+       RTW_CHIP_VER_CUT_A = 0x00,
+       RTW_CHIP_VER_CUT_B = 0x01,
+       RTW_CHIP_VER_CUT_C = 0x02,
+       RTW_CHIP_VER_CUT_D = 0x03,
+       RTW_CHIP_VER_CUT_E = 0x04,
+       RTW_CHIP_VER_CUT_F = 0x05,
+       RTW_CHIP_VER_CUT_G = 0x06,
+};
+
+#define RTW_INTF_PHY_PLATFORM_ALL 0
+
+enum rtw_intf_phy_cut {
+       RTW_INTF_PHY_CUT_A = BIT(0),
+       RTW_INTF_PHY_CUT_B = BIT(1),
+       RTW_INTF_PHY_CUT_C = BIT(2),
+       RTW_INTF_PHY_CUT_D = BIT(3),
+       RTW_INTF_PHY_CUT_E = BIT(4),
+       RTW_INTF_PHY_CUT_F = BIT(5),
+       RTW_INTF_PHY_CUT_G = BIT(6),
+       RTW_INTF_PHY_CUT_ALL = 0xFFFF,
+};
+
+enum rtw_ip_sel {
+       RTW_IP_SEL_PHY = 0,
+       RTW_IP_SEL_MAC = 1,
+       RTW_IP_SEL_DBI = 2,
+
+       RTW_IP_SEL_UNDEF = 0xFFFF
+};
+
+enum rtw_pq_map_id {
+       RTW_PQ_MAP_VO = 0x0,
+       RTW_PQ_MAP_VI = 0x1,
+       RTW_PQ_MAP_BE = 0x2,
+       RTW_PQ_MAP_BK = 0x3,
+       RTW_PQ_MAP_MG = 0x4,
+       RTW_PQ_MAP_HI = 0x5,
+       RTW_PQ_MAP_NUM = 0x6,
+
+       RTW_PQ_MAP_UNDEF,
+};
+
+enum rtw_dma_mapping {
+       RTW_DMA_MAPPING_EXTRA   = 0,
+       RTW_DMA_MAPPING_LOW     = 1,
+       RTW_DMA_MAPPING_NORMAL  = 2,
+       RTW_DMA_MAPPING_HIGH    = 3,
+
+       RTW_DMA_MAPPING_UNDEF,
+};
+
+struct rtw_rqpn {
+       enum rtw_dma_mapping dma_map_vo;
+       enum rtw_dma_mapping dma_map_vi;
+       enum rtw_dma_mapping dma_map_be;
+       enum rtw_dma_mapping dma_map_bk;
+       enum rtw_dma_mapping dma_map_mg;
+       enum rtw_dma_mapping dma_map_hi;
+};
+
+struct rtw_page_table {
+       u16 hq_num;
+       u16 nq_num;
+       u16 lq_num;
+       u16 exq_num;
+       u16 gapq_num;
+};
+
+struct rtw_intf_phy_para {
+       u16 offset;
+       u16 value;
+       u16 ip_sel;
+       u16 cut_mask;
+       u16 platform;
+};
+
+struct rtw_intf_phy_para_table {
+       struct rtw_intf_phy_para *usb2_para;
+       struct rtw_intf_phy_para *usb3_para;
+       struct rtw_intf_phy_para *gen1_para;
+       struct rtw_intf_phy_para *gen2_para;
+       u8 n_usb2_para;
+       u8 n_usb3_para;
+       u8 n_gen1_para;
+       u8 n_gen2_para;
+};
+
+struct rtw_table {
+       const void *data;
+       const u32 size;
+       void (*parse)(struct rtw_dev *rtwdev, const struct rtw_table *tbl);
+       void (*do_cfg)(struct rtw_dev *rtwdev, const struct rtw_table *tbl,
+                      u32 addr, u32 data);
+       enum rtw_rf_path rf_path;
+};
+
+static inline void rtw_load_table(struct rtw_dev *rtwdev,
+                                 const struct rtw_table *tbl)
+{
+       (*tbl->parse)(rtwdev, tbl);
+}
+
+enum rtw_rfe_fem {
+       RTW_RFE_IFEM,
+       RTW_RFE_EFEM,
+       RTW_RFE_IFEM2G_EFEM5G,
+       RTW_RFE_NUM,
+};
+
+struct rtw_rfe_def {
+       const struct rtw_table *phy_pg_tbl;
+       const struct rtw_table *txpwr_lmt_tbl;
+};
+
+#define RTW_DEF_RFE(chip, bb_pg, pwrlmt) {                               \
+       .phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl,       \
+       .txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \
+       }
+
+/* hardware configuration for each IC */
+struct rtw_chip_info {
+       struct rtw_chip_ops *ops;
+       u8 id;
+
+       const char *fw_name;
+       u8 tx_pkt_desc_sz;
+       u8 tx_buf_desc_sz;
+       u8 rx_pkt_desc_sz;
+       u8 rx_buf_desc_sz;
+       u32 phy_efuse_size;
+       u32 log_efuse_size;
+       u32 ptct_efuse_size;
+       u32 txff_size;
+       u32 rxff_size;
+       u8 band;
+       u8 page_size;
+       u8 csi_buf_pg_num;
+       u8 dig_max;
+       u8 dig_min;
+
+       bool ht_supported;
+       bool vht_supported;
+
+       /* init values */
+       u8 sys_func_en;
+       struct rtw_pwr_seq_cmd **pwr_on_seq;
+       struct rtw_pwr_seq_cmd **pwr_off_seq;
+       struct rtw_rqpn *rqpn_table;
+       struct rtw_page_table *page_table;
+       struct rtw_intf_phy_para_table *intf_table;
+
+       struct rtw_hw_reg *dig;
+       u32 rf_base_addr[2];
+       u32 rf_sipi_addr[2];
+
+       const struct rtw_table *mac_tbl;
+       const struct rtw_table *agc_tbl;
+       const struct rtw_table *bb_tbl;
+       const struct rtw_table *rf_tbl[RTW_RF_PATH_MAX];
+
+       const struct rtw_rfe_def *rfe_defs;
+       u32 rfe_defs_size;
+};
+
+struct rtw_dm_info {
+       u32 cck_fa_cnt;
+       u32 ofdm_fa_cnt;
+       u32 total_fa_cnt;
+       u8 min_rssi;
+       u8 pre_min_rssi;
+       u16 fa_history[4];
+       u8 igi_history[4];
+       u8 igi_bitmap;
+       bool damping;
+       u8 damping_cnt;
+       u8 damping_rssi;
+
+       u8 cck_gi_u_bnd;
+       u8 cck_gi_l_bnd;
+};
+
+struct rtw_efuse {
+       /* protect efuse map read/write */
+       struct mutex mutex;
+       u32 size;
+       u32 physical_size;
+       u32 logical_size;
+       u32 protect_size;
+
+       u8 addr[ETH_ALEN];
+       u8 channel_plan;
+       u8 rfe_option;
+       u8 thermal_meter;
+       u8 crystal_cap;
+       u8 ant_div_cfg;
+       u8 ant_div_type;
+       u8 regd;
+
+       u8 lna_type_2g;
+       u8 lna_type_5g;
+       u8 glna_type;
+       u8 alna_type;
+       bool ext_lna_2g;
+       bool ext_lna_5g;
+       u8 pa_type_2g;
+       u8 pa_type_5g;
+       u8 gpa_type;
+       u8 apa_type;
+       bool ext_pa_2g;
+       bool ext_pa_5g;
+       u8 x3d7;
+       u8 x3d8;
+
+       bool btcoex;
+       /* bt share antenna with wifi */
+       bool share_ant;
+       u8 bt_setting;
+
+       struct {
+               u8 hci;
+               u8 bw;
+               u8 ptcl;
+               u8 nss;
+               u8 ant_num;
+       } hw_cap;
+
+       struct rtw_txpwr_idx txpwr_idx_table[4];
+};
+
+struct rtw_phy_cond {
+#ifdef __LITTLE_ENDIAN
+       u32 rfe:8;
+       u32 intf:4;
+       u32 pkg:4;
+       u32 plat:4;
+       u32 intf_rsvd:4;
+       u32 cut:4;
+       u32 branch:2;
+       u32 neg:1;
+       u32 pos:1;
+#else
+       u32 pos:1;
+       u32 neg:1;
+       u32 branch:2;
+       u32 cut:4;
+       u32 intf_rsvd:4;
+       u32 plat:4;
+       u32 pkg:4;
+       u32 intf:4;
+       u32 rfe:8;
+#endif
+       /* for intf:4 */
+       #define INTF_PCIE       BIT(0)
+       #define INTF_USB        BIT(1)
+       #define INTF_SDIO       BIT(2)
+       /* for branch:2 */
+       #define BRANCH_IF       0
+       #define BRANCH_ELIF     1
+       #define BRANCH_ELSE     2
+       #define BRANCH_ENDIF    3
+};
+
+struct rtw_fifo_conf {
+       /* tx fifo information */
+       u16 rsvd_boundary;
+       u16 rsvd_pg_num;
+       u16 rsvd_drv_pg_num;
+       u16 txff_pg_num;
+       u16 acq_pg_num;
+       u16 rsvd_drv_addr;
+       u16 rsvd_h2c_info_addr;
+       u16 rsvd_h2c_sta_info_addr;
+       u16 rsvd_h2cq_addr;
+       u16 rsvd_cpu_instr_addr;
+       u16 rsvd_fw_txbuf_addr;
+       u16 rsvd_csibuf_addr;
+       enum rtw_dma_mapping pq_map[RTW_PQ_MAP_NUM];
+};
+
+struct rtw_fw_state {
+       const struct firmware *firmware;
+       const u8 *data;
+       u32 size;
+       u16 version;
+       u8 sub_version;
+       u8 sub_index;
+       u16 h2c_version;
+};
+
+struct rtw_hal {
+       u32 rcr;
+
+       u32 chip_version;
+       u8 fab_version;
+       u8 cut_version;
+       u8 mp_chip;
+       u8 oem_id;
+       struct rtw_phy_cond phy_cond;
+
+       /* incicate the mail box to use with fw */
+       u8 last_box_num;
+       /* protect to send h2c to fw */
+       struct mutex h2c_mutex;
+       u32 buf_sz;
+       u32 seq;
+
+       u8 ps_mode;
+       u8 current_channel;
+       u8 current_band_width;
+       u8 current_band_type;
+       u8 sec_ch_offset;
+       u8 rf_type;
+       u8 rf_path_num;
+       u8 antenna_tx;
+       u8 antenna_rx;
+
+       /* protect tx power section */
+       struct mutex tx_power_mutex;
+       s8 tx_pwr_by_rate_offset_2g[RTW_RF_PATH_MAX]
+                                  [DESC_RATE_MAX];
+       s8 tx_pwr_by_rate_offset_5g[RTW_RF_PATH_MAX]
+                                  [DESC_RATE_MAX];
+       s8 tx_pwr_by_rate_base_2g[RTW_RF_PATH_MAX]
+                                [RTW_RATE_SECTION_MAX];
+       s8 tx_pwr_by_rate_base_5g[RTW_RF_PATH_MAX]
+                                [RTW_RATE_SECTION_MAX];
+       s8 tx_pwr_limit_2g[RTW_REGD_MAX]
+                         [RTW_CHANNEL_WIDTH_MAX]
+                         [RTW_RATE_SECTION_MAX]
+                         [RTW_MAX_CHANNEL_NUM_2G];
+       s8 tx_pwr_limit_5g[RTW_REGD_MAX]
+                         [RTW_CHANNEL_WIDTH_MAX]
+                         [RTW_RATE_SECTION_MAX]
+                         [RTW_MAX_CHANNEL_NUM_5G];
+};
+
+struct rtw_dev {
+       struct ieee80211_hw *hw;
+       struct device *dev;
+
+       struct rtw_hci hci;
+
+       struct rtw_chip_info *chip;
+       struct rtw_hal hal;
+       struct rtw_fifo_conf fifo;
+       struct rtw_fw_state fw;
+       struct rtw_efuse efuse;
+       struct rtw_sec_desc sec;
+       struct rtw_traffic_stats stats;
+       struct rtw_regulatory regd;
+
+       struct rtw_dm_info dm_info;
+
+       /* lock for dm to use */
+       spinlock_t dm_lock;
+
+       /* read/write rf register */
+       spinlock_t rf_lock;
+
+       /* watch dog every 2 sec */
+       struct delayed_work watch_dog_work;
+       u32 watch_dog_cnt;
+
+       /* list for virtual interfaces */
+       struct list_head vif_list;
+
+       struct list_head rsvd_page_list;
+
+       /* c2h cmd queue & handler work */
+       struct sk_buff_head c2h_queue;
+       struct work_struct c2h_work;
+
+       /* lps power state & handler work */
+       struct rtw_lps_conf lps_conf;
+       struct delayed_work lps_work;
+
+       bool macid_used[RTW_MAX_MAC_ID_NUM];
+
+       unsigned long flags[BITS_TO_LONGS(NUM_OF_RTW_FLAGS)];
+
+       u8 mp_mode;
+
+       /* hci related data, must be last */
+       u8 priv[0] __aligned(sizeof(void *));
+};
+
+#include "hci.h"
+
+static inline bool rtw_flag_check(struct rtw_dev *rtwdev, enum rtw_flags flag)
+{
+       return test_bit(flag, rtwdev->flags);
+}
+
+static inline void rtw_flag_clear(struct rtw_dev *rtwdev, enum rtw_flags flag)
+{
+       clear_bit(flag, rtwdev->flags);
+}
+
+static inline void rtw_flag_set(struct rtw_dev *rtwdev, enum rtw_flags flag)
+{
+       set_bit(flag, rtwdev->flags);
+}
+
+static inline bool get_hdr_match_bssid(struct rtw_dev *rtwdev,
+                                      struct ieee80211_hdr *hdr,
+                                      u8 *bssid)
+{
+       struct ieee80211_vif *vif;
+       struct rtw_vif *rtwvif;
+
+       list_for_each_entry(rtwvif, &rtwdev->vif_list, list) {
+               vif = rtwvif->vif;
+               if (ether_addr_equal(vif->bss_conf.bssid, bssid))
+                       return true;
+       }
+
+       return false;
+}
+
+static inline struct ieee80211_vif *get_hdr_vif(struct rtw_dev *rtwdev,
+                                               struct ieee80211_hdr *hdr)
+{
+       struct ieee80211_vif *vif;
+       struct rtw_vif *rtwvif;
+
+       list_for_each_entry(rtwvif, &rtwdev->vif_list, list) {
+               vif = rtwvif->vif;
+               if (ether_addr_equal(vif->addr, hdr->addr1))
+                       return vif;
+       }
+
+       return NULL;
+}
+
+static inline struct rtw_sta_info *get_hdr_sta(struct rtw_dev *rtwdev,
+                                              struct ieee80211_vif *vif,
+                                              struct ieee80211_hdr *hdr)
+{
+       struct rtw_vif *rtwvif;
+       struct rtw_sta_info *si;
+
+       if (vif) {
+               rtwvif = (struct rtw_vif *)vif->drv_priv;
+               list_for_each_entry(si, &rtwvif->sta_list, list) {
+                       if (ether_addr_equal(si->sta->addr, hdr->addr2))
+                               return si;
+               }
+       } else {
+               list_for_each_entry(rtwvif, &rtwdev->vif_list, list) {
+                       list_for_each_entry(si, &rtwvif->sta_list, list) {
+                               if (ether_addr_equal(si->sta->addr, hdr->addr2))
+                                       return si;
+                       }
+               }
+       }
+
+       return NULL;
+}
+
+static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr)
+{
+       __le16 fc = hdr->frame_control;
+       u8 *bssid;
+
+       if (ieee80211_has_tods(fc))
+               bssid = hdr->addr1;
+       else if (ieee80211_has_fromds(fc))
+               bssid = hdr->addr2;
+       else
+               bssid = hdr->addr3;
+
+       return bssid;
+}
+
+static inline bool get_link_status(struct rtw_dev *rtwdev)
+{
+       struct rtw_vif *rtwvif;
+
+       list_for_each_entry(rtwvif, &rtwdev->vif_list, list) {
+               /* test if we have any peer in present */
+               if (!list_empty(&rtwvif->sta_list))
+                       return true;
+       }
+
+       return false;
+}
+
+void rtw_get_channel_params(struct cfg80211_chan_def *chandef,
+                           struct rtw_channel_params *ch_param);
+void rtw_set_channel(struct rtw_dev *rtwdev);
+void rtw_vif_port_config(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,
+                        u32 config);
+void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si);
+int rtw_core_start(struct rtw_dev *rtwdev);
+void rtw_core_stop(struct rtw_dev *rtwdev);
+int rtw_chip_info_setup(struct rtw_dev *rtwdev);
+int rtw_core_init(struct rtw_dev *rtwdev);
+void rtw_core_deinit(struct rtw_dev *rtwdev);
+int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw);
+void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw);
+
+#endif
diff --git a/drivers/net/wireless/realtek/rtwlan/reg.h 
b/drivers/net/wireless/realtek/rtwlan/reg.h
new file mode 100644
index 0000000..7adf568
--- /dev/null
+++ b/drivers/net/wireless/realtek/rtwlan/reg.h
@@ -0,0 +1,399 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2018  Realtek Corporation.
+ */
+
+#ifndef __RTW_REG_DEF_H__
+#define __RTW_REG_DEF_H__
+
+#define REG_SYS_FUNC_EN                0x0002
+#define REG_SYS_PW_CTRL                0x0004
+#define REG_SYS_CLK_CTRL       0x0008
+
+#define REG_RSV_CTRL           0x001C
+#define REG_RF_CTRL            0x001F
+
+#define REG_EFUSE_CTRL         0x0030
+#define BIT_EF_FLAG            BIT(31)
+#define BIT_SHIFT_EF_ADDR      8
+#define BIT_MASK_EF_ADDR       0x3ff
+#define BIT_MASK_EF_DATA       0xff
+#define BITS_EF_ADDR           (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR)
+
+#define REG_LDO_EFUSE_CTRL     0x0034
+
+#define REG_GPIO_MUXCFG                0x0040
+#define BIT_FSPI_EN            BIT(19)
+
+#define REG_LED_CFG            0x004C
+#define REG_PAD_CTRL1          0x0064
+#define REG_WL_BT_PWR_CTRL     0x0068
+#define BIT_BT_FUNC_EN         BIT(18)
+#define REG_HCI_OPT_CTRL       0x0074
+
+#define REG_MCUFW_CTRL         0x0080
+#define BIT_ANA_PORT_EN                BIT(22)
+#define BIT_MAC_PORT_EN                BIT(21)
+#define BIT_BOOT_FSPI_EN       BIT(20)
+#define BIT_FW_DW_RDY          BIT(14)
+#define BIT_DMEM_CHKSUM_OK     BIT(6)
+#define BIT_DMEM_DW_OK         BIT(5)
+#define BIT_IMEM_CHKSUM_OK     BIT(4)
+#define BIT_IMEM_DW_OK         BIT(3)
+
+#define REG_SYS_CFG1           0x00F0
+#define        BIT_RTL_ID              BIT(23)
+#define BIT_RF_TYPE_ID         BIT(27)
+#define BIT_SHIFT_VENDOR_ID    16
+#define BIT_MASK_VENDOR_ID     0xf
+#define BIT_VENDOR_ID(x) (((x) & BIT_MASK_VENDOR_ID) << BIT_SHIFT_VENDOR_ID)
+#define BITS_VENDOR_ID         (BIT_MASK_VENDOR_ID << BIT_SHIFT_VENDOR_ID)
+#define BIT_CLEAR_VENDOR_ID(x) ((x) & (~BITS_VENDOR_ID))
+#define BIT_GET_VENDOR_ID(x) (((x) >> BIT_SHIFT_VENDOR_ID) & 
BIT_MASK_VENDOR_ID)
+#define BIT_SHIFT_CHIP_VER     12
+#define BIT_MASK_CHIP_VER      0xf
+#define BIT_CHIP_VER(x)         (((x) & BIT_MASK_CHIP_VER) << 
BIT_SHIFT_CHIP_VER)
+#define BITS_CHIP_VER          (BIT_MASK_CHIP_VER << BIT_SHIFT_CHIP_VER)
+#define BIT_CLEAR_CHIP_VER(x)  ((x) & (~BITS_CHIP_VER))
+#define BIT_GET_CHIP_VER(x) (((x) >> BIT_SHIFT_CHIP_VER) & BIT_MASK_CHIP_VER)
+#define REG_SYS_STATUS1                0x00F4
+#define REG_SYS_STATUS2                0x00F8
+#define REG_SYS_CFG2           0x00FC
+#define REG_WLRF1              0x00EC
+#define REG_CR                 0x0100
+#define BIT_32K_CAL_TMR_EN     BIT(10)
+#define BIT_MAC_SEC_EN         BIT(9)
+#define BIT_ENSWBCN            BIT(8)
+#define BIT_MACRXEN            BIT(7)
+#define BIT_MACTXEN            BIT(6)
+#define BIT_SCHEDULE_EN                BIT(5)
+#define BIT_PROTOCOL_EN                BIT(4)
+#define BIT_RXDMA_EN           BIT(3)
+#define BIT_TXDMA_EN           BIT(2)
+#define BIT_HCI_RXDMA_EN       BIT(1)
+#define BIT_HCI_TXDMA_EN       BIT(0)
+#define MAC_TRX_ENABLE (BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN | \
+                       BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | \
+                       BIT_MACTXEN | BIT_MACRXEN)
+#define BIT_SHIFT_TXDMA_VOQ_MAP        4
+#define BIT_MASK_TXDMA_VOQ_MAP 0x3
+#define BIT_TXDMA_VOQ_MAP(x)                                                   
\
+       (((x) & BIT_MASK_TXDMA_VOQ_MAP) << BIT_SHIFT_TXDMA_VOQ_MAP)
+#define BIT_SHIFT_TXDMA_VIQ_MAP        6
+#define BIT_MASK_TXDMA_VIQ_MAP 0x3
+#define BIT_TXDMA_VIQ_MAP(x)                                                   
\
+       (((x) & BIT_MASK_TXDMA_VIQ_MAP) << BIT_SHIFT_TXDMA_VIQ_MAP)
+#define REG_TXDMA_PQ_MAP       0x010C
+#define BIT_SHIFT_TXDMA_BEQ_MAP        8
+#define BIT_MASK_TXDMA_BEQ_MAP 0x3
+#define BIT_TXDMA_BEQ_MAP(x)                                                   
\
+       (((x) & BIT_MASK_TXDMA_BEQ_MAP) << BIT_SHIFT_TXDMA_BEQ_MAP)
+#define BIT_SHIFT_TXDMA_BKQ_MAP        10
+#define BIT_MASK_TXDMA_BKQ_MAP 0x3
+#define BIT_TXDMA_BKQ_MAP(x)                                                   
\
+       (((x) & BIT_MASK_TXDMA_BKQ_MAP) << BIT_SHIFT_TXDMA_BKQ_MAP)
+#define BIT_SHIFT_TXDMA_MGQ_MAP        12
+#define BIT_MASK_TXDMA_MGQ_MAP 0x3
+#define BIT_TXDMA_MGQ_MAP(x)                                                   
\
+       (((x) & BIT_MASK_TXDMA_MGQ_MAP) << BIT_SHIFT_TXDMA_MGQ_MAP)
+#define BIT_SHIFT_TXDMA_HIQ_MAP        14
+#define BIT_MASK_TXDMA_HIQ_MAP 0x3
+#define BIT_TXDMA_HIQ_MAP(x)                                                   
\
+       (((x) & BIT_MASK_TXDMA_HIQ_MAP) << BIT_SHIFT_TXDMA_HIQ_MAP)
+#define BIT_SHIFT_TXSC_40M     4
+#define BIT_MASK_TXSC_40M      0xf
+#define BIT_TXSC_40M(x)                                                        
       \
+       (((x) & BIT_MASK_TXSC_40M) << BIT_SHIFT_TXSC_40M)
+#define BIT_SHIFT_TXSC_20M     0
+#define BIT_MASK_TXSC_20M      0xf
+#define BIT_TXSC_20M(x)                                                        
       \
+       (((x) & BIT_MASK_TXSC_20M) << BIT_SHIFT_TXSC_20M)
+#define BIT_SHIFT_MAC_CLK_SEL  20
+#define MAC_CLK_HW_DEF_80M     0
+#define MAC_CLK_HW_DEF_40M     1
+#define MAC_CLK_HW_DEF_20M     2
+#define MAC_CLK_SPEED          80
+
+#define REG_AFE_CTRL1          0x0024
+
+#define REG_CR                 0x0100
+#define REG_TRXFF_BNDY         0x0114
+#define REG_RXFF_BNDY          0x011C
+#define REG_PKTBUF_DBG_CTRL    0x0140
+#define REG_C2HEVT             0x01A0
+#define REG_HMETFR             0x01CC
+#define REG_HMEBOX0            0x01D0
+#define REG_HMEBOX1            0x01D4
+#define REG_HMEBOX2            0x01D8
+#define REG_HMEBOX3            0x01DC
+#define REG_HMEBOX0_EX         0x01F0
+#define REG_HMEBOX1_EX         0x01F4
+#define REG_HMEBOX2_EX         0x01F8
+#define REG_HMEBOX3_EX         0x01FC
+
+#define REG_FIFOPAGE_CTRL_2    0x0204
+#define BIT_MASK_BCN_HEAD_1_V1 0xfff
+#define REG_AUTO_LLT_V1                0x0208
+#define BIT_AUTO_INIT_LLT_V1   BIT(0)
+#define REG_TXDMA_OFFSET_CHK   0x020C
+#define REG_TXDMA_STATUS       0x0210
+#define REG_RQPN_CTRL_1                0x0228
+#define REG_RQPN_CTRL_2                0x022C
+#define REG_FIFOPAGE_INFO_1    0x0230
+#define REG_FIFOPAGE_INFO_2    0x0234
+#define REG_FIFOPAGE_INFO_3    0x0238
+#define REG_FIFOPAGE_INFO_4    0x023C
+#define REG_FIFOPAGE_INFO_5    0x0240
+#define REG_H2C_HEAD           0x0244
+#define REG_H2C_TAIL           0x0248
+#define REG_H2C_READ_ADDR      0x024C
+#define REG_H2C_INFO           0x0254
+
+#define REG_FWHW_TXQ_CTRL      0x0420
+#define REG_BCNQ_BDNY_V1       0x0424
+#define REG_LIFETIME_EN                0x0426
+#define REG_SPEC_SIFS          0x0428
+#define REG_DARFRC             0x0430
+#define REG_DARFRCH            0x0434
+#define REG_RARFRCH            0x043C
+#define REG_ARFR0              0x0444
+#define REG_ARFRH0             0x0448
+#define REG_ARFR1_V1           0x044C
+#define REG_ARFRH1_V1          0x0450
+#define REG_CCK_CHECK          0x0454
+#define REG_AMPDU_MAX_TIME_V1  0x0455
+#define REG_BCNQ1_BDNY_V1      0x0456
+#define REG_TX_HANG_CTRL       0x045E
+#define BIT_EN_EOF_V1          BIT(2)
+#define REG_DATA_SC            0x0483
+#define REG_ARFR4              0x049C
+#define REG_ARFRH4             0x04A0
+#define REG_ARFR5              0x04A4
+#define REG_ARFRH5             0x04A8
+#define REG_SW_AMPDU_BURST_MODE_CTRL 0x04BC
+#define REG_PROT_MODE_CTRL     0x04C8
+#define REG_BAR_MODE_CTRL      0x04CC
+#define REG_PRECNT_CTRL                0x04E5
+#define BIT_EN_PRECNT          BIT(11)
+
+#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_PIFS               0x0512
+#define REG_SIFS               0x0514
+#define BIT_SHIFT_SIFS_OFDM_CTX        8
+#define BIT_SHIFT_SIFS_CCK_TRX 16
+#define BIT_SHIFT_SIFS_OFDM_TRX        24
+#define REG_SLOT               0x051B
+#define REG_TX_PTCL_CTRL       0x0520
+#define REG_TXPAUSE            0x0522
+#define REG_RD_CTRL            0x0524
+#define REG_TBTT_PROHIBIT      0x0540
+#define BIT_SHIFT_TBTT_HOLD_TIME_AP 8
+#define REG_RD_NAV_NXT         0x0544
+#define REG_BCN_CTRL           0x0550
+#define BIT_EN_BCN_FUNCTION    BIT(3)
+#define REG_BCN_CTRL_CLINT0    0x0551
+#define REG_DRVERLYINT         0x0558
+#define REG_BCNDMATIM          0x0559
+#define REG_USTIME_TSF         0x055C
+#define REG_BCN_MAX_ERR                0x055D
+#define REG_RXTSF_OFFSET_CCK   0x055E
+#define REG_MISC_CTRL          0x0577
+#define REG_TIMER0_SRC_SEL     0x05B4
+
+#define REG_TCR                        0x0604
+#define REG_RCR                        0x0608
+#define BIT_APP_FCS            BIT(31)
+#define BIT_APP_MIC            BIT(30)
+#define BIT_APP_ICV            BIT(29)
+#define BIT_APP_PHYSTS         BIT(28)
+#define BIT_APP_BASSN          BIT(27)
+#define BIT_VHT_DACK           BIT(26)
+#define BIT_TCPOFLD_EN         BIT(25)
+#define BIT_ENMBID             BIT(24)
+#define BIT_LSIGEN             BIT(23)
+#define BIT_MFBEN              BIT(22)
+#define BIT_DISCHKPPDLLEN      BIT(21)
+#define BIT_PKTCTL_DLEN                BIT(20)
+#define BIT_TIM_PARSER_EN      BIT(18)
+#define BIT_BC_MD_EN           BIT(17)
+#define BIT_UC_MD_EN           BIT(16)
+#define BIT_RXSK_PERPKT                BIT(15)
+#define BIT_HTC_LOC_CTRL       BIT(14)
+#define BIT_RPFM_CAM_ENABLE    BIT(12)
+#define BIT_TA_BCN             BIT(11)
+#define BIT_DISDECMYPKT                BIT(10)
+#define BIT_AICV               BIT(9)
+#define BIT_ACRC32             BIT(8)
+#define BIT_CBSSID_BCN         BIT(7)
+#define BIT_CBSSID_DATA                BIT(6)
+#define BIT_APWRMGT            BIT(5)
+#define BIT_ADD3               BIT(4)
+#define BIT_AB                 BIT(3)
+#define BIT_AM                 BIT(2)
+#define BIT_APM                        BIT(1)
+#define BIT_AAP                        BIT(0)
+#define REG_RX_PKT_LIMIT       0x060C
+#define REG_RX_DRVINFO_SZ      0x060F
+#define BIT_APP_PHYSTS         BIT(28)
+#define REG_USTIME_EDCA                0x0638
+#define REG_RESP_SIFS_CCK      0x063C
+#define REG_RESP_SIFS_OFDM     0x063E
+#define REG_ACKTO              0x0640
+#define REG_EIFS               0x0642
+#define REG_NAV_CTRL           0x0650
+#define REG_WMAC_TRXPTCL_CTL   0x0668
+#define REG_WMAC_TRXPTCL_CTL_H 0x066C
+#define REG_RXFLTMAP0          0x06A0
+#define REG_RXFLTMAP1          0x06A2
+#define REG_RXFLTMAP2          0x06A4
+#define REG_BBPSF_CTRL         0x06DC
+
+#define REG_WMAC_OPTION_FUNCTION 0x07D0
+#define REG_WMAC_OPTION_FUNCTION_1 0x07D4
+
+#define REG_CPU_DMEM_CON       0x1080
+#define BIT_WL_PLATFORM_RST    BIT(16)
+#define BIT_WL_SECURITY_CLK    BIT(15)
+#define BIT_DDMA_EN            BIT(8)
+
+#define REG_H2C_PKT_READADDR   0x10D0
+#define REG_H2C_PKT_WRITEADDR  0x10D4
+#define REG_FW_DBG7            0x10FC
+
+#define REG_CR_EXT             0x1100
+
+#define REG_DDMA_CH0SA         0x1200
+#define REG_DDMA_CH0DA         0x1204
+#define REG_DDMA_CH0CTRL       0x1208
+#define BIT_DDMACH0_OWN                BIT(31)
+#define BIT_DDMACH0_CHKSUM_EN  BIT(29)
+#define BIT_DDMACH0_CHKSUM_STS BIT(27)
+#define BIT_DDMACH0_RESET_CHKSUM_STS BIT(25)
+#define BIT_DDMACH0_CHKSUM_CONT        BIT(24)
+#define BIT_MASK_DDMACH0_DLEN  0x3ffff
+
+#define REG_H2CQ_CSR           0x1330
+#define REG_FAST_EDCA_VOVI_SETTING 0x1448
+#define REG_FAST_EDCA_BEBK_SETTING 0x144C
+
+#define REG_RXPSF_CTRL         0x1610
+#define BIT_RXGCK_FIFOTHR_EN   BIT(28)
+
+#define BIT_SHIFT_RXGCK_VHT_FIFOTHR 26
+#define BIT_MASK_RXGCK_VHT_FIFOTHR 0x3
+#define BIT_RXGCK_VHT_FIFOTHR(x)                                               
\
+       (((x) & BIT_MASK_RXGCK_VHT_FIFOTHR) << BIT_SHIFT_RXGCK_VHT_FIFOTHR)
+#define BITS_RXGCK_VHT_FIFOTHR                                                 
\
+       (BIT_MASK_RXGCK_VHT_FIFOTHR << BIT_SHIFT_RXGCK_VHT_FIFOTHR)
+#define BIT_CLEAR_RXGCK_VHT_FIFOTHR(x) ((x) & (~BITS_RXGCK_VHT_FIFOTHR))
+#define BIT_GET_RXGCK_VHT_FIFOTHR(x)                                           
\
+       (((x) >> BIT_SHIFT_RXGCK_VHT_FIFOTHR) & BIT_MASK_RXGCK_VHT_FIFOTHR)
+#define BIT_SET_RXGCK_VHT_FIFOTHR(x, v)                                        
\
+       (BIT_CLEAR_RXGCK_VHT_FIFOTHR(x) | BIT_RXGCK_VHT_FIFOTHR(v))
+
+#define BIT_SHIFT_RXGCK_HT_FIFOTHR 24
+#define BIT_MASK_RXGCK_HT_FIFOTHR 0x3
+#define BIT_RXGCK_HT_FIFOTHR(x)                                                
\
+       (((x) & BIT_MASK_RXGCK_HT_FIFOTHR) << BIT_SHIFT_RXGCK_HT_FIFOTHR)
+#define BITS_RXGCK_HT_FIFOTHR                                                  
\
+       (BIT_MASK_RXGCK_HT_FIFOTHR << BIT_SHIFT_RXGCK_HT_FIFOTHR)
+#define BIT_CLEAR_RXGCK_HT_FIFOTHR(x) ((x) & (~BITS_RXGCK_HT_FIFOTHR))
+#define BIT_GET_RXGCK_HT_FIFOTHR(x)                                            
\
+       (((x) >> BIT_SHIFT_RXGCK_HT_FIFOTHR) & BIT_MASK_RXGCK_HT_FIFOTHR)
+#define BIT_SET_RXGCK_HT_FIFOTHR(x, v)                                         
\
+       (BIT_CLEAR_RXGCK_HT_FIFOTHR(x) | BIT_RXGCK_HT_FIFOTHR(v))
+
+#define BIT_SHIFT_RXGCK_OFDM_FIFOTHR 22
+#define BIT_MASK_RXGCK_OFDM_FIFOTHR 0x3
+#define BIT_RXGCK_OFDM_FIFOTHR(x)                                              
\
+       (((x) & BIT_MASK_RXGCK_OFDM_FIFOTHR) << BIT_SHIFT_RXGCK_OFDM_FIFOTHR)
+#define BITS_RXGCK_OFDM_FIFOTHR                                                
\
+       (BIT_MASK_RXGCK_OFDM_FIFOTHR << BIT_SHIFT_RXGCK_OFDM_FIFOTHR)
+#define BIT_CLEAR_RXGCK_OFDM_FIFOTHR(x) ((x) & (~BITS_RXGCK_OFDM_FIFOTHR))
+#define BIT_GET_RXGCK_OFDM_FIFOTHR(x)                                          
\
+       (((x) >> BIT_SHIFT_RXGCK_OFDM_FIFOTHR) & BIT_MASK_RXGCK_OFDM_FIFOTHR)
+#define BIT_SET_RXGCK_OFDM_FIFOTHR(x, v)                                       
\
+       (BIT_CLEAR_RXGCK_OFDM_FIFOTHR(x) | BIT_RXGCK_OFDM_FIFOTHR(v))
+
+#define BIT_SHIFT_RXGCK_CCK_FIFOTHR 20
+#define BIT_MASK_RXGCK_CCK_FIFOTHR 0x3
+#define BIT_RXGCK_CCK_FIFOTHR(x)                                               
\
+       (((x) & BIT_MASK_RXGCK_CCK_FIFOTHR) << BIT_SHIFT_RXGCK_CCK_FIFOTHR)
+#define BITS_RXGCK_CCK_FIFOTHR                                                 
\
+       (BIT_MASK_RXGCK_CCK_FIFOTHR << BIT_SHIFT_RXGCK_CCK_FIFOTHR)
+#define BIT_CLEAR_RXGCK_CCK_FIFOTHR(x) ((x) & (~BITS_RXGCK_CCK_FIFOTHR))
+#define BIT_GET_RXGCK_CCK_FIFOTHR(x)                                           
\
+       (((x) >> BIT_SHIFT_RXGCK_CCK_FIFOTHR) & BIT_MASK_RXGCK_CCK_FIFOTHR)
+#define BIT_SET_RXGCK_CCK_FIFOTHR(x, v)                                        
\
+       (BIT_CLEAR_RXGCK_CCK_FIFOTHR(x) | BIT_RXGCK_CCK_FIFOTHR(v))
+
+#define BIT_SHIFT_RXGCK_ENTRY_DELAY 17
+#define BIT_MASK_RXGCK_ENTRY_DELAY 0x7
+#define BIT_RXGCK_ENTRY_DELAY(x)                                               
\
+       (((x) & BIT_MASK_RXGCK_ENTRY_DELAY) << BIT_SHIFT_RXGCK_ENTRY_DELAY)
+#define BITS_RXGCK_ENTRY_DELAY                                                 
\
+       (BIT_MASK_RXGCK_ENTRY_DELAY << BIT_SHIFT_RXGCK_ENTRY_DELAY)
+#define BIT_CLEAR_RXGCK_ENTRY_DELAY(x) ((x) & (~BITS_RXGCK_ENTRY_DELAY))
+#define BIT_GET_RXGCK_ENTRY_DELAY(x)                                           
\
+       (((x) >> BIT_SHIFT_RXGCK_ENTRY_DELAY) & BIT_MASK_RXGCK_ENTRY_DELAY)
+#define BIT_SET_RXGCK_ENTRY_DELAY(x, v)                                        
\
+       (BIT_CLEAR_RXGCK_ENTRY_DELAY(x) | BIT_RXGCK_ENTRY_DELAY(v))
+
+#define BIT_RXGCK_OFDMCCA_EN BIT(16)
+
+#define BIT_SHIFT_RXPSF_PKTLENTHR 13
+#define BIT_MASK_RXPSF_PKTLENTHR 0x7
+#define BIT_RXPSF_PKTLENTHR(x)                                                 
\
+       (((x) & BIT_MASK_RXPSF_PKTLENTHR) << BIT_SHIFT_RXPSF_PKTLENTHR)
+#define BITS_RXPSF_PKTLENTHR                                                   
\
+       (BIT_MASK_RXPSF_PKTLENTHR << BIT_SHIFT_RXPSF_PKTLENTHR)
+#define BIT_CLEAR_RXPSF_PKTLENTHR(x) ((x) & (~BITS_RXPSF_PKTLENTHR))
+#define BIT_GET_RXPSF_PKTLENTHR(x)                                             
\
+       (((x) >> BIT_SHIFT_RXPSF_PKTLENTHR) & BIT_MASK_RXPSF_PKTLENTHR)
+#define BIT_SET_RXPSF_PKTLENTHR(x, v)                                          
\
+       (BIT_CLEAR_RXPSF_PKTLENTHR(x) | BIT_RXPSF_PKTLENTHR(v))
+
+#define BIT_RXPSF_CTRLEN       BIT(12)
+#define BIT_RXPSF_VHTCHKEN     BIT(11)
+#define BIT_RXPSF_HTCHKEN      BIT(10)
+#define BIT_RXPSF_OFDMCHKEN    BIT(9)
+#define BIT_RXPSF_CCKCHKEN     BIT(8)
+#define BIT_RXPSF_OFDMRST      BIT(7)
+#define BIT_RXPSF_CCKRST       BIT(6)
+#define BIT_RXPSF_MHCHKEN      BIT(5)
+#define BIT_RXPSF_CONT_ERRCHKEN        BIT(4)
+#define BIT_RXPSF_ALL_ERRCHKEN BIT(3)
+
+#define BIT_SHIFT_RXPSF_ERRTHR 0
+#define BIT_MASK_RXPSF_ERRTHR 0x7
+#define BIT_RXPSF_ERRTHR(x)                                                    
\
+       (((x) & BIT_MASK_RXPSF_ERRTHR) << BIT_SHIFT_RXPSF_ERRTHR)
+#define BITS_RXPSF_ERRTHR (BIT_MASK_RXPSF_ERRTHR << BIT_SHIFT_RXPSF_ERRTHR)
+#define BIT_CLEAR_RXPSF_ERRTHR(x) ((x) & (~BITS_RXPSF_ERRTHR))
+#define BIT_GET_RXPSF_ERRTHR(x)                                                
\
+       (((x) >> BIT_SHIFT_RXPSF_ERRTHR) & BIT_MASK_RXPSF_ERRTHR)
+#define BIT_SET_RXPSF_ERRTHR(x, v)                                             
\
+       (BIT_CLEAR_RXPSF_ERRTHR(x) | BIT_RXPSF_ERRTHR(v))
+
+#define REG_RXPSF_TYPE_CTRL    0x1614
+
+#define REG_WL2LTECOEX_INDIRECT_ACCESS_CTRL_V1         0x1700
+#define REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1   0x1704
+#define REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1    0x1708
+#define LTECOEX_ACCESS_CTRL REG_WL2LTECOEX_INDIRECT_ACCESS_CTRL_V1
+#define LTECOEX_WRITE_DATA REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1
+#define LTECOEX_READ_DATA REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1
+
+#define RF_DTXLOK      0x08
+#define RF_CFGCH       0x18
+#define RF_LUTWA       0x33
+#define RF_LUTWD1      0x3e
+#define RF_LUTWD0      0x3f
+#define RF_XTALX2      0xb8
+#define RF_MALSEL      0xbe
+#define RF_LUTDBG      0xdf
+#define RF_LUTWE       0xef
+
+#endif
-- 
2.7.4

Reply via email to